SlideShare a Scribd company logo
1 of 35
Download to read offline
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 1Byrne Reese
 
Web Projects: From Theory To Practice
Web Projects: From Theory To PracticeWeb Projects: From Theory To Practice
Web Projects: From Theory To PracticeSergey Bolshchikov
 
Mobile HTML, CSS, and JavaScript
Mobile HTML, CSS, and JavaScriptMobile HTML, CSS, and JavaScript
Mobile HTML, CSS, and JavaScriptfranksvalli
 
OSDC 2009 Rails Turtorial
OSDC 2009 Rails TurtorialOSDC 2009 Rails Turtorial
OSDC 2009 Rails TurtorialYi-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 2017Max Pronko
 
WordPress Third Party Authentication
WordPress Third Party AuthenticationWordPress Third Party Authentication
WordPress Third Party AuthenticationAaron Brazell
 
jQuery Presentation to Rails Developers
jQuery Presentation to Rails DevelopersjQuery Presentation to Rails Developers
jQuery Presentation to Rails DevelopersYehuda 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 TouchJames Pearce
 
Devoxx 2014-webComponents
Devoxx 2014-webComponentsDevoxx 2014-webComponents
Devoxx 2014-webComponentsCyril 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 todaygerbille
 
PSD to WordPress
PSD to WordPressPSD to WordPress
PSD to WordPressNile Flores
 
Front End Development: The Important Parts
Front End Development: The Important PartsFront End Development: The Important Parts
Front End Development: The Important PartsSergey 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 OrlandoChris Scott
 
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 JasminePaulo Ragonha
 
Mozilla Web Apps - Super-VanJS
Mozilla Web Apps - Super-VanJSMozilla Web Apps - Super-VanJS
Mozilla Web Apps - Super-VanJSRobert 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ówLaravel 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 WebpackIgnacio 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 AutomationChris 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 WordPressChris 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 PoolChris Jean
 
Plugins at WordCamp Phoenix
Plugins at WordCamp PhoenixPlugins at WordCamp Phoenix
Plugins at WordCamp PhoenixAndrew 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 SoftwareChris Jean
 
How To Rank In Google News
How To Rank In Google NewsHow To Rank In Google News
How To Rank In Google News6S Marketing
 
WordPress Standardized Loop API
WordPress Standardized Loop APIWordPress Standardized Loop API
WordPress Standardized Loop APIChris 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
 
60分鐘完送百萬edm,背後雲端ci/cd實戰大公開
60分鐘完送百萬edm,背後雲端ci/cd實戰大公開60分鐘完送百萬edm,背後雲端ci/cd實戰大公開
60分鐘完送百萬edm,背後雲端ci/cd實戰大公開KAI CHU CHUNG
 
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 FrameworkDirk Haun
 
Optimizing AngularJS Application
Optimizing AngularJS ApplicationOptimizing AngularJS Application
Optimizing AngularJS ApplicationMd. Ziaul Haq
 
Intro To Django
Intro To DjangoIntro To Django
Intro To DjangoUdi Bauman
 
OWASP TOP 10 for PHP Programmers
OWASP TOP 10 for PHP ProgrammersOWASP TOP 10 for PHP Programmers
OWASP TOP 10 for PHP Programmersrjsmelo
 
Introduction to Using PHP & MVC Frameworks
Introduction to Using PHP & MVC FrameworksIntroduction to Using PHP & MVC Frameworks
Introduction to Using PHP & MVC FrameworksGerald Krishnan
 
Creating native apps with WordPress
Creating native apps with WordPressCreating native apps with WordPress
Creating native apps with WordPressMarko Heijnen
 
Desymfony2013.gonzalo123
Desymfony2013.gonzalo123Desymfony2013.gonzalo123
Desymfony2013.gonzalo123Gonzalo Ayuso
 
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 stackJeroen van Dijk
 
Plugin development wpmeetup010
Plugin development wpmeetup010Plugin development wpmeetup010
Plugin development wpmeetup010Barry Kooij
 
The Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressThe Enterprise Wor/d/thy/Press
The Enterprise Wor/d/thy/PressJeroen van Dijk
 
Security and Performance - Italian WordPress Conference
Security and Performance - Italian WordPress ConferenceSecurity and Performance - Italian WordPress Conference
Security and Performance - Italian WordPress ConferenceMaurizio Pelizzone
 
Getting Started with DrupalGap
Getting Started with DrupalGapGetting Started with DrupalGap
Getting Started with DrupalGapAlex 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

Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Evaluating the top large language models.pdf
Evaluating the top large language models.pdfEvaluating the top large language models.pdf
Evaluating the top large language models.pdfChristopherTHyatt
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdflior mazor
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 

Recently uploaded (20)

Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Evaluating the top large language models.pdf
Evaluating the top large language models.pdfEvaluating the top large language models.pdf
Evaluating the top large language models.pdf
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 

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