FS_Plugin_Updater

The NextGEN Gallery FS Plugin Updater class.

Defined (1)

The class is defined in the following location(s).

/freemius/includes/class-fs-plugin-updater.php  
  1. class FS_Plugin_Updater { 
  2.  
  3. /** 
  4. * @var Freemius 
  5. * @since 1.0.4 
  6. */ 
  7. private $_fs; 
  8. /** 
  9. * @var FS_Logger 
  10. * @since 1.0.4 
  11. */ 
  12. private $_logger; 
  13. /** 
  14. * @var object 
  15. * @since 1.1.8.1 
  16. */ 
  17. private $_update_details; 
  18.  
  19. function __construct( Freemius $freemius ) { 
  20. $this->_fs = $freemius; 
  21.  
  22. $this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_' . $freemius->get_slug() . '_updater', WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK ); 
  23.  
  24. $this->_filters(); 
  25.  
  26. /** 
  27. * Initiate required filters. 
  28. * @author Vova Feldman (@svovaf) 
  29. * @since 1.0.4 
  30. */ 
  31. private function _filters() { 
  32. // Override request for plugin information 
  33. add_filter( 'plugins_api', array( &$this, 'plugins_api_filter' ), 10, 3 ); 
  34.  
  35. // WP 3.0+ 
  36. add_filter( 'pre_set_site_transient_update_plugins', array( 
  37. &$this,  
  38. 'pre_set_site_transient_update_plugins_filter' 
  39. ) ); 
  40.  
  41. if ( ! $this->_fs->has_active_valid_license() ) { 
  42. /** 
  43. * If user has the premium plugin's code but do NOT have an active license,  
  44. * encourage him to upgrade by showing that there's a new release, but instead 
  45. * of showing an update link, show upgrade link to the pricing page. 
  46. * @since 1.1.6 
  47. */ 
  48. // WP 2.9+ 
  49. add_action( "after_plugin_row_{$this->_fs->get_plugin_basename()}", array( 
  50. &$this,  
  51. 'catch_plugin_update_row' 
  52. ), 9 ); 
  53. add_action( "after_plugin_row_{$this->_fs->get_plugin_basename()}", array( 
  54. &$this,  
  55. 'edit_and_echo_plugin_update_row' 
  56. ), 11, 2 ); 
  57.  
  58. if ( ! WP_FS__IS_PRODUCTION_MODE ) { 
  59. add_filter( 'http_request_host_is_external', array( 
  60. $this,  
  61. 'http_request_host_is_external_filter' 
  62. ), 10, 3 ); 
  63.  
  64. /** 
  65. * Capture plugin update row by turning output buffering. 
  66. * @author Vova Feldman (@svovaf) 
  67. * @since 1.1.6 
  68. */ 
  69. function catch_plugin_update_row() { 
  70. ob_start(); 
  71.  
  72. /** 
  73. * Overrides default update message format with "renew your license" message. 
  74. * @author Vova Feldman (@svovaf) 
  75. * @since 1.1.6 
  76. * @param string $file 
  77. * @param array $plugin_data 
  78. */ 
  79. function edit_and_echo_plugin_update_row( $file, $plugin_data ) { 
  80. $plugin_update_row = ob_get_clean(); 
  81.  
  82. $current = get_site_transient( 'update_plugins' ); 
  83. if ( ! isset( $current->response[ $file ] ) ) { 
  84. echo $plugin_update_row; 
  85.  
  86. return; 
  87.  
  88. $r = $current->response[ $file ]; 
  89.  
  90. $plugin_update_row = preg_replace( 
  91. '/(\<div.+>)(.+)(\<a.+\<a.+)\<\/div\>/is',  
  92. '$1 $2 ' . sprintf( 
  93. __fs( 'renew-license-now' ),  
  94. '<a href="' . $this->_fs->pricing_url() . '">', '</a>',  
  95. $r->new_version ) . 
  96. '$4',  
  97. $plugin_update_row 
  98. ); 
  99.  
  100. echo $plugin_update_row; 
  101.  
  102. /** 
  103. * Since WP version 3.6, a new security feature was added that denies access to repository with a local ip. 
  104. * During development mode we want to be able updating plugin versions via our localhost repository. This 
  105. * filter white-list all domains including "api.freemius". 
  106. * @link http://www.emanueletessore.com/wordpress-download-failed-valid-url-provided/ 
  107. * @author Vova Feldman (@svovaf) 
  108. * @since 1.0.4 
  109. * @param bool $allow 
  110. * @param string $host 
  111. * @param string $url 
  112. * @return bool 
  113. */ 
  114. function http_request_host_is_external_filter( $allow, $host, $url ) { 
  115. return ( false !== strpos( $host, 'freemius' ) ) ? true : $allow; 
  116.  
  117. /** 
  118. * Check for Updates at the defined API endpoint and modify the update array. 
  119. * This function dives into the update api just when WordPress creates its update array,  
  120. * then adds a custom API call and injects the custom plugin data retrieved from the API. 
  121. * It is reassembled from parts of the native WordPress plugin update code. 
  122. * See wp-includes/update.php line 121 for the original wp_update_plugins() function. 
  123. * @author Vova Feldman (@svovaf) 
  124. * @since 1.0.4 
  125. * @uses FS_Api 
  126. * @param stdClass $transient_data Update array build by WordPress. 
  127. * @return array Modified update array with custom plugin data. 
  128. */ 
  129. function pre_set_site_transient_update_plugins_filter( $transient_data ) { 
  130. $this->_logger->entrance(); 
  131.  
  132. if ( empty( $transient_data ) || 
  133. defined( 'WP_FS__UNINSTALL_MODE' ) 
  134. ) { 
  135. return $transient_data; 
  136.  
  137. if ( ! isset( $this->_update_details ) ) { 
  138. // Get plugin's newest update. 
  139. $new_version = $this->_fs->get_update( false, false ); 
  140.  
  141. $this->_update_details = false; 
  142.  
  143. if ( is_object( $new_version ) ) { 
  144. $this->_logger->log( 'Found newer plugin version ' . $new_version->version ); 
  145.  
  146. $plugin_details = new stdClass(); 
  147. $plugin_details->slug = $this->_fs->get_slug(); 
  148. $plugin_details->new_version = $new_version->version; 
  149. $plugin_details->url = WP_FS__ADDRESS; 
  150. $plugin_details->package = $new_version->url; 
  151. $plugin_details->plugin = $this->_fs->get_plugin_basename(); 
  152.  
  153. /** 
  154. * Cache plugin details locally since set_site_transient( 'update_plugins' ) 
  155. * called multiple times and the non wp.org plugins are filtered after the 
  156. * call to .org. 
  157. * @since 1.1.8.1 
  158. */ 
  159. $this->_update_details = $plugin_details; 
  160.  
  161. if ( is_object( $this->_update_details ) ) { 
  162. // Add plugin to transient data. 
  163. $transient_data->response[ $this->_fs->get_plugin_basename() ] = $this->_update_details; 
  164.  
  165. return $transient_data; 
  166.  
  167. /** 
  168. * Try to fetch plugin's info from .org repository. 
  169. * @author Vova Feldman (@svovaf) 
  170. * @since 1.0.5 
  171. * @param string $action 
  172. * @param object $args 
  173. * @return bool|mixed 
  174. */ 
  175. static function _fetch_plugin_info_from_repository( $action, $args ) { 
  176. $url = $http_url = 'http://api.wordpress.org/plugins/info/1.0/'; 
  177. if ( $ssl = wp_http_supports( array( 'ssl' ) ) ) { 
  178. $url = set_url_scheme( $url, 'https' ); 
  179.  
  180. $args = array( 
  181. 'timeout' => 15,  
  182. 'body' => array( 
  183. 'action' => $action,  
  184. 'request' => serialize( $args ) 
  185. ); 
  186.  
  187. $request = wp_remote_post( $url, $args ); 
  188.  
  189. if ( is_wp_error( $request ) ) { 
  190. return false; 
  191.  
  192. $res = maybe_unserialize( wp_remote_retrieve_body( $request ) ); 
  193.  
  194. if ( ! is_object( $res ) && ! is_array( $res ) ) { 
  195. return false; 
  196.  
  197. return $res; 
  198.  
  199. /** 
  200. * Updates information on the "View version x.x details" page with custom data. 
  201. * @author Vova Feldman (@svovaf) 
  202. * @since 1.0.4 
  203. * @uses FS_Api 
  204. * @param object $data 
  205. * @param string $action 
  206. * @param mixed $args 
  207. * @return object 
  208. */ 
  209. function plugins_api_filter( $data, $action = '', $args = null ) { 
  210. $this->_logger->entrance(); 
  211.  
  212. if ( ( 'plugin_information' !== $action ) || 
  213. ! isset( $args->slug ) 
  214. ) { 
  215. return $data; 
  216.  
  217. $addon = false; 
  218. $is_addon = false; 
  219.  
  220. if ( $this->_fs->get_slug() !== $args->slug ) { 
  221. $addon = $this->_fs->get_addon_by_slug( $args->slug ); 
  222.  
  223. if ( ! is_object( $addon ) ) { 
  224. return $data; 
  225.  
  226. $is_addon = true; 
  227.  
  228. $plugin_in_repo = false; 
  229. if ( ! $is_addon ) { 
  230. // Try to fetch info from .org repository. 
  231. $data = self::_fetch_plugin_info_from_repository( $action, $args ); 
  232.  
  233. $plugin_in_repo = ( false !== $data ); 
  234.  
  235. if ( ! $plugin_in_repo ) { 
  236. $data = $args; 
  237.  
  238. // Fetch as much as possible info from local files. 
  239. $plugin_local_data = $this->_fs->get_plugin_data(); 
  240. $data->name = $plugin_local_data['Name']; 
  241. $data->author = $plugin_local_data['Author']; 
  242. $data->sections = array( 
  243. 'description' => 'Upgrade ' . $plugin_local_data['Name'] . ' to latest.',  
  244. ); 
  245.  
  246. // @todo Store extra plugin info on Freemius or parse readme.txt markup. 
  247. /**$info = $this->_fs->get_api_site_scope()->call('/information.json'); 
  248.   
  249. if ( !isset($info->error) ) { 
  250. $data = $info; 
  251. }*/ 
  252.  
  253. // Get plugin's newest update. 
  254. $new_version = $this->_fs->_fetch_latest_version( $is_addon ? $addon->id : false ); 
  255.  
  256. if ( $is_addon ) { 
  257. $data->name = $addon->title . ' ' . __fs( 'addon', $this->_fs->get_slug() ); 
  258. $data->slug = $addon->slug; 
  259. $data->url = WP_FS__ADDRESS; 
  260. $data->package = $new_version->url; 
  261.  
  262. if ( ! $plugin_in_repo ) { 
  263. $data->last_updated = ! is_null( $new_version->updated ) ? $new_version->updated : $new_version->created; 
  264. $data->requires = $new_version->requires_platform_version; 
  265. $data->tested = $new_version->tested_up_to_version; 
  266.  
  267. $data->version = $new_version->version; 
  268. $data->download_link = $new_version->url; 
  269.  
  270. return $data;