PluginProbe
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards / 5.5.83
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards v5.5.83
5.5.83 5.5.82 5.5.81 5.5.80 5.5.79 5.5.77 5.5.76 5.5.75 5.5.73 5.5.72 5.5.22 5.5.23 5.5.29 5.5.3 5.5.31 5.5.32 5.5.34 5.5.35 5.5.36 5.5.37 5.5.4 5.5.40 5.5.41 5.5.42 5.5.43 All 159 releases
wp-data-access / WPDataProjects / WPDP.php

WPDP.php in WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards 5.5.83, at WPDataProjects/WPDP.php

515 lines 22.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Suppress "error - 0 - No summary was found for this file" on phpdoc generation
5 *
6 * @package WPDataProjects
7 */
8 namespace WPDataProjects;
9
10 use WPDataAccess\Plugin_Table_Models\WPDP_Page_Model;
11 use WPDataAccess\Plugin_Table_Models\WPDP_Project_Model;
12 use WPDataAccess\Plugin_Table_Models\WPDP_Project_Design_Table_Model;
13 use WPDataAccess\Utilities\WPDA_Repository;
14 use WPDataAccess\WPDA;
15 use WPDataProjects\Project\WPDP_Project_Project_View;
16 use WPDataProjects\Project\WPDP_Project_Table_View;
17 use WPDataAccess\Dashboard\WPDA_Dashboard;
18 /**
19 * Class WPDP
20 *
21 * Implements Data Projects and Project Templates pages:
22 * (1) WPDP_Project_Project_View - To manage Data Projects
23 * (2) WPDP_Project_Table_View - To manage Table Options
24 *
25 * @author Peter Schulz
26 * @since 2.0.0
27 */
28 class WPDP {
29 /**
30 * Menu slug of Data Project page
31 */
32 const PAGE_MAIN = 'wpda_wpdp';
33
34 /**
35 * Menu slug of Project Templates page
36 */
37 const PAGE_TEMPLATES = 'wpda_templates';
38
39 /**
40 * Menu slug taken from URL
41 *
42 * @var null
43 */
44 protected $page = null;
45
46 /**
47 * Templates Page title
48 */
49 protected $projects_page_title;
50
51 /**
52 * Projects Page title
53 */
54 protected $templates_page_title;
55
56 /**
57 * Data Projects menu
58 *
59 * @var
60 */
61 protected $wpdp_projects_menu;
62
63 /**
64 * Handle to Data Projects view
65 *
66 * @var
67 */
68 protected $wpdp_projects_view;
69
70 /**
71 * Handle to Project Templates view
72 *
73 * @var
74 */
75 protected $wpdp_templates_view;
76
77 /**
78 * Used for static pages
79 *
80 * @var
81 */
82 protected $wpdp_projects_content;
83
84 /**
85 * Array containing all project pages
86 *
87 * @var
88 */
89 protected $wpdp_project_menus;
90
91 /**
92 * Array containing all project page views
93 *
94 * @var
95 */
96 protected $wpdp_project_views;
97
98 protected $wp_admin_toolbar = array();
99
100 protected $main_menu_slug = null;
101
102 /**
103 * WPDP constructor
104 */
105 public function __construct( $main_menu_slug = null ) {
106 // phpcs:disable WordPress.Security.NonceVerification.Recommended -- verfication in main app
107 if ( isset( $_REQUEST['page'] ) ) {
108 $this->page = sanitize_text_field( wp_unslash( $_REQUEST['page'] ) );
109 }
110 // phpcs:enable WordPress.Security.NonceVerification.Recommended
111 $this->main_menu_slug = $main_menu_slug;
112 $this->projects_page_title = 'Data Projects';
113 $this->templates_page_title = 'Project Templates';
114 }
115
116 /**
117 * Add menu items
118 *
119 * Adds Data Projects tool to dashboard menu.
120 */
121 public function add_menu_items() {
122 if ( WPDA::current_user_is_admin() ) {
123 if ( 'on' === WPDA::get_option( WPDA::OPTION_PLUGIN_HIDE_ADMIN_MENU ) ) {
124 // Hide admin menu
125 return;
126 }
127 global $wpdb;
128 // Add Data Projects menu
129 $this->wpdp_projects_menu = add_submenu_page(
130 $this->main_menu_slug,
131 'Form Builder',
132 'Form Builder',
133 'manage_options',
134 self::PAGE_MAIN,
135 [$this, 'data_projects_page']
136 );
137 if ( $this->page === self::PAGE_MAIN ) {
138 $this->wpdp_projects_view = new WPDP_Project_Project_View([
139 'page_hook_suffix' => $this->wpdp_projects_menu,
140 'table_name' => $wpdb->prefix . 'wpda_project',
141 'edit_form_class' => 'WPDataProjects\\Project\\WPDP_Project_Project_Form',
142 'list_table_class' => 'WPDataProjects\\Project\\WPDP_Project_Project_List',
143 'title' => $this->projects_page_title,
144 ]);
145 }
146 // Add Project Templates menu
147 $this->wpdp_projects_menu = add_submenu_page(
148 $this->main_menu_slug,
149 'Form Templates',
150 'Form Templates',
151 'manage_options',
152 self::PAGE_TEMPLATES,
153 [$this, 'project_templates_page']
154 );
155 if ( $this->page === self::PAGE_TEMPLATES ) {
156 $this->wpdp_templates_view = new WPDP_Project_Table_View([
157 'page_hook_suffix' => $this->wpdp_projects_menu,
158 'table_name' => $wpdb->prefix . 'wpda_project_table',
159 'list_table_class' => 'WPDataProjects\\Project\\WPDP_Project_Table_List',
160 'edit_form_class' => 'WPDataProjects\\Project\\WPDP_Project_Table_Form',
161 'title' => $this->templates_page_title,
162 'subtitle' => '',
163 ]);
164 }
165 }
166 }
167
168 /**
169 * Implementation of the Data Projects page
170 */
171 public function data_projects_page() {
172 WPDA_Dashboard::add_dashboard();
173 // Check for repository tables to prevent dashboard errors.
174 if ( WPDP_Project_Design_Table_Model::table_exists() && WPDP_Project_Model::table_exists() ) {
175 $this->wpdp_projects_view->show();
176 } else {
177 $this->data_projects_page_not_found();
178 }
179 }
180
181 /**
182 * Implementation of the Project Templates page
183 */
184 public function project_templates_page() {
185 WPDA_Dashboard::add_dashboard();
186 // Check for repository tables to prevent dashboard errors.
187 if ( WPDP_Page_Model::table_exists() ) {
188 $this->wpdp_templates_view->show();
189 } else {
190 $this->data_projects_page_not_found();
191 }
192 }
193
194 /**
195 * Data Designer repository table not found
196 */
197 public function data_projects_page_not_found() {
198 $wpda_repository = new WPDA_Repository();
199 $wpda_repository->inform_user();
200 ?>
201 <div class="wrap">
202 <h1 class="wp-heading-inline">
203 <span><?php
204 echo esc_attr( $this->projects_page_title );
205 ?></span>
206 <a href="<?php
207 echo 'https://docs.legacy.wpdataaccess.com/docs/data-projects/';
208 ?>" target="_blank">
209 <span class="dashicons dashicons-editor-help"
210 style="text-decoration:none;vertical-align:top;font-size:30px;">
211 </span></a>
212 </h1>
213 <p>
214 <?php
215 esc_html_e( 'ERROR: Repository table(s) not found!', 'wp-data-access' );
216 ?>
217 </p>
218 </div>
219 <?php
220 }
221
222 public function project_templates_page_not_found() {
223 $wpda_repository = new WPDA_Repository();
224 $wpda_repository->inform_user();
225 ?>
226 <div class="wrap">
227 <h1 class="wp-heading-inline">
228 <span><?php
229 echo esc_attr( $this->projects_page_title );
230 ?></span>
231 <a href="<?php
232 echo 'https://docs.legacy.wpdataaccess.com/docs/project-templates/';
233 ?>" target="_blank">
234 <span class="dashicons dashicons-editor-help"
235 style="text-decoration:none;vertical-align:top;font-size:30px;">
236 </span></a>
237 </h1>
238 <p>
239 <?php
240 esc_html_e( 'ERROR: Repository table(s) not found!', 'wp-data-access' );
241 ?>
242 </p>
243 </div>
244 <?php
245 }
246
247 /**
248 * Add projects to menu
249 *
250 * Menu items are taken from active projects. Project pages marked as "add to menu" are added to the
251 * dashboard menu.
252 */
253 public function add_projects() {
254 if ( !is_admin() && 'on' !== WPDA::get_option( WPDA::OPTION_FE_ADD_PROJECTS_TO_TOOLBAR ) ) {
255 return;
256 }
257 // Add project Menus.
258 global $wpdb;
259 $project_project_table_name = $wpdb->prefix . 'wpda_project';
260 $project_page_table_name = $wpdb->prefix . 'wpda_project_page';
261 $query_projects = "select * from {$project_project_table_name} where add_to_menu = 'Yes' order by project_sequence";
262 // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter -- plugin table
263 $projects = $wpdb->get_results( $query_projects, 'ARRAY_A' );
264 // phpcs:enable WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
265 if ( count( $projects ) > 0 ) {
266 // phpcs:ignore -- 8.1 proof
267 // Check for repository tables to prevent dashboard errors.
268 if ( !WPDP_Project_Design_Table_Model::table_exists() || !WPDP_Page_Model::table_exists() ) {
269 return;
270 }
271 }
272 foreach ( $projects as $project ) {
273 if ( null === $project['menu_name'] || '' === trim( $project['menu_name'] ) ) {
274 $menu_name = 'UNNAMED';
275 } else {
276 $menu_name = $project['menu_name'];
277 }
278 $user_roles = WPDA::get_current_user_roles();
279 if ( false === $user_roles ) {
280 // Cannot determine the user role(s). Not able to show project menus.
281 break;
282 }
283 // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- plugin table
284 $query_pages = $wpdb->prepare( " select * from {$project_page_table_name} " . " where project_id = %d " . " and add_to_menu = 'Yes' " . " order by page_sequence", [$project['project_id']] );
285 // phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
286 // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
287 $pages = $wpdb->get_results( $query_pages, 'ARRAY_A' );
288 // phpcs:enable WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
289 $project_menu_shown = false;
290 foreach ( $pages as $page ) {
291 $user_has_role = false;
292 if ( '' === $page['page_role'] || null === $page['page_role'] ) {
293 $user_has_role = in_array( 'administrator', $user_roles );
294 // phpcs:ignore -- 8.1 proof
295 } else {
296 $user_role_array = explode( ',', $page['page_role'] );
297 // phpcs:ignore -- 8.1 proof
298 foreach ( $user_role_array as $user_role_array_item ) {
299 $user_has_role = in_array( $user_role_array_item, $user_roles );
300 // phpcs:ignore -- 8.1 proof
301 if ( $user_has_role ) {
302 break;
303 }
304 }
305 }
306 if ( $user_has_role ) {
307 if ( is_admin() ) {
308 $page_name = self::PAGE_MAIN . '_' . $page['project_id'] . '_' . $page['page_id'];
309 $page_schema_name = $page['page_schema_name'];
310 $page_table_name = $page['page_table_name'];
311 $page_type = $page['page_type'];
312 if ( !$project_menu_shown ) {
313 $main_page_name = $page_name;
314 add_menu_page(
315 $menu_name,
316 $menu_name,
317 WPDA::get_current_user_capability(),
318 $main_page_name,
319 null,
320 'dashicons-database-view'
321 );
322 $project_menu_shown = true;
323 }
324 $this->wpdp_project_menus[$page['project_id'] . '_' . $page['page_id']] = add_submenu_page(
325 $main_page_name,
326 $menu_name,
327 $page['page_name'],
328 WPDA::get_current_user_capability(),
329 $page_name,
330 [$this, 'manage_project_page']
331 );
332 if ( $this->page === self::PAGE_MAIN . '_' . $page['project_id'] . '_' . $page['page_id'] ) {
333 if ( 'static' !== $page_type && null !== $page['page_where'] && '' !== $page['page_where'] ) {
334 if ( 'where' === strtolower( substr( str_replace( ' ', '', $page['page_where'] ), 0, 5 ) ) ) {
335 $where_clause = " {$page['page_where']}";
336 } else {
337 $where_clause = " where {$page['page_where']} ";
338 }
339 $where_clause = WPDA::substitute_environment_vars( $where_clause );
340 } else {
341 $where_clause = '';
342 }
343 switch ( $page_type ) {
344 case 'static':
345 $this->wpdp_projects_content[$page['project_id'] . '_' . $page['page_id']] = $page['page_content'];
346 break;
347 case 'table':
348 $args = array(
349 'page_hook_suffix' => $this->wpdp_project_menus[$page['project_id'] . '_' . $page['page_id']],
350 'wpdaschema_name' => $page_schema_name,
351 'table_name' => $page_table_name,
352 'project_id' => $page['project_id'],
353 'page_id' => $page['page_id'],
354 'list_table_class' => 'WPDataProjects\\List_Table\\WPDP_List_Table',
355 'edit_form_class' => 'WPDataProjects\\Simple_Form\\WPDP_Simple_Form',
356 'where_clause' => $where_clause,
357 'orderby_clause' => $page['page_orderby'],
358 );
359 if ( 'view' === $page['page_mode'] ) {
360 $args['allow_update'] = 'off';
361 $args['allow_import'] = 'off';
362 }
363 if ( 'no' === $page['page_allow_insert'] ) {
364 $args['allow_insert'] = 'off';
365 $args['allow_import'] = 'off';
366 }
367 if ( 'no' === $page['page_allow_delete'] ) {
368 $args['allow_delete'] = 'off';
369 }
370 if ( 'only' === $page['page_allow_insert'] ) {
371 $args['action'] = 'new';
372 $args['allow_insert'] = 'only';
373 $args['allow_update'] = 'off';
374 $args['allow_import'] = 'off';
375 $args['allow_delete'] = 'off';
376 }
377 if ( 'no' === $page['page_allow_import'] ) {
378 $args['allow_import'] = 'off';
379 }
380 if ( 'no' === $page['page_allow_bulk'] ) {
381 $args['bulk_actions_enabled'] = false;
382 }
383 $this->wpdp_project_views[$page['project_id'] . '_' . $page['page_id']] = new \WPDataProjects\List_Table\WPDP_List_View($args);
384 break;
385 case 'parent/child':
386 $args = array(
387 'page_hook_suffix' => $this->wpdp_project_menus[$page['project_id'] . '_' . $page['page_id']],
388 'wpdaschema_name' => $page_schema_name,
389 'table_name' => $page_table_name,
390 'list_table_class' => 'WPDataProjects\\Parent_Child\\WPDP_Parent_List_Table',
391 'edit_form_class' => 'WPDataProjects\\Parent_Child\\WPDP_Parent_Form',
392 'project_id' => $page['project_id'],
393 'page_id' => $page['page_id'],
394 'where_clause' => $where_clause,
395 'orderby_clause' => $page['page_orderby'],
396 );
397 if ( 'view' === $page['page_mode'] ) {
398 $args['allow_update'] = 'off';
399 $args['allow_import'] = 'off';
400 }
401 if ( 'no' === $page['page_allow_insert'] ) {
402 $args['allow_insert'] = 'off';
403 $args['allow_import'] = 'off';
404 }
405 if ( 'no' === $page['page_allow_delete'] ) {
406 $args['allow_delete'] = 'off';
407 }
408 if ( 'only' === $page['page_allow_insert'] ) {
409 $args['action'] = 'new';
410 $args['allow_insert'] = 'only';
411 $args['allow_update'] = 'off';
412 $args['allow_import'] = 'off';
413 $args['allow_delete'] = 'off';
414 }
415 if ( 'no' === $page['page_allow_import'] ) {
416 $args['allow_import'] = 'off';
417 }
418 if ( 'no' === $page['page_allow_bulk'] ) {
419 $args['bulk_actions_enabled'] = false;
420 }
421 $this->wpdp_project_views[$page['project_id'] . '_' . $page['page_id']] = new \WPDataProjects\Parent_Child\WPDP_Parent_List_View($args);
422 }
423 }
424 } else {
425 $page_title = $page['page_title'];
426 if ( null === $page_title || '' === trim( $page_title ) ) {
427 $page_title = 'Untitled';
428 }
429 $title = $project['project_description'];
430 if ( null === $title || '' === trim( $title ) ) {
431 $title = $page_title;
432 }
433 $menu = array(
434 'menu_id' => self::PAGE_MAIN . '_' . $page['project_id'] . '_' . $page['page_id'],
435 'menu_name' => $project['menu_name'],
436 'menu_title' => $title,
437 'page_title' => $page_title,
438 );
439 if ( !isset( $this->wp_admin_toolbar[$page['project_id']] ) ) {
440 $this->wp_admin_toolbar[$page['project_id']][] = $menu;
441 } else {
442 $this->wp_admin_toolbar[$page['project_id']][] = $menu;
443 }
444 }
445 }
446 }
447 }
448 if ( !is_admin() ) {
449 $this->wpda_add_project_to_toolbar();
450 }
451 }
452
453 protected function wpda_add_project_to_toolbar() {
454 foreach ( $this->wp_admin_toolbar as $pid => $toolbar ) {
455 foreach ( $toolbar as $key => $menu ) {
456 if ( 0 === $key ) {
457 $this->additem_to_toolbar( $pid, $menu );
458 }
459 $this->additem_to_toolbar( $menu['menu_id'], $menu, $pid );
460 }
461 }
462 }
463
464 protected function additem_to_toolbar( $pid, $menu, $parent = null ) {
465 global $wp_admin_bar;
466 $args = array(
467 'id' => $pid,
468 'title' => ( null === $parent ? $menu['menu_name'] : $menu['page_title'] ),
469 'href' => admin_url( 'admin.php' ) . '?page=' . $menu['menu_id'],
470 'zindex' => '9999',
471 'meta' => array(
472 'class' => ( null === $parent ? 'wpda-wpdp-toolbar' : '' ),
473 'title' => ( null === $parent ? $menu['menu_title'] : $menu['page_title'] ),
474 ),
475 );
476 if ( null !== $parent ) {
477 $args['parent'] = $parent;
478 }
479 $wp_admin_bar->add_node( $args );
480 }
481
482 /**
483 * Manage project page
484 */
485 public function manage_project_page() {
486 $ids = explode( '_', (string) $this->page );
487 // phpcs:ignore -- 8.1 proof
488 if ( 4 !== count( $ids ) ) {
489 // phpcs:ignore -- 8.1 proof
490 wp_die( esc_attr__( 'ERROR: Wrong arguments [missing page]', 'wp-data-access' ) );
491 }
492 $project_id = $ids[2];
493 $page_id = $ids[3];
494 if ( isset( $this->wpdp_project_views[$project_id . '_' . $page_id] ) ) {
495 $this->wpdp_project_views[$project_id . '_' . $page_id]->show();
496 } else {
497 if ( isset( $this->wpdp_projects_content[$project_id . '_' . $page_id] ) ) {
498 $post_id = $this->wpdp_projects_content[$project_id . '_' . $page_id];
499 $post = get_post( $post_id );
500 $content = $post->post_content;
501 // phpcs:disable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
502 $content = apply_filters( 'the_content', $content );
503 // phpcs:enable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
504 $content = str_replace( ']]>', ']]&gt;', $content );
505 // phpcs:disable WordPress.Security.EscapeOutput
506 echo $content;
507 // phpcs:enable WordPress.Security.EscapeOutput
508 } else {
509 wp_die( esc_attr__( 'ERROR: Project page initialization failed', 'wp-data-access' ) );
510 }
511 }
512 }
513
514 }
515