wordcamp jerusalem - doing it wrong
Post on 08-May-2015
3.758 Views
Preview:
DESCRIPTION
TRANSCRIPT
You’re doing it wrong!עשר טעויות נפוצות בפיתוח לוורדפרס
Monday, September 12, 11
You’re doing it wrong!עשר תשע טעויות נפוצות בפיתוח לוורדפרס
Monday, September 12, 11
Monday, September 12, 11
Monday, September 12, 11
מפתח VIP בחברת Automattic
צוות ה-VIP מפקח בין WordPress השאר על קוד
שיוצר מעל ל-1,000,000,000 דפים
נצפים בחודש
http://yoavfarhi.com @yoavf
Monday, September 12, 11
Monday, September 12, 11
Monday, September 12, 11
/me activates WP_DEBUG...Monday, September 12, 11
Monday, September 12, 11
1. WP_DEBUG
(wsod)
Monday, September 12, 11
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
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
2. Function Naming
Monday, September 12, 11
Imagine...
Plugin 1function custom_script() { //...}
Theme / Plugin 2function custom_script() { //...}
Monday, September 12, 11
Imagine...
Plugin 1function custom_script() { //...}
Theme / Plugin 2function custom_script() { //...}
Fatal Error
Monday, September 12, 11
Imagine...
Plugin 1function custom_script() { //...}
Theme / Plugin 2function custom_script() { //...}
Angry Client
Monday, September 12, 11
Imagine...
Plugin 1function custom_script() { //...}
Theme / Plugin 2function custom_script() { //...}
Call From Client
Monday, September 12, 11
Imagine...
Plugin 1function custom_script() { //...}
Theme / Plugin 2function custom_script() { //...}
Time / Money
Monday, September 12, 11
Imagine...
Plugin 1function custom_script() { //...}
Theme / Plugin 2function custom_script() { //...}
We don’t want that!
Monday, September 12, 11
Imagine...
Plugin 1function custom_script() { //...}
Theme / Plugin 2function custom_script() { //...}
Solution: Prefix
Monday, September 12, 11
Prefix!
Plugin 1function plugin1_custom_script() { //...}
Theme / Plugin 2function themename_custom_script() { //...}
Monday, September 12, 11
Prefix!
Plugin 1function plugin1_custom_script() { //...}
Theme / Plugin 2function themename_custom_script() { //...}
Happy!
Monday, September 12, 11
Or: Use a Classclass my_plugin {
function custom_script() { //... }
function whatever() { //... }
}
new my_plugin;
Monday, September 12, 11
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
$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
$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
$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
$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
This is so much better because:
Monday, September 12, 11
This is so much better because:
• It is easier to read, easier to change
Monday, September 12, 11
This is so much better because:
• It is easier to read, easier to change
• It is more secure
Monday, September 12, 11
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
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
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
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
4. Loading JS/CSS/etc
Monday, September 12, 11
Javascript
Monday, September 12, 11
<script type='text/javascript' src='http://thisismysite.com/wp-content/themes/mytheme/js/newsletter.js'></script>
Javascript
Monday, September 12, 11
<script type='text/javascript' src='http://thisismysite.com/wp-content/themes/mytheme/js/newsletter.js'></script>
Wrong!
Javascript
Monday, September 12, 11
<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
<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
Wrong!
Javascript
<script type='text/javascript' src='http://thisismysite.com/wp-content/themes/mytheme/js/newsletter.js'></script>
Monday, September 12, 11
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
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
Never assume a file location
Monday, September 12, 11
Never assume a file location
• There’s a function for that:
Monday, September 12, 11
Never assume a file location
• There’s a function for that:
site_url()
Monday, September 12, 11
Never assume a file location
• There’s a function for that:
site_url()plugins_url()
Monday, September 12, 11
Never assume a file location
• There’s a function for that:
site_url()plugins_url()content_url()
Monday, September 12, 11
Never assume a file location
• There’s a function for that:
site_url()plugins_url()content_url()get_theme_directory() *
Monday, September 12, 11
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
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
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
5. Fetching remote content
Monday, September 12, 11
What’s your transport?
file_get_contents() ?CURL ?
fsockopen() ?stream_socket_client() ?
Monday, September 12, 11
What’s your transport?
file_get_contents() ?CURL ?
fsockopen() ?stream_socket_client() ?
WRONG!
Monday, September 12, 11
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
The WP_Http class
• Cookies
• Headers
• Authentication
• Timeouts
• Etc...
* Add your own caching
Supports
Monday, September 12, 11
6. Doing Ajax
Monday, September 12, 11
Doing Ajax
Monday, September 12, 11
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
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
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
Doing Ajax
Monday, September 12, 11
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
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
7. Security? What ‘bout it?
http://xkcd.com/327/
Monday, September 12, 11
Never trust user input
Monday, September 12, 11
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
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
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
Never trust user input
Monday, September 12, 11
Never trust user input2.SQL Injection $wpdb->query( " UPDATE $wpdb->posts SET post_title = ". $POST['title'] ." WHERE ID = 1" );
Monday, September 12, 11
Never trust user input2.SQL Injection $wpdb->query( " UPDATE $wpdb->posts SET post_title = ". $POST['title'] ." WHERE ID = 1" );
Wrong!
Monday, September 12, 11
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
Never trust user input
Monday, September 12, 11
Never trust user input
3.CSRFAuthorization VS Intention
Monday, September 12, 11
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
8. Trunk?Monday, September 12, 11
$ mkdir blog
$ cd blog
$ svn co http://core.svn.wordpress.org/trunk/ .
Mac / Linux
Monday, September 12, 11
Windows / Tortoise SVN
Monday, September 12, 11
Running on Trunk
No, not for production
Monday, September 12, 11
9. Not ContributingMonday, September 12, 11
Contributing
Monday, September 12, 11
Contributing
• Core patches/testing/documentation
Monday, September 12, 11
Contributing
• Core patches/testing/documentation
• Release plugins and themes
Monday, September 12, 11
Contributing
• Core patches/testing/documentation
• Release plugins and themes
• Translations and i18n
Monday, September 12, 11
Contributing
• Core patches/testing/documentation
• Release plugins and themes
• Translations and i18n
• Forums support
Monday, September 12, 11
Contributing
• Core patches/testing/documentation
• Release plugins and themes
• Translations and i18n
• Forums support
• Tip! (or Buy)
Monday, September 12, 11
Questions ?Monday, September 12, 11
top related