SlideShare a Scribd company logo
1 of 90
Download to read offline
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 ‫השאר על קוד‬
                          ‫שיוצר מעל‬
               ‫ל-000,000,000,1 דפים‬
                       ‫נצפים בחודש‬



          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
(wsod)




                           1. WP_DEBUG
Monday, September 12, 11
WP_DEBUG 1/2
                                        define('WP_DEBUG', true);


                   • Include notices
                   • Bypasses some error suppression (ie
                           WPDB )
                   • Triggers notices for deprecated functions
                           ex:   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
                           Don’t display
                           define('WP_DEBUG_DISPLAY', false);


                           Output to wp-content/debug.log
                           define('WP_DEBUG_LOG', true);




Monday, September 12, 11
2. Function Naming




Monday, September 12, 11
Imagine...
                           Plugin 1           Theme / Plugin 2
                 function custom_script() {   function custom_script() {
                     //...                        //...
                 }                            }




Monday, September 12, 11
Imagine...
                           Plugin 1                     Theme / Plugin 2
                 function custom_script() {             function custom_script() {
                     //...                                  //...
                 }                                      }




                                          Fatal Error


Monday, September 12, 11
Imagine...
                           Plugin 1                    Theme / Plugin 2
                 function custom_script() {            function custom_script() {
                     //...                                 //...
                 }                                     }




                                        Angry Client


Monday, September 12, 11
Imagine...
                           Plugin 1                 Theme / Plugin 2
                 function custom_script() {         function custom_script() {
                     //...                              //...
                 }                                  }




                                      Call From Client


Monday, September 12, 11
Imagine...
                           Plugin 1                   Theme / Plugin 2
                 function custom_script() {           function custom_script() {
                     //...                                //...
                 }                                    }




                                       Time / Money


Monday, September 12, 11
Imagine...
                           Plugin 1                Theme / Plugin 2
                 function custom_script() {        function custom_script() {
                     //...                             //...
                 }                                 }




                                   We don’t want that!


Monday, September 12, 11
Imagine...
                           Plugin 1                  Theme / Plugin 2
                 function custom_script() {          function custom_script() {
                     //...                               //...
                 }                                   }




                                       Solution: Prefix


Monday, September 12, 11
Prefix!
                           Plugin 1                   Theme / Plugin 2
                 function plugin1_custom_script() {   function themename_custom_script() {
                     //...                                //...
                 }                                    }




Monday, September 12, 11
Prefix!
                           Plugin 1                   Theme / Plugin 2
                 function plugin1_custom_script() {   function themename_custom_script() {
                     //...                                //...
                 }                                    }




                                             Happy!


Monday, September 12, 11
Or: Use a Class
                            class my_plugin {

                                function custom_script() {
                                    //...
                                }

                                function whatever() {
                                    //...
                                }

                            }

                            new my_plugin;




Monday, September 12, 11
AND {$table_prefix}
erms.term_id =
$table_prefix}
erm_taxonomy.term_taxonomy_
donomy.term_id Queries
    3. Direct SQL
        AND {$table_prefix}
osts.ID = {$table_prefix}
ostmetata.post_id
        AND {$table_prefix}
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



                                NG!
        AND {$table_prefix}term_taxonomy.term_taxonomy_id =


                              O
                             R
{$table_prefix}term_relationships.term_taxonomy_id


                           W
        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
$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
Javascript
          <script type='text/javascript' src='http://thisismysite.com/wp-content/
          themes/mytheme/js/newsletter.js'></script>




Monday, September 12, 11
Javascript
          <script type='text/javascript' src='http://thisismysite.com/wp-content/


                                                                             ng!
          themes/mytheme/js/newsletter.js'></script>


                                                                        W ro




Monday, September 12, 11
Javascript
          <script type='text/javascript' src='http://thisismysite.com/wp-content/


                                                                                  ng!
          themes/mytheme/js/newsletter.js'></script>


                                                                             W ro

             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');




Monday, September 12, 11
Javascript
          <script type='text/javascript' src='http://thisismysite.com/wp-content/


                                                                                  ng!
          themes/mytheme/js/newsletter.js'></script>


                                                                             W ro

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



                                                                at i f ...
                 add_action( 'wp_enqueue_scripts', 'mytheme_load_script');


                                                         but wh
                                                    O k,
