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.
Zur Liste
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 +