Completed
Pull Request — master (#223)
by
unknown
01:56
created
classes/external/php/plugin-update-checker/Puc/v4p4/Vcs/GitLabApi.php 1 patch
Indentation   +267 added lines, -267 removed lines patch added patch discarded remove patch
@@ -2,273 +2,273 @@
 block discarded – undo
2 2
 
3 3
 if ( !class_exists('Puc_v4p4_Vcs_GitLabApi', false) ):
4 4
 
5
-	class Puc_v4p4_Vcs_GitLabApi extends Puc_v4p4_Vcs_Api {
6
-		/**
7
-		 * @var string GitLab username.
8
-		 */
9
-		protected $userName;
10
-
11
-		/**
12
-		 * @var string GitLab server host.
13
-		 */
14
-		private $repositoryHost;
15
-
16
-		/**
17
-		 * @var string GitLab repository name.
18
-		 */
19
-		protected $repositoryName;
20
-
21
-		/**
22
-		 * @var string GitLab authentication token. Optional.
23
-		 */
24
-		protected $accessToken;
25
-
26
-		public function __construct($repositoryUrl, $accessToken = null) {
27
-			//Parse the repository host to support custom hosts.
28
-			$this->repositoryHost = @parse_url($repositoryUrl, PHP_URL_HOST);
29
-
30
-			//Find the repository information
31
-			$path = @parse_url($repositoryUrl, PHP_URL_PATH);
32
-			if ( preg_match('@^/?(?P<username>[^/]+?)/(?P<repository>[^/#?&]+?)/?$@', $path, $matches) ) {
33
-				$this->userName = $matches['username'];
34
-				$this->repositoryName = $matches['repository'];
35
-			} else {
36
-				//This is not a traditional url, it could be gitlab is in a deeper subdirectory.
37
-				//Get the path segments.
38
-				$segments = explode('/', untrailingslashit(ltrim($path, '/')));
39
-
40
-				//We need at least /user-name/repository-name/
41
-				if ( count($segments) < 2 ) {
42
-					throw new InvalidArgumentException('Invalid GitLab repository URL: "' . $repositoryUrl . '"');
43
-				}
44
-
45
-				//Get the username and repository name.
46
-				$usernameRepo = array_splice($segments, -2, 2);
47
-				$this->userName = $usernameRepo[0];
48
-				$this->repositoryName = $usernameRepo[1];
49
-
50
-				//Append the remaining segments to the host.
51
-				$this->repositoryHost = trailingslashit($this->repositoryHost) . implode('/', $segments);
52
-			}
53
-
54
-			parent::__construct($repositoryUrl, $accessToken);
55
-		}
56
-
57
-		/**
58
-		 * Get the latest release from GitLab.
59
-		 *
60
-		 * @return Puc_v4p4_Vcs_Reference|null
61
-		 */
62
-		public function getLatestRelease() {
63
-			return $this->getLatestTag();
64
-		}
65
-
66
-		/**
67
-		 * Get the tag that looks like the highest version number.
68
-		 *
69
-		 * @return Puc_v4p4_Vcs_Reference|null
70
-		 */
71
-		public function getLatestTag() {
72
-			$tags = $this->api('/:user/:repo/repository/tags');
73
-			if ( is_wp_error($tags) || empty($tags) || !is_array($tags) ) {
74
-				return null;
75
-			}
76
-
77
-			$versionTags = $this->sortTagsByVersion($tags);
78
-			if ( empty($versionTags) ) {
79
-				return null;
80
-			}
81
-
82
-			$tag = $versionTags[0];
83
-			return new Puc_v4p4_Vcs_Reference(array(
84
-				'name' => $tag->name,
85
-				'version' => ltrim($tag->name, 'v'),
86
-				'downloadUrl' => $this->buildArchiveDownloadUrl($tag->name),
87
-				'apiResponse' => $tag
88
-			));
89
-		}
90
-
91
-		/**
92
-		 * Get a branch by name.
93
-		 *
94
-		 * @param string $branchName
95
-		 * @return null|Puc_v4p4_Vcs_Reference
96
-		 */
97
-		public function getBranch($branchName) {
98
-			$branch = $this->api('/:user/:repo/repository/branches/' . $branchName);
99
-			if ( is_wp_error($branch) || empty($branch) ) {
100
-				return null;
101
-			}
102
-
103
-			$reference = new Puc_v4p4_Vcs_Reference(array(
104
-				'name' => $branch->name,
105
-				'downloadUrl' => $this->buildArchiveDownloadUrl($branch->name),
106
-				'apiResponse' => $branch,
107
-			));
108
-
109
-			if ( isset($branch->commit, $branch->commit->committed_date) ) {
110
-				$reference->updated = $branch->commit->committed_date;
111
-			}
112
-
113
-			return $reference;
114
-		}
115
-
116
-		/**
117
-		 * Get the timestamp of the latest commit that changed the specified branch or tag.
118
-		 *
119
-		 * @param string $ref Reference name (e.g. branch or tag).
120
-		 * @return string|null
121
-		 */
122
-		public function getLatestCommitTime($ref) {
123
-			$commits = $this->api('/:user/:repo/repository/commits/', array('ref_name' => $ref));
124
-			if ( is_wp_error($commits) || !is_array($commits) || !isset($commits[0]) ) {
125
-				return null;
126
-			}
127
-
128
-			return $commits[0]->committed_date;
129
-		}
130
-
131
-		/**
132
-		 * Perform a GitLab API request.
133
-		 *
134
-		 * @param string $url
135
-		 * @param array $queryParams
136
-		 * @return mixed|WP_Error
137
-		 */
138
-		protected function api($url, $queryParams = array()) {
139
-			$baseUrl = $url;
140
-			$url = $this->buildApiUrl($url, $queryParams);
141
-
142
-			$options = array('timeout' => 10);
143
-			if ( !empty($this->httpFilterName) ) {
144
-				$options = apply_filters($this->httpFilterName, $options);
145
-			}
5
+    class Puc_v4p4_Vcs_GitLabApi extends Puc_v4p4_Vcs_Api {
6
+        /**
7
+         * @var string GitLab username.
8
+         */
9
+        protected $userName;
10
+
11
+        /**
12
+         * @var string GitLab server host.
13
+         */
14
+        private $repositoryHost;
15
+
16
+        /**
17
+         * @var string GitLab repository name.
18
+         */
19
+        protected $repositoryName;
20
+
21
+        /**
22
+         * @var string GitLab authentication token. Optional.
23
+         */
24
+        protected $accessToken;
25
+
26
+        public function __construct($repositoryUrl, $accessToken = null) {
27
+            //Parse the repository host to support custom hosts.
28
+            $this->repositoryHost = @parse_url($repositoryUrl, PHP_URL_HOST);
29
+
30
+            //Find the repository information
31
+            $path = @parse_url($repositoryUrl, PHP_URL_PATH);
32
+            if ( preg_match('@^/?(?P<username>[^/]+?)/(?P<repository>[^/#?&]+?)/?$@', $path, $matches) ) {
33
+                $this->userName = $matches['username'];
34
+                $this->repositoryName = $matches['repository'];
35
+            } else {
36
+                //This is not a traditional url, it could be gitlab is in a deeper subdirectory.
37
+                //Get the path segments.
38
+                $segments = explode('/', untrailingslashit(ltrim($path, '/')));
39
+
40
+                //We need at least /user-name/repository-name/
41
+                if ( count($segments) < 2 ) {
42
+                    throw new InvalidArgumentException('Invalid GitLab repository URL: "' . $repositoryUrl . '"');
43
+                }
44
+
45
+                //Get the username and repository name.
46
+                $usernameRepo = array_splice($segments, -2, 2);
47
+                $this->userName = $usernameRepo[0];
48
+                $this->repositoryName = $usernameRepo[1];
49
+
50
+                //Append the remaining segments to the host.
51
+                $this->repositoryHost = trailingslashit($this->repositoryHost) . implode('/', $segments);
52
+            }
53
+
54
+            parent::__construct($repositoryUrl, $accessToken);
55
+        }
56
+
57
+        /**
58
+         * Get the latest release from GitLab.
59
+         *
60
+         * @return Puc_v4p4_Vcs_Reference|null
61
+         */
62
+        public function getLatestRelease() {
63
+            return $this->getLatestTag();
64
+        }
65
+
66
+        /**
67
+         * Get the tag that looks like the highest version number.
68
+         *
69
+         * @return Puc_v4p4_Vcs_Reference|null
70
+         */
71
+        public function getLatestTag() {
72
+            $tags = $this->api('/:user/:repo/repository/tags');
73
+            if ( is_wp_error($tags) || empty($tags) || !is_array($tags) ) {
74
+                return null;
75
+            }
76
+
77
+            $versionTags = $this->sortTagsByVersion($tags);
78
+            if ( empty($versionTags) ) {
79
+                return null;
80
+            }
81
+
82
+            $tag = $versionTags[0];
83
+            return new Puc_v4p4_Vcs_Reference(array(
84
+                'name' => $tag->name,
85
+                'version' => ltrim($tag->name, 'v'),
86
+                'downloadUrl' => $this->buildArchiveDownloadUrl($tag->name),
87
+                'apiResponse' => $tag
88
+            ));
89
+        }
90
+
91
+        /**
92
+         * Get a branch by name.
93
+         *
94
+         * @param string $branchName
95
+         * @return null|Puc_v4p4_Vcs_Reference
96
+         */
97
+        public function getBranch($branchName) {
98
+            $branch = $this->api('/:user/:repo/repository/branches/' . $branchName);
99
+            if ( is_wp_error($branch) || empty($branch) ) {
100
+                return null;
101
+            }
102
+
103
+            $reference = new Puc_v4p4_Vcs_Reference(array(
104
+                'name' => $branch->name,
105
+                'downloadUrl' => $this->buildArchiveDownloadUrl($branch->name),
106
+                'apiResponse' => $branch,
107
+            ));
108
+
109
+            if ( isset($branch->commit, $branch->commit->committed_date) ) {
110
+                $reference->updated = $branch->commit->committed_date;
111
+            }
112
+
113
+            return $reference;
114
+        }
115
+
116
+        /**
117
+         * Get the timestamp of the latest commit that changed the specified branch or tag.
118
+         *
119
+         * @param string $ref Reference name (e.g. branch or tag).
120
+         * @return string|null
121
+         */
122
+        public function getLatestCommitTime($ref) {
123
+            $commits = $this->api('/:user/:repo/repository/commits/', array('ref_name' => $ref));
124
+            if ( is_wp_error($commits) || !is_array($commits) || !isset($commits[0]) ) {
125
+                return null;
126
+            }
127
+
128
+            return $commits[0]->committed_date;
129
+        }
130
+
131
+        /**
132
+         * Perform a GitLab API request.
133
+         *
134
+         * @param string $url
135
+         * @param array $queryParams
136
+         * @return mixed|WP_Error
137
+         */
138
+        protected function api($url, $queryParams = array()) {
139
+            $baseUrl = $url;
140
+            $url = $this->buildApiUrl($url, $queryParams);
141
+
142
+            $options = array('timeout' => 10);
143
+            if ( !empty($this->httpFilterName) ) {
144
+                $options = apply_filters($this->httpFilterName, $options);
145
+            }
146 146
 			
147
-			$response = wp_remote_get($url, $options);
148
-			if ( is_wp_error($response) ) {
149
-				do_action('puc_api_error', $response, null, $url, $this->slug);
150
-				return $response;
151
-			}
152
-
153
-			$code = wp_remote_retrieve_response_code($response);
154
-			$body = wp_remote_retrieve_body($response);
155
-			if ( $code === 200 ) {
156
-				return json_decode($body);
157
-			}
158
-
159
-			$error = new WP_Error(
160
-				'puc-gitlab-http-error',
161
-				sprintf('GitLab API error. URL: "%s",  HTTP status code: %d.', $baseUrl, $code)
162
-			);
163
-			do_action('puc_api_error', $error, $response, $url, $this->slug);
164
-
165
-			return $error;
166
-		}
167
-
168
-		/**
169
-		 * Build a fully qualified URL for an API request.
170
-		 *
171
-		 * @param string $url
172
-		 * @param array $queryParams
173
-		 * @return string
174
-		 */
175
-		protected function buildApiUrl($url, $queryParams) {
176
-			$variables = array(
177
-				'user' => $this->userName,
178
-				'repo' => $this->repositoryName
179
-			);
180
-
181
-			foreach ($variables as $name => $value) {
182
-				$url = str_replace("/:{$name}", urlencode('/' . $value), $url);
183
-			}
184
-
185
-			$url = substr($url, 3);
186
-			$url = sprintf('https://%1$s/api/v4/projects/%2$s', $this->repositoryHost, $url);
187
-
188
-			if ( !empty($this->accessToken) ) {
189
-				$queryParams['private_token'] = $this->accessToken;
190
-			}
191
-
192
-			if ( !empty($queryParams) ) {
193
-				$url = add_query_arg($queryParams, $url);
194
-			}
195
-
196
-			return $url;
197
-		}
198
-
199
-		/**
200
-		 * Get the contents of a file from a specific branch or tag.
201
-		 *
202
-		 * @param string $path File name.
203
-		 * @param string $ref
204
-		 * @return null|string Either the contents of the file, or null if the file doesn't exist or there's an error.
205
-		 */
206
-		public function getRemoteFile($path, $ref = 'master') {
207
-			$response = $this->api('/:user/:repo/repository/files/' . $path, array('ref' => $ref));
208
-			if ( is_wp_error($response) || !isset($response->content) || $response->encoding !== 'base64' ) {
209
-				return null;
210
-			}
211
-
212
-			return base64_decode($response->content);
213
-		}
214
-
215
-		/**
216
-		 * Generate a URL to download a ZIP archive of the specified branch/tag/etc.
217
-		 *
218
-		 * @param string $ref
219
-		 * @return string
220
-		 */
221
-		public function buildArchiveDownloadUrl($ref = 'master') {
222
-			$url = sprintf(
223
-				'https://%1$s/%2$s/%3$s/repository/%4$s/archive.zip',
224
-				$this->repositoryHost,
225
-				urlencode($this->userName),
226
-				urlencode($this->repositoryName),
227
-				urlencode($ref)
228
-			);
229
-
230
-			if ( !empty($this->accessToken) ) {
231
-				$url = add_query_arg('private_token', $this->accessToken, $url);
232
-			}
233
-
234
-			return $url;
235
-		}
236
-
237
-		/**
238
-		 * Get a specific tag.
239
-		 *
240
-		 * @param string $tagName
241
-		 * @return Puc_v4p4_Vcs_Reference|null
242
-		 */
243
-		public function getTag($tagName) {
244
-			throw new LogicException('The ' . __METHOD__ . ' method is not implemented and should not be used.');
245
-		}
246
-
247
-		/**
248
-		 * Figure out which reference (i.e tag or branch) contains the latest version.
249
-		 *
250
-		 * @param string $configBranch Start looking in this branch.
251
-		 * @return null|Puc_v4p4_Vcs_Reference
252
-		 */
253
-		public function chooseReference($configBranch) {
254
-			$updateSource = null;
255
-
256
-			// GitLab doesn't handle releases the same as GitHub so just use the latest tag
257
-			if ( $configBranch === 'master' ) {
258
-				$updateSource = $this->getLatestTag();
259
-			}
260
-
261
-			if ( empty($updateSource) ) {
262
-				$updateSource = $this->getBranch($configBranch);
263
-			}
264
-
265
-			return $updateSource;
266
-		}
267
-
268
-		public function setAuthentication($credentials) {
269
-			parent::setAuthentication($credentials);
270
-			$this->accessToken = is_string($credentials) ? $credentials : null;
271
-		}
272
-	}
147
+            $response = wp_remote_get($url, $options);
148
+            if ( is_wp_error($response) ) {
149
+                do_action('puc_api_error', $response, null, $url, $this->slug);
150
+                return $response;
151
+            }
152
+
153
+            $code = wp_remote_retrieve_response_code($response);
154
+            $body = wp_remote_retrieve_body($response);
155
+            if ( $code === 200 ) {
156
+                return json_decode($body);
157
+            }
158
+
159
+            $error = new WP_Error(
160
+                'puc-gitlab-http-error',
161
+                sprintf('GitLab API error. URL: "%s",  HTTP status code: %d.', $baseUrl, $code)
162
+            );
163
+            do_action('puc_api_error', $error, $response, $url, $this->slug);
164
+
165
+            return $error;
166
+        }
167
+
168
+        /**
169
+         * Build a fully qualified URL for an API request.
170
+         *
171
+         * @param string $url
172
+         * @param array $queryParams
173
+         * @return string
174
+         */
175
+        protected function buildApiUrl($url, $queryParams) {
176
+            $variables = array(
177
+                'user' => $this->userName,
178
+                'repo' => $this->repositoryName
179
+            );
180
+
181
+            foreach ($variables as $name => $value) {
182
+                $url = str_replace("/:{$name}", urlencode('/' . $value), $url);
183
+            }
184
+
185
+            $url = substr($url, 3);
186
+            $url = sprintf('https://%1$s/api/v4/projects/%2$s', $this->repositoryHost, $url);
187
+
188
+            if ( !empty($this->accessToken) ) {
189
+                $queryParams['private_token'] = $this->accessToken;
190
+            }
191
+
192
+            if ( !empty($queryParams) ) {
193
+                $url = add_query_arg($queryParams, $url);
194
+            }
195
+
196
+            return $url;
197
+        }
198
+
199
+        /**
200
+         * Get the contents of a file from a specific branch or tag.
201
+         *
202
+         * @param string $path File name.
203
+         * @param string $ref
204
+         * @return null|string Either the contents of the file, or null if the file doesn't exist or there's an error.
205
+         */
206
+        public function getRemoteFile($path, $ref = 'master') {
207
+            $response = $this->api('/:user/:repo/repository/files/' . $path, array('ref' => $ref));
208
+            if ( is_wp_error($response) || !isset($response->content) || $response->encoding !== 'base64' ) {
209
+                return null;
210
+            }
211
+
212
+            return base64_decode($response->content);
213
+        }
214
+
215
+        /**
216
+         * Generate a URL to download a ZIP archive of the specified branch/tag/etc.
217
+         *
218
+         * @param string $ref
219
+         * @return string
220
+         */
221
+        public function buildArchiveDownloadUrl($ref = 'master') {
222
+            $url = sprintf(
223
+                'https://%1$s/%2$s/%3$s/repository/%4$s/archive.zip',
224
+                $this->repositoryHost,
225
+                urlencode($this->userName),
226
+                urlencode($this->repositoryName),
227
+                urlencode($ref)
228
+            );
229
+
230
+            if ( !empty($this->accessToken) ) {
231
+                $url = add_query_arg('private_token', $this->accessToken, $url);
232
+            }
233
+
234
+            return $url;
235
+        }
236
+
237
+        /**
238
+         * Get a specific tag.
239
+         *
240
+         * @param string $tagName
241
+         * @return Puc_v4p4_Vcs_Reference|null
242
+         */
243
+        public function getTag($tagName) {
244
+            throw new LogicException('The ' . __METHOD__ . ' method is not implemented and should not be used.');
245
+        }
246
+
247
+        /**
248
+         * Figure out which reference (i.e tag or branch) contains the latest version.
249
+         *
250
+         * @param string $configBranch Start looking in this branch.
251
+         * @return null|Puc_v4p4_Vcs_Reference
252
+         */
253
+        public function chooseReference($configBranch) {
254
+            $updateSource = null;
255
+
256
+            // GitLab doesn't handle releases the same as GitHub so just use the latest tag
257
+            if ( $configBranch === 'master' ) {
258
+                $updateSource = $this->getLatestTag();
259
+            }
260
+
261
+            if ( empty($updateSource) ) {
262
+                $updateSource = $this->getBranch($configBranch);
263
+            }
264
+
265
+            return $updateSource;
266
+        }
267
+
268
+        public function setAuthentication($credentials) {
269
+            parent::setAuthentication($credentials);
270
+            $this->accessToken = is_string($credentials) ? $credentials : null;
271
+        }
272
+    }
273 273
 
274 274
 endif;
275 275
\ No newline at end of file
Please login to merge, or discard this patch.
classes/external/php/plugin-update-checker/Puc/v4p4/Vcs/Api.php 1 patch
Indentation   +297 added lines, -297 removed lines patch added patch discarded remove patch
@@ -1,302 +1,302 @@
 block discarded – undo
1 1
 <?php
2 2
 if ( !class_exists('Puc_v4p4_Vcs_Api') ):
3 3
 
4
-	abstract class Puc_v4p4_Vcs_Api {
5
-		protected $tagNameProperty = 'name';
6
-		protected $slug = '';
7
-
8
-		/**
9
-		 * @var string
10
-		 */
11
-		protected $repositoryUrl = '';
12
-
13
-		/**
14
-		 * @var mixed Authentication details for private repositories. Format depends on service.
15
-		 */
16
-		protected $credentials = null;
17
-
18
-		/**
19
-		 * @var string The filter tag that's used to filter options passed to wp_remote_get.
20
-		 * For example, "puc_request_info_options-slug" or "puc_request_update_options_theme-slug".
21
-		 */
22
-		protected $httpFilterName = '';
23
-
24
-		/**
25
-		 * @var string|null
26
-		 */
27
-		protected $localDirectory = null;
28
-
29
-		/**
30
-		 * Puc_v4p4_Vcs_Api constructor.
31
-		 *
32
-		 * @param string $repositoryUrl
33
-		 * @param array|string|null $credentials
34
-		 */
35
-		public function __construct($repositoryUrl, $credentials = null) {
36
-			$this->repositoryUrl = $repositoryUrl;
37
-			$this->setAuthentication($credentials);
38
-		}
39
-
40
-		/**
41
-		 * @return string
42
-		 */
43
-		public function getRepositoryUrl() {
44
-			return $this->repositoryUrl;
45
-		}
46
-
47
-		/**
48
-		 * Figure out which reference (i.e tag or branch) contains the latest version.
49
-		 *
50
-		 * @param string $configBranch Start looking in this branch.
51
-		 * @return null|Puc_v4p4_Vcs_Reference
52
-		 */
53
-		abstract public function chooseReference($configBranch);
54
-
55
-		/**
56
-		 * Get the readme.txt file from the remote repository and parse it
57
-		 * according to the plugin readme standard.
58
-		 *
59
-		 * @param string $ref Tag or branch name.
60
-		 * @return array Parsed readme.
61
-		 */
62
-		public function getRemoteReadme($ref = 'master') {
63
-			$fileContents = $this->getRemoteFile($this->getLocalReadmeName(), $ref);
64
-			if ( empty($fileContents) ) {
65
-				return array();
66
-			}
67
-
68
-			$parser = new PucReadmeParser();
69
-			return $parser->parse_readme_contents($fileContents);
70
-		}
71
-
72
-		/**
73
-		 * Get the case-sensitive name of the local readme.txt file.
74
-		 *
75
-		 * In most cases it should just be called "readme.txt", but some plugins call it "README.txt",
76
-		 * "README.TXT", or even "Readme.txt". Most VCS are case-sensitive so we need to know the correct
77
-		 * capitalization.
78
-		 *
79
-		 * Defaults to "readme.txt" (all lowercase).
80
-		 *
81
-		 * @return string
82
-		 */
83
-		public function getLocalReadmeName() {
84
-			static $fileName = null;
85
-			if ( $fileName !== null ) {
86
-				return $fileName;
87
-			}
88
-
89
-			$fileName = 'readme.txt';
90
-			if ( isset($this->localDirectory) ) {
91
-				$files = scandir($this->localDirectory);
92
-				if ( !empty($files) ) {
93
-					foreach ($files as $possibleFileName) {
94
-						if ( strcasecmp($possibleFileName, 'readme.txt') === 0 ) {
95
-							$fileName = $possibleFileName;
96
-							break;
97
-						}
98
-					}
99
-				}
100
-			}
101
-			return $fileName;
102
-		}
103
-
104
-		/**
105
-		 * Get a branch.
106
-		 *
107
-		 * @param string $branchName
108
-		 * @return Puc_v4p4_Vcs_Reference|null
109
-		 */
110
-		abstract public function getBranch($branchName);
111
-
112
-		/**
113
-		 * Get a specific tag.
114
-		 *
115
-		 * @param string $tagName
116
-		 * @return Puc_v4p4_Vcs_Reference|null
117
-		 */
118
-		abstract public function getTag($tagName);
119
-
120
-		/**
121
-		 * Get the tag that looks like the highest version number.
122
-		 * (Implementations should skip pre-release versions if possible.)
123
-		 *
124
-		 * @return Puc_v4p4_Vcs_Reference|null
125
-		 */
126
-		abstract public function getLatestTag();
127
-
128
-		/**
129
-		 * Check if a tag name string looks like a version number.
130
-		 *
131
-		 * @param string $name
132
-		 * @return bool
133
-		 */
134
-		protected function looksLikeVersion($name) {
135
-			//Tag names may be prefixed with "v", e.g. "v1.2.3".
136
-			$name = ltrim($name, 'v');
137
-
138
-			//The version string must start with a number.
139
-			if ( !is_numeric(substr($name, 0, 1)) ) {
140
-				return false;
141
-			}
142
-
143
-			//The goal is to accept any SemVer-compatible or "PHP-standardized" version number.
144
-			return (preg_match('@^(\d{1,5}?)(\.\d{1,10}?){0,4}?($|[abrdp+_\-]|\s)@i', $name) === 1);
145
-		}
146
-
147
-		/**
148
-		 * Check if a tag appears to be named like a version number.
149
-		 *
150
-		 * @param stdClass $tag
151
-		 * @return bool
152
-		 */
153
-		protected function isVersionTag($tag) {
154
-			$property = $this->tagNameProperty;
155
-			return isset($tag->$property) && $this->looksLikeVersion($tag->$property);
156
-		}
157
-
158
-		/**
159
-		 * Sort a list of tags as if they were version numbers.
160
-		 * Tags that don't look like version number will be removed.
161
-		 *
162
-		 * @param stdClass[] $tags Array of tag objects.
163
-		 * @return stdClass[] Filtered array of tags sorted in descending order.
164
-		 */
165
-		protected function sortTagsByVersion($tags) {
166
-			//Keep only those tags that look like version numbers.
167
-			$versionTags = array_filter($tags, array($this, 'isVersionTag'));
168
-			//Sort them in descending order.
169
-			usort($versionTags, array($this, 'compareTagNames'));
170
-
171
-			return $versionTags;
172
-		}
173
-
174
-		/**
175
-		 * Compare two tags as if they were version number.
176
-		 *
177
-		 * @param stdClass $tag1 Tag object.
178
-		 * @param stdClass $tag2 Another tag object.
179
-		 * @return int
180
-		 */
181
-		protected function compareTagNames($tag1, $tag2) {
182
-			$property = $this->tagNameProperty;
183
-			if ( !isset($tag1->$property) ) {
184
-				return 1;
185
-			}
186
-			if ( !isset($tag2->$property) ) {
187
-				return -1;
188
-			}
189
-			return -version_compare(ltrim($tag1->$property, 'v'), ltrim($tag2->$property, 'v'));
190
-		}
191
-
192
-		/**
193
-		 * Get the contents of a file from a specific branch or tag.
194
-		 *
195
-		 * @param string $path File name.
196
-		 * @param string $ref
197
-		 * @return null|string Either the contents of the file, or null if the file doesn't exist or there's an error.
198
-		 */
199
-		abstract public function getRemoteFile($path, $ref = 'master');
200
-
201
-		/**
202
-		 * Get the timestamp of the latest commit that changed the specified branch or tag.
203
-		 *
204
-		 * @param string $ref Reference name (e.g. branch or tag).
205
-		 * @return string|null
206
-		 */
207
-		abstract public function getLatestCommitTime($ref);
208
-
209
-		/**
210
-		 * Get the contents of the changelog file from the repository.
211
-		 *
212
-		 * @param string $ref
213
-		 * @param string $localDirectory Full path to the local plugin or theme directory.
214
-		 * @return null|string The HTML contents of the changelog.
215
-		 */
216
-		public function getRemoteChangelog($ref, $localDirectory) {
217
-			$filename = $this->findChangelogName($localDirectory);
218
-			if ( empty($filename) ) {
219
-				return null;
220
-			}
221
-
222
-			$changelog = $this->getRemoteFile($filename, $ref);
223
-			if ( $changelog === null ) {
224
-				return null;
225
-			}
226
-
227
-			/** @noinspection PhpUndefinedClassInspection */
228
-			return Parsedown::instance()->text($changelog);
229
-		}
230
-
231
-		/**
232
-		 * Guess the name of the changelog file.
233
-		 *
234
-		 * @param string $directory
235
-		 * @return string|null
236
-		 */
237
-		protected function findChangelogName($directory = null) {
238
-			if ( !isset($directory) ) {
239
-				$directory = $this->localDirectory;
240
-			}
241
-			if ( empty($directory) || !is_dir($directory) || ($directory === '.') ) {
242
-				return null;
243
-			}
244
-
245
-			$possibleNames = array('CHANGES.md', 'CHANGELOG.md', 'changes.md', 'changelog.md');
246
-			$files = scandir($directory);
247
-			$foundNames = array_intersect($possibleNames, $files);
248
-
249
-			if ( !empty($foundNames) ) {
250
-				return reset($foundNames);
251
-			}
252
-			return null;
253
-		}
254
-
255
-		/**
256
-		 * Set authentication credentials.
257
-		 *
258
-		 * @param $credentials
259
-		 */
260
-		public function setAuthentication($credentials) {
261
-			$this->credentials = $credentials;
262
-		}
263
-
264
-		public function isAuthenticationEnabled() {
265
-			return !empty($this->credentials);
266
-		}
267
-
268
-		/**
269
-		 * @param string $url
270
-		 * @return string
271
-		 */
272
-		public function signDownloadUrl($url) {
273
-			return $url;
274
-		}
275
-
276
-		/**
277
-		 * @param string $filterName
278
-		 */
279
-		public function setHttpFilterName($filterName) {
280
-			$this->httpFilterName = $filterName;
281
-		}
282
-
283
-		/**
284
-		 * @param string $directory
285
-		 */
286
-		public function setLocalDirectory($directory) {
287
-			if ( empty($directory) || !is_dir($directory) || ($directory === '.') ) {
288
-				$this->localDirectory = null;
289
-			} else {
290
-				$this->localDirectory = $directory;
291
-			}
292
-		}
293
-
294
-		/**
295
-		 * @param string $slug
296
-		 */
297
-		public function setSlug($slug) {
298
-			$this->slug = $slug;
299
-		}
300
-	}
4
+    abstract class Puc_v4p4_Vcs_Api {
5
+        protected $tagNameProperty = 'name';
6
+        protected $slug = '';
7
+
8
+        /**
9
+         * @var string
10
+         */
11
+        protected $repositoryUrl = '';
12
+
13
+        /**
14
+         * @var mixed Authentication details for private repositories. Format depends on service.
15
+         */
16
+        protected $credentials = null;
17
+
18
+        /**
19
+         * @var string The filter tag that's used to filter options passed to wp_remote_get.
20
+         * For example, "puc_request_info_options-slug" or "puc_request_update_options_theme-slug".
21
+         */
22
+        protected $httpFilterName = '';
23
+
24
+        /**
25
+         * @var string|null
26
+         */
27
+        protected $localDirectory = null;
28
+
29
+        /**
30
+         * Puc_v4p4_Vcs_Api constructor.
31
+         *
32
+         * @param string $repositoryUrl
33
+         * @param array|string|null $credentials
34
+         */
35
+        public function __construct($repositoryUrl, $credentials = null) {
36
+            $this->repositoryUrl = $repositoryUrl;
37
+            $this->setAuthentication($credentials);
38
+        }
39
+
40
+        /**
41
+         * @return string
42
+         */
43
+        public function getRepositoryUrl() {
44
+            return $this->repositoryUrl;
45
+        }
46
+
47
+        /**
48
+         * Figure out which reference (i.e tag or branch) contains the latest version.
49
+         *
50
+         * @param string $configBranch Start looking in this branch.
51
+         * @return null|Puc_v4p4_Vcs_Reference
52
+         */
53
+        abstract public function chooseReference($configBranch);
54
+
55
+        /**
56
+         * Get the readme.txt file from the remote repository and parse it
57
+         * according to the plugin readme standard.
58
+         *
59
+         * @param string $ref Tag or branch name.
60
+         * @return array Parsed readme.
61
+         */
62
+        public function getRemoteReadme($ref = 'master') {
63
+            $fileContents = $this->getRemoteFile($this->getLocalReadmeName(), $ref);
64
+            if ( empty($fileContents) ) {
65
+                return array();
66
+            }
67
+
68
+            $parser = new PucReadmeParser();
69
+            return $parser->parse_readme_contents($fileContents);
70
+        }
71
+
72
+        /**
73
+         * Get the case-sensitive name of the local readme.txt file.
74
+         *
75
+         * In most cases it should just be called "readme.txt", but some plugins call it "README.txt",
76
+         * "README.TXT", or even "Readme.txt". Most VCS are case-sensitive so we need to know the correct
77
+         * capitalization.
78
+         *
79
+         * Defaults to "readme.txt" (all lowercase).
80
+         *
81
+         * @return string
82
+         */
83
+        public function getLocalReadmeName() {
84
+            static $fileName = null;
85
+            if ( $fileName !== null ) {
86
+                return $fileName;
87
+            }
88
+
89
+            $fileName = 'readme.txt';
90
+            if ( isset($this->localDirectory) ) {
91
+                $files = scandir($this->localDirectory);
92
+                if ( !empty($files) ) {
93
+                    foreach ($files as $possibleFileName) {
94
+                        if ( strcasecmp($possibleFileName, 'readme.txt') === 0 ) {
95
+                            $fileName = $possibleFileName;
96
+                            break;
97
+                        }
98
+                    }
99
+                }
100
+            }
101
+            return $fileName;
102
+        }
103
+
104
+        /**
105
+         * Get a branch.
106
+         *
107
+         * @param string $branchName
108
+         * @return Puc_v4p4_Vcs_Reference|null
109
+         */
110
+        abstract public function getBranch($branchName);
111
+
112
+        /**
113
+         * Get a specific tag.
114
+         *
115
+         * @param string $tagName
116
+         * @return Puc_v4p4_Vcs_Reference|null
117
+         */
118
+        abstract public function getTag($tagName);
119
+
120
+        /**
121
+         * Get the tag that looks like the highest version number.
122
+         * (Implementations should skip pre-release versions if possible.)
123
+         *
124
+         * @return Puc_v4p4_Vcs_Reference|null
125
+         */
126
+        abstract public function getLatestTag();
127
+
128
+        /**
129
+         * Check if a tag name string looks like a version number.
130
+         *
131
+         * @param string $name
132
+         * @return bool
133
+         */
134
+        protected function looksLikeVersion($name) {
135
+            //Tag names may be prefixed with "v", e.g. "v1.2.3".
136
+            $name = ltrim($name, 'v');
137
+
138
+            //The version string must start with a number.
139
+            if ( !is_numeric(substr($name, 0, 1)) ) {
140
+                return false;
141
+            }
142
+
143
+            //The goal is to accept any SemVer-compatible or "PHP-standardized" version number.
144
+            return (preg_match('@^(\d{1,5}?)(\.\d{1,10}?){0,4}?($|[abrdp+_\-]|\s)@i', $name) === 1);
145
+        }
146
+
147
+        /**
148
+         * Check if a tag appears to be named like a version number.
149
+         *
150
+         * @param stdClass $tag
151
+         * @return bool
152
+         */
153
+        protected function isVersionTag($tag) {
154
+            $property = $this->tagNameProperty;
155
+            return isset($tag->$property) && $this->looksLikeVersion($tag->$property);
156
+        }
157
+
158
+        /**
159
+         * Sort a list of tags as if they were version numbers.
160
+         * Tags that don't look like version number will be removed.
161
+         *
162
+         * @param stdClass[] $tags Array of tag objects.
163
+         * @return stdClass[] Filtered array of tags sorted in descending order.
164
+         */
165
+        protected function sortTagsByVersion($tags) {
166
+            //Keep only those tags that look like version numbers.
167
+            $versionTags = array_filter($tags, array($this, 'isVersionTag'));
168
+            //Sort them in descending order.
169
+            usort($versionTags, array($this, 'compareTagNames'));
170
+
171
+            return $versionTags;
172
+        }
173
+
174
+        /**
175
+         * Compare two tags as if they were version number.
176
+         *
177
+         * @param stdClass $tag1 Tag object.
178
+         * @param stdClass $tag2 Another tag object.
179
+         * @return int
180
+         */
181
+        protected function compareTagNames($tag1, $tag2) {
182
+            $property = $this->tagNameProperty;
183
+            if ( !isset($tag1->$property) ) {
184
+                return 1;
185
+            }
186
+            if ( !isset($tag2->$property) ) {
187
+                return -1;
188
+            }
189
+            return -version_compare(ltrim($tag1->$property, 'v'), ltrim($tag2->$property, 'v'));
190
+        }
191
+
192
+        /**
193
+         * Get the contents of a file from a specific branch or tag.
194
+         *
195
+         * @param string $path File name.
196
+         * @param string $ref
197
+         * @return null|string Either the contents of the file, or null if the file doesn't exist or there's an error.
198
+         */
199
+        abstract public function getRemoteFile($path, $ref = 'master');
200
+
201
+        /**
202
+         * Get the timestamp of the latest commit that changed the specified branch or tag.
203
+         *
204
+         * @param string $ref Reference name (e.g. branch or tag).
205
+         * @return string|null
206
+         */
207
+        abstract public function getLatestCommitTime($ref);
208
+
209
+        /**
210
+         * Get the contents of the changelog file from the repository.
211
+         *
212
+         * @param string $ref
213
+         * @param string $localDirectory Full path to the local plugin or theme directory.
214
+         * @return null|string The HTML contents of the changelog.
215
+         */
216
+        public function getRemoteChangelog($ref, $localDirectory) {
217
+            $filename = $this->findChangelogName($localDirectory);
218
+            if ( empty($filename) ) {
219
+                return null;
220
+            }
221
+
222
+            $changelog = $this->getRemoteFile($filename, $ref);
223
+            if ( $changelog === null ) {
224
+                return null;
225
+            }
226
+
227
+            /** @noinspection PhpUndefinedClassInspection */
228
+            return Parsedown::instance()->text($changelog);
229
+        }
230
+
231
+        /**
232
+         * Guess the name of the changelog file.
233
+         *
234
+         * @param string $directory
235
+         * @return string|null
236
+         */
237
+        protected function findChangelogName($directory = null) {
238
+            if ( !isset($directory) ) {
239
+                $directory = $this->localDirectory;
240
+            }
241
+            if ( empty($directory) || !is_dir($directory) || ($directory === '.') ) {
242
+                return null;
243
+            }
244
+
245
+            $possibleNames = array('CHANGES.md', 'CHANGELOG.md', 'changes.md', 'changelog.md');
246
+            $files = scandir($directory);
247
+            $foundNames = array_intersect($possibleNames, $files);
248
+
249
+            if ( !empty($foundNames) ) {
250
+                return reset($foundNames);
251
+            }
252
+            return null;
253
+        }
254
+
255
+        /**
256
+         * Set authentication credentials.
257
+         *
258
+         * @param $credentials
259
+         */
260
+        public function setAuthentication($credentials) {
261
+            $this->credentials = $credentials;
262
+        }
263
+
264
+        public function isAuthenticationEnabled() {
265
+            return !empty($this->credentials);
266
+        }
267
+
268
+        /**
269
+         * @param string $url
270
+         * @return string
271
+         */
272
+        public function signDownloadUrl($url) {
273
+            return $url;
274
+        }
275
+
276
+        /**
277
+         * @param string $filterName
278
+         */
279
+        public function setHttpFilterName($filterName) {
280
+            $this->httpFilterName = $filterName;
281
+        }
282
+
283
+        /**
284
+         * @param string $directory
285
+         */
286
+        public function setLocalDirectory($directory) {
287
+            if ( empty($directory) || !is_dir($directory) || ($directory === '.') ) {
288
+                $this->localDirectory = null;
289
+            } else {
290
+                $this->localDirectory = $directory;
291
+            }
292
+        }
293
+
294
+        /**
295
+         * @param string $slug
296
+         */
297
+        public function setSlug($slug) {
298
+            $this->slug = $slug;
299
+        }
300
+    }
301 301
 
302 302
 endif;
Please login to merge, or discard this patch.
classes/external/php/plugin-update-checker/Puc/v4p4/Vcs/BitBucketApi.php 1 patch
Indentation   +251 added lines, -251 removed lines patch added patch discarded remove patch
@@ -1,256 +1,256 @@
 block discarded – undo
1 1
 <?php
2 2
 if ( !class_exists('Puc_v4p4_Vcs_BitBucketApi', false) ):
3 3
 
4
-	class Puc_v4p4_Vcs_BitBucketApi extends Puc_v4p4_Vcs_Api {
5
-		/**
6
-		 * @var Puc_v4p4_OAuthSignature
7
-		 */
8
-		private $oauth = null;
9
-
10
-		/**
11
-		 * @var string
12
-		 */
13
-		private $username;
14
-
15
-		/**
16
-		 * @var string
17
-		 */
18
-		private $repository;
19
-
20
-		public function __construct($repositoryUrl, $credentials = array()) {
21
-			$path = @parse_url($repositoryUrl, PHP_URL_PATH);
22
-			if ( preg_match('@^/?(?P<username>[^/]+?)/(?P<repository>[^/#?&]+?)/?$@', $path, $matches) ) {
23
-				$this->username = $matches['username'];
24
-				$this->repository = $matches['repository'];
25
-			} else {
26
-				throw new InvalidArgumentException('Invalid BitBucket repository URL: "' . $repositoryUrl . '"');
27
-			}
28
-
29
-			parent::__construct($repositoryUrl, $credentials);
30
-		}
31
-
32
-		/**
33
-		 * Figure out which reference (i.e tag or branch) contains the latest version.
34
-		 *
35
-		 * @param string $configBranch Start looking in this branch.
36
-		 * @return null|Puc_v4p4_Vcs_Reference
37
-		 */
38
-		public function chooseReference($configBranch) {
39
-			$updateSource = null;
40
-
41
-			//Check if there's a "Stable tag: 1.2.3" header that points to a valid tag.
42
-			$updateSource = $this->getStableTag($configBranch);
43
-
44
-			//Look for version-like tags.
45
-			if ( !$updateSource && ($configBranch === 'master') ) {
46
-				$updateSource = $this->getLatestTag();
47
-			}
48
-			//If all else fails, use the specified branch itself.
49
-			if ( !$updateSource ) {
50
-				$updateSource = $this->getBranch($configBranch);
51
-			}
52
-
53
-			return $updateSource;
54
-		}
55
-
56
-		public function getBranch($branchName) {
57
-			$branch = $this->api('/refs/branches/' . $branchName);
58
-			if ( is_wp_error($branch) || empty($branch) ) {
59
-				return null;
60
-			}
61
-
62
-			return new Puc_v4p4_Vcs_Reference(array(
63
-				'name' => $branch->name,
64
-				'updated' => $branch->target->date,
65
-				'downloadUrl' => $this->getDownloadUrl($branch->name),
66
-			));
67
-		}
68
-
69
-		/**
70
-		 * Get a specific tag.
71
-		 *
72
-		 * @param string $tagName
73
-		 * @return Puc_v4p4_Vcs_Reference|null
74
-		 */
75
-		public function getTag($tagName) {
76
-			$tag = $this->api('/refs/tags/' . $tagName);
77
-			if ( is_wp_error($tag) || empty($tag) ) {
78
-				return null;
79
-			}
80
-
81
-			return new Puc_v4p4_Vcs_Reference(array(
82
-				'name' => $tag->name,
83
-				'version' => ltrim($tag->name, 'v'),
84
-				'updated' => $tag->target->date,
85
-				'downloadUrl' => $this->getDownloadUrl($tag->name),
86
-			));
87
-		}
88
-
89
-		/**
90
-		 * Get the tag that looks like the highest version number.
91
-		 *
92
-		 * @return Puc_v4p4_Vcs_Reference|null
93
-		 */
94
-		public function getLatestTag() {
95
-			$tags = $this->api('/refs/tags?sort=-target.date');
96
-			if ( !isset($tags, $tags->values) || !is_array($tags->values) ) {
97
-				return null;
98
-			}
99
-
100
-			//Filter and sort the list of tags.
101
-			$versionTags = $this->sortTagsByVersion($tags->values);
102
-
103
-			//Return the first result.
104
-			if ( !empty($versionTags) ) {
105
-				$tag = $versionTags[0];
106
-				return new Puc_v4p4_Vcs_Reference(array(
107
-					'name' => $tag->name,
108
-					'version' => ltrim($tag->name, 'v'),
109
-					'updated' => $tag->target->date,
110
-					'downloadUrl' => $this->getDownloadUrl($tag->name),
111
-				));
112
-			}
113
-			return null;
114
-		}
115
-
116
-		/**
117
-		 * Get the tag/ref specified by the "Stable tag" header in the readme.txt of a given branch.
118
-		 *
119
-		 * @param string $branch
120
-		 * @return null|Puc_v4p4_Vcs_Reference
121
-		 */
122
-		protected function getStableTag($branch) {
123
-			$remoteReadme = $this->getRemoteReadme($branch);
124
-			if ( !empty($remoteReadme['stable_tag']) ) {
125
-				$tag = $remoteReadme['stable_tag'];
126
-
127
-				//You can explicitly opt out of using tags by setting "Stable tag" to
128
-				//"trunk" or the name of the current branch.
129
-				if ( ($tag === $branch) || ($tag === 'trunk') ) {
130
-					return $this->getBranch($branch);
131
-				}
132
-
133
-				return $this->getTag($tag);
134
-			}
135
-
136
-			return null;
137
-		}
138
-
139
-		/**
140
-		 * @param string $ref
141
-		 * @return string
142
-		 */
143
-		protected function getDownloadUrl($ref) {
144
-			return sprintf(
145
-				'https://bitbucket.org/%s/%s/get/%s.zip',
146
-				$this->username,
147
-				$this->repository,
148
-				$ref
149
-			);
150
-		}
151
-
152
-		/**
153
-		 * Get the contents of a file from a specific branch or tag.
154
-		 *
155
-		 * @param string $path File name.
156
-		 * @param string $ref
157
-		 * @return null|string Either the contents of the file, or null if the file doesn't exist or there's an error.
158
-		 */
159
-		public function getRemoteFile($path, $ref = 'master') {
160
-			$response = $this->api('src/' . $ref . '/' . ltrim($path), '1.0');
161
-			if ( is_wp_error($response) || !isset($response, $response->data) ) {
162
-				return null;
163
-			}
164
-			return $response->data;
165
-		}
166
-
167
-		/**
168
-		 * Get the timestamp of the latest commit that changed the specified branch or tag.
169
-		 *
170
-		 * @param string $ref Reference name (e.g. branch or tag).
171
-		 * @return string|null
172
-		 */
173
-		public function getLatestCommitTime($ref) {
174
-			$response = $this->api('commits/' . $ref);
175
-			if ( isset($response->values, $response->values[0], $response->values[0]->date) ) {
176
-				return $response->values[0]->date;
177
-			}
178
-			return null;
179
-		}
180
-
181
-		/**
182
-		 * Perform a BitBucket API 2.0 request.
183
-		 *
184
-		 * @param string $url
185
-		 * @param string $version
186
-		 * @return mixed|WP_Error
187
-		 */
188
-		public function api($url, $version = '2.0') {
189
-			$url = implode('/', array(
190
-				'https://api.bitbucket.org',
191
-				$version,
192
-				'repositories',
193
-				$this->username,
194
-				$this->repository,
195
-				ltrim($url, '/')
196
-			));
197
-			$baseUrl = $url;
198
-
199
-			if ( $this->oauth ) {
200
-				$url = $this->oauth->sign($url,'GET');
201
-			}
202
-
203
-			$options = array('timeout' => 10);
204
-			if ( !empty($this->httpFilterName) ) {
205
-				$options = apply_filters($this->httpFilterName, $options);
206
-			}
207
-			$response = wp_remote_get($url, $options);
208
-			if ( is_wp_error($response) ) {
209
-				do_action('puc_api_error', $response, null, $url, $this->slug);
210
-				return $response;
211
-			}
212
-
213
-			$code = wp_remote_retrieve_response_code($response);
214
-			$body = wp_remote_retrieve_body($response);
215
-			if ( $code === 200 ) {
216
-				$document = json_decode($body);
217
-				return $document;
218
-			}
219
-
220
-			$error = new WP_Error(
221
-				'puc-bitbucket-http-error',
222
-				sprintf('BitBucket API error. Base URL: "%s",  HTTP status code: %d.', $baseUrl, $code)
223
-			);
224
-			do_action('puc_api_error', $error, $response, $url, $this->slug);
225
-
226
-			return $error;
227
-		}
228
-
229
-		/**
230
-		 * @param array $credentials
231
-		 */
232
-		public function setAuthentication($credentials) {
233
-			parent::setAuthentication($credentials);
234
-
235
-			if ( !empty($credentials) && !empty($credentials['consumer_key']) ) {
236
-				$this->oauth = new Puc_v4p4_OAuthSignature(
237
-					$credentials['consumer_key'],
238
-					$credentials['consumer_secret']
239
-				);
240
-			} else {
241
-				$this->oauth = null;
242
-			}
243
-		}
244
-
245
-		public function signDownloadUrl($url) {
246
-			//Add authentication data to download URLs. Since OAuth signatures incorporate
247
-			//timestamps, we have to do this immediately before inserting the update. Otherwise
248
-			//authentication could fail due to a stale timestamp.
249
-			if ( $this->oauth ) {
250
-				$url = $this->oauth->sign($url);
251
-			}
252
-			return $url;
253
-		}
254
-	}
4
+    class Puc_v4p4_Vcs_BitBucketApi extends Puc_v4p4_Vcs_Api {
5
+        /**
6
+         * @var Puc_v4p4_OAuthSignature
7
+         */
8
+        private $oauth = null;
9
+
10
+        /**
11
+         * @var string
12
+         */
13
+        private $username;
14
+
15
+        /**
16
+         * @var string
17
+         */
18
+        private $repository;
19
+
20
+        public function __construct($repositoryUrl, $credentials = array()) {
21
+            $path = @parse_url($repositoryUrl, PHP_URL_PATH);
22
+            if ( preg_match('@^/?(?P<username>[^/]+?)/(?P<repository>[^/#?&]+?)/?$@', $path, $matches) ) {
23
+                $this->username = $matches['username'];
24
+                $this->repository = $matches['repository'];
25
+            } else {
26
+                throw new InvalidArgumentException('Invalid BitBucket repository URL: "' . $repositoryUrl . '"');
27
+            }
28
+
29
+            parent::__construct($repositoryUrl, $credentials);
30
+        }
31
+
32
+        /**
33
+         * Figure out which reference (i.e tag or branch) contains the latest version.
34
+         *
35
+         * @param string $configBranch Start looking in this branch.
36
+         * @return null|Puc_v4p4_Vcs_Reference
37
+         */
38
+        public function chooseReference($configBranch) {
39
+            $updateSource = null;
40
+
41
+            //Check if there's a "Stable tag: 1.2.3" header that points to a valid tag.
42
+            $updateSource = $this->getStableTag($configBranch);
43
+
44
+            //Look for version-like tags.
45
+            if ( !$updateSource && ($configBranch === 'master') ) {
46
+                $updateSource = $this->getLatestTag();
47
+            }
48
+            //If all else fails, use the specified branch itself.
49
+            if ( !$updateSource ) {
50
+                $updateSource = $this->getBranch($configBranch);
51
+            }
52
+
53
+            return $updateSource;
54
+        }
55
+
56
+        public function getBranch($branchName) {
57
+            $branch = $this->api('/refs/branches/' . $branchName);
58
+            if ( is_wp_error($branch) || empty($branch) ) {
59
+                return null;
60
+            }
61
+
62
+            return new Puc_v4p4_Vcs_Reference(array(
63
+                'name' => $branch->name,
64
+                'updated' => $branch->target->date,
65
+                'downloadUrl' => $this->getDownloadUrl($branch->name),
66
+            ));
67
+        }
68
+
69
+        /**
70
+         * Get a specific tag.
71
+         *
72
+         * @param string $tagName
73
+         * @return Puc_v4p4_Vcs_Reference|null
74
+         */
75
+        public function getTag($tagName) {
76
+            $tag = $this->api('/refs/tags/' . $tagName);
77
+            if ( is_wp_error($tag) || empty($tag) ) {
78
+                return null;
79
+            }
80
+
81
+            return new Puc_v4p4_Vcs_Reference(array(
82
+                'name' => $tag->name,
83
+                'version' => ltrim($tag->name, 'v'),
84
+                'updated' => $tag->target->date,
85
+                'downloadUrl' => $this->getDownloadUrl($tag->name),
86
+            ));
87
+        }
88
+
89
+        /**
90
+         * Get the tag that looks like the highest version number.
91
+         *
92
+         * @return Puc_v4p4_Vcs_Reference|null
93
+         */
94
+        public function getLatestTag() {
95
+            $tags = $this->api('/refs/tags?sort=-target.date');
96
+            if ( !isset($tags, $tags->values) || !is_array($tags->values) ) {
97
+                return null;
98
+            }
99
+
100
+            //Filter and sort the list of tags.
101
+            $versionTags = $this->sortTagsByVersion($tags->values);
102
+
103
+            //Return the first result.
104
+            if ( !empty($versionTags) ) {
105
+                $tag = $versionTags[0];
106
+                return new Puc_v4p4_Vcs_Reference(array(
107
+                    'name' => $tag->name,
108
+                    'version' => ltrim($tag->name, 'v'),
109
+                    'updated' => $tag->target->date,
110
+                    'downloadUrl' => $this->getDownloadUrl($tag->name),
111
+                ));
112
+            }
113
+            return null;
114
+        }
115
+
116
+        /**
117
+         * Get the tag/ref specified by the "Stable tag" header in the readme.txt of a given branch.
118
+         *
119
+         * @param string $branch
120
+         * @return null|Puc_v4p4_Vcs_Reference
121
+         */
122
+        protected function getStableTag($branch) {
123
+            $remoteReadme = $this->getRemoteReadme($branch);
124
+            if ( !empty($remoteReadme['stable_tag']) ) {
125
+                $tag = $remoteReadme['stable_tag'];
126
+
127
+                //You can explicitly opt out of using tags by setting "Stable tag" to
128
+                //"trunk" or the name of the current branch.
129
+                if ( ($tag === $branch) || ($tag === 'trunk') ) {
130
+                    return $this->getBranch($branch);
131
+                }
132
+
133
+                return $this->getTag($tag);
134
+            }
135
+
136
+            return null;
137
+        }
138
+
139
+        /**
140
+         * @param string $ref
141
+         * @return string
142
+         */
143
+        protected function getDownloadUrl($ref) {
144
+            return sprintf(
145
+                'https://bitbucket.org/%s/%s/get/%s.zip',
146
+                $this->username,
147
+                $this->repository,
148
+                $ref
149
+            );
150
+        }
151
+
152
+        /**
153
+         * Get the contents of a file from a specific branch or tag.
154
+         *
155
+         * @param string $path File name.
156
+         * @param string $ref
157
+         * @return null|string Either the contents of the file, or null if the file doesn't exist or there's an error.
158
+         */
159
+        public function getRemoteFile($path, $ref = 'master') {
160
+            $response = $this->api('src/' . $ref . '/' . ltrim($path), '1.0');
161
+            if ( is_wp_error($response) || !isset($response, $response->data) ) {
162
+                return null;
163
+            }
164
+            return $response->data;
165
+        }
166
+
167
+        /**
168
+         * Get the timestamp of the latest commit that changed the specified branch or tag.
169
+         *
170
+         * @param string $ref Reference name (e.g. branch or tag).
171
+         * @return string|null
172
+         */
173
+        public function getLatestCommitTime($ref) {
174
+            $response = $this->api('commits/' . $ref);
175
+            if ( isset($response->values, $response->values[0], $response->values[0]->date) ) {
176
+                return $response->values[0]->date;
177
+            }
178
+            return null;
179
+        }
180
+
181
+        /**
182
+         * Perform a BitBucket API 2.0 request.
183
+         *
184
+         * @param string $url
185
+         * @param string $version
186
+         * @return mixed|WP_Error
187
+         */
188
+        public function api($url, $version = '2.0') {
189
+            $url = implode('/', array(
190
+                'https://api.bitbucket.org',
191
+                $version,
192
+                'repositories',
193
+                $this->username,
194
+                $this->repository,
195
+                ltrim($url, '/')
196
+            ));
197
+            $baseUrl = $url;
198
+
199
+            if ( $this->oauth ) {
200
+                $url = $this->oauth->sign($url,'GET');
201
+            }
202
+
203
+            $options = array('timeout' => 10);
204
+            if ( !empty($this->httpFilterName) ) {
205
+                $options = apply_filters($this->httpFilterName, $options);
206
+            }
207
+            $response = wp_remote_get($url, $options);
208
+            if ( is_wp_error($response) ) {
209
+                do_action('puc_api_error', $response, null, $url, $this->slug);
210
+                return $response;
211
+            }
212
+
213
+            $code = wp_remote_retrieve_response_code($response);
214
+            $body = wp_remote_retrieve_body($response);
215
+            if ( $code === 200 ) {
216
+                $document = json_decode($body);
217
+                return $document;
218
+            }
219
+
220
+            $error = new WP_Error(
221
+                'puc-bitbucket-http-error',
222
+                sprintf('BitBucket API error. Base URL: "%s",  HTTP status code: %d.', $baseUrl, $code)
223
+            );
224
+            do_action('puc_api_error', $error, $response, $url, $this->slug);
225
+
226
+            return $error;
227
+        }
228
+
229
+        /**
230
+         * @param array $credentials
231
+         */
232
+        public function setAuthentication($credentials) {
233
+            parent::setAuthentication($credentials);
234
+
235
+            if ( !empty($credentials) && !empty($credentials['consumer_key']) ) {
236
+                $this->oauth = new Puc_v4p4_OAuthSignature(
237
+                    $credentials['consumer_key'],
238
+                    $credentials['consumer_secret']
239
+                );
240
+            } else {
241
+                $this->oauth = null;
242
+            }
243
+        }
244
+
245
+        public function signDownloadUrl($url) {
246
+            //Add authentication data to download URLs. Since OAuth signatures incorporate
247
+            //timestamps, we have to do this immediately before inserting the update. Otherwise
248
+            //authentication could fail due to a stale timestamp.
249
+            if ( $this->oauth ) {
250
+                $url = $this->oauth->sign($url);
251
+            }
252
+            return $url;
253
+        }
254
+    }
255 255
 
256 256
 endif;
Please login to merge, or discard this patch.
classes/external/php/plugin-update-checker/Puc/v4p4/Vcs/GitHubApi.php 1 patch
Indentation   +407 added lines, -407 removed lines patch added patch discarded remove patch
@@ -2,412 +2,412 @@
 block discarded – undo
2 2
 
3 3
 if ( !class_exists('Puc_v4p4_Vcs_GitHubApi', false) ):
4 4
 
5
-	class Puc_v4p4_Vcs_GitHubApi extends Puc_v4p4_Vcs_Api {
6
-		/**
7
-		 * @var string GitHub username.
8
-		 */
9
-		protected $userName;
10
-		/**
11
-		 * @var string GitHub repository name.
12
-		 */
13
-		protected $repositoryName;
14
-
15
-		/**
16
-		 * @var string Either a fully qualified repository URL, or just "user/repo-name".
17
-		 */
18
-		protected $repositoryUrl;
19
-
20
-		/**
21
-		 * @var string GitHub authentication token. Optional.
22
-		 */
23
-		protected $accessToken;
24
-
25
-		/**
26
-		 * @var bool Whether to download release assets instead of the auto-generated source code archives.
27
-		 */
28
-		protected $releaseAssetsEnabled = false;
29
-
30
-		/**
31
-		 * @var string|null Regular expression that's used to filter release assets by name. Optional.
32
-		 */
33
-		protected $assetFilterRegex = null;
34
-
35
-		/**
36
-		 * @var string|null The unchanging part of a release asset URL. Used to identify download attempts.
37
-		 */
38
-		protected $assetApiBaseUrl = null;
39
-
40
-		public function __construct($repositoryUrl, $accessToken = null) {
41
-			$path = @parse_url($repositoryUrl, PHP_URL_PATH);
42
-			if ( preg_match('@^/?(?P<username>[^/]+?)/(?P<repository>[^/#?&]+?)/?$@', $path, $matches) ) {
43
-				$this->userName = $matches['username'];
44
-				$this->repositoryName = $matches['repository'];
45
-			} else {
46
-				throw new InvalidArgumentException('Invalid GitHub repository URL: "' . $repositoryUrl . '"');
47
-			}
48
-
49
-			parent::__construct($repositoryUrl, $accessToken);
50
-		}
51
-
52
-		/**
53
-		 * Get the latest release from GitHub.
54
-		 *
55
-		 * @return Puc_v4p4_Vcs_Reference|null
56
-		 */
57
-		public function getLatestRelease() {
58
-			$release = $this->api('/repos/:user/:repo/releases/latest');
59
-			if ( is_wp_error($release) || !is_object($release) || !isset($release->tag_name) ) {
60
-				return null;
61
-			}
62
-
63
-			$reference = new Puc_v4p4_Vcs_Reference(array(
64
-				'name'        => $release->tag_name,
65
-				'version'     => ltrim($release->tag_name, 'v'), //Remove the "v" prefix from "v1.2.3".
66
-				'downloadUrl' => $this->signDownloadUrl($release->zipball_url),
67
-				'updated'     => $release->created_at,
68
-				'apiResponse' => $release,
69
-			));
70
-
71
-			if ( isset($release->assets[0]) ) {
72
-				$reference->downloadCount = $release->assets[0]->download_count;
73
-			}
74
-
75
-			if ( $this->releaseAssetsEnabled && isset($release->assets, $release->assets[0]) ) {
76
-				//Use the first release asset that matches the specified regular expression.
77
-				$matchingAssets = array_filter($release->assets, array($this, 'matchesAssetFilter'));
78
-				if ( !empty($matchingAssets) ) {
79
-					if ( $this->isAuthenticationEnabled() ) {
80
-						/**
81
-						 * Keep in mind that we'll need to add an "Accept" header to download this asset.
82
-						 * @see setReleaseDownloadHeader()
83
-						 */
84
-						$reference->downloadUrl = $this->signDownloadUrl($matchingAssets[0]->url);
85
-					} else {
86
-						//It seems that browser_download_url only works for public repositories.
87
-						//Using an access_token doesn't help. Maybe OAuth would work?
88
-						$reference->downloadUrl = $matchingAssets[0]->browser_download_url;
89
-					}
90
-
91
-					$reference->downloadCount = $matchingAssets[0]->download_count;
92
-				}
93
-			}
94
-
95
-			if ( !empty($release->body) ) {
96
-				/** @noinspection PhpUndefinedClassInspection */
97
-				$reference->changelog = Parsedown::instance()->text($release->body);
98
-			}
99
-
100
-			return $reference;
101
-		}
102
-
103
-		/**
104
-		 * Get the tag that looks like the highest version number.
105
-		 *
106
-		 * @return Puc_v4p4_Vcs_Reference|null
107
-		 */
108
-		public function getLatestTag() {
109
-			$tags = $this->api('/repos/:user/:repo/tags');
110
-
111
-			if ( is_wp_error($tags) || empty($tags) || !is_array($tags) ) {
112
-				return null;
113
-			}
114
-
115
-			$versionTags = $this->sortTagsByVersion($tags);
116
-			if ( empty($versionTags) ) {
117
-				return null;
118
-			}
119
-
120
-			$tag = $versionTags[0];
121
-			return new Puc_v4p4_Vcs_Reference(array(
122
-				'name'        => $tag->name,
123
-				'version'     => ltrim($tag->name, 'v'),
124
-				'downloadUrl' => $this->signDownloadUrl($tag->zipball_url),
125
-				'apiResponse' => $tag,
126
-			));
127
-		}
128
-
129
-		/**
130
-		 * Get a branch by name.
131
-		 *
132
-		 * @param string $branchName
133
-		 * @return null|Puc_v4p4_Vcs_Reference
134
-		 */
135
-		public function getBranch($branchName) {
136
-			$branch = $this->api('/repos/:user/:repo/branches/' . $branchName);
137
-			if ( is_wp_error($branch) || empty($branch) ) {
138
-				return null;
139
-			}
140
-
141
-			$reference = new Puc_v4p4_Vcs_Reference(array(
142
-				'name'        => $branch->name,
143
-				'downloadUrl' => $this->buildArchiveDownloadUrl($branch->name),
144
-				'apiResponse' => $branch,
145
-			));
146
-
147
-			if ( isset($branch->commit, $branch->commit->commit, $branch->commit->commit->author->date) ) {
148
-				$reference->updated = $branch->commit->commit->author->date;
149
-			}
150
-
151
-			return $reference;
152
-		}
153
-
154
-		/**
155
-		 * Get the latest commit that changed the specified file.
156
-		 *
157
-		 * @param string $filename
158
-		 * @param string $ref Reference name (e.g. branch or tag).
159
-		 * @return StdClass|null
160
-		 */
161
-		public function getLatestCommit($filename, $ref = 'master') {
162
-			$commits = $this->api(
163
-				'/repos/:user/:repo/commits',
164
-				array(
165
-					'path' => $filename,
166
-					'sha'  => $ref,
167
-				)
168
-			);
169
-			if ( !is_wp_error($commits) && is_array($commits) && isset($commits[0]) ) {
170
-				return $commits[0];
171
-			}
172
-			return null;
173
-		}
174
-
175
-		/**
176
-		 * Get the timestamp of the latest commit that changed the specified branch or tag.
177
-		 *
178
-		 * @param string $ref Reference name (e.g. branch or tag).
179
-		 * @return string|null
180
-		 */
181
-		public function getLatestCommitTime($ref) {
182
-			$commits = $this->api('/repos/:user/:repo/commits', array('sha' => $ref));
183
-			if ( !is_wp_error($commits) && is_array($commits) && isset($commits[0]) ) {
184
-				return $commits[0]->commit->author->date;
185
-			}
186
-			return null;
187
-		}
188
-
189
-		/**
190
-		 * Perform a GitHub API request.
191
-		 *
192
-		 * @param string $url
193
-		 * @param array $queryParams
194
-		 * @return mixed|WP_Error
195
-		 */
196
-		protected function api($url, $queryParams = array()) {
197
-			$baseUrl = $url;
198
-			$url = $this->buildApiUrl($url, $queryParams);
199
-
200
-			$options = array('timeout' => 10);
201
-			if ( !empty($this->httpFilterName) ) {
202
-				$options = apply_filters($this->httpFilterName, $options);
203
-			}
204
-			$response = wp_remote_get($url, $options);
205
-			if ( is_wp_error($response) ) {
206
-				do_action('puc_api_error', $response, null, $url, $this->slug);
207
-				return $response;
208
-			}
209
-
210
-			$code = wp_remote_retrieve_response_code($response);
211
-			$body = wp_remote_retrieve_body($response);
212
-			if ( $code === 200 ) {
213
-				$document = json_decode($body);
214
-				return $document;
215
-			}
216
-
217
-			$error = new WP_Error(
218
-				'puc-github-http-error',
219
-				sprintf('GitHub API error. Base URL: "%s",  HTTP status code: %d.', $baseUrl, $code)
220
-			);
221
-			do_action('puc_api_error', $error, $response, $url, $this->slug);
222
-
223
-			return $error;
224
-		}
225
-
226
-		/**
227
-		 * Build a fully qualified URL for an API request.
228
-		 *
229
-		 * @param string $url
230
-		 * @param array $queryParams
231
-		 * @return string
232
-		 */
233
-		protected function buildApiUrl($url, $queryParams) {
234
-			$variables = array(
235
-				'user' => $this->userName,
236
-				'repo' => $this->repositoryName,
237
-			);
238
-			foreach ($variables as $name => $value) {
239
-				$url = str_replace('/:' . $name, '/' . urlencode($value), $url);
240
-			}
241
-			$url = 'https://api.github.com' . $url;
242
-
243
-			if ( !empty($this->accessToken) ) {
244
-				$queryParams['access_token'] = $this->accessToken;
245
-			}
246
-			if ( !empty($queryParams) ) {
247
-				$url = add_query_arg($queryParams, $url);
248
-			}
249
-
250
-			return $url;
251
-		}
252
-
253
-		/**
254
-		 * Get the contents of a file from a specific branch or tag.
255
-		 *
256
-		 * @param string $path File name.
257
-		 * @param string $ref
258
-		 * @return null|string Either the contents of the file, or null if the file doesn't exist or there's an error.
259
-		 */
260
-		public function getRemoteFile($path, $ref = 'master') {
261
-			$apiUrl = '/repos/:user/:repo/contents/' . $path;
262
-			$response = $this->api($apiUrl, array('ref' => $ref));
263
-
264
-			if ( is_wp_error($response) || !isset($response->content) || ($response->encoding !== 'base64') ) {
265
-				return null;
266
-			}
267
-			return base64_decode($response->content);
268
-		}
269
-
270
-		/**
271
-		 * Generate a URL to download a ZIP archive of the specified branch/tag/etc.
272
-		 *
273
-		 * @param string $ref
274
-		 * @return string
275
-		 */
276
-		public function buildArchiveDownloadUrl($ref = 'master') {
277
-			$url = sprintf(
278
-				'https://api.github.com/repos/%1$s/%2$s/zipball/%3$s',
279
-				urlencode($this->userName),
280
-				urlencode($this->repositoryName),
281
-				urlencode($ref)
282
-			);
283
-			if ( !empty($this->accessToken) ) {
284
-				$url = $this->signDownloadUrl($url);
285
-			}
286
-			return $url;
287
-		}
288
-
289
-		/**
290
-		 * Get a specific tag.
291
-		 *
292
-		 * @param string $tagName
293
-		 * @return Puc_v4p4_Vcs_Reference|null
294
-		 */
295
-		public function getTag($tagName) {
296
-			//The current GitHub update checker doesn't use getTag, so I didn't bother to implement it.
297
-			throw new LogicException('The ' . __METHOD__ . ' method is not implemented and should not be used.');
298
-		}
299
-
300
-		public function setAuthentication($credentials) {
301
-			parent::setAuthentication($credentials);
302
-			$this->accessToken = is_string($credentials) ? $credentials : null;
303
-		}
304
-
305
-		/**
306
-		 * Figure out which reference (i.e tag or branch) contains the latest version.
307
-		 *
308
-		 * @param string $configBranch Start looking in this branch.
309
-		 * @return null|Puc_v4p4_Vcs_Reference
310
-		 */
311
-		public function chooseReference($configBranch) {
312
-			$updateSource = null;
313
-
314
-			if ( $configBranch === 'master' ) {
315
-				//Use the latest release.
316
-				$updateSource = $this->getLatestRelease();
317
-				if ( $updateSource === null ) {
318
-					//Failing that, use the tag with the highest version number.
319
-					$updateSource = $this->getLatestTag();
320
-				}
321
-			}
322
-			//Alternatively, just use the branch itself.
323
-			if ( empty($updateSource) ) {
324
-				$updateSource = $this->getBranch($configBranch);
325
-			}
326
-
327
-			return $updateSource;
328
-		}
329
-
330
-		/**
331
-		 * @param string $url
332
-		 * @return string
333
-		 */
334
-		public function signDownloadUrl($url) {
335
-			if ( empty($this->credentials) ) {
336
-				return $url;
337
-			}
338
-			return add_query_arg('access_token', $this->credentials, $url);
339
-		}
340
-
341
-		/**
342
-		 * Enable updating via release assets.
343
-		 *
344
-		 * If the latest release contains no usable assets, the update checker
345
-		 * will fall back to using the automatically generated ZIP archive.
346
-		 *
347
-		 * Private repositories will only work with WordPress 3.7 or later.
348
-		 *
349
-		 * @param string|null $fileNameRegex Optional. Use only those assets where the file name matches this regex.
350
-		 */
351
-		public function enableReleaseAssets($fileNameRegex = null) {
352
-			$this->releaseAssetsEnabled = true;
353
-			$this->assetFilterRegex = $fileNameRegex;
354
-			$this->assetApiBaseUrl = sprintf(
355
-				'//api.github.com/repos/%1$s/%2$s/releases/assets/',
356
-				$this->userName,
357
-				$this->repositoryName
358
-			);
359
-
360
-			//Optimization: Instead of filtering all HTTP requests, let's do it only when
361
-			//WordPress is about to download an update.
362
-			add_filter('upgrader_pre_download', array($this, 'addHttpRequestFilter'), 10, 1); //WP 3.7+
363
-		}
364
-
365
-		/**
366
-		 * Does this asset match the file name regex?
367
-		 *
368
-		 * @param stdClass $releaseAsset
369
-		 * @return bool
370
-		 */
371
-		protected function matchesAssetFilter($releaseAsset) {
372
-			if ( $this->assetFilterRegex === null ) {
373
-				//The default is to accept all assets.
374
-				return true;
375
-			}
376
-			return isset($releaseAsset->name) && preg_match($this->assetFilterRegex, $releaseAsset->name);
377
-		}
378
-
379
-		/**
380
-		 * @internal
381
-		 * @param bool $result
382
-		 * @return bool
383
-		 */
384
-		public function addHttpRequestFilter($result) {
385
-			static $filterAdded = false;
386
-			if ( $this->releaseAssetsEnabled && !$filterAdded && $this->isAuthenticationEnabled() ) {
387
-				add_filter('http_request_args', array($this, 'setReleaseDownloadHeader'), 10, 2);
388
-				$filterAdded = true;
389
-			}
390
-			return $result;
391
-		}
392
-
393
-		/**
394
-		 * Set the HTTP header that's necessary to download private release assets.
395
-		 *
396
-		 * See GitHub docs:
397
-		 * @link https://developer.github.com/v3/repos/releases/#get-a-single-release-asset
398
-		 *
399
-		 * @internal
400
-		 * @param array $requestArgs
401
-		 * @param string $url
402
-		 * @return array
403
-		 */
404
-		public function setReleaseDownloadHeader($requestArgs, $url = '') {
405
-			//Is WordPress trying to download one of our assets?
406
-			if ( strpos($url, $this->assetApiBaseUrl) !== false ) {
407
-				$requestArgs['headers']['accept'] = 'application/octet-stream';
408
-			}
409
-			return $requestArgs;
410
-		}
411
-	}
5
+    class Puc_v4p4_Vcs_GitHubApi extends Puc_v4p4_Vcs_Api {
6
+        /**
7
+         * @var string GitHub username.
8
+         */
9
+        protected $userName;
10
+        /**
11
+         * @var string GitHub repository name.
12
+         */
13
+        protected $repositoryName;
14
+
15
+        /**
16
+         * @var string Either a fully qualified repository URL, or just "user/repo-name".
17
+         */
18
+        protected $repositoryUrl;
19
+
20
+        /**
21
+         * @var string GitHub authentication token. Optional.
22
+         */
23
+        protected $accessToken;
24
+
25
+        /**
26
+         * @var bool Whether to download release assets instead of the auto-generated source code archives.
27
+         */
28
+        protected $releaseAssetsEnabled = false;
29
+
30
+        /**
31
+         * @var string|null Regular expression that's used to filter release assets by name. Optional.
32
+         */
33
+        protected $assetFilterRegex = null;
34
+
35
+        /**
36
+         * @var string|null The unchanging part of a release asset URL. Used to identify download attempts.
37
+         */
38
+        protected $assetApiBaseUrl = null;
39
+
40
+        public function __construct($repositoryUrl, $accessToken = null) {
41
+            $path = @parse_url($repositoryUrl, PHP_URL_PATH);
42
+            if ( preg_match('@^/?(?P<username>[^/]+?)/(?P<repository>[^/#?&]+?)/?$@', $path, $matches) ) {
43
+                $this->userName = $matches['username'];
44
+                $this->repositoryName = $matches['repository'];
45
+            } else {
46
+                throw new InvalidArgumentException('Invalid GitHub repository URL: "' . $repositoryUrl . '"');
47
+            }
48
+
49
+            parent::__construct($repositoryUrl, $accessToken);
50
+        }
51
+
52
+        /**
53
+         * Get the latest release from GitHub.
54
+         *
55
+         * @return Puc_v4p4_Vcs_Reference|null
56
+         */
57
+        public function getLatestRelease() {
58
+            $release = $this->api('/repos/:user/:repo/releases/latest');
59
+            if ( is_wp_error($release) || !is_object($release) || !isset($release->tag_name) ) {
60
+                return null;
61
+            }
62
+
63
+            $reference = new Puc_v4p4_Vcs_Reference(array(
64
+                'name'        => $release->tag_name,
65
+                'version'     => ltrim($release->tag_name, 'v'), //Remove the "v" prefix from "v1.2.3".
66
+                'downloadUrl' => $this->signDownloadUrl($release->zipball_url),
67
+                'updated'     => $release->created_at,
68
+                'apiResponse' => $release,
69
+            ));
70
+
71
+            if ( isset($release->assets[0]) ) {
72
+                $reference->downloadCount = $release->assets[0]->download_count;
73
+            }
74
+
75
+            if ( $this->releaseAssetsEnabled && isset($release->assets, $release->assets[0]) ) {
76
+                //Use the first release asset that matches the specified regular expression.
77
+                $matchingAssets = array_filter($release->assets, array($this, 'matchesAssetFilter'));
78
+                if ( !empty($matchingAssets) ) {
79
+                    if ( $this->isAuthenticationEnabled() ) {
80
+                        /**
81
+                         * Keep in mind that we'll need to add an "Accept" header to download this asset.
82
+                         * @see setReleaseDownloadHeader()
83
+                         */
84
+                        $reference->downloadUrl = $this->signDownloadUrl($matchingAssets[0]->url);
85
+                    } else {
86
+                        //It seems that browser_download_url only works for public repositories.
87
+                        //Using an access_token doesn't help. Maybe OAuth would work?
88
+                        $reference->downloadUrl = $matchingAssets[0]->browser_download_url;
89
+                    }
90
+
91
+                    $reference->downloadCount = $matchingAssets[0]->download_count;
92
+                }
93
+            }
94
+
95
+            if ( !empty($release->body) ) {
96
+                /** @noinspection PhpUndefinedClassInspection */
97
+                $reference->changelog = Parsedown::instance()->text($release->body);
98
+            }
99
+
100
+            return $reference;
101
+        }
102
+
103
+        /**
104
+         * Get the tag that looks like the highest version number.
105
+         *
106
+         * @return Puc_v4p4_Vcs_Reference|null
107
+         */
108
+        public function getLatestTag() {
109
+            $tags = $this->api('/repos/:user/:repo/tags');
110
+
111
+            if ( is_wp_error($tags) || empty($tags) || !is_array($tags) ) {
112
+                return null;
113
+            }
114
+
115
+            $versionTags = $this->sortTagsByVersion($tags);
116
+            if ( empty($versionTags) ) {
117
+                return null;
118
+            }
119
+
120
+            $tag = $versionTags[0];
121
+            return new Puc_v4p4_Vcs_Reference(array(
122
+                'name'        => $tag->name,
123
+                'version'     => ltrim($tag->name, 'v'),
124
+                'downloadUrl' => $this->signDownloadUrl($tag->zipball_url),
125
+                'apiResponse' => $tag,
126
+            ));
127
+        }
128
+
129
+        /**
130
+         * Get a branch by name.
131
+         *
132
+         * @param string $branchName
133
+         * @return null|Puc_v4p4_Vcs_Reference
134
+         */
135
+        public function getBranch($branchName) {
136
+            $branch = $this->api('/repos/:user/:repo/branches/' . $branchName);
137
+            if ( is_wp_error($branch) || empty($branch) ) {
138
+                return null;
139
+            }
140
+
141
+            $reference = new Puc_v4p4_Vcs_Reference(array(
142
+                'name'        => $branch->name,
143
+                'downloadUrl' => $this->buildArchiveDownloadUrl($branch->name),
144
+                'apiResponse' => $branch,
145
+            ));
146
+
147
+            if ( isset($branch->commit, $branch->commit->commit, $branch->commit->commit->author->date) ) {
148
+                $reference->updated = $branch->commit->commit->author->date;
149
+            }
150
+
151
+            return $reference;
152
+        }
153
+
154
+        /**
155
+         * Get the latest commit that changed the specified file.
156
+         *
157
+         * @param string $filename
158
+         * @param string $ref Reference name (e.g. branch or tag).
159
+         * @return StdClass|null
160
+         */
161
+        public function getLatestCommit($filename, $ref = 'master') {
162
+            $commits = $this->api(
163
+                '/repos/:user/:repo/commits',
164
+                array(
165
+                    'path' => $filename,
166
+                    'sha'  => $ref,
167
+                )
168
+            );
169
+            if ( !is_wp_error($commits) && is_array($commits) && isset($commits[0]) ) {
170
+                return $commits[0];
171
+            }
172
+            return null;
173
+        }
174
+
175
+        /**
176
+         * Get the timestamp of the latest commit that changed the specified branch or tag.
177
+         *
178
+         * @param string $ref Reference name (e.g. branch or tag).
179
+         * @return string|null
180
+         */
181
+        public function getLatestCommitTime($ref) {
182
+            $commits = $this->api('/repos/:user/:repo/commits', array('sha' => $ref));
183
+            if ( !is_wp_error($commits) && is_array($commits) && isset($commits[0]) ) {
184
+                return $commits[0]->commit->author->date;
185
+            }
186
+            return null;
187
+        }
188
+
189
+        /**
190
+         * Perform a GitHub API request.
191
+         *
192
+         * @param string $url
193
+         * @param array $queryParams
194
+         * @return mixed|WP_Error
195
+         */
196
+        protected function api($url, $queryParams = array()) {
197
+            $baseUrl = $url;
198
+            $url = $this->buildApiUrl($url, $queryParams);
199
+
200
+            $options = array('timeout' => 10);
201
+            if ( !empty($this->httpFilterName) ) {
202
+                $options = apply_filters($this->httpFilterName, $options);
203
+            }
204
+            $response = wp_remote_get($url, $options);
205
+            if ( is_wp_error($response) ) {
206
+                do_action('puc_api_error', $response, null, $url, $this->slug);
207
+                return $response;
208
+            }
209
+
210
+            $code = wp_remote_retrieve_response_code($response);
211
+            $body = wp_remote_retrieve_body($response);
212
+            if ( $code === 200 ) {
213
+                $document = json_decode($body);
214
+                return $document;
215
+            }
216
+
217
+            $error = new WP_Error(
218
+                'puc-github-http-error',
219
+                sprintf('GitHub API error. Base URL: "%s",  HTTP status code: %d.', $baseUrl, $code)
220
+            );
221
+            do_action('puc_api_error', $error, $response, $url, $this->slug);
222
+
223
+            return $error;
224
+        }
225
+
226
+        /**
227
+         * Build a fully qualified URL for an API request.
228
+         *
229
+         * @param string $url
230
+         * @param array $queryParams
231
+         * @return string
232
+         */
233
+        protected function buildApiUrl($url, $queryParams) {
234
+            $variables = array(
235
+                'user' => $this->userName,
236
+                'repo' => $this->repositoryName,
237
+            );
238
+            foreach ($variables as $name => $value) {
239
+                $url = str_replace('/:' . $name, '/' . urlencode($value), $url);
240
+            }
241
+            $url = 'https://api.github.com' . $url;
242
+
243
+            if ( !empty($this->accessToken) ) {
244
+                $queryParams['access_token'] = $this->accessToken;
245
+            }
246
+            if ( !empty($queryParams) ) {
247
+                $url = add_query_arg($queryParams, $url);
248
+            }
249
+
250
+            return $url;
251
+        }
252
+
253
+        /**
254
+         * Get the contents of a file from a specific branch or tag.
255
+         *
256
+         * @param string $path File name.
257
+         * @param string $ref
258
+         * @return null|string Either the contents of the file, or null if the file doesn't exist or there's an error.
259
+         */
260
+        public function getRemoteFile($path, $ref = 'master') {
261
+            $apiUrl = '/repos/:user/:repo/contents/' . $path;
262
+            $response = $this->api($apiUrl, array('ref' => $ref));
263
+
264
+            if ( is_wp_error($response) || !isset($response->content) || ($response->encoding !== 'base64') ) {
265
+                return null;
266
+            }
267
+            return base64_decode($response->content);
268
+        }
269
+
270
+        /**
271
+         * Generate a URL to download a ZIP archive of the specified branch/tag/etc.
272
+         *
273
+         * @param string $ref
274
+         * @return string
275
+         */
276
+        public function buildArchiveDownloadUrl($ref = 'master') {
277
+            $url = sprintf(
278
+                'https://api.github.com/repos/%1$s/%2$s/zipball/%3$s',
279
+                urlencode($this->userName),
280
+                urlencode($this->repositoryName),
281
+                urlencode($ref)
282
+            );
283
+            if ( !empty($this->accessToken) ) {
284
+                $url = $this->signDownloadUrl($url);
285
+            }
286
+            return $url;
287
+        }
288
+
289
+        /**
290
+         * Get a specific tag.
291
+         *
292
+         * @param string $tagName
293
+         * @return Puc_v4p4_Vcs_Reference|null
294
+         */
295
+        public function getTag($tagName) {
296
+            //The current GitHub update checker doesn't use getTag, so I didn't bother to implement it.
297
+            throw new LogicException('The ' . __METHOD__ . ' method is not implemented and should not be used.');
298
+        }
299
+
300
+        public function setAuthentication($credentials) {
301
+            parent::setAuthentication($credentials);
302
+            $this->accessToken = is_string($credentials) ? $credentials : null;
303
+        }
304
+
305
+        /**
306
+         * Figure out which reference (i.e tag or branch) contains the latest version.
307
+         *
308
+         * @param string $configBranch Start looking in this branch.
309
+         * @return null|Puc_v4p4_Vcs_Reference
310
+         */
311
+        public function chooseReference($configBranch) {
312
+            $updateSource = null;
313
+
314
+            if ( $configBranch === 'master' ) {
315
+                //Use the latest release.
316
+                $updateSource = $this->getLatestRelease();
317
+                if ( $updateSource === null ) {
318
+                    //Failing that, use the tag with the highest version number.
319
+                    $updateSource = $this->getLatestTag();
320
+                }
321
+            }
322
+            //Alternatively, just use the branch itself.
323
+            if ( empty($updateSource) ) {
324
+                $updateSource = $this->getBranch($configBranch);
325
+            }
326
+
327
+            return $updateSource;
328
+        }
329
+
330
+        /**
331
+         * @param string $url
332
+         * @return string
333
+         */
334
+        public function signDownloadUrl($url) {
335
+            if ( empty($this->credentials) ) {
336
+                return $url;
337
+            }
338
+            return add_query_arg('access_token', $this->credentials, $url);
339
+        }
340
+
341
+        /**
342
+         * Enable updating via release assets.
343
+         *
344
+         * If the latest release contains no usable assets, the update checker
345
+         * will fall back to using the automatically generated ZIP archive.
346
+         *
347
+         * Private repositories will only work with WordPress 3.7 or later.
348
+         *
349
+         * @param string|null $fileNameRegex Optional. Use only those assets where the file name matches this regex.
350
+         */
351
+        public function enableReleaseAssets($fileNameRegex = null) {
352
+            $this->releaseAssetsEnabled = true;
353
+            $this->assetFilterRegex = $fileNameRegex;
354
+            $this->assetApiBaseUrl = sprintf(
355
+                '//api.github.com/repos/%1$s/%2$s/releases/assets/',
356
+                $this->userName,
357
+                $this->repositoryName
358
+            );
359
+
360
+            //Optimization: Instead of filtering all HTTP requests, let's do it only when
361
+            //WordPress is about to download an update.
362
+            add_filter('upgrader_pre_download', array($this, 'addHttpRequestFilter'), 10, 1); //WP 3.7+
363
+        }
364
+
365
+        /**
366
+         * Does this asset match the file name regex?
367
+         *
368
+         * @param stdClass $releaseAsset
369
+         * @return bool
370
+         */
371
+        protected function matchesAssetFilter($releaseAsset) {
372
+            if ( $this->assetFilterRegex === null ) {
373
+                //The default is to accept all assets.
374
+                return true;
375
+            }
376
+            return isset($releaseAsset->name) && preg_match($this->assetFilterRegex, $releaseAsset->name);
377
+        }
378
+
379
+        /**
380
+         * @internal
381
+         * @param bool $result
382
+         * @return bool
383
+         */
384
+        public function addHttpRequestFilter($result) {
385
+            static $filterAdded = false;
386
+            if ( $this->releaseAssetsEnabled && !$filterAdded && $this->isAuthenticationEnabled() ) {
387
+                add_filter('http_request_args', array($this, 'setReleaseDownloadHeader'), 10, 2);
388
+                $filterAdded = true;
389
+            }
390
+            return $result;
391
+        }
392
+
393
+        /**
394
+         * Set the HTTP header that's necessary to download private release assets.
395
+         *
396
+         * See GitHub docs:
397
+         * @link https://developer.github.com/v3/repos/releases/#get-a-single-release-asset
398
+         *
399
+         * @internal
400
+         * @param array $requestArgs
401
+         * @param string $url
402
+         * @return array
403
+         */
404
+        public function setReleaseDownloadHeader($requestArgs, $url = '') {
405
+            //Is WordPress trying to download one of our assets?
406
+            if ( strpos($url, $this->assetApiBaseUrl) !== false ) {
407
+                $requestArgs['headers']['accept'] = 'application/octet-stream';
408
+            }
409
+            return $requestArgs;
410
+        }
411
+    }
412 412
 
413 413
 endif;
414 414
\ No newline at end of file
Please login to merge, or discard this patch.
external/php/plugin-update-checker/Puc/v4p4/Vcs/PluginUpdateChecker.php 1 patch
Indentation   +212 added lines, -212 removed lines patch added patch discarded remove patch
@@ -1,217 +1,217 @@
 block discarded – undo
1 1
 <?php
2 2
 if ( !class_exists('Puc_v4p4_Vcs_PluginUpdateChecker') ):
3 3
 
4
-	class Puc_v4p4_Vcs_PluginUpdateChecker extends Puc_v4p4_Plugin_UpdateChecker implements Puc_v4p4_Vcs_BaseChecker {
5
-		/**
6
-		 * @var string The branch where to look for updates. Defaults to "master".
7
-		 */
8
-		protected $branch = 'master';
9
-
10
-		/**
11
-		 * @var Puc_v4p4_Vcs_Api Repository API client.
12
-		 */
13
-		protected $api = null;
14
-
15
-		/**
16
-		 * Puc_v4p4_Vcs_PluginUpdateChecker constructor.
17
-		 *
18
-		 * @param Puc_v4p4_Vcs_Api $api
19
-		 * @param string $pluginFile
20
-		 * @param string $slug
21
-		 * @param int $checkPeriod
22
-		 * @param string $optionName
23
-		 * @param string $muPluginFile
24
-		 */
25
-		public function __construct($api, $pluginFile, $slug = '', $checkPeriod = 12, $optionName = '', $muPluginFile = '') {
26
-			$this->api = $api;
27
-			$this->api->setHttpFilterName($this->getUniqueName('request_info_options'));
28
-
29
-			parent::__construct($api->getRepositoryUrl(), $pluginFile, $slug, $checkPeriod, $optionName, $muPluginFile);
30
-
31
-			$this->api->setSlug($this->slug);
32
-		}
33
-
34
-		public function requestInfo($unusedParameter = null) {
35
-			//We have to make several remote API requests to gather all the necessary info
36
-			//which can take a while on slow networks.
37
-			if ( function_exists('set_time_limit') ) {
38
-				@set_time_limit(60);
39
-			}
40
-
41
-			$api = $this->api;
42
-			$api->setLocalDirectory($this->getAbsoluteDirectoryPath());
43
-
44
-			$info = new Puc_v4p4_Plugin_Info();
45
-			$info->filename = $this->pluginFile;
46
-			$info->slug = $this->slug;
47
-
48
-			$this->setInfoFromHeader($this->getPluginHeader(), $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->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, dirname($this->getAbsolutePath()));
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
-			$pluginDirectory = $this->getAbsoluteDirectoryPath();
121
-			if ( empty($pluginDirectory) || !is_dir($pluginDirectory) || ($pluginDirectory === '.') ) {
122
-				return false;
123
-			}
124
-			return is_file($pluginDirectory . '/' . $this->api->getLocalReadmeName());
125
-		}
126
-
127
-		/**
128
-		 * Copy plugin metadata from a file header to a Plugin Info object.
129
-		 *
130
-		 * @param array $fileHeader
131
-		 * @param Puc_v4p4_Plugin_Info $pluginInfo
132
-		 */
133
-		protected function setInfoFromHeader($fileHeader, $pluginInfo) {
134
-			$headerToPropertyMap = array(
135
-				'Version' => 'version',
136
-				'Name' => 'name',
137
-				'PluginURI' => 'homepage',
138
-				'Author' => 'author',
139
-				'AuthorName' => 'author',
140
-				'AuthorURI' => 'author_homepage',
141
-
142
-				'Requires WP' => 'requires',
143
-				'Tested WP' => 'tested',
144
-				'Requires at least' => 'requires',
145
-				'Tested up to' => 'tested',
146
-			);
147
-			foreach ($headerToPropertyMap as $headerName => $property) {
148
-				if ( isset($fileHeader[$headerName]) && !empty($fileHeader[$headerName]) ) {
149
-					$pluginInfo->$property = $fileHeader[$headerName];
150
-				}
151
-			}
152
-
153
-			if ( !empty($fileHeader['Description']) ) {
154
-				$pluginInfo->sections['description'] = $fileHeader['Description'];
155
-			}
156
-		}
157
-
158
-		/**
159
-		 * Copy plugin metadata from the remote readme.txt file.
160
-		 *
161
-		 * @param string $ref GitHub tag or branch where to look for the readme.
162
-		 * @param Puc_v4p4_Plugin_Info $pluginInfo
163
-		 */
164
-		protected function setInfoFromRemoteReadme($ref, $pluginInfo) {
165
-			$readme = $this->api->getRemoteReadme($ref);
166
-			if ( empty($readme) ) {
167
-				return;
168
-			}
169
-
170
-			if ( isset($readme['sections']) ) {
171
-				$pluginInfo->sections = array_merge($pluginInfo->sections, $readme['sections']);
172
-			}
173
-			if ( !empty($readme['tested_up_to']) ) {
174
-				$pluginInfo->tested = $readme['tested_up_to'];
175
-			}
176
-			if ( !empty($readme['requires_at_least']) ) {
177
-				$pluginInfo->requires = $readme['requires_at_least'];
178
-			}
179
-
180
-			if ( isset($readme['upgrade_notice'], $readme['upgrade_notice'][$pluginInfo->version]) ) {
181
-				$pluginInfo->upgrade_notice = $readme['upgrade_notice'][$pluginInfo->version];
182
-			}
183
-		}
184
-
185
-		public function setBranch($branch) {
186
-			$this->branch = $branch;
187
-			return $this;
188
-		}
189
-
190
-		public function setAuthentication($credentials) {
191
-			$this->api->setAuthentication($credentials);
192
-			return $this;
193
-		}
194
-
195
-		public function getVcsApi() {
196
-			return $this->api;
197
-		}
198
-
199
-		public function getUpdate() {
200
-			$update = parent::getUpdate();
201
-
202
-			if ( isset($update) && !empty($update->download_url) ) {
203
-				$update->download_url = $this->api->signDownloadUrl($update->download_url);
204
-			}
205
-
206
-			return $update;
207
-		}
208
-
209
-		public function onDisplayConfiguration($panel) {
210
-			parent::onDisplayConfiguration($panel);
211
-			$panel->row('Branch', $this->branch);
212
-			$panel->row('Authentication enabled', $this->api->isAuthenticationEnabled() ? 'Yes' : 'No');
213
-			$panel->row('API client', get_class($this->api));
214
-		}
215
-	}
4
+    class Puc_v4p4_Vcs_PluginUpdateChecker extends Puc_v4p4_Plugin_UpdateChecker implements Puc_v4p4_Vcs_BaseChecker {
5
+        /**
6
+         * @var string The branch where to look for updates. Defaults to "master".
7
+         */
8
+        protected $branch = 'master';
9
+
10
+        /**
11
+         * @var Puc_v4p4_Vcs_Api Repository API client.
12
+         */
13
+        protected $api = null;
14
+
15
+        /**
16
+         * Puc_v4p4_Vcs_PluginUpdateChecker constructor.
17
+         *
18
+         * @param Puc_v4p4_Vcs_Api $api
19
+         * @param string $pluginFile
20
+         * @param string $slug
21
+         * @param int $checkPeriod
22
+         * @param string $optionName
23
+         * @param string $muPluginFile
24
+         */
25
+        public function __construct($api, $pluginFile, $slug = '', $checkPeriod = 12, $optionName = '', $muPluginFile = '') {
26
+            $this->api = $api;
27
+            $this->api->setHttpFilterName($this->getUniqueName('request_info_options'));
28
+
29
+            parent::__construct($api->getRepositoryUrl(), $pluginFile, $slug, $checkPeriod, $optionName, $muPluginFile);
30
+
31
+            $this->api->setSlug($this->slug);
32
+        }
33
+
34
+        public function requestInfo($unusedParameter = null) {
35
+            //We have to make several remote API requests to gather all the necessary info
36
+            //which can take a while on slow networks.
37
+            if ( function_exists('set_time_limit') ) {
38
+                @set_time_limit(60);
39
+            }
40
+
41
+            $api = $this->api;
42
+            $api->setLocalDirectory($this->getAbsoluteDirectoryPath());
43
+
44
+            $info = new Puc_v4p4_Plugin_Info();
45
+            $info->filename = $this->pluginFile;
46
+            $info->slug = $this->slug;
47
+
48
+            $this->setInfoFromHeader($this->getPluginHeader(), $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->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, dirname($this->getAbsolutePath()));
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
+            $pluginDirectory = $this->getAbsoluteDirectoryPath();
121
+            if ( empty($pluginDirectory) || !is_dir($pluginDirectory) || ($pluginDirectory === '.') ) {
122
+                return false;
123
+            }
124
+            return is_file($pluginDirectory . '/' . $this->api->getLocalReadmeName());
125
+        }
126
+
127
+        /**
128
+         * Copy plugin metadata from a file header to a Plugin Info object.
129
+         *
130
+         * @param array $fileHeader
131
+         * @param Puc_v4p4_Plugin_Info $pluginInfo
132
+         */
133
+        protected function setInfoFromHeader($fileHeader, $pluginInfo) {
134
+            $headerToPropertyMap = array(
135
+                'Version' => 'version',
136
+                'Name' => 'name',
137
+                'PluginURI' => 'homepage',
138
+                'Author' => 'author',
139
+                'AuthorName' => 'author',
140
+                'AuthorURI' => 'author_homepage',
141
+
142
+                'Requires WP' => 'requires',
143
+                'Tested WP' => 'tested',
144
+                'Requires at least' => 'requires',
145
+                'Tested up to' => 'tested',
146
+            );
147
+            foreach ($headerToPropertyMap as $headerName => $property) {
148
+                if ( isset($fileHeader[$headerName]) && !empty($fileHeader[$headerName]) ) {
149
+                    $pluginInfo->$property = $fileHeader[$headerName];
150
+                }
151
+            }
152
+
153
+            if ( !empty($fileHeader['Description']) ) {
154
+                $pluginInfo->sections['description'] = $fileHeader['Description'];
155
+            }
156
+        }
157
+
158
+        /**
159
+         * Copy plugin metadata from the remote readme.txt file.
160
+         *
161
+         * @param string $ref GitHub tag or branch where to look for the readme.
162
+         * @param Puc_v4p4_Plugin_Info $pluginInfo
163
+         */
164
+        protected function setInfoFromRemoteReadme($ref, $pluginInfo) {
165
+            $readme = $this->api->getRemoteReadme($ref);
166
+            if ( empty($readme) ) {
167
+                return;
168
+            }
169
+
170
+            if ( isset($readme['sections']) ) {
171
+                $pluginInfo->sections = array_merge($pluginInfo->sections, $readme['sections']);
172
+            }
173
+            if ( !empty($readme['tested_up_to']) ) {
174
+                $pluginInfo->tested = $readme['tested_up_to'];
175
+            }
176
+            if ( !empty($readme['requires_at_least']) ) {
177
+                $pluginInfo->requires = $readme['requires_at_least'];
178
+            }
179
+
180
+            if ( isset($readme['upgrade_notice'], $readme['upgrade_notice'][$pluginInfo->version]) ) {
181
+                $pluginInfo->upgrade_notice = $readme['upgrade_notice'][$pluginInfo->version];
182
+            }
183
+        }
184
+
185
+        public function setBranch($branch) {
186
+            $this->branch = $branch;
187
+            return $this;
188
+        }
189
+
190
+        public function setAuthentication($credentials) {
191
+            $this->api->setAuthentication($credentials);
192
+            return $this;
193
+        }
194
+
195
+        public function getVcsApi() {
196
+            return $this->api;
197
+        }
198
+
199
+        public function getUpdate() {
200
+            $update = parent::getUpdate();
201
+
202
+            if ( isset($update) && !empty($update->download_url) ) {
203
+                $update->download_url = $this->api->signDownloadUrl($update->download_url);
204
+            }
205
+
206
+            return $update;
207
+        }
208
+
209
+        public function onDisplayConfiguration($panel) {
210
+            parent::onDisplayConfiguration($panel);
211
+            $panel->row('Branch', $this->branch);
212
+            $panel->row('Authentication enabled', $this->api->isAuthenticationEnabled() ? 'Yes' : 'No');
213
+            $panel->row('API client', get_class($this->api));
214
+        }
215
+    }
216 216
 
217 217
 endif;
218 218
\ No newline at end of file
Please login to merge, or discard this patch.
classes/external/php/plugin-update-checker/Puc/v4p4/StateStore.php 1 patch
Indentation   +201 added lines, -201 removed lines patch added patch discarded remove patch
@@ -2,206 +2,206 @@
 block discarded – undo
2 2
 
3 3
 if ( !class_exists('Puc_v4p4_StateStore', false) ):
4 4
 
5
-	class Puc_v4p4_StateStore {
6
-		/**
7
-		 * @var int Last update check timestamp.
8
-		 */
9
-		protected $lastCheck = 0;
10
-
11
-		/**
12
-		 * @var string Version number.
13
-		 */
14
-		protected $checkedVersion = '';
15
-
16
-		/**
17
-		 * @var Puc_v4p4_Update|null Cached update.
18
-		 */
19
-		protected $update = null;
20
-
21
-		/**
22
-		 * @var string Site option name.
23
-		 */
24
-		private $optionName = '';
25
-
26
-		/**
27
-		 * @var bool Whether we've already tried to load the state from the database.
28
-		 */
29
-		private $isLoaded = false;
30
-
31
-		public function __construct($optionName) {
32
-			$this->optionName = $optionName;
33
-		}
34
-
35
-		/**
36
-		 * Get time elapsed since the last update check.
37
-		 *
38
-		 * If there are no recorded update checks, this method returns a large arbitrary number
39
-		 * (i.e. time since the Unix epoch).
40
-		 *
41
-		 * @return int Elapsed time in seconds.
42
-		 */
43
-		public function timeSinceLastCheck() {
44
-			$this->lazyLoad();
45
-			return time() - $this->lastCheck;
46
-		}
47
-
48
-		/**
49
-		 * @return int
50
-		 */
51
-		public function getLastCheck() {
52
-			$this->lazyLoad();
53
-			return $this->lastCheck;
54
-		}
55
-
56
-		/**
57
-		 * Set the time of the last update check to the current timestamp.
58
-		 *
59
-		 * @return $this
60
-		 */
61
-		public function setLastCheckToNow() {
62
-			$this->lazyLoad();
63
-			$this->lastCheck = time();
64
-			return $this;
65
-		}
66
-
67
-		/**
68
-		 * @return null|Puc_v4p4_Update
69
-		 */
70
-		public function getUpdate() {
71
-			$this->lazyLoad();
72
-			return $this->update;
73
-		}
74
-
75
-		/**
76
-		 * @param Puc_v4p4_Update|null $update
77
-		 * @return $this
78
-		 */
79
-		public function setUpdate(Puc_v4p4_Update $update = null) {
80
-			$this->lazyLoad();
81
-			$this->update = $update;
82
-			return $this;
83
-		}
84
-
85
-		/**
86
-		 * @return string
87
-		 */
88
-		public function getCheckedVersion() {
89
-			$this->lazyLoad();
90
-			return $this->checkedVersion;
91
-		}
92
-
93
-		/**
94
-		 * @param string $version
95
-		 * @return $this
96
-		 */
97
-		public function setCheckedVersion($version) {
98
-			$this->lazyLoad();
99
-			$this->checkedVersion = strval($version);
100
-			return $this;
101
-		}
102
-
103
-		/**
104
-		 * Get translation updates.
105
-		 *
106
-		 * @return array
107
-		 */
108
-		public function getTranslations() {
109
-			$this->lazyLoad();
110
-			if ( isset($this->update, $this->update->translations) ) {
111
-				return $this->update->translations;
112
-			}
113
-			return array();
114
-		}
115
-
116
-		/**
117
-		 * Set translation updates.
118
-		 *
119
-		 * @param array $translationUpdates
120
-		 */
121
-		public function setTranslations($translationUpdates) {
122
-			$this->lazyLoad();
123
-			if ( isset($this->update) ) {
124
-				$this->update->translations = $translationUpdates;
125
-				$this->save();
126
-			}
127
-		}
128
-
129
-		public function save() {
130
-			$state = new stdClass();
131
-
132
-			$state->lastCheck = $this->lastCheck;
133
-			$state->checkedVersion = $this->checkedVersion;
134
-
135
-			if ( isset($this->update)) {
136
-				$state->update = $this->update->toStdClass();
137
-
138
-				$updateClass = get_class($this->update);
139
-				$state->updateClass = $updateClass;
140
-				$prefix = $this->getLibPrefix();
141
-				if ( Puc_v4p4_Utils::startsWith($updateClass, $prefix) ) {
142
-					$state->updateBaseClass = substr($updateClass, strlen($prefix));
143
-				}
144
-			}
145
-
146
-			update_site_option($this->optionName, $state);
147
-			$this->isLoaded = true;
148
-		}
149
-
150
-		/**
151
-		 * @return $this
152
-		 */
153
-		public function lazyLoad() {
154
-			if ( !$this->isLoaded ) {
155
-				$this->load();
156
-			}
157
-			return $this;
158
-		}
159
-
160
-		protected function load() {
161
-			$this->isLoaded = true;
162
-
163
-			$state = get_site_option($this->optionName, null);
164
-
165
-			if ( !is_object($state) ) {
166
-				$this->lastCheck = 0;
167
-				$this->checkedVersion = '';
168
-				$this->update = null;
169
-				return;
170
-			}
171
-
172
-			$this->lastCheck = intval(Puc_v4p4_Utils::get($state, 'lastCheck', 0));
173
-			$this->checkedVersion = Puc_v4p4_Utils::get($state, 'checkedVersion', '');
174
-			$this->update = null;
175
-
176
-			if ( isset($state->update) ) {
177
-				//This mess is due to the fact that the want the update class from this version
178
-				//of the library, not the version that saved the update.
179
-
180
-				$updateClass = null;
181
-				if ( isset($state->updateBaseClass) ) {
182
-					$updateClass = $this->getLibPrefix() . $state->updateBaseClass;
183
-				} else if ( isset($state->updateClass) && class_exists($state->updateClass) ) {
184
-					$updateClass = $state->updateClass;
185
-				}
186
-
187
-				if ( $updateClass !== null ) {
188
-					$this->update = call_user_func(array($updateClass, 'fromObject'), $state->update);
189
-				}
190
-			}
191
-		}
192
-
193
-		public function delete() {
194
-			delete_site_option($this->optionName);
195
-
196
-			$this->lastCheck = 0;
197
-			$this->checkedVersion = '';
198
-			$this->update = null;
199
-		}
200
-
201
-		private function getLibPrefix() {
202
-			$parts = explode('_', __CLASS__, 3);
203
-			return $parts[0] . '_' . $parts[1] . '_';
204
-		}
205
-	}
5
+    class Puc_v4p4_StateStore {
6
+        /**
7
+         * @var int Last update check timestamp.
8
+         */
9
+        protected $lastCheck = 0;
10
+
11
+        /**
12
+         * @var string Version number.
13
+         */
14
+        protected $checkedVersion = '';
15
+
16
+        /**
17
+         * @var Puc_v4p4_Update|null Cached update.
18
+         */
19
+        protected $update = null;
20
+
21
+        /**
22
+         * @var string Site option name.
23
+         */
24
+        private $optionName = '';
25
+
26
+        /**
27
+         * @var bool Whether we've already tried to load the state from the database.
28
+         */
29
+        private $isLoaded = false;
30
+
31
+        public function __construct($optionName) {
32
+            $this->optionName = $optionName;
33
+        }
34
+
35
+        /**
36
+         * Get time elapsed since the last update check.
37
+         *
38
+         * If there are no recorded update checks, this method returns a large arbitrary number
39
+         * (i.e. time since the Unix epoch).
40
+         *
41
+         * @return int Elapsed time in seconds.
42
+         */
43
+        public function timeSinceLastCheck() {
44
+            $this->lazyLoad();
45
+            return time() - $this->lastCheck;
46
+        }
47
+
48
+        /**
49
+         * @return int
50
+         */
51
+        public function getLastCheck() {
52
+            $this->lazyLoad();
53
+            return $this->lastCheck;
54
+        }
55
+
56
+        /**
57
+         * Set the time of the last update check to the current timestamp.
58
+         *
59
+         * @return $this
60
+         */
61
+        public function setLastCheckToNow() {
62
+            $this->lazyLoad();
63
+            $this->lastCheck = time();
64
+            return $this;
65
+        }
66
+
67
+        /**
68
+         * @return null|Puc_v4p4_Update
69
+         */
70
+        public function getUpdate() {
71
+            $this->lazyLoad();
72
+            return $this->update;
73
+        }
74
+
75
+        /**
76
+         * @param Puc_v4p4_Update|null $update
77
+         * @return $this
78
+         */
79
+        public function setUpdate(Puc_v4p4_Update $update = null) {
80
+            $this->lazyLoad();
81
+            $this->update = $update;
82
+            return $this;
83
+        }
84
+
85
+        /**
86
+         * @return string
87
+         */
88
+        public function getCheckedVersion() {
89
+            $this->lazyLoad();
90
+            return $this->checkedVersion;
91
+        }
92
+
93
+        /**
94
+         * @param string $version
95
+         * @return $this
96
+         */
97
+        public function setCheckedVersion($version) {
98
+            $this->lazyLoad();
99
+            $this->checkedVersion = strval($version);
100
+            return $this;
101
+        }
102
+
103
+        /**
104
+         * Get translation updates.
105
+         *
106
+         * @return array
107
+         */
108
+        public function getTranslations() {
109
+            $this->lazyLoad();
110
+            if ( isset($this->update, $this->update->translations) ) {
111
+                return $this->update->translations;
112
+            }
113
+            return array();
114
+        }
115
+
116
+        /**
117
+         * Set translation updates.
118
+         *
119
+         * @param array $translationUpdates
120
+         */
121
+        public function setTranslations($translationUpdates) {
122
+            $this->lazyLoad();
123
+            if ( isset($this->update) ) {
124
+                $this->update->translations = $translationUpdates;
125
+                $this->save();
126
+            }
127
+        }
128
+
129
+        public function save() {
130
+            $state = new stdClass();
131
+
132
+            $state->lastCheck = $this->lastCheck;
133
+            $state->checkedVersion = $this->checkedVersion;
134
+
135
+            if ( isset($this->update)) {
136
+                $state->update = $this->update->toStdClass();
137
+
138
+                $updateClass = get_class($this->update);
139
+                $state->updateClass = $updateClass;
140
+                $prefix = $this->getLibPrefix();
141
+                if ( Puc_v4p4_Utils::startsWith($updateClass, $prefix) ) {
142
+                    $state->updateBaseClass = substr($updateClass, strlen($prefix));
143
+                }
144
+            }
145
+
146
+            update_site_option($this->optionName, $state);
147
+            $this->isLoaded = true;
148
+        }
149
+
150
+        /**
151
+         * @return $this
152
+         */
153
+        public function lazyLoad() {
154
+            if ( !$this->isLoaded ) {
155
+                $this->load();
156
+            }
157
+            return $this;
158
+        }
159
+
160
+        protected function load() {
161
+            $this->isLoaded = true;
162
+
163
+            $state = get_site_option($this->optionName, null);
164
+
165
+            if ( !is_object($state) ) {
166
+                $this->lastCheck = 0;
167
+                $this->checkedVersion = '';
168
+                $this->update = null;
169
+                return;
170
+            }
171
+
172
+            $this->lastCheck = intval(Puc_v4p4_Utils::get($state, 'lastCheck', 0));
173
+            $this->checkedVersion = Puc_v4p4_Utils::get($state, 'checkedVersion', '');
174
+            $this->update = null;
175
+
176
+            if ( isset($state->update) ) {
177
+                //This mess is due to the fact that the want the update class from this version
178
+                //of the library, not the version that saved the update.
179
+
180
+                $updateClass = null;
181
+                if ( isset($state->updateBaseClass) ) {
182
+                    $updateClass = $this->getLibPrefix() . $state->updateBaseClass;
183
+                } else if ( isset($state->updateClass) && class_exists($state->updateClass) ) {
184
+                    $updateClass = $state->updateClass;
185
+                }
186
+
187
+                if ( $updateClass !== null ) {
188
+                    $this->update = call_user_func(array($updateClass, 'fromObject'), $state->update);
189
+                }
190
+            }
191
+        }
192
+
193
+        public function delete() {
194
+            delete_site_option($this->optionName);
195
+
196
+            $this->lastCheck = 0;
197
+            $this->checkedVersion = '';
198
+            $this->update = null;
199
+        }
200
+
201
+        private function getLibPrefix() {
202
+            $parts = explode('_', __CLASS__, 3);
203
+            return $parts[0] . '_' . $parts[1] . '_';
204
+        }
205
+    }
206 206
 
207 207
 endif;
Please login to merge, or discard this patch.
classes/external/php/plugin-update-checker/Puc/v4p4/OAuthSignature.php 1 patch
Indentation   +71 added lines, -71 removed lines patch added patch discarded remove patch
@@ -2,87 +2,87 @@
 block discarded – undo
2 2
 
3 3
 if ( !class_exists('Puc_v4p4_OAuthSignature', false) ):
4 4
 
5
-	/**
6
-	 * A basic signature generator for zero-legged OAuth 1.0.
7
-	 */
8
-	class Puc_v4p4_OAuthSignature {
9
-		private $consumerKey = '';
10
-		private $consumerSecret = '';
5
+    /**
6
+     * A basic signature generator for zero-legged OAuth 1.0.
7
+     */
8
+    class Puc_v4p4_OAuthSignature {
9
+        private $consumerKey = '';
10
+        private $consumerSecret = '';
11 11
 
12
-		public function __construct($consumerKey, $consumerSecret) {
13
-			$this->consumerKey = $consumerKey;
14
-			$this->consumerSecret = $consumerSecret;
15
-		}
12
+        public function __construct($consumerKey, $consumerSecret) {
13
+            $this->consumerKey = $consumerKey;
14
+            $this->consumerSecret = $consumerSecret;
15
+        }
16 16
 
17
-		/**
18
-		 * Sign a URL using OAuth 1.0.
19
-		 *
20
-		 * @param string $url The URL to be signed. It may contain query parameters.
21
-		 * @param string $method HTTP method such as "GET", "POST" and so on.
22
-		 * @return string The signed URL.
23
-		 */
24
-		public function sign($url, $method = 'GET') {
25
-			$parameters = array();
17
+        /**
18
+         * Sign a URL using OAuth 1.0.
19
+         *
20
+         * @param string $url The URL to be signed. It may contain query parameters.
21
+         * @param string $method HTTP method such as "GET", "POST" and so on.
22
+         * @return string The signed URL.
23
+         */
24
+        public function sign($url, $method = 'GET') {
25
+            $parameters = array();
26 26
 
27
-			//Parse query parameters.
28
-			$query = @parse_url($url, PHP_URL_QUERY);
29
-			if ( !empty($query) ) {
30
-				parse_str($query, $parsedParams);
31
-				if ( is_array($parameters) ) {
32
-					$parameters = $parsedParams;
33
-				}
34
-				//Remove the query string from the URL. We'll replace it later.
35
-				$url = substr($url, 0, strpos($url, '?'));
36
-			}
27
+            //Parse query parameters.
28
+            $query = @parse_url($url, PHP_URL_QUERY);
29
+            if ( !empty($query) ) {
30
+                parse_str($query, $parsedParams);
31
+                if ( is_array($parameters) ) {
32
+                    $parameters = $parsedParams;
33
+                }
34
+                //Remove the query string from the URL. We'll replace it later.
35
+                $url = substr($url, 0, strpos($url, '?'));
36
+            }
37 37
 
38
-			$parameters = array_merge(
39
-				$parameters,
40
-				array(
41
-					'oauth_consumer_key' => $this->consumerKey,
42
-					'oauth_nonce' => $this->nonce(),
43
-					'oauth_signature_method' => 'HMAC-SHA1',
44
-					'oauth_timestamp' => time(),
45
-					'oauth_version' => '1.0',
46
-				)
47
-			);
48
-			unset($parameters['oauth_signature']);
38
+            $parameters = array_merge(
39
+                $parameters,
40
+                array(
41
+                    'oauth_consumer_key' => $this->consumerKey,
42
+                    'oauth_nonce' => $this->nonce(),
43
+                    'oauth_signature_method' => 'HMAC-SHA1',
44
+                    'oauth_timestamp' => time(),
45
+                    'oauth_version' => '1.0',
46
+                )
47
+            );
48
+            unset($parameters['oauth_signature']);
49 49
 
50
-			//Parameters must be sorted alphabetically before signing.
51
-			ksort($parameters);
50
+            //Parameters must be sorted alphabetically before signing.
51
+            ksort($parameters);
52 52
 
53
-			//The most complicated part of the request - generating the signature.
54
-			//The string to sign contains the HTTP method, the URL path, and all of
55
-			//our query parameters. Everything is URL encoded. Then we concatenate
56
-			//them with ampersands into a single string to hash.
57
-			$encodedVerb = urlencode($method);
58
-			$encodedUrl = urlencode($url);
59
-			$encodedParams = urlencode(http_build_query($parameters, '', '&'));
53
+            //The most complicated part of the request - generating the signature.
54
+            //The string to sign contains the HTTP method, the URL path, and all of
55
+            //our query parameters. Everything is URL encoded. Then we concatenate
56
+            //them with ampersands into a single string to hash.
57
+            $encodedVerb = urlencode($method);
58
+            $encodedUrl = urlencode($url);
59
+            $encodedParams = urlencode(http_build_query($parameters, '', '&'));
60 60
 
61
-			$stringToSign = $encodedVerb . '&' . $encodedUrl . '&' . $encodedParams;
61
+            $stringToSign = $encodedVerb . '&' . $encodedUrl . '&' . $encodedParams;
62 62
 
63
-			//Since we only have one OAuth token (the consumer secret) we only have
64
-			//to use it as our HMAC key. However, we still have to append an & to it
65
-			//as if we were using it with additional tokens.
66
-			$secret = urlencode($this->consumerSecret) . '&';
63
+            //Since we only have one OAuth token (the consumer secret) we only have
64
+            //to use it as our HMAC key. However, we still have to append an & to it
65
+            //as if we were using it with additional tokens.
66
+            $secret = urlencode($this->consumerSecret) . '&';
67 67
 
68
-			//The signature is a hash of the consumer key and the base string. Note
69
-			//that we have to get the raw output from hash_hmac and base64 encode
70
-			//the binary data result.
71
-			$parameters['oauth_signature'] = base64_encode(hash_hmac('sha1', $stringToSign, $secret, true));
68
+            //The signature is a hash of the consumer key and the base string. Note
69
+            //that we have to get the raw output from hash_hmac and base64 encode
70
+            //the binary data result.
71
+            $parameters['oauth_signature'] = base64_encode(hash_hmac('sha1', $stringToSign, $secret, true));
72 72
 
73
-			return ($url . '?' . http_build_query($parameters));
74
-		}
73
+            return ($url . '?' . http_build_query($parameters));
74
+        }
75 75
 
76
-		/**
77
-		 * Generate a random nonce.
78
-		 *
79
-		 * @return string
80
-		 */
81
-		private function nonce() {
82
-			$mt = microtime();
83
-			$rand = mt_rand();
84
-			return md5($mt . '_' . $rand);
85
-		}
86
-	}
76
+        /**
77
+         * Generate a random nonce.
78
+         *
79
+         * @return string
80
+         */
81
+        private function nonce() {
82
+            $mt = microtime();
83
+            $rand = mt_rand();
84
+            return md5($mt . '_' . $rand);
85
+        }
86
+    }
87 87
 
88 88
 endif;
89 89
\ No newline at end of file
Please login to merge, or discard this patch.
classes/external/php/plugin-update-checker/Puc/v4p4/Metadata.php 1 patch
Indentation   +127 added lines, -127 removed lines patch added patch discarded remove patch
@@ -1,132 +1,132 @@
 block discarded – undo
1 1
 <?php
2 2
 if ( !class_exists('Puc_v4p4_Metadata', false) ):
3 3
 
4
-	/**
5
-	 * A base container for holding information about updates and plugin metadata.
6
-	 *
7
-	 * @author Janis Elsts
8
-	 * @copyright 2016
9
-	 * @access public
10
-	 */
11
-	abstract class Puc_v4p4_Metadata {
12
-
13
-		/**
14
-		 * Create an instance of this class from a JSON document.
15
-		 *
16
-		 * @abstract
17
-		 * @param string $json
18
-		 * @return self
19
-		 */
20
-		public static function fromJson(/** @noinspection PhpUnusedParameterInspection */ $json) {
21
-			throw new LogicException('The ' . __METHOD__ . ' method must be implemented by subclasses');
22
-		}
23
-
24
-		/**
25
-		 * @param string $json
26
-		 * @param self $target
27
-		 * @return bool
28
-		 */
29
-		protected static function createFromJson($json, $target) {
30
-			/** @var StdClass $apiResponse */
31
-			$apiResponse = json_decode($json);
32
-			if ( empty($apiResponse) || !is_object($apiResponse) ){
33
-				$errorMessage = "Failed to parse update metadata. Try validating your .json file with http://jsonlint.com/";
34
-				do_action('puc_api_error', new WP_Error('puc-invalid-json', $errorMessage));
35
-				trigger_error($errorMessage, E_USER_NOTICE);
36
-				return false;
37
-			}
38
-
39
-			$valid = $target->validateMetadata($apiResponse);
40
-			if ( is_wp_error($valid) ){
41
-				do_action('puc_api_error', $valid);
42
-				trigger_error($valid->get_error_message(), E_USER_NOTICE);
43
-				return false;
44
-			}
45
-
46
-			foreach(get_object_vars($apiResponse) as $key => $value){
47
-				$target->$key = $value;
48
-			}
49
-
50
-			return true;
51
-		}
52
-
53
-		/**
54
-		 * No validation by default! Subclasses should check that the required fields are present.
55
-		 *
56
-		 * @param StdClass $apiResponse
57
-		 * @return bool|WP_Error
58
-		 */
59
-		protected function validateMetadata(/** @noinspection PhpUnusedParameterInspection */ $apiResponse) {
60
-			return true;
61
-		}
62
-
63
-		/**
64
-		 * Create a new instance by copying the necessary fields from another object.
65
-		 *
66
-		 * @abstract
67
-		 * @param StdClass|self $object The source object.
68
-		 * @return self The new copy.
69
-		 */
70
-		public static function fromObject(/** @noinspection PhpUnusedParameterInspection */ $object) {
71
-			throw new LogicException('The ' . __METHOD__ . ' method must be implemented by subclasses');
72
-		}
73
-
74
-		/**
75
-		 * Create an instance of StdClass that can later be converted back to an
76
-		 * update or info container. Useful for serialization and caching, as it
77
-		 * avoids the "incomplete object" problem if the cached value is loaded
78
-		 * before this class.
79
-		 *
80
-		 * @return StdClass
81
-		 */
82
-		public function toStdClass() {
83
-			$object = new stdClass();
84
-			$this->copyFields($this, $object);
85
-			return $object;
86
-		}
87
-
88
-		/**
89
-		 * Transform the metadata into the format used by WordPress core.
90
-		 *
91
-		 * @return object
92
-		 */
93
-		abstract public function toWpFormat();
94
-
95
-		/**
96
-		 * Copy known fields from one object to another.
97
-		 *
98
-		 * @param StdClass|self $from
99
-		 * @param StdClass|self $to
100
-		 */
101
-		protected function copyFields($from, $to) {
102
-			$fields = $this->getFieldNames();
103
-
104
-			if ( property_exists($from, 'slug') && !empty($from->slug) ) {
105
-				//Let plugins add extra fields without having to create subclasses.
106
-				$fields = apply_filters($this->getPrefixedFilter('retain_fields') . '-' . $from->slug, $fields);
107
-			}
108
-
109
-			foreach ($fields as $field) {
110
-				if ( property_exists($from, $field) ) {
111
-					$to->$field = $from->$field;
112
-				}
113
-			}
114
-		}
115
-
116
-		/**
117
-		 * @return string[]
118
-		 */
119
-		protected function getFieldNames() {
120
-			return array();
121
-		}
122
-
123
-		/**
124
-		 * @param string $tag
125
-		 * @return string
126
-		 */
127
-		protected function getPrefixedFilter($tag) {
128
-			return 'puc_' . $tag;
129
-		}
130
-	}
4
+    /**
5
+     * A base container for holding information about updates and plugin metadata.
6
+     *
7
+     * @author Janis Elsts
8
+     * @copyright 2016
9
+     * @access public
10
+     */
11
+    abstract class Puc_v4p4_Metadata {
12
+
13
+        /**
14
+         * Create an instance of this class from a JSON document.
15
+         *
16
+         * @abstract
17
+         * @param string $json
18
+         * @return self
19
+         */
20
+        public static function fromJson(/** @noinspection PhpUnusedParameterInspection */ $json) {
21
+            throw new LogicException('The ' . __METHOD__ . ' method must be implemented by subclasses');
22
+        }
23
+
24
+        /**
25
+         * @param string $json
26
+         * @param self $target
27
+         * @return bool
28
+         */
29
+        protected static function createFromJson($json, $target) {
30
+            /** @var StdClass $apiResponse */
31
+            $apiResponse = json_decode($json);
32
+            if ( empty($apiResponse) || !is_object($apiResponse) ){
33
+                $errorMessage = "Failed to parse update metadata. Try validating your .json file with http://jsonlint.com/";
34
+                do_action('puc_api_error', new WP_Error('puc-invalid-json', $errorMessage));
35
+                trigger_error($errorMessage, E_USER_NOTICE);
36
+                return false;
37
+            }
38
+
39
+            $valid = $target->validateMetadata($apiResponse);
40
+            if ( is_wp_error($valid) ){
41
+                do_action('puc_api_error', $valid);
42
+                trigger_error($valid->get_error_message(), E_USER_NOTICE);
43
+                return false;
44
+            }
45
+
46
+            foreach(get_object_vars($apiResponse) as $key => $value){
47
+                $target->$key = $value;
48
+            }
49
+
50
+            return true;
51
+        }
52
+
53
+        /**
54
+         * No validation by default! Subclasses should check that the required fields are present.
55
+         *
56
+         * @param StdClass $apiResponse
57
+         * @return bool|WP_Error
58
+         */
59
+        protected function validateMetadata(/** @noinspection PhpUnusedParameterInspection */ $apiResponse) {
60
+            return true;
61
+        }
62
+
63
+        /**
64
+         * Create a new instance by copying the necessary fields from another object.
65
+         *
66
+         * @abstract
67
+         * @param StdClass|self $object The source object.
68
+         * @return self The new copy.
69
+         */
70
+        public static function fromObject(/** @noinspection PhpUnusedParameterInspection */ $object) {
71
+            throw new LogicException('The ' . __METHOD__ . ' method must be implemented by subclasses');
72
+        }
73
+
74
+        /**
75
+         * Create an instance of StdClass that can later be converted back to an
76
+         * update or info container. Useful for serialization and caching, as it
77
+         * avoids the "incomplete object" problem if the cached value is loaded
78
+         * before this class.
79
+         *
80
+         * @return StdClass
81
+         */
82
+        public function toStdClass() {
83
+            $object = new stdClass();
84
+            $this->copyFields($this, $object);
85
+            return $object;
86
+        }
87
+
88
+        /**
89
+         * Transform the metadata into the format used by WordPress core.
90
+         *
91
+         * @return object
92
+         */
93
+        abstract public function toWpFormat();
94
+
95
+        /**
96
+         * Copy known fields from one object to another.
97
+         *
98
+         * @param StdClass|self $from
99
+         * @param StdClass|self $to
100
+         */
101
+        protected function copyFields($from, $to) {
102
+            $fields = $this->getFieldNames();
103
+
104
+            if ( property_exists($from, 'slug') && !empty($from->slug) ) {
105
+                //Let plugins add extra fields without having to create subclasses.
106
+                $fields = apply_filters($this->getPrefixedFilter('retain_fields') . '-' . $from->slug, $fields);
107
+            }
108
+
109
+            foreach ($fields as $field) {
110
+                if ( property_exists($from, $field) ) {
111
+                    $to->$field = $from->$field;
112
+                }
113
+            }
114
+        }
115
+
116
+        /**
117
+         * @return string[]
118
+         */
119
+        protected function getFieldNames() {
120
+            return array();
121
+        }
122
+
123
+        /**
124
+         * @param string $tag
125
+         * @return string
126
+         */
127
+        protected function getPrefixedFilter($tag) {
128
+            return 'puc_' . $tag;
129
+        }
130
+    }
131 131
 
132 132
 endif;
133 133
\ No newline at end of file
Please login to merge, or discard this patch.
classes/external/php/plugin-update-checker/Puc/v4p4/Update.php 1 patch
Indentation   +25 added lines, -25 removed lines patch added patch discarded remove patch
@@ -1,34 +1,34 @@
 block discarded – undo
1 1
 <?php
2 2
 if ( !class_exists('Puc_v4p4_Update', false) ):
3 3
 
4
-	/**
5
-	 * A simple container class for holding information about an available update.
6
-	 *
7
-	 * @author Janis Elsts
8
-	 * @access public
9
-	 */
10
-	abstract class Puc_v4p4_Update extends Puc_v4p4_Metadata {
11
-		public $slug;
12
-		public $version;
13
-		public $download_url;
14
-		public $translations = array();
4
+    /**
5
+     * A simple container class for holding information about an available update.
6
+     *
7
+     * @author Janis Elsts
8
+     * @access public
9
+     */
10
+    abstract class Puc_v4p4_Update extends Puc_v4p4_Metadata {
11
+        public $slug;
12
+        public $version;
13
+        public $download_url;
14
+        public $translations = array();
15 15
 
16
-		/**
17
-		 * @return string[]
18
-		 */
19
-		protected function getFieldNames() {
20
-			return array('slug', 'version', 'download_url', 'translations');
21
-		}
16
+        /**
17
+         * @return string[]
18
+         */
19
+        protected function getFieldNames() {
20
+            return array('slug', 'version', 'download_url', 'translations');
21
+        }
22 22
 
23
-		public function toWpFormat() {
24
-			$update = new stdClass();
23
+        public function toWpFormat() {
24
+            $update = new stdClass();
25 25
 
26
-			$update->slug = $this->slug;
27
-			$update->new_version = $this->version;
28
-			$update->package = $this->download_url;
26
+            $update->slug = $this->slug;
27
+            $update->new_version = $this->version;
28
+            $update->package = $this->download_url;
29 29
 
30
-			return $update;
31
-		}
32
-	}
30
+            return $update;
31
+        }
32
+    }
33 33
 
34 34
 endif;
35 35
\ No newline at end of file
Please login to merge, or discard this patch.