SlideShare a Scribd company logo
HOW TO SELL PREMIUM
PLUGINS WHILE STILL
SUPPORTING THE GPL



@BRANDONDOVE OF @PIXEL_JAR   #PREMIUMGPL   2012 · SAN DIEGO · WORDCAMP
HTTP://BDOVE.ME/WCSD2012-SLIDES



@BRANDONDOVE OF @PIXEL_JAR   #PREMIUMGPL   2012 · SAN DIEGO · WORDCAMP
INTRO
‣ WORDPRESS PLUGIN & THEME DEVELOPER FOR PIXEL JAR

‣ WORDCAMP ORANGE COUNTY ORGANIZER

‣ LEAD DEVELOPER OF THE PREMIUM PLUGIN ADSANITY




@BRANDONDOVE OF @PIXEL_JAR           #PREMIUMGPL     2012 · SAN DIEGO · WORDCAMP
WHAT WE’RE GOING TO COVER
‣ ONE DEVELOPER'S SOLUTION TO THIS PROBLEM (MINE)

‣ AUTHENTICATION AGAINST A “MOTHERSHIP” USING XML-RPC

‣ REAL, ACTUAL CODE – YOU'VE BEEN WARNED




@BRANDONDOVE OF @PIXEL_JAR            #PREMIUMGPL       2012 · SAN DIEGO · WORDCAMP
SO, WHAT IS A PREMIUM PLUGIN?


              A PLUGIN THAT
           REQUIRES YOU TO PAY
          FOR ACCESS TO CODE OR
              THE DEVELOPER
@BRANDONDOVE OF @PIXEL_JAR   #PREMIUMGPL   2012 · SAN DIEGO · WORDCAMP
JUST CAUSE YOU PAY FOR SOMETHING...




              PREMIUM DOES NOT
             ALWAYS MEAN BETTER

@BRANDONDOVE OF @PIXEL_JAR   #PREMIUMGPL   2012 · SAN DIEGO · WORDCAMP
BUT WHAT ABOUT THE GPL?



            DON’T ALL WORDPRESS
             PLUGINS HAVE TO BE
               OPEN SOURCE?
@BRANDONDOVE OF @PIXEL_JAR   #PREMIUMGPL   2012 · SAN DIEGO · WORDCAMP
BUT WHAT ABOUT THE GPL?




 <                  INSERT PHILOSOPHICAL
                        DEBATE HERE        >
@BRANDONDOVE OF @PIXEL_JAR   #PREMIUMGPL   2012 · SAN DIEGO · WORDCAMP
BUT WHAT ABOUT THE GPL?




                             YES*
                                            *UNLESS YOU’RE A DIRTBAG
@BRANDONDOVE OF @PIXEL_JAR    #PREMIUMGPL            2012 · SAN DIEGO · WORDCAMP
BUT WHAT ABOUT THE GPL?


           UNDER THE GPL, CODE
          CAN BE REDISTRIBUTED
           AND/OR MODIFIED BY
          ANYONE. END OF STORY.
@BRANDONDOVE OF @PIXEL_JAR   #PREMIUMGPL   2012 · SAN DIEGO · WORDCAMP
MORE THAN ONE WAY TO SKIN A KITTEH
‣ DONATIONWARE

‣ FREEMIUM

‣ PAY ONCE FOR CODE

‣ SUBSCRIBE TO UPDATES & SUPPORT

‣ PROBABLY OTHERS...




                                     HTTP://WHYEVOLUTIONISTRUE.WORDPRESS.COM/2010/05/29/CATURDAY-FELIDS-COOL-CATS/SHAVED-CAT-2/



@BRANDONDOVE OF @PIXEL_JAR         #PREMIUMGPL                                                     2012 · SAN DIEGO · WORDCAMP
SOME ASSUMPTIONS ON MY PART
‣ ENCODING = BAD

‣ YOU RESPECT THE GPL

‣ SUPPORTING USERS IS A FULL TIME JOB

‣ YOU NEED TO MAKE A LIVING




@BRANDONDOVE OF @PIXEL_JAR              #PREMIUMGPL   2012 · SAN DIEGO · WORDCAMP
PREMIUM PLUGINS SHOULDN’T TAKE AWAY YOUR RIGHTS



             ENCODING MAKES IT
             HARD FOR USERS TO
            CUSTOMIZE YOUR CODE
                             YOU ARE USING ACTIONS & FILTERS, RIGHT?



@BRANDONDOVE OF @PIXEL_JAR                 #PREMIUMGPL                 2012 · SAN DIEGO · WORDCAMP
STOPPING PIRACY IS HARD




                                  SOPA & PIPA SUCK
                             HTTP://WWW.MEMBERGUIDE.GPOACCESS.GOV/112/RP/SMITHLAMAR




          JUST ASK LAMAR SMITH
@BRANDONDOVE OF @PIXEL_JAR                    #PREMIUMGPL                             2012 · SAN DIEGO · WORDCAMP
AUTHENTICATION IS EASY

WITH AUTHENTICATION, WE CAN:
  ‣ CHARGE FOR SUPPORT & ACCESS TO UPDATES

  ‣ CHARGE FOR ADD-ONS




