YIT_Upgrade

YIT Upgrade.

Defined (1)

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

/plugin-fw/lib/yit-upgrade.php  
  1. class YIT_Upgrade { 
  2.  
  3. /** 
  4. * @var string XML notifier update 
  5. */ 
  6. protected $_xml = 'http://update.yithemes.com/plugins/%plugin_slug%.xml'; 
  7.  
  8. /** 
  9. * @var string api server url 
  10. */ 
  11. protected $_package_url = 'https://yithemes.com'; 
  12.  
  13. /** 
  14. * @var array The registered plugins 
  15. */ 
  16. protected $_plugins = array(); 
  17.  
  18. /** 
  19. * @var YIT_Upgrade The main instance 
  20. */ 
  21. protected static $_instance; 
  22.  
  23. /** 
  24. * Construct 
  25. * @author Andrea Grillo <andrea.grillo@yithemes.com> 
  26. * @since 1.0 
  27. */ 
  28. public function __construct() { 
  29. add_filter( 'upgrader_pre_download', array( $this, 'upgrader_pre_download' ), 10, 3 ); 
  30. add_action( 'update-custom_upgrade-plugin-multisite', array( $this, 'upgrade_plugin_multisite' ) ); 
  31.  
  32. if ( is_network_admin() ) { 
  33. add_action( 'admin_enqueue_scripts', array( $this, 'network_admin_enqueue_scripts' ) ); 
  34.  
  35. $is_debug_enabled = defined( 'YIT_LICENCE_DEBUG' ) && YIT_LICENCE_DEBUG; 
  36. if ( $is_debug_enabled ) { 
  37. $this->_package_url = defined( 'YIT_LICENCE_DEBUG_LOCALHOST' ) ? YIT_LICENCE_DEBUG_LOCALHOST : 'http://dev.yithemes.com'; 
  38. add_filter( 'block_local_requests', '__return_false' ); 
  39.  
  40. /** 
  41. * Main plugin Instance 
  42. * @param $plugin_slug | string The plugin slug 
  43. * @param $plugin_init | string The plugin init file 
  44. * @return void 
  45. * @since 1.0 
  46. * @author Andrea Grillo <andrea.grillo@yithemes.com> 
  47. */ 
  48. public function register( $plugin_slug, $plugin_init ) { 
  49.  
  50. if ( ! function_exists( 'get_plugins' ) ) { 
  51. include_once( ABSPATH . 'wp-admin/includes/plugin.php' ); 
  52.  
  53. $plugins = get_plugins(); 
  54. $plugin_info = $plugins[ $plugin_init ]; 
  55.  
  56. $this->_plugins[ $plugin_init ] = array( 
  57. 'info' => $plugin_info,  
  58. 'slug' => $plugin_slug,  
  59. ); 
  60.  
  61. /** === HOOKS === */ 
  62. if ( ! is_multisite() || is_plugin_active_for_network( $plugin_init ) ) { 
  63. add_action( 'load-plugins.php', array( $this, 'remove_wp_plugin_update_row' ), 25 ); 
  64. add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) ); 
  65. } else if ( is_multisite() && current_user_can( 'update_plugins' ) ) { 
  66. $transient = 'yith_register_' . md5( $plugin_slug ); 
  67. if ( apply_filters( 'yith_register_delete_transient', false ) ) { 
  68. delete_transient( $transient ); 
  69. $info = get_transient( $transient ); 
  70. if ( false === $info || apply_filters( 'yith_register_delete_transient', false ) ) { 
  71. $xml = str_replace( '%plugin_slug%', $plugin_slug, $this->_xml ); 
  72. $remote_xml = wp_remote_get( $xml ); 
  73.  
  74. if ( ! is_wp_error( $remote_xml ) && isset( $remote_xml['response']['code'] ) && '200' == $remote_xml['response']['code'] ) { 
  75. $plugin_remote_info = new SimpleXmlElement( $remote_xml['body'] ); 
  76. $info['Latest'] = (string) $plugin_remote_info->latest; 
  77. $info['changelog'] = (string) $plugin_remote_info->changelog; 
  78. YIT_Plugin_Licence()->check( $plugin_slug, false ); 
  79. set_transient( $transient, $info, DAY_IN_SECONDS ); 
  80.  
  81. $this->_plugins[ $plugin_init ]['info']['Latest'] = $info['Latest']; 
  82. $this->_plugins[ $plugin_init ]['info']['changelog'] = $info['changelog']; 
  83. add_action( 'admin_enqueue_scripts', array( $this, 'multisite_updater_script' ) ); 
  84.  
  85. /** 
  86. * Add the multisite updater scripts 
  87. * @return void 
  88. * @since 1.0 
  89. * @author Andrea Grillo <andrea.grillo@yithemes.com> 
  90. */ 
  91. public function multisite_updater_script() { 
  92.  
  93. $update_url = $changelogs = $details_url = array(); 
  94. $strings = array( 
  95. 'new_version' => __( 'There is a new version of %plugin_name% available.', 'yith-plugin-fw' ),  
  96. 'latest' => __( 'View version %latest% details.', 'yith-plugin-fw' ),  
  97. 'unavailable' => __( 'Automatic update is unavailable for this plugin, ', 'yith-plugin-fw' ),  
  98. 'activate' => __( 'please <a href="%activate_link%">activate</a> your copy of %plugin_name%.', 'yith-plugin-fw' ),  
  99. 'update_now' => __( 'Update now.', 'yith-plugin-fw' ) 
  100.  
  101. ); 
  102.  
  103. foreach ( $this->_plugins as $init => $info ) { 
  104. $update_url[ $init ] = wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin-multisite&plugin=' ) . $init, 'upgrade-plugin-multisite_' . $init ); 
  105. $changelog_id = str_replace( array( '/', '.php', '.' ), array( '-', '', '-' ), $init ); 
  106. $details_url[ $init ] = '#TB_inline' . esc_url( add_query_arg( array( 'width' => 722, 'height' => 914, 'inlineId' => $changelog_id ), '' ) ); 
  107. $plugin_changelog = isset( $this->_plugins[ $init ]['info']['changelog'] ) ? $this->_plugins[ $init ]['info']['changelog'] : ''; 
  108. $changelogs[ $init ] = $this->in_theme_update_message( $this->_plugins[ $init ], $plugin_changelog, $changelog_id, false ); 
  109.  
  110. $localize_script_args = array( 
  111. 'registered' => $this->_plugins,  
  112. 'activated' => YIT_Plugin_Licence()->get_activated_products(),  
  113. 'licence_activation_url' => YIT_Plugin_Licence()->get_licence_activation_page_url(),  
  114. 'update_url' => $update_url,  
  115. 'details_url' => $details_url,  
  116. 'strings' => $strings,  
  117. 'changelogs' => $changelogs 
  118. ); 
  119. $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; 
  120. yit_enqueue_script( 'yit-multisite-updater', YIT_CORE_PLUGIN_URL . '/assets/js/multisite-updater' . $suffix . '.js', array( 'jquery' ), false, true ); 
  121.  
  122. wp_localize_script( 'yit-multisite-updater', 'plugins', $localize_script_args ); 
  123.  
  124. public function network_admin_enqueue_scripts() { 
  125. yit_enqueue_style( 'yit-upgrader', YIT_CORE_PLUGIN_URL . '/assets/css/yit-upgrader.css' ); 
  126.  
  127. /** 
  128. * Retrive the zip package file 
  129. * @param bool $reply Whether to bail without returning the package. Default false. 
  130. * @param string $package The package file name. 
  131. * @param \WP_Upgrader $upgrader WP_Upgrader instance. 
  132. * @return string | The download file 
  133. * @since 1.0 
  134. * @see wp-admin/includes/class-wp-upgrader.php 
  135. * @access public 
  136. * @author Andrea Grillo <andrea.grillo@yithemes.com> 
  137. */ 
  138. public function upgrader_pre_download( $reply, $package, $upgrader ) { 
  139. $plugin = false; 
  140. $is_bulk = $upgrader->skin instanceof Bulk_Plugin_Upgrader_Skin; 
  141.  
  142. if ( ! $is_bulk ) { 
  143. $plugin = isset( $upgrader->skin->plugin ) ? $upgrader->skin->plugin : false; 
  144. } else { 
  145. //Bulk action upgrade 
  146. $action_url = parse_url( $upgrader->skin->options['url'] ); 
  147. parse_str( rawurldecode( htmlspecialchars_decode( $action_url['query'] ) ) ); 
  148. $plugins = explode( ', ', $plugins ); 
  149. foreach ( $plugins as $plugin_init ) { 
  150. $to_upgrade = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin_init ); 
  151. if ( $to_upgrade['Name'] == $upgrader->skin->plugin_info['Name'] ) { 
  152. $plugin = $plugin_init; 
  153.  
  154. /** 
  155. * It isn't YITH Premium plugins, please wordpress update it for me! 
  156. */ 
  157. if ( ! $plugin ) { 
  158. return $reply; 
  159.  
  160. $plugin_info = YIT_Plugin_Licence()->get_product( $plugin ); 
  161.  
  162. /** 
  163. * False ? It isn't YITH Premium plugins, please wordpress update it for me! 
  164. */ 
  165. if ( false === $plugin_info ) { 
  166. return $reply; 
  167.  
  168. $licence = YIT_Plugin_Licence()->get_licence(); 
  169. $product_id = $plugin_info['product_id']; 
  170. $args = array( 
  171. 'email' => $licence[ $product_id ]['email'],  
  172. 'licence_key' => $licence[ $product_id ]['licence_key'],  
  173. 'product_id' => $plugin_info['product_id'],  
  174. 'secret_key' => $plugin_info['secret_key'],  
  175. 'instance' => YIT_Plugin_Licence()->get_home_url(),  
  176. 'wc-api' => 'download-api',  
  177. 'request' => 'download' 
  178. ); 
  179.  
  180. if ( ! preg_match( '!^(http|https|ftp)://!i', $package ) && file_exists( $package ) ) { 
  181. //Local file or remote? 
  182. return $package; 
  183.  
  184. if ( empty( $package ) ) { 
  185. return new WP_Error( 'no_package', $upgrader->strings['no_package'] ); 
  186.  
  187. $upgrader->skin->feedback( 'downloading_package', __( 'YIThemes Repository', 'yith-plugin-fw' ) ); 
  188.  
  189. $download_file = $this->_download_url( $package, $args ); 
  190.  
  191. /** 
  192. * Regenerate update_plugins transient 
  193. */ 
  194. $this->force_regenerate_update_transient(); 
  195.  
  196. if ( is_wp_error( $download_file ) ) { 
  197. return new WP_Error( 'download_failed', $upgrader->strings['download_failed'], $download_file->get_error_message() ); 
  198.  
  199. return $download_file; 
  200.  
  201. /** 
  202. * Retrive the temp filename 
  203. * @param string $url The package url 
  204. * @param string $body The post data fields 
  205. * @param int $timeout Execution timeout (default: 300) 
  206. * @return string | The temp filename 
  207. * @since 1.0 
  208. * @see wp-admin/includes/class-wp-upgrader.php 
  209. * @access protected 
  210. * @author Andrea Grillo <andrea.grillo@yithemes.com> 
  211. */ 
  212. protected function _download_url( $url, $body, $timeout = 300 ) { 
  213.  
  214. //WARNING: The file is not automatically deleted, The script must unlink() the file. 
  215. if ( ! $url ) { 
  216. return new WP_Error( 'http_no_url', __( 'Invalid URL Provided.', 'yit' ) ); 
  217.  
  218. $tmpfname = wp_tempnam( $url ); 
  219.  
  220. $args = array( 
  221. 'timeout' => $timeout,  
  222. 'stream' => true,  
  223. 'filename' => $tmpfname,  
  224. 'body' => $body 
  225. ); 
  226.  
  227. if ( ! $tmpfname ) { 
  228. return new WP_Error( 'http_no_file', __( 'Could not create Temporary file.', 'yit' ) ); 
  229.  
  230. $response = wp_safe_remote_post( $url, $args ); 
  231.  
  232. if ( is_wp_error( $response ) ) { 
  233. unlink( $tmpfname ); 
  234.  
  235. return $response; 
  236.  
  237. if ( 200 != wp_remote_retrieve_response_code( $response ) ) { 
  238. unlink( $tmpfname ); 
  239.  
  240. return new WP_Error( 'http_404', trim( wp_remote_retrieve_response_message( $response ) ) ); 
  241.  
  242. $content_md5 = wp_remote_retrieve_header( $response, 'content-md5' ); 
  243.  
  244. if ( $content_md5 ) { 
  245. $md5_check = verify_file_md5( $tmpfname, $content_md5 ); 
  246. if ( is_wp_error( $md5_check ) ) { 
  247. unlink( $tmpfname ); 
  248.  
  249. return $md5_check; 
  250.  
  251. return $tmpfname; 
  252.  
  253. /** 
  254. * Main plugin Instance 
  255. * @static 
  256. * @return object Main instance 
  257. * @since 1.0 
  258. * @author Andrea Grillo <andrea.grillo@yithemes.com> 
  259. */ 
  260. public static function instance() { 
  261. if ( is_null( self::$_instance ) ) { 
  262. self::$_instance = new self(); 
  263.  
  264. return self::$_instance; 
  265.  
  266. /** 
  267. * Delete the update plugins transient 
  268. * @return void 
  269. * @since 1.0 
  270. * @see update_plugins transient and pre_set_site_transient_update_plugins hooks 
  271. * @author Andrea Grillo <andrea.grillo@yithemes.com> 
  272. */ 
  273. public function force_regenerate_update_transient() { 
  274. delete_site_transient( 'update_plugins' ); 
  275.  
  276. /** 
  277. * Check for plugins update 
  278. * If a new plugin version is available set it in the pre_set_site_transient_update_plugins hooks 
  279. * @param mixed $transient | update_plugins transient value 
  280. * @param bool $save | Default: false. Set true to regenerate the update_transient plugins 
  281. * @return mixed $transient | The new update_plugins transient value 
  282. * @since 1.0 
  283. * @see update_plugins transient and pre_set_site_transient_update_plugins hooks 
  284. * @author Andrea Grillo <andrea.grillo@yithemes.com> 
  285. */ 
  286. public function check_update( $transient, $save = false ) { 
  287.  
  288. foreach ( $this->_plugins as $init => $plugin ) { 
  289. $xml = str_replace( '%plugin_slug%', $this->_plugins[ $init ]['slug'], $this->_xml ); 
  290. $remote_xml = wp_remote_get( $xml ); 
  291.  
  292. if ( ! is_wp_error( $remote_xml ) && isset( $remote_xml['response']['code'] ) && '200' == $remote_xml['response']['code'] ) { 
  293.  
  294. try { 
  295.  
  296. $plugin_remote_info = new SimpleXmlElement( $remote_xml['body'] ); 
  297.  
  298. if ( version_compare( $plugin_remote_info->latest, $plugin['info']['Version'], '>' ) && ! isset( $transient->response[ $init ] ) ) { 
  299.  
  300. $package = YIT_Plugin_Licence()->check( $init ) ? $this->_package_url : null; 
  301.  
  302. $obj = new stdClass(); 
  303. $obj->slug = (string) $init; 
  304. $obj->new_version = (string) $plugin_remote_info->latest; 
  305. $obj->changelog = (string) $plugin_remote_info->changelog; 
  306. $obj->package = $package; 
  307. $obj->plugin = $init; 
  308. $transient->response[ $init ] = $obj; 
  309.  
  310. } catch ( Exception $e ) { 
  311.  
  312. return $transient; 
  313.  
  314.  
  315.  
  316. if ( $save ) { 
  317. set_site_transient( 'update_plugins', $transient ); 
  318.  
  319. return $transient; 
  320.  
  321. /** 
  322. * Add the plugin update row in plugin page 
  323. * @return void 
  324. * @fire "in_theme_update_message-{$init}" action 
  325. * @since 1.0 
  326. * @see after_plugin_row_{$init} action 
  327. * @author Andrea Grillo <andrea.grillo@yithemes.com> 
  328. */ 
  329. public function plugin_update_row() { 
  330.  
  331. $current = get_site_transient( 'update_plugins' ); 
  332. $init = str_replace( 'after_plugin_row_', '', current_filter() ); 
  333.  
  334. if ( ! isset( $current->response[ $init ] ) ) { 
  335. return false; 
  336.  
  337. /** 
  338. * stdClass Object 
  339. */ 
  340. $r = $current->response[ $init ]; 
  341.  
  342. $changelog_id = str_replace( array( '/', '.php', '.' ), array( '-', '', '-' ), $init ); 
  343. $details_url = '#TB_inline' . esc_url( add_query_arg( array( 'width' => 722, 'height' => 914, 'inlineId' => $changelog_id ), '' ) ); 
  344.  
  345. /** 
  346. * @see wp_plugin_update_rows() in wp-single\wp-admin\includes\update.php 
  347. */ 
  348. $wp_list_table = _get_list_table( 'WP_MS_Themes_List_Table' ); 
  349.  
  350. if ( is_network_admin() || ! is_multisite() || true ) { 
  351. global $wp_version; 
  352. $is_wp_4_6 = version_compare( $wp_version, '4.6', '>=' ); 
  353.  
  354. echo '<tr class="plugin-update-tr' . ( is_plugin_active( $init ) ? ' active' : '' ) . '"><td colspan="' . $wp_list_table->get_column_count() . '" class="plugin-update colspanchange">'; 
  355.  
  356. echo '<div class="update-message' . ( $is_wp_4_6 ? ' notice inline notice-warning notice-alt' : '' ) . '">'; 
  357.  
  358. echo( $is_wp_4_6 ? '<p>' : '' ); 
  359.  
  360. if ( ! current_user_can( 'update_plugins' ) ) { 
  361. printf( __( 'There is a new version of %1$s available. <a href="%2$s" class="thickbox yit-changelog-button open-plugin-details-modal" title="%3$s">View version %4$s details</a>.', 'yith-plugin-fw' ), $this->_plugins[ $init ]['info']['Name'], esc_url( $details_url ), esc_attr( $this->_plugins[ $init ]['info']['Name'] ), $r->new_version ); 
  362. } elseif ( is_plugin_active_for_network( $init ) ) { 
  363. printf( __( 'There is a new version of %1$s available. <a href="%2$s" class="thickbox yit-changelog-button open-plugin-details-modal" title="%3$s">View version %4$s details</a>. <em>You have to activate the plugin on a single site of the network to benefit from automatic updates.</em>', 'yith-plugin-fw' ), $this->_plugins[ $init ]['info']['Name'], esc_url( $details_url ), esc_attr( $this->_plugins[ $init ]['info']['Name'] ), $r->new_version ); 
  364. } elseif ( empty( $r->package ) ) { 
  365. printf( __( 'There is a new version of %1$s available. <a href="%2$s" class="thickbox yit-changelog-button open-plugin-details-modal" title="%3$s">View version %4$s details</a>. <em>Automatic update is unavailable for this plugin, please <a href="%5$s" title="License activation">activate</a> your copy of %6s.</em>', 'yith-plugin-fw' ), $this->_plugins[ $init ]['info']['Name'], esc_url( $details_url ), esc_attr( $this->_plugins[ $init ]['info']['Name'] ), $r->new_version, YIT_Plugin_Licence()->get_licence_activation_page_url(), $this->_plugins[ $init ]['info']['Name'] ); 
  366. } else { 
  367. printf( __( 'There is a new version of %1$s available. <a href="%2$s" class="thickbox yit-changelog-button open-plugin-details-modal" title="%3$s">View version %4$s details</a> or <a href="%5$s">update now</a>.', 'yith-plugin-fw' ), $this->_plugins[ $init ]['info']['Name'], esc_url( $details_url ), esc_attr( $this->_plugins[ $init ]['info']['Name'] ), $r->new_version, wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' ) . $init, 'upgrade-plugin_' . $init ) ); 
  368.  
  369. echo( $is_wp_4_6 ? '</p>' : '' ); 
  370.  
  371. /** 
  372. * Fires at the end of the update message container in each 
  373. * row of the themes list table. 
  374. * The dynamic portion of the hook name, `$theme_key`, refers to 
  375. * the theme slug as found in the WordPress.org themes repository. 
  376. * @since Wordpress 3.1.0 
  377. * } 
  378. */ 
  379. do_action( "in_theme_update_message-{$init}", $this->_plugins[ $init ], $r->changelog, $changelog_id ); 
  380.  
  381. echo '</div></td></tr>'; 
  382.  
  383. /** 
  384. * Remove the standard plugin_update_row 
  385. * Remove the standard plugin_update_row and Add a custom plugin update row in plugin page. 
  386. * @return void 
  387. * @fire "in_theme_update_message-{$init}" action 
  388. * @since 1.0 
  389. * @see after_plugin_row_{$init} action 
  390. * @author Andrea Grillo <andrea.grillo@yithemes.com> 
  391. */ 
  392. public function remove_wp_plugin_update_row() { 
  393. foreach ( $this->_plugins as $init => $plugin ) { 
  394. remove_action( "after_plugin_row_{$init}", 'wp_plugin_update_row', 10 ); 
  395. add_action( "after_plugin_row_{$init}", array( $this, 'plugin_update_row' ) ); 
  396. add_action( "in_theme_update_message-{$init}", array( $this, 'in_theme_update_message' ), 10, 3 ); 
  397.  
  398. public function in_theme_update_message( $plugin, $changelog, $changelog_id, $echo = true ) { 
  399.  
  400. $res = "<div id='{$changelog_id}' class='yit-plugin-changelog-wrapper'> 
  401. <div class='yit-plugin-changelog'> 
  402. <h2 class='yit-plugin-changelog-title'>{$plugin['info']['Name']} - Changelog</h2> 
  403. <p>{$changelog}</p> 
  404. </div> 
  405. </div>"; 
  406.  
  407. if ( $echo ) { 
  408. echo $res; 
  409. } else { 
  410. return $res; 
  411.  
  412. /** 
  413. * Auto-Update Plugin in multisite 
  414. * Manage the non standard upgrade-plugin-multisite action 
  415. * @return void 
  416. * @since 1.0 
  417. * @see upgrade-plugin action 
  418. * @author Andrea Grillo <andrea.grillo@yithemes.com> 
  419. */ 
  420. public function upgrade_plugin_multisite() { 
  421.  
  422. $plugin = isset( $_REQUEST['plugin'] ) ? trim( $_REQUEST['plugin'] ) : ''; 
  423. $action = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : ''; 
  424.  
  425. if ( 'upgrade-plugin-multisite' != $action ) { 
  426. wp_die( __( 'You can\'t update the plugins for this site.', 'yith-plugin-fw' ) ); 
  427.  
  428. if ( ! current_user_can( 'update_plugins' ) ) { 
  429. wp_die( __( 'You do not have sufficient permissions to update the plugins for this site.', 'yith-plugin-fw' ) ); 
  430.  
  431. $this->check_update( get_site_transient( 'update_plugins' ), true ); 
  432.  
  433. check_admin_referer( 'upgrade-plugin-multisite_' . $plugin ); 
  434.  
  435. $title = __( 'Update Plugin', 'yith-plugin-fw' ); 
  436. $parent_file = 'plugins.php'; 
  437. $submenu_file = 'plugins.php'; 
  438.  
  439. wp_enqueue_script( 'updates' ); 
  440. require_once( ABSPATH . 'wp-admin/admin-header.php' ); 
  441.  
  442. $nonce = 'upgrade-plugin-multisite_' . $plugin; 
  443. $url = 'update.php?action=upgrade-plugin-multisite&plugin=' . urlencode( $plugin ); 
  444.  
  445. $upgrader = new Plugin_Upgrader( new Plugin_Upgrader_Skin( compact( 'title', 'nonce', 'url', 'plugin' ) ) ); 
  446. $upgrader->upgrade( $plugin ); 
  447.  
  448. include( ABSPATH . 'wp-admin/admin-footer.php' );