Sviluppare plugin per WordPress: Best Practice e Silver Bullet
-
Upload
luca-bartoli -
Category
Entertainment & Humor
-
view
1.583 -
download
0
description
Transcript of Sviluppare plugin per WordPress: Best Practice e Silver Bullet
WORDCAMP BOLOGNA - 9 FEBBRAIO 2013 @WORDCAMPBOLOGNA # WPCAMPBO13
Sviluppare plugin per WordPress
di LUCA BARTOLI
WORDCAMP BOLOGNA - 9 FEBBRAIO 2013 @WORDCAMPBOLOGNA # WPCAMPBO13
Luca Bartoli
CHI SONO
Web: www.orbitalwaves.it
Twitter: @lucabartoliLinkedIn: lucabartoli00
Sviluppatore e ed esperto SEO, si occupa di web da oltre 10 anni e sviluppa in PHP dal 2004. Attivo soprattutto in ambito B2B, collabora con diverse società per la realizzazione di progetti web che spaziano dai portali istituzionali ai backend aziendali e CRM.
E’ fondatore della neonata Orbital Waves, società che si occupa di strategie e tecnologie per il web.
BIO
PERCHÉ?
WORDCAMP BOLOGNA - 9 FEBBRAIO 2013 @WORDCAMPBOLOGNA # WPCAMPBO13
Mantenere il codice
leggibile
Utilizzare solo le risorse necessarie
Ridurre il numero di bug
Semplificare lo
sviluppo
OOP: OBJECT ORIENTED PLUGINS
WORDCAMP BOLOGNA - 9 FEBBRAIO 2013 @WORDCAMPBOLOGNA # WPCAMPBO13
OOP NELLO SVILUPPO DEI PLUGINS
WORDCAMP BOLOGNA - 9 FEBBRAIO 2013 @WORDCAMPBOLOGNA # WPCAMPBO13
1. <?2. class Mio_Plugin {3. ...4. }
Moltissimi plugin non implementano un modello di programmazione ad oggetti.
Principali problemi della programmazione procedurale:
1. Confusione
2. Alto impatto delle modifiche sul codice
WordPress sta gradualmente riorganizzandotutto il proprio codice in classi.
STRUTTURA TIPO DI UN PLUGIN (1/2)
WORDCAMP BOLOGNA - 9 FEBBRAIO 2013 @WORDCAMPBOLOGNA # WPCAMPBO13
1. <?php2. 3. class Mio_Plugin {4. 5. function __construct() { 6. add_action( 'plugins_loaded', array( $this, 'init' ));7. }8. 9. function init() {10. ...11. }12. 13. function my_function_1(...) {14. ...15. }16. 17. function my_function_2(...) {18. ...19. }20. }21. 22. $mio_plugin = new MioPlugin;
STRUTTURA TIPO DI UN PLUGIN (2/2)
WORDCAMP BOLOGNA - 9 FEBBRAIO 2013 @WORDCAMPBOLOGNA # WPCAMPBO13
L’organizzazione tipica delle cartelle di un plugin ben strutturato divide i files per scopo.
mio-plugin.php contiene solamente il bootstrap del plugin, ed instanzia la classe principale contenuta in core/classes/
STRUTTURA TIPO DI UN PLUGIN: 2 SIMPLE TIPS
WORDCAMP BOLOGNA - 9 FEBBRAIO 2013 @WORDCAMPBOLOGNA # WPCAMPBO13
1. if (!function_exists ('add_action')) {2. header('Status: 403 Forbidden');3. header('HTTP/1.1 403 Forbidden');4. exit();5. }
Evitare le chiamate dirette al plugin, se non ci si trova in ambiente WP:
Evitare conflitti
1. if ( !class_exists( 'MioPlugin' ) ) {2. 3. class MioPlugin {4. ...5. }6. }
CODING STANDARDS
WORDCAMP BOLOGNA - 9 FEBBRAIO 2013 @WORDCAMPBOLOGNA # WPCAMPBO13
CODING STANDARDS: ORGANIZZAZIONE E PULIZIA!
WORDCAMP BOLOGNA - 9 FEBBRAIO 2013 @WORDCAMPBOLOGNA # WPCAMPBO13
1. Applicare i coding standards raccomandati dal Codex
3. Scrivere il codice nell’ordine in cui viene eseguito
4. Documentare il codice
1. /**2. * Documentare il codice con phpDocumentor3. * @link http://manual.phpdoc.org/HTMLSmartyConverter/HandS/ phpDoc4. */
http://codex.wordpress.org/WordPress_Coding_Standards
2. Evitare classi o files troppo lunghi (troppe responsabilità)
ALCUNE RACCOMANDAZIONI
WORDCAMP BOLOGNA - 9 FEBBRAIO 2013 @WORDCAMPBOLOGNA # WPCAMPBO13
WORDCAMP BOLOGNA - 9 FEBBRAIO 2013 @WORDCAMPBOLOGNA # WPCAMPBO13
Utilizzate le funzioni di WordPress!!
UTILIZZARE LE FUNZIONI E GLI OGGETTI DI WORDPRESS
WORDCAMP BOLOGNA - 9 FEBBRAIO 2013 @WORDCAMPBOLOGNA # WPCAMPBO13
Qualche esempio:
1. global $wpdb;2. $myrows = $wpdb->get_results( "SELECT id, name FROM mytable" );
1. wp_remote_request(…) 1. WP_Http::request(…)oppure
1. wp_enqueque_style(…)
1. wp_enqueque_script(…)
Include di script e css:
Retrieve di contenuti esterni senza curl:
Query sul database:
Alcune funzioni utili per i files:
1. wp_handle_upload( $file, $overrides, $time );2. wp_handle_sideload( $file, $overrides, $time );
1. unzip_file( $file, $to );
UTILIZZARE LE FUNZIONI E GLI OGGETTI DI WORDPRESS
WORDCAMP BOLOGNA - 9 FEBBRAIO 2013 @WORDCAMPBOLOGNA # WPCAMPBO13
Una nuova classe per gestire le immagini:1. $image = wp_get_image_editor( 'cool_image.jpg' );2. 3. if ( ! is_wp_error( $image ) ) {4. $image->rotate( 90 );5. $image->resize( 300, 300, true );6. $image->save( 'new_image.jpg' );7. }
http://codex.wordpress.org/Class_Reference/WP_Image_Editor
UTILIZZARE LE FUNZIONI E GLI OGGETTI DI WORDPRESS
WORDCAMP BOLOGNA - 9 FEBBRAIO 2013 @WORDCAMPBOLOGNA # WPCAMPBO13
Argomenti delle funzioni:1. function mia_funzione( $args = array() ) {2. $defaults = array(3. 'first_arg' => true,4. 'second_arg' => 'bar'5. $args = wp_parse_args($args, $defaults);6. ...7. }
1. mia_funzione( array( 'first_arg' => 'foo' ) );2. mia_funzione('first_arg=false');
INTERNAZIONALIZZARE I PROPRI PLUGIN
WORDCAMP BOLOGNA - 9 FEBBRAIO 2013 @WORDCAMPBOLOGNA # WPCAMPBO13
Quando internazionalizzare un plugin?
1. __( $text, $domain );2. _e( $text, $domain );3. _n( $single, $plural, $number, $domain );
http://codex.wordpress.org/I18n_for_WordPress_Developers
1. printf( _n( 'We deleted %d spam message.', 'We deleted %d spam messages.', $count ), $count );
È una buona abitudine, e non comporta lavoro aggiuntivo. È consigliabile anche se non si ha la necessità di avere altre lingue:
Potrebbe servire successivamente o essere implementato da altri
SILVER BULLETS
WORDCAMP BOLOGNA - 9 FEBBRAIO 2013 @WORDCAMPBOLOGNA # WPCAMPBO13
ACTIONS E FILTERS
WORDCAMP BOLOGNA - 9 FEBBRAIO 2013 @WORDCAMPBOLOGNA # WPCAMPBO13
Può essere interessante poter aggiungere o alterare alcuni dati prima dell’output:
1. $myvar = apply_filters( $tag, $value, $param, $otherparam );
http://codex.wordpress.org/Plugin_API
1. $myEmailClass = new emailer();2. add_action('my_action', array($myEmailClass, 'send'));
Ed eseguire particolari azioni ogni volta che si verifica un evento:
1. …2. do_action( 'my_action', $arg );3. …
DEBUG
WORDCAMP BOLOGNA - 9 FEBBRAIO 2013 @WORDCAMPBOLOGNA # WPCAMPBO13
È fondamentale mantenere attivo il debug durante tutto lo sviluppo e accertarsi che non vengano generati errori:
1. define('WP_DEBUG', true);
1. define('WP_DEBUG', false); 2. define('WP_DEBUG_LOG', true);
In produzione disattiviamo il debug e attiviamo il log:
GESTIONE DEGLI ERRORI
WORDCAMP BOLOGNA - 9 FEBBRAIO 2013 @WORDCAMPBOLOGNA # WPCAMPBO13
Possiamo gestire gli errori attraverso la classe WP_Error:
1. $error = new WP_Error( 'Error Code', __( 'My error description', TEXTDOMAIN ) );
http://codex.wordpress.org/Class_Reference/WP_Error
1. if ( isset( $error ) && is_wp_error( $error ))2. wp_die( $error );
Utilizzare wp_die permette anche di ottenere un feedback corretto dai test automatici PHPUnithttp://codex.wordpress.org/User Hakre/WP_Unit-Tests
COMPOSIZIONE DELLE URL
WORDCAMP BOLOGNA - 9 FEBBRAIO 2013 @WORDCAMPBOLOGNA # WPCAMPBO13
Mai comporre url hardcoded:
1. get_bloginfo('url').'wp-content/plugins/nomeplugin/a.php'
1. plugins_url( 'a.php',__FILE__);
Spesso è utile salvare la directory del plugin durante il bootstrap
1. site_url(); 1. home_url();
1. define( 'MY_PLUGIN_DIR', dirname(__FILE__) );
SICUREZZA DEI PLUGINS
WORDCAMP BOLOGNA - 9 FEBBRAIO 2013 @WORDCAMPBOLOGNA # WPCAMPBO13
1. Filter input, escape output
1. current_user_can( $capability, $args );
2. Verificare le capabilities dell’utente
1. <form method="post">2. <!-- some inputs here ... -->3. <?php wp_nonce_field('name_of_my_action','name_of_nonce_field'); ?>4. </form>
3. Usare i nonces per evitare i CSRF
1. if ( empty($_POST) || !wp_verify_nonce($_POST['name_of_nonce_field'],'name_of_my_action') )
1. $sql = $wpdb->prepare( 'query' , value_parameter[, ... ] );
4. Usare wpdb::prepare per evitare SQL Injection
ATTIVAZIONE DISATTIVAZIONE E
RIMOZIONE
WORDCAMP BOLOGNA - 9 FEBBRAIO 2013 @WORDCAMPBOLOGNA # WPCAMPBO13
DISATTIVAZIONE E RIMOZIONE PLUGIN
WORDCAMP BOLOGNA - 9 FEBBRAIO 2013 @WORDCAMPBOLOGNA # WPCAMPBO13
Attivazione del plugin1. register_activation_hook( __FILE__, 'my_activation_hook' );
Impostare e modificare rewrite rules
Impostare ruoli e capabilities
Init del plugin
add_option, custom posts, taxonomies…
Disattivazione del plugin1. register_deactivation_hook( __FILE__, 'my_deactivation_hook' );
Restore e flush rewrite rules
Restore ruoli e capabilitiesNon rimuovere i dati
Rimozione del plugin1. //uninstall.php2. if ( ! defined ( 'WP_UNINSTALL_PLUGIN' ) )3. die();4. delete_option ( 'my_plugin_option' );
Eliminiamo i dati, possibilmente informando l’utente, o chiedendo il consenso
SFRUTTARE LE NOVITÀ DI PHP 5.3
WORDCAMP BOLOGNA - 9 FEBBRAIO 2013 @WORDCAMPBOLOGNA # WPCAMPBO13
CLOSURES
WORDCAMP BOLOGNA - 9 FEBBRAIO 2013 @WORDCAMPBOLOGNA # WPCAMPBO13
Sicuramente le avrete già viste ed utilizzate in javascript, in particolare in framework tipo jQuery
Dalla versione 5.3 è possibile anche in PHP1. add_filter( 'excerpt_length', function() {2. return 50;3. } );
1. $("#target").click(function() {2. alert("Yeeee.");3. });
1. remove_filter( $tag, $function_to_remove, $priority, $accepted_args );
Problemi di prestazioni e …
???
NAMESPACES
WORDCAMP BOLOGNA - 9 FEBBRAIO 2013 @WORDCAMPBOLOGNA # WPCAMPBO13
Esistono molte tecniche per evitare i conflitti di naming.
Dalla versione 5.3 è possibile anche in PHP
1. function myprefix_slider_render( $foo, $bar );2. function myprefix_slider_add_slide ( $slide );
1. //2.php2. require_once('1.php');3. use MyPrefix\Slider as Slider;4. Slider\render();
Da PHP 5.3 possiamo utilizzare i namespaces:
1. Prefixing
1. class myprefix_slider {2. function render( $foo, $bar );3. function add_slide( $slide );4. }
2. Class wrapping
1. //1.php2. namespace MyPrefix\Slider;3. function render() { ... }4. function add_slide( $slide ) { ... }
CLOSURES E NAMESPACES: QUANDO USARLI
WORDCAMP BOLOGNA - 9 FEBBRAIO 2013 @WORDCAMPBOLOGNA # WPCAMPBO13
È importante valutare quando utilizzare funzioni e funzionalità che richiedono PHP 5.3:
GRAZIE PER L’ATTENZIONE,CI SONO DOMANDE?
WORDCAMP BOLOGNA - 9 FEBBRAIO 2013 @WORDCAMPBOLOGNA # WPCAMPBO13
WORDCAMP BOLOGNA - 9 FEBBRAIO 2013 @WORDCAMPBOLOGNA # WPCAMPBO13
Luca Bartoli
LUCA BARTOLI
Web: www.orbitalwaves.it
Twitter: @lucabartoliLinkedIn: lucabartoli00
Sviluppatore e ed esperto SEO, si occupa di web da oltre 10 anni e sviluppa in PHP dal 2004. Attivo soprattutto in ambito B2B, collabora con diverse società per la realizzazione di progetti web che spaziano dai portali istituzionali ai backend aziendali e CRM.
E’ fondatore della neonata Orbital Waves, società che si occupa di strategie e tecnologie per il web.
BIO