@BRANDONDOVE OF @PIXEL_JAR           #PREMIUMGPL   2012 · SAN DIEGO · WORDCAMP
STANDARD PLUGIN WORKFLOW
‣ USER DOWNLOADS THE PLUGIN FROM THE WORDPRESS REPO

‣ USER INSTALLS/ACTIVATES THE PLUGIN

‣ DEVELOPER RELEASES AN UPDATE

‣ USER IS NOTIFIED OF THE UPDATE IN THE WORDPRESS DASHBOARD

‣ USER UPDATES THE PLUGIN




@BRANDONDOVE OF @PIXEL_JAR             #PREMIUMGPL            2012 · SAN DIEGO · WORDCAMP
THE WORKFLOW
‣ CUSTOMER PURCHASES THE PLUGIN

‣ CUSTOMER DOWNLOADS THE PLUGIN FROM DEVELOPER’S SITE

‣ CUSTOMER INSTALLS/ACTIVATES THE PLUGIN

‣ DEVELOPER RELEASES AN UPDATE

‣ CUSTOMER IS NOTIFIED OF THE UPDATE IN THE WORDPRESS DASHBOARD

‣ IF CUSTOMER IS AUTHENTICATED

  ‣ CUSTOMER IS ALLOWED TO UPDATE THE PLUGIN




@BRANDONDOVE OF @PIXEL_JAR            #PREMIUMGPL                 2012 · SAN DIEGO · WORDCAMP
IN PRACTICAL TERMS,
               HOW DO WE DO THAT?

@BRANDONDOVE OF @PIXEL_JAR   #PREMIUMGPL   2012 · SAN DIEGO · WORDCAMP
STEP 1: MAKE A SWEET LOOKIN’ CHART


              Plugin Authentication
                                           2A

                email                                              Mothership
                                      XMLRPC POST

                password


                             Submit
                                                                      auth




                                                        Success!       2B         Oh Noes!


                                                      API Key                   IXR_Error




@BRANDONDOVE OF @PIXEL_JAR              #PREMIUMGPL                                  2012 · SAN DIEGO · WORDCAMP
XML-RPC



              COMMUNICATION
            CHANNEL TO A REMOTE
             SERVER USING XML
@BRANDONDOVE OF @PIXEL_JAR   #PREMIUMGPL   2012 · SAN DIEGO · WORDCAMP
STEP 2A: SUBMIT CREDENTIALS TO THE MOTHERSHIP
                                                                      gist.github.com/f3e2a1cbd7a3a7c693f2

    // check against remote server
    if( !class_exists( 'IXR_Client' ) )
        require_once( ABSPATH.WPINC.'/class-IXR.php' );
    $client = new IXR_Client( 'http://mothership.com/xmlrpc.php' );

    $client_request_args = array(
        'username' => $_POST['U'],
        'password' => $_POST['P'],
        'plugin'    => 'plugin-slug.php',
        'url'       => site_url()
    );

    if ( !$client->query( 'pue.is_user_authorized', $client_request_args ) ) :
        add_action( 'admin_notices', 'oh_noes' );
    else :

        // store the unique api key, and enable auto-updates

    endif;

    // handle the error
    function oh_noes() {
        global $client;
        echo '<div class="error"><p>' . esc_html( $client->message->faultString ) . '</p></div>';
    }




@BRANDONDOVE OF @PIXEL_JAR                       #PREMIUMGPL                                  2012 · SAN DIEGO · WORDCAMP
XML-RPC (PLUGIN)




  if( !class_exists( 'IXR_Client' ) )

      require_once( ABSPATH . WPINC . '/class-IXR.php' );

  $client = new IXR_Client( 'http://mothership.com/xmlrpc.php' );




@BRANDONDOVE OF @PIXEL_JAR     #PREMIUMGPL              2012 · SAN DIEGO · WORDCAMP
XML-RPC (PLUGIN)


                       $client_request_args = array(

                             'username'   => $_POST['u'],

                             'password'   => $_POST['p'],

                             'plugin'     => 'plugin-slug.php',

                             'url'        => site_url()

                       );




@BRANDONDOVE OF @PIXEL_JAR                #PREMIUMGPL             2012 · SAN DIEGO · WORDCAMP
XML-RPC (PLUGIN)



                             $client->query(

                                  'pue.is_user_authorized',

                                  $client_request_args

                             );




@BRANDONDOVE OF @PIXEL_JAR                 #PREMIUMGPL        2012 · SAN DIEGO · WORDCAMP
STEP 2B: HAVE MOTHERSHIP VALIDATE CREDENTIALS
                                                                   github.com/brandondove/plugin-update-engine

    /*
      * Adding XMLRPC methods for the client plugin to call
    /**/
    add_filter( 'xmlrpc_methods', 'custom_xmlrpc_methods' );
    function custom_xmlrpc_methods( $api_methods ) {
         $api_methods['pue.is_user_authorized'] = 'custom_auth';
         return $api_methods;
    }
         function custom_auth( $args = array() ) {

            extract( $args ), EXTR_OVERWRITE );

            if( !$username || !$password || !$plugin || !$url ) :
                return new IXR_Error( 401, "OH NOES! You're doin' it wrong!" );
            endif;

            if( !user_pass_ok( $username, $password ) ) :
                return new IXR_Error( 401, 'Sorry, Username and/or Password is Incorrect' );
            endif;

            require_once( PUENGINE_CORE.'models/pue-authenticated-user.php' );
            $user = new pue_authenticated_user( $username );

            if( !$user->is_authorized( $plugin ) )
                return new IXR_Error( 401, __( "You don't have an active license for this plugin." ) );

            if( !$user->has_available_licenses( $plugin, $url ) )
                return new IXR_Error( 401, __( 'NOT AUTHORIZED! You have used up all of your licenses.' ) );

            return md5( $username.$password.$plugin.$url.PUENGINE_SALT );
        }




