Passed
Push — main ( 44ea53...137754 )
by TARIQ
15:15 queued 02:39
created
includes/plugin-update-checker-5-1.0/Puc/v5p0/Vcs/ThemeUpdateChecker.php 2 patches
Indentation   +62 added lines, -62 removed lines patch added patch discarded remove patch
@@ -7,77 +7,77 @@
 block discarded – undo
7 7
 
8 8
 if ( !class_exists(ThemeUpdateChecker::class, false) ):
9 9
 
10
-	class ThemeUpdateChecker extends Theme\UpdateChecker implements BaseChecker {
11
-		use VcsCheckerMethods;
10
+    class ThemeUpdateChecker extends Theme\UpdateChecker implements BaseChecker {
11
+        use VcsCheckerMethods;
12 12
 
13
-		/**
14
-		 * ThemeUpdateChecker constructor.
15
-		 *
16
-		 * @param Api $api
17
-		 * @param null $stylesheet
18
-		 * @param null $customSlug
19
-		 * @param int $checkPeriod
20
-		 * @param string $optionName
21
-		 */
22
-		public function __construct($api, $stylesheet = null, $customSlug = null, $checkPeriod = 12, $optionName = '') {
23
-			$this->api = $api;
13
+        /**
14
+         * ThemeUpdateChecker constructor.
15
+         *
16
+         * @param Api $api
17
+         * @param null $stylesheet
18
+         * @param null $customSlug
19
+         * @param int $checkPeriod
20
+         * @param string $optionName
21
+         */
22
+        public function __construct($api, $stylesheet = null, $customSlug = null, $checkPeriod = 12, $optionName = '') {
23
+            $this->api = $api;
24 24
 
25
-			parent::__construct($api->getRepositoryUrl(), $stylesheet, $customSlug, $checkPeriod, $optionName);
25
+            parent::__construct($api->getRepositoryUrl(), $stylesheet, $customSlug, $checkPeriod, $optionName);
26 26
 
27
-			$this->api->setHttpFilterName($this->getUniqueName('request_update_options'));
28
-			$this->api->setStrategyFilterName($this->getUniqueName('vcs_update_detection_strategies'));
29
-			$this->api->setSlug($this->slug);
30
-		}
27
+            $this->api->setHttpFilterName($this->getUniqueName('request_update_options'));
28
+            $this->api->setStrategyFilterName($this->getUniqueName('vcs_update_detection_strategies'));
29
+            $this->api->setSlug($this->slug);
30
+        }
31 31
 
32
-		public function requestUpdate() {
33
-			$api = $this->api;
34
-			$api->setLocalDirectory($this->package->getAbsoluteDirectoryPath());
32
+        public function requestUpdate() {
33
+            $api = $this->api;
34
+            $api->setLocalDirectory($this->package->getAbsoluteDirectoryPath());
35 35
 
36
-			$update = new Theme\Update();
37
-			$update->slug = $this->slug;
36
+            $update = new Theme\Update();
37
+            $update->slug = $this->slug;
38 38
 
39
-			//Figure out which reference (tag or branch) we'll use to get the latest version of the theme.
40
-			$updateSource = $api->chooseReference($this->branch);
41
-			if ( $updateSource ) {
42
-				$ref = $updateSource->name;
43
-				$update->download_url = $updateSource->downloadUrl;
44
-			} else {
45
-				do_action(
46
-					'puc_api_error',
47
-					new \WP_Error(
48
-						'puc-no-update-source',
49
-						'Could not retrieve version information from the repository. '
50
-						. 'This usually means that the update checker either can\'t connect '
51
-						. 'to the repository or it\'s configured incorrectly.'
52
-					),
53
-					null, null, $this->slug
54
-				);
55
-				$ref = $this->branch;
56
-			}
39
+            //Figure out which reference (tag or branch) we'll use to get the latest version of the theme.
40
+            $updateSource = $api->chooseReference($this->branch);
41
+            if ( $updateSource ) {
42
+                $ref = $updateSource->name;
43
+                $update->download_url = $updateSource->downloadUrl;
44
+            } else {
45
+                do_action(
46
+                    'puc_api_error',
47
+                    new \WP_Error(
48
+                        'puc-no-update-source',
49
+                        'Could not retrieve version information from the repository. '
50
+                        . 'This usually means that the update checker either can\'t connect '
51
+                        . 'to the repository or it\'s configured incorrectly.'
52
+                    ),
53
+                    null, null, $this->slug
54
+                );
55
+                $ref = $this->branch;
56
+            }
57 57
 
58
-			//Get headers from the main stylesheet in this branch/tag. Its "Version" header and other metadata
59
-			//are what the WordPress install will actually see after upgrading, so they take precedence over releases/tags.
60
-			$remoteHeader = $this->package->getFileHeader($api->getRemoteFile('style.css', $ref));
61
-			$update->version = Utils::findNotEmpty(array(
62
-				$remoteHeader['Version'],
63
-				Utils::get($updateSource, 'version'),
64
-			));
58
+            //Get headers from the main stylesheet in this branch/tag. Its "Version" header and other metadata
59
+            //are what the WordPress install will actually see after upgrading, so they take precedence over releases/tags.
60
+            $remoteHeader = $this->package->getFileHeader($api->getRemoteFile('style.css', $ref));
61
+            $update->version = Utils::findNotEmpty(array(
62
+                $remoteHeader['Version'],
63
+                Utils::get($updateSource, 'version'),
64
+            ));
65 65
 
66
-			//The details URL defaults to the Theme URI header or the repository URL.
67
-			$update->details_url = Utils::findNotEmpty(array(
68
-				$remoteHeader['ThemeURI'],
69
-				$this->package->getHeaderValue('ThemeURI'),
70
-				$this->metadataUrl,
71
-			));
66
+            //The details URL defaults to the Theme URI header or the repository URL.
67
+            $update->details_url = Utils::findNotEmpty(array(
68
+                $remoteHeader['ThemeURI'],
69
+                $this->package->getHeaderValue('ThemeURI'),
70
+                $this->metadataUrl,
71
+            ));
72 72
 
73
-			if ( empty($update->version) ) {
74
-				//It looks like we didn't find a valid update after all.
75
-				$update = null;
76
-			}
73
+            if ( empty($update->version) ) {
74
+                //It looks like we didn't find a valid update after all.
75
+                $update = null;
76
+            }
77 77
 
78
-			$update = $this->filterUpdateResult($update);
79
-			return $update;
80
-		}
81
-	}
78
+            $update = $this->filterUpdateResult($update);
79
+            return $update;
80
+        }
81
+    }
82 82
 
83 83
 endif;
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -5,7 +5,7 @@  discard block
 block discarded – undo
5 5
 use YahnisElsts\PluginUpdateChecker\v5p0\Theme;
6 6
 use YahnisElsts\PluginUpdateChecker\v5p0\Utils;
7 7
 
8
-if ( !class_exists(ThemeUpdateChecker::class, false) ):
8
+if (!class_exists(ThemeUpdateChecker::class, false)):
9 9
 
