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
 
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
 
Rapid Application Development with WSO2 Platform
Rapid Application Development with WSO2 PlatformRapid Application Development with WSO2 Platform
Rapid Application Development with WSO2 PlatformWSO2
 

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
 
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
 
Rapid Application Development with WSO2 Platform
Rapid Application Development with WSO2 PlatformRapid Application Development with WSO2 Platform
Rapid Application Development with WSO2 Platform
 

Recently uploaded

AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesZilliz
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 

Recently uploaded (20)

AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector Databases
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 

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