@BRANDONDOVE OF @PIXEL_JAR                        #PREMIUMGPL                                  2012 · SAN DIEGO · WORDCAMP
XML-RPC (MOTHERSHIP)



    add_filter( 'xmlrpc_methods', 'custom_xmlrpc_methods' );

    function custom_xmlrpc_methods( $api ) {

         $api['pue.is_user_authorized'] = 'custom_auth';

         return $api;

    }




@BRANDONDOVE OF @PIXEL_JAR      #PREMIUMGPL                2012 · SAN DIEGO · WORDCAMP
XML-RPC (MOTHERSHIP)



extract( $args ), EXTR_OVERWRITE );


// ensure the correct data was submitted
if( !$username || !$password || !$plugin || !$url ) :
     return new IXR_Error( 401, "OH NOES! You're doin' it wrong!" );
endif;




@BRANDONDOVE OF @PIXEL_JAR     #PREMIUMGPL              2012 · SAN DIEGO · WORDCAMP
XML-RPC (MOTHERSHIP)




// ensure the user/pass combo is real
if( !user_pass_ok( $username, $password ) ) :
      return new IXR_Error( 401, 'Username/Password is Incorrect' );
endif;




@BRANDONDOVE OF @PIXEL_JAR     #PREMIUMGPL              2012 · SAN DIEGO · WORDCAMP
XML-RPC (MOTHERSHIP)




require_once( PUENGINE_CORE.'models/pue-authenticated-user.php' );
$user = new pue_authenticated_user( $username );




@BRANDONDOVE OF @PIXEL_JAR   #PREMIUMGPL              2012 · SAN DIEGO · WORDCAMP
XML-RPC (MOTHERSHIP)




if( !$user->is_authorized( $plugin ) )
    return new IXR_Error( 401, __( "No license for this plugin." ) );




 @BRANDONDOVE OF @PIXEL_JAR    #PREMIUMGPL              2012 · SAN DIEGO · WORDCAMP
XML-RPC (MOTHERSHIP)




 if( !$user->has_available_licenses( $plugin, $url ) )
       return new IXR_Error( 401, __( 'No more your licenses.' ) );




@BRANDONDOVE OF @PIXEL_JAR     #PREMIUMGPL              2012 · SAN DIEGO · WORDCAMP
XML-RPC (MOTHERSHIP)



                             return md5(
                              $username . $password .
                              $plugin . $url .
                              PUENGINE_SALT
                             );




@BRANDONDOVE OF @PIXEL_JAR            #PREMIUMGPL       2012 · SAN DIEGO · WORDCAMP
THE PLUGIN IS
                        AUTHENTICATED.

@BRANDONDOVE OF @PIXEL_JAR   #PREMIUMGPL   2012 · SAN DIEGO · WORDCAMP
NEXT STEPS...


                                REPO HOSTING
                “PROFESSIONAL WORDPRESS PLUGIN DEVELOPMENT”
                               PAGES 263-269
                            WRITTEN BY THE AWESOME
                  BRAD WILLIAMS, OZH RICHARD & JUSTIN TADLOCK
                             HTTP://BDOVE.ME/PWPPD



@BRANDONDOVE OF @PIXEL_JAR          #PREMIUMGPL             2012 · SAN DIEGO · WORDCAMP
TWITTER                 WEB


          BRANDONDOVE@PIXELJAR.NET
                                          EMAIL

@BRANDONDOVE OF @PIXEL_JAR             #PREMIUMGPL         2012 · SAN DIEGO · WORDCAMP

More Related Content

What's hot

Hacking Movable Type Training - Day 1
Hacking Movable Type Training - Day 1Hacking Movable Type Training - Day 1
Hacking Movable Type Training - Day 1
Byrne Reese
 
WCLA12 JavaScript
WCLA12 JavaScriptWCLA12 JavaScript
WCLA12 JavaScript
Jeffrey Zinn
 
Web Projects: From Theory To Practice
Web Projects: From Theory To PracticeWeb Projects: From Theory To Practice
Web Projects: From Theory To Practice
Sergey Bolshchikov
 
Mobile HTML, CSS, and JavaScript
Mobile HTML, CSS, and JavaScriptMobile HTML, CSS, and JavaScript
Mobile HTML, CSS, and JavaScript
franksvalli
 
OSDC 2009 Rails Turtorial
OSDC 2009 Rails TurtorialOSDC 2009 Rails Turtorial
OSDC 2009 Rails Turtorial
Yi-Ting Cheng
 
Checkout Customizations in Magento 2 - MageTitansMCR 2017
Checkout Customizations in Magento 2 - MageTitansMCR 2017Checkout Customizations in Magento 2 - MageTitansMCR 2017
Checkout Customizations in Magento 2 - MageTitansMCR 2017
Max Pronko
 
