1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* This file contains only the Menus class |
4
|
|
|
* |
5
|
|
|
* @package Tabulate |
6
|
|
|
*/ |
7
|
|
|
|
8
|
|
|
namespace WordPress\Tabulate; |
9
|
|
|
|
10
|
|
|
use Exception; |
11
|
|
|
use WordPress\Tabulate\DB\ChangeTracker; |
12
|
|
|
use WordPress\Tabulate\DB\Exception as TabulateException; |
13
|
|
|
use WordPress\Tabulate\DB\Reports; |
14
|
|
|
use WordPress\Tabulate\DB\Table; |
15
|
|
|
use WP_Admin_Bar; |
16
|
|
|
use WP_Filesystem_Base; |
17
|
|
|
use wpdb; |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* This class is an attempt to group all functionality around managing the menus |
21
|
|
|
* in the Admin Area in one place. It includes adding scripts and stylesheets. |
22
|
|
|
*/ |
23
|
|
|
class Menus { |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* The global wpdb object. |
27
|
|
|
* |
28
|
|
|
* @var wpdb |
29
|
|
|
*/ |
30
|
|
|
protected $wpdb; |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* The global filesystem object |
34
|
|
|
* |
35
|
|
|
* @var WP_Filesystem_Base |
36
|
|
|
*/ |
37
|
|
|
protected $filesystem; |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* The page output is stored between being called/created in |
41
|
|
|
* self::dispatch() and output in self::add_menu_pages() |
42
|
|
|
* |
43
|
|
|
* @var string |
44
|
|
|
*/ |
45
|
|
|
protected $output; |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* Create a new Menus object, supplying it with the database so that it |
49
|
|
|
* doesn't have to use a global. |
50
|
|
|
* |
51
|
|
|
* @param wpdb $wpdb The global wpdb object. |
52
|
|
|
* @param WP_Filesystem_Base $filesystem The global filesystem object. |
53
|
|
|
*/ |
54
|
|
|
public function __construct( $wpdb, WP_Filesystem_Base $filesystem ) { |
55
|
|
|
$this->wpdb = $wpdb; |
56
|
|
|
$this->filesystem = $filesystem; |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* Set up all required hooks. This is called from the top level of tabulate.php |
61
|
|
|
* |
62
|
|
|
* @return void |
63
|
|
|
*/ |
64
|
|
|
public function init() { |
65
|
|
|
add_action( 'init', array( $this, 'dispatch' ) ); |
66
|
|
|
add_action( 'admin_menu', array( $this, 'add_menu_pages' ) ); |
67
|
|
|
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue' ) ); |
68
|
|
|
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue' ) ); |
69
|
|
|
add_action( 'admin_bar_menu', array( $this, 'admin_bar_menu' ) ); |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* The main plugin activation method. This is called from tabulate.php and from the TestBase class. |
74
|
|
|
*/ |
75
|
|
|
public function activation() { |
76
|
|
|
// Add change-tracker and reports' tables. |
77
|
|
|
ChangeTracker::activate( $this->wpdb ); |
78
|
|
|
Reports::activate( $this->wpdb ); |
79
|
|
|
// Clean up out-of-date option. |
80
|
|
|
delete_option( TABULATE_SLUG . '_managed_tables' ); |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
/** |
84
|
|
|
* Add Tabulate's menu items to the main admin menu. |
85
|
|
|
* |
86
|
|
|
* @return void |
87
|
|
|
*/ |
88
|
|
|
public function add_menu_pages() { |
89
|
|
|
$dispatch_callback = array( $this, 'output' ); |
90
|
|
|
|
91
|
|
|
// Home page (also change the first submenu item's title). |
92
|
|
|
add_menu_page( 'Tabulate', 'Tabulate', 'read', TABULATE_SLUG, $dispatch_callback ); |
93
|
|
|
$page_title = ( isset( $_GET['table'] ) ) ? Text::titlecase( $_GET['table'] ) : 'Tabulate'; |
94
|
|
|
add_submenu_page( TABULATE_SLUG, $page_title, 'Overview', 'read', TABULATE_SLUG, $dispatch_callback ); |
95
|
|
|
|
96
|
|
|
// Add submenu pages. |
97
|
|
|
if ( Util::is_plugin_active( 'tfo-graphviz/tfo-graphviz.php' ) ) { |
98
|
|
|
add_submenu_page( TABULATE_SLUG, 'Tabulate ERD', 'ERD', 'read', TABULATE_SLUG . '_erd', $dispatch_callback ); |
99
|
|
|
} |
100
|
|
|
add_submenu_page( TABULATE_SLUG, 'Tabulate Reports', 'Reports', 'promote_users', TABULATE_SLUG . '_reports', $dispatch_callback ); |
101
|
|
|
add_submenu_page( TABULATE_SLUG, 'Tabulate Grants', 'Grants', 'promote_users', TABULATE_SLUG . '_grants', $dispatch_callback ); |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
/** |
105
|
|
|
* Add all tables in which the user is allowed to create records to the |
106
|
|
|
* Admin Bar new-content menu. If there are more than ten, none are added |
107
|
|
|
* because the menu would get too long. Not sure how this should be fixed. |
108
|
|
|
* |
109
|
|
|
* @global WP_Admin_Bar $wp_admin_bar |
110
|
|
|
* @global wpdb $wpdb |
111
|
|
|
*/ |
112
|
|
|
public function admin_bar_menu() { |
113
|
|
|
global $wp_admin_bar, $wpdb; |
114
|
|
|
$db = new DB\Database( $wpdb ); |
115
|
|
|
$tables = $db->get_tables(); |
116
|
|
|
if ( count( $tables ) > 10 ) { |
117
|
|
|
return; |
118
|
|
|
} |
119
|
|
|
foreach ( $tables as $table ) { |
120
|
|
|
if ( ! DB\Grants::current_user_can( DB\Grants::CREATE, $table->get_name() ) ) { |
121
|
|
|
continue; |
122
|
|
|
} |
123
|
|
|
$wp_admin_bar->add_menu( array( |
124
|
|
|
'parent' => 'new-content', |
125
|
|
|
'id' => TABULATE_SLUG . '-' . $table->get_name(), |
126
|
|
|
'title' => $table->get_title(), |
127
|
|
|
'href' => $table->get_url( 'index', false, 'record' ), |
128
|
|
|
) ); |
129
|
|
|
} |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
/** |
133
|
|
|
* Print the currently-stored output; this is the callback for all the menu items. |
134
|
|
|
*/ |
135
|
|
|
public function output() { |
136
|
|
|
echo $this->output; |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
/** |
140
|
|
|
* Create and dispatch the controller, capturing its output for use later |
141
|
|
|
* in the callback for the menu items. |
142
|
|
|
* |
143
|
|
|
* @return string The HTML to display. |
144
|
|
|
*/ |
145
|
|
|
public function dispatch() { |
146
|
|
|
$request = $_REQUEST; |
147
|
|
|
|
148
|
|
|
// Only dispatch when it's our page. |
149
|
|
|
$slug_lenth = strlen( TABULATE_SLUG ); |
150
|
|
|
if ( ! isset( $request['page'] ) || substr( $request['page'], 0, $slug_lenth ) !== TABULATE_SLUG ) { |
151
|
|
|
return; |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
// Discern the controller name, based on an explicit request parameter, or |
155
|
|
|
// the trailing part of the page slug (i.e. after 'tabulate_'). |
156
|
|
|
$controller_name = 'home'; |
157
|
|
|
if ( isset( $request['controller'] ) && strlen( $request['controller'] ) > 0 ) { |
158
|
|
|
$controller_name = $request['controller']; |
159
|
|
|
} elseif ( isset( $request['page'] ) && strlen( $request['page'] ) > $slug_lenth ) { |
160
|
|
|
$controller_name = substr( $request['page'], $slug_lenth + 1 ); |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
// Create the controller and run the action. |
164
|
|
|
$controller_classname = '\\WordPress\\Tabulate\\Controllers\\' . ucfirst( $controller_name ) . 'Controller'; |
165
|
|
|
if ( ! class_exists( $controller_classname ) ) { |
166
|
|
|
TabulateException::wp_die( "Controller '$controller_name' not found", 'Error', "Class doesn't exist: $controller_classname" ); |
167
|
|
|
} |
168
|
|
|
$controller = new $controller_classname( $this->wpdb ); |
169
|
|
|
$controller->set_filesystem( $this->filesystem ); |
170
|
|
|
$action = ! empty( $request['action'] ) ? $request['action'] : 'index'; |
171
|
|
|
unset( $request['page'], $request['controller'], $request['action'] ); |
172
|
|
|
try { |
173
|
|
|
$this->output = $controller->$action( $request ); |
174
|
|
|
} catch ( Exception $e ) { |
175
|
|
|
$this->output = '<h1>An error occured</h1><div class="error"><p>' . $e->getMessage() . '</p></div>'; |
176
|
|
|
if ( WP_DEBUG ) { |
177
|
|
|
$this->output .= '<h2>Stack trace</h2><pre>' . $e->getTraceAsString() . '</pre>'; |
178
|
|
|
} |
179
|
|
|
} |
180
|
|
|
} |
181
|
|
|
|
182
|
|
|
/** |
183
|
|
|
* This is the callback method used in self::init() to add scripts and |
184
|
|
|
* styles to the Tabulate admin pages and everywhere the shortcode is used. |
185
|
|
|
* |
186
|
|
|
* @param string $page The current page name. |
187
|
|
|
* @return void |
188
|
|
|
*/ |
189
|
|
|
public function enqueue( $page ) { |
190
|
|
|
// Make sure we only enqueue on Tabulate pages. |
191
|
|
|
$allowed_pages = array( |
192
|
|
|
'index.php', // For the Dashboard widget. |
193
|
|
|
'tabulate_shortcode', // Not really a page. |
194
|
|
|
'toplevel_page_tabulate', |
195
|
|
|
'tabulate_page_tabulate_erd', |
196
|
|
|
'tabulate_page_tabulate_reports', |
197
|
|
|
'tabulate_page_tabulate_grants', |
198
|
|
|
'tabulate_page_tabulate_schema', |
199
|
|
|
); |
200
|
|
|
if ( ! ( empty( $page ) || in_array( $page, $allowed_pages, true ) ) ) { |
201
|
|
|
return; |
202
|
|
|
} |
203
|
|
|
|
204
|
|
|
// Register dependency scripts. |
205
|
|
|
$maskedinput_url = plugins_url( TABULATE_SLUG ) . '/assets/jquery.maskedinput.min.js'; |
206
|
|
|
wp_register_script( 'tabulate-maskedinput', $maskedinput_url, array( 'jquery' ), '1.4.1', true ); |
207
|
|
|
$timepicker_url = plugins_url( TABULATE_SLUG ) . '/assets/jquery-ui-timepicker-addon.min.js'; |
208
|
|
|
wp_register_script( 'tabulate-timepicker', $timepicker_url, array( 'jquery-ui-datepicker' ), TABULATE_VERSION, true ); |
209
|
|
|
$omnivore_url = plugins_url( TABULATE_SLUG ) . '/assets/leaflet-omnivore.min.js'; |
210
|
|
|
wp_register_script( 'tabulate-omnivore', $omnivore_url, array( 'tabulate-leaflet' ), '0.3.1', true ); |
211
|
|
|
$leaflet_url = plugins_url( TABULATE_SLUG ) . '/assets/components/leaflet/js/leaflet.min.js'; |
212
|
|
|
wp_register_script( 'tabulate-leaflet', $leaflet_url, null, TABULATE_VERSION, true ); |
213
|
|
|
|
214
|
|
|
// Enqueue Tabulate's scripts. |
215
|
|
|
$script_url = plugins_url( TABULATE_SLUG ) . '/assets/scripts.js'; |
216
|
|
|
$deps = array( 'jquery-ui-autocomplete', 'tabulate-omnivore', 'tabulate-maskedinput', 'tabulate-timepicker' ); |
217
|
|
|
if ( Util::is_plugin_active( 'rest-api/plugin.php' ) ) { |
218
|
|
|
$deps[] = 'wp-api'; |
219
|
|
|
} |
220
|
|
|
wp_enqueue_script( 'tabulate-scripts', $script_url, $deps, TABULATE_VERSION, true ); |
221
|
|
|
|
222
|
|
|
// Javascript page variables. |
223
|
|
|
$js_vars = array( |
224
|
|
|
'admin_url' => admin_url() . 'admin.php?page=' . TABULATE_SLUG, |
225
|
|
|
); |
226
|
|
|
wp_localize_script( 'tabulate-scripts', 'tabulate', $js_vars ); |
227
|
|
|
|
228
|
|
|
// Add stylesheets. |
229
|
|
|
$timepicker_url = plugins_url( TABULATE_SLUG ) . '/assets/jquery-ui-timepicker-addon.css'; |
230
|
|
|
wp_enqueue_style( 'tabulate-timepicker', $timepicker_url, null, TABULATE_VERSION ); |
231
|
|
|
$leaflet_css_url = plugins_url( TABULATE_SLUG ) . '/assets/components/leaflet/css/leaflet.css'; |
232
|
|
|
wp_enqueue_style( 'tabulate-leaflet', $leaflet_css_url, null, TABULATE_VERSION ); |
233
|
|
|
$jqueryui_url = plugins_url( TABULATE_SLUG ) . '/assets/components/jquery-ui/themes/base/jquery-ui.min.css'; |
234
|
|
|
wp_enqueue_style( 'tabulate-jquery-ui', $jqueryui_url, null, TABULATE_VERSION ); |
235
|
|
|
$style_url = plugins_url( TABULATE_SLUG ) . '/assets/style.css'; |
236
|
|
|
wp_enqueue_style( 'tabulate-styles', $style_url, null, TABULATE_VERSION ); |
237
|
|
|
} |
238
|
|
|
} |
239
|
|
|
|