PageRenderTime 45ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/envato-wordpress-toolkit/includes/class-github-updater.php

https://gitlab.com/juanito.abelo/nlmobile
PHP | 395 lines | 186 code | 77 blank | 132 comment | 54 complexity | 8c257d8c6044b97f8151b36f03469e67 MD5 | raw file
  1. <?php
  2. // Prevent loading this file directly and/or if the class is already defined
  3. if ( ! defined( 'ABSPATH' ) || class_exists( 'WP_GitHub_Updater' ) )
  4. return;
  5. /**
  6. * Updates the Envato WordPress Toolkit via Guthub.
  7. *
  8. * This is a derivitive work of Joachim Kudish's `WP_GitHub_Updater`.
  9. * It has been heavily modified to work with this plugin specifically.
  10. */
  11. class WP_GitHub_Updater {
  12. /**
  13. * GitHub Updater version
  14. */
  15. const VERSION = EWPT_PLUGIN_VER;
  16. /**
  17. * @var $config the config for the updater
  18. * @access public
  19. */
  20. var $config;
  21. /**
  22. * @var $missing_config any config that is missing from the initialization of this instance
  23. * @access public
  24. */
  25. var $missing_config;
  26. /**
  27. * @var $github_data temporiraly store the data fetched from GitHub, allows us to only load the data once per class instance
  28. * @access private
  29. */
  30. private $github_data;
  31. /**
  32. * Class Constructor
  33. *
  34. * @since 1.0
  35. * @param array $config the configuration required for the updater to work
  36. * @see has_minimum_config()
  37. * @return void
  38. */
  39. public function __construct( $config = array() ) {
  40. $defaults = array(
  41. 'slug' => plugin_basename( __FILE__ ),
  42. 'plugin' => plugin_basename( __FILE__ ),
  43. 'proper_folder_name' => dirname( plugin_basename( __FILE__ ) ),
  44. 'sslverify' => true,
  45. 'access_token' => '',
  46. );
  47. $this->config = wp_parse_args( $config, $defaults );
  48. // if the minimum config isn't set, issue a warning and bail
  49. if ( ! $this->has_minimum_config() ) {
  50. $message = 'The GitHub Updater was initialized without the minimum required configuration, please check the config in your plugin. The following params are missing: ';
  51. $message .= implode( ',', $this->missing_config );
  52. _doing_it_wrong( __CLASS__, $message , self::VERSION );
  53. return;
  54. }
  55. $this->set_defaults();
  56. add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'api_check' ) );
  57. // Hook into the plugin details screen
  58. add_filter( 'plugins_api', array( $this, 'get_plugin_info' ), 10, 3 );
  59. add_filter( 'upgrader_source_selection', array( $this, 'upgrader_source_selection' ) );
  60. // set timeout
  61. add_filter( 'http_request_timeout', array( $this, 'http_request_timeout' ) );
  62. // set sslverify for zip download
  63. add_filter( 'http_request_args', array( $this, 'http_request_sslverify' ), 10, 2 );
  64. }
  65. public function has_minimum_config() {
  66. $this->missing_config = array();
  67. $required_config_params = array(
  68. 'api_url',
  69. 'raw_url',
  70. 'github_url',
  71. 'zip_url'
  72. );
  73. foreach ( $required_config_params as $required_param ) {
  74. if ( empty( $this->config[$required_param] ) )
  75. $this->missing_config[] = $required_param;
  76. }
  77. return ( empty( $this->missing_config ) );
  78. }
  79. /**
  80. * Check wether or not the transients need to be overruled and API needs to be called for every single page load
  81. *
  82. * @return bool overrule or not
  83. */
  84. public function overrule_transients() {
  85. return ( defined( 'WP_GITHUB_FORCE_UPDATE' ) && WP_GITHUB_FORCE_UPDATE );
  86. }
  87. /**
  88. * Set defaults
  89. *
  90. * @since 1.2
  91. * @return void
  92. */
  93. public function set_defaults() {
  94. if ( ! empty( $this->config['access_token'] ) ) {
  95. // See Downloading a zipball (private repo) https://help.github.com/articles/downloading-files-from-the-command-line
  96. extract( parse_url( $this->config['zip_url'] ) ); // $scheme, $host, $path
  97. $zip_url = $scheme . '://api.github.com/repos' . $path;
  98. $zip_url = add_query_arg( array( 'access_token' => $this->config['access_token'] ), $zip_url );
  99. $this->config['zip_url'] = $zip_url;
  100. }
  101. if ( ! isset( $this->config['readme'] ) )
  102. $this->config['readme'] = 'readme.txt';
  103. // Get the contents of the readme.txt file
  104. $this->readme = $this->get_readme();
  105. if ( ! isset( $this->config['new_version'] ) )
  106. $this->config['new_version'] = $this->get_readme_header_info( 'Stable tag' );
  107. if ( ! isset( $this->config['tested'] ) )
  108. $this->config['tested'] = $this->get_readme_header_info( 'Tested up to' );
  109. if ( ! isset( $this->config['requires'] ) )
  110. $this->config['requires'] = $this->get_readme_header_info( 'Requires at least' );
  111. if ( ! isset( $this->config['last_updated'] ) )
  112. $this->config['last_updated'] = $this->get_date();
  113. $plugin_data = $this->get_plugin_data();
  114. if ( ! isset( $this->config['description'] ) )
  115. $this->config['description'] = $plugin_data['Description'];
  116. if ( ! isset( $this->config['plugin_name'] ) )
  117. $this->config['plugin_name'] = $plugin_data['Name'];
  118. if ( ! isset( $this->config['version'] ) )
  119. $this->config['version'] = $plugin_data['Version'];
  120. if ( ! isset( $this->config['author'] ) )
  121. $this->config['author'] = $plugin_data['Author'];
  122. if ( ! isset( $this->config['homepage'] ) )
  123. $this->config['homepage'] = $plugin_data['PluginURI'];
  124. }
  125. /**
  126. * Callback fn for the http_request_timeout filter
  127. *
  128. * @since 1.0
  129. * @return int timeout value
  130. */
  131. public function http_request_timeout() {
  132. return 2;
  133. }
  134. /**
  135. * Callback fn for the http_request_args filter
  136. *
  137. * @param unknown $args
  138. * @param unknown $url
  139. *
  140. * @return mixed
  141. */
  142. public function http_request_sslverify( $args, $url ) {
  143. if ( $this->config[ 'zip_url' ] == $url )
  144. $args[ 'sslverify' ] = $this->config[ 'sslverify' ];
  145. return $args;
  146. }
  147. /**
  148. * Get readme.txt from github
  149. *
  150. * @since 1.7.2
  151. * @return int $readme The readme.txt contents
  152. */
  153. public function get_readme() {
  154. $readme = get_site_transient( 'ewt_readme' );
  155. if ( $this->overrule_transients() || ( ! isset( $readme ) || ! $readme || '' == $readme ) ) {
  156. $raw_url = trailingslashit( $this->config['raw_url'] ) . $this->config['readme'];
  157. $raw_response = $this->remote_get( $raw_url );
  158. if ( is_wp_error( $raw_response ) )
  159. return false;
  160. if ( is_array( $raw_response ) && ! empty( $raw_response['body'] ) ) {
  161. set_site_transient( 'ewt_readme', $raw_response['body'], 3600 );
  162. }
  163. }
  164. return $readme;
  165. }
  166. /**
  167. * Get readme header info
  168. *
  169. * @since 1.7.2
  170. * @return mixed
  171. */
  172. public function get_readme_header_info( $search = '' ) {
  173. if ( '' != $search && '' != $this->readme ) {
  174. preg_match( '#' . $search . '\:\s*(.*)$#im', $this->readme, $matches );
  175. if ( ! empty( $matches[1] ) ) {
  176. return $matches[1];
  177. }
  178. }
  179. return false;
  180. }
  181. /**
  182. * Interact with GitHub
  183. *
  184. * @param string $query
  185. *
  186. * @since 1.6
  187. * @return mixed
  188. */
  189. public function remote_get( $query ) {
  190. if ( ! empty( $this->config['access_token'] ) )
  191. $query = add_query_arg( array( 'access_token' => $this->config['access_token'] ), $query );
  192. $raw_response = wp_remote_get( $query, array(
  193. 'sslverify' => $this->config['sslverify']
  194. ) );
  195. return $raw_response;
  196. }
  197. /**
  198. * Get GitHub Data from the specified repository
  199. *
  200. * @since 1.0
  201. * @return array $github_data the data
  202. */
  203. public function get_github_data() {
  204. if ( isset( $this->github_data ) && ! empty( $this->github_data ) ) {
  205. $github_data = $this->github_data;
  206. } else {
  207. $github_data = get_site_transient( 'ewt_github_data' );
  208. if ( $this->overrule_transients() || ( ! isset( $github_data ) || ! $github_data || '' == $github_data ) ) {
  209. $github_data = $this->remote_get( $this->config['api_url'] );
  210. if ( is_wp_error( $github_data ) )
  211. return false;
  212. $github_data = json_decode( $github_data['body'] );
  213. // refresh every hour
  214. set_site_transient( 'ewt_github_data', $github_data, 3600 );
  215. }
  216. // Store the data in this class instance for future calls
  217. $this->github_data = $github_data;
  218. }
  219. return $github_data;
  220. }
  221. /**
  222. * Get update date
  223. *
  224. * @since 1.0
  225. * @return string $date the date
  226. */
  227. public function get_date() {
  228. $_date = $this->get_github_data();
  229. return ( !empty( $_date->updated_at ) ) ? date( 'Y-m-d', strtotime( $_date->updated_at ) ) : false;
  230. }
  231. /**
  232. * Get Plugin data
  233. *
  234. * @since 1.0
  235. * @return object $data the data
  236. */
  237. public function get_plugin_data() {
  238. include_once ABSPATH.'/wp-admin/includes/plugin.php';
  239. $data = get_plugin_data( WP_PLUGIN_DIR . '/' . $this->config['slug'] );
  240. return $data;
  241. }
  242. /**
  243. * Hook into the plugin update check and connect to github
  244. *
  245. * @since 1.0
  246. * @param object $transient the plugin data transient
  247. * @return object $transient updated plugin data transient
  248. */
  249. public function api_check( $transient ) {
  250. // Check if the transient contains the 'checked' information
  251. // If not, just return its value without hacking it
  252. if ( empty( $transient->checked ) )
  253. return $transient;
  254. // check the version and decide if it's new
  255. $update = version_compare( $this->config['new_version'], $this->config['version'] );
  256. if ( 1 === $update ) {
  257. $response = new stdClass;
  258. $response->new_version = $this->config['new_version'];
  259. $response->slug = $this->config['proper_folder_name'];
  260. $response->plugin = $this->config['plugin'];
  261. $response->url = add_query_arg( array( 'access_token' => $this->config['access_token'] ), $this->config['github_url'] );
  262. $response->package = $this->config['zip_url'];
  263. // If response is false, don't alter the transient
  264. if ( false !== $response )
  265. $transient->response[ $this->config['slug'] ] = $response;
  266. }
  267. return $transient;
  268. }
  269. /**
  270. * Get Plugin info
  271. *
  272. * @since 1.0
  273. * @param bool $false always false
  274. * @param string $action the API function being performed
  275. * @param object $args plugin arguments
  276. * @return object $response the plugin info
  277. */
  278. public function get_plugin_info( $false, $action, $response ) {
  279. // Include plugin updates for `list_plugin_updates()`
  280. if ( $action == 'plugin_information' && isset( $response->slug ) && $response->slug == dirname( $this->config['slug'] ) ) {
  281. $found_it = true;
  282. }
  283. // Check if this call API is for the right plugin
  284. if ( ! isset( $found_it ) && ( ! isset( $response->slug ) || $response->slug != $this->config['slug'] ) )
  285. return $false;
  286. $response->slug = $this->config['slug'];
  287. $response->plugin = $this->config['plugin'];
  288. $response->plugin_name = $this->config['plugin_name'];
  289. $response->version = $this->config['new_version'];
  290. $response->author = $this->config['author'];
  291. $response->homepage = $this->config['homepage'];
  292. $response->requires = $this->config['requires'];
  293. $response->tested = $this->config['tested'];
  294. $response->downloaded = 0;
  295. $response->last_updated = $this->config['last_updated'];
  296. $response->sections = array( 'description' => $this->config['description'] );
  297. $response->download_link = $this->config['zip_url'];
  298. return $response;
  299. }
  300. /**
  301. * Filter the source file location for the upgrade package.
  302. *
  303. * @since 1.0
  304. * @param string $source File source location.
  305. */
  306. public function upgrader_source_selection( $source ) {
  307. // Fix the destination path
  308. if ( strpos( $source, $this->config['proper_folder_name'] . '-master' ) !== false ) {
  309. global $wp_filesystem;
  310. $proper_source = str_replace( '-master', '', $source );
  311. $wp_filesystem->move( $source, $proper_source );
  312. $source = $proper_source;
  313. }
  314. return $source;
  315. }
  316. }
  317. /* End of file class-github-updater.php */
  318. /* Location: ./includes/class-github-updater.php */