Monday, September 12, 11
Javascript
          <script type='text/javascript' src='http://thisismysite.com/wp-content/


                                                                             ng!
          themes/mytheme/js/newsletter.js'></script>


                                                                        W ro




Monday, September 12, 11
Javascript
          <script type='text/javascript' src='http://thisismysite.com/wp-content/


                                                                                  ng!
          themes/mytheme/js/newsletter.js'></script>


                                                                             W ro

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




                                                                                 ht!
                 add_action( 'wp_enqueue_scripts', 'mytheme_load_script');


                                                                             Rig

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() ?


                              W RO NG
                                    CURL ?
                                fsockopen() ?
                           stream_socket_client() ?




Monday, September 12, 11
The WP_Http class
                               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 );




Monday, September 12, 11
The WP_Http class
                                     Supports

               • Cookies
               • Headers
               • Authentication
               • Timeouts
               • Etc...
                       * Add your own caching
Monday, September 12, 11
6. Doing Ajax



Monday, September 12, 11
Doing Ajax




Monday, September 12, 11
Doing Ajax
 front-end:                <script>
                           var ajaxurl =   <?php echo plugins_url( 'ajax.php', __FILE__ ); ?>

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




Monday, September 12, 11
Doing Ajax
 front-end:                 <script>
                            var ajaxurl =   <?php echo plugins_url( 'ajax.php', __FILE__ ); ?>

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




ajax.php:                  <?php
                           require_once('../../../wp-load.php');
                           //...




Monday, September 12, 11
Doing Ajax
 front-end:                 <script>
                            var ajaxurl =   <?php echo plugins_url( 'ajax.php', __FILE__ ); ?>

                            $('#button').click(function(){
                                $.post(ajaxurl, function(data) {
                                  $('.result').html(data);




                                           NG!
                                });
                            });




                                        RO
                            </script>




ajax.php:                  <?php
                                      W
                           require_once('../../../wp-load.php');
                           //...




Monday, September 12, 11
Doing Ajax




Monday, September 12, 11
Doing Ajax
 front-end:                <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>




Monday, September 12, 11
Doing Ajax
 front-end:                <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>


php:                       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();
                           }


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
                 1. XSS
                 <h1>Search results for: <?php echo $_GET['s']; ?></h1>
                 http://mysite.com/?s=</h1><script>alert('This Javascript can do anything!');</script>




Monday, September 12, 11
Never trust user input
                 1. XSS
                                                              Wro ng!
                 <h1>Search results for: <?php echo $_GET['s']; ?></h1>
                 http://mysite.com/?s=</h1><script>alert('This Javascript can do anything!');</script>




Monday, September 12, 11
Never trust user input
                 1. XSS
                                                              Wro ng!
                 <h1>Search results for: <?php echo $_GET['s']; ?></h1>
                 http://mysite.com/?s=</h1><script>alert('This Javascript can do anything!');</script>




                                                         get_search_query()

                 Solution:
                 Escape late, escape EVERYTHING
                 <h1>Search results for: <?php echo esc_attr( $_GET['s'] ) ; ?></h1>




Monday, September 12, 11
Never trust user input




Monday, September 12, 11
Never trust user input
                  2.SQL Injection
                           $wpdb->query(
                               " UPDATE $wpdb->posts
                                 SET post_title = ". $POST['title'] ."
                                 WHERE ID = 1"
                           );




Monday, September 12, 11
Never trust user input
                  2.SQL Injection
                           $wpdb->query(


                                        ro ng!
                               " UPDATE $wpdb->posts

                                      W
                                 SET post_title = ". $POST['title'] ."
                                 WHERE ID = 1"
                           );




Monday, September 12, 11
Never trust user input
                  2.SQL Injection
                           $wpdb->query(


                                        ro ng!
                               " UPDATE $wpdb->posts

                                      W
                                 SET post_title = ". $POST['title'] ."
                                 WHERE ID = 1"
                           );




                 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.CSRF
                  Authorization VS Intention




Monday, September 12, 11
Never trust user input
                  3.CSRF
                  Authorization VS Intention




                  Solution:
                  Use nonces, not just current_user_can()

                  wp_create_nonce(), wp_verify_nonce(), check_admin_referer()




Monday, September 12, 11
8. Trunk?
Monday, September 12, 11
Mac / Linux
             $ mkdir blog

             $ cd blog

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




Monday, September 12, 11
Windows / Tortoise SVN




