90
You’re doing it wrong! לוורדפרס בפיתוח נפוצות טעויות עשרMonday, September 12, 11

WordCamp Jerusalem - Doing it Wrong

Embed Size (px)

DESCRIPTION

Things developers tend to do wrong with WordPress. Based on amazing presentations from many great WordPress developers across the world. Slides mostly in English, presentation was in Hebrew at WordCamp Jerusalem (September 2011). הערות והפניות בבלוג בכתובת http://wp.me/pD4bk-Jn

Citation preview

Page 1: WordCamp Jerusalem - Doing it Wrong

You’re doing it wrong!עשר טעויות נפוצות בפיתוח לוורדפרס

Monday, September 12, 11

Page 2: WordCamp Jerusalem - Doing it Wrong

You’re doing it wrong!עשר תשע טעויות נפוצות בפיתוח לוורדפרס

Monday, September 12, 11

Page 3: WordCamp Jerusalem - Doing it Wrong

Monday, September 12, 11

Page 4: WordCamp Jerusalem - Doing it Wrong

Monday, September 12, 11

Page 5: WordCamp Jerusalem - Doing it Wrong

מפתח VIP בחברת Automattic

צוות ה-VIP מפקח בין WordPress השאר על קוד

שיוצר מעל ל-1,000,000,000 דפים

נצפים בחודש

http://yoavfarhi.com @yoavf

Monday, September 12, 11

Page 6: WordCamp Jerusalem - Doing it Wrong

Monday, September 12, 11

Page 7: WordCamp Jerusalem - Doing it Wrong

Monday, September 12, 11

Page 8: WordCamp Jerusalem - Doing it Wrong

/me activates WP_DEBUG...Monday, September 12, 11

Page 9: WordCamp Jerusalem - Doing it Wrong

Monday, September 12, 11

Page 10: WordCamp Jerusalem - Doing it Wrong

1. WP_DEBUG

(wsod)

Monday, September 12, 11

Page 11: WordCamp Jerusalem - Doing it Wrong

WP_DEBUG 1/2

• Include notices

• Bypasses some error suppression (ie WPDB )

• Triggers notices for deprecated functions ex:

define('WP_DEBUG', true);

PHP Notice: get_links is deprecated since version 2.1! Use get_bookmarks() instead. in /Users/yoavfarhi/Sites/trunk/wp-includes/functions.php on line 3409

Monday, September 12, 11

Page 12: WordCamp Jerusalem - Doing it Wrong

WP_DEBUG 2/2

define('WP_DEBUG_DISPLAY', false);

define('WP_DEBUG_LOG', true);

Output to wp-content/debug.log

Don’t display

Monday, September 12, 11

Page 13: WordCamp Jerusalem - Doing it Wrong

2. Function Naming

Monday, September 12, 11

Page 14: WordCamp Jerusalem - Doing it Wrong

Imagine...

