Completed
Push — master ( 157cf9...0e73b5 )
by Sam
03:38
created

Menus   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 216
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 26
lcom 1
cbo 8
dl 0
loc 216
rs 10
c 2
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A init() 0 7 1
A activation() 0 7 1
A add_menu_pages() 0 15 3
A admin_bar_menu() 0 19 4
A output() 0 3 1
C dispatch() 0 36 11
B enqueue() 0 49 4
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