Completed
Push — master ( 67078f...11dea5 )
by Sam
02:17
created

src/Menus.php (1 issue)

Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * This file contains only the Menus class
4
 *
5
 * @package Tabulate
6
 */
7
8
namespace WordPress\Tabulate;
9
10
use WordPress\Tabulate\Controllers\ControllerBase;
11
12
/**
13
 * This class is an attempt to group all functionality around managing the menus
14
 * in the Admin Area in one place. It includes adding scripts and stylesheets.
15
 */
16
class Menus {
17
18
	/**
19
	 * The global wpdb object.
20
	 *
21
	 * @var \wpdb
22
	 */
23
	protected $wpdb;
24
25
	/**
26
	 * The global filesystem object
27
	 *
28
	 * @var \WP_Filesystem_Base
29
	 */
30
	protected $filesystem;
31
32
	/**
33
	 * The page output is stored between being called/created in
34
	 * self::dispatch() and output in self::add_menu_pages()
35
	 *
36
	 * @var string
37
	 */
38
	protected $output;
39
40
	/**
41
	 * Create a new Menus object, supplying it with the database so that it
42
	 * doesn't have to use a global.
43
	 *
44
	 * @param \wpdb               $wpdb The global wpdb object.
45
	 * @param \WP_Filesystem_Base $filesystem The global filesystem object.
46
	 */
47
	public function __construct( $wpdb, \WP_Filesystem_Base $filesystem ) {
48
		$this->wpdb = $wpdb;
49
		$this->filesystem = $filesystem;
50
	}
51
52
	/**
53
	 * Set up all required hooks. This is called from the top level of tabulate.php
54
	 *
55
	 * @return void
56
	 */
57
	public function init() {
58
		add_action( 'init', array( $this, 'dispatch' ) );
59
		add_action( 'admin_menu', array( $this, 'add_menu_pages' ) );
60
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue' ) );
61
		add_action( 'wp_enqueue_scripts', array( $this, 'enqueue' ) );
62
		add_action( 'admin_bar_menu', array( $this, 'admin_bar_menu' ) );
63
	}
64
65
	/**
66
	 * Add Tabulate's menu items to the main admin menu.
67
	 *
68
	 * @return void
69
	 */
70
	public function add_menu_pages() {
71
		$dispatch_callback = array( $this, 'output' );
72
73
		// Home page (also change the first submenu item's title).
74
		add_menu_page( 'Tabulate', 'Tabulate', 'read', TABULATE_SLUG, $dispatch_callback );
75
		$page_title = ( isset( $_GET['table'] ) ) ? Text::titlecase( $_GET['table'] ) : 'Tabulate';
76
		add_submenu_page( TABULATE_SLUG, $page_title, 'Overview', 'read', TABULATE_SLUG, $dispatch_callback );
77
78
		// Add submenu pages.
79
		if ( Util::is_plugin_active( 'tfo-graphviz/tfo-graphviz.php' ) ) {
80
			add_submenu_page( TABULATE_SLUG, 'Tabulate ERD', 'ERD', 'read', TABULATE_SLUG . '_erd', $dispatch_callback );
81
		}
82
		add_submenu_page( TABULATE_SLUG, 'Tabulate Reports', 'Reports', 'promote_users', TABULATE_SLUG . '_reports', $dispatch_callback );
83
		add_submenu_page( TABULATE_SLUG, 'Tabulate Grants', 'Grants', 'promote_users', TABULATE_SLUG . '_grants', $dispatch_callback );
84
	}
85
86
	/**
87
	 * Add all tables in which the user is allowed to create records to the
88
	 * Admin Bar new-content menu. If there are more than ten, none are added
89
	 * because the menu would get too long. Not sure how this should be fixed.
90
	 *
91
	 * @global \WP_Admin_Bar $wp_admin_bar
92
	 * @global \wpdb $wpdb
93
	 */
94
	public function admin_bar_menu() {
95
		global $wp_admin_bar, $wpdb;
96
		$db = new DB\Database( $wpdb );
97
		$tables = $db->get_tables();
98
		if ( count( $tables ) > 10 ) {
99
			return false;
100
		}
101
		foreach ( $tables as $table ) {
102
			if ( ! DB\Grants::current_user_can( DB\Grants::CREATE, $table->get_name() ) ) {
103
				continue;
104
			}
105
			$wp_admin_bar->add_menu( array(
106
				'parent' => 'new-content',
107
				'id'     => TABULATE_SLUG . '-' . $table->get_name(),
108
				'title'  => $table->get_title(),
109
				'href'   => $table->get_url( 'index', null, 'record' ),
0 ignored issues
show
null is of type null, but the function expects a array<integer,string>|boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
110
			) );
111
		}
112
	}
113
114
	/**
115
	 * Print the currently-stored output; this is the callback for all the menu items.
116
	 */
117
	public function output() {
118
		echo $this->output;
119
	}
120
121
	/**
122
	 * Create and dispatch the controller, capturing its output for use later
123
	 * in the callback for the menu items.
124
	 *
125
	 * @return string The HTML to display.
126
	 */
127
	public function dispatch() {
128
		$request = $_REQUEST;
129
130
		// Only dispatch when it's our page.
131
		$slug_lenth = strlen( TABULATE_SLUG );
132
		if ( ! isset( $request['page'] ) || substr( $request['page'], 0, $slug_lenth ) !== TABULATE_SLUG ) {
133
			return;
134
		}
135
136
		// Discern the controller name, based on an explicit request parameter, or
137
		// the trailing part of the page slug (i.e. after 'tabulate_').
138
		$controller_name = 'home';
139
		if ( isset( $request['controller'] ) && strlen( $request['controller'] ) > 0 ) {
140
			$controller_name = $request['controller'];
141
		} elseif ( isset( $request['page'] ) && strlen( $request['page'] ) > $slug_lenth ) {
142
			$controller_name = substr( $request['page'], $slug_lenth + 1 );
143
		}
144
145
		// Create the controller and run the action.
146
		$controller_classname = '\\WordPress\\Tabulate\\Controllers\\' . ucfirst( $controller_name ) . 'Controller';
147
		$controller = new $controller_classname( $this->wpdb );
148
		$controller->set_filesystem( $this->filesystem );
149
		$action = ! empty( $request['action'] ) ? $request['action'] : 'index';
150
		unset( $request['page'], $request['controller'], $request['action'] );
151
		try {
152
			$this->output = $controller->$action( $request );
153
		} catch ( \Exception $e ) {
154
			$this->output = '<h1>An error occured</h1><div class="error"><p>' . $e->getMessage() . '</p></div>';
155
			if ( WP_DEBUG ) {
156
				$this->output .= '<h2>Stack trace</h2><pre>' . $e->getTraceAsString() . '</pre>';
157
			}
158
		}
159
	}
160
161
	/**
162
	 * This is the callback method used in self::init() to add scripts and
163
	 * styles to the Tabulate admin pages and everywhere the shortcode is used.
164
	 *
165
	 * @param string $page The current page name.
166
	 * @return void
167
	 */
168
	public function enqueue( $page ) {
169
		// Make sure we only enqueue on Tabulate pages.
170
		$allowed_pages = array(
171
			'index.php', // For the Dashboard widget.
172
			'tabulate_shortcode', // Not really a page.
173
			'toplevel_page_tabulate',
174
			'tabulate_page_tabulate_erd',
175
			'tabulate_page_tabulate_reports',
176
			'tabulate_page_tabulate_grants',
177
			'tabulate_page_tabulate_schema',
178
		);
179
		if ( ! ( empty( $page ) || in_array( $page, $allowed_pages, true ) ) ) {
180
			return;
181
		}
182
183
		// Register dependency scripts.
184
		$maskedinput_url = plugins_url( TABULATE_SLUG ) . '/assets/jquery.maskedinput.min.js';
185
		wp_register_script( 'tabulate-maskedinput', $maskedinput_url, array( 'jquery' ), '1.4.1', true );
186
		$timepicker_url = plugins_url( TABULATE_SLUG ) . '/assets/jquery-ui-timepicker-addon.min.js';
187
		wp_register_script( 'tabulate-timepicker', $timepicker_url, array( 'jquery-ui-datepicker' ), TABULATE_VERSION, true );
188
		$onmivore_url = plugins_url( TABULATE_SLUG ) . '/assets/leaflet/leaflet-omnivore.min.js';
189
		wp_register_script( 'tabulate-onmivore', $onmivore_url, array( 'tabulate-leaflet' ), TABULATE_VERSION, true );
190
		$leaflet_url = plugins_url( TABULATE_SLUG ) . '/assets/leaflet/leaflet.js';
191
		wp_register_script( 'tabulate-leaflet', $leaflet_url, null, TABULATE_VERSION, true );
192
193
		// Enqueue Tabulate's scripts.
194
		$script_url = plugins_url( TABULATE_SLUG ) . '/assets/scripts.js';
195
		$deps = array( 'jquery-ui-autocomplete', 'tabulate-leaflet', 'tabulate-maskedinput', 'tabulate-timepicker' );
196
		if ( Util::is_plugin_active( 'rest-api/plugin.php' ) ) {
197
			$deps[] = 'wp-api';
198
		}
199
		wp_enqueue_script( 'tabulate-scripts', $script_url, $deps, TABULATE_VERSION, true );
200
201
		// Javascript page variables.
202
		$js_vars = array(
203
			'admin_url' => admin_url() . 'admin.php?page=' . TABULATE_SLUG,
204
		);
205
		wp_localize_script( 'tabulate-scripts', 'tabulate', $js_vars );
206
207
		// Add stylesheets.
208
		$timepicker_url = plugins_url( TABULATE_SLUG ) . '/assets/jquery-ui-timepicker-addon.css';
209
		wp_enqueue_style( 'tabulate-timepicker', $timepicker_url, null, TABULATE_VERSION );
210
		$leaflet_css_url = plugins_url( TABULATE_SLUG ) . '/assets/leaflet/leaflet.css';
211
		wp_enqueue_style( 'tabulate-leaflet', $leaflet_css_url, null, TABULATE_VERSION );
212
		$jqueryui_url = plugins_url( TABULATE_SLUG ) . '/assets/jquery-ui/jquery-ui.min.css';
213
		wp_enqueue_style( 'tabulate-jquery-ui', $jqueryui_url, null, TABULATE_VERSION );
214
		$jqueryui_theme_url = plugins_url( TABULATE_SLUG ) . '/assets/jquery-ui/jquery-ui.theme.min.css';
215
		wp_enqueue_style( 'tabulate-jquery-ui-theme', $jqueryui_theme_url, null, TABULATE_VERSION );
216
		$style_url = plugins_url( TABULATE_SLUG ) . '/assets/style.css';
217
		wp_enqueue_style( 'tabulate-styles', $style_url, null, TABULATE_VERSION );
218
	}
219
}
220