10 10
 	class ThemeUpdateChecker extends Theme\UpdateChecker implements BaseChecker {
11 11
 		use VcsCheckerMethods;
@@ -38,7 +38,7 @@  discard block
 block discarded – undo
38 38
 
39 39
 			//Figure out which reference (tag or branch) we'll use to get the latest version of the theme.
40 40
 			$updateSource = $api->chooseReference($this->branch);
41
-			if ( $updateSource ) {
41
+			if ($updateSource) {
42 42
 				$ref = $updateSource->name;
43 43
 				$update->download_url = $updateSource->downloadUrl;
44 44
 			} else {
@@ -70,7 +70,7 @@  discard block
 block discarded – undo
70 70
 				$this->metadataUrl,
71 71
 			));
72 72
 
73
-			if ( empty($update->version) ) {
73
+			if (empty($update->version)) {
74 74
 				//It looks like we didn't find a valid update after all.
75 75
 				$update = null;
76 76
 			}
Please login to merge, or discard this patch.
includes/plugin-update-checker-5-1.0/Puc/v5p0/Vcs/PluginUpdateChecker.php 2 patches
Indentation   +250 added lines, -250 removed lines patch added patch discarded remove patch
@@ -6,255 +6,255 @@
 block discarded – undo
6 6
 
7 7
 if ( !class_exists(PluginUpdateChecker::class, false) ):
8 8
 
9
-	class PluginUpdateChecker extends Plugin\UpdateChecker implements BaseChecker {
10
-		use VcsCheckerMethods;
11
-
12
-		/**
13
-		 * PluginUpdateChecker constructor.
14
-		 *
15
-		 * @param 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
-
25
-			parent::__construct($api->getRepositoryUrl(), $pluginFile, $slug, $checkPeriod, $optionName, $muPluginFile);
26
-
27
-			$this->api->setHttpFilterName($this->getUniqueName('request_info_options'));
28
-			$this->api->setStrategyFilterName($this->getUniqueName('vcs_update_detection_strategies'));
29
-			$this->api->setSlug($this->slug);
30
-		}
31
-
32
-		public function requestInfo($unusedParameter = null) {
33
-			//We have to make several remote API requests to gather all the necessary info
34
-			//which can take a while on slow networks.
35
-			if ( function_exists('set_time_limit') ) {
36
-				@set_time_limit(60);
37
-			}
38
-
39
-			$api = $this->api;
40
-			$api->setLocalDirectory($this->package->getAbsoluteDirectoryPath());
41
-
42
-			$info = new Plugin\PluginInfo();
43
-			$info->filename = $this->pluginFile;
44
-			$info->slug = $this->slug;
45
-
46
-			$this->setInfoFromHeader($this->package->getPluginHeader(), $info);
47
-			$this->setIconsFromLocalAssets($info);
48
-			$this->setBannersFromLocalAssets($info);
49
-
50
-			//Pick a branch or tag.
51
-			$updateSource = $api->chooseReference($this->branch);
52
-			if ( $updateSource ) {
53
-				$ref = $updateSource->name;
54
-				$info->version = $updateSource->version;
55
-				$info->last_updated = $updateSource->updated;
56
-				$info->download_url = $updateSource->downloadUrl;
57
-
58
-				if ( !empty($updateSource->changelog) ) {
59
-					$info->sections['changelog'] = $updateSource->changelog;
60
-				}
61
-				if ( isset($updateSource->downloadCount) ) {
62
-					$info->downloaded = $updateSource->downloadCount;
63
-				}
64
-			} else {
65
-				//There's probably a network problem or an authentication error.
66
-				do_action(
67
-					'puc_api_error',
68
-					new \WP_Error(
69
-						'puc-no-update-source',
70
-						'Could not retrieve version information from the repository. '
71
-						. 'This usually means that the update checker either can\'t connect '
72
-						. 'to the repository or it\'s configured incorrectly.'
73
-					),
74
-					null, null, $this->slug
75
-				);
76
-				return null;
77
-			}
78
-
79
-			//Get headers from the main plugin file in this branch/tag. Its "Version" header and other metadata
80
-			//are what the WordPress install will actually see after upgrading, so they take precedence over releases/tags.
81
-			$mainPluginFile = basename($this->pluginFile);
82
-			$remotePlugin = $api->getRemoteFile($mainPluginFile, $ref);
83
-			if ( !empty($remotePlugin) ) {
84
-				$remoteHeader = $this->package->getFileHeader($remotePlugin);
85
-				$this->setInfoFromHeader($remoteHeader, $info);
86
-			}
87
-
88
-			//Try parsing readme.txt. If it's formatted according to WordPress.org standards, it will contain
89
-			//a lot of useful information like the required/tested WP version, changelog, and so on.
90
-			if ( $this->readmeTxtExistsLocally() ) {
91
-				$this->setInfoFromRemoteReadme($ref, $info);
92
-			}
93
-
94
-			//The changelog might be in a separate file.
95
-			if ( empty($info->sections['changelog']) ) {
96
-				$info->sections['changelog'] = $api->getRemoteChangelog($ref, $this->package->getAbsoluteDirectoryPath());
97
-				if ( empty($info->sections['changelog']) ) {
98
-					$info->sections['changelog'] = __('There is no changelog available.', 'plugin-update-checker');
99
-				}
100
-			}
101
-
102
-			if ( empty($info->last_updated) ) {
103
-				//Fetch the latest commit that changed the tag or branch and use it as the "last_updated" date.
104
-				$latestCommitTime = $api->getLatestCommitTime($ref);
105
-				if ( $latestCommitTime !== null ) {
106
-					$info->last_updated = $latestCommitTime;
107
-				}
108
-			}
109
-
110
-			$info = apply_filters($this->getUniqueName('request_info_result'), $info, null);
111
-			return $info;
112
-		}
113
-
114
-		/**
115
-		 * Check if the currently installed version has a readme.txt file.
116
-		 *
117
-		 * @return bool
118
-		 */
119
-		protected function readmeTxtExistsLocally() {
120
-			return $this->package->fileExists($this->api->getLocalReadmeName());
121
-		}
122
-
123
-		/**
124
-		 * Copy plugin metadata from a file header to a Plugin Info object.
125
-		 *
126
-		 * @param array $fileHeader
127
-		 * @param Plugin\PluginInfo $pluginInfo
128
-		 */
129
-		protected function setInfoFromHeader($fileHeader, $pluginInfo) {
130
-			$headerToPropertyMap = array(
131
-				'Version' => 'version',
132
-				'Name' => 'name',
133
-				'PluginURI' => 'homepage',
134
-				'Author' => 'author',
135
-				'AuthorName' => 'author',
136
-				'AuthorURI' => 'author_homepage',
137
-
138
-				'Requires WP' => 'requires',
139
-				'Tested WP' => 'tested',
140
-				'Requires at least' => 'requires',
141
-				'Tested up to' => 'tested',
142
-
143
-				'Requires PHP' => 'requires_php',
144
-			);
145
-			foreach ($headerToPropertyMap as $headerName => $property) {
146
-				if ( isset($fileHeader[$headerName]) && !empty($fileHeader[$headerName]) ) {
147
-					$pluginInfo->$property = $fileHeader[$headerName];
148
-				}
149
-			}
150
-
151
-			if ( !empty($fileHeader['Description']) ) {
152
-				$pluginInfo->sections['description'] = $fileHeader['Description'];
153
-			}
154
-		}
155
-
156
-		/**
157
-		 * Copy plugin metadata from the remote readme.txt file.
158
-		 *
159
-		 * @param string $ref GitHub tag or branch where to look for the readme.
160
-		 * @param Plugin\PluginInfo $pluginInfo
161
-		 */
162
-		protected function setInfoFromRemoteReadme($ref, $pluginInfo) {
163
-			$readme = $this->api->getRemoteReadme($ref);
164
-			if ( empty($readme) ) {
165
-				return;
166
-			}
167
-
168
-			if ( isset($readme['sections']) ) {
169
-				$pluginInfo->sections = array_merge($pluginInfo->sections, $readme['sections']);
170
-			}
171
-			if ( !empty($readme['tested_up_to']) ) {
172
-				$pluginInfo->tested = $readme['tested_up_to'];
173
-			}
174
-			if ( !empty($readme['requires_at_least']) ) {
175
-				$pluginInfo->requires = $readme['requires_at_least'];
176
-			}
177
-			if ( !empty($readme['requires_php']) ) {
178
-				$pluginInfo->requires_php = $readme['requires_php'];
179
-			}
180
-
181
-			if ( isset($readme['upgrade_notice'], $readme['upgrade_notice'][$pluginInfo->version]) ) {
182
-				$pluginInfo->upgrade_notice = $readme['upgrade_notice'][$pluginInfo->version];
183
-			}
184
-		}
185
-
186
-		/**
187
-		 * Add icons from the currently installed version to a Plugin Info object.
188
-		 *
189
-		 * The icons should be in a subdirectory named "assets". Supported image formats
190
-		 * and file names are described here:
191
-		 * @link https://developer.wordpress.org/plugins/wordpress-org/plugin-assets/#plugin-icons
192
-		 *
193
-		 * @param Plugin\PluginInfo $pluginInfo
194
-		 */
195
-		protected function setIconsFromLocalAssets($pluginInfo) {
196
-			$icons = $this->getLocalAssetUrls(array(
197
-				'icon.svg'         => 'svg',
198
-				'icon-256x256.png' => '2x',
199
-				'icon-256x256.jpg' => '2x',
200
-				'icon-128x128.png' => '1x',
201
-				'icon-128x128.jpg' => '1x',
202
-			));
203
-
204
-			if ( !empty($icons) ) {
205
-				//The "default" key seems to be used only as last-resort fallback in WP core (5.8/5.9),
206
-				//but we'll set it anyway in case some code somewhere needs it.
207
-				reset($icons);
208
-				$firstKey = key($icons);
209
-				$icons['default'] = $icons[$firstKey];
210
-
211
-				$pluginInfo->icons = $icons;
212
-			}
213
-		}
214
-
215
-		/**
216
-		 * Add banners from the currently installed version to a Plugin Info object.
217
-		 *
218
-		 * The banners should be in a subdirectory named "assets". Supported image formats
219
-		 * and file names are described here:
220
-		 * @link https://developer.wordpress.org/plugins/wordpress-org/plugin-assets/#plugin-headers
221
-		 *
222
-		 * @param Plugin\PluginInfo $pluginInfo
223
-		 */
224
-		protected function setBannersFromLocalAssets($pluginInfo) {
225
-			$banners = $this->getLocalAssetUrls(array(
226
-				'banner-772x250.png' => 'high',
227
-				'banner-772x250.jpg' => 'high',
228
-				'banner-1544x500.png' => 'low',
229
-				'banner-1544x500.jpg' => 'low',
230
-			));
231
-
232
-			if ( !empty($banners) ) {
233
-				$pluginInfo->banners = $banners;
234
-			}
235
-		}
236
-
237
-		/**
238
-		 * @param array<string, string> $filesToKeys
239
-		 * @return array<string, string>
240
-		 */
241
-		protected function getLocalAssetUrls($filesToKeys) {
242
-			$assetDirectory = $this->package->getAbsoluteDirectoryPath() . DIRECTORY_SEPARATOR . 'assets';
243
-			if ( !is_dir($assetDirectory) ) {
244
-				return array();
245
-			}
246
-			$assetBaseUrl = trailingslashit(plugins_url('', $assetDirectory . '/imaginary.file'));
247
-
248
-			$foundAssets = array();
249
-			foreach ($filesToKeys as $fileName => $key) {
250
-				$fullBannerPath = $assetDirectory . DIRECTORY_SEPARATOR . $fileName;
251
-				if ( !isset($icons[$key]) && is_file($fullBannerPath) ) {
252
-					$foundAssets[$key] = $assetBaseUrl . $fileName;
253
-				}
254
-			}
255
-
256
-			return $foundAssets;
257
-		}
258
-	}
9
+    class PluginUpdateChecker extends Plugin\UpdateChecker implements BaseChecker {
10
+        use VcsCheckerMethods;
11
+
12
+        /**
13
+         * PluginUpdateChecker constructor.
14
+         *
15
+         * @param 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
+
25
+            parent::__construct($api->getRepositoryUrl(), $pluginFile, $slug, $checkPeriod, $optionName, $muPluginFile);
26
+
27
+            $this->api->setHttpFilterName($this->getUniqueName('request_info_options'));
28
+            $this->api->setStrategyFilterName($this->getUniqueName('vcs_update_detection_strategies'));
29
+            $this->api->setSlug($this->slug);
30
+        }
31
+
32
+        public function requestInfo($unusedParameter = null) {
33
+            //We have to make several remote API requests to gather all the necessary info
34
+            //which can take a while on slow networks.
35
+            if ( function_exists('set_time_limit') ) {
36
+                @set_time_limit(60);
37
+            }
38
+
39
+            $api = $this->api;
40
+            $api->setLocalDirectory($this->package->getAbsoluteDirectoryPath());
41
+
42
+            $info = new Plugin\PluginInfo();
43
+            $info->filename = $this->pluginFile;
44
+            $info->slug = $this->slug;
45
+
46
+            $this->setInfoFromHeader($this->package->getPluginHeader(), $info);
47
+            $this->setIconsFromLocalAssets($info);
48
+            $this->setBannersFromLocalAssets($info);
49
+
50
+            //Pick a branch or tag.
51
+            $updateSource = $api->chooseReference($this->branch);
52
+            if ( $updateSource ) {
53
+                $ref = $updateSource->name;
54
+                $info->version = $updateSource->version;
55
+                $info->last_updated = $updateSource->updated;
56
+                $info->download_url = $updateSource->downloadUrl;
57
+
58
+                if ( !empty($updateSource->changelog) ) {
59
+                    $info->sections['changelog'] = $updateSource->changelog;
60
+                }
61
+                if ( isset($updateSource->downloadCount) ) {
62
+                    $info->downloaded = $updateSource->downloadCount;
63
+                }
64
+            } else {
65
+                //There's probably a network problem or an authentication error.
66
+                do_action(
67
+                    'puc_api_error',
68
+                    new \WP_Error(
69
+                        'puc-no-update-source',
70
+                        'Could not retrieve version information from the repository. '
71
+                        . 'This usually means that the update checker either can\'t connect '
72
+                        . 'to the repository or it\'s configured incorrectly.'
73
+                    ),
74
+                    null, null, $this->slug
75
+                );
76
+                return null;
77
+            }
78
+
79
+            //Get headers from the main plugin file in this branch/tag. Its "Version" header and other metadata
80
+            //are what the WordPress install will actually see after upgrading, so they take precedence over releases/tags.
81
+            $mainPluginFile = basename($this->pluginFile);
82
+            $remotePlugin = $api->getRemoteFile($mainPluginFile, $ref);
83
+            if ( !empty($remotePlugin) ) {
84
+                $remoteHeader = $this->package->getFileHeader($remotePlugin);
85
+                $this->setInfoFromHeader($remoteHeader, $info);
86
+            }
87
+
88
+            //Try parsing readme.txt. If it's formatted according to WordPress.org standards, it will contain
89
+            //a lot of useful information like the required/tested WP version, changelog, and so on.
90
+            if ( $this->readmeTxtExistsLocally() ) {
91
+                $this->setInfoFromRemoteReadme($ref, $info);
92
+            }
93
+
94
+            //The changelog might be in a separate file.
95
+            if ( empty($info->sections['changelog']) ) {
96
+                $info->sections['changelog'] = $api->getRemoteChangelog($ref, $this->package->getAbsoluteDirectoryPath());
97
+                if ( empty($info->sections['changelog']) ) {
98
+                    $info->sections['changelog'] = __('There is no changelog available.', 'plugin-update-checker');
99
+                }
100
+            }
101
+
102
+            if ( empty($info->last_updated) ) {
103
+                //Fetch the latest commit that changed the tag or branch and use it as the "last_updated" date.
104
+                $latestCommitTime = $api->getLatestCommitTime($ref);
105
+                if ( $latestCommitTime !== null ) {
106
+                    $info->last_updated = $latestCommitTime;
107
+                }
108
+            }
109
+
110
+            $info = apply_filters($this->getUniqueName('request_info_result'), $info, null);
111
+            return $info;
112
+        }
113
+
114
+        /**
115
+         * Check if the currently installed version has a readme.txt file.
116
+         *
117
+         * @return bool
118
+         */
119
+        protected function readmeTxtExistsLocally() {
120
+            return $this->package->fileExists($this->api->getLocalReadmeName());
121
+        }
122
+
123
+        /**
124
+         * Copy plugin metadata from a file header to a Plugin Info object.
125
+         *
126
+         * @param array $fileHeader
127
+         * @param Plugin\PluginInfo $pluginInfo
128
+         */
129
+        protected function setInfoFromHeader($fileHeader, $pluginInfo) {
130
+            $headerToPropertyMap = array(
131
+                'Version' => 'version',
132
+                'Name' => 'name',
133
+                'PluginURI' => 'homepage',
134
+                'Author' => 'author',
135
+                'AuthorName' => 'author',
136
+                'AuthorURI' => 'author_homepage',
137
+
138
+                'Requires WP' => 'requires',
139
+                'Tested WP' => 'tested',
140
+                'Requires at least' => 'requires',
141
+                'Tested up to' => 'tested',
142
+
143
+                'Requires PHP' => 'requires_php',
144
+            );
145
+            foreach ($headerToPropertyMap as $headerName => $property) {
146
+                if ( isset($fileHeader[$headerName]) && !empty($fileHeader[$headerName]) ) {
147
+                    $pluginInfo->$property = $fileHeader[$headerName];
148
+                }
149
+            }
150
+
151
+            if ( !empty($fileHeader['Description']) ) {
152
+                $pluginInfo->sections['description'] = $fileHeader['Description'];
153
+            }
154
+        }
155
+
156
+        /**
157
+         * Copy plugin metadata from the remote readme.txt file.
158
+         *
159
+         * @param string $ref GitHub tag or branch where to look for the readme.
160
+         * @param Plugin\PluginInfo $pluginInfo
161
+         */
162
+        protected function setInfoFromRemoteReadme($ref, $pluginInfo) {
163
+            $readme = $this->api->getRemoteReadme($ref);
164
+            if ( empty($readme) ) {
165
+                return;
166
+            }
167
+
168
+            if ( isset($readme['sections']) ) {
169
+                $pluginInfo->sections = array_merge($pluginInfo->sections, $readme['sections']);
170
+            }
171
+            if ( !empty($readme['tested_up_to']) ) {
172
+                $pluginInfo->tested = $readme['tested_up_to'];
173
+            }
174
+            if ( !empty($readme['requires_at_least']) ) {
175
+                $pluginInfo->requires = $readme['requires_at_least'];
176
+            }
177
+            if ( !empty($readme['requires_php']) ) {
178
+                $pluginInfo->requires_php = $readme['requires_php'];
179
+            }
180
+
181
+            if ( isset($readme['upgrade_notice'], $readme['upgrade_notice'][$pluginInfo->version]) ) {
182
+                $pluginInfo->upgrade_notice = $readme['upgrade_notice'][$pluginInfo->version];
183
+            }
184
+        }
185
+
186
+        /**
187
+         * Add icons from the currently installed version to a Plugin Info object.
188
+         *
189
+         * The icons should be in a subdirectory named "assets". Supported image formats
190
+         * and file names are described here:
191
+         * @link https://developer.wordpress.org/plugins/wordpress-org/plugin-assets/#plugin-icons
192
+         *
193
+         * @param Plugin\PluginInfo $pluginInfo
194
+         */
195
+        protected function setIconsFromLocalAssets($pluginInfo) {
196
+            $icons = $this->getLocalAssetUrls(array(
197
+                'icon.svg'         => 'svg',
198
+                'icon-256x256.png' => '2x',
199
+                'icon-256x256.jpg' => '2x',
200
+                'icon-128x128.png' => '1x',
201
+                'icon-128x128.jpg' => '1x',
202
+            ));
203
+
204
+            if ( !empty($icons) ) {
205
+                //The "default" key seems to be used only as last-resort fallback in WP core (5.8/5.9),
206
+                //but we'll set it anyway in case some code somewhere needs it.
207
+                reset($icons);
208
+                $firstKey = key($icons);
209
+                $icons['default'] = $icons[$firstKey];
210
+
211
+                $pluginInfo->icons = $icons;
212
+            }
213
+        }
214
+
215
+        /**
216
+         * Add banners from the currently installed version to a Plugin Info object.
217
+         *
218
+         * The banners should be in a subdirectory named "assets". Supported image formats
219
+         * and file names are described here:
220
+         * @link https://developer.wordpress.org/plugins/wordpress-org/plugin-assets/#plugin-headers
221
+         *
222
+         * @param Plugin\PluginInfo $pluginInfo
223
+         */
224
+        protected function setBannersFromLocalAssets($pluginInfo) {
225
+            $banners = $this->getLocalAssetUrls(array(
226
+                'banner-772x250.png' => 'high',
227
+                'banner-772x250.jpg' => 'high',
228
+                'banner-1544x500.png' => 'low',
229
+                'banner-1544x500.jpg' => 'low',
230
+            ));
231
+
232
+            if ( !empty($banners) ) {
233
+                $pluginInfo->banners = $banners;
234
+            }
235
+        }
236
+
237
+        /**
238
+         * @param array<string, string> $filesToKeys
239
+         * @return array<string, string>
240
+         */
241
+        protected function getLocalAssetUrls($filesToKeys) {
242
+            $assetDirectory = $this->package->getAbsoluteDirectoryPath() . DIRECTORY_SEPARATOR . 'assets';
243
+            if ( !is_dir($assetDirectory) ) {
244
+                return array();
245
+            }
246
+            $assetBaseUrl = trailingslashit(plugins_url('', $assetDirectory . '/imaginary.file'));
247
+
248
+            $foundAssets = array();
249
+            foreach ($filesToKeys as $fileName => $key) {
250
+                $fullBannerPath = $assetDirectory . DIRECTORY_SEPARATOR . $fileName;
251
+                if ( !isset($icons[$key]) && is_file($fullBannerPath) ) {
252
+                    $foundAssets[$key] = $assetBaseUrl . $fileName;
253
+                }
254
+            }
255
+
256
+            return $foundAssets;
257
+        }
258
+    }
259 259
 
260 260
 endif;
Please login to merge, or discard this patch.
Spacing   +23 added lines, -23 removed lines patch added patch discarded remove patch
@@ -4,7 +4,7 @@  discard block
 block discarded – undo
4 4
 
5 5
 use YahnisElsts\PluginUpdateChecker\v5p0\Plugin;
6 6
 
7
-if ( !class_exists(PluginUpdateChecker::class, false) ):
7
+if (!class_exists(PluginUpdateChecker::class, false)):
8 8
 
9 9
 	class PluginUpdateChecker extends Plugin\UpdateChecker implements BaseChecker {
10 10
 		use VcsCheckerMethods;
@@ -32,7 +32,7 @@  discard block
 block discarded – undo
32 32
 		public function requestInfo($unusedParameter = null) {
33 33
 			//We have to make several remote API requests to gather all the necessary info
34 34
 			//which can take a while on slow networks.
35
-			if ( function_exists('set_time_limit') ) {
35
+			if (function_exists('set_time_limit')) {
36 36
 				@set_time_limit(60);
37 37
 			}
38 38
 
@@ -49,16 +49,16 @@  discard block
 block discarded – undo
49 49
 
50 50
 			//Pick a branch or tag.
51 51
 			$updateSource = $api->chooseReference($this->branch);
52
-			if ( $updateSource ) {
52
+			if ($updateSource) {
53 53
 				$ref = $updateSource->name;
54 54
 				$info->version = $updateSource->version;
55 55
 				$info->last_updated = $updateSource->updated;
56 56
 				$info->download_url = $updateSource->downloadUrl;
57 57
 
58
-				if ( !empty($updateSource->changelog) ) {
58
+				if (!empty($updateSource->changelog)) {
59 59
 					$info->sections['changelog'] = $updateSource->changelog;
60 60
 				}
61
-				if ( isset($updateSource->downloadCount) ) {
61
+				if (isset($updateSource->downloadCount)) {
62 62
 					$info->downloaded = $updateSource->downloadCount;
63 63
 				}
64 64
 			} else {
@@ -80,29 +80,29 @@  discard block
 block discarded – undo
80 80
 			//are what the WordPress install will actually see after upgrading, so they take precedence over releases/tags.
81 81
 			$mainPluginFile = basename($this->pluginFile);
82 82
 			$remotePlugin = $api->getRemoteFile($mainPluginFile, $ref);
83
-			if ( !empty($remotePlugin) ) {
83
+			if (!empty($remotePlugin)) {
84 84
 				$remoteHeader = $this->package->getFileHeader($remotePlugin);
85 85
 				$this->setInfoFromHeader($remoteHeader, $info);
86 86
 			}
87 87
 
88 88
 			//Try parsing readme.txt. If it's formatted according to WordPress.org standards, it will contain
89 89
 			//a lot of useful information like the required/tested WP version, changelog, and so on.
90
-			if ( $this->readmeTxtExistsLocally() ) {
90
+			if ($this->readmeTxtExistsLocally()) {
91 91
 				$this->setInfoFromRemoteReadme($ref, $info);
92 92
 			}
93 93
 
94 94
 			//The changelog might be in a separate file.
95
-			if ( empty($info->sections['changelog']) ) {
95
+			if (empty($info->sections['changelog'])) {
96 96
 				$info->sections['changelog'] = $api->getRemoteChangelog($ref, $this->package->getAbsoluteDirectoryPath());
97
-				if ( empty($info->sections['changelog']) ) {
97
+				if (empty($info->sections['changelog'])) {
98 98
 					$info->sections['changelog'] = __('There is no changelog available.', 'plugin-update-checker');
99 99
 				}
100 100
 			}
101 101
 
102
-			if ( empty($info->last_updated) ) {
102
+			if (empty($info->last_updated)) {
103 103
 				//Fetch the latest commit that changed the tag or branch and use it as the "last_updated" date.
104 104
 				$latestCommitTime = $api->getLatestCommitTime($ref);
105
-				if ( $latestCommitTime !== null ) {
105
+				if ($latestCommitTime !== null) {
106 106
 					$info->last_updated = $latestCommitTime;
107 107
 				}
108 108
 			}
@@ -143,12 +143,12 @@  discard block
 block discarded – undo
143 143
 				'Requires PHP' => 'requires_php',
144 144
 			);
145 145
 			foreach ($headerToPropertyMap as $headerName => $property) {
146
-				if ( isset($fileHeader[$headerName]) && !empty($fileHeader[$headerName]) ) {
146
+				if (isset($fileHeader[$headerName]) && !empty($fileHeader[$headerName])) {
147 147
 					$pluginInfo->$property = $fileHeader[$headerName];
148 148
 				}
149 149
 			}
150 150
 
151
-			if ( !empty($fileHeader['Description']) ) {
151
+			if (!empty($fileHeader['Description'])) {
152 152
 				$pluginInfo->sections['description'] = $fileHeader['Description'];
153 153
 			}
154 154
 		}
@@ -161,24 +161,24 @@  discard block
 block discarded – undo
161 161
 		 */
162 162
 		protected function setInfoFromRemoteReadme($ref, $pluginInfo) {
163 163
 			$readme = $this->api->getRemoteReadme($ref);
164
-			if ( empty($readme) ) {
164
+			if (empty($readme)) {
165 165
 				return;
166 166
 			}
167 167
 
168
-			if ( isset($readme['sections']) ) {
168
+			if (isset($readme['sections'])) {
169 169
 				$pluginInfo->sections = array_merge($pluginInfo->sections, $readme['sections']);
170 170
 			}
171
-			if ( !empty($readme['tested_up_to']) ) {
171
+			if (!empty($readme['tested_up_to'])) {
172 172
 				$pluginInfo->tested = $readme['tested_up_to'];
173 173
 			}
174
-			if ( !empty($readme['requires_at_least']) ) {
174
+			if (!empty($readme['requires_at_least'])) {
175 175
 				$pluginInfo->requires = $readme['requires_at_least'];
176 176
 			}
177
-			if ( !empty($readme['requires_php']) ) {
177
+			if (!empty($readme['requires_php'])) {
178 178
 				$pluginInfo->requires_php = $readme['requires_php'];
179 179
 			}
180 180
 
181
-			if ( isset($readme['upgrade_notice'], $readme['upgrade_notice'][$pluginInfo->version]) ) {
181
+			if (isset($readme['upgrade_notice'], $readme['upgrade_notice'][$pluginInfo->version])) {
182 182
 				$pluginInfo->upgrade_notice = $readme['upgrade_notice'][$pluginInfo->version];
183 183
 			}
184 184
 		}
@@ -201,7 +201,7 @@  discard block
 block discarded – undo
201 201
 				'icon-128x128.jpg' => '1x',
202 202
 			));
203 203
 
204
-			if ( !empty($icons) ) {
204
+			if (!empty($icons)) {
205 205
 				//The "default" key seems to be used only as last-resort fallback in WP core (5.8/5.9),
206 206
 				//but we'll set it anyway in case some code somewhere needs it.
207 207
 				reset($icons);
@@ -229,7 +229,7 @@  discard block
 block discarded – undo
229 229
 				'banner-1544x500.jpg' => 'low',
230 230
 			));
231 231
 
232
-			if ( !empty($banners) ) {
232
+			if (!empty($banners)) {
233 233
 				$pluginInfo->banners = $banners;
234 234
 			}
235 235
 		}
@@ -240,7 +240,7 @@  discard block
 block discarded – undo
240 240
 		 */
241 241
 		protected function getLocalAssetUrls($filesToKeys) {
242 242
 			$assetDirectory = $this->package->getAbsoluteDirectoryPath() . DIRECTORY_SEPARATOR . 'assets';
243
-			if ( !is_dir($assetDirectory) ) {
243
+			if (!is_dir($assetDirectory)) {
244 244
 				return array();
245 245
 			}
246 246
 			$assetBaseUrl = trailingslashit(plugins_url('', $assetDirectory . '/imaginary.file'));
@@ -248,7 +248,7 @@  discard block
 block discarded – undo
248 248
 			$foundAssets = array();
249 249
 			foreach ($filesToKeys as $fileName => $key) {
250 250
 				$fullBannerPath = $assetDirectory . DIRECTORY_SEPARATOR . $fileName;
251
-				if ( !isset($icons[$key]) && is_file($fullBannerPath) ) {
251
+				if (!isset($icons[$key]) && is_file($fullBannerPath)) {
252 252
 					$foundAssets[$key] = $assetBaseUrl . $fileName;
253 253
 				}
254 254
 			}
Please login to merge, or discard this patch.
includes/plugin-update-checker-5-1.0/Puc/v5p0/Vcs/GitLabApi.php 2 patches
Indentation   +385 added lines, -385 removed lines patch added patch discarded remove patch
@@ -3,390 +3,390 @@
 block discarded – undo
3 3
 
4 4
 if ( !class_exists(GitLabApi::class, false) ):
5 5
 
6
-	class GitLabApi extends Api {
7
-		/**
8
-		 * @var string GitLab username.
9
-		 */
10
-		protected $userName;
11
-
12
-		/**
13
-		 * @var string GitLab server host.
14
-		 */
15
-		protected $repositoryHost;
16
-
17
-		/**
18
-		 * @var string Protocol used by this GitLab server: "http" or "https".
19
-		 */
20
-		protected $repositoryProtocol = 'https';
21
-
22
-		/**
23
-		 * @var string GitLab repository name.
24
-		 */
25
-		protected $repositoryName;
26
-
27
-		/**
28
-		 * @var string GitLab authentication token. Optional.
29
-		 */
30
-		protected $accessToken;
31
-
32
-		/**
33
-		 * @var bool Whether to download release assets instead of the auto-generated source code archives.
34
-		 */
35
-		protected $releaseAssetsEnabled = false;
36
-
37
-		/**
38
-		 * @var bool Whether to download release asset package rather than release asset source.
39
-		 */
40
-		protected $releasePackageEnabled = false;
41
-
42
-		public function __construct($repositoryUrl, $accessToken = null, $subgroup = null) {
43
-			//Parse the repository host to support custom hosts.
44
-			$port = wp_parse_url($repositoryUrl, PHP_URL_PORT);
45
-			if ( !empty($port) ) {
46
-				$port = ':' . $port;
47
-			}
48
-			$this->repositoryHost = wp_parse_url($repositoryUrl, PHP_URL_HOST) . $port;
49
-
50
-			if ( $this->repositoryHost !== 'gitlab.com' ) {
51
-				$this->repositoryProtocol = wp_parse_url($repositoryUrl, PHP_URL_SCHEME);
52
-			}
53
-
54
-			//Find the repository information
55
-			$path = wp_parse_url($repositoryUrl, PHP_URL_PATH);
56
-			if ( preg_match('@^/?(?P<username>[^/]+?)/(?P<repository>[^/#?&]+?)/?$@', $path, $matches) ) {
57
-				$this->userName = $matches['username'];
58
-				$this->repositoryName = $matches['repository'];
59
-			} elseif ( ($this->repositoryHost === 'gitlab.com') ) {
60
-				//This is probably a repository in a subgroup, e.g. "/organization/category/repo".
61
-				$parts = explode('/', trim($path, '/'));
62
-				if ( count($parts) < 3 ) {
63
-					throw new \InvalidArgumentException('Invalid GitLab.com repository URL: "' . $repositoryUrl . '"');
64
-				}
65
-				$lastPart = array_pop($parts);
66
-				$this->userName = implode('/', $parts);
67
-				$this->repositoryName = $lastPart;
68
-			} else {
69
-				//There could be subgroups in the URL:  gitlab.domain.com/group/subgroup/subgroup2/repository
70
-				if ( $subgroup !== null ) {
71
-					$path = str_replace(trailingslashit($subgroup), '', $path);
72
-				}
73
-
74
-				//This is not a traditional url, it could be gitlab is in a deeper subdirectory.
75
-				//Get the path segments.
76
-				$segments = explode('/', untrailingslashit(ltrim($path, '/')));
77
-
78
-				//We need at least /user-name/repository-name/
79
-				if ( count($segments) < 2 ) {
80
-					throw new \InvalidArgumentException('Invalid GitLab repository URL: "' . $repositoryUrl . '"');
81
-				}
82
-
83
-				//Get the username and repository name.
84
-				$usernameRepo = array_splice($segments, -2, 2);
85
-				$this->userName = $usernameRepo[0];
86
-				$this->repositoryName = $usernameRepo[1];
87
-
88
-				//Append the remaining segments to the host if there are segments left.
89
-				if ( count($segments) > 0 ) {
90
-					$this->repositoryHost = trailingslashit($this->repositoryHost) . implode('/', $segments);
91
-				}
92
-
93
-				//Add subgroups to username.
94
-				if ( $subgroup !== null ) {
95
-					$this->userName = $usernameRepo[0] . '/' . untrailingslashit($subgroup);
96
-				}
97
-			}
98
-
99
-			parent::__construct($repositoryUrl, $accessToken);
100
-		}
101
-
102
-		/**
103
-		 * Get the latest release from GitLab.
104
-		 *
105
-		 * @return Reference|null
106
-		 */
107
-		public function getLatestRelease() {
108
-			$releases = $this->api('/:id/releases');
109
-			if ( is_wp_error($releases) || empty($releases) || !is_array($releases) ) {
110
-				return null;
111
-			}
112
-
113
-			foreach ($releases as $release) {
114
-				if ( true !== $release->upcoming_release ) {
115
-					break 1; //Break the loop on the first release we find that isn't an upcoming release
116
-				}
117
-			}
118
-			if ( is_wp_error($release) || !is_object($release) || !isset($release->tag_name) ) {
119
-				return null;
120
-			}
121
-
122
-			$reference = new Reference(array(
123
-				'name'        => $release->tag_name,
124
-				'version'     => ltrim($release->tag_name, 'v'), //Remove the "v" prefix from "v1.2.3".
125
-				'downloadUrl' => '',
126
-				'updated'     => $release->released_at,
127
-				'apiResponse' => $release,
128
-			));
129
-			$download_url = false;
130
-
131
-			if ( $this->releasePackageEnabled && isset($release->assets, $release->assets->links) ) {
132
-				/**
133
-				 * Use the first asset LINK that is a zip format file generated by a Gitlab Release Pipeline
134
-				 *
135
-				 * @link https://gist.github.com/timwiel/9dfd3526c768efad4973254085e065ce
136
-				 */
137
-				foreach ($release->assets->links as $link) {
138
-					//TODO: Check the "format" property instead of the URL suffix.
139
-					if ( 'zip' === substr($link->url, -3) ) {
140
-						$download_url = $link->url;
141
-						break 1;
142
-					}
143
-				}
144
-				if ( empty( $download_url ) ) {
145
-					return null;
146
-				}
147
-				if ( ! empty( $this->accessToken ) ) {
148
-					$download_url = add_query_arg('private_token', $this->accessToken, $download_url);
149
-				}
150
-				$reference->downloadUrl = $download_url;
151
-				return $reference;
152
-
153
-			} elseif ( isset($release->assets) ) {
154
-				/**
155
-				 * Use the first asset SOURCE file that is a zip format from a Gitlab Release which should be a zip file
156
-				 */
157
-				foreach ($release->assets->sources as $source) {
158
-					if ( 'zip' === $source->format ) {
159
-						$download_url = $source->url;
160
-						break 1;
161
-					}
162
-				}
163
-				if ( empty( $download_url ) ) {
164
-					return null;
165
-				}
166
-				if ( ! empty( $this->accessToken ) ) {
167
-					$download_url = add_query_arg('private_token', $this->accessToken, $download_url);
168
-				}
169
-				$reference->downloadUrl = $download_url;
170
-				return $reference;
171
-
172
-			}
173
-
174
-			//If we get this far without a return then obviosuly noi release download urls were found
175
-			return null;
176
-			}
177
-
178
-		/**
179
-		 * Get the tag that looks like the highest version number.
180
-		 *
181
-		 * @return Reference|null
182
-		 */
183
-		public function getLatestTag() {
184
-			$tags = $this->api('/:id/repository/tags');
185
-			if ( is_wp_error($tags) || empty($tags) || !is_array($tags) ) {
186
-				return null;
187
-			}
188
-
189
-			$versionTags = $this->sortTagsByVersion($tags);
190
-			if ( empty($versionTags) ) {
191
-				return null;
192
-			}
193
-
194
-			$tag = $versionTags[0];
195
-			return new Reference(array(
196
-				'name'        => $tag->name,
197
-				'version'     => ltrim($tag->name, 'v'),
198
-				'downloadUrl' => $this->buildArchiveDownloadUrl($tag->name),
199
-				'apiResponse' => $tag,
200
-			));
201
-		}
202
-
203
-		/**
204
-		 * Get a branch by name.
205
-		 *
206
-		 * @param string $branchName
207
-		 * @return null|Reference
208
-		 */
209
-		public function getBranch($branchName) {
210
-			$branch = $this->api('/:id/repository/branches/' . $branchName);
211
-			if ( is_wp_error($branch) || empty($branch) ) {
212
-				return null;
213
-			}
214
-
215
-			$reference = new Reference(array(
216
-				'name'        => $branch->name,
217
-				'downloadUrl' => $this->buildArchiveDownloadUrl($branch->name),
218
-				'apiResponse' => $branch,
219
-			));
220
-
221
-			if ( isset($branch->commit, $branch->commit->committed_date) ) {
222
-				$reference->updated = $branch->commit->committed_date;
223
-			}
224
-
225
-			return $reference;
226
-		}
227
-
228
-		/**
229
-		 * Get the timestamp of the latest commit that changed the specified branch or tag.
230
-		 *
231
-		 * @param string $ref Reference name (e.g. branch or tag).
232
-		 * @return string|null
233
-		 */
234
-		public function getLatestCommitTime($ref) {
235
-			$commits = $this->api('/:id/repository/commits/', array('ref_name' => $ref));
236
-			if ( is_wp_error($commits) || !is_array($commits) || !isset($commits[0]) ) {
237
-				return null;
238
-			}
239
-
240
-			return $commits[0]->committed_date;
241
-		}
242
-
243
-		/**
244
-		 * Perform a GitLab API request.
245
-		 *
246
-		 * @param string $url
247
-		 * @param array $queryParams
248
-		 * @return mixed|\WP_Error
249
-		 */
250
-		protected function api($url, $queryParams = array()) {
251
-			$baseUrl = $url;
252
-			$url = $this->buildApiUrl($url, $queryParams);
253
-
254
-			$options = array('timeout' => 10);
255
-			if ( !empty($this->httpFilterName) ) {
256
-				$options = apply_filters($this->httpFilterName, $options);
257
-			}
258
-
259
-			$response = wp_remote_get($url, $options);
260
-			if ( is_wp_error($response) ) {
261
-				do_action('puc_api_error', $response, null, $url, $this->slug);
262
-				return $response;
263
-			}
264
-
265
-			$code = wp_remote_retrieve_response_code($response);
266
-			$body = wp_remote_retrieve_body($response);
267
-			if ( $code === 200 ) {
268
-				return json_decode($body);
269
-			}
270
-
271
-			$error = new \WP_Error(
272
-				'puc-gitlab-http-error',
273
-				sprintf('GitLab API error. URL: "%s",  HTTP status code: %d.', $baseUrl, $code)
274
-			);
275
-			do_action('puc_api_error', $error, $response, $url, $this->slug);
276
-
277
-			return $error;
278
-		}
279
-
280
-		/**
281
-		 * Build a fully qualified URL for an API request.
282
-		 *
283
-		 * @param string $url
284
-		 * @param array $queryParams
285
-		 * @return string
286
-		 */
287
-		protected function buildApiUrl($url, $queryParams) {
288
-			$variables = array(
289
-				'user' => $this->userName,
290
-				'repo' => $this->repositoryName,
291
-				'id'   => $this->userName . '/' . $this->repositoryName,
292
-			);
293
-
294
-			foreach ($variables as $name => $value) {
295
-				$url = str_replace("/:{$name}", '/' . urlencode($value), $url);
296
-			}
297
-
298
-			$url = substr($url, 1);
299
-			$url = sprintf('%1$s://%2$s/api/v4/projects/%3$s', $this->repositoryProtocol, $this->repositoryHost, $url);
300
-
301
-			if ( !empty($this->accessToken) ) {
302
-				$queryParams['private_token'] = $this->accessToken;
303
-			}
304
-
305
-			if ( !empty($queryParams) ) {
306
-				$url = add_query_arg($queryParams, $url);
307
-			}
308
-
309
-			return $url;
310
-		}
311
-
312
-		/**
313
-		 * Get the contents of a file from a specific branch or tag.
314
-		 *
315
-		 * @param string $path File name.
316
-		 * @param string $ref
317
-		 * @return null|string Either the contents of the file, or null if the file doesn't exist or there's an error.
318
-		 */
319
-		public function getRemoteFile($path, $ref = 'master') {
320
-			$response = $this->api('/:id/repository/files/' . $path, array('ref' => $ref));
321
-			if ( is_wp_error($response) || !isset($response->content) || $response->encoding !== 'base64' ) {
322
-				return null;
323
-			}
324
-
325
-			return base64_decode($response->content);
326
-		}
327
-
328
-		/**
329
-		 * Generate a URL to download a ZIP archive of the specified branch/tag/etc.
330
-		 *
331
-		 * @param string $ref
332
-		 * @return string
333
-		 */
334
-		public function buildArchiveDownloadUrl($ref = 'master') {
335
-			$url = sprintf(
336
-				'%1$s://%2$s/api/v4/projects/%3$s/repository/archive.zip',
337
-				$this->repositoryProtocol,
338
-				$this->repositoryHost,
339
-				urlencode($this->userName . '/' . $this->repositoryName)
340
-			);
341
-			$url = add_query_arg('sha', urlencode($ref), $url);
342
-
343
-			if ( !empty($this->accessToken) ) {
344
-				$url = add_query_arg('private_token', $this->accessToken, $url);
345
-			}
346
-
347
-			return $url;
348
-		}
349
-
350
-		/**
351
-		 * Get a specific tag.
352
-		 *
353
-		 * @param string $tagName
354
-		 * @return void
355
-		 */
356
-		public function getTag($tagName) {
357
-			throw new \LogicException('The ' . __METHOD__ . ' method is not implemented and should not be used.');
358
-		}
359
-
360
-		protected function getUpdateDetectionStrategies($configBranch) {
361
-			$strategies = array();
362
-
363
-			if ( ($configBranch === 'main') || ($configBranch === 'master') ) {
364
-				$strategies[self::STRATEGY_LATEST_RELEASE] = array($this, 'getLatestRelease');
365
-				$strategies[self::STRATEGY_LATEST_TAG] = array($this, 'getLatestTag');
366
-			}
367
-
368
-			$strategies[self::STRATEGY_BRANCH] = function() use ($configBranch) {
369
-				return $this->getBranch($configBranch);
370
-			};
371
-
372
-			return $strategies;
373
-		}
374
-
375
-		public function setAuthentication($credentials) {
376
-			parent::setAuthentication($credentials);
377
-			$this->accessToken = is_string($credentials) ? $credentials : null;
378
-		}
379
-
380
-		public function enableReleaseAssets() {
381
-			$this->releaseAssetsEnabled  = true;
382
-			$this->releasePackageEnabled = false;
383
-		}
384
-
385
-		public function enableReleasePackages() {
386
-			$this->releaseAssetsEnabled  = false;
387
-			$this->releasePackageEnabled = true;
388
-		}
389
-
390
-	}
6
+    class GitLabApi extends Api {
7
+        /**
8
+         * @var string GitLab username.
9
+         */
10
+        protected $userName;
11
+
12
+        /**
13
+         * @var string GitLab server host.
14
+         */
15
+        protected $repositoryHost;
16
+
17
+        /**
18
+         * @var string Protocol used by this GitLab server: "http" or "https".
19
+         */
20
+        protected $repositoryProtocol = 'https';
21
+
22
+        /**
23
+         * @var string GitLab repository name.
24
+         */
25
+        protected $repositoryName;
26
+
27
+        /**
28
+         * @var string GitLab authentication token. Optional.
29
+         */
30
+        protected $accessToken;
31
+
32
+        /**
33
+         * @var bool Whether to download release assets instead of the auto-generated source code archives.
34
+         */
35
+        protected $releaseAssetsEnabled = false;
36
+
37
+        /**
38
+         * @var bool Whether to download release asset package rather than release asset source.
39
+         */
40
+        protected $releasePackageEnabled = false;
41
+
42
+        public function __construct($repositoryUrl, $accessToken = null, $subgroup = null) {
43
+            //Parse the repository host to support custom hosts.
44
+            $port = wp_parse_url($repositoryUrl, PHP_URL_PORT);
45
+            if ( !empty($port) ) {
46
+                $port = ':' . $port;
47
+            }
48
+            $this->repositoryHost = wp_parse_url($repositoryUrl, PHP_URL_HOST) . $port;
49
+
50
+            if ( $this->repositoryHost !== 'gitlab.com' ) {
51
+                $this->repositoryProtocol = wp_parse_url($repositoryUrl, PHP_URL_SCHEME);
52
+            }
53
+
54
+            //Find the repository information
55
+            $path = wp_parse_url($repositoryUrl, PHP_URL_PATH);
56
+            if ( preg_match('@^/?(?P<username>[^/]+?)/(?P<repository>[^/#?&]+?)/?$@', $path, $matches) ) {
57
+                $this->userName = $matches['username'];
58
+                $this->repositoryName = $matches['repository'];
59
+            } elseif ( ($this->repositoryHost === 'gitlab.com') ) {
60
+                //This is probably a repository in a subgroup, e.g. "/organization/category/repo".
61
+                $parts = explode('/', trim($path, '/'));
62
+                if ( count($parts) < 3 ) {
63
+                    throw new \InvalidArgumentException('Invalid GitLab.com repository URL: "' . $repositoryUrl . '"');
64
+                }
65
+                $lastPart = array_pop($parts);
66
+                $this->userName = implode('/', $parts);
67
+                $this->repositoryName = $lastPart;
68
+            } else {
69
+                //There could be subgroups in the URL:  gitlab.domain.com/group/subgroup/subgroup2/repository
70
+                if ( $subgroup !== null ) {
71
+                    $path = str_replace(trailingslashit($subgroup), '', $path);
72
+                }
73
+
74
+                //This is not a traditional url, it could be gitlab is in a deeper subdirectory.
75
+                //Get the path segments.
76
+                $segments = explode('/', untrailingslashit(ltrim($path, '/')));
77
+
78
+                //We need at least /user-name/repository-name/
79
+                if ( count($segments) < 2 ) {
80
+                    throw new \InvalidArgumentException('Invalid GitLab repository URL: "' . $repositoryUrl . '"');
81
+                }
82
+
83
+                //Get the username and repository name.
84
+                $usernameRepo = array_splice($segments, -2, 2);
85
+                $this->userName = $usernameRepo[0];
86
+                $this->repositoryName = $usernameRepo[1];
87
+
88
+                //Append the remaining segments to the host if there are segments left.
89
+                if ( count($segments) > 0 ) {
90
+                    $this->repositoryHost = trailingslashit($this->repositoryHost) . implode('/', $segments);
91
+                }
92
+
93
+                //Add subgroups to username.
94
+                if ( $subgroup !== null ) {
95
+                    $this->userName = $usernameRepo[0] . '/' . untrailingslashit($subgroup);
96
+                }
97
+            }
98
+
99
+            parent::__construct($repositoryUrl, $accessToken);
100
+        }
101
+
102
+        /**
103
+         * Get the latest release from GitLab.
104
+         *
105
+         * @return Reference|null
106
+         */
107
+        public function getLatestRelease() {
108
+            $releases = $this->api('/:id/releases');
109
+            if ( is_wp_error($releases) || empty($releases) || !is_array($releases) ) {
110
+                return null;
111
+            }
112
+
113
+            foreach ($releases as $release) {
114
+                if ( true !== $release->upcoming_release ) {
115
+                    break 1; //Break the loop on the first release we find that isn't an upcoming release
116
+                }
117
+            }
118
+            if ( is_wp_error($release) || !is_object($release) || !isset($release->tag_name) ) {
119
+                return null;
120
+            }
121
+
122
+            $reference = new Reference(array(
123
+                'name'        => $release->tag_name,
124
+                'version'     => ltrim($release->tag_name, 'v'), //Remove the "v" prefix from "v1.2.3".
125
+                'downloadUrl' => '',
126
+                'updated'     => $release->released_at,
127
+                'apiResponse' => $release,
128
+            ));
129
+            $download_url = false;
130
+
131
+            if ( $this->releasePackageEnabled && isset($release->assets, $release->assets->links) ) {
132
+                /**
133
+                 * Use the first asset LINK that is a zip format file generated by a Gitlab Release Pipeline
134
+                 *
135
+                 * @link https://gist.github.com/timwiel/9dfd3526c768efad4973254085e065ce
136
+                 */
137
+                foreach ($release->assets->links as $link) {
138
+                    //TODO: Check the "format" property instead of the URL suffix.
139
+                    if ( 'zip' === substr($link->url, -3) ) {
140
+                        $download_url = $link->url;
141
+                        break 1;
142
+                    }
143
+                }
144
+                if ( empty( $download_url ) ) {
145
+                    return null;
146
+                }
147
+                if ( ! empty( $this->accessToken ) ) {
148
+                    $download_url = add_query_arg('private_token', $this->accessToken, $download_url);
149
+                }
150
+                $reference->downloadUrl = $download_url;
151
+                return $reference;
152
+
153
+            } elseif ( isset($release->assets) ) {
154
+                /**
155
+                 * Use the first asset SOURCE file that is a zip format from a Gitlab Release which should be a zip file
156
+                 */
157
+                foreach ($release->assets->sources as $source) {
158
+                    if ( 'zip' === $source->format ) {
159
+                        $download_url = $source->url;
160
+                        break 1;
161
+                    }
162
+                }
163
+                if ( empty( $download_url ) ) {
164
+                    return null;
165
+                }
166
+                if ( ! empty( $this->accessToken ) ) {
167
+                    $download_url = add_query_arg('private_token', $this->accessToken, $download_url);
168
+                }
169
+                $reference->downloadUrl = $download_url;
170
+                return $reference;
171
+
172
+            }
173
+
174
+            //If we get this far without a return then obviosuly noi release download urls were found
175
+            return null;
176
+            }
177
+
178
+        /**
179
+         * Get the tag that looks like the highest version number.
180
+         *
181
+         * @return Reference|null
182
+         */
183
+        public function getLatestTag() {
184
+            $tags = $this->api('/:id/repository/tags');
185
+            if ( is_wp_error($tags) || empty($tags) || !is_array($tags) ) {
186
+                return null;
187
+            }
188
+
189
+            $versionTags = $this->sortTagsByVersion($tags);
190
+            if ( empty($versionTags) ) {
191
+                return null;
192
+            }
193
+
194
+            $tag = $versionTags[0];
195
+            return new Reference(array(
196
+                'name'        => $tag->name,
197
+                'version'     => ltrim($tag->name, 'v'),
198
+                'downloadUrl' => $this->buildArchiveDownloadUrl($tag->name),
199
+                'apiResponse' => $tag,
200
+            ));
201
+        }
202
+
203
+        /**
204
+         * Get a branch by name.
205
+         *
206
+         * @param string $branchName
207
+         * @return null|Reference
208
+         */
209
+        public function getBranch($branchName) {
210
+            $branch = $this->api('/:id/repository/branches/' . $branchName);
211
+            if ( is_wp_error($branch) || empty($branch) ) {
212
+                return null;
213
+            }
214
+
215
+            $reference = new Reference(array(
216
+                'name'        => $branch->name,
217
+                'downloadUrl' => $this->buildArchiveDownloadUrl($branch->name),
218
+                'apiResponse' => $branch,
219
+            ));
220
+
221
+            if ( isset($branch->commit, $branch->commit->committed_date) ) {
222
+                $reference->updated = $branch->commit->committed_date;
223
+            }
224
+
225
+            return $reference;
226
+        }
227
+
228
+        /**
229
+         * Get the timestamp of the latest commit that changed the specified branch or tag.
230
+         *
231
+         * @param string $ref Reference name (e.g. branch or tag).
232
+         * @return string|null
233
+         */
234
+        public function getLatestCommitTime($ref) {
235
+            $commits = $this->api('/:id/repository/commits/', array('ref_name' => $ref));
236
+            if ( is_wp_error($commits) || !is_array($commits) || !isset($commits[0]) ) {
237
+                return null;
238
+            }
239
+
240
+            return $commits[0]->committed_date;
241
+        }
242
+
243
+        /**
244
+         * Perform a GitLab API request.
245
+         *
246
+         * @param string $url
247
+         * @param array $queryParams
248
+         * @return mixed|\WP_Error
249
+         */
250
+        protected function api($url, $queryParams = array()) {
251
+            $baseUrl = $url;
252
+            $url = $this->buildApiUrl($url, $queryParams);
253
+
254
+            $options = array('timeout' => 10);
255
+            if ( !empty($this->httpFilterName) ) {
256
+                $options = apply_filters($this->httpFilterName, $options);
257
+            }
258
+
259
+            $response = wp_remote_get($url, $options);
260
+            if ( is_wp_error($response) ) {
261
+                do_action('puc_api_error', $response, null, $url, $this->slug);
262
+                return $response;
263
+            }
264
+
265
+            $code = wp_remote_retrieve_response_code($response);
266
+            $body = wp_remote_retrieve_body($response);
267
+            if ( $code === 200 ) {
268
+                return json_decode($body);
269
+            }
270
+
271
+            $error = new \WP_Error(
272
+                'puc-gitlab-http-error',
273
+                sprintf('GitLab API error. URL: "%s",  HTTP status code: %d.', $baseUrl, $code)
274
+            );
275
+            do_action('puc_api_error', $error, $response, $url, $this->slug);
276
+
277
+            return $error;
278
+        }
279
+
280
+        /**
281
+         * Build a fully qualified URL for an API request.
282
+         *
283
+         * @param string $url
284
+         * @param array $queryParams
285
+         * @return string
286
+         */
287
+        protected function buildApiUrl($url, $queryParams) {
288
+            $variables = array(
289
+                'user' => $this->userName,
290
+                'repo' => $this->repositoryName,
291
+                'id'   => $this->userName . '/' . $this->repositoryName,
292
+            );
293
+
294
+            foreach ($variables as $name => $value) {
295
+                $url = str_replace("/:{$name}", '/' . urlencode($value), $url);
296
+            }
297
+
298
+            $url = substr($url, 1);
299
+            $url = sprintf('%1$s://%2$s/api/v4/projects/%3$s', $this->repositoryProtocol, $this->repositoryHost, $url);
300
+
301
+            if ( !empty($this->accessToken) ) {
302
+                $queryParams['private_token'] = $this->accessToken;
303
+            }
304
+
305
+            if ( !empty($queryParams) ) {
306
+                $url = add_query_arg($queryParams, $url);
307
+            }
308
+
309
+            return $url;
310
+        }
311
+
312
+        /**
313
+         * Get the contents of a file from a specific branch or tag.
314
+         *
315
+         * @param string $path File name.
316
+         * @param string $ref
317
+         * @return null|string Either the contents of the file, or null if the file doesn't exist or there's an error.
318
+         */
319
+        public function getRemoteFile($path, $ref = 'master') {
320
+            $response = $this->api('/:id/repository/files/' . $path, array('ref' => $ref));
321
+            if ( is_wp_error($response) || !isset($response->content) || $response->encoding !== 'base64' ) {
322
+                return null;
323
+            }
324
+
325
+            return base64_decode($response->content);
326
+        }
327
+
328
+        /**
329
+         * Generate a URL to download a ZIP archive of the specified branch/tag/etc.
330
+         *
331
+         * @param string $ref
332
+         * @return string
333
+         */
334
+        public function buildArchiveDownloadUrl($ref = 'master') {
335
+            $url = sprintf(
336
+                '%1$s://%2$s/api/v4/projects/%3$s/repository/archive.zip',
337
+                $this->repositoryProtocol,
338
+                $this->repositoryHost,
339
+                urlencode($this->userName . '/' . $this->repositoryName)
340
+            );
341
+            $url = add_query_arg('sha', urlencode($ref), $url);
342
+
343
+            if ( !empty($this->accessToken) ) {
344
+                $url = add_query_arg('private_token', $this->accessToken, $url);
345
+            }
346
+
347
+            return $url;
348
+        }
349
+
350
+        /**
351
+         * Get a specific tag.
352
+         *
353
+         * @param string $tagName
354
+         * @return void
355
+         */
356
+        public function getTag($tagName) {
357
+            throw new \LogicException('The ' . __METHOD__ . ' method is not implemented and should not be used.');
358
+        }
359
+
360
+        protected function getUpdateDetectionStrategies($configBranch) {
361
+            $strategies = array();
362
+
363
+            if ( ($configBranch === 'main') || ($configBranch === 'master') ) {
364
+                $strategies[self::STRATEGY_LATEST_RELEASE] = array($this, 'getLatestRelease');
365
+                $strategies[self::STRATEGY_LATEST_TAG] = array($this, 'getLatestTag');
366
+            }
367
+
368
+            $strategies[self::STRATEGY_BRANCH] = function() use ($configBranch) {
369
+                return $this->getBranch($configBranch);
370
+            };
371
+
372
+            return $strategies;
373
+        }
374
+
375
+        public function setAuthentication($credentials) {
376
+            parent::setAuthentication($credentials);
377
+            $this->accessToken = is_string($credentials) ? $credentials : null;
378
+        }
379
+
380
+        public function enableReleaseAssets() {
381
+            $this->releaseAssetsEnabled  = true;
382
+            $this->releasePackageEnabled = false;
383
+        }
384
+
385
+        public function enableReleasePackages() {
386
+            $this->releaseAssetsEnabled  = false;
387
+            $this->releasePackageEnabled = true;
388
+        }
389
+
390
+    }
391 391
 
392 392
 endif;
Please login to merge, or discard this patch.
Spacing   +34 added lines, -34 removed lines patch added patch discarded remove patch
@@ -1,7 +1,7 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 namespace YahnisElsts\PluginUpdateChecker\v5p0\Vcs;
3 3
 
4
-if ( !class_exists(GitLabApi::class, false) ):
4
+if (!class_exists(GitLabApi::class, false)):
5 5
 
6 6
 	class GitLabApi extends Api {
7 7
 		/**
@@ -42,24 +42,24 @@  discard block
 block discarded – undo
42 42
 		public function __construct($repositoryUrl, $accessToken = null, $subgroup = null) {
43 43
 			//Parse the repository host to support custom hosts.
44 44
 			$port = wp_parse_url($repositoryUrl, PHP_URL_PORT);
45
-			if ( !empty($port) ) {
45
+			if (!empty($port)) {
46 46
 				$port = ':' . $port;
47 47
 			}
48 48
 			$this->repositoryHost = wp_parse_url($repositoryUrl, PHP_URL_HOST) . $port;
49 49
 
50
-			if ( $this->repositoryHost !== 'gitlab.com' ) {
50
+			if ($this->repositoryHost !== 'gitlab.com') {
51 51
 				$this->repositoryProtocol = wp_parse_url($repositoryUrl, PHP_URL_SCHEME);
52 52
 			}
53 53
 
54 54
 			//Find the repository information
55 55
 			$path = wp_parse_url($repositoryUrl, PHP_URL_PATH);
56
-			if ( preg_match('@^/?(?P<username>[^/]+?)/(?P<repository>[^/#?&]+?)/?$@', $path, $matches) ) {
56
+			if (preg_match('@^/?(?P<username>[^/]+?)/(?P<repository>[^/#?&]+?)/?$@', $path, $matches)) {
57 57
 				$this->userName = $matches['username'];
58 58
 				$this->repositoryName = $matches['repository'];
59
-			} elseif ( ($this->repositoryHost === 'gitlab.com') ) {
59
+			} elseif (($this->repositoryHost === 'gitlab.com')) {
60 60
 				//This is probably a repository in a subgroup, e.g. "/organization/category/repo".
61 61
 				$parts = explode('/', trim($path, '/'));
62
-				if ( count($parts) < 3 ) {
62
+				if (count($parts) < 3) {
63 63
 					throw new \InvalidArgumentException('Invalid GitLab.com repository URL: "' . $repositoryUrl . '"');
64 64
 				}
65 65
 				$lastPart = array_pop($parts);
@@ -67,7 +67,7 @@  discard block
 block discarded – undo
67 67
 				$this->repositoryName = $lastPart;
68 68
 			} else {
69 69
 				//There could be subgroups in the URL:  gitlab.domain.com/group/subgroup/subgroup2/repository
70
-				if ( $subgroup !== null ) {
70
+				if ($subgroup !== null) {
71 71
 					$path = str_replace(trailingslashit($subgroup), '', $path);
72 72
 				}
73 73
 
@@ -76,7 +76,7 @@  discard block
 block discarded – undo
76 76
 				$segments = explode('/', untrailingslashit(ltrim($path, '/')));
77 77
 
78 78
 				//We need at least /user-name/repository-name/
79
-				if ( count($segments) < 2 ) {
79
+				if (count($segments) < 2) {
80 80
 					throw new \InvalidArgumentException('Invalid GitLab repository URL: "' . $repositoryUrl . '"');
81 81
 				}
82 82
 
@@ -86,12 +86,12 @@  discard block
 block discarded – undo
86 86
 				$this->repositoryName = $usernameRepo[1];
87 87
 
88 88
 				//Append the remaining segments to the host if there are segments left.
89
-				if ( count($segments) > 0 ) {
89
+				if (count($segments) > 0) {
90 90
 					$this->repositoryHost = trailingslashit($this->repositoryHost) . implode('/', $segments);
91 91
 				}
92 92
 
93 93
 				//Add subgroups to username.
94
-				if ( $subgroup !== null ) {
94
+				if ($subgroup !== null) {
95 95
 					$this->userName = $usernameRepo[0] . '/' . untrailingslashit($subgroup);
96 96
 				}
97 97
 			}
@@ -106,16 +106,16 @@  discard block
 block discarded – undo
106 106
 		 */
107 107
 		public function getLatestRelease() {
108 108
 			$releases = $this->api('/:id/releases');
109
-			if ( is_wp_error($releases) || empty($releases) || !is_array($releases) ) {
109
+			if (is_wp_error($releases) || empty($releases) || !is_array($releases)) {
110 110
 				return null;
111 111
 			}
112 112
 
113 113
 			foreach ($releases as $release) {
114
-				if ( true !== $release->upcoming_release ) {
114
+				if (true !== $release->upcoming_release) {
115 115
 					break 1; //Break the loop on the first release we find that isn't an upcoming release
116 116
 				}
117 117
 			}
118
-			if ( is_wp_error($release) || !is_object($release) || !isset($release->tag_name) ) {
118
+			if (is_wp_error($release) || !is_object($release) || !isset($release->tag_name)) {
119 119
 				return null;
120 120
 			}
121 121
 
@@ -128,7 +128,7 @@  discard block
 block discarded – undo
128 128
 			));
129 129
 			$download_url = false;
130 130
 
131
-			if ( $this->releasePackageEnabled && isset($release->assets, $release->assets->links) ) {
131
+			if ($this->releasePackageEnabled && isset($release->assets, $release->assets->links)) {
132 132
 				/**
133 133
 				 * Use the first asset LINK that is a zip format file generated by a Gitlab Release Pipeline
134 134
 				 *
@@ -136,34 +136,34 @@  discard block
 block discarded – undo
136 136
 				 */
137 137
 				foreach ($release->assets->links as $link) {
138 138
 					//TODO: Check the "format" property instead of the URL suffix.
139
-					if ( 'zip' === substr($link->url, -3) ) {
139
+					if ('zip' === substr($link->url, -3)) {
140 140
 						$download_url = $link->url;
141 141
 						break 1;
142 142
 					}
143 143
 				}
144
-				if ( empty( $download_url ) ) {
144
+				if (empty($download_url)) {
145 145
 					return null;
146 146
 				}
147
-				if ( ! empty( $this->accessToken ) ) {
147
+				if (!empty($this->accessToken)) {
148 148
 					$download_url = add_query_arg('private_token', $this->accessToken, $download_url);
149 149
 				}
150 150
 				$reference->downloadUrl = $download_url;
151 151
 				return $reference;
152 152
 
153
-			} elseif ( isset($release->assets) ) {
153
+			} elseif (isset($release->assets)) {
154 154
 				/**
155 155
 				 * Use the first asset SOURCE file that is a zip format from a Gitlab Release which should be a zip file
156 156
 				 */
157 157
 				foreach ($release->assets->sources as $source) {
158
-					if ( 'zip' === $source->format ) {
158
+					if ('zip' === $source->format) {
159 159
 						$download_url = $source->url;
160 160
 						break 1;
161 161
 					}
162 162
 				}
163
-				if ( empty( $download_url ) ) {
163
+				if (empty($download_url)) {
164 164
 					return null;
165 165
 				}
166
-				if ( ! empty( $this->accessToken ) ) {
166
+				if (!empty($this->accessToken)) {
167 167
 					$download_url = add_query_arg('private_token', $this->accessToken, $download_url);
168 168
 				}
169 169
 				$reference->downloadUrl = $download_url;
@@ -182,12 +182,12 @@  discard block
 block discarded – undo
182 182
 		 */
183 183
 		public function getLatestTag() {
184 184
 			$tags = $this->api('/:id/repository/tags');
185
-			if ( is_wp_error($tags) || empty($tags) || !is_array($tags) ) {
185
+			if (is_wp_error($tags) || empty($tags) || !is_array($tags)) {
186 186
 				return null;
187 187
 			}
188 188
 
189 189
 			$versionTags = $this->sortTagsByVersion($tags);
190
-			if ( empty($versionTags) ) {
190
+			if (empty($versionTags)) {
191 191
 				return null;
192 192
 			}
193 193
 
@@ -208,7 +208,7 @@  discard block
 block discarded – undo
208 208
 		 */
209 209
 		public function getBranch($branchName) {
210 210
 			$branch = $this->api('/:id/repository/branches/' . $branchName);
211
-			if ( is_wp_error($branch) || empty($branch) ) {
211
+			if (is_wp_error($branch) || empty($branch)) {
212 212
 				return null;
213 213
 			}
214 214
 
@@ -218,7 +218,7 @@  discard block
 block discarded – undo
218 218
 				'apiResponse' => $branch,
219 219
 			));
220 220
 
221
-			if ( isset($branch->commit, $branch->commit->committed_date) ) {
221
+			if (isset($branch->commit, $branch->commit->committed_date)) {
222 222
 				$reference->updated = $branch->commit->committed_date;
223 223
 			}
224 224
 
@@ -233,7 +233,7 @@  discard block
 block discarded – undo
233 233
 		 */
234 234
 		public function getLatestCommitTime($ref) {
235 235
 			$commits = $this->api('/:id/repository/commits/', array('ref_name' => $ref));
236
-			if ( is_wp_error($commits) || !is_array($commits) || !isset($commits[0]) ) {
236
+			if (is_wp_error($commits) || !is_array($commits) || !isset($commits[0])) {
237 237
 				return null;
238 238
 			}
239 239
 
@@ -252,19 +252,19 @@  discard block
 block discarded – undo
252 252
 			$url = $this->buildApiUrl($url, $queryParams);
253 253
 
254 254
 			$options = array('timeout' => 10);
255
-			if ( !empty($this->httpFilterName) ) {
255
+			if (!empty($this->httpFilterName)) {
256 256
 				$options = apply_filters($this->httpFilterName, $options);
257 257
 			}
258 258
 
259 259
 			$response = wp_remote_get($url, $options);
260
-			if ( is_wp_error($response) ) {
260
+			if (is_wp_error($response)) {
261 261
 				do_action('puc_api_error', $response, null, $url, $this->slug);
262 262
 				return $response;
263 263
 			}
264 264
 
265 265
 			$code = wp_remote_retrieve_response_code($response);
266 266
 			$body = wp_remote_retrieve_body($response);
267
-			if ( $code === 200 ) {
267
+			if ($code === 200) {
268 268
 				return json_decode($body);
269 269
 			}
270 270
 
@@ -298,11 +298,11 @@  discard block
 block discarded – undo
298 298
 			$url = substr($url, 1);
299 299
 			$url = sprintf('%1$s://%2$s/api/v4/projects/%3$s', $this->repositoryProtocol, $this->repositoryHost, $url);
300 300
 
301
-			if ( !empty($this->accessToken) ) {
301
+			if (!empty($this->accessToken)) {
302 302
 				$queryParams['private_token'] = $this->accessToken;
303 303
 			}
304 304
 
305
-			if ( !empty($queryParams) ) {
305
+			if (!empty($queryParams)) {
306 306
 				$url = add_query_arg($queryParams, $url);
307 307
 			}
308 308
 
@@ -318,7 +318,7 @@  discard block
 block discarded – undo
318 318
 		 */
319 319
 		public function getRemoteFile($path, $ref = 'master') {
320 320
 			$response = $this->api('/:id/repository/files/' . $path, array('ref' => $ref));
321
-			if ( is_wp_error($response) || !isset($response->content) || $response->encoding !== 'base64' ) {
321
+			if (is_wp_error($response) || !isset($response->content) || $response->encoding !== 'base64') {
322 322
 				return null;
323 323
 			}
324 324
 
@@ -340,7 +340,7 @@  discard block
 block discarded – undo
340 340
 			);
341 341
 			$url = add_query_arg('sha', urlencode($ref), $url);
342 342
 
343
-			if ( !empty($this->accessToken) ) {
343
+			if (!empty($this->accessToken)) {
344 344
 				$url = add_query_arg('private_token', $this->accessToken, $url);
345 345
 			}
346 346
 
@@ -360,7 +360,7 @@  discard block
 block discarded – undo
360 360
 		protected function getUpdateDetectionStrategies($configBranch) {
361 361
 			$strategies = array();
362 362
 
363
-			if ( ($configBranch === 'main') || ($configBranch === 'master') ) {
363
+			if (($configBranch === 'main') || ($configBranch === 'master')) {
364 364
 				$strategies[self::STRATEGY_LATEST_RELEASE] = array($this, 'getLatestRelease');
365 365
 				$strategies[self::STRATEGY_LATEST_TAG] = array($this, 'getLatestTag');
366 366
 			}
Please login to merge, or discard this patch.
includes/plugin-update-checker-5-1.0/Puc/v5p0/Vcs/Reference.php 2 patches
Indentation   +44 added lines, -44 removed lines patch added patch discarded remove patch
@@ -3,49 +3,49 @@
 block discarded – undo
3 3
 
4 4
 if ( !class_exists(Reference::class, false) ):
5 5
 
6
-	/**
7
-	 * This class represents a VCS branch or tag. It's intended as a read only, short-lived container
8
-	 * that only exists to provide a limited degree of type checking.
9
-	 *
10
-	 * @property string $name
11
-	 * @property string|null version
12
-	 * @property string $downloadUrl
13
-	 * @property string $updated
14
-	 *
15
-	 * @property string|null $changelog
16
-	 * @property int|null $downloadCount
17
-	 */
18
-	class Reference {
19
-		private $properties = array();
20
-
21
-		public function __construct($properties = array()) {
22
-			$this->properties = $properties;
23
-		}
24
-
25
-		/**
26
-		 * @param string $name
27
-		 * @return mixed|null
28
-		 */
29
-		public function __get($name) {
30
-			return array_key_exists($name, $this->properties) ? $this->properties[$name] : null;
31
-		}
32
-
33
-		/**
34
-		 * @param string $name
35
-		 * @param mixed $value
36
-		 */
37
-		public function __set($name, $value) {
38
-			$this->properties[$name] = $value;
39
-		}
40
-
41
-		/**
42
-		 * @param string $name
43
-		 * @return bool
44
-		 */
45
-		public function __isset($name) {
46
-			return isset($this->properties[$name]);
47
-		}
48
-
49
-	}
6
+    /**
7
+     * This class represents a VCS branch or tag. It's intended as a read only, short-lived container
8
+     * that only exists to provide a limited degree of type checking.
9
+     *
10
+     * @property string $name
11
+     * @property string|null version
12
+     * @property string $downloadUrl
13
+     * @property string $updated
14
+     *
15
+     * @property string|null $changelog
16
+     * @property int|null $downloadCount
17
+     */
18
+    class Reference {
19
+        private $properties = array();
20
+
21
+        public function __construct($properties = array()) {
22
+            $this->properties = $properties;
23
+        }
24
+
25
+        /**
26
+         * @param string $name
27
+         * @return mixed|null
28
+         */
29
+        public function __get($name) {
30
+            return array_key_exists($name, $this->properties) ? $this->properties[$name] : null;
31
+        }
32
+
33
+        /**
34
+         * @param string $name
35
+         * @param mixed $value
36
+         */
37
+        public function __set($name, $value) {
38
+            $this->properties[$name] = $value;
39
+        }
40
+
41
+        /**
42
+         * @param string $name
43
+         * @return bool
44
+         */
45
+        public function __isset($name) {
46
+            return isset($this->properties[$name]);
47
+        }
48
+
49
+    }
50 50
 
51 51
 endif;
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -1,7 +1,7 @@
 block discarded – undo
1 1
 <?php
2 2
 namespace YahnisElsts\PluginUpdateChecker\v5p0\Vcs;
3 3
 
4
-if ( !class_exists(Reference::class, false) ):
4
+if (!class_exists(Reference::class, false)):
5 5
 
6 6
 	/**
7 7
 	 * This class represents a VCS branch or tag. It's intended as a read only, short-lived container
Please login to merge, or discard this patch.
includes/plugin-update-checker-5-1.0/Puc/v5p0/Vcs/GitHubApi.php 2 patches
Indentation   +428 added lines, -428 removed lines patch added patch discarded remove patch
@@ -5,433 +5,433 @@
 block discarded – undo
5 5
 
6 6
 if ( !class_exists(GitHubApi::class, false) ):
7 7
 
8
-	class GitHubApi extends Api {
9
-		/**
10
-		 * @var string GitHub username.
11
-		 */
12
-		protected $userName;
13
-		/**
14
-		 * @var string GitHub repository name.
15
-		 */
16
-		protected $repositoryName;
17
-
18
-		/**
19
-		 * @var string Either a fully qualified repository URL, or just "user/repo-name".
20
-		 */
21
-		protected $repositoryUrl;
22
-
23
-		/**
24
-		 * @var string GitHub authentication token. Optional.
25
-		 */
26
-		protected $accessToken;
27
-
28
-		/**
29
-		 * @var bool Whether to download release assets instead of the auto-generated source code archives.
30
-		 */
31
-		protected $releaseAssetsEnabled = false;
32
-
33
-		/**
34
-		 * @var string|null Regular expression that's used to filter release assets by name. Optional.
35
-		 */
36
-		protected $assetFilterRegex = null;
37
-
38
-		/**
39
-		 * @var string|null The unchanging part of a release asset URL. Used to identify download attempts.
40
-		 */
41
-		protected $assetApiBaseUrl = null;
42
-
43
-		/**
44
-		 * @var bool
45
-		 */
46
-		private $downloadFilterAdded = false;
47
-
48
-		public function __construct($repositoryUrl, $accessToken = null) {
49
-			$path = wp_parse_url($repositoryUrl, PHP_URL_PATH);
50
-			if ( preg_match('@^/?(?P<username>[^/]+?)/(?P<repository>[^/#?&]+?)/?$@', $path, $matches) ) {
51
-				$this->userName = $matches['username'];
52
-				$this->repositoryName = $matches['repository'];
53
-			} else {
54
-				throw new \InvalidArgumentException('Invalid GitHub repository URL: "' . $repositoryUrl . '"');
55
-			}
56
-
57
-			parent::__construct($repositoryUrl, $accessToken);
58
-		}
59
-
60
-		/**
61
-		 * Get the latest release from GitHub.
62
-		 *
63
-		 * @return Reference|null
64
-		 */
65
-		public function getLatestRelease() {
66
-			$release = $this->api('/repos/:user/:repo/releases/latest');
67
-			if ( is_wp_error($release) || !is_object($release) || !isset($release->tag_name) ) {
68
-				return null;
69
-			}
70
-
71
-			$reference = new Reference(array(
72
-				'name'        => $release->tag_name,
73
-				'version'     => ltrim($release->tag_name, 'v'), //Remove the "v" prefix from "v1.2.3".
74
-				'downloadUrl' => $release->zipball_url,
75
-				'updated'     => $release->created_at,
76
-				'apiResponse' => $release,
77
-			));
78
-
79
-			if ( isset($release->assets[0]) ) {
80
-				$reference->downloadCount = $release->assets[0]->download_count;
81
-			}
82
-
83
-			if ( $this->releaseAssetsEnabled && isset($release->assets, $release->assets[0]) ) {
84
-				//Use the first release asset that matches the specified regular expression.
85
-				$matchingAssets = array_filter($release->assets, array($this, 'matchesAssetFilter'));
86
-				if ( !empty($matchingAssets) ) {
87
-					if ( $this->isAuthenticationEnabled() ) {
88
-						/**
89
-						 * Keep in mind that we'll need to add an "Accept" header to download this asset.
90
-						 *
91
-						 * @see setUpdateDownloadHeaders()
92
-						 */
93
-						$reference->downloadUrl = $matchingAssets[0]->url;
94
-					} else {
95
-						//It seems that browser_download_url only works for public repositories.
96
-						//Using an access_token doesn't help. Maybe OAuth would work?
97
-						$reference->downloadUrl = $matchingAssets[0]->browser_download_url;
98
-					}
99
-
100
-					$reference->downloadCount = $matchingAssets[0]->download_count;
101
-				}
102
-			}
103
-
104
-			if ( !empty($release->body) ) {
105
-				$reference->changelog = Parsedown::instance()->text($release->body);
106
-			}
107
-
108
-			return $reference;
109
-		}
110
-
111
-		/**
112
-		 * Get the tag that looks like the highest version number.
113
-		 *
114
-		 * @return Reference|null
115
-		 */
116
-		public function getLatestTag() {
117
-			$tags = $this->api('/repos/:user/:repo/tags');
118
-
119
-			if ( is_wp_error($tags) || !is_array($tags) ) {
120
-				return null;
121
-			}
122
-
123
-			$versionTags = $this->sortTagsByVersion($tags);
124
-			if ( empty($versionTags) ) {
125
-				return null;
126
-			}
127
-
128
-			$tag = $versionTags[0];
129
-			return new Reference(array(
130
-				'name'        => $tag->name,
131
-				'version'     => ltrim($tag->name, 'v'),
132
-				'downloadUrl' => $tag->zipball_url,
133
-				'apiResponse' => $tag,
134
-			));
135
-		}
136
-
137
-		/**
138
-		 * Get a branch by name.
139
-		 *
140
-		 * @param string $branchName
141
-		 * @return null|Reference
142
-		 */
143
-		public function getBranch($branchName) {
144
-			$branch = $this->api('/repos/:user/:repo/branches/' . $branchName);
145
-			if ( is_wp_error($branch) || empty($branch) ) {
146
-				return null;
147
-			}
148
-
149
-			$reference = new Reference(array(
150
-				'name'        => $branch->name,
151
-				'downloadUrl' => $this->buildArchiveDownloadUrl($branch->name),
152
-				'apiResponse' => $branch,
153
-			));
154
-
155
-			if ( isset($branch->commit, $branch->commit->commit, $branch->commit->commit->author->date) ) {
156
-				$reference->updated = $branch->commit->commit->author->date;
157
-			}
158
-
159
-			return $reference;
160
-		}
161
-
162
-		/**
163
-		 * Get the latest commit that changed the specified file.
164
-		 *
165
-		 * @param string $filename
166
-		 * @param string $ref Reference name (e.g. branch or tag).
167
-		 * @return \StdClass|null
168
-		 */
169
-		public function getLatestCommit($filename, $ref = 'master') {
170
-			$commits = $this->api(
171
-				'/repos/:user/:repo/commits',
172
-				array(
173
-					'path' => $filename,
174
-					'sha'  => $ref,
175
-				)
176
-			);
177
-			if ( !is_wp_error($commits) && isset($commits[0]) ) {
178
-				return $commits[0];
179
-			}
180
-			return null;
181
-		}
182
-
183
-		/**
184
-		 * Get the timestamp of the latest commit that changed the specified branch or tag.
185
-		 *
186
-		 * @param string $ref Reference name (e.g. branch or tag).
187
-		 * @return string|null
188
-		 */
189
-		public function getLatestCommitTime($ref) {
190
-			$commits = $this->api('/repos/:user/:repo/commits', array('sha' => $ref));
191
-			if ( !is_wp_error($commits) && isset($commits[0]) ) {
192
-				return $commits[0]->commit->author->date;
193
-			}
194
-			return null;
195
-		}
196
-
197
-		/**
198
-		 * Perform a GitHub API request.
199
-		 *
200
-		 * @param string $url
201
-		 * @param array $queryParams
202
-		 * @return mixed|\WP_Error
203
-		 */
204
-		protected function api($url, $queryParams = array()) {
205
-			$baseUrl = $url;
206
-			$url = $this->buildApiUrl($url, $queryParams);
207
-
208
-			$options = array('timeout' => 10);
209
-			if ( $this->isAuthenticationEnabled() ) {
210
-				$options['headers'] = array('Authorization' => $this->getAuthorizationHeader());
211
-			}
212
-
213
-			if ( !empty($this->httpFilterName) ) {
214
-				$options = apply_filters($this->httpFilterName, $options);
215
-			}
216
-			$response = wp_remote_get($url, $options);
217
-			if ( is_wp_error($response) ) {
218
-				do_action('puc_api_error', $response, null, $url, $this->slug);
219
-				return $response;
220
-			}
221
-
222
-			$code = wp_remote_retrieve_response_code($response);
223
-			$body = wp_remote_retrieve_body($response);
224
-			if ( $code === 200 ) {
225
-				$document = json_decode($body);
226
-				return $document;
227
-			}
228
-
229
-			$error = new \WP_Error(
230
-				'puc-github-http-error',
231
-				sprintf('GitHub API error. Base URL: "%s",  HTTP status code: %d.', $baseUrl, $code)
232
-			);
233
-			do_action('puc_api_error', $error, $response, $url, $this->slug);
234
-
235
-			return $error;
236
-		}
237
-
238
-		/**
239
-		 * Build a fully qualified URL for an API request.
240
-		 *
241
-		 * @param string $url
242
-		 * @param array $queryParams
243
-		 * @return string
244
-		 */
245
-		protected function buildApiUrl($url, $queryParams) {
246
-			$variables = array(
247
-				'user' => $this->userName,
248
-				'repo' => $this->repositoryName,
249
-			);
250
-			foreach ($variables as $name => $value) {
251
-				$url = str_replace('/:' . $name, '/' . urlencode($value), $url);
252
-			}
253
-			$url = 'https://api.github.com' . $url;
254
-
255
-			if ( !empty($queryParams) ) {
256
-				$url = add_query_arg($queryParams, $url);
257
-			}
258
-
259
-			return $url;
260
-		}
261
-
262
-		/**
263
-		 * Get the contents of a file from a specific branch or tag.
264
-		 *
265
-		 * @param string $path File name.
266
-		 * @param string $ref
267
-		 * @return null|string Either the contents of the file, or null if the file doesn't exist or there's an error.
268
-		 */
269
-		public function getRemoteFile($path, $ref = 'master') {
270
-			$apiUrl = '/repos/:user/:repo/contents/' . $path;
271
-			$response = $this->api($apiUrl, array('ref' => $ref));
272
-
273
-			if ( is_wp_error($response) || !isset($response->content) || ($response->encoding !== 'base64') ) {
274
-				return null;
275
-			}
276
-			return base64_decode($response->content);
277
-		}
278
-
279
-		/**
280
-		 * Generate a URL to download a ZIP archive of the specified branch/tag/etc.
281
-		 *
282
-		 * @param string $ref
283
-		 * @return string
284
-		 */
285
-		public function buildArchiveDownloadUrl($ref = 'master') {
286
-			$url = sprintf(
287
-				'https://api.github.com/repos/%1$s/%2$s/zipball/%3$s',
288
-				urlencode($this->userName),
289
-				urlencode($this->repositoryName),
290
-				urlencode($ref)
291
-			);
292
-			return $url;
293
-		}
294
-
295
-		/**
296
-		 * Get a specific tag.
297
-		 *
298
-		 * @param string $tagName
299
-		 * @return void
300
-		 */
301
-		public function getTag($tagName) {
302
-			//The current GitHub update checker doesn't use getTag, so I didn't bother to implement it.
303
-			throw new \LogicException('The ' . __METHOD__ . ' method is not implemented and should not be used.');
304
-		}
305
-
306
-		public function setAuthentication($credentials) {
307
-			parent::setAuthentication($credentials);
308
-			$this->accessToken = is_string($credentials) ? $credentials : null;
309
-
310
-			//Optimization: Instead of filtering all HTTP requests, let's do it only when
311
-			//WordPress is about to download an update.
312
-			add_filter('upgrader_pre_download', array($this, 'addHttpRequestFilter'), 10, 1); //WP 3.7+
313
-		}
314
-
315
-		protected function getUpdateDetectionStrategies($configBranch) {
316
-			$strategies = array();
317
-
318
-			if ( $configBranch === 'master' ) {
319
-				//Use the latest release.
320
-				$strategies[self::STRATEGY_LATEST_RELEASE] = array($this, 'getLatestRelease');
321
-				//Failing that, use the tag with the highest version number.
322
-				$strategies[self::STRATEGY_LATEST_TAG] = array($this, 'getLatestTag');
323
-			}
324
-
325
-			//Alternatively, just use the branch itself.
326
-			$strategies[self::STRATEGY_BRANCH] = function() use ($configBranch) {
327
-				return $this->getBranch($configBranch);
328
-			};
329
-
330
-			return $strategies;
331
-		}
332
-
333
-		/**
334
-		 * Enable updating via release assets.
335
-		 *
336
-		 * If the latest release contains no usable assets, the update checker
337
-		 * will fall back to using the automatically generated ZIP archive.
338
-		 *
339
-		 * Private repositories will only work with WordPress 3.7 or later.
340
-		 *
341
-		 * @param string|null $fileNameRegex Optional. Use only those assets where the file name matches this regex.
342
-		 */
343
-		public function enableReleaseAssets($fileNameRegex = null) {
344
-			$this->releaseAssetsEnabled = true;
345
-			$this->assetFilterRegex = $fileNameRegex;
346
-			$this->assetApiBaseUrl = sprintf(
347
-				'//api.github.com/repos/%1$s/%2$s/releases/assets/',
348
-				$this->userName,
349
-				$this->repositoryName
350
-			);
351
-		}
352
-
353
-		/**
354
-		 * Does this asset match the file name regex?
355
-		 *
356
-		 * @param \stdClass $releaseAsset
357
-		 * @return bool
358
-		 */
359
-		protected function matchesAssetFilter($releaseAsset) {
360
-			if ( $this->assetFilterRegex === null ) {
361
-				//The default is to accept all assets.
362
-				return true;
363
-			}
364
-			return isset($releaseAsset->name) && preg_match($this->assetFilterRegex, $releaseAsset->name);
365
-		}
366
-
367
-		/**
368
-		 * @internal
369
-		 * @param bool $result
370
-		 * @return bool
371
-		 */
372
-		public function addHttpRequestFilter($result) {
373
-			if ( !$this->downloadFilterAdded && $this->isAuthenticationEnabled() ) {
374
-				//phpcs:ignore WordPressVIPMinimum.Hooks.RestrictedHooks.http_request_args -- The callback doesn't change the timeout.
375
-				add_filter('http_request_args', array($this, 'setUpdateDownloadHeaders'), 10, 2);
376
-				add_action('requests-requests.before_redirect', array($this, 'removeAuthHeaderFromRedirects'), 10, 4);
377
-				$this->downloadFilterAdded = true;
378
-			}
379
-			return $result;
380
-		}
381
-
382
-		/**
383
-		 * Set the HTTP headers that are necessary to download updates from private repositories.
384
-		 *
385
-		 * See GitHub docs:
386
-		 * @link https://developer.github.com/v3/repos/releases/#get-a-single-release-asset
387
-		 * @link https://developer.github.com/v3/auth/#basic-authentication
388
-		 *
389
-		 * @internal
390
-		 * @param array $requestArgs
391
-		 * @param string $url
392
-		 * @return array
393
-		 */
394
-		public function setUpdateDownloadHeaders($requestArgs, $url = '') {
395
-			//Is WordPress trying to download one of our release assets?
396
-			if ( $this->releaseAssetsEnabled && (strpos($url, $this->assetApiBaseUrl) !== false) ) {
397
-				$requestArgs['headers']['Accept'] = 'application/octet-stream';
398
-			}
399
-			//Use Basic authentication, but only if the download is from our repository.
400
-			$repoApiBaseUrl = $this->buildApiUrl('/repos/:user/:repo/', array());
401
-			if ( $this->isAuthenticationEnabled() && (strpos($url, $repoApiBaseUrl)) === 0 ) {
402
-				$requestArgs['headers']['Authorization'] = $this->getAuthorizationHeader();
403
-			}
404
-			return $requestArgs;
405
-		}
406
-
407
-		/**
408
-		 * When following a redirect, the Requests library will automatically forward
409
-		 * the authorization header to other hosts. We don't want that because it breaks
410
-		 * AWS downloads and can leak authorization information.
411
-		 *
412
-		 * @internal
413
-		 * @param string $location
414
-		 * @param array $headers
415
-		 */
416
-		public function removeAuthHeaderFromRedirects(&$location, &$headers) {
417
-			$repoApiBaseUrl = $this->buildApiUrl('/repos/:user/:repo/', array());
418
-			if ( strpos($location, $repoApiBaseUrl) === 0 ) {
419
-				return; //This request is going to GitHub, so it's fine.
420
-			}
421
-			//Remove the header.
422
-			if ( isset($headers['Authorization']) ) {
423
-				unset($headers['Authorization']);
424
-			}
425
-		}
426
-
427
-		/**
428
-		 * Generate the value of the "Authorization" header.
429
-		 *
430
-		 * @return string
431
-		 */
432
-		protected function getAuthorizationHeader() {
433
-			return 'Basic ' . base64_encode($this->userName . ':' . $this->accessToken);
434
-		}
435
-	}
8
+    class GitHubApi extends Api {
9
+        /**
10
+         * @var string GitHub username.
11
+         */
12
+        protected $userName;
13
+        /**
14
+         * @var string GitHub repository name.
15
+         */
16
+        protected $repositoryName;
17
+
18
+        /**
19
+         * @var string Either a fully qualified repository URL, or just "user/repo-name".
20
+         */
21
+        protected $repositoryUrl;
22
+
23
+        /**
24
+         * @var string GitHub authentication token. Optional.
25
+         */
26
+        protected $accessToken;
27
+
28
+        /**
29
+         * @var bool Whether to download release assets instead of the auto-generated source code archives.
30
+         */
31
+        protected $releaseAssetsEnabled = false;
32
+
33
+        /**
34
+         * @var string|null Regular expression that's used to filter release assets by name. Optional.
35
+         */
36
+        protected $assetFilterRegex = null;
37
+
38
+        /**
39
+         * @var string|null The unchanging part of a release asset URL. Used to identify download attempts.
40
+         */
41
+        protected $assetApiBaseUrl = null;
42
+
43
+        /**
44
+         * @var bool
45
+         */
46
+        private $downloadFilterAdded = false;
47
+
48
+        public function __construct($repositoryUrl, $accessToken = null) {
49
+            $path = wp_parse_url($repositoryUrl, PHP_URL_PATH);
50
+            if ( preg_match('@^/?(?P<username>[^/]+?)/(?P<repository>[^/#?&]+?)/?$@', $path, $matches) ) {
51
+                $this->userName = $matches['username'];
52
+                $this->repositoryName = $matches['repository'];
53
+            } else {
54
+                throw new \InvalidArgumentException('Invalid GitHub repository URL: "' . $repositoryUrl . '"');
55
+            }
56
+
57
+            parent::__construct($repositoryUrl, $accessToken);
58
+        }
59
+
60
+        /**
61
+         * Get the latest release from GitHub.
62
+         *
63
+         * @return Reference|null
64
+         */
65
+        public function getLatestRelease() {
66
+            $release = $this->api('/repos/:user/:repo/releases/latest');
67
+            if ( is_wp_error($release) || !is_object($release) || !isset($release->tag_name) ) {
68
+                return null;
69
+            }
70
+
71
+            $reference = new Reference(array(
72
+                'name'        => $release->tag_name,
73
+                'version'     => ltrim($release->tag_name, 'v'), //Remove the "v" prefix from "v1.2.3".
74
+                'downloadUrl' => $release->zipball_url,
75
+                'updated'     => $release->created_at,
76
+                'apiResponse' => $release,
77
+            ));
78
+
79
+            if ( isset($release->assets[0]) ) {
80
+                $reference->downloadCount = $release->assets[0]->download_count;
81
+            }
82
+
83
+            if ( $this->releaseAssetsEnabled && isset($release->assets, $release->assets[0]) ) {
84
+                //Use the first release asset that matches the specified regular expression.
85
+                $matchingAssets = array_filter($release->assets, array($this, 'matchesAssetFilter'));
86
+                if ( !empty($matchingAssets) ) {
87
+                    if ( $this->isAuthenticationEnabled() ) {
88
+                        /**
89
+                         * Keep in mind that we'll need to add an "Accept" header to download this asset.
90
+                         *
91
+                         * @see setUpdateDownloadHeaders()
92
+                         */
93
+                        $reference->downloadUrl = $matchingAssets[0]->url;
94
+                    } else {
95
+                        //It seems that browser_download_url only works for public repositories.
96
+                        //Using an access_token doesn't help. Maybe OAuth would work?
97
+                        $reference->downloadUrl = $matchingAssets[0]->browser_download_url;
98
+                    }
99
+
100
+                    $reference->downloadCount = $matchingAssets[0]->download_count;
101
+                }
102
+            }
103
+
104
+            if ( !empty($release->body) ) {
105
+                $reference->changelog = Parsedown::instance()->text($release->body);
106
+            }
107
+
108
+            return $reference;
109
+        }
110
+
111
+        /**
112
+         * Get the tag that looks like the highest version number.
113
+         *
114
+         * @return Reference|null
115
+         */
116
+        public function getLatestTag() {
117
+            $tags = $this->api('/repos/:user/:repo/tags');
118
+
119
+            if ( is_wp_error($tags) || !is_array($tags) ) {
120
+                return null;
121
+            }
122
+
123
+            $versionTags = $this->sortTagsByVersion($tags);
124
+            if ( empty($versionTags) ) {
125
+                return null;
126
+            }
127
+
128
+            $tag = $versionTags[0];
129
+            return new Reference(array(
130
+                'name'        => $tag->name,
131
+                'version'     => ltrim($tag->name, 'v'),
132
+                'downloadUrl' => $tag->zipball_url,
133
+                'apiResponse' => $tag,
134
+            ));
135
+        }
136
+
137
+        /**
138
+         * Get a branch by name.
139
+         *
140
+         * @param string $branchName
141
+         * @return null|Reference
142
+         */
143
+        public function getBranch($branchName) {
144
+            $branch = $this->api('/repos/:user/:repo/branches/' . $branchName);
145
+            if ( is_wp_error($branch) || empty($branch) ) {
146
+                return null;
147
+            }
148
+
149
+            $reference = new Reference(array(
150
+                'name'        => $branch->name,
151
+                'downloadUrl' => $this->buildArchiveDownloadUrl($branch->name),
152
+                'apiResponse' => $branch,
153
+            ));
154
+
155
+            if ( isset($branch->commit, $branch->commit->commit, $branch->commit->commit->author->date) ) {
156
+                $reference->updated = $branch->commit->commit->author->date;
157
+            }
158
+
159
+            return $reference;
160
+        }
161
+
162
+        /**
163
+         * Get the latest commit that changed the specified file.
164
+         *
165
+         * @param string $filename
166
+         * @param string $ref Reference name (e.g. branch or tag).
167
+         * @return \StdClass|null
168
+         */
169
+        public function getLatestCommit($filename, $ref = 'master') {
170
+            $commits = $this->api(
171
+                '/repos/:user/:repo/commits',
172
+                array(
173
+                    'path' => $filename,
174
+                    'sha'  => $ref,
175
+                )
176
+            );
177
+            if ( !is_wp_error($commits) && isset($commits[0]) ) {
178
+                return $commits[0];
179
+            }
180
+            return null;
181
+        }
182
+
183
+        /**
184
+         * Get the timestamp of the latest commit that changed the specified branch or tag.
185
+         *
186
+         * @param string $ref Reference name (e.g. branch or tag).
187
+         * @return string|null
188
+         */
189
+        public function getLatestCommitTime($ref) {
190
+            $commits = $this->api('/repos/:user/:repo/commits', array('sha' => $ref));
191
+            if ( !is_wp_error($commits) && isset($commits[0]) ) {
192
+                return $commits[0]->commit->author->date;
193
+            }
194
+            return null;
195
+        }
196
+
197
+        /**
198
+         * Perform a GitHub API request.
199
+         *
200
+         * @param string $url
201
+         * @param array $queryParams
202
+         * @return mixed|\WP_Error
203
+         */
204
+        protected function api($url, $queryParams = array()) {
205
+            $baseUrl = $url;
206
+            $url = $this->buildApiUrl($url, $queryParams);
207
+
208
+            $options = array('timeout' => 10);
209
+            if ( $this->isAuthenticationEnabled() ) {
210
+                $options['headers'] = array('Authorization' => $this->getAuthorizationHeader());
211
+            }
212
+
213
+            if ( !empty($this->httpFilterName) ) {
214
+                $options = apply_filters($this->httpFilterName, $options);
215
+            }
216
+            $response = wp_remote_get($url, $options);
217
+            if ( is_wp_error($response) ) {
218
+                do_action('puc_api_error', $response, null, $url, $this->slug);
219
+                return $response;
220
+            }
221
+
222
+            $code = wp_remote_retrieve_response_code($response);
223
+            $body = wp_remote_retrieve_body($response);
224
+            if ( $code === 200 ) {
225
+                $document = json_decode($body);
226
+                return $document;
227
+            }
228
+
229
+            $error = new \WP_Error(
230
+                'puc-github-http-error',
231
+                sprintf('GitHub API error. Base URL: "%s",  HTTP status code: %d.', $baseUrl, $code)
232
+            );
233
+            do_action('puc_api_error', $error, $response, $url, $this->slug);
234
+
235
+            return $error;
236
+        }
237
+
238
+        /**
239
+         * Build a fully qualified URL for an API request.
240
+         *
241
+         * @param string $url
242
+         * @param array $queryParams
243
+         * @return string
244
+         */
245
+        protected function buildApiUrl($url, $queryParams) {
246
+            $variables = array(
247
+                'user' => $this->userName,
248
+                'repo' => $this->repositoryName,
249
+            );
250
+            foreach ($variables as $name => $value) {
251
+                $url = str_replace('/:' . $name, '/' . urlencode($value), $url);
252
+            }
253
+            $url = 'https://api.github.com' . $url;
254
+
255
+            if ( !empty($queryParams) ) {
256
+                $url = add_query_arg($queryParams, $url);
257
+            }
258
+
259
+            return $url;
260
+        }
261
+
262
+        /**
263
+         * Get the contents of a file from a specific branch or tag.
264
+         *
265
+         * @param string $path File name.
266
+         * @param string $ref
267
+         * @return null|string Either the contents of the file, or null if the file doesn't exist or there's an error.
268
+         */
269
+        public function getRemoteFile($path, $ref = 'master') {
270
+            $apiUrl = '/repos/:user/:repo/contents/' . $path;
271
+            $response = $this->api($apiUrl, array('ref' => $ref));
272
+
273
+            if ( is_wp_error($response) || !isset($response->content) || ($response->encoding !== 'base64') ) {
274
+                return null;
275
+            }
276
+            return base64_decode($response->content);
277
+        }
278
+
279
+        /**
280
+         * Generate a URL to download a ZIP archive of the specified branch/tag/etc.
281
+         *
282
+         * @param string $ref
283
+         * @return string
284
+         */
285
+        public function buildArchiveDownloadUrl($ref = 'master') {
286
+            $url = sprintf(
287
+                'https://api.github.com/repos/%1$s/%2$s/zipball/%3$s',
288
+                urlencode($this->userName),
289
+                urlencode($this->repositoryName),
290
+                urlencode($ref)
291
+            );
292
+            return $url;
293
+        }
294
+
295
+        /**
296
+         * Get a specific tag.
297
+         *
298
+         * @param string $tagName
299
+         * @return void
300
+         */
301
+        public function getTag($tagName) {
302
+            //The current GitHub update checker doesn't use getTag, so I didn't bother to implement it.
303
+            throw new \LogicException('The ' . __METHOD__ . ' method is not implemented and should not be used.');
304
+        }
305
+
306
+        public function setAuthentication($credentials) {
307
+            parent::setAuthentication($credentials);
308
+            $this->accessToken = is_string($credentials) ? $credentials : null;
309
+
310
+            //Optimization: Instead of filtering all HTTP requests, let's do it only when
311
+            //WordPress is about to download an update.
312
+            add_filter('upgrader_pre_download', array($this, 'addHttpRequestFilter'), 10, 1); //WP 3.7+
313
+        }
314
+
315
+        protected function getUpdateDetectionStrategies($configBranch) {
316
+            $strategies = array();
317
+
318
+            if ( $configBranch === 'master' ) {
319
+                //Use the latest release.
320
+                $strategies[self::STRATEGY_LATEST_RELEASE] = array($this, 'getLatestRelease');
321
+                //Failing that, use the tag with the highest version number.
322
+                $strategies[self::STRATEGY_LATEST_TAG] = array($this, 'getLatestTag');
323
+            }
324
+
325
+            //Alternatively, just use the branch itself.
326
+            $strategies[self::STRATEGY_BRANCH] = function() use ($configBranch) {
327
+                return $this->getBranch($configBranch);
328
+            };
329
+
330
+            return $strategies;
331
+        }
332
+
333
+        /**
334
+         * Enable updating via release assets.
335
+         *
336
+         * If the latest release contains no usable assets, the update checker
337
+         * will fall back to using the automatically generated ZIP archive.
338
+         *
339
+         * Private repositories will only work with WordPress 3.7 or later.
340
+         *
341
+         * @param string|null $fileNameRegex Optional. Use only those assets where the file name matches this regex.
342
+         */
343
+        public function enableReleaseAssets($fileNameRegex = null) {
344
+            $this->releaseAssetsEnabled = true;
345
+            $this->assetFilterRegex = $fileNameRegex;
346
+            $this->assetApiBaseUrl = sprintf(
347
+                '//api.github.com/repos/%1$s/%2$s/releases/assets/',
348
+                $this->userName,
349
+                $this->repositoryName
350
+            );
351
+        }
352
+
353
+        /**
354
+         * Does this asset match the file name regex?
355
+         *
356
+         * @param \stdClass $releaseAsset
357
+         * @return bool
358
+         */
359
+        protected function matchesAssetFilter($releaseAsset) {
360
+            if ( $this->assetFilterRegex === null ) {
361
+                //The default is to accept all assets.
362
+                return true;
363
+            }
364
+            return isset($releaseAsset->name) && preg_match($this->assetFilterRegex, $releaseAsset->name);
365
+        }
366
+
367
+        /**
368
+         * @internal
369
+         * @param bool $result
370
+         * @return bool
371
+         */
372
+        public function addHttpRequestFilter($result) {
373
+            if ( !$this->downloadFilterAdded && $this->isAuthenticationEnabled() ) {
374
+                //phpcs:ignore WordPressVIPMinimum.Hooks.RestrictedHooks.http_request_args -- The callback doesn't change the timeout.
375
+                add_filter('http_request_args', array($this, 'setUpdateDownloadHeaders'), 10, 2);
376
+                add_action('requests-requests.before_redirect', array($this, 'removeAuthHeaderFromRedirects'), 10, 4);
377
+                $this->downloadFilterAdded = true;
378
+            }
379
+            return $result;
380
+        }
381
+
382
+        /**
383
+         * Set the HTTP headers that are necessary to download updates from private repositories.
384
+         *
385
+         * See GitHub docs:
386
+         * @link https://developer.github.com/v3/repos/releases/#get-a-single-release-asset
387
+         * @link https://developer.github.com/v3/auth/#basic-authentication
388
+         *
389
+         * @internal
390
+         * @param array $requestArgs
391
+         * @param string $url
392
+         * @return array
393
+         */
394
+        public function setUpdateDownloadHeaders($requestArgs, $url = '') {
395
+            //Is WordPress trying to download one of our release assets?
396
+            if ( $this->releaseAssetsEnabled && (strpos($url, $this->assetApiBaseUrl) !== false) ) {
397
+                $requestArgs['headers']['Accept'] = 'application/octet-stream';
398
+            }
399
+            //Use Basic authentication, but only if the download is from our repository.
400
+            $repoApiBaseUrl = $this->buildApiUrl('/repos/:user/:repo/', array());
401
+            if ( $this->isAuthenticationEnabled() && (strpos($url, $repoApiBaseUrl)) === 0 ) {
402
+                $requestArgs['headers']['Authorization'] = $this->getAuthorizationHeader();
403
+            }
404
+            return $requestArgs;
405
+        }
406
+
407
+        /**
408
+         * When following a redirect, the Requests library will automatically forward
409
+         * the authorization header to other hosts. We don't want that because it breaks
410
+         * AWS downloads and can leak authorization information.
411
+         *
412
+         * @internal
413
+         * @param string $location
414
+         * @param array $headers
415
+         */
416
+        public function removeAuthHeaderFromRedirects(&$location, &$headers) {
417
+            $repoApiBaseUrl = $this->buildApiUrl('/repos/:user/:repo/', array());
418
+            if ( strpos($location, $repoApiBaseUrl) === 0 ) {
419
+                return; //This request is going to GitHub, so it's fine.
420
+            }
421
+            //Remove the header.
422
+            if ( isset($headers['Authorization']) ) {
423
+                unset($headers['Authorization']);
424
+            }
425
+        }
426
+
427
+        /**
428
+         * Generate the value of the "Authorization" header.
429
+         *
430
+         * @return string
431
+         */
432
+        protected function getAuthorizationHeader() {
433
+            return 'Basic ' . base64_encode($this->userName . ':' . $this->accessToken);
434
+        }
435
+    }
436 436
 
437 437
 endif;
Please login to merge, or discard this patch.
Spacing   +27 added lines, -27 removed lines patch added patch discarded remove patch
@@ -3,7 +3,7 @@  discard block
 block discarded – undo
3 3
 
4 4
 use Parsedown;
5 5
 
6
-if ( !class_exists(GitHubApi::class, false) ):
6
+if (!class_exists(GitHubApi::class, false)):
7 7
 
8 8
 	class GitHubApi extends Api {
9 9
 		/**
@@ -47,7 +47,7 @@  discard block
 block discarded – undo
47 47
 
48 48
 		public function __construct($repositoryUrl, $accessToken = null) {
49 49
 			$path = wp_parse_url($repositoryUrl, PHP_URL_PATH);
50
-			if ( preg_match('@^/?(?P<username>[^/]+?)/(?P<repository>[^/#?&]+?)/?$@', $path, $matches) ) {
50
+			if (preg_match('@^/?(?P<username>[^/]+?)/(?P<repository>[^/#?&]+?)/?$@', $path, $matches)) {
51 51
 				$this->userName = $matches['username'];
52 52
 				$this->repositoryName = $matches['repository'];
53 53
 			} else {
@@ -64,7 +64,7 @@  discard block
 block discarded – undo
64 64
 		 */
65 65
 		public function getLatestRelease() {
66 66
 			$release = $this->api('/repos/:user/:repo/releases/latest');
67
-			if ( is_wp_error($release) || !is_object($release) || !isset($release->tag_name) ) {
67
+			if (is_wp_error($release) || !is_object($release) || !isset($release->tag_name)) {
68 68
 				return null;
69 69
 			}
70 70
 
@@ -76,15 +76,15 @@  discard block
 block discarded – undo
76 76
 				'apiResponse' => $release,
77 77
 			));
78 78
 
79
-			if ( isset($release->assets[0]) ) {
79
+			if (isset($release->assets[0])) {
80 80
 				$reference->downloadCount = $release->assets[0]->download_count;
81 81
 			}
82 82
 
83
-			if ( $this->releaseAssetsEnabled && isset($release->assets, $release->assets[0]) ) {
83
+			if ($this->releaseAssetsEnabled && isset($release->assets, $release->assets[0])) {
84 84
 				//Use the first release asset that matches the specified regular expression.
85 85
 				$matchingAssets = array_filter($release->assets, array($this, 'matchesAssetFilter'));
86
-				if ( !empty($matchingAssets) ) {
87
-					if ( $this->isAuthenticationEnabled() ) {
86
+				if (!empty($matchingAssets)) {
87
+					if ($this->isAuthenticationEnabled()) {
88 88
 						/**
89 89
 						 * Keep in mind that we'll need to add an "Accept" header to download this asset.
90 90
 						 *
@@ -101,7 +101,7 @@  discard block
 block discarded – undo
101 101
 				}
102 102
 			}
103 103
 
104
-			if ( !empty($release->body) ) {
104
+			if (!empty($release->body)) {
105 105
 				$reference->changelog = Parsedown::instance()->text($release->body);
106 106
 			}
107 107
 
@@ -116,12 +116,12 @@  discard block
 block discarded – undo
116 116
 		public function getLatestTag() {
117 117
 			$tags = $this->api('/repos/:user/:repo/tags');
118 118
 
119
-			if ( is_wp_error($tags) || !is_array($tags) ) {
119
+			if (is_wp_error($tags) || !is_array($tags)) {
120 120
 				return null;
121 121
 			}
122 122
 
123 123
 			$versionTags = $this->sortTagsByVersion($tags);
124
-			if ( empty($versionTags) ) {
124
+			if (empty($versionTags)) {
125 125
 				return null;
126 126
 			}
127 127
 
@@ -142,7 +142,7 @@  discard block
 block discarded – undo
142 142
 		 */
143 143
 		public function getBranch($branchName) {
144 144
 			$branch = $this->api('/repos/:user/:repo/branches/' . $branchName);
145
-			if ( is_wp_error($branch) || empty($branch) ) {
145
+			if (is_wp_error($branch) || empty($branch)) {
146 146
 				return null;
147 147
 			}
148 148
 
@@ -152,7 +152,7 @@  discard block
 block discarded – undo
152 152
 				'apiResponse' => $branch,
153 153
 			));
154 154
 
155
-			if ( isset($branch->commit, $branch->commit->commit, $branch->commit->commit->author->date) ) {
155
+			if (isset($branch->commit, $branch->commit->commit, $branch->commit->commit->author->date)) {
156 156
 				$reference->updated = $branch->commit->commit->author->date;
157 157
 			}
158 158
 
@@ -174,7 +174,7 @@  discard block
 block discarded – undo
174 174
 					'sha'  => $ref,
175 175
 				)
176 176
 			);
177
-			if ( !is_wp_error($commits) && isset($commits[0]) ) {
177
+			if (!is_wp_error($commits) && isset($commits[0])) {
178 178
 				return $commits[0];
179 179
 			}
180 180
 			return null;
@@ -188,7 +188,7 @@  discard block
 block discarded – undo
188 188
 		 */
189 189
 		public function getLatestCommitTime($ref) {
190 190
 			$commits = $this->api('/repos/:user/:repo/commits', array('sha' => $ref));
191
-			if ( !is_wp_error($commits) && isset($commits[0]) ) {
191
+			if (!is_wp_error($commits) && isset($commits[0])) {
192 192
 				return $commits[0]->commit->author->date;
193 193
 			}
194 194
 			return null;
@@ -206,22 +206,22 @@  discard block
 block discarded – undo
206 206
 			$url = $this->buildApiUrl($url, $queryParams);
207 207
 
208 208
 			$options = array('timeout' => 10);
209
-			if ( $this->isAuthenticationEnabled() ) {
209
+			if ($this->isAuthenticationEnabled()) {
210 210
 				$options['headers'] = array('Authorization' => $this->getAuthorizationHeader());
211 211
 			}
212 212
 
213
-			if ( !empty($this->httpFilterName) ) {
213
+			if (!empty($this->httpFilterName)) {
214 214
 				$options = apply_filters($this->httpFilterName, $options);
215 215
 			}
216 216
 			$response = wp_remote_get($url, $options);
217
-			if ( is_wp_error($response) ) {
217
+			if (is_wp_error($response)) {
218 218
 				do_action('puc_api_error', $response, null, $url, $this->slug);
219 219
 				return $response;
220 220
 			}
221 221
 
222 222
 			$code = wp_remote_retrieve_response_code($response);
223 223
 			$body = wp_remote_retrieve_body($response);
224
-			if ( $code === 200 ) {
224
+			if ($code === 200) {
225 225
 				$document = json_decode($body);
226 226
 				return $document;
227 227
 			}
@@ -252,7 +252,7 @@  discard block
 block discarded – undo
252 252
 			}
253 253
 			$url = 'https://api.github.com' . $url;
254 254
 
255
-			if ( !empty($queryParams) ) {
255
+			if (!empty($queryParams)) {
256 256
 				$url = add_query_arg($queryParams, $url);
257 257
 			}
258 258
 
@@ -270,7 +270,7 @@  discard block
 block discarded – undo
270 270
 			$apiUrl = '/repos/:user/:repo/contents/' . $path;
271 271
 			$response = $this->api($apiUrl, array('ref' => $ref));
272 272
 
273
-			if ( is_wp_error($response) || !isset($response->content) || ($response->encoding !== 'base64') ) {
273
+			if (is_wp_error($response) || !isset($response->content) || ($response->encoding !== 'base64')) {
274 274
 				return null;
275 275
 			}
276 276
 			return base64_decode($response->content);
@@ -315,7 +315,7 @@  discard block
 block discarded – undo
315 315
 		protected function getUpdateDetectionStrategies($configBranch) {
316 316
 			$strategies = array();
317 317
 
318
-			if ( $configBranch === 'master' ) {
318
+			if ($configBranch === 'master') {
319 319
 				//Use the latest release.
320 320
 				$strategies[self::STRATEGY_LATEST_RELEASE] = array($this, 'getLatestRelease');
321 321
 				//Failing that, use the tag with the highest version number.
@@ -357,7 +357,7 @@  discard block
 block discarded – undo
357 357
 		 * @return bool
358 358
 		 */
359 359
 		protected function matchesAssetFilter($releaseAsset) {
360
-			if ( $this->assetFilterRegex === null ) {
360
+			if ($this->assetFilterRegex === null) {
361 361
 				//The default is to accept all assets.
362 362
 				return true;
363 363
 			}
@@ -370,7 +370,7 @@  discard block
 block discarded – undo
370 370
 		 * @return bool
371 371
 		 */
372 372
 		public function addHttpRequestFilter($result) {
373
-			if ( !$this->downloadFilterAdded && $this->isAuthenticationEnabled() ) {
373
+			if (!$this->downloadFilterAdded && $this->isAuthenticationEnabled()) {
374 374
 				//phpcs:ignore WordPressVIPMinimum.Hooks.RestrictedHooks.http_request_args -- The callback doesn't change the timeout.
375 375
 				add_filter('http_request_args', array($this, 'setUpdateDownloadHeaders'), 10, 2);
376 376
 				add_action('requests-requests.before_redirect', array($this, 'removeAuthHeaderFromRedirects'), 10, 4);
@@ -393,12 +393,12 @@  discard block
 block discarded – undo
393 393
 		 */
394 394
 		public function setUpdateDownloadHeaders($requestArgs, $url = '') {
395 395
 			//Is WordPress trying to download one of our release assets?
396
-			if ( $this->releaseAssetsEnabled && (strpos($url, $this->assetApiBaseUrl) !== false) ) {
396
+			if ($this->releaseAssetsEnabled && (strpos($url, $this->assetApiBaseUrl) !== false)) {
397 397
 				$requestArgs['headers']['Accept'] = 'application/octet-stream';
398 398
 			}
399 399
 			//Use Basic authentication, but only if the download is from our repository.
400 400
 			$repoApiBaseUrl = $this->buildApiUrl('/repos/:user/:repo/', array());
401
-			if ( $this->isAuthenticationEnabled() && (strpos($url, $repoApiBaseUrl)) === 0 ) {
401
+			if ($this->isAuthenticationEnabled() && (strpos($url, $repoApiBaseUrl)) === 0) {
402 402
 				$requestArgs['headers']['Authorization'] = $this->getAuthorizationHeader();
403 403
 			}
404 404
 			return $requestArgs;
@@ -415,11 +415,11 @@  discard block
 block discarded – undo
415 415
 		 */
416 416
 		public function removeAuthHeaderFromRedirects(&$location, &$headers) {
417 417
 			$repoApiBaseUrl = $this->buildApiUrl('/repos/:user/:repo/', array());
418
-			if ( strpos($location, $repoApiBaseUrl) === 0 ) {
418
+			if (strpos($location, $repoApiBaseUrl) === 0) {
419 419
 				return; //This request is going to GitHub, so it's fine.
420 420
 			}
421 421
 			//Remove the header.
422
-			if ( isset($headers['Authorization']) ) {
422
+			if (isset($headers['Authorization'])) {
423 423
 				unset($headers['Authorization']);
424 424
 			}
425 425
 		}
Please login to merge, or discard this patch.
includes/plugin-update-checker-5-1.0/Puc/v5p0/Vcs/BitBucketApi.php 2 patches
Indentation   +261 added lines, -261 removed lines patch added patch discarded remove patch
@@ -7,266 +7,266 @@
 block discarded – undo
7 7
 
8 8
 if ( !class_exists(BitBucketApi::class, false) ):
9 9
 
10
-	class BitBucketApi extends Api {
11
-		/**
12
-		 * @var OAuthSignature
13
-		 */
14
-		private $oauth = null;
15
-
16
-		/**
17
-		 * @var string
18
-		 */
19
-		private $username;
20
-
21
-		/**
22
-		 * @var string
23
-		 */
24
-		private $repository;
25
-
26
-		public function __construct($repositoryUrl, $credentials = array()) {
27
-			$path = wp_parse_url($repositoryUrl, PHP_URL_PATH);
28
-			if ( preg_match('@^/?(?P<username>[^/]+?)/(?P<repository>[^/#?&]+?)/?$@', $path, $matches) ) {
29
-				$this->username = $matches['username'];
30
-				$this->repository = $matches['repository'];
31
-			} else {
32
-				throw new \InvalidArgumentException('Invalid BitBucket repository URL: "' . $repositoryUrl . '"');
33
-			}
34
-
35
-			parent::__construct($repositoryUrl, $credentials);
36
-		}
37
-
38
-		protected function getUpdateDetectionStrategies($configBranch) {
39
-			$strategies = array(
40
-				self::STRATEGY_STABLE_TAG => function () use ($configBranch) {
41
-					return $this->getStableTag($configBranch);
42
-				},
43
-			);
44
-
45
-			if ( ($configBranch === 'master' || $configBranch === 'main') ) {
46
-				$strategies[self::STRATEGY_LATEST_TAG] = array($this, 'getLatestTag');
47
-			}
48
-
49
-			$strategies[self::STRATEGY_BRANCH] = function () use ($configBranch) {
50
-				return $this->getBranch($configBranch);
51
-			};
52
-			return $strategies;
53
-		}
54
-
55
-		public function getBranch($branchName) {
56
-			$branch = $this->api('/refs/branches/' . $branchName);
57
-			if ( is_wp_error($branch) || empty($branch) ) {
58
-				return null;
59
-			}
60
-
61
-			//The "/src/{stuff}/{path}" endpoint doesn't seem to handle branch names that contain slashes.
62
-			//If we don't encode the slash, we get a 404. If we encode it as "%2F", we get a 401.
63
-			//To avoid issues, if the branch name is not URL-safe, let's use the commit hash instead.
64
-			$ref = $branch->name;
65
-			if ((urlencode($ref) !== $ref) && isset($branch->target->hash)) {
66
-				$ref = $branch->target->hash;
67
-			}
68
-
69
-			return new Reference(array(
70
-				'name' => $ref,
71
-				'updated' => $branch->target->date,
72
-				'downloadUrl' => $this->getDownloadUrl($branch->name),
73
-			));
74
-		}
75
-
76
-		/**
77
-		 * Get a specific tag.
78
-		 *
79
-		 * @param string $tagName
80
-		 * @return Reference|null
81
-		 */
82
-		public function getTag($tagName) {
83
-			$tag = $this->api('/refs/tags/' . $tagName);
84
-			if ( is_wp_error($tag) || empty($tag) ) {
85
-				return null;
86
-			}
87
-
88
-			return new Reference(array(
89
-				'name' => $tag->name,
90
-				'version' => ltrim($tag->name, 'v'),
91
-				'updated' => $tag->target->date,
92
-				'downloadUrl' => $this->getDownloadUrl($tag->name),
93
-			));
94
-		}
95
-
96
-		/**
97
-		 * Get the tag that looks like the highest version number.
98
-		 *
99
-		 * @return Reference|null
100
-		 */
101
-		public function getLatestTag() {
102
-			$tags = $this->api('/refs/tags?sort=-target.date');
103
-			if ( !isset($tags, $tags->values) || !is_array($tags->values) ) {
104
-				return null;
105
-			}
106
-
107
-			//Filter and sort the list of tags.
108
-			$versionTags = $this->sortTagsByVersion($tags->values);
109
-
110
-			//Return the first result.
111
-			if ( !empty($versionTags) ) {
112
-				$tag = $versionTags[0];
113
-				return new Reference(array(
114
-					'name' => $tag->name,
115
-					'version' => ltrim($tag->name, 'v'),
116
-					'updated' => $tag->target->date,
117
-					'downloadUrl' => $this->getDownloadUrl($tag->name),
118
-				));
119
-			}
120
-			return null;
121
-		}
122
-
123
-		/**
124
-		 * Get the tag/ref specified by the "Stable tag" header in the readme.txt of a given branch.
125
-		 *
126
-		 * @param string $branch
127
-		 * @return null|Reference
128
-		 */
129
-		protected function getStableTag($branch) {
130
-			$remoteReadme = $this->getRemoteReadme($branch);
131
-			if ( !empty($remoteReadme['stable_tag']) ) {
132
-				$tag = $remoteReadme['stable_tag'];
133
-
134
-				//You can explicitly opt out of using tags by setting "Stable tag" to
135
-				//"trunk" or the name of the current branch.
136
-				if ( ($tag === $branch) || ($tag === 'trunk') ) {
137
-					return $this->getBranch($branch);
138
-				}
139
-
140
-				return $this->getTag($tag);
141
-			}
142
-
143
-			return null;
144
-		}
145
-
146
-		/**
147
-		 * @param string $ref
148
-		 * @return string
149
-		 */
150
-		protected function getDownloadUrl($ref) {
151
-			return sprintf(
152
-				'https://bitbucket.org/%s/%s/get/%s.zip',
153
-				$this->username,
154
-				$this->repository,
155
-				$ref
156
-			);
157
-		}
158
-
159
-		/**
160
-		 * Get the contents of a file from a specific branch or tag.
161
-		 *
162
-		 * @param string $path File name.
163
-		 * @param string $ref
164
-		 * @return null|string Either the contents of the file, or null if the file doesn't exist or there's an error.
165
-		 */
166
-		public function getRemoteFile($path, $ref = 'master') {
167
-			$response = $this->api('src/' . $ref . '/' . ltrim($path));
168
-			if ( is_wp_error($response) || !is_string($response) ) {
169
-				return null;
170
-			}
171
-			return $response;
172
-		}
173
-
174
-		/**
175
-		 * Get the timestamp of the latest commit that changed the specified branch or tag.
176
-		 *
177
-		 * @param string $ref Reference name (e.g. branch or tag).
178
-		 * @return string|null
179
-		 */
180
-		public function getLatestCommitTime($ref) {
181
-			$response = $this->api('commits/' . $ref);
182
-			if ( isset($response->values, $response->values[0], $response->values[0]->date) ) {
183
-				return $response->values[0]->date;
184
-			}
185
-			return null;
186
-		}
187
-
188
-		/**
189
-		 * Perform a BitBucket API 2.0 request.
190
-		 *
191
-		 * @param string $url
192
-		 * @param string $version
193
-		 * @return mixed|\WP_Error
194
-		 */
195
-		public function api($url, $version = '2.0') {
196
-			$url = ltrim($url, '/');
197
-			$isSrcResource = Utils::startsWith($url, 'src/');
198
-
199
-			$url = implode('/', array(
200
-				'https://api.bitbucket.org',
201
-				$version,
202
-				'repositories',
203
-				$this->username,
204
-				$this->repository,
205
-				$url
206
-			));
207
-			$baseUrl = $url;
208
-
209
-			if ( $this->oauth ) {
210
-				$url = $this->oauth->sign($url,'GET');
211
-			}
212
-
213
-			$options = array('timeout' => 10);
214
-			if ( !empty($this->httpFilterName) ) {
215
-				$options = apply_filters($this->httpFilterName, $options);
216
-			}
217
-			$response = wp_remote_get($url, $options);
218
-			if ( is_wp_error($response) ) {
219
-				do_action('puc_api_error', $response, null, $url, $this->slug);
220
-				return $response;
221
-			}
222
-
223
-			$code = wp_remote_retrieve_response_code($response);
224
-			$body = wp_remote_retrieve_body($response);
225
-			if ( $code === 200 ) {
226
-				if ( $isSrcResource ) {
227
-					//Most responses are JSON-encoded, but src resources just
228
-					//return raw file contents.
229
-					$document = $body;
230
-				} else {
231
-					$document = json_decode($body);
232
-				}
233
-				return $document;
234
-			}
235
-
236
-			$error = new \WP_Error(
237
-				'puc-bitbucket-http-error',
238
-				sprintf('BitBucket API error. Base URL: "%s",  HTTP status code: %d.', $baseUrl, $code)
239
-			);
240
-			do_action('puc_api_error', $error, $response, $url, $this->slug);
241
-
242
-			return $error;
243
-		}
244
-
245
-		/**
246
-		 * @param array $credentials
247
-		 */
248
-		public function setAuthentication($credentials) {
249
-			parent::setAuthentication($credentials);
250
-
251
-			if ( !empty($credentials) && !empty($credentials['consumer_key']) ) {
252
-				$this->oauth = new OAuthSignature(
253
-					$credentials['consumer_key'],
254
-					$credentials['consumer_secret']
255
-				);
256
-			} else {
257
-				$this->oauth = null;
258
-			}
259
-		}
260
-
261
-		public function signDownloadUrl($url) {
262
-			//Add authentication data to download URLs. Since OAuth signatures incorporate
263
-			//timestamps, we have to do this immediately before inserting the update. Otherwise,
264
-			//authentication could fail due to a stale timestamp.
265
-			if ( $this->oauth ) {
266
-				$url = $this->oauth->sign($url);
267
-			}
268
-			return $url;
269
-		}
270
-	}
10
+    class BitBucketApi extends Api {
11
+        /**
12
+         * @var OAuthSignature
13
+         */
14
+        private $oauth = null;
15
+
16
+        /**
17
+         * @var string
18
+         */
19
+        private $username;
20
+
21
+        /**
22
+         * @var string
23
+         */
24
+        private $repository;
25
+
26
+        public function __construct($repositoryUrl, $credentials = array()) {
27
+            $path = wp_parse_url($repositoryUrl, PHP_URL_PATH);
28
+            if ( preg_match('@^/?(?P<username>[^/]+?)/(?P<repository>[^/#?&]+?)/?$@', $path, $matches) ) {
29
+                $this->username = $matches['username'];
30
+                $this->repository = $matches['repository'];
31
+            } else {
32
+                throw new \InvalidArgumentException('Invalid BitBucket repository URL: "' . $repositoryUrl . '"');
33
+            }
34
+
35
+            parent::__construct($repositoryUrl, $credentials);
36
+        }
37
+
38
+        protected function getUpdateDetectionStrategies($configBranch) {
39
+            $strategies = array(
40
+                self::STRATEGY_STABLE_TAG => function () use ($configBranch) {
41
+                    return $this->getStableTag($configBranch);
42
+                },
43
+            );
44
+
45
+            if ( ($configBranch === 'master' || $configBranch === 'main') ) {
46
+                $strategies[self::STRATEGY_LATEST_TAG] = array($this, 'getLatestTag');
47
+            }
48
+
49
+            $strategies[self::STRATEGY_BRANCH] = function () use ($configBranch) {
50
+                return $this->getBranch($configBranch);
51
+            };
52
+            return $strategies;
53
+        }
54
+
55
+        public function getBranch($branchName) {
56
+            $branch = $this->api('/refs/branches/' . $branchName);
57
+            if ( is_wp_error($branch) || empty($branch) ) {
58
+                return null;
59
+            }
60
+
61
+            //The "/src/{stuff}/{path}" endpoint doesn't seem to handle branch names that contain slashes.
62
+            //If we don't encode the slash, we get a 404. If we encode it as "%2F", we get a 401.
63
+            //To avoid issues, if the branch name is not URL-safe, let's use the commit hash instead.
64
+            $ref = $branch->name;
65
+            if ((urlencode($ref) !== $ref) && isset($branch->target->hash)) {
66
+                $ref = $branch->target->hash;
67
+            }
68
+
69
+            return new Reference(array(
70
+                'name' => $ref,
71
+                'updated' => $branch->target->date,
72
+                'downloadUrl' => $this->getDownloadUrl($branch->name),
73
+            ));
74
+        }
75
+
76
+        /**
77
+         * Get a specific tag.
78
+         *
79
+         * @param string $tagName
80
+         * @return Reference|null
81
+         */
82
+        public function getTag($tagName) {
83
+            $tag = $this->api('/refs/tags/' . $tagName);
84
+            if ( is_wp_error($tag) || empty($tag) ) {
85
+                return null;
86
+            }
87
+
88
+            return new Reference(array(
89
+                'name' => $tag->name,
90
+                'version' => ltrim($tag->name, 'v'),
91
+                'updated' => $tag->target->date,
92
+                'downloadUrl' => $this->getDownloadUrl($tag->name),
93
+            ));
94
+        }
95
+
96
+        /**
97
+         * Get the tag that looks like the highest version number.
98
+         *
99
+         * @return Reference|null
100
+         */
101
+        public function getLatestTag() {
102
+            $tags = $this->api('/refs/tags?sort=-target.date');
103
+            if ( !isset($tags, $tags->values) || !is_array($tags->values) ) {
104
+                return null;
105
+            }
106
+
107
+            //Filter and sort the list of tags.
108
+            $versionTags = $this->sortTagsByVersion($tags->values);
109
+
110
+            //Return the first result.
111
+            if ( !empty($versionTags) ) {
112
+                $tag = $versionTags[0];
113
+                return new Reference(array(
114
+                    'name' => $tag->name,
115
+                    'version' => ltrim($tag->name, 'v'),
116
+                    'updated' => $tag->target->date,
117
+                    'downloadUrl' => $this->getDownloadUrl($tag->name),
118
+                ));
119
+            }
120
+            return null;
121
+        }
122
+
123
+        /**
124
+         * Get the tag/ref specified by the "Stable tag" header in the readme.txt of a given branch.
125
+         *
126
+         * @param string $branch
127
+         * @return null|Reference
128
+         */
129
+        protected function getStableTag($branch) {
130
+            $remoteReadme = $this->getRemoteReadme($branch);
131
+            if ( !empty($remoteReadme['stable_tag']) ) {
132
+                $tag = $remoteReadme['stable_tag'];
133
+
134
+                //You can explicitly opt out of using tags by setting "Stable tag" to
135
+                //"trunk" or the name of the current branch.
136
+                if ( ($tag === $branch) || ($tag === 'trunk') ) {
137
+                    return $this->getBranch($branch);
138
+                }
139
+
140
+                return $this->getTag($tag);
141
+            }
142
+
143
+            return null;
144
+        }
145
+
146
+        /**
147
+         * @param string $ref
148
+         * @return string
149
+         */
150
+        protected function getDownloadUrl($ref) {
151
+            return sprintf(
152
+                'https://bitbucket.org/%s/%s/get/%s.zip',
153
+                $this->username,
154
+                $this->repository,
155
+                $ref
156
+            );
157
+        }
158
+
159
+        /**
160
+         * Get the contents of a file from a specific branch or tag.
161
+         *
162
+         * @param string $path File name.
163
+         * @param string $ref
164
+         * @return null|string Either the contents of the file, or null if the file doesn't exist or there's an error.
165
+         */
166
+        public function getRemoteFile($path, $ref = 'master') {
167
+            $response = $this->api('src/' . $ref . '/' . ltrim($path));
168
+            if ( is_wp_error($response) || !is_string($response) ) {
169
+                return null;
170
+            }
171
+            return $response;
172
+        }
173
+
174
+        /**
175
+         * Get the timestamp of the latest commit that changed the specified branch or tag.
176
+         *
177
+         * @param string $ref Reference name (e.g. branch or tag).
178
+         * @return string|null
179
+         */
180
+        public function getLatestCommitTime($ref) {
181
+            $response = $this->api('commits/' . $ref);
182
+            if ( isset($response->values, $response->values[0], $response->values[0]->date) ) {
183
+                return $response->values[0]->date;
184
+            }
185
+            return null;
186
+        }
187
+
188
+        /**
189
+         * Perform a BitBucket API 2.0 request.
190
+         *
191
+         * @param string $url
192
+         * @param string $version
193
+         * @return mixed|\WP_Error
194
+         */
195
+        public function api($url, $version = '2.0') {
196
+            $url = ltrim($url, '/');
197
+            $isSrcResource = Utils::startsWith($url, 'src/');
198
+
199
+            $url = implode('/', array(
200
+                'https://api.bitbucket.org',
201
+                $version,
202
+                'repositories',
203
+                $this->username,
204
+                $this->repository,
205
+                $url
206
+            ));
207
+            $baseUrl = $url;
208
+
209
+            if ( $this->oauth ) {
210
+                $url = $this->oauth->sign($url,'GET');
211
+            }
212
+
213
+            $options = array('timeout' => 10);
214
+            if ( !empty($this->httpFilterName) ) {
215
+                $options = apply_filters($this->httpFilterName, $options);
216
+            }
217
+            $response = wp_remote_get($url, $options);
218
+            if ( is_wp_error($response) ) {
219
+                do_action('puc_api_error', $response, null, $url, $this->slug);
220
+                return $response;
221
+            }
222
+
223
+            $code = wp_remote_retrieve_response_code($response);
224
+            $body = wp_remote_retrieve_body($response);
225
+            if ( $code === 200 ) {
226
+                if ( $isSrcResource ) {
227
+                    //Most responses are JSON-encoded, but src resources just
228
+                    //return raw file contents.
229
+                    $document = $body;
230
+                } else {
231
+                    $document = json_decode($body);
232
+                }
233
+                return $document;
234
+            }
235
+
236
+            $error = new \WP_Error(
237
+                'puc-bitbucket-http-error',
238
+                sprintf('BitBucket API error. Base URL: "%s",  HTTP status code: %d.', $baseUrl, $code)
239
+            );
240
+            do_action('puc_api_error', $error, $response, $url, $this->slug);
241
+
242
+            return $error;
243
+        }
244
+
245
+        /**
246
+         * @param array $credentials
247
+         */
248
+        public function setAuthentication($credentials) {
249
+            parent::setAuthentication($credentials);
250
+
251
+            if ( !empty($credentials) && !empty($credentials['consumer_key']) ) {
252
+                $this->oauth = new OAuthSignature(
253
+                    $credentials['consumer_key'],
254
+                    $credentials['consumer_secret']
255
+                );
256
+            } else {
257
+                $this->oauth = null;
258
+            }
259
+        }
260
+
261
+        public function signDownloadUrl($url) {
262
+            //Add authentication data to download URLs. Since OAuth signatures incorporate
263
+            //timestamps, we have to do this immediately before inserting the update. Otherwise,
264
+            //authentication could fail due to a stale timestamp.
265
+            if ( $this->oauth ) {
266
+                $url = $this->oauth->sign($url);
267
+            }
268
+            return $url;
269
+        }
270
+    }
271 271
 
272 272
 endif;
Please login to merge, or discard this patch.
Spacing   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -5,7 +5,7 @@  discard block
 block discarded – undo
5 5
 use YahnisElsts\PluginUpdateChecker\v5p0\OAuthSignature;
6 6
 use YahnisElsts\PluginUpdateChecker\v5p0\Utils;
7 7
 
8
-if ( !class_exists(BitBucketApi::class, false) ):
8
+if (!class_exists(BitBucketApi::class, false)):
9 9
 
10 10
 	class BitBucketApi extends Api {
11 11
 		/**
@@ -25,7 +25,7 @@  discard block
 block discarded – undo
25 25
 
26 26
 		public function __construct($repositoryUrl, $credentials = array()) {
27 27
 			$path = wp_parse_url($repositoryUrl, PHP_URL_PATH);
28
-			if ( preg_match('@^/?(?P<username>[^/]+?)/(?P<repository>[^/#?&]+?)/?$@', $path, $matches) ) {
28
+			if (preg_match('@^/?(?P<username>[^/]+?)/(?P<repository>[^/#?&]+?)/?$@', $path, $matches)) {
29 29
 				$this->username = $matches['username'];
30 30
 				$this->repository = $matches['repository'];
31 31
 			} else {
@@ -37,16 +37,16 @@  discard block
 block discarded – undo
37 37
 
38 38
 		protected function getUpdateDetectionStrategies($configBranch) {
39 39
 			$strategies = array(
40
-				self::STRATEGY_STABLE_TAG => function () use ($configBranch) {
40
+				self::STRATEGY_STABLE_TAG => function() use ($configBranch) {
41 41
 					return $this->getStableTag($configBranch);
42 42
 				},
43 43
 			);
44 44
 
45
-			if ( ($configBranch === 'master' || $configBranch === 'main') ) {
45
+			if (($configBranch === 'master' || $configBranch === 'main')) {
46 46
 				$strategies[self::STRATEGY_LATEST_TAG] = array($this, 'getLatestTag');
47 47
 			}
48 48
 
49
-			$strategies[self::STRATEGY_BRANCH] = function () use ($configBranch) {
49
+			$strategies[self::STRATEGY_BRANCH] = function() use ($configBranch) {
50 50
 				return $this->getBranch($configBranch);
51 51
 			};
52 52
 			return $strategies;
@@ -54,7 +54,7 @@  discard block
 block discarded – undo
54 54
 
55 55
 		public function getBranch($branchName) {
56 56
 			$branch = $this->api('/refs/branches/' . $branchName);
57
-			if ( is_wp_error($branch) || empty($branch) ) {
57
+			if (is_wp_error($branch) || empty($branch)) {
58 58
 				return null;
59 59
 			}
60 60
 
@@ -81,7 +81,7 @@  discard block
 block discarded – undo
81 81
 		 */
82 82
 		public function getTag($tagName) {
83 83
 			$tag = $this->api('/refs/tags/' . $tagName);
84
-			if ( is_wp_error($tag) || empty($tag) ) {
84
+			if (is_wp_error($tag) || empty($tag)) {
85 85
 				return null;
86 86
 			}
87 87
 
@@ -100,7 +100,7 @@  discard block
 block discarded – undo
100 100
 		 */
101 101
 		public function getLatestTag() {
102 102
 			$tags = $this->api('/refs/tags?sort=-target.date');
103
-			if ( !isset($tags, $tags->values) || !is_array($tags->values) ) {
103
+			if (!isset($tags, $tags->values) || !is_array($tags->values)) {
104 104
 				return null;
105 105
 			}
106 106
 
@@ -108,7 +108,7 @@  discard block
 block discarded – undo
108 108
 			$versionTags = $this->sortTagsByVersion($tags->values);
109 109
 
110 110
 			//Return the first result.
111
-			if ( !empty($versionTags) ) {
111
+			if (!empty($versionTags)) {
112 112
 				$tag = $versionTags[0];
113 113
 				return new Reference(array(
114 114
 					'name' => $tag->name,
@@ -128,12 +128,12 @@  discard block
 block discarded – undo
128 128
 		 */
129 129
 		protected function getStableTag($branch) {
130 130
 			$remoteReadme = $this->getRemoteReadme($branch);
131
-			if ( !empty($remoteReadme['stable_tag']) ) {
131
+			if (!empty($remoteReadme['stable_tag'])) {
132 132
 				$tag = $remoteReadme['stable_tag'];
133 133
 
134 134
 				//You can explicitly opt out of using tags by setting "Stable tag" to
135 135
 				//"trunk" or the name of the current branch.
136
-				if ( ($tag === $branch) || ($tag === 'trunk') ) {
136
+				if (($tag === $branch) || ($tag === 'trunk')) {
137 137
 					return $this->getBranch($branch);
138 138
 				}
139 139
 
@@ -165,7 +165,7 @@  discard block
 block discarded – undo
165 165
 		 */
166 166
 		public function getRemoteFile($path, $ref = 'master') {
167 167
 			$response = $this->api('src/' . $ref . '/' . ltrim($path));
168
-			if ( is_wp_error($response) || !is_string($response) ) {
168
+			if (is_wp_error($response) || !is_string($response)) {
169 169
 				return null;
170 170
 			}
171 171
 			return $response;
@@ -179,7 +179,7 @@  discard block
 block discarded – undo
179 179
 		 */
180 180
 		public function getLatestCommitTime($ref) {
181 181
 			$response = $this->api('commits/' . $ref);
182
-			if ( isset($response->values, $response->values[0], $response->values[0]->date) ) {
182
+			if (isset($response->values, $response->values[0], $response->values[0]->date)) {
183 183
 				return $response->values[0]->date;
184 184
 			}
185 185
 			return null;
@@ -206,24 +206,24 @@  discard block
 block discarded – undo
206 206
 			));
207 207
 			$baseUrl = $url;
208 208
 
209
-			if ( $this->oauth ) {
210
-				$url = $this->oauth->sign($url,'GET');
209
+			if ($this->oauth) {
210
+				$url = $this->oauth->sign($url, 'GET');
211 211
 			}
212 212
 
213 213
 			$options = array('timeout' => 10);
214
-			if ( !empty($this->httpFilterName) ) {
214
+			if (!empty($this->httpFilterName)) {
215 215
 				$options = apply_filters($this->httpFilterName, $options);
216 216
 			}
217 217
 			$response = wp_remote_get($url, $options);
218
-			if ( is_wp_error($response) ) {
218
+			if (is_wp_error($response)) {
219 219
 				do_action('puc_api_error', $response, null, $url, $this->slug);
220 220
 				return $response;
221 221
 			}
222 222
 
223 223
 			$code = wp_remote_retrieve_response_code($response);
224 224
 			$body = wp_remote_retrieve_body($response);
225
-			if ( $code === 200 ) {
226
-				if ( $isSrcResource ) {
225
+			if ($code === 200) {
226
+				if ($isSrcResource) {
227 227
 					//Most responses are JSON-encoded, but src resources just
228 228
 					//return raw file contents.
229 229
 					$document = $body;
@@ -248,7 +248,7 @@  discard block
 block discarded – undo
248 248
 		public function setAuthentication($credentials) {
249 249
 			parent::setAuthentication($credentials);
250 250
 
251
-			if ( !empty($credentials) && !empty($credentials['consumer_key']) ) {
251
+			if (!empty($credentials) && !empty($credentials['consumer_key'])) {
252 252
 				$this->oauth = new OAuthSignature(
253 253
 					$credentials['consumer_key'],
254 254
 					$credentials['consumer_secret']
@@ -262,7 +262,7 @@  discard block
 block discarded – undo
262 262
 			//Add authentication data to download URLs. Since OAuth signatures incorporate
263 263
 			//timestamps, we have to do this immediately before inserting the update. Otherwise,
264 264
 			//authentication could fail due to a stale timestamp.
265
-			if ( $this->oauth ) {
265
+			if ($this->oauth) {
266 266
 				$url = $this->oauth->sign($url);
267 267
 			}
268 268
 			return $url;
Please login to merge, or discard this patch.
brighty-core/includes/plugin-update-checker-5-1.0/Puc/v5p0/Vcs/Api.php 2 patches
Indentation   +343 added lines, -343 removed lines patch added patch discarded remove patch
@@ -6,348 +6,348 @@
 block discarded – undo
6 6
 
7 7
 if ( !class_exists(Api::class, false) ):
8 8
 
9
-	abstract class Api {
10
-		const STRATEGY_LATEST_RELEASE = 'latest_release';
11
-		const STRATEGY_LATEST_TAG = 'latest_tag';
12
-		const STRATEGY_STABLE_TAG = 'stable_tag';
13
-		const STRATEGY_BRANCH = 'branch';
14
-
15
-		protected $tagNameProperty = 'name';
16
-		protected $slug = '';
17
-
18
-		/**
19
-		 * @var string
20
-		 */
21
-		protected $repositoryUrl = '';
22
-
23
-		/**
24
-		 * @var mixed Authentication details for private repositories. Format depends on service.
25
-		 */
26
-		protected $credentials = null;
27
-
28
-		/**
29
-		 * @var string The filter tag that's used to filter options passed to wp_remote_get.
30
-		 * For example, "puc_request_info_options-slug" or "puc_request_update_options_theme-slug".
31
-		 */
32
-		protected $httpFilterName = '';
33
-
34
-		/**
35
-		 * @var string The filter applied to the list of update detection strategies that
36
-		 * are used to find the latest version.
37
-		 */
38
-		protected $strategyFilterName = '';
39
-
40
-		/**
41
-		 * @var string|null
42
-		 */
43
-		protected $localDirectory = null;
44
-
45
-		/**
46
-		 * Api constructor.
47
-		 *
48
-		 * @param string $repositoryUrl
49
-		 * @param array|string|null $credentials
50
-		 */
51
-		public function __construct($repositoryUrl, $credentials = null) {
52
-			$this->repositoryUrl = $repositoryUrl;
53
-			$this->setAuthentication($credentials);
54
-		}
55
-
56
-		/**
57
-		 * @return string
58
-		 */
59
-		public function getRepositoryUrl() {
60
-			return $this->repositoryUrl;
61
-		}
62
-
63
-		/**
64
-		 * Figure out which reference (i.e. tag or branch) contains the latest version.
65
-		 *
66
-		 * @param string $configBranch Start looking in this branch.
67
-		 * @return null|Reference
68
-		 */
69
-		public function chooseReference($configBranch) {
70
-			$strategies = $this->getUpdateDetectionStrategies($configBranch);
71
-
72
-			if ( !empty($this->strategyFilterName) ) {
73
-				$strategies = apply_filters(
74
-					$this->strategyFilterName,
75
-					$strategies,
76
-					$this->slug
77
-				);
78
-			}
79
-
80
-			foreach ($strategies as $strategy) {
81
-				$reference = call_user_func($strategy);
82
-				if ( !empty($reference) ) {
83
-					return $reference;
84
-				}
85
-			}
86
-			return null;
87
-		}
88
-
89
-		/**
90
-		 * Get an ordered list of strategies that can be used to find the latest version.
91
-		 *
92
-		 * The update checker will try each strategy in order until one of them
93
-		 * returns a valid reference.
94
-		 *
95
-		 * @param string $configBranch
96
-		 * @return array<callable> Array of callables that return Vcs_Reference objects.
97
-		 */
98
-		abstract protected function getUpdateDetectionStrategies($configBranch);
99
-
100
-		/**
101
-		 * Get the readme.txt file from the remote repository and parse it
102
-		 * according to the plugin readme standard.
103
-		 *
104
-		 * @param string $ref Tag or branch name.
105
-		 * @return array Parsed readme.
106
-		 */
107
-		public function getRemoteReadme($ref = 'master') {
108
-			$fileContents = $this->getRemoteFile($this->getLocalReadmeName(), $ref);
109
-			if ( empty($fileContents) ) {
110
-				return array();
111
-			}
112
-
113
-			$parser = new PucReadmeParser();
114
-			return $parser->parse_readme_contents($fileContents);
115
-		}
116
-
117
-		/**
118
-		 * Get the case-sensitive name of the local readme.txt file.
119
-		 *
120
-		 * In most cases it should just be called "readme.txt", but some plugins call it "README.txt",
121
-		 * "README.TXT", or even "Readme.txt". Most VCS are case-sensitive so we need to know the correct
122
-		 * capitalization.
123
-		 *
124
-		 * Defaults to "readme.txt" (all lowercase).
125
-		 *
126
-		 * @return string
127
-		 */
128
-		public function getLocalReadmeName() {
129
-			static $fileName = null;
130
-			if ( $fileName !== null ) {
131
-				return $fileName;
132
-			}
133
-
134
-			$fileName = 'readme.txt';
135
-			if ( isset($this->localDirectory) ) {
136
-				$files = scandir($this->localDirectory);
137
-				if ( !empty($files) ) {
138
-					foreach ($files as $possibleFileName) {
139
-						if ( strcasecmp($possibleFileName, 'readme.txt') === 0 ) {
140
-							$fileName = $possibleFileName;
141
-							break;
142
-						}
143
-					}
144
-				}
145
-			}
146
-			return $fileName;
147
-		}
148
-
149
-		/**
150
-		 * Get a branch.
151
-		 *
152
-		 * @param string $branchName
153
-		 * @return Reference|null
154
-		 */
155
-		abstract public function getBranch($branchName);
156
-
157
-		/**
158
-		 * Get a specific tag.
159
-		 *
160
-		 * @param string $tagName
161
-		 * @return Reference|null
162
-		 */
163
-		abstract public function getTag($tagName);
164
-
165
-		/**
166
-		 * Get the tag that looks like the highest version number.
167
-		 * (Implementations should skip pre-release versions if possible.)
168
-		 *
169
-		 * @return Reference|null
170
-		 */
171
-		abstract public function getLatestTag();
172
-
173
-		/**
174
-		 * Check if a tag name string looks like a version number.
175
-		 *
176
-		 * @param string $name
177
-		 * @return bool
178
-		 */
179
-		protected function looksLikeVersion($name) {
180
-			//Tag names may be prefixed with "v", e.g. "v1.2.3".
181
-			$name = ltrim($name, 'v');
182
-
183
-			//The version string must start with a number.
184
-			if ( !is_numeric(substr($name, 0, 1)) ) {
185
-				return false;
186
-			}
187
-
188
-			//The goal is to accept any SemVer-compatible or "PHP-standardized" version number.
189
-			return (preg_match('@^(\d{1,5}?)(\.\d{1,10}?){0,4}?($|[abrdp+_\-]|\s)@i', $name) === 1);
190
-		}
191
-
192
-		/**
193
-		 * Check if a tag appears to be named like a version number.
194
-		 *
195
-		 * @param \stdClass $tag
196
-		 * @return bool
197
-		 */
198
-		protected function isVersionTag($tag) {
199
-			$property = $this->tagNameProperty;
200
-			return isset($tag->$property) && $this->looksLikeVersion($tag->$property);
201
-		}
202
-
203
-		/**
204
-		 * Sort a list of tags as if they were version numbers.
205
-		 * Tags that don't look like version number will be removed.
206
-		 *
207
-		 * @param \stdClass[] $tags Array of tag objects.
208
-		 * @return \stdClass[] Filtered array of tags sorted in descending order.
209
-		 */
210
-		protected function sortTagsByVersion($tags) {
211
-			//Keep only those tags that look like version numbers.
212
-			$versionTags = array_filter($tags, array($this, 'isVersionTag'));
213
-			//Sort them in descending order.
214
-			usort($versionTags, array($this, 'compareTagNames'));
215
-
216
-			return $versionTags;
217
-		}
218
-
219
-		/**
220
-		 * Compare two tags as if they were version number.
221
-		 *
222
-		 * @param \stdClass $tag1 Tag object.
223
-		 * @param \stdClass $tag2 Another tag object.
224
-		 * @return int
225
-		 */
226
-		protected function compareTagNames($tag1, $tag2) {
227
-			$property = $this->tagNameProperty;
228
-			if ( !isset($tag1->$property) ) {
229
-				return 1;
230
-			}
231
-			if ( !isset($tag2->$property) ) {
232
-				return -1;
233
-			}
234
-			return -version_compare(ltrim($tag1->$property, 'v'), ltrim($tag2->$property, 'v'));
235
-		}
236
-
237
-		/**
238
-		 * Get the contents of a file from a specific branch or tag.
239
-		 *
240
-		 * @param string $path File name.
241
-		 * @param string $ref
242
-		 * @return null|string Either the contents of the file, or null if the file doesn't exist or there's an error.
243
-		 */
244
-		abstract public function getRemoteFile($path, $ref = 'master');
245
-
246
-		/**
247
-		 * Get the timestamp of the latest commit that changed the specified branch or tag.
248
-		 *
249
-		 * @param string $ref Reference name (e.g. branch or tag).
250
-		 * @return string|null
251
-		 */
252
-		abstract public function getLatestCommitTime($ref);
253
-
254
-		/**
255
-		 * Get the contents of the changelog file from the repository.
256
-		 *
257
-		 * @param string $ref
258
-		 * @param string $localDirectory Full path to the local plugin or theme directory.
259
-		 * @return null|string The HTML contents of the changelog.
260
-		 */
261
-		public function getRemoteChangelog($ref, $localDirectory) {
262
-			$filename = $this->findChangelogName($localDirectory);
263
-			if ( empty($filename) ) {
264
-				return null;
265
-			}
266
-
267
-			$changelog = $this->getRemoteFile($filename, $ref);
268
-			if ( $changelog === null ) {
269
-				return null;
270
-			}
271
-
272
-			return Parsedown::instance()->text($changelog);
273
-		}
274
-
275
-		/**
276
-		 * Guess the name of the changelog file.
277
-		 *
278
-		 * @param string $directory
279
-		 * @return string|null
280
-		 */
281
-		protected function findChangelogName($directory = null) {
282
-			if ( !isset($directory) ) {
283
-				$directory = $this->localDirectory;
284
-			}
285
-			if ( empty($directory) || !is_dir($directory) || ($directory === '.') ) {
286
-				return null;
287
-			}
288
-
289
-			$possibleNames = array('CHANGES.md', 'CHANGELOG.md', 'changes.md', 'changelog.md');
290
-			$files = scandir($directory);
291
-			$foundNames = array_intersect($possibleNames, $files);
292
-
293
-			if ( !empty($foundNames) ) {
294
-				return reset($foundNames);
295
-			}
296
-			return null;
297
-		}
298
-
299
-		/**
300
-		 * Set authentication credentials.
301
-		 *
302
-		 * @param $credentials
303
-		 */
304
-		public function setAuthentication($credentials) {
305
-			$this->credentials = $credentials;
306
-		}
307
-
308
-		public function isAuthenticationEnabled() {
309
-			return !empty($this->credentials);
310
-		}
311
-
312
-		/**
313
-		 * @param string $url
314
-		 * @return string
315
-		 */
316
-		public function signDownloadUrl($url) {
317
-			return $url;
318
-		}
319
-
320
-		/**
321
-		 * @param string $filterName
322
-		 */
323
-		public function setHttpFilterName($filterName) {
324
-			$this->httpFilterName = $filterName;
325
-		}
326
-
327
-		/**
328
-		 * @param string $filterName
329
-		 */
330
-		public function setStrategyFilterName($filterName) {
331
-			$this->strategyFilterName = $filterName;
332
-		}
333
-
334
-		/**
335
-		 * @param string $directory
336
-		 */
337
-		public function setLocalDirectory($directory) {
338
-			if ( empty($directory) || !is_dir($directory) || ($directory === '.') ) {
339
-				$this->localDirectory = null;
340
-			} else {
341
-				$this->localDirectory = $directory;
342
-			}
343
-		}
344
-
345
-		/**
346
-		 * @param string $slug
347
-		 */
348
-		public function setSlug($slug) {
349
-			$this->slug = $slug;
350
-		}
351
-	}
9
+    abstract class Api {
10
+        const STRATEGY_LATEST_RELEASE = 'latest_release';
11
+        const STRATEGY_LATEST_TAG = 'latest_tag';
12
+        const STRATEGY_STABLE_TAG = 'stable_tag';
13
+        const STRATEGY_BRANCH = 'branch';
14
+
15
+        protected $tagNameProperty = 'name';
16
+        protected $slug = '';
17
+
18
+        /**
19
+         * @var string
20
+         */
21
+        protected $repositoryUrl = '';
22
+
23
+        /**
24
+         * @var mixed Authentication details for private repositories. Format depends on service.
25
+         */
26
+        protected $credentials = null;
27
+
28
+        /**
29
+         * @var string The filter tag that's used to filter options passed to wp_remote_get.
30
+         * For example, "puc_request_info_options-slug" or "puc_request_update_options_theme-slug".
31
+         */
32
+        protected $httpFilterName = '';
33
+
34
+        /**
35
+         * @var string The filter applied to the list of update detection strategies that
36
+         * are used to find the latest version.
37
+         */
38
+        protected $strategyFilterName = '';
39
+
40
+        /**
41
+         * @var string|null
42
+         */
43
+        protected $localDirectory = null;
44
+
45
+        /**
46
+         * Api constructor.
47
+         *
48
+         * @param string $repositoryUrl
49
+         * @param array|string|null $credentials
50
+         */
51
+        public function __construct($repositoryUrl, $credentials = null) {
52
+            $this->repositoryUrl = $repositoryUrl;
53
+            $this->setAuthentication($credentials);
54
+        }
55
+
56
+        /**
57
+         * @return string
58
+         */
59
+        public function getRepositoryUrl() {
60
+            return $this->repositoryUrl;
61
+        }
62
+
63
+        /**
64
+         * Figure out which reference (i.e. tag or branch) contains the latest version.
65
+         *
66
+         * @param string $configBranch Start looking in this branch.
67
+         * @return null|Reference
68
+         */
69
+        public function chooseReference($configBranch) {
70
+            $strategies = $this->getUpdateDetectionStrategies($configBranch);
71
+
72
+            if ( !empty($this->strategyFilterName) ) {
73
+                $strategies = apply_filters(
74
+                    $this->strategyFilterName,
75
+                    $strategies,
76
+                    $this->slug
77
+                );
78
+            }
79
+
80
+            foreach ($strategies as $strategy) {
81
+                $reference = call_user_func($strategy);
82
+                if ( !empty($reference) ) {
83
+                    return $reference;
84
+                }
85
+            }
86
+            return null;
87
+        }
88
+
89
+        /**
90
+         * Get an ordered list of strategies that can be used to find the latest version.
91
+         *
92
+         * The update checker will try each strategy in order until one of them
93
+         * returns a valid reference.
94
+         *
95
+         * @param string $configBranch
96
+         * @return array<callable> Array of callables that return Vcs_Reference objects.
97
+         */
98
+        abstract protected function getUpdateDetectionStrategies($configBranch);
99
+
100
+        /**
101
+         * Get the readme.txt file from the remote repository and parse it
102
+         * according to the plugin readme standard.
103
+         *
104
+         * @param string $ref Tag or branch name.
105
+         * @return array Parsed readme.
106
+         */
107
+        public function getRemoteReadme($ref = 'master') {
108
+            $fileContents = $this->getRemoteFile($this->getLocalReadmeName(), $ref);
109
+            if ( empty($fileContents) ) {
110
+                return array();
111
+            }
112
+
113
+            $parser = new PucReadmeParser();
114
+            return $parser->parse_readme_contents($fileContents);
115
+        }
116
+
117
+        /**
118
+         * Get the case-sensitive name of the local readme.txt file.
119
+         *
120
+         * In most cases it should just be called "readme.txt", but some plugins call it "README.txt",
121
+         * "README.TXT", or even "Readme.txt". Most VCS are case-sensitive so we need to know the correct
122
+         * capitalization.
123
+         *
124
+         * Defaults to "readme.txt" (all lowercase).
125
+         *
126
+         * @return string
127
+         */
128
+        public function getLocalReadmeName() {
129
+            static $fileName = null;
130
+            if ( $fileName !== null ) {
131
+                return $fileName;
132
+            }
133
+
134
+            $fileName = 'readme.txt';
135
+            if ( isset($this->localDirectory) ) {
136
+                $files = scandir($this->localDirectory);
137
+                if ( !empty($files) ) {
138
+                    foreach ($files as $possibleFileName) {
139
+                        if ( strcasecmp($possibleFileName, 'readme.txt') === 0 ) {
140
+                            $fileName = $possibleFileName;
141
+                            break;
142
+                        }
143
+                    }
144
+                }
145
+            }
146
+            return $fileName;
147
+        }
148
+
149
+        /**
150
+         * Get a branch.
151
+         *
152
+         * @param string $branchName
153
+         * @return Reference|null
154
+         */
155
+        abstract public function getBranch($branchName);
156
+
157
+        /**
158
+         * Get a specific tag.
159
+         *
160
+         * @param string $tagName
161
+         * @return Reference|null
162
+         */
163
+        abstract public function getTag($tagName);
164
+
165
+        /**
166
+         * Get the tag that looks like the highest version number.
167
+         * (Implementations should skip pre-release versions if possible.)
168
+         *
169
+         * @return Reference|null
170
+         */
171
+        abstract public function getLatestTag();
172
+
173
+        /**
174
+         * Check if a tag name string looks like a version number.
175
+         *
176
+         * @param string $name
177
+         * @return bool
178
+         */
179
+        protected function looksLikeVersion($name) {
180
+            //Tag names may be prefixed with "v", e.g. "v1.2.3".
181
+            $name = ltrim($name, 'v');
182
+
183
+            //The version string must start with a number.
184
+            if ( !is_numeric(substr($name, 0, 1)) ) {
185
+                return false;
186
+            }
187
+
188
+            //The goal is to accept any SemVer-compatible or "PHP-standardized" version number.
189
+            return (preg_match('@^(\d{1,5}?)(\.\d{1,10}?){0,4}?($|[abrdp+_\-]|\s)@i', $name) === 1);
190
+        }
191
+
192
+        /**
193
+         * Check if a tag appears to be named like a version number.
194
+         *
195
+         * @param \stdClass $tag
196
+         * @return bool
197
+         */
198
+        protected function isVersionTag($tag) {
199
+            $property = $this->tagNameProperty;
200
+            return isset($tag->$property) && $this->looksLikeVersion($tag->$property);
201
+        }
202
+
203
+        /**
204
+         * Sort a list of tags as if they were version numbers.
205
+         * Tags that don't look like version number will be removed.
206
+         *
207
+         * @param \stdClass[] $tags Array of tag objects.
208
+         * @return \stdClass[] Filtered array of tags sorted in descending order.
209
+         */
210
+        protected function sortTagsByVersion($tags) {
211
+            //Keep only those tags that look like version numbers.
212
+            $versionTags = array_filter($tags, array($this, 'isVersionTag'));
213
+            //Sort them in descending order.
214
+            usort($versionTags, array($this, 'compareTagNames'));
215
+
216
+            return $versionTags;
217
+        }
218
+
219
+        /**
220
+         * Compare two tags as if they were version number.
221
+         *
222
+         * @param \stdClass $tag1 Tag object.
223
+         * @param \stdClass $tag2 Another tag object.
224
+         * @return int
225
+         */
226
+        protected function compareTagNames($tag1, $tag2) {
227
+            $property = $this->tagNameProperty;
228
+            if ( !isset($tag1->$property) ) {
229
+                return 1;
230
+            }
231
+            if ( !isset($tag2->$property) ) {
232
+                return -1;
233
+            }
234
+            return -version_compare(ltrim($tag1->$property, 'v'), ltrim($tag2->$property, 'v'));
235
+        }
236
+
237
+        /**
238
+         * Get the contents of a file from a specific branch or tag.
239
+         *
240
+         * @param string $path File name.
241
+         * @param string $ref
242
+         * @return null|string Either the contents of the file, or null if the file doesn't exist or there's an error.
243
+         */
244
+        abstract public function getRemoteFile($path, $ref = 'master');
245
+
246
+        /**
247
+         * Get the timestamp of the latest commit that changed the specified branch or tag.
248
+         *
249
+         * @param string $ref Reference name (e.g. branch or tag).
250
+         * @return string|null
251
+         */
252
+        abstract public function getLatestCommitTime($ref);
253
+
254
+        /**
255
+         * Get the contents of the changelog file from the repository.
256
+         *
257
+         * @param string $ref
258
+         * @param string $localDirectory Full path to the local plugin or theme directory.
259
+         * @return null|string The HTML contents of the changelog.
260
+         */
261
+        public function getRemoteChangelog($ref, $localDirectory) {
262
+            $filename = $this->findChangelogName($localDirectory);
263
+            if ( empty($filename) ) {
264
+                return null;
265
+            }
266
+
267
+            $changelog = $this->getRemoteFile($filename, $ref);
268
+            if ( $changelog === null ) {
269
+                return null;
270
+            }
271
+
272
+            return Parsedown::instance()->text($changelog);
273
+        }
274
+
275
+        /**
276
+         * Guess the name of the changelog file.
277
+         *
278
+         * @param string $directory
279
+         * @return string|null
280
+         */
281
+        protected function findChangelogName($directory = null) {
282
+            if ( !isset($directory) ) {
283
+                $directory = $this->localDirectory;
284
+            }
285
+            if ( empty($directory) || !is_dir($directory) || ($directory === '.') ) {
286
+                return null;
287
+            }
288
+
289
+            $possibleNames = array('CHANGES.md', 'CHANGELOG.md', 'changes.md', 'changelog.md');
290
+            $files = scandir($directory);
291
+            $foundNames = array_intersect($possibleNames, $files);
292
+
293
+            if ( !empty($foundNames) ) {
294
+                return reset($foundNames);
295
+            }
296
+            return null;
297
+        }
298
+
299
+        /**
300
+         * Set authentication credentials.
301
+         *
302
+         * @param $credentials
303
+         */
304
+        public function setAuthentication($credentials) {
305
+            $this->credentials = $credentials;
306
+        }
307
+
308
+        public function isAuthenticationEnabled() {
309
+            return !empty($this->credentials);
310
+        }
311
+
312
+        /**
313
+         * @param string $url
314
+         * @return string
315
+         */
316
+        public function signDownloadUrl($url) {
317
+            return $url;
318
+        }
319
+
320
+        /**
321
+         * @param string $filterName
322
+         */
323
+        public function setHttpFilterName($filterName) {
324
+            $this->httpFilterName = $filterName;
325
+        }
326
+
327
+        /**
328
+         * @param string $filterName
329
+         */
330
+        public function setStrategyFilterName($filterName) {
331
+            $this->strategyFilterName = $filterName;
332
+        }
333
+
334
+        /**
335
+         * @param string $directory
336
+         */
337
+        public function setLocalDirectory($directory) {
338
+            if ( empty($directory) || !is_dir($directory) || ($directory === '.') ) {
339
+                $this->localDirectory = null;
340
+            } else {
341
+                $this->localDirectory = $directory;
342
+            }
343
+        }
344
+
345
+        /**
346
+         * @param string $slug
347
+         */
348
+        public function setSlug($slug) {
349
+            $this->slug = $slug;
350
+        }
351
+    }
352 352
 
353 353
 endif;
Please login to merge, or discard this patch.
Spacing   +17 added lines, -17 removed lines patch added patch discarded remove patch
@@ -4,7 +4,7 @@  discard block
 block discarded – undo
4 4
 use Parsedown;
5 5
 use PucReadmeParser;
6 6
 
7
-if ( !class_exists(Api::class, false) ):
7
+if (!class_exists(Api::class, false)):
8 8
 
9 9
 	abstract class Api {
10 10
 		const STRATEGY_LATEST_RELEASE = 'latest_release';
@@ -69,7 +69,7 @@  discard block
 block discarded – undo
69 69
 		public function chooseReference($configBranch) {
70 70
 			$strategies = $this->getUpdateDetectionStrategies($configBranch);
71 71
 
72
-			if ( !empty($this->strategyFilterName) ) {
72
+			if (!empty($this->strategyFilterName)) {
73 73
 				$strategies = apply_filters(
74 74
 					$this->strategyFilterName,
75 75
 					$strategies,
@@ -79,7 +79,7 @@  discard block
 block discarded – undo
79 79
 
80 80
 			foreach ($strategies as $strategy) {
81 81
 				$reference = call_user_func($strategy);
82
-				if ( !empty($reference) ) {
82
+				if (!empty($reference)) {
83 83
 					return $reference;
84 84
 				}
85 85
 			}
@@ -106,7 +106,7 @@  discard block
 block discarded – undo
106 106
 		 */
107 107
 		public function getRemoteReadme($ref = 'master') {
108 108
 			$fileContents = $this->getRemoteFile($this->getLocalReadmeName(), $ref);
109
-			if ( empty($fileContents) ) {
109
+			if (empty($fileContents)) {
110 110
 				return array();
111 111
 			}
112 112
 
@@ -127,16 +127,16 @@  discard block
 block discarded – undo
127 127
 		 */
128 128
 		public function getLocalReadmeName() {
129 129
 			static $fileName = null;
130
-			if ( $fileName !== null ) {
130
+			if ($fileName !== null) {
131 131
 				return $fileName;
132 132
 			}
133 133
 
134 134
 			$fileName = 'readme.txt';
135
-			if ( isset($this->localDirectory) ) {
135
+			if (isset($this->localDirectory)) {
136 136
 				$files = scandir($this->localDirectory);
137
-				if ( !empty($files) ) {
137
+				if (!empty($files)) {
138 138
 					foreach ($files as $possibleFileName) {
139
-						if ( strcasecmp($possibleFileName, 'readme.txt') === 0 ) {
139
+						if (strcasecmp($possibleFileName, 'readme.txt') === 0) {
140 140
 							$fileName = $possibleFileName;
141 141
 							break;
142 142
 						}
@@ -181,7 +181,7 @@  discard block
 block discarded – undo
181 181
 			$name = ltrim($name, 'v');
182 182
 
183 183
 			//The version string must start with a number.
184
-			if ( !is_numeric(substr($name, 0, 1)) ) {
184
+			if (!is_numeric(substr($name, 0, 1))) {
185 185
 				return false;
186 186
 			}
187 187
 
@@ -225,10 +225,10 @@  discard block
 block discarded – undo
225 225
 		 */
226 226
 		protected function compareTagNames($tag1, $tag2) {
227 227
 			$property = $this->tagNameProperty;
228
-			if ( !isset($tag1->$property) ) {
228
+			if (!isset($tag1->$property)) {
229 229
 				return 1;
230 230
 			}
231
-			if ( !isset($tag2->$property) ) {
231
+			if (!isset($tag2->$property)) {
232 232
 				return -1;
233 233
 			}
234 234
 			return -version_compare(ltrim($tag1->$property, 'v'), ltrim($tag2->$property, 'v'));
@@ -260,12 +260,12 @@  discard block
 block discarded – undo
260 260
 		 */
261 261
 		public function getRemoteChangelog($ref, $localDirectory) {
262 262
 			$filename = $this->findChangelogName($localDirectory);
263
-			if ( empty($filename) ) {
263
+			if (empty($filename)) {
264 264
 				return null;
265 265
 			}
266 266
 
267 267
 			$changelog = $this->getRemoteFile($filename, $ref);
268
-			if ( $changelog === null ) {
268
+			if ($changelog === null) {
269 269
 				return null;
270 270
 			}
271 271
 
@@ -279,10 +279,10 @@  discard block
 block discarded – undo
279 279
 		 * @return string|null
280 280
 		 */
281 281
 		protected function findChangelogName($directory = null) {
282
-			if ( !isset($directory) ) {
282
+			if (!isset($directory)) {
283 283
 				$directory = $this->localDirectory;
284 284
 			}
285
-			if ( empty($directory) || !is_dir($directory) || ($directory === '.') ) {
285
+			if (empty($directory) || !is_dir($directory) || ($directory === '.')) {
286 286
 				return null;
287 287
 			}
288 288
 
@@ -290,7 +290,7 @@  discard block
 block discarded – undo
290 290
 			$files = scandir($directory);
291 291
 			$foundNames = array_intersect($possibleNames, $files);
292 292
 
293
-			if ( !empty($foundNames) ) {
293
+			if (!empty($foundNames)) {
294 294
 				return reset($foundNames);
295 295
 			}
296 296
 			return null;
@@ -335,7 +335,7 @@  discard block
 block discarded – undo
335 335
 		 * @param string $directory
336 336
 		 */
337 337
 		public function setLocalDirectory($directory) {
338
-			if ( empty($directory) || !is_dir($directory) || ($directory === '.') ) {
338
+			if (empty($directory) || !is_dir($directory) || ($directory === '.')) {
339 339
 				$this->localDirectory = null;
340 340
 			} else {
341 341
 				$this->localDirectory = $directory;
Please login to merge, or discard this patch.
includes/plugin-update-checker-5-1.0/Puc/v5p0/Vcs/BaseChecker.php 2 patches
Indentation   +20 added lines, -20 removed lines patch added patch discarded remove patch
@@ -3,27 +3,27 @@
 block discarded – undo
3 3
 
4 4
 if ( !interface_exists(BaseChecker::class, false) ):
5 5
 
6
-	interface BaseChecker {
7
-		/**
8
-		 * Set the repository branch to use for updates. Defaults to 'master'.
9
-		 *
10
-		 * @param string $branch
11
-		 * @return $this
12
-		 */
13
-		public function setBranch($branch);
6
+    interface BaseChecker {
7
+        /**
8
+         * Set the repository branch to use for updates. Defaults to 'master'.
9
+         *
10
+         * @param string $branch
11
+         * @return $this
12
+         */
13
+        public function setBranch($branch);
14 14
 
15
-		/**
16
-		 * Set authentication credentials.
17
-		 *
18
-		 * @param array|string $credentials
19
-		 * @return $this
20
-		 */
21
-		public function setAuthentication($credentials);
15
+        /**
16
+         * Set authentication credentials.
17
+         *
18
+         * @param array|string $credentials
19
+         * @return $this
20
+         */
21
+        public function setAuthentication($credentials);
22 22
 
23
-		/**
24
-		 * @return Api
25
-		 */
26
-		public function getVcsApi();
27
-	}
23
+        /**
24
+         * @return Api
25
+         */
26
+        public function getVcsApi();
27
+    }
28 28
 
29 29
 endif;
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -1,7 +1,7 @@
 block discarded – undo
1 1
 <?php
2 2
 namespace YahnisElsts\PluginUpdateChecker\v5p0\Vcs;
3 3
 
4
-if ( !interface_exists(BaseChecker::class, false) ):
4
+if (!interface_exists(BaseChecker::class, false)):
5 5
 
6 6
 	interface BaseChecker {
7 7
 		/**
Please login to merge, or discard this patch.
includes/plugin-update-checker-5-1.0/Puc/v5p0/Vcs/VcsCheckerMethods.php 2 patches
Indentation   +51 added lines, -51 removed lines patch added patch discarded remove patch
@@ -4,56 +4,56 @@
 block discarded – undo
4 4
 
5 5
 if ( !trait_exists(VcsCheckerMethods::class, false) ) :
6 6
 
7
-	trait VcsCheckerMethods {
8
-		/**
9
-		 * @var string The branch where to look for updates. Defaults to "master".
10
-		 */
11
-		protected $branch = 'master';
12
-
13
-		/**
14
-		 * @var Api Repository API client.
15
-		 */
16
-		protected $api = null;
17
-
18
-		public function setBranch($branch) {
19
-			$this->branch = $branch;
20
-			return $this;
21
-		}
22
-
23
-		/**
24
-		 * Set authentication credentials.
25
-		 *
26
-		 * @param array|string $credentials
27
-		 * @return $this
28
-		 */
29
-		public function setAuthentication($credentials) {
30
-			$this->api->setAuthentication($credentials);
31
-			return $this;
32
-		}
33
-
34
-		/**
35
-		 * @return Api
36
-		 */
37
-		public function getVcsApi() {
38
-			return $this->api;
39
-		}
40
-
41
-		public function getUpdate() {
42
-			$update = parent::getUpdate();
43
-
44
-			if ( isset($update) && !empty($update->download_url) ) {
45
-				$update->download_url = $this->api->signDownloadUrl($update->download_url);
46
-			}
47
-
48
-			return $update;
49
-		}
50
-
51
-		public function onDisplayConfiguration($panel) {
52
-			parent::onDisplayConfiguration($panel);
53
-			$panel->row('Branch', $this->branch);
54
-			$panel->row('Authentication enabled', $this->api->isAuthenticationEnabled() ? 'Yes' : 'No');
55
-			$panel->row('API client', get_class($this->api));
56
-		}
57
-	}
7
+    trait VcsCheckerMethods {
8
+        /**
9
+         * @var string The branch where to look for updates. Defaults to "master".
10
+         */
11
+        protected $branch = 'master';
12
+
13
+        /**
14
+         * @var Api Repository API client.
15
+         */
16
+        protected $api = null;
17
+
18
+        public function setBranch($branch) {
19
+            $this->branch = $branch;
20
+            return $this;
21
+        }
22
+
23
+        /**
24
+         * Set authentication credentials.
25
+         *
26
+         * @param array|string $credentials
27
+         * @return $this
28
+         */
29
+        public function setAuthentication($credentials) {
30
+            $this->api->setAuthentication($credentials);
31
+            return $this;
32
+        }
33
+
34
+        /**
35
+         * @return Api
36
+         */
37
+        public function getVcsApi() {
38
+            return $this->api;
39
+        }
40
+
41
+        public function getUpdate() {
42
+            $update = parent::getUpdate();
43
+
44
+            if ( isset($update) && !empty($update->download_url) ) {
45
+                $update->download_url = $this->api->signDownloadUrl($update->download_url);
46
+            }
47
+
48
+            return $update;
49
+        }
50
+
51
+        public function onDisplayConfiguration($panel) {
52
+            parent::onDisplayConfiguration($panel);
53
+            $panel->row('Branch', $this->branch);
54
+            $panel->row('Authentication enabled', $this->api->isAuthenticationEnabled() ? 'Yes' : 'No');
55
+            $panel->row('API client', get_class($this->api));
56
+        }
57
+    }
58 58
 
59 59
 endif;
60 60
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -2,7 +2,7 @@  discard block
 block discarded – undo
2 2
 
3 3
 namespace YahnisElsts\PluginUpdateChecker\v5p0\Vcs;
4 4
 
5
-if ( !trait_exists(VcsCheckerMethods::class, false) ) :
5
+if (!trait_exists(VcsCheckerMethods::class, false)) :
6 6
 
7 7
 	trait VcsCheckerMethods {
8 8
 		/**
@@ -41,7 +41,7 @@  discard block
 block discarded – undo
41 41
 		public function getUpdate() {
42 42
 			$update = parent::getUpdate();
43 43
 
44
-			if ( isset($update) && !empty($update->download_url) ) {
44
+			if (isset($update) && !empty($update->download_url)) {
45 45
 				$update->download_url = $this->api->signDownloadUrl($update->download_url);
46 46
 			}
47 47
 
Please login to merge, or discard this patch.