Successfully reported this slideshow.
Your SlideShare is downloading. ×

2012.sandiego.wordcamp

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Loading in …3
×

Check these out next

1 of 35 Ad
Advertisement

More Related Content

Slideshows for you (20)

Advertisement

Similar to 2012.sandiego.wordcamp (20)

Recently uploaded (20)

Advertisement

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

×