WordPress Third Party Authentication
WordPress Third Party AuthenticationWordPress Third Party Authentication
WordPress Third Party Authentication
Aaron Brazell
 
jQuery Presentation to Rails Developers
jQuery Presentation to Rails DevelopersjQuery Presentation to Rails Developers
jQuery Presentation to Rails Developers
Yehuda Katz
 
Merb jQuery
Merb jQueryMerb jQuery
Merb jQuery
Yehuda Katz
 
Create a mobile web app with Sencha Touch
Create a mobile web app with Sencha TouchCreate a mobile web app with Sencha Touch
Create a mobile web app with Sencha Touch
James Pearce
 
Devoxx 2014-webComponents
Devoxx 2014-webComponentsDevoxx 2014-webComponents
Devoxx 2014-webComponents
Cyril Balit
 
Creating the interfaces of the future with the APIs of today
Creating the interfaces of the future with the APIs of todayCreating the interfaces of the future with the APIs of today
Creating the interfaces of the future with the APIs of today
gerbille
 
PSD to WordPress
PSD to WordPressPSD to WordPress
PSD to WordPress
Nile Flores
 
Front End Development: The Important Parts
Front End Development: The Important PartsFront End Development: The Important Parts
Front End Development: The Important Parts
Sergey Bolshchikov
 
You're Doing it Wrong - WordCamp Orlando
You're Doing it Wrong - WordCamp OrlandoYou're Doing it Wrong - WordCamp Orlando
You're Doing it Wrong - WordCamp Orlando
Chris Scott
 
End-to-end testing with geb
End-to-end testing with gebEnd-to-end testing with geb
End-to-end testing with geb
Jesús L. Domínguez Muriel
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Paulo Ragonha
 
Mozilla Web Apps - Super-VanJS
Mozilla Web Apps - Super-VanJSMozilla Web Apps - Super-VanJS
Mozilla Web Apps - Super-VanJS
Robert Nyman
 
Vue.js - zastosowanie i budowa komponentów
Vue.js - zastosowanie i budowa komponentówVue.js - zastosowanie i budowa komponentów
Vue.js - zastosowanie i budowa komponentów
Laravel Poland MeetUp
 
Keeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and WebpackKeeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and Webpack
Ignacio Martín
 

What's hot (20)

Hacking Movable Type Training - Day 1
Hacking Movable Type Training - Day 1Hacking Movable Type Training - Day 1
Hacking Movable Type Training - Day 1
 
WCLA12 JavaScript
WCLA12 JavaScriptWCLA12 JavaScript
WCLA12 JavaScript
 
Web Projects: From Theory To Practice
Web Projects: From Theory To PracticeWeb Projects: From Theory To Practice
Web Projects: From Theory To Practice
 
Mobile HTML, CSS, and JavaScript
Mobile HTML, CSS, and JavaScriptMobile HTML, CSS, and JavaScript
Mobile HTML, CSS, and JavaScript
 
OSDC 2009 Rails Turtorial
OSDC 2009 Rails TurtorialOSDC 2009 Rails Turtorial
OSDC 2009 Rails Turtorial
 
Checkout Customizations in Magento 2 - MageTitansMCR 2017
Checkout Customizations in Magento 2 - MageTitansMCR 2017Checkout Customizations in Magento 2 - MageTitansMCR 2017
Checkout Customizations in Magento 2 - MageTitansMCR 2017
 
WordPress Third Party Authentication
WordPress Third Party AuthenticationWordPress Third Party Authentication
WordPress Third Party Authentication
 
jQuery Presentation to Rails Developers
jQuery Presentation to Rails DevelopersjQuery Presentation to Rails Developers
jQuery Presentation to Rails Developers
 
Merb jQuery
Merb jQueryMerb jQuery
Merb jQuery
 
Create a mobile web app with Sencha Touch
Create a mobile web app with Sencha TouchCreate a mobile web app with Sencha Touch
Create a mobile web app with Sencha Touch
 
Devoxx 2014-webComponents
Devoxx 2014-webComponentsDevoxx 2014-webComponents
Devoxx 2014-webComponents
 
Creating the interfaces of the future with the APIs of today
Creating the interfaces of the future with the APIs of todayCreating the interfaces of the future with the APIs of today
Creating the interfaces of the future with the APIs of today
 
PSD to WordPress
PSD to WordPressPSD to WordPress
PSD to WordPress
 
Front End Development: The Important Parts
Front End Development: The Important PartsFront End Development: The Important Parts
Front End Development: The Important Parts
 
You're Doing it Wrong - WordCamp Orlando
You're Doing it Wrong - WordCamp OrlandoYou're Doing it Wrong - WordCamp Orlando
You're Doing it Wrong - WordCamp Orlando
 
End-to-end testing with geb
End-to-end testing with gebEnd-to-end testing with geb
End-to-end testing with geb
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
 
Mozilla Web Apps - Super-VanJS
Mozilla Web Apps - Super-VanJSMozilla Web Apps - Super-VanJS
Mozilla Web Apps - Super-VanJS
 
Vue.js - zastosowanie i budowa komponentów
Vue.js - zastosowanie i budowa komponentówVue.js - zastosowanie i budowa komponentów
Vue.js - zastosowanie i budowa komponentów
 
Keeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and WebpackKeeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and Webpack
 

Viewers also liked

Save Time and Money with Automation
Save Time and Money with AutomationSave Time and Money with Automation
Save Time and Money with Automation
Chris Jean
 
How I Learned to Stop Worrying and Backup WordPress
How I Learned to Stop Worrying and Backup WordPressHow I Learned to Stop Worrying and Backup WordPress
How I Learned to Stop Worrying and Backup WordPress
Chris Jean
 
Tolga saglam –Isıtma havalandirma otomasyonun novaproopen scada i̇le gerçekle...
Tolga saglam –Isıtma havalandirma otomasyonun novaproopen scada i̇le gerçekle...Tolga saglam –Isıtma havalandirma otomasyonun novaproopen scada i̇le gerçekle...
Tolga saglam –Isıtma havalandirma otomasyonun novaproopen scada i̇le gerçekle...
Tolga SAĞLAM
 
Don't sh** in the Pool
Don't sh** in the PoolDon't sh** in the Pool
Don't sh** in the Pool
Chris Jean
 
Plugins at WordCamp Phoenix
Plugins at WordCamp PhoenixPlugins at WordCamp Phoenix
Plugins at WordCamp Phoenix
Andrew Ryno
 
Using a Private Git Server for Packaging Software
Using a Private Git Server for Packaging SoftwareUsing a Private Git Server for Packaging Software
Using a Private Git Server for Packaging Software
Chris Jean
 
How To Rank In Google News
How To Rank In Google NewsHow To Rank In Google News
How To Rank In Google News
6S Marketing
 
WordPress Standardized Loop API
WordPress Standardized Loop APIWordPress Standardized Loop API
WordPress Standardized Loop API
Chris Jean
 

Viewers also liked (8)

Save Time and Money with Automation
Save Time and Money with AutomationSave Time and Money with Automation
Save Time and Money with Automation
 
How I Learned to Stop Worrying and Backup WordPress
How I Learned to Stop Worrying and Backup WordPressHow I Learned to Stop Worrying and Backup WordPress
How I Learned to Stop Worrying and Backup WordPress
 
Tolga saglam –Isıtma havalandirma otomasyonun novaproopen scada i̇le gerçekle...
Tolga saglam –Isıtma havalandirma otomasyonun novaproopen scada i̇le gerçekle...Tolga saglam –Isıtma havalandirma otomasyonun novaproopen scada i̇le gerçekle...
Tolga saglam –Isıtma havalandirma otomasyonun novaproopen scada i̇le gerçekle...
 
Don't sh** in the Pool
Don't sh** in the PoolDon't sh** in the Pool
Don't sh** in the Pool
 
Plugins at WordCamp Phoenix
Plugins at WordCamp PhoenixPlugins at WordCamp Phoenix
Plugins at WordCamp Phoenix
 
Using a Private Git Server for Packaging Software
Using a Private Git Server for Packaging SoftwareUsing a Private Git Server for Packaging Software
Using a Private Git Server for Packaging Software
 
How To Rank In Google News
How To Rank In Google NewsHow To Rank In Google News
How To Rank In Google News
 
WordPress Standardized Loop API
WordPress Standardized Loop APIWordPress Standardized Loop API
WordPress Standardized Loop API
 

Similar to 2012.sandiego.wordcamp

Using PHP Functions! (Not those functions, Google Cloud Functions)
Using PHP Functions! (Not those functions, Google Cloud Functions)Using PHP Functions! (Not those functions, Google Cloud Functions)
Using PHP Functions! (Not those functions, Google Cloud Functions)
Chris Tankersley
 
Introduction to angular js
Introduction to angular jsIntroduction to angular js
Introduction to angular js
Marco Vito Moscaritolo
 
60分鐘完送百萬edm,背後雲端ci/cd實戰大公開
60分鐘完送百萬edm,背後雲端ci/cd實戰大公開60分鐘完送百萬edm,背後雲端ci/cd實戰大公開
60分鐘完送百萬edm,背後雲端ci/cd實戰大公開
KAI CHU CHUNG
 
Hexagonal architecture
Hexagonal architectureHexagonal architecture
Hexagonal architecture
Alessandro Minoccheri
 
Using Geeklog as a Web Application Framework
Using Geeklog as a Web Application FrameworkUsing Geeklog as a Web Application Framework
Using Geeklog as a Web Application Framework
Dirk Haun
 
Optimizing AngularJS Application
Optimizing AngularJS ApplicationOptimizing AngularJS Application
Optimizing AngularJS Application
Md. Ziaul Haq
 
Intro To Django
Intro To DjangoIntro To Django
Intro To Django
Udi Bauman
 
Cqrs api v2
Cqrs api v2Cqrs api v2
Cqrs api v2
Brandon Mueller
 
OWASP TOP 10 for PHP Programmers
OWASP TOP 10 for PHP ProgrammersOWASP TOP 10 for PHP Programmers
OWASP TOP 10 for PHP Programmers
rjsmelo
 
Introduction to Using PHP & MVC Frameworks
Introduction to Using PHP & MVC FrameworksIntroduction to Using PHP & MVC Frameworks
Introduction to Using PHP & MVC Frameworks
Gerald Krishnan
 
