Diff: STRATO-apps/wordpress_03/app/wp-content/plugins/aimogen-pro/update-checker/Puc/v5p6/Plugin/Ui.php
Keine Baseline-Datei – Diff nur gegen leer.
1
-
1
+
<?php
2
+
namespace YahnisElsts\PluginUpdateChecker\v5p6\Plugin;
3
+
4
+
if ( !class_exists(Ui::class, false) ):
5
+
/**
6
+
* Additional UI elements for plugins.
7
+
*/
8
+
class Ui {
9
+
private $updateChecker;
10
+
private $manualCheckErrorTransient = '';
11
+
12
+
/**
13
+
* @param UpdateChecker $updateChecker
14
+
*/
15
+
public function __construct($updateChecker) {
16
+
$this->updateChecker = $updateChecker;
17
+
$this->manualCheckErrorTransient = $this->updateChecker->getUniqueName('manual_check_errors');
18
+
19
+
add_action('admin_init', array($this, 'onAdminInit'));
20
+
}
21
+
22
+
public function onAdminInit() {
23
+
if ( $this->updateChecker->userCanInstallUpdates() ) {
24
+
$this->handleManualCheck();
25
+
26
+
add_filter('plugin_row_meta', array($this, 'addViewDetailsLink'), 10, 3);
27
+
add_filter('plugin_row_meta', array($this, 'addCheckForUpdatesLink'), 10, 2);
28
+
add_action('all_admin_notices', array($this, 'displayManualCheckResult'));
29
+
}
30
+
}
31
+
32
+
/**
33
+
* Add a "View Details" link to the plugin row in the "Plugins" page. By default,
34
+
* the new link will appear before the "Visit plugin site" link (if present).
35
+
*
36
+
* You can change the link text by using the "puc_view_details_link-$slug" filter.
37
+
* Returning an empty string from the filter will disable the link.
38
+
*
39
+
* You can change the position of the link using the
40
+
* "puc_view_details_link_position-$slug" filter.
41
+
* Returning 'before' or 'after' will place the link immediately before/after
42
+
* the "Visit plugin site" link.
43
+
* Returning 'append' places the link after any existing links at the time of the hook.
44
+
* Returning 'replace' replaces the "Visit plugin site" link.
45
+
* Returning anything else disables the link when there is a "Visit plugin site" link.
46
+
*
47
+
* If there is no "Visit plugin site" link 'append' is always used!
48
+
*
49
+
* @param array $pluginMeta Array of meta links.
50
+
* @param string $pluginFile
51
+
* @param array $pluginData Array of plugin header data.
52
+
* @return array
53
+
*/
54
+
public function addViewDetailsLink($pluginMeta, $pluginFile, $pluginData = array()) {
55
+
if ( $this->isMyPluginFile($pluginFile) && !isset($pluginData['slug']) ) {
56
+
$linkText = apply_filters($this->updateChecker->getUniqueName('view_details_link'), __('View details'));
57
+
if ( !empty($linkText) ) {
58
+
$viewDetailsLinkPosition = 'append';
59
+
60
+
//Find the "Visit plugin site" link (if present).
61
+
$visitPluginSiteLinkIndex = count($pluginMeta) - 1;
62
+
if ( $pluginData['PluginURI'] ) {
63
+
$escapedPluginUri = esc_url($pluginData['PluginURI']);
64
+
foreach ($pluginMeta as $linkIndex => $existingLink) {
65
+
if ( strpos($existingLink, $escapedPluginUri) !== false ) {
66
+
$visitPluginSiteLinkIndex = $linkIndex;
67
+
$viewDetailsLinkPosition = apply_filters(
68
+
$this->updateChecker->getUniqueName('view_details_link_position'),
69
+
'before'
70
+
);
71
+
break;
72
+
}
73
+
}
74
+
}
75
+
76
+
$viewDetailsLink = sprintf('<a href="%s" class="thickbox open-plugin-details-modal" aria-label="%s" data-title="%s">%s</a>',
77
+
esc_url(network_admin_url('plugin-install.php?tab=plugin-information&plugin=' . urlencode($this->updateChecker->slug) .
78
+
'&TB_iframe=true&width=600&height=550')),
79
+
esc_attr(sprintf(__('More information about %s'), $pluginData['Name'])),
80
+
esc_attr($pluginData['Name']),
81
+
$linkText
82
+
);
83
+
switch ($viewDetailsLinkPosition) {
84
+
case 'before':
85
+
array_splice($pluginMeta, $visitPluginSiteLinkIndex, 0, $viewDetailsLink);
86
+
break;
87
+
case 'after':
88
+
array_splice($pluginMeta, $visitPluginSiteLinkIndex + 1, 0, $viewDetailsLink);
89
+
break;
90
+
case 'replace':
91
+
$pluginMeta[$visitPluginSiteLinkIndex] = $viewDetailsLink;
92
+
break;
93
+
case 'append':
94
+
default:
95
+
$pluginMeta[] = $viewDetailsLink;
96
+
break;
97
+
}
98
+
}
99
+
}
100
+
return $pluginMeta;
101
+
}
102
+
103
+
/**
104
+
* Add a "Check for updates" link to the plugin row in the "Plugins" page. By default,
105
+
* the new link will appear after the "Visit plugin site" link if present, otherwise
106
+
* after the "View plugin details" link.
107
+
*
108
+
* You can change the link text by using the "puc_manual_check_link-$slug" filter.
109
+
* Returning an empty string from the filter will disable the link.
110
+
*
111
+
* @param array $pluginMeta Array of meta links.
112
+
* @param string $pluginFile
113
+
* @return array
114
+
*/
115
+
public function addCheckForUpdatesLink($pluginMeta, $pluginFile) {
116
+
if ( $this->isMyPluginFile($pluginFile) ) {
117
+
$linkUrl = wp_nonce_url(
118
+
add_query_arg(
119
+
array(
120
+
'puc_check_for_updates' => 1,
121
+
'puc_slug' => $this->updateChecker->slug,
122
+
),
123
+
self_admin_url('plugins.php')
124
+
),
125
+
'puc_check_for_updates'
126
+
);
127
+
128
+
$linkText = apply_filters(
129
+
$this->updateChecker->getUniqueName('manual_check_link'),
130
+
__('Check for updates', 'plugin-update-checker')
131
+
);
132
+
if ( !empty($linkText) ) {
133
+
/** @noinspection HtmlUnknownTarget */
134
+
$pluginMeta[] = sprintf('<a href="%s">%s</a>', esc_attr($linkUrl), $linkText);
135
+
}
136
+
}
137
+
return $pluginMeta;
138
+
}
139
+
140
+
protected function isMyPluginFile($pluginFile) {
141
+
return ($pluginFile == $this->updateChecker->pluginFile)
142
+
|| (!empty($this->updateChecker->muPluginFile) && ($pluginFile == $this->updateChecker->muPluginFile));
143
+
}
144
+
145
+
/**
146
+
* Check for updates when the user clicks the "Check for updates" link.
147
+
*
148
+
* @see self::addCheckForUpdatesLink()
149
+
*
150
+
* @return void
151
+
*/
152
+
public function handleManualCheck() {
153
+
$shouldCheck =
154
+
isset($_GET['puc_check_for_updates'], $_GET['puc_slug'])
155
+
&& $_GET['puc_slug'] == $this->updateChecker->slug
156
+
&& check_admin_referer('puc_check_for_updates');
157
+
158
+
if ( $shouldCheck ) {
159
+
$update = $this->updateChecker->checkForUpdates();
160
+
$status = ($update === null) ? 'no_update' : 'update_available';
161
+
$lastRequestApiErrors = $this->updateChecker->getLastRequestApiErrors();
162
+
163
+
if ( ($update === null) && !empty($lastRequestApiErrors) ) {
164
+
//Some errors are not critical. For example, if PUC tries to retrieve the readme.txt
165
+
//file from GitHub and gets a 404, that's an API error, but it doesn't prevent updates
166
+
//from working. Maybe the plugin simply doesn't have a readme.
167
+
//Let's only show important errors.
168
+
$foundCriticalErrors = false;
169
+
$questionableErrorCodes = array(
170
+
'puc-github-http-error',
171
+
'puc-gitlab-http-error',
172
+
'puc-bitbucket-http-error',
173
+
);
174
+
175
+
foreach ($lastRequestApiErrors as $item) {
176
+
$wpError = $item['error'];
177
+
/** @var \WP_Error $wpError */
178
+
if ( !in_array($wpError->get_error_code(), $questionableErrorCodes) ) {
179
+
$foundCriticalErrors = true;
180
+
break;
181
+
}
182
+
}
183
+
184
+
if ( $foundCriticalErrors ) {
185
+
$status = 'error';
186
+
set_site_transient($this->manualCheckErrorTransient, $lastRequestApiErrors, 60);
187
+
}
188
+
}
189
+
190
+
wp_redirect(add_query_arg(
191
+
array(
192
+
'puc_update_check_result' => $status,
193
+
'puc_slug' => $this->updateChecker->slug,
194
+
),
195
+
self_admin_url('plugins.php')
196
+
));
197
+
exit;
198
+
}
199
+
}
200
+
201
+
/**
202
+
* Display the results of a manual update check.
203
+
*
204
+
* @see self::handleManualCheck()
205
+
*
206
+
* You can change the result message by using the "puc_manual_check_message-$slug" filter.
207
+
*/
208
+
public function displayManualCheckResult() {
209
+
//phpcs:disable WordPress.Security.NonceVerification.Recommended -- Just displaying a message.
210
+
if ( isset($_GET['puc_update_check_result'], $_GET['puc_slug']) && ($_GET['puc_slug'] == $this->updateChecker->slug) ) {
211
+
$status = sanitize_key($_GET['puc_update_check_result']);
212
+
$title = $this->updateChecker->getInstalledPackage()->getPluginTitle();
213
+
$noticeClass = 'updated notice-success';
214
+
$details = '';
215
+
216
+
if ( $status == 'no_update' ) {
217
+
$message = sprintf(_x('The %s plugin is up to date.', 'the plugin title', 'plugin-update-checker'), $title);
218
+
} else if ( $status == 'update_available' ) {
219
+
$message = sprintf(_x('A new version of the %s plugin is available.', 'the plugin title', 'plugin-update-checker'), $title);
220
+
} else if ( $status === 'error' ) {
221
+
$message = sprintf(_x('Could not determine if updates are available for %s.', 'the plugin title', 'plugin-update-checker'), $title);
222
+
$noticeClass = 'error notice-error';
223
+
224
+
$details = $this->formatManualCheckErrors(get_site_transient($this->manualCheckErrorTransient));
225
+
delete_site_transient($this->manualCheckErrorTransient);
226
+
} else {
227
+
$message = sprintf(__('Unknown update checker status "%s"', 'plugin-update-checker'), $status);
228
+
$noticeClass = 'error notice-error';
229
+
}
230
+
231
+
$message = esc_html($message);
232
+
233
+
//Plugins can replace the message with their own, including adding HTML.
234
+
$message = apply_filters(
235
+
$this->updateChecker->getUniqueName('manual_check_message'),
236
+
$message,
237
+
$status
238
+
);
239
+
240
+
printf(
241
+
'<div class="notice %s is-dismissible"><p>%s</p>%s</div>',
242
+
esc_attr($noticeClass),
243
+
//phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Was escaped above, and plugins can add HTML.
244
+
$message,
245
+
//phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Contains HTML. Content should already be escaped.
246
+
$details
247
+
);
248
+
}
249
+
//phpcs:enable
250
+
}
251
+
252
+
/**
253
+
* Format the list of errors that were thrown during an update check.
254
+
*
255
+
* @param array $errors
256
+
* @return string
257
+
*/
258
+
protected function formatManualCheckErrors($errors) {
259
+
if ( empty($errors) ) {
260
+
return '';
261
+
}
262
+
$output = '';
263
+
264
+
$showAsList = count($errors) > 1;
265
+
if ( $showAsList ) {
266
+
$output .= '<ol>';
267
+
$formatString = '<li>%1$s <code>%2$s</code></li>';
268
+
} else {
269
+
$formatString = '<p>%1$s <code>%2$s</code></p>';
270
+
}
271
+
foreach ($errors as $item) {
272
+
$wpError = $item['error'];
273
+
/** @var \WP_Error $wpError */
274
+
$output .= sprintf(
275
+
$formatString,
276
+
esc_html($wpError->get_error_message()),
277
+
esc_html($wpError->get_error_code())
278
+
);
279
+
}
280
+
if ( $showAsList ) {
281
+
$output .= '</ol>';
282
+
}
283
+
284
+
return $output;
285
+
}
286
+
287
+
public function removeHooks() {
288
+
remove_action('admin_init', array($this, 'onAdminInit'));
289
+
remove_filter('plugin_row_meta', array($this, 'addViewDetailsLink'), 10);
290
+
remove_filter('plugin_row_meta', array($this, 'addCheckForUpdatesLink'), 10);
291
+
remove_action('all_admin_notices', array($this, 'displayManualCheckResult'));
292
+
}
293
+
}
294
+
endif;
295
+