PluginProbe
Listdom: AI-powered Business Directory with Classifieds Ads Listings / trunk
Listdom: AI-powered Business Directory with Classifieds Ads Listings vtrunk
6.0.0 5.9.0 5.8.1 5.8.0 5.7.0 5.6.0 trunk 1.0.0 1.0.1 1.0.2 1.1.0 1.1.1 1.2.0 1.2.1 1.3.0 1.3.1 1.4.0 1.5.0 1.6.0 1.6.1 1.6.2 1.6.3 1.7.0 1.8.0 1.9.0 All 75 releases
listdom / app / includes / admin.php

admin.php in Listdom: AI-powered Business Directory with Classifieds Ads Listings trunk, at app/includes/admin.php

482 lines 16.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 class LSD_Admin extends LSD_Base
4 {
5 private $settings;
6
7 public function __construct()
8 {
9 $this->settings = LSD_Options::settings();
10 }
11
12 public function init()
13 {
14 // Listdom Reports
15 $report = new LSD_Plugin_Report();
16 $report->init();
17
18 $payments = new LSD_Payments();
19
20 // Activation Redirect
21 add_action('admin_init', [$this, 'post_activate']);
22
23 // Notices
24 add_action('admin_notices', ['LSD_Flash', 'show']);
25 add_action('admin_notices', [$this, 'general_settings_roles_notice']);
26 add_action('admin_notices', [$this, 'loco_addon_translation_notice']);
27 add_action('user_new_form', [$this, 'user_profile_roles_notice']);
28 add_action('edit_user_profile', [$this, 'user_profile_roles_notice']);
29 add_action('show_user_profile', [$this, 'user_profile_roles_notice']);
30
31 // Database Tables
32 add_action('admin_init', function ()
33 {
34 // Create Table
35 if ((new LSD_Main())->is_db_update_required())
36 {
37 LSD_Plugin_Hooks::db_update();
38 }
39 });
40
41 // Block Admin Access
42 add_action('admin_init', [$this, 'block_admin']);
43 add_filter('show_admin_bar', [$this, 'show_admin_bar']);
44
45 // Admin Body Class
46 add_filter('admin_body_class', [$this, 'admin_body_class']);
47
48 // WordPress Dashboard Widget
49 add_action('wp_dashboard_setup', [$this, 'dashboard_widget']);
50
51 // Backend Header for post types
52 add_action('all_admin_notices', [$this, 'backend_post_type_header']);
53
54 // Backend Header for taxonomies
55 add_action('all_admin_notices', [$this, 'backend_taxonomy_header']);
56
57 // Show post states for Listdom system pages
58 add_filter('display_post_states', [$this, 'post_states'], 10, 2);
59
60 // WooCommerce product duration field used by Listdom addons.
61 add_action('woocommerce_product_options_general_product_data', [$payments, 'product_duration_field']);
62 add_action('woocommerce_process_product_meta', [$payments, 'save_product_duration'], 10, 1);
63 }
64
65 public function post_activate()
66 {
67 // No need to run
68 if (!get_option('lsd_activation_redirect', false) || wp_doing_ajax()) return;
69
70 // Delete the option to don't do it again
71 delete_option('lsd_activation_redirect');
72
73 // Uncategorized Category
74 LSD_Base::add_uncategorized();
75
76 // Redirect to Listdom Dashboard
77 wp_redirect(admin_url('/admin.php?page=' . LSD_Base::WELCOME_SLUG));
78 exit;
79 }
80
81 public function block_admin(): void
82 {
83 if (wp_doing_ajax() || !is_user_logged_in()) return;
84
85 // Redirect User to Home Page
86 if ($this->is_admin_blocked())
87 {
88 wp_redirect(get_home_url());
89 exit;
90 }
91 }
92
93 public function show_admin_bar(): bool
94 {
95 return is_user_logged_in() && $this->is_admin_allowed();
96 }
97
98 public function admin_body_class($classes): string
99 {
100 if (!is_admin()) return $classes;
101 if (!function_exists('get_current_screen')) return $classes;
102
103 $screen = get_current_screen();
104 if (!$screen || $screen->post_type !== LSD_Base::PTYPE_LISTING || $screen->base !== 'post') return $classes;
105
106 $action = isset($_GET['action']) ? sanitize_text_field(wp_unslash($_GET['action'])) : '';
107 $post_id = isset($_GET['post']) ? intval($_GET['post']) : 0;
108
109 if ($action !== 'edit' || $post_id <= 0) return $classes;
110 if (get_post_type($post_id) !== LSD_Base::PTYPE_LISTING) return $classes;
111
112 if (strpos($classes, 'lsd-edit-listing-page') === false) $classes .= ' lsd-edit-listing-page';
113 return $classes;
114 }
115
116 private function is_admin_allowed(): bool
117 {
118 return !$this->is_admin_blocked();
119 }
120
121 private function is_admin_blocked(): bool
122 {
123 if (!is_user_logged_in() || is_super_admin()) return false;
124
125 $roles = wp_get_current_user()->roles;
126 foreach ($roles as $role)
127 {
128 if (!isset($this->settings['block_admin_' . $role]) || !$this->settings['block_admin_' . $role]) return false;
129 }
130
131 return true;
132 }
133
134 public function general_settings_roles_notice(): void
135 {
136 if (!current_user_can('manage_options')) return;
137 if (!function_exists('get_current_screen')) return;
138
139 $screen = get_current_screen();
140 if (!$screen || $screen->id !== 'options-general') return;
141
142 ?>
143 <div class="notice notice-info">
144 <p>
145 <strong><?php esc_html_e('Listdom roles:', 'listdom'); ?></strong>
146 <?php echo esc_html($this->roles_notice_description()); ?>
147 </p>
148 </div>
149 <?php
150 }
151
152 public function loco_addon_translation_notice(): void
153 {
154 if (!is_admin()) return;
155
156 $page = isset($_GET['page']) ? sanitize_key(wp_unslash($_GET['page'])) : '';
157 if (strpos($page, 'loco') !== 0) return;
158
159 $domain = isset($_GET['domain']) ? sanitize_key(wp_unslash($_GET['domain'])) : '';
160 $bundle_domain = '';
161 if (isset($_GET['bundle']))
162 {
163 $bundle = sanitize_text_field(wp_unslash($_GET['bundle']));
164 $parts = explode('/', trim($bundle, '/'));
165
166 foreach ($parts as $part)
167 {
168 $part = sanitize_key($part);
169 if (strpos($part, 'listdom-') === 0)
170 {
171 $bundle_domain = $part;
172 break;
173 }
174 }
175 }
176
177 if ($bundle_domain) $domain = $bundle_domain;
178
179 if (!$domain || strpos($domain, 'listdom-') !== 0) return;
180
181 $listdom_url = add_query_arg([
182 'page' => 'loco-plugin',
183 'bundle' => 'listdom/listdom.php',
184 'action' => 'view',
185 ], admin_url('admin.php'));
186
187 ?>
188 <div class="lsd-ask-review-wrapper notice notice-info is-dismissible lsd-flex lsd-flex-row lsd-flex-content-start lsd-flex-items-start">
189 <div class="lsd-flex lsd-flex-col lsd-gap-3 lsd-flex-items-start">
190 <h3 class="lsd-m-0 lsd-admin-title">
191 <?php esc_html_e('Listdom translation reminder', 'listdom'); ?>
192 </h3>
193 <p class="lsd-m-0">
194 <?php
195 echo wp_kses_post(sprintf(
196 /* translators: %s: The Listdom product name. */
197 __('Some strings used by this addon are provided by Listdom core. To fully translate the addon, please translate the %s strings as well.', 'listdom'),
198 '<strong>' . esc_html__('Listdom', 'listdom') . '</strong>'
199 ));
200 ?>
201 </p>
202 <div class="lsd-ask-review-buttons lsd-flex lsd-flex-row lsd-gap-3 lsd-mt-3 lsd-flex-items-center">
203 <a class="lsd-primary-button" href="<?php echo esc_url($listdom_url); ?>">
204 <span><?php esc_html_e('Translate Listdom core', 'listdom'); ?></span>
205 <i class="webilia-icon wbli-right-arrow"></i>
206 </a>
207 </div>
208 </div>
209 </div>
210 <?php
211 }
212
213 public function user_profile_roles_notice($user): void
214 {
215 if (!current_user_can('promote_users')) return;
216
217 ?>
218 <tr class="form-field">
219 <th></th>
220 <td>
221 <div class="notice notice-info">
222 <p class="description">
223 <strong><?php esc_html_e('Listdom roles:', 'listdom'); ?></strong>
224 <?php echo esc_html($this->roles_notice_description()); ?>
225 </p>
226 </div>
227 </td>
228 </tr>
229 <?php
230 }
231
232 private function roles_notice_description(): string
233 {
234 return __('Listdom adds two new WordPress roles. Listdom Authors can create listings and manage their own submissions, while Listdom Publishers can publish listings directly and manage published ones.', 'listdom');
235 }
236
237 public function dashboard_widget(): void
238 {
239 wp_add_dashboard_widget(
240 'lsd_news_updates',
241 esc_html__('Listdom', 'listdom'),
242 [$this, 'dashboard_widget_content']
243 );
244 }
245
246 public function dashboard_widget_content(): void
247 {
248 if (!function_exists('fetch_feed')) include_once ABSPATH . WPINC . '/feed.php';
249
250 $rss = fetch_feed('https://listdom.net/blog/feed/');
251 $items = [];
252 $error = null;
253
254 if (is_wp_error($rss)) $error = esc_html__('Unable to retrieve news.', 'listdom');
255 else
256 {
257 $max = $rss->get_item_quantity(5);
258 $items = $rss->get_items(0, $max);
259
260 if (!$items) $error = esc_html__('No news items found.', 'listdom');
261 }
262
263 $this->include_html_file('plugin/dashboard-widget.php', [
264 'parameters' => [
265 'items' => $items,
266 'error' => $error,
267 ],
268 ]);
269 }
270
271 public function backend_post_types(): array
272 {
273 $post_types = [
274 LSD_Base::PTYPE_LISTING,
275 LSD_Base::PTYPE_SHORTCODE,
276 LSD_Base::PTYPE_TEMPLATE,
277 LSD_Base::PTYPE_SEARCH,
278 LSD_Base::PTYPE_NOTIFICATION,
279 ];
280
281 return apply_filters('lsd_backend_header_post_types', $post_types);
282 }
283
284 public function backend_post_type_header()
285 {
286 if (!is_admin()) return;
287
288 $screen = get_current_screen();
289 if (!$screen || !in_array($screen->post_type, $this->backend_post_types())) return;
290
291 if (!in_array($screen->base, ['edit', 'post'])) return;
292
293 $obj = get_post_type_object($screen->post_type);
294 if (!$obj) return;
295
296 $add_button = '';
297 if (current_user_can($obj->cap->create_posts ?? 'edit_posts'))
298 {
299 $button_label = esc_html($obj->labels->add_new);
300
301 if ($screen->post_type === LSD_Base::PTYPE_TEMPLATE && $screen->base === 'edit')
302 {
303 $add_button = ' <a href="#" class="lsd-primary-button lsd-open-template-modal" data-modal-target="lsd-template-modal">' . $button_label . '</a>';
304 }
305 else if ($screen->post_type !== LSD_Base::PTYPE_TEMPLATE)
306 {
307 $add_button = ' <a href="' . esc_url(admin_url('post-new.php?post_type=' . $screen->post_type)) . '" class="lsd-primary-button">' . $button_label . '</a>';
308 }
309 }
310
311 if ($screen->base === 'edit')
312 {
313 $title = $obj->labels->name;
314 $title .= $add_button;
315
316 $url = admin_url('edit.php?post_type=' . $screen->post_type);
317 }
318 else
319 {
320 if (isset($_GET['action']) && $_GET['action'] === 'edit')
321 {
322 $title = $obj->labels->edit_item;
323 $title .= $add_button;
324
325 $url = admin_url('post.php?post=' . (isset($_GET['post']) ? intval($_GET['post']) : 0) . '&action=edit');
326 }
327 else
328 {
329 $title = $obj->labels->add_new_item;
330 $url = admin_url('post-new.php?post_type=' . $screen->post_type);
331 }
332 }
333
334 $menus = apply_filters('lsd_post_type_header_menus', [], $screen);
335
336 $this->include_html_file('plugin/post-type-header.php', [
337 'parameters' => [
338 'title' => $title,
339 'url' => $url,
340 'menus' => $menus,
341 'notice' => LSD_Admin::get_header_notice(),
342 ],
343 ]);
344 }
345
346 public function backend_taxonomies(): array
347 {
348 $taxonomies = LSD_Base::taxonomies();
349 $taxonomies[] = LSD_Base::TAX_ATTRIBUTE;
350
351 return apply_filters('lsd_backend_header_taxonomies', $taxonomies);
352 }
353
354 public function backend_taxonomy_header()
355 {
356 if (!is_admin()) return;
357
358 $screen = get_current_screen();
359 if (!$screen || !isset($screen->taxonomy) || !in_array($screen->taxonomy, $this->backend_taxonomies())) return;
360
361 if (!in_array($screen->base, ['edit-tags', 'term'])) return;
362
363 $obj = get_taxonomy($screen->taxonomy);
364 if (!$obj) return;
365
366 if ($screen->base === 'edit-tags')
367 {
368 $title = $obj->labels->name;
369 $url = admin_url('edit-tags.php?taxonomy=' . $screen->taxonomy . '&post_type=' . $screen->post_type);
370 }
371 else
372 {
373 if (isset($_GET['tag_ID']))
374 {
375 $title = $obj->labels->edit_item;
376 $url = admin_url('term.php?taxonomy=' . $screen->taxonomy . '&tag_ID=' . intval($_GET['tag_ID']) . '&post_type=' . $screen->post_type);
377 }
378 else
379 {
380 $title = $obj->labels->add_new_item;
381 $url = admin_url('term-new.php?taxonomy=' . $screen->taxonomy . '&post_type=' . $screen->post_type);
382 }
383 }
384
385 $menus = apply_filters('lsd_taxonomy_header_menus', [], $screen);
386
387 $this->include_html_file('plugin/taxonomy-header.php', [
388 'parameters' => [
389 'title' => $title,
390 'url' => $url,
391 'show_links' => $screen->base === 'edit-tags',
392 'menus' => $menus,
393 ],
394 ]);
395 }
396
397 private static function get_header_notice(): string
398 {
399 $screen = get_current_screen();
400
401 $notice = '';
402 if (
403 $screen->post_type === LSD_Base::PTYPE_RECURRING &&
404 $screen->base === 'edit' &&
405 LSD_Base::isLite()
406 )
407 {
408 $notice = LSD_Base::alert(
409 LSD_Base::missFeatureMessage(esc_html__('Recurring Payments', 'listdom')),
410 'warning'
411 );
412 }
413
414 return apply_filters('lsd_backend_header_notice', $notice);
415 }
416
417 public function post_states($states, $post)
418 {
419 if ($post->post_type !== 'page') return $states;
420
421 $pages = $this->post_state_pages();
422 foreach ($pages as $id => $label)
423 {
424 $id = (int) $id;
425 if ($id && $post->ID === $id) $states['listdom_' . $id] = $label;
426 }
427
428 return $states;
429 }
430
431 public function post_state_pages(): array
432 {
433 $cached = get_transient('lsd_post_state_pages');
434 if (is_array($cached)) return $cached;
435
436 $settings = LSD_Options::settings();
437 $auth = LSD_Options::auth();
438 $payments = LSD_Options::payments();
439
440 $pages = [
441 $settings['submission_page'] ?? 0 => esc_html__('Listdom Dashboard Page', 'listdom'),
442 $settings['add_listing_page'] ?? 0 => esc_html__('Listdom Add Listing Page', 'listdom'),
443 $auth['auth']['login_page'] ?? 0 => esc_html__('Listdom Login Page', 'listdom'),
444 $auth['auth']['register_page'] ?? 0 => esc_html__('Listdom Register Page', 'listdom'),
445 $auth['auth']['forgot_password_page'] ?? 0 => esc_html__('Listdom Forgot Password Page', 'listdom'),
446 $auth['profile']['page'] ?? 0 => esc_html__('Listdom Profile Page', 'listdom'),
447 $auth['login']['redirect'] ?? 0 => esc_html__('Listdom Login Redirect Page', 'listdom'),
448 $auth['register']['redirect'] ?? 0 => esc_html__('Listdom Register Redirect Page', 'listdom'),
449 $auth['forgot_password']['redirect'] ?? 0 => esc_html__('Listdom Forgot Password Redirect Page', 'listdom'),
450 $auth['logout']['redirect'] ?? 0 => esc_html__('Listdom Logout Redirect Page', 'listdom'),
451 $auth['account']['redirect'] ?? 0 => esc_html__('Listdom Account Redirect Page', 'listdom'),
452 $payments['checkout_page'] ?? 0 => esc_html__('Listdom Checkout Page', 'listdom'),
453 $payments['appreciation_page'] ?? 0 => esc_html__('Listdom Payment Appreciation Page', 'listdom'),
454 ];
455
456 // Include search form results pages
457 $search_forms = get_posts([
458 'post_type' => LSD_Base::PTYPE_SEARCH,
459 'posts_per_page' => 100,
460 'post_status' => 'publish',
461 ]);
462
463 foreach ($search_forms as $search)
464 {
465 $form = get_post_meta($search->ID, 'lsd_form', true);
466 if (is_array($form) && isset($form['page']) && $form['page'])
467 {
468 $pages[(int) $form['page']] = sprintf(
469 /* translators: %s: Search form title. */
470 esc_html__('Search Results (%s)', 'listdom'),
471 $search->post_title
472 );
473 }
474 }
475
476 $pages = apply_filters('lsd_post_state_pages', $pages);
477 set_transient('lsd_post_state_pages', $pages, HOUR_IN_SECONDS);
478
479 return $pages;
480 }
481 }
482