KEMBAR78
Best Practices in Plugin Development (WordCamp Seattle) | PDF
Best Practices
for Plugin
Development

                   @nacin
Core Developer, WordPress.org
 Tech Ninja, Audrey Capital
how not to
 write a plugin
ur doin
  it wrong
DEVELOPERS:
Y U NO CODE WELL
lsp_add_scripts()	
  
lsp_add_custom_meta()	
  
lsp_create_html()	
  
lsp_save_meta()	
  
install()	
  

         One of these things
        is not like the others
function	
  nacin_project_func_name()	
  {}	
  
class	
  Nacin_Project	
  {	
  	
  
	
  	
  	
  	
  	
  function	
  __construct()	
  {}	
  
	
  
	
  	
  	
  	
  	
  function	
  init()	
  {}	
  
	
  
	
  	
  	
  	
  	
  function	
  activate()	
  {}	
  
}	
  
class	
  Nacin_Project	
  {	
  
	
  	
  	
  	
  	
  static	
  $instance;	
  
	
  
	
  	
  	
  	
  	
  function	
  __construct()	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  self::$instance	
  =	
  $this;	
  
	
  	
  	
  	
  	
  }	
  
}	
  
new	
  Nacin_Project;	
  
class	
  Nacin_Project	
  {	
  
	
  	
  	
  	
  	
  function	
  __construct()	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  add_action(	
  'init',	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  array(	
  $this,	
  
'init'	
  )	
  );	
  
	
  	
  	
  	
  	
  }	
  
	
  	
  	
  	
  	
  function	
  init()	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  //	
  Add	
  hooks	
  here	
  
	
  	
  	
  	
  	
  }	
  
}	
  
HTTP
Make HTTP requests
cURL example
Let’s fetch a URL:
$ch	
  =	
  curl_init();	
  
curl_setopt($ch,	
  CURLOPT_URL,	
  $url);	
  
curl_setopt($ch,	
  CURLOPT_RETURNTRANSFER,	
  
            true);	
  
curl_setopt($ch,	
  CURLOPT_HEADER,	
  false);	
  
Curl_setopt($ch,	
  CURLOPT_FOLLOWLOCATION,	
  
            true);	
  	
  
$result	
  =	
  curl_exec($ch);	
  
curl_close($ch);	
  
var_dump(	
  
 function_exists(	
  
 	
  	
  'curl_init'	
  )	
  );	
  

                    bool(false)	
  
And what
      about:
§ Cookies   § HTTP Auth
§ Headers   § POST
§ Proxies   § Timeouts
wp_remote_request
(	
  
	
  	
  $url,	
  
	
  	
  $args	
  =	
  array()	
  
);	
  
Pick a card, any card
        cURL
      streams
       fopen
     fsockopen
   HTTP extension
2000 lines of work
already done for you
Helpers
We make it so easy.
Functions designed
    for filters
__return_true();	
  
__return_false();	
  
__return_zero();	
  
__return_empty_array();	
  
Serialization
maybe_serialize();	
  
maybe_unserialize();	
  
is_serialized();	
  
is_serialized_string();	
  
Server helpers
apache_mod_loaded($module);	
  
got_mod_rewrite();	
  
insert_with_markers();	
  
extract_with_markers();	
  
URLs
Bad:     get_option('home');	
  
Better: get_bloginfo('url');	
  
Yes:	
   home_url();	
  
URLs
Bad:     get_option
Better: ('siteurl');	
  
Yes:	
   get_bloginfo
          ('wpurl');	
  
         site_url();	
  
Bad:
ABSPATH.	
  'wp-­‐content/plugins/nacin'	
  
Still bad:
WP_CONTENT_DIR	
  .	
  'plugins/nacin'	
  
Better:
WP_PLUGIN_DIR	
  .	
  '/nacin'	
  
Yes:
dirname(	
  __FILE__	
  )	
  
	
  
Bad:
get_bloginfo('url')	
  
 	
   	
   	
  .	
  'wp-­‐content/plugins/nacin/a.php'	
  
Better:
WP_CONTENT_URL	
  .	
  '/plugins/nacin/a.php'	
  
Yes:
plugins_url(	
  'a.php',	
  __FILE__	
  )	
  
	
  
Default Function Arguments
function	
  myfunc(	
  $args	
  =	
  array()	
  )	
  {	
  
   	
  $defaults	
  =	
  array(	
  
   	
  	
   	
  'first_arg'	
  	
  =>	
  true,	
  
   	
  	
  	
  	
  'second_arg'	
  =>	
  'foo'	
  );	
  
	
  	
  $args	
  =	
  wp_parse_args($args,	
  
       $defaults);	
  
	
  
Even allows for query string calls:	
  
 nacin_my_func(	
  'first_arg=false'	
  );	
  
Post Types      Settings
Taxonomies     Capabilities
  Widgets       Templates
Shortcodes        Query
  Options       i18n/L10n
 Transients   Admin Menus
   Cache       Meta Boxes
    Cron         Multisite
 Formatting      Updates
    HTTP       Filesystem
  Embeds       Admin Bar
Other nifty helpers

   download_url(	
  $target	
  );	
  
  unzip_file(	
  $file,	
  $to	
  );	
  
wp_handle_sideload(	
  $file	
  );	
  
register_activation_hook(	
  
     __FILE__,	
  
     'my_activation_hook');	
  
	
  
Ready your plugin (add_option)
Set and flush rewrite rules
Modify roles/capabilities
register_deactivation_hook(	
  
     __FILE__,	
  
     'my_deactivation_hook');	
  
	
  
Restore and flush rewrite rules
Restore roles/capabilities
But don’t remove your options
Uninstall hook

Clean	
  up	
  after	
  yourself.
uninstall.php
if	
  (!defined
      ('WP_UNINSTALL_PLUGIN'))	
  
  	
  die();	
  
	
  
delete_option('my_plugin_option');	
  
                                             	
  
 There’s also a hook, like activation and
         deactivation, but it has its caveats.
But be considerate
    of my data.
Here’s a secret…



I hate
activation
hooks.
Use the right level
   of the API.
Don’t make any
assumptions. Ever.
Friends don’t let friends use
  direct database queries.
Security.
 Please.
 Please.
 Please.
Authentication
     vs. Intention
  Nonces for CSRF
protection. But check
  capabilities too.
Plugins can
do anything.
Plugins can
do anything.
Be considerate of
 other plugins.
Documentation is nice, but…




                Consult
               the code.
Please…



           Read and
              follow.
          the coding
          standards.
“
         I love the
         feeling
I get from my work
being used by
 30 million .
Benefit from
lessons in
development
and user
experience.
  (Consultants, hint hint.)
I learned more
in 3 months than
I had learned in
 3 years .
@nacin


  Thanks!

Best Practices in Plugin Development (WordCamp Seattle)