An updated theme (based on Atticus Finch) for ClassicPress
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

197 lines
6.3 KiB

3 years ago
  1. <?php
  2. if ( !class_exists('Puc_v4p1_Vcs_PluginUpdateChecker') ):
  3. class Puc_v4p1_Vcs_PluginUpdateChecker extends Puc_v4p1_Plugin_UpdateChecker implements Puc_v4p1_Vcs_BaseChecker {
  4. /**
  5. * @var string The branch where to look for updates. Defaults to "master".
  6. */
  7. protected $branch = 'master';
  8. /**
  9. * @var Puc_v4p1_Vcs_Api Repository API client.
  10. */
  11. protected $api = null;
  12. /**
  13. * Puc_v4p1_Vcs_PluginUpdateChecker constructor.
  14. *
  15. * @param Puc_v4p1_Vcs_Api $api
  16. * @param string $pluginFile
  17. * @param string $slug
  18. * @param int $checkPeriod
  19. * @param string $optionName
  20. * @param string $muPluginFile
  21. */
  22. public function __construct($api, $pluginFile, $slug = '', $checkPeriod = 12, $optionName = '', $muPluginFile = '') {
  23. $this->api = $api;
  24. $this->api->setHttpFilterName($this->getUniqueName('request_info_options'));
  25. parent::__construct($api->getRepositoryUrl(), $pluginFile, $slug, $checkPeriod, $optionName, $muPluginFile);
  26. }
  27. public function requestInfo($unusedParameter = null) {
  28. //We have to make several remote API requests to gather all the necessary info
  29. //which can take a while on slow networks.
  30. set_time_limit(60);
  31. $api = $this->api;
  32. $info = new Puc_v4p1_Plugin_Info();
  33. $info->filename = $this->pluginFile;
  34. $info->slug = $this->slug;
  35. $this->setInfoFromHeader($this->getPluginHeader(), $info);
  36. //Pick a branch or tag.
  37. $updateSource = $api->chooseReference($this->branch);
  38. if ( $updateSource ) {
  39. $ref = $updateSource->name;
  40. $info->version = $updateSource->version;
  41. $info->last_updated = $updateSource->updated;
  42. $info->download_url = $updateSource->downloadUrl;
  43. if ( !empty($updateSource->changelog) ) {
  44. $info->sections['changelog'] = $updateSource->changelog;
  45. }
  46. if ( isset($updateSource->downloadCount) ) {
  47. $info->downloaded = $updateSource->downloadCount;
  48. }
  49. } else {
  50. //There's probably a network problem or an authentication error.
  51. return null;
  52. }
  53. //Get headers from the main plugin file in this branch/tag. Its "Version" header and other metadata
  54. //are what the WordPress install will actually see after upgrading, so they take precedence over releases/tags.
  55. $mainPluginFile = basename($this->pluginFile);
  56. $remotePlugin = $api->getRemoteFile($mainPluginFile, $ref);
  57. if ( !empty($remotePlugin) ) {
  58. $remoteHeader = $this->getFileHeader($remotePlugin);
  59. $this->setInfoFromHeader($remoteHeader, $info);
  60. }
  61. //Try parsing readme.txt. If it's formatted according to WordPress.org standards, it will contain
  62. //a lot of useful information like the required/tested WP version, changelog, and so on.
  63. if ( $this->readmeTxtExistsLocally() ) {
  64. $this->setInfoFromRemoteReadme($ref, $info);
  65. }
  66. //The changelog might be in a separate file.
  67. if ( empty($info->sections['changelog']) ) {
  68. $info->sections['changelog'] = $api->getRemoteChangelog($ref, dirname($this->getAbsolutePath()));
  69. if ( empty($info->sections['changelog']) ) {
  70. $info->sections['changelog'] = __('There is no changelog available.', 'plugin-update-checker');
  71. }
  72. }
  73. if ( empty($info->last_updated) ) {
  74. //Fetch the latest commit that changed the tag or branch and use it as the "last_updated" date.
  75. $latestCommitTime = $api->getLatestCommitTime($ref);
  76. if ( $latestCommitTime !== null ) {
  77. $info->last_updated = $latestCommitTime;
  78. }
  79. }
  80. $info = apply_filters($this->getUniqueName('request_info_result'), $info, null);
  81. return $info;
  82. }
  83. /**
  84. * Check if the currently installed version has a readme.txt file.
  85. *
  86. * @return bool
  87. */
  88. protected function readmeTxtExistsLocally() {
  89. $pluginDirectory = dirname($this->pluginAbsolutePath);
  90. if ( empty($this->pluginAbsolutePath) || !is_dir($pluginDirectory) || ($pluginDirectory === '.') ) {
  91. return false;
  92. }
  93. return is_file($pluginDirectory . '/readme.txt');
  94. }
  95. /**
  96. * Copy plugin metadata from a file header to a Plugin Info object.
  97. *
  98. * @param array $fileHeader
  99. * @param Puc_v4p1_Plugin_Info $pluginInfo
  100. */
  101. protected function setInfoFromHeader($fileHeader, $pluginInfo) {
  102. $headerToPropertyMap = array(
  103. 'Version' => 'version',
  104. 'Name' => 'name',
  105. 'PluginURI' => 'homepage',
  106. 'Author' => 'author',
  107. 'AuthorName' => 'author',
  108. 'AuthorURI' => 'author_homepage',
  109. 'Requires WP' => 'requires',
  110. 'Tested WP' => 'tested',
  111. 'Requires at least' => 'requires',
  112. 'Tested up to' => 'tested',
  113. );
  114. foreach ($headerToPropertyMap as $headerName => $property) {
  115. if ( isset($fileHeader[$headerName]) && !empty($fileHeader[$headerName]) ) {
  116. $pluginInfo->$property = $fileHeader[$headerName];
  117. }
  118. }
  119. if ( !empty($fileHeader['Description']) ) {
  120. $pluginInfo->sections['description'] = $fileHeader['Description'];
  121. }
  122. }
  123. /**
  124. * Copy plugin metadata from the remote readme.txt file.
  125. *
  126. * @param string $ref GitHub tag or branch where to look for the readme.
  127. * @param Puc_v4p1_Plugin_Info $pluginInfo
  128. */
  129. protected function setInfoFromRemoteReadme($ref, $pluginInfo) {
  130. $readme = $this->api->getRemoteReadme($ref);
  131. if ( empty($readme) ) {
  132. return;
  133. }
  134. if ( isset($readme['sections']) ) {
  135. $pluginInfo->sections = array_merge($pluginInfo->sections, $readme['sections']);
  136. }
  137. if ( !empty($readme['tested_up_to']) ) {
  138. $pluginInfo->tested = $readme['tested_up_to'];
  139. }
  140. if ( !empty($readme['requires_at_least']) ) {
  141. $pluginInfo->requires = $readme['requires_at_least'];
  142. }
  143. if ( isset($readme['upgrade_notice'], $readme['upgrade_notice'][$pluginInfo->version]) ) {
  144. $pluginInfo->upgrade_notice = $readme['upgrade_notice'][$pluginInfo->version];
  145. }
  146. }
  147. public function setBranch($branch) {
  148. $this->branch = $branch;
  149. return $this;
  150. }
  151. public function setAuthentication($credentials) {
  152. $this->api->setAuthentication($credentials);
  153. return $this;
  154. }
  155. public function getUpdate() {
  156. $update = parent::getUpdate();
  157. if ( isset($update) && !empty($update->download_url) ) {
  158. $update->download_url = $this->api->signDownloadUrl($update->download_url);
  159. }
  160. return $update;
  161. }
  162. public function onDisplayConfiguration($panel) {
  163. parent::onDisplayConfiguration($panel);
  164. $panel->row('Branch', $this->branch);
  165. $panel->row('Authentication enabled', $this->api->isAuthenticationEnabled() ? 'Yes' : 'No');
  166. $panel->row('API client', get_class($this->api));
  167. }
  168. }
  169. endif;