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

Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DaySri Ambati
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 

Recently uploaded (20)

Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 

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