Monday, September 12, 11
Running on Trunk


                              No, not for production




Monday, September 12, 11
9. Not Contributing
Monday, 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

More Related Content

Similar to WordCamp Jerusalem - Doing it Wrong

Symfony War Stories
Symfony War StoriesSymfony War Stories
Symfony War StoriesJakub Zalas
 
Coding For Config: Install Profile Development Using Features
Coding For Config: Install Profile Development Using FeaturesCoding For Config: Install Profile Development Using Features
Coding For Config: Install Profile Development Using FeaturesMyplanet Digital
 
Cloudstack talk
Cloudstack talkCloudstack talk
Cloudstack talkbodepd
 
TripCase Unit Testing with Jasmine
TripCase Unit Testing with JasmineTripCase Unit Testing with Jasmine
TripCase Unit Testing with JasmineStephen Pond
 
Ext JS 4: Advanced Expert Techniques
Ext JS 4: Advanced Expert TechniquesExt JS 4: Advanced Expert Techniques
Ext JS 4: Advanced Expert TechniquesSencha
 
Rcos presentation
Rcos presentationRcos presentation
Rcos presentationmskmoorthy
 
Active Record Introduction - 3
Active Record Introduction - 3Active Record Introduction - 3
Active Record Introduction - 3Blazing Cloud
 
Getting started with ClojureScript
Getting started with ClojureScriptGetting started with ClojureScript
Getting started with ClojureScriptSiva Jagadeesan
 
Coding, Scaling, and Deploys... Oh My!
Coding, Scaling, and Deploys... Oh My!Coding, Scaling, and Deploys... Oh My!
Coding, Scaling, and Deploys... Oh My!Mark Jaquith
 
Introduction to Twig
Introduction to TwigIntroduction to Twig
Introduction to Twigmarkstory
 
OpenDolphin: Enterprise Apps for collaboration on Desktop, Web, and Mobile
OpenDolphin: Enterprise Apps for collaboration on Desktop, Web, and MobileOpenDolphin: Enterprise Apps for collaboration on Desktop, Web, and Mobile
OpenDolphin: Enterprise Apps for collaboration on Desktop, Web, and MobileDierk König
 
Laying the proper foundation for plugin and theme development
Laying the proper foundation for plugin and theme developmentLaying the proper foundation for plugin and theme development
Laying the proper foundation for plugin and theme developmentTammy Hart
 
Ember and containers
Ember and containersEmber and containers
Ember and containersMatthew Beale
 
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry PiGrâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry PiJérémy Derussé
 

Similar to WordCamp Jerusalem - Doing it Wrong (17)

Symfony War Stories
Symfony War StoriesSymfony War Stories
Symfony War Stories
 
Coding For Config: Install Profile Development Using Features
Coding For Config: Install Profile Development Using FeaturesCoding For Config: Install Profile Development Using Features
Coding For Config: Install Profile Development Using Features
 
Cloudstack talk
Cloudstack talkCloudstack talk
Cloudstack talk
 
TripCase Unit Testing with Jasmine
TripCase Unit Testing with JasmineTripCase Unit Testing with Jasmine
TripCase Unit Testing with Jasmine
 
Building Custom PHP Extensions
Building Custom PHP ExtensionsBuilding Custom PHP Extensions
Building Custom PHP Extensions
 
Ext JS 4: Advanced Expert Techniques
Ext JS 4: Advanced Expert TechniquesExt JS 4: Advanced Expert Techniques
Ext JS 4: Advanced Expert Techniques
 
Rcos presentation
Rcos presentationRcos presentation
Rcos presentation
 
Fork cli tool
Fork cli toolFork cli tool
Fork cli tool
 
Active Record Introduction - 3
Active Record Introduction - 3Active Record Introduction - 3
Active Record Introduction - 3
 
DrupalCon jQuery
DrupalCon jQueryDrupalCon jQuery
DrupalCon jQuery
 
Getting started with ClojureScript
Getting started with ClojureScriptGetting started with ClojureScript
Getting started with ClojureScript
 
Coding, Scaling, and Deploys... Oh My!
Coding, Scaling, and Deploys... Oh My!Coding, Scaling, and Deploys... Oh My!
Coding, Scaling, and Deploys... Oh My!
 
Introduction to Twig
Introduction to TwigIntroduction to Twig
Introduction to Twig
 