Creating native apps with WordPress
Creating native apps with WordPressCreating native apps with WordPress
Creating native apps with WordPress
Marko Heijnen
 
Desymfony2013.gonzalo123
Desymfony2013.gonzalo123Desymfony2013.gonzalo123
Desymfony2013.gonzalo123
Gonzalo Ayuso
 
Rebuilding our Foundation
Rebuilding our FoundationRebuilding our Foundation
Rebuilding our Foundation
Jessica Mauerhan
 
Zend Server: Not just a PHP stack
Zend Server: Not just a PHP stackZend Server: Not just a PHP stack
Zend Server: Not just a PHP stack
Jeroen van Dijk
 
Plugin development wpmeetup010
Plugin development wpmeetup010Plugin development wpmeetup010
Plugin development wpmeetup010
Barry Kooij
 
The Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressThe Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/Press
Jeroen van Dijk
 
Security and Performance - Italian WordPress Conference
Security and Performance - Italian WordPress ConferenceSecurity and Performance - Italian WordPress Conference
Security and Performance - Italian WordPress Conference
Maurizio Pelizzone
 
AngularJS Basic Training
AngularJS Basic TrainingAngularJS Basic Training
AngularJS Basic Training
Cornel Stefanache
 
Api Design
Api DesignApi Design
Getting Started with DrupalGap
Getting Started with DrupalGapGetting Started with DrupalGap
Getting Started with DrupalGap
Alex S
 

Similar to 2012.sandiego.wordcamp (20)

Using PHP Functions! (Not those functions, Google Cloud Functions)
Using PHP Functions! (Not those functions, Google Cloud Functions)Using PHP Functions! (Not those functions, Google Cloud Functions)
Using PHP Functions! (Not those functions, Google Cloud Functions)
 
Introduction to angular js
Introduction to angular jsIntroduction to angular js
Introduction to angular js
 
60分鐘完送百萬edm,背後雲端ci/cd實戰大公開
60分鐘完送百萬edm,背後雲端ci/cd實戰大公開60分鐘完送百萬edm,背後雲端ci/cd實戰大公開
60分鐘完送百萬edm,背後雲端ci/cd實戰大公開
 
Hexagonal architecture
Hexagonal architectureHexagonal architecture
Hexagonal architecture
 
Using Geeklog as a Web Application Framework
Using Geeklog as a Web Application FrameworkUsing Geeklog as a Web Application Framework
Using Geeklog as a Web Application Framework
 
Optimizing AngularJS Application
Optimizing AngularJS ApplicationOptimizing AngularJS Application
Optimizing AngularJS Application
 
Intro To Django
Intro To DjangoIntro To Django
Intro To Django
 
Cqrs api v2
Cqrs api v2Cqrs api v2
Cqrs api v2
 
OWASP TOP 10 for PHP Programmers
OWASP TOP 10 for PHP ProgrammersOWASP TOP 10 for PHP Programmers
OWASP TOP 10 for PHP Programmers
 
Introduction to Using PHP & MVC Frameworks
Introduction to Using PHP & MVC FrameworksIntroduction to Using PHP & MVC Frameworks
Introduction to Using PHP & MVC Frameworks
 
Creating native apps with WordPress
Creating native apps with WordPressCreating native apps with WordPress
Creating native apps with WordPress
 
Desymfony2013.gonzalo123
Desymfony2013.gonzalo123Desymfony2013.gonzalo123
Desymfony2013.gonzalo123
 
Rebuilding our Foundation
Rebuilding our FoundationRebuilding our Foundation
Rebuilding our Foundation
 
Zend Server: Not just a PHP stack
Zend Server: Not just a PHP stackZend Server: Not just a PHP stack
Zend Server: Not just a PHP stack
 
Plugin development wpmeetup010
Plugin development wpmeetup010Plugin development wpmeetup010
Plugin development wpmeetup010
 
The Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressThe Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/Press
 
Security and Performance - Italian WordPress Conference
Security and Performance - Italian WordPress ConferenceSecurity and Performance - Italian WordPress Conference
Security and Performance - Italian WordPress Conference
 
AngularJS Basic Training
AngularJS Basic TrainingAngularJS Basic Training
AngularJS Basic Training
 
Api Design
Api DesignApi Design
Api Design
 
Getting Started with DrupalGap
Getting Started with DrupalGapGetting Started with DrupalGap
Getting Started with DrupalGap
 

Recently uploaded

Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
KatiaHIMEUR1
 
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
Neo4j
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6
DianaGray10
 
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Speck&Tech
 
Microsoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdfMicrosoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdf
Uni Systems S.M.S.A.
 
UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5
DianaGray10
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
ControlCase
 
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy SurveyTrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc
 
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
SOFTTECHHUB
 
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
Neo4j
 
Data structures and Algorithms in Python.pdf
Data structures and Algorithms in Python.pdfData structures and Algorithms in Python.pdf
Data structures and Algorithms in Python.pdf
TIPNGVN2
 
Mind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AIMind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AI
Kumud Singh
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
mikeeftimakis1
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
Matthew Sinclair
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
Kari Kakkonen
 
