PluginProbe
Site Reviews / trunk
Site Reviews vtrunk
8.3.1 8.3.0 8.2.2 8.2.1 8.2.0 8.1.0 8.0.13 8.0.12 8.0.11 trunk 1.2.2 2.17.1 3.5.4 4.7.0 5.25.1 6.11.8 7.0.10 7.0.11 7.0.12 7.0.13 7.0.14 7.0.15 7.0.16 7.0.17 7.0.18 All 54 releases
site-reviews / plugin / Controllers / AdminController.php

AdminController.php in Site Reviews trunk, at plugin/Controllers/AdminController.php

375 lines 12.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace GeminiLabs\SiteReviews\Controllers;
4
5 use GeminiLabs\SiteReviews\Commands\ApproveReview;
6 use GeminiLabs\SiteReviews\Commands\EnqueueAdminAssets;
7 use GeminiLabs\SiteReviews\Commands\ExportRatings;
8 use GeminiLabs\SiteReviews\Commands\ImportRatings;
9 use GeminiLabs\SiteReviews\Commands\TogglePinned;
10 use GeminiLabs\SiteReviews\Commands\ToggleStatus;
11 use GeminiLabs\SiteReviews\Database;
12 use GeminiLabs\SiteReviews\Defaults\ColumnFilterbyDefaults;
13 use GeminiLabs\SiteReviews\Helpers\Arr;
14 use GeminiLabs\SiteReviews\Helpers\Svg;
15 use GeminiLabs\SiteReviews\Install;
16 use GeminiLabs\SiteReviews\License;
17 use GeminiLabs\SiteReviews\Modules\Html\Builder;
18 use GeminiLabs\SiteReviews\Modules\Migrate;
19 use GeminiLabs\SiteReviews\Modules\Notice;
20 use GeminiLabs\SiteReviews\Modules\Queue;
21 use GeminiLabs\SiteReviews\Modules\Sanitizer;
22 use GeminiLabs\SiteReviews\Modules\Translation;
23 use GeminiLabs\SiteReviews\Request;
24
25 class AdminController extends AbstractController
26 {
27 /**
28 * @action site-reviews/route/get/admin/approve
29 */
30 public function approveReview(Request $request): void
31 {
32 $postId = Arr::get($request->data, 0);
33 $review = glsr_get_review($postId);
34 if ($review->isValid()) {
35 $command = $this->execute(new ApproveReview($review));
36 if ($command->successful()) {
37 glsr(Notice::class)->store(); // because of the redirect
38 }
39 }
40 wp_redirect(glsr_admin_url());
41 glsr_exit();
42 }
43
44 /**
45 * @action in_plugin_update_message-{glsr()->basename}
46 */
47 public function displayUpdateWarning(array $data): void
48 {
49 $version = Arr::get($data, 'new_version');
50 $parts = explode('.', $version);
51 $newVersion = Arr::getAs('int', $parts, 0, 0);
52 if ($newVersion > (int) glsr()->version('major')) {
53 glsr()->render('views/partials/update-warning');
54 }
55 }
56
57 /**
58 * @action admin_enqueue_scripts
59 */
60 public function enqueueAssets(): void
61 {
62 $this->execute(new EnqueueAdminAssets());
63 }
64
65 /**
66 * @filter plugin_action_links_site-reviews/site-reviews.php
67 */
68 public function filterActionLinks(array $links): array
69 {
70 $actions = [];
71 if (glsr()->hasPermission('settings')) {
72 $actions['settings'] = glsr_admin_link('settings', _x('Settings', 'admin-text', 'site-reviews'));
73 }
74 return array_merge($actions, $links);
75 }
76
77 /**
78 * @filter export_args
79 */
80 public function filterExportArgs(array $args): array
81 {
82 if (in_array(Arr::get($args, 'content'), ['all', glsr()->post_type])) {
83 $this->execute(new ExportRatings(glsr()->args($args)));
84 }
85 return $args;
86 }
87
88 /**
89 * @filter plugin_row_meta
90 */
91 public function filterRowMeta(array $links, string $file): array
92 {
93 if ($file !== glsr()->basename) {
94 return $links;
95 }
96 $actions = [];
97 if (glsr()->hasPermission('documentation')) {
98 $actions['documentation'] = glsr_admin_link('documentation', _x('Documentation', 'admin-text', 'site-reviews'));
99 }
100 $actions['support'] = glsr(Builder::class)->a([
101 'aria-label' => esc_attr_x('Visit community forums', 'admin-text', 'site-reviews'),
102 'href' => esc_url('https://wordpress.org/support/plugin/site-reviews'),
103 'text' => esc_html_x('Community support', 'admin-text', 'site-reviews'),
104 ]);
105 return array_merge($links, $actions);
106 }
107
108 /**
109 * @filter screen_options_show_submit
110 */
111 public function filterScreenOptionsButton(bool $showButton): bool
112 {
113 global $post_type_object, $title, $typenow;
114 if (!str_starts_with($typenow, glsr()->post_type)) {
115 return $showButton;
116 }
117 $submit = get_submit_button(_x('Apply', 'admin-text', 'site-reviews'), 'primary', 'screen-options-apply', false);
118 $close = glsr(Builder::class)->button([
119 'aria-controls' => 'screen-options-wrap',
120 'class' => 'button glsr-screen-meta-toggle',
121 'text' => _x('Close Panel', 'admin-text', 'site-reviews'),
122 'type' => 'button',
123 ]);
124 echo glsr(Builder::class)->p([
125 'style' => 'display:inline-flex;gap:6px;',
126 'text' => $submit.$close,
127 ]);
128 return false; // don't display the default submit button
129 }
130
131 /**
132 * @filter mce_external_plugins
133 */
134 public function filterTinymcePlugins(array $plugins): array
135 {
136 if (glsr()->can('edit_posts')) {
137 $plugins['glsr_shortcode'] = glsr()->url('assets/scripts/mce-plugin.js');
138 }
139 return $plugins;
140 }
141
142 /**
143 * @action admin_init
144 */
145 public function onActivation(): void
146 {
147 if (empty(get_option(glsr()->prefix.'activated'))) {
148 glsr(Install::class)->run(); // this hard-resets role permissions
149 glsr(Migrate::class)->run();
150 update_option(glsr()->prefix.'activated', true);
151 glsr()->action('activated');
152 }
153 }
154
155 /**
156 * @action deactivate_{glsr()->basename}
157 */
158 public function onDeactivation(bool $isNetworkDeactivation): void
159 {
160 glsr(Install::class)->deactivate($isNetworkDeactivation);
161 }
162
163 /**
164 * @action import_end
165 */
166 public function onImportEnd(): void
167 {
168 $this->execute(new ImportRatings());
169 }
170
171 /**
172 * @action admin_head
173 */
174 public function printInlineStyle(): void
175 {
176 $rules = [];
177 $rules[] = '@media only screen and (max-width: 960px) {'.
178 '.auto-fold #adminmenu .menu-icon-site-review div.wp-menu-image {'.
179 'height: 34px;'.
180 '}'.
181 '}';
182 $rules[] = 'li:is(.submenu_glsr-settings,.submenu_glsr-premium)::before {'.
183 'background: hsla(0,0%,100%,.2);'.
184 'content: \'\';'.
185 'display: block;'.
186 'height: 1px;'.
187 'margin: 5px 0;'.
188 'width: 100%;'.
189 '}';
190 if (!glsr(License::class)->isPremium()) {
191 $rules[] = 'li.submenu_glsr-premium a {'.
192 'color: #e8ff5e !important;'. // --glsr-primary
193 '}';
194 }
195 printf('<style type="text/css">%s</style>', implode('', $rules));
196 }
197
198 /**
199 * @action in_admin_header
200 */
201 public function renderPageHeader(): void
202 {
203 global $post_type_object, $title;
204 if (!$this->isAdminScreen()) {
205 return;
206 }
207 $buttons = [];
208 $screen = glsr_current_screen();
209 if (glsr()->post_type === $screen->post_type && !glsr(License::class)->isPremium()) {
210 $buttons['premium'] = [
211 'class' => 'components-button is-primary glsr-try-premium',
212 'href' => glsr_premium_url('site-reviews-premium'),
213 'target' => '_blank',
214 'text' => _x('Try Premium', 'admin-text', 'site-reviews'),
215 ];
216 }
217 if (glsr()->can('import') && 'edit' === $screen->base) {
218 $buttons['import'] = [
219 'class' => 'components-button is-secondary',
220 'data-expand' => '#tools-import-reviews',
221 'href' => glsr_admin_url('tools', 'general'),
222 'text' => _x('Import', 'admin-text', 'site-reviews'),
223 ];
224 }
225 if (glsr()->can('create_posts') && in_array($screen->base, ['edit', 'post'])) {
226 $buttons['new'] = [
227 'class' => 'components-button is-secondary glsr-new-post',
228 'data-new' => '',
229 'href' => admin_url("post-new.php?post_type={$screen->post_type}"),
230 'text' => Arr::get($post_type_object, 'labels.add_new'),
231 ];
232 }
233 $buttons = glsr()->filterArray('page-header/buttons', $buttons);
234 glsr()->render('views/partials/page-header', [
235 'buttons' => $buttons,
236 'hasScreenOptions' => in_array($screen->base, ['edit', 'edit-tags', 'post']),
237 'logo' => Svg::get('assets/images/icon.svg', ['width' => 44]),
238 'title' => esc_html($title),
239 ]);
240 }
241
242 /**
243 * @action admin_init
244 */
245 public function scheduleMigration(): void
246 {
247 if (!$this->isAdminScreen()) {
248 return;
249 }
250 if (!glsr(Migrate::class)->canQueue()) {
251 return;
252 }
253 if (!glsr(Migrate::class)->isMigrationNeeded() && !glsr(Database::class)->isMigrationNeeded()) {
254 return;
255 }
256 glsr(Queue::class)->once(time() + \MINUTE_IN_SECONDS, 'queue/migration');
257 }
258
259 /**
260 * @action site-reviews/route/ajax/filter-assigned_post
261 */
262 public function searchAssignedPostsAjax(Request $request): void
263 {
264 $search = glsr(Sanitizer::class)->sanitizeText($request->search);
265 $results = glsr(Database::class)->searchAssignedPosts($search)->results();
266 wp_send_json_success([
267 'items' => $results,
268 ]);
269 }
270
271 /**
272 * @action site-reviews/route/ajax/filter-assigned_user
273 */
274 public function searchAssignedUsersAjax(Request $request): void
275 {
276 $search = glsr(Sanitizer::class)->sanitizeText($request->search);
277 $results = glsr(Database::class)->searchAssignedUsers($search)->results();
278 array_walk($results, function ($user) {
279 $user->name = glsr(Sanitizer::class)->sanitizeUserName($user->name, $user->nickname);
280 });
281 wp_send_json_success([
282 'items' => $results,
283 ]);
284 }
285
286 /**
287 * @action site-reviews/route/ajax/filter-author
288 */
289 public function searchAuthorsAjax(Request $request): void
290 {
291 $search = glsr(Sanitizer::class)->sanitizeText($request->search);
292 $results = glsr(Database::class)->searchUsers($search)->results();
293 array_walk($results, function ($user) {
294 $user->name = glsr(Sanitizer::class)->sanitizeUserName($user->name, $user->nickname);
295 });
296 wp_send_json_success([
297 'items' => $results,
298 ]);
299 }
300
301 /**
302 * @action site-reviews/route/ajax/search-posts
303 */
304 public function searchPostsAjax(Request $request): void
305 {
306 $search = glsr(Sanitizer::class)->sanitizeText($request->search);
307 $results = glsr(Database::class)->searchPosts($search)->render();
308 wp_send_json_success([
309 'empty' => '<div>'._x('Nothing found.', 'admin-text', 'site-reviews').'</div>',
310 'items' => $results,
311 ]);
312 }
313
314 /**
315 * @action site-reviews/route/ajax/search-strings
316 */
317 public function searchStringsAjax(Request $request): void
318 {
319 $search = glsr(Sanitizer::class)->sanitizeText($request->search);
320 $exclude = Arr::consolidate($request->exclude);
321 $results = glsr(Translation::class)
322 ->search($search)
323 ->exclude()
324 ->exclude($exclude)
325 ->renderResults();
326 wp_send_json_success([
327 'empty' => '<div>'._x('Nothing found.', 'admin-text', 'site-reviews').'</div>',
328 'items' => $results,
329 ]);
330 }
331
332 /**
333 * @action site-reviews/route/ajax/search-users
334 */
335 public function searchUsersAjax(Request $request): void
336 {
337 $search = glsr(Sanitizer::class)->sanitizeText($request->search);
338 $results = glsr(Database::class)->searchUsers($search)->render();
339 wp_send_json_success([
340 'empty' => '<div>'._x('Nothing found.', 'admin-text', 'site-reviews').'</div>',
341 'items' => $results,
342 ]);
343 }
344
345 /**
346 * @action site-reviews/route/ajax/toggle-filters
347 */
348 public function toggleFiltersAjax(Request $request): void
349 {
350 if ($userId = get_current_user_id()) {
351 $filters = array_keys(glsr(ColumnFilterbyDefaults::class)->defaults());
352 $enabled = glsr(Sanitizer::class)->sanitizeArrayString($request->enabled);
353 $enabled = array_intersect($filters, $enabled);
354 update_user_meta($userId, 'edit_'.glsr()->post_type.'_filters', $enabled);
355 }
356 wp_send_json_success();
357 }
358
359 /**
360 * @action site-reviews/route/ajax/toggle-pinned
361 */
362 public function togglePinnedAjax(Request $request): void
363 {
364 $this->execute(new TogglePinned($request))->sendJsonResponse();
365 }
366
367 /**
368 * @action site-reviews/route/ajax/toggle-status
369 */
370 public function toggleStatusAjax(Request $request): void
371 {
372 $this->execute(new ToggleStatus($request))->sendJsonResponse();
373 }
374 }
375