OpenDolphin: Enterprise Apps for collaboration on Desktop, Web, and Mobile
OpenDolphin: Enterprise Apps for collaboration on Desktop, Web, and MobileOpenDolphin: Enterprise Apps for collaboration on Desktop, Web, and Mobile
OpenDolphin: Enterprise Apps for collaboration on Desktop, Web, and Mobile
 
Laying the proper foundation for plugin and theme development
Laying the proper foundation for plugin and theme developmentLaying the proper foundation for plugin and theme development
Laying the proper foundation for plugin and theme development
 
Ember and containers
Ember and containersEmber and containers
Ember and containers
 
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry PiGrâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
 

More from Yoav Farhi

Your First Gutenberg Block
Your First Gutenberg BlockYour First Gutenberg Block
Your First Gutenberg BlockYoav Farhi
 
[Atelier] Comment traduire un thème (ou une extension) WordPress
[Atelier] Comment traduire un thème (ou une extension) WordPress[Atelier] Comment traduire un thème (ou une extension) WordPress
[Atelier] Comment traduire un thème (ou une extension) WordPressYoav Farhi
 
Gender-fair WordPress: Fixing translation inequality at the core
Gender-fair WordPress: Fixing translation inequality at the coreGender-fair WordPress: Fixing translation inequality at the core
Gender-fair WordPress: Fixing translation inequality at the coreYoav Farhi
 
Right To Left Languages Support – The Right Way
Right To Left Languages Support – The Right WayRight To Left Languages Support – The Right Way
Right To Left Languages Support – The Right WayYoav Farhi
 
Localization: beyond translation
Localization: beyond translationLocalization: beyond translation
Localization: beyond translationYoav Farhi
 
WordPress in NOT English - WordCamp Hamburg 2014
WordPress in NOT English - WordCamp Hamburg 2014WordPress in NOT English - WordCamp Hamburg 2014
WordPress in NOT English - WordCamp Hamburg 2014Yoav Farhi
 
Contributing to WordPress (Hebrew)
Contributing to WordPress (Hebrew)Contributing to WordPress (Hebrew)
Contributing to WordPress (Hebrew)Yoav Farhi
 
WordPress: From Antispambot to Zeroize
WordPress: From Antispambot to ZeroizeWordPress: From Antispambot to Zeroize
WordPress: From Antispambot to ZeroizeYoav Farhi
 
Distributed: Reinventing the Workplace
Distributed: Reinventing the WorkplaceDistributed: Reinventing the Workplace
Distributed: Reinventing the WorkplaceYoav Farhi
 
וורדפרס.קום - אתרי וורדפרס בקלות
וורדפרס.קום - אתרי וורדפרס בקלותוורדפרס.קום - אתרי וורדפרס בקלות
וורדפרס.קום - אתרי וורדפרס בקלותYoav Farhi
 
התוסף הראשון שלי - וורדפרס
התוסף הראשון שלי - וורדפרסהתוסף הראשון שלי - וורדפרס
התוסף הראשון שלי - וורדפרסYoav Farhi
 
WordPress theme translation
WordPress theme translationWordPress theme translation
WordPress theme translationYoav Farhi
 
WordPress RTL
WordPress RTL WordPress RTL
WordPress RTL Yoav Farhi
 
WordPress Developers Israel Meetup #1
WordPress Developers Israel Meetup #1WordPress Developers Israel Meetup #1
WordPress Developers Israel Meetup #1Yoav Farhi
 

More from Yoav Farhi (14)

Your First Gutenberg Block
Your First Gutenberg BlockYour First Gutenberg Block
Your First Gutenberg Block
 
[Atelier] Comment traduire un thème (ou une extension) WordPress
[Atelier] Comment traduire un thème (ou une extension) WordPress[Atelier] Comment traduire un thème (ou une extension) WordPress
[Atelier] Comment traduire un thème (ou une extension) WordPress
 
Gender-fair WordPress: Fixing translation inequality at the core
Gender-fair WordPress: Fixing translation inequality at the coreGender-fair WordPress: Fixing translation inequality at the core
Gender-fair WordPress: Fixing translation inequality at the core
 
Right To Left Languages Support – The Right Way
Right To Left Languages Support – The Right WayRight To Left Languages Support – The Right Way
Right To Left Languages Support – The Right Way
 
Localization: beyond translation
Localization: beyond translationLocalization: beyond translation
Localization: beyond translation
 