Building RAG with self-deployed Milvus vector database and Snowpark Container...
Building RAG with self-deployed Milvus vector database and Snowpark Container...Building RAG with self-deployed Milvus vector database and Snowpark Container...
Building RAG with self-deployed Milvus vector database and Snowpark Container...
Zilliz
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
Quotidiano Piemontese
 
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to ProductionGenerative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Aggregage
 
Presentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of GermanyPresentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of Germany
innovationoecd
 

Recently uploaded (20)

Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
 
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6
 
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
 
Microsoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdfMicrosoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdf
 
UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
 
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy SurveyTrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy Survey
 
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
 
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
 
Data structures and Algorithms in Python.pdf
Data structures and Algorithms in Python.pdfData structures and Algorithms in Python.pdf
Data structures and Algorithms in Python.pdf
 
Mind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AIMind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AI
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
 
Building RAG with self-deployed Milvus vector database and Snowpark Container...
Building RAG with self-deployed Milvus vector database and Snowpark Container...Building RAG with self-deployed Milvus vector database and Snowpark Container...
Building RAG with self-deployed Milvus vector database and Snowpark Container...
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
 
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to ProductionGenerative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to Production
 
Presentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of GermanyPresentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of Germany
 

2012.sandiego.wordcamp

  • 1. HOW TO SELL PREMIUM PLUGINS WHILE STILL SUPPORTING THE GPL @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 2. HTTP://BDOVE.ME/WCSD2012-SLIDES @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 3. INTRO ‣ WORDPRESS PLUGIN & THEME DEVELOPER FOR PIXEL JAR ‣ WORDCAMP ORANGE COUNTY ORGANIZER ‣ LEAD DEVELOPER OF THE PREMIUM PLUGIN ADSANITY @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 4. WHAT WE’RE GOING TO COVER ‣ ONE DEVELOPER'S SOLUTION TO THIS PROBLEM (MINE) ‣ AUTHENTICATION AGAINST A “MOTHERSHIP” USING XML-RPC ‣ REAL, ACTUAL CODE – YOU'VE BEEN WARNED @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 5. SO, WHAT IS A PREMIUM PLUGIN? A PLUGIN THAT REQUIRES YOU TO PAY FOR ACCESS TO CODE OR THE DEVELOPER @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 6. JUST CAUSE YOU PAY FOR SOMETHING... PREMIUM DOES NOT ALWAYS MEAN BETTER @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 7. BUT WHAT ABOUT THE GPL? DON’T ALL WORDPRESS PLUGINS HAVE TO BE OPEN SOURCE? @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 8. BUT WHAT ABOUT THE GPL? < INSERT PHILOSOPHICAL DEBATE HERE > @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 9. BUT WHAT ABOUT THE GPL? YES* *UNLESS YOU’RE A DIRTBAG @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 10. BUT WHAT ABOUT THE GPL? UNDER THE GPL, CODE CAN BE REDISTRIBUTED AND/OR MODIFIED BY ANYONE. END OF STORY. @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 11. MORE THAN ONE WAY TO SKIN A KITTEH ‣ DONATIONWARE ‣ FREEMIUM ‣ PAY ONCE FOR CODE ‣ SUBSCRIBE TO UPDATES & SUPPORT ‣ PROBABLY OTHERS... HTTP://WHYEVOLUTIONISTRUE.WORDPRESS.COM/2010/05/29/CATURDAY-FELIDS-COOL-CATS/SHAVED-CAT-2/ @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 12. SOME ASSUMPTIONS ON MY PART ‣ ENCODING = BAD ‣ YOU RESPECT THE GPL ‣ SUPPORTING USERS IS A FULL TIME JOB ‣ YOU NEED TO MAKE A LIVING @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 13. PREMIUM PLUGINS SHOULDN’T TAKE AWAY YOUR RIGHTS ENCODING MAKES IT HARD FOR USERS TO CUSTOMIZE YOUR CODE YOU ARE USING ACTIONS & FILTERS, RIGHT? @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 14. STOPPING PIRACY IS HARD SOPA & PIPA SUCK HTTP://WWW.MEMBERGUIDE.GPOACCESS.GOV/112/RP/SMITHLAMAR JUST ASK LAMAR SMITH @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 15. AUTHENTICATION IS EASY WITH AUTHENTICATION, WE CAN: ‣ CHARGE FOR SUPPORT & ACCESS TO UPDATES ‣ CHARGE FOR ADD-ONS @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 16. STANDARD PLUGIN WORKFLOW ‣ USER DOWNLOADS THE PLUGIN FROM THE WORDPRESS REPO ‣ USER INSTALLS/ACTIVATES THE PLUGIN ‣ DEVELOPER RELEASES AN UPDATE ‣ USER IS NOTIFIED OF THE UPDATE IN THE WORDPRESS DASHBOARD ‣ USER UPDATES THE PLUGIN @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 17. THE WORKFLOW ‣ CUSTOMER PURCHASES THE PLUGIN ‣ CUSTOMER DOWNLOADS THE PLUGIN FROM DEVELOPER’S SITE ‣ CUSTOMER INSTALLS/ACTIVATES THE PLUGIN ‣ DEVELOPER RELEASES AN UPDATE ‣ CUSTOMER IS NOTIFIED OF THE UPDATE IN THE WORDPRESS DASHBOARD ‣ IF CUSTOMER IS AUTHENTICATED ‣ CUSTOMER IS ALLOWED TO UPDATE THE PLUGIN @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 18. IN PRACTICAL TERMS, HOW DO WE DO THAT? @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 19. STEP 1: MAKE A SWEET LOOKIN’ CHART Plugin Authentication 2A email Mothership XMLRPC POST password Submit auth Success! 2B Oh Noes! API Key IXR_Error @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 20. XML-RPC COMMUNICATION CHANNEL TO A REMOTE SERVER USING XML @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 21. STEP 2A: SUBMIT CREDENTIALS TO THE MOTHERSHIP gist.github.com/f3e2a1cbd7a3a7c693f2 // check against remote server if( !class_exists( 'IXR_Client' ) ) require_once( ABSPATH.WPINC.'/class-IXR.php' ); $client = new IXR_Client( 'http://mothership.com/xmlrpc.php' ); $client_request_args = array( 'username' => $_POST['U'], 'password' => $_POST['P'], 'plugin' => 'plugin-slug.php', 'url' => site_url() ); if ( !$client->query( 'pue.is_user_authorized', $client_request_args ) ) : add_action( 'admin_notices', 'oh_noes' ); else : // store the unique api key, and enable auto-updates endif; // handle the error function oh_noes() { global $client; echo '<div class="error"><p>' . esc_html( $client->message->faultString ) . '</p></div>'; } @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 22. XML-RPC (PLUGIN) if( !class_exists( 'IXR_Client' ) ) require_once( ABSPATH . WPINC . '/class-IXR.php' ); $client = new IXR_Client( 'http://mothership.com/xmlrpc.php' ); @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 23. XML-RPC (PLUGIN) $client_request_args = array( 'username' => $_POST['u'], 'password' => $_POST['p'], 'plugin' => 'plugin-slug.php', 'url' => site_url() ); @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 24. XML-RPC (PLUGIN) $client->query( 'pue.is_user_authorized', $client_request_args ); @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 25. STEP 2B: HAVE MOTHERSHIP VALIDATE CREDENTIALS github.com/brandondove/plugin-update-engine /* * Adding XMLRPC methods for the client plugin to call /**/ add_filter( 'xmlrpc_methods', 'custom_xmlrpc_methods' ); function custom_xmlrpc_methods( $api_methods ) { $api_methods['pue.is_user_authorized'] = 'custom_auth'; return $api_methods; } function custom_auth( $args = array() ) { extract( $args ), EXTR_OVERWRITE ); if( !$username || !$password || !$plugin || !$url ) : return new IXR_Error( 401, "OH NOES! You're doin' it wrong!" ); endif; if( !user_pass_ok( $username, $password ) ) : return new IXR_Error( 401, 'Sorry, Username and/or Password is Incorrect' ); endif; require_once( PUENGINE_CORE.'models/pue-authenticated-user.php' ); $user = new pue_authenticated_user( $username ); if( !$user->is_authorized( $plugin ) ) return new IXR_Error( 401, __( "You don't have an active license for this plugin." ) ); if( !$user->has_available_licenses( $plugin, $url ) ) return new IXR_Error( 401, __( 'NOT AUTHORIZED! You have used up all of your licenses.' ) ); return md5( $username.$password.$plugin.$url.PUENGINE_SALT ); } @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 26. XML-RPC (MOTHERSHIP) add_filter( 'xmlrpc_methods', 'custom_xmlrpc_methods' ); function custom_xmlrpc_methods( $api ) { $api['pue.is_user_authorized'] = 'custom_auth'; return $api; } @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 27. XML-RPC (MOTHERSHIP) extract( $args ), EXTR_OVERWRITE ); // ensure the correct data was submitted if( !$username || !$password || !$plugin || !$url ) : return new IXR_Error( 401, "OH NOES! You're doin' it wrong!" ); endif; @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 28. XML-RPC (MOTHERSHIP) // ensure the user/pass combo is real if( !user_pass_ok( $username, $password ) ) : return new IXR_Error( 401, 'Username/Password is Incorrect' ); endif; @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 29. XML-RPC (MOTHERSHIP) require_once( PUENGINE_CORE.'models/pue-authenticated-user.php' ); $user = new pue_authenticated_user( $username ); @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 30. XML-RPC (MOTHERSHIP) if( !$user->is_authorized( $plugin ) ) return new IXR_Error( 401, __( "No license for this plugin." ) ); @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 31. XML-RPC (MOTHERSHIP) if( !$user->has_available_licenses( $plugin, $url ) ) return new IXR_Error( 401, __( 'No more your licenses.' ) ); @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 32. XML-RPC (MOTHERSHIP) return md5( $username . $password . $plugin . $url . PUENGINE_SALT ); @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 33. THE PLUGIN IS AUTHENTICATED. @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 34. NEXT STEPS... REPO HOSTING “PROFESSIONAL WORDPRESS PLUGIN DEVELOPMENT” PAGES 263-269 WRITTEN BY THE AWESOME BRAD WILLIAMS, OZH RICHARD & JUSTIN TADLOCK HTTP://BDOVE.ME/PWPPD @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP
  • 35. TWITTER WEB BRANDONDOVE@PIXELJAR.NET EMAIL @BRANDONDOVE OF @PIXEL_JAR #PREMIUMGPL 2012 · SAN DIEGO · WORDCAMP