Plugin 1function custom_script() { //...}

Theme / Plugin 2function custom_script() { //...}

Monday, September 12, 11

Page 15: WordCamp Jerusalem - Doing it Wrong

Imagine...

Plugin 1function custom_script() { //...}

Theme / Plugin 2function custom_script() { //...}

Fatal Error

Monday, September 12, 11

Page 16: WordCamp Jerusalem - Doing it Wrong

Imagine...

Plugin 1function custom_script() { //...}

Theme / Plugin 2function custom_script() { //...}

Angry Client

Monday, September 12, 11

Page 17: WordCamp Jerusalem - Doing it Wrong

Imagine...

Plugin 1function custom_script() { //...}

Theme / Plugin 2function custom_script() { //...}

Call From Client

Monday, September 12, 11

Page 18: WordCamp Jerusalem - Doing it Wrong

Imagine...

Plugin 1function custom_script() { //...}

Theme / Plugin 2function custom_script() { //...}

Time / Money

Monday, September 12, 11

Page 19: WordCamp Jerusalem - Doing it Wrong

Imagine...

Plugin 1function custom_script() { //...}

Theme / Plugin 2function custom_script() { //...}

We don’t want that!

Monday, September 12, 11

Page 20: WordCamp Jerusalem - Doing it Wrong

Imagine...

Plugin 1function custom_script() { //...}

Theme / Plugin 2function custom_script() { //...}

Solution: Prefix

Monday, September 12, 11

Page 21: WordCamp Jerusalem - Doing it Wrong

Prefix!

Plugin 1function plugin1_custom_script() { //...}

Theme / Plugin 2function themename_custom_script() { //...}

Monday, September 12, 11

Page 22: WordCamp Jerusalem - Doing it Wrong

Prefix!

Plugin 1function plugin1_custom_script() { //...}

Theme / Plugin 2function themename_custom_script() { //...}

Happy!

Monday, September 12, 11

Page 23: WordCamp Jerusalem - Doing it Wrong

Or: Use a Classclass my_plugin {

function custom_script() { //... }

function whatever() { //... }

}

new my_plugin;

Monday, September 12, 11

Page 24: WordCamp Jerusalem - Doing it Wrong

nomy_id AND {$table_prefix}terms.term_id = {$table_prefix}term_taxonomy.term_taxonomy_idonomy.term_id AND {$table_prefix}posts.ID = {$table_prefix}postmetata.post_id AND {$table_prefix}

3. Direct SQL Queries

Monday, September 12, 11

Page 25: WordCamp Jerusalem - Doing it Wrong

$last_posts = (array)$wpdb->get_results(" SELECT post_date, ID, post_title, name, {$table_prefix}terms.term_id FROM {$table_prefix}posts, {$table_prefix}term_relationships, {$table_prefix}terms, {$table_prefix}postmeta, {$table_prefix}term_taxonomy WHERE {$table_prefix}posts.ID = {$table_prefix}term_relationships.object_id AND {$table_prefix}term_taxonomy.term_taxonomy_id = {$table_prefix}term_relationships.term_taxonomy_id AND {$table_prefix}terms.term_id = {$table_prefix}term_taxonomy.term_id AND {$table_prefix}posts.ID = {$table_prefix}postmeta.post_id AND {$table_prefix}postmeta.meta_key = '_mini_post' AND {$table_prefix}postmeta.meta_value = 0 AND post_status = 'publish' AND {$table_prefix}terms.term_id != 25 AND {$table_prefix}terms.term_id != 24 AND {$table_prefix}term_taxonomy.taxonomy = 'category' ");Monday, September 12, 11

Page 26: WordCamp Jerusalem - Doing it Wrong

$last_posts = (array)$wpdb->get_results(" SELECT post_date, ID, post_title, name, {$table_prefix}terms.term_id FROM {$table_prefix}posts, {$table_prefix}term_relationships, {$table_prefix}terms, {$table_prefix}postmeta, {$table_prefix}term_taxonomy WHERE {$table_prefix}posts.ID = {$table_prefix}term_relationships.object_id AND {$table_prefix}term_taxonomy.term_taxonomy_id = {$table_prefix}term_relationships.term_taxonomy_id AND {$table_prefix}terms.term_id = {$table_prefix}term_taxonomy.term_id AND {$table_prefix}posts.ID = {$table_prefix}postmeta.post_id AND {$table_prefix}postmeta.meta_key = '_mini_post' AND {$table_prefix}postmeta.meta_value = 0 AND post_status = 'publish' AND {$table_prefix}terms.term_id != 25 AND {$table_prefix}terms.term_id != 24 AND {$table_prefix}term_taxonomy.taxonomy = 'category' ");

WRONG!

Monday, September 12, 11

Page 27: WordCamp Jerusalem - Doing it Wrong

$args = array( 'post_type' => 'post', 'post_status' => 'publish', 'tax_query' => array( array( 'taxonomy' => 'category', 'terms' => array( '25', '24'), 'field' => 'id', 'operator' => 'NOT IN', ) ), 'meta_query' => array( array( 'key' => '_mini_post', 'value' => 0, ) ));

$last_posts = new WP_Query( $args );

Monday, September 12, 11

Page 28: WordCamp Jerusalem - Doing it Wrong

$args = array( 'post_type' => 'post', 'post_status' => 'publish', 'tax_query' => array( array( 'taxonomy' => 'category', 'terms' => array( '25', '24'), 'field' => 'id', 'operator' => 'NOT IN', ) ), 'meta_query' => array( array( 'key' => '_mini_post', 'value' => 0, ) ));

$last_posts = new WP_Query( $args );

Monday, September 12, 11

Page 29: WordCamp Jerusalem - Doing it Wrong

This is so much better because:

Monday, September 12, 11

Page 30: WordCamp Jerusalem - Doing it Wrong

This is so much better because:

• It is easier to read, easier to change

Monday, September 12, 11

Page 31: WordCamp Jerusalem - Doing it Wrong

This is so much better because:

• It is easier to read, easier to change

• It is more secure

Monday, September 12, 11

Page 32: WordCamp Jerusalem - Doing it Wrong

This is so much better because:

• It is easier to read, easier to change

• It is more secure

• It Uses WP object caching and so faster

Monday, September 12, 11

Page 33: WordCamp Jerusalem - Doing it Wrong

This is so much better because:

• It is easier to read, easier to change

• It is more secure

• It Uses WP object caching and so faster

• It is platform indifferent

Monday, September 12, 11

Page 34: WordCamp Jerusalem - Doing it Wrong

This is so much better because:

• It is easier to read, easier to change

• It is more secure

• It Uses WP object caching and so faster

• It is platform indifferent

• It is future proof

Monday, September 12, 11

Page 35: WordCamp Jerusalem - Doing it Wrong

This is so much better because:

• It is easier to read, easier to change

• It is more secure

• It Uses WP object caching and so faster

• It is platform indifferent

• It is future proof

• It is bound to be improved

Monday, September 12, 11

Page 36: WordCamp Jerusalem - Doing it Wrong

4. Loading JS/CSS/etc

Monday, September 12, 11

Page 37: WordCamp Jerusalem - Doing it Wrong

Javascript

Monday, September 12, 11

Page 40: WordCamp Jerusalem - Doing it Wrong

<script type='text/javascript' src='http://thisismysite.com/wp-content/themes/mytheme/js/newsletter.js'></script>

Wrong!

function mytheme_load_script() { wp_enqueue_script( 'newsletter', 'http://thisismysite.com/wp-content/themes/mytheme/js/newsletter.js', array( 'jquery' ), '0.1' ); }

add_action( 'wp_enqueue_scripts', 'mytheme_load_script');

Javascript

Monday, September 12, 11

Page 41: WordCamp Jerusalem - Doing it Wrong

<script type='text/javascript' src='http://thisismysite.com/wp-content/themes/mytheme/js/newsletter.js'></script>

Wrong!

function mytheme_load_script() { wp_enqueue_script( 'newsletter', 'http://thisismysite.com/wp-content/themes/mytheme/js/newsletter.js', array( 'jquery' ), '0.1' ); }

add_action( 'wp_enqueue_scripts', 'mytheme_load_script');

Ok, but what if ...

Javascript

Monday, September 12, 11

Page 43: WordCamp Jerusalem - Doing it Wrong

Wrong!

Right!

Javascript

<script type='text/javascript' src='http://thisismysite.com/wp-content/themes/mytheme/js/newsletter.js'></script>

function mytheme_load_script() { wp_enqueue_script( 'newsletter', get_template_directory_uri() . '/js/newsletter.js', array( 'jquery' ), '0.1' ); }

add_action( 'wp_enqueue_scripts', 'mytheme_load_script');

Monday, September 12, 11

Page 44: WordCamp Jerusalem - Doing it Wrong

Use wp_enqueue_* because:

• DRY - don’t repeat yourself

• You can set dependencies

• And manage versions

• And easily move to the footer

• And control where it loads (admin/page/...)

Monday, September 12, 11

Page 45: WordCamp Jerusalem - Doing it Wrong

Never assume a file location

Monday, September 12, 11

Page 46: WordCamp Jerusalem - Doing it Wrong

Never assume a file location

• There’s a function for that:

Monday, September 12, 11

Page 47: WordCamp Jerusalem - Doing it Wrong

Never assume a file location

• There’s a function for that:

site_url()

Monday, September 12, 11

Page 48: WordCamp Jerusalem - Doing it Wrong

Never assume a file location

• There’s a function for that:

site_url()plugins_url()

Monday, September 12, 11

Page 49: WordCamp Jerusalem - Doing it Wrong

Never assume a file location

• There’s a function for that:

site_url()plugins_url()content_url()

Monday, September 12, 11

Page 50: WordCamp Jerusalem - Doing it Wrong

Never assume a file location

• There’s a function for that:

site_url()plugins_url()content_url()get_theme_directory() *

Monday, September 12, 11

Page 51: WordCamp Jerusalem - Doing it Wrong

Never assume a file location

• There’s a function for that:

site_url()plugins_url()content_url()get_theme_directory() *get_theme_directory_uri() *

Monday, September 12, 11

Page 52: WordCamp Jerusalem - Doing it Wrong

Never assume a file location

• There’s a function for that:

site_url()plugins_url()content_url()get_theme_directory() *get_theme_directory_uri() *includes_url()

Monday, September 12, 11

Page 53: WordCamp Jerusalem - Doing it Wrong

Never assume a file location

• There’s a function for that:

site_url()plugins_url()content_url()get_theme_directory() *get_theme_directory_uri() *includes_url()admin_url()

Monday, September 12, 11

Page 54: WordCamp Jerusalem - Doing it Wrong

5. Fetching remote content

Monday, September 12, 11

Page 55: WordCamp Jerusalem - Doing it Wrong

What’s your transport?

file_get_contents() ?CURL ?

fsockopen() ?stream_socket_client() ?

Monday, September 12, 11

Page 56: WordCamp Jerusalem - Doing it Wrong

What’s your transport?

file_get_contents() ?CURL ?

fsockopen() ?stream_socket_client() ?

WRONG!

Monday, September 12, 11

Page 57: WordCamp Jerusalem - Doing it Wrong

Helper functions

//Simple Get$resp = wp_remote_get( 'http://example.com/' );

//Simple Post$args = array( 'body' => 'some data', 'user-agent' => 'your plugin');$resp = wp_remote_post( 'http://example.com', $args );

The WP_Http class

Monday, September 12, 11

Page 58: WordCamp Jerusalem - Doing it Wrong

The WP_Http class

• Cookies

• Headers

• Authentication

• Timeouts

• Etc...

* Add your own caching

Supports

Monday, September 12, 11

Page 59: WordCamp Jerusalem - Doing it Wrong

6. Doing Ajax

Monday, September 12, 11

Page 60: WordCamp Jerusalem - Doing it Wrong

Doing Ajax

Monday, September 12, 11

Page 61: WordCamp Jerusalem - Doing it Wrong

Doing Ajax<script>var ajaxurl = <?php echo plugins_url( 'ajax.php', __FILE__ ); ?>

$('#button').click(function(){ $.post(ajaxurl, function(data) { $('.result').html(data); }); });</script>

front-end:

Monday, September 12, 11

Page 62: WordCamp Jerusalem - Doing it Wrong

Doing Ajax<script>var ajaxurl = <?php echo plugins_url( 'ajax.php', __FILE__ ); ?>

$('#button').click(function(){ $.post(ajaxurl, function(data) { $('.result').html(data); }); });</script>

<?phprequire_once('../../../wp-load.php');//...

front-end:

ajax.php:

Monday, September 12, 11

Page 63: WordCamp Jerusalem - Doing it Wrong

Doing Ajax<script>var ajaxurl = <?php echo plugins_url( 'ajax.php', __FILE__ ); ?>

$('#button').click(function(){ $.post(ajaxurl, function(data) { $('.result').html(data); }); });</script>

<?phprequire_once('../../../wp-load.php');//...

front-end:

ajax.php:WRONG!

Monday, September 12, 11

Page 64: WordCamp Jerusalem - Doing it Wrong

Doing Ajax

Monday, September 12, 11

Page 65: WordCamp Jerusalem - Doing it Wrong

Doing Ajax<script>var ajaxurl = <?php echo admin_url( 'admin-ajax.php'); ?>

$('#button').click(function(){ var data = { action: 'my_action', }; $.post(ajaxurl, function(data) { $('.result').html(data); }); });</script>

front-end:

Monday, September 12, 11

Page 66: WordCamp Jerusalem - Doing it Wrong

Doing Ajax

add_action('wp_ajax_my_action', 'plugin_action_callback');add_action('wp_ajax_nopriv_my_action', 'plugin_action_callback');

function plugin_action_callback() { // do whatever echo $whatever; die();}

<script>var ajaxurl = <?php echo admin_url( 'admin-ajax.php'); ?>

$('#button').click(function(){ var data = { action: 'my_action', }; $.post(ajaxurl, function(data) { $('.result').html(data); }); });</script>

front-end:

php:

Monday, September 12, 11

Page 67: WordCamp Jerusalem - Doing it Wrong

7. Security? What ‘bout it?

http://xkcd.com/327/

Monday, September 12, 11

Page 68: WordCamp Jerusalem - Doing it Wrong

Never trust user input

Monday, September 12, 11

Page 69: WordCamp Jerusalem - Doing it Wrong

Never trust user input

<h1>Search results for: <?php echo $_GET['s']; ?></h1>

1. XSS

http://mysite.com/?s=</h1><script>alert('This Javascript can do anything!');</script>

Monday, September 12, 11

Page 70: WordCamp Jerusalem - Doing it Wrong

Never trust user input

<h1>Search results for: <?php echo $_GET['s']; ?></h1>

1. XSS

http://mysite.com/?s=</h1><script>alert('This Javascript can do anything!');</script>Wrong!

Monday, September 12, 11

Page 71: WordCamp Jerusalem - Doing it Wrong

Never trust user input

<h1>Search results for: <?php echo $_GET['s']; ?></h1>

1. XSS

http://mysite.com/?s=</h1><script>alert('This Javascript can do anything!');</script>Wrong!

<h1>Search results for: <?php echo esc_attr( $_GET['s'] ) ; ?></h1>

get_search_query()

Escape late, escape EVERYTHING

Solution:

Monday, September 12, 11

Page 72: WordCamp Jerusalem - Doing it Wrong

Never trust user input

Monday, September 12, 11

Page 73: WordCamp Jerusalem - Doing it Wrong

Never trust user input2.SQL Injection $wpdb->query( " UPDATE $wpdb->posts SET post_title = ". $POST['title'] ." WHERE ID = 1" );

Monday, September 12, 11

Page 74: WordCamp Jerusalem - Doing it Wrong

Never trust user input2.SQL Injection $wpdb->query( " UPDATE $wpdb->posts SET post_title = ". $POST['title'] ." WHERE ID = 1" );

Wrong!

Monday, September 12, 11

Page 75: WordCamp Jerusalem - Doing it Wrong

Never trust user input2.SQL Injection $wpdb->query( " UPDATE $wpdb->posts SET post_title = ". $POST['title'] ." WHERE ID = 1" );

Wrong!

Solution:• Use APIS ( $wpdb->update, $wpdb->prepare )• Validate data ( whitelist > blacklist )

Monday, September 12, 11

Page 76: WordCamp Jerusalem - Doing it Wrong

Never trust user input

Monday, September 12, 11

Page 77: WordCamp Jerusalem - Doing it Wrong

Never trust user input

3.CSRFAuthorization VS Intention

Monday, September 12, 11

Page 78: WordCamp Jerusalem - Doing it Wrong

Never trust user input

3.CSRFAuthorization VS Intention

Use nonces, not just current_user_can()

wp_create_nonce(), wp_verify_nonce(), check_admin_referer()

Solution:

Monday, September 12, 11

Page 79: WordCamp Jerusalem - Doing it Wrong

8. Trunk?Monday, September 12, 11

Page 80: WordCamp Jerusalem - Doing it Wrong

$ mkdir blog

$ cd blog

$ svn co http://core.svn.wordpress.org/trunk/ .

Mac / Linux

Monday, September 12, 11

Page 81: WordCamp Jerusalem - Doing it Wrong

Windows / Tortoise SVN

Monday, September 12, 11

Page 82: WordCamp Jerusalem - Doing it Wrong

Running on Trunk

No, not for production

Monday, September 12, 11

Page 83: WordCamp Jerusalem - Doing it Wrong

9. Not ContributingMonday, September 12, 11

Page 84: WordCamp Jerusalem - Doing it Wrong

Contributing

Monday, September 12, 11

Page 85: WordCamp Jerusalem - Doing it Wrong

Contributing

• Core patches/testing/documentation

Monday, September 12, 11

Page 86: WordCamp Jerusalem - Doing it Wrong

Contributing

• Core patches/testing/documentation

• Release plugins and themes

Monday, September 12, 11

Page 87: WordCamp Jerusalem - Doing it Wrong

Contributing

• Core patches/testing/documentation

• Release plugins and themes

• Translations and i18n

Monday, September 12, 11

Page 88: WordCamp Jerusalem - Doing it Wrong

Contributing

• Core patches/testing/documentation

• Release plugins and themes

• Translations and i18n

• Forums support

Monday, September 12, 11

Page 89: WordCamp Jerusalem - Doing it Wrong

Contributing

• Core patches/testing/documentation

• Release plugins and themes

• Translations and i18n

• Forums support

• Tip! (or Buy)

Monday, September 12, 11

Page 90: WordCamp Jerusalem - Doing it Wrong

Questions ?Monday, September 12, 11