WordPress in NOT English - WordCamp Hamburg 2014
WordPress in NOT English - WordCamp Hamburg 2014WordPress in NOT English - WordCamp Hamburg 2014
WordPress in NOT English - WordCamp Hamburg 2014
 
Contributing to WordPress (Hebrew)
Contributing to WordPress (Hebrew)Contributing to WordPress (Hebrew)
Contributing to WordPress (Hebrew)
 
WordPress: From Antispambot to Zeroize
WordPress: From Antispambot to ZeroizeWordPress: From Antispambot to Zeroize
WordPress: From Antispambot to Zeroize
 
Distributed: Reinventing the Workplace
Distributed: Reinventing the WorkplaceDistributed: Reinventing the Workplace
Distributed: Reinventing the Workplace
 
וורדפרס.קום - אתרי וורדפרס בקלות
וורדפרס.קום - אתרי וורדפרס בקלותוורדפרס.קום - אתרי וורדפרס בקלות
וורדפרס.קום - אתרי וורדפרס בקלות
 
התוסף הראשון שלי - וורדפרס
התוסף הראשון שלי - וורדפרסהתוסף הראשון שלי - וורדפרס
התוסף הראשון שלי - וורדפרס
 
WordPress theme translation
WordPress theme translationWordPress theme translation
WordPress theme translation
 
WordPress RTL
WordPress RTL WordPress RTL
WordPress RTL
 
WordPress Developers Israel Meetup #1
WordPress Developers Israel Meetup #1WordPress Developers Israel Meetup #1
WordPress Developers Israel Meetup #1
 

Recently uploaded

presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontologyjohnbeverley2021
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...apidays
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Orbitshub
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...apidays
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Angeliki Cooney
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Bhuvaneswari Subramani
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxRemote DBA Services
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Zilliz
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024The Digital Insurer
 

Recently uploaded (20)

presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 

WordCamp Jerusalem - Doing it Wrong

  • 1. You’re doing it wrong! ‫עשר טעויות נפוצות בפיתוח לוורדפרס‬ Monday, September 12, 11
  • 2. You’re doing it wrong! ‫עשר תשע טעויות נפוצות בפיתוח לוורדפרס‬ Monday, September 12, 11
  • 5. ‫ בחברת‬VIP ‫מפתח‬ Automattic ‫ מפקח בין‬VIP-‫צוות ה‬ WordPress ‫השאר על קוד‬ ‫שיוצר מעל‬ ‫ל-000,000,000,1 דפים‬ ‫נצפים בחודש‬ http://yoavfarhi.com @yoavf Monday, September 12, 11
  • 10. (wsod) 1. WP_DEBUG Monday, September 12, 11
  • 11. WP_DEBUG 1/2 define('WP_DEBUG', true); • Include notices • Bypasses some error suppression (ie WPDB ) • Triggers notices for deprecated functions ex: 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
  • 12. WP_DEBUG 2/2 Don’t display define('WP_DEBUG_DISPLAY', false); Output to wp-content/debug.log define('WP_DEBUG_LOG', true); Monday, September 12, 11
  • 13. 2. Function Naming Monday, September 12, 11
  • 14. Imagine... Plugin 1 Theme / Plugin 2 function custom_script() { function custom_script() { //... //... } } Monday, September 12, 11
  • 15. Imagine... Plugin 1 Theme / Plugin 2 function custom_script() { function custom_script() { //... //... } } Fatal Error Monday, September 12, 11
  • 16. Imagine... Plugin 1 Theme / Plugin 2 function custom_script() { function custom_script() { //... //... } } Angry Client Monday, September 12, 11
  • 17. Imagine... Plugin 1 Theme / Plugin 2 function custom_script() { function custom_script() { //... //... } } Call From Client Monday, September 12, 11
  • 18. Imagine... Plugin 1 Theme / Plugin 2 function custom_script() { function custom_script() { //... //... } } Time / Money Monday, September 12, 11
  • 19. Imagine... Plugin 1 Theme / Plugin 2 function custom_script() { function custom_script() { //... //... } } We don’t want that! Monday, September 12, 11
  • 20. Imagine... Plugin 1 Theme / Plugin 2 function custom_script() { function custom_script() { //... //... } } Solution: Prefix Monday, September 12, 11
  • 21. Prefix! Plugin 1 Theme / Plugin 2 function plugin1_custom_script() { function themename_custom_script() { //... //... } } Monday, September 12, 11
  • 22. Prefix! Plugin 1 Theme / Plugin 2 function plugin1_custom_script() { function themename_custom_script() { //... //... } } Happy! Monday, September 12, 11
  • 23. Or: Use a Class class my_plugin { function custom_script() { //... } function whatever() { //... } } new my_plugin; Monday, September 12, 11
  • 24. AND {$table_prefix} erms.term_id = $table_prefix} erm_taxonomy.term_taxonomy_ donomy.term_id Queries 3. Direct SQL AND {$table_prefix} osts.ID = {$table_prefix} ostmetata.post_id AND {$table_prefix} Monday, September 12, 11
  • 25. $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
  • 26. $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 NG! AND {$table_prefix}term_taxonomy.term_taxonomy_id = O R {$table_prefix}term_relationships.term_taxonomy_id W 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
  • 27. $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
  • 28. $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
  • 29. This is so much better because: Monday, September 12, 11
  • 30. This is so much better because: • It is easier to read, easier to change Monday, September 12, 11
  • 31. This is so much better because: • It is easier to read, easier to change • It is more secure Monday, September 12, 11
  • 32. 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
  • 33. 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
  • 34. 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
  • 35. 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
  • 36. 4. Loading JS/CSS/etc Monday, September 12, 11
  • 38. Javascript <script type='text/javascript' src='http://thisismysite.com/wp-content/ themes/mytheme/js/newsletter.js'></script> Monday, September 12, 11
  • 39. Javascript <script type='text/javascript' src='http://thisismysite.com/wp-content/ ng! themes/mytheme/js/newsletter.js'></script> W ro Monday, September 12, 11
  • 40. Javascript <script type='text/javascript' src='http://thisismysite.com/wp-content/ ng! themes/mytheme/js/newsletter.js'></script> W ro 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'); Monday, September 12, 11
  • 41. Javascript <script type='text/javascript' src='http://thisismysite.com/wp-content/ ng! themes/mytheme/js/newsletter.js'></script> W ro function mytheme_load_script() { wp_enqueue_script( 'newsletter', 'http://thisismysite.com/wp-content/ themes/mytheme/js/newsletter.js', array( 'jquery' ), '0.1' ); } at i f ... add_action( 'wp_enqueue_scripts', 'mytheme_load_script'); but wh O k, Monday, September 12, 11
  • 42. Javascript <script type='text/javascript' src='http://thisismysite.com/wp-content/ ng! themes/mytheme/js/newsletter.js'></script> W ro Monday, September 12, 11
  • 43. Javascript <script type='text/javascript' src='http://thisismysite.com/wp-content/ ng! themes/mytheme/js/newsletter.js'></script> W ro function mytheme_load_script() { wp_enqueue_script( 'newsletter', get_template_directory_uri() . '/js/newsletter.js', array( 'jquery' ), '0.1' ); } ht! add_action( 'wp_enqueue_scripts', 'mytheme_load_script'); Rig Monday, September 12, 11
  • 44. 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
  • 45. Never assume a file location Monday, September 12, 11
  • 46. Never assume a file location • There’s a function for that: Monday, September 12, 11
  • 47. Never assume a file location • There’s a function for that: site_url() Monday, September 12, 11
  • 48. Never assume a file location • There’s a function for that: site_url() plugins_url() Monday, September 12, 11
  • 49. Never assume a file location • There’s a function for that: site_url() plugins_url() content_url() Monday, September 12, 11
  • 50. Never assume a file location • There’s a function for that: site_url() plugins_url() content_url() get_theme_directory() * Monday, September 12, 11
  • 51. 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
  • 52. 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
  • 53. 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
  • 54. 5. Fetching remote content Monday, September 12, 11
  • 55. What’s your transport? file_get_contents() ? CURL ? fsockopen() ? stream_socket_client() ? Monday, September 12, 11
  • 56. What’s your transport? ! file_get_contents() ? W RO NG CURL ? fsockopen() ? stream_socket_client() ? Monday, September 12, 11
  • 57. The WP_Http class 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 ); Monday, September 12, 11
  • 58. The WP_Http class Supports • Cookies • Headers • Authentication • Timeouts • Etc... * Add your own caching Monday, September 12, 11
  • 59. 6. Doing Ajax Monday, September 12, 11
  • 61. Doing Ajax front-end: <script> var ajaxurl = <?php echo plugins_url( 'ajax.php', __FILE__ ); ?> $('#button').click(function(){ $.post(ajaxurl, function(data) { $('.result').html(data); }); }); </script> Monday, September 12, 11
  • 62. Doing Ajax front-end: <script> var ajaxurl = <?php echo plugins_url( 'ajax.php', __FILE__ ); ?> $('#button').click(function(){ $.post(ajaxurl, function(data) { $('.result').html(data); }); }); </script> ajax.php: <?php require_once('../../../wp-load.php'); //... Monday, September 12, 11
  • 63. Doing Ajax front-end: <script> var ajaxurl = <?php echo plugins_url( 'ajax.php', __FILE__ ); ?> $('#button').click(function(){ $.post(ajaxurl, function(data) { $('.result').html(data); NG! }); }); RO </script> ajax.php: <?php W require_once('../../../wp-load.php'); //... Monday, September 12, 11
  • 65. Doing Ajax front-end: <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> Monday, September 12, 11
  • 66. Doing Ajax front-end: <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> php: 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(); } Monday, September 12, 11
  • 67. 7. Security? What ‘bout it? http://xkcd.com/327/ Monday, September 12, 11
  • 68. Never trust user input Monday, September 12, 11
  • 69. Never trust user input 1. XSS <h1>Search results for: <?php echo $_GET['s']; ?></h1> http://mysite.com/?s=</h1><script>alert('This Javascript can do anything!');</script> Monday, September 12, 11
  • 70. Never trust user input 1. XSS Wro ng! <h1>Search results for: <?php echo $_GET['s']; ?></h1> http://mysite.com/?s=</h1><script>alert('This Javascript can do anything!');</script> Monday, September 12, 11
  • 71. Never trust user input 1. XSS Wro ng! <h1>Search results for: <?php echo $_GET['s']; ?></h1> http://mysite.com/?s=</h1><script>alert('This Javascript can do anything!');</script> get_search_query() Solution: Escape late, escape EVERYTHING <h1>Search results for: <?php echo esc_attr( $_GET['s'] ) ; ?></h1> Monday, September 12, 11
  • 72. Never trust user input Monday, September 12, 11
  • 73. Never trust user input 2.SQL Injection $wpdb->query( " UPDATE $wpdb->posts SET post_title = ". $POST['title'] ." WHERE ID = 1" ); Monday, September 12, 11
  • 74. Never trust user input 2.SQL Injection $wpdb->query( ro ng! " UPDATE $wpdb->posts W SET post_title = ". $POST['title'] ." WHERE ID = 1" ); Monday, September 12, 11
  • 75. Never trust user input 2.SQL Injection $wpdb->query( ro ng! " UPDATE $wpdb->posts W SET post_title = ". $POST['title'] ." WHERE ID = 1" ); Solution: • Use APIS ( $wpdb->update, $wpdb->prepare ) • Validate data ( whitelist > blacklist ) Monday, September 12, 11
  • 76. Never trust user input Monday, September 12, 11
  • 77. Never trust user input 3.CSRF Authorization VS Intention Monday, September 12, 11
  • 78. Never trust user input 3.CSRF Authorization VS Intention Solution: Use nonces, not just current_user_can() wp_create_nonce(), wp_verify_nonce(), check_admin_referer() Monday, September 12, 11
  • 80. Mac / Linux $ mkdir blog $ cd blog $ svn co http://core.svn.wordpress.org/trunk/ . Monday, September 12, 11
  • 81. Windows / Tortoise SVN Monday, September 12, 11
  • 82. Running on Trunk No, not for production Monday, September 12, 11
  • 83. 9. Not Contributing Monday, September 12, 11
  • 85. Contributing • Core patches/testing/documentation Monday, September 12, 11
  • 86. Contributing • Core patches/testing/documentation • Release plugins and themes Monday, September 12, 11
  • 87. Contributing • Core patches/testing/documentation • Release plugins and themes • Translations and i18n Monday, September 12, 11
  • 88. Contributing • Core patches/testing/documentation • Release plugins and themes • Translations and i18n • Forums support Monday, September 12, 11
  • 89. Contributing • Core patches/testing/documentation • Release plugins and themes • Translations and i18n • Forums support • Tip! (or Buy) Monday, September 12, 11