Completed
Branch milestone/2_0/react-ui (57d10c)
by htmlBurger
02:47
created

Theme_Options_Container::set_page_position()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 3
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 4
ccs 0
cts 0
cp 0
crap 2
rs 10
1
<?php
2
3
namespace Carbon_Fields\Container;
4
5
use Carbon_Fields\Datastore\Datastore;
6
use Carbon_Fields\Exception\Incorrect_Syntax_Exception;
7
8
/**
9
 * Theme options container class.
10
 */
11
class Theme_Options_Container extends Container {
12
	
13
	/**
14
	 * Array of registered page slugs to verify uniqueness with
15
	 * 
16
	 * @var array
17
	 */
18
	protected static $registered_pages = array();
19
20
	/**
21
	 * Array of container settings
22
	 *
23
	 * @var array
24
	 */
25
	public $settings = array(
26
		'parent' => '',
27
		'file' => '',
28
		'icon' => '',
29
		'position' => null,
30
	);
31
32
	/**
33
	 * Create a new container
34
	 *
35
	 * @param string $unique_id Unique id of the container
36
	 * @param string $title title of the container
37
	 * @param string $type Type of the container
38
	 */
39
	public function __construct( $unique_id, $title, $type ) {
40
		parent::__construct( $unique_id, $title, $type );
41
42
		if ( ! $this->get_datastore() ) {
43
			$this->set_datastore( Datastore::make( 'theme_options' ), $this->has_default_datastore() );
44
		}
45
	}
46
47
	/**
48
	 * Sanitize the container title for use in
49
	 * the theme options file name.
50
	 *
51
	 * @param string $string
52
	 * @return string
53
	 */
54
	protected function clear_string( $string ) {
55
		return preg_replace( array( '~ +~', '~[^\w\d-]+~u', '~-+~' ), array( '-', '-', '-' ), strtolower( remove_accents( $string ) ) );
56
	}
57
58
	/**
59
	 * Attach container as a theme options page/subpage.
60
	 */
61
	public function init() {
62
		if ( $this->settings['parent'] !== '' && strpos( $this->settings['parent'], '.php' ) === false ) {
63
			$clear_title = $this->clear_string( $this->settings['parent'] );
64
			$this->settings['parent'] = 'crbn-' . $clear_title . '.php';
65
		}
66
67
		if ( ! $this->settings['file'] ) {
68
			$clear_title = $this->clear_string( $this->title );
69
			$this->settings['file'] .= 'crbn-' . $clear_title . '.php';
70
		}
71
72
		$registered = $this->register_page();
73
		if ( $registered ) {
74
			add_action( 'admin_menu', array( $this, '_attach' ) );
75
		}
76
	}
77
78
	/**
79
	 * Checks whether the current save request is valid
80
	 *
81
	 * @return bool
82
	 */
83
	public function is_valid_save() {
84
		if ( ! $this->verified_nonce_in_request() ) {
85
			return false;
86
		}
87
88
		return $this->is_valid_attach_for_object( null );
89
	}
90
91
	/**
92
	 * Perform save operation after successful is_valid_save() check.
93
	 * The call is propagated to all fields in the container.
94
	 *
95
	 * @param mixed $user_data
96
	 */
97
	public function save( $user_data = null ) {
98
		try {
99
			parent::save( $user_data );
100
		} catch ( Incorrect_Syntax_Exception $e ) {
101
			$this->errors[] = $e->getMessage();
102
		}
103
104
		do_action( 'carbon_after_save_theme_options', $user_data );
105
106
		if ( ! headers_sent() ) {
107
			wp_redirect( add_query_arg( array( 'settings-updated' => 'true' ) ) );
108
		}
109
	}
110
111
	/**
112
	 * Get environment array for page request (in admin)
113
	 *
114
	 * @return array
115
	 */
116
	protected function get_environment_for_request() {
117
		return array();
118
	}
119
120
	/**
121
	 * Perform checks whether the container should be attached during the current request
122
	 *
123
	 * @return bool True if the container is allowed to be attached
124
	 */
125
	public function is_valid_attach_for_request() {
126
		return $this->static_conditions_pass();
127
	}
128
129
	/**
130
	 * Get environment array for object id
131
	 *
132
	 * @return array
133
	 */
134
	protected function get_environment_for_object( $object_id ) {
135
		return array();
136
	}
137
138
	/**
139
	 * Check container attachment rules against object id
140
	 *
141
	 * @param int $object_id
142
	 * @return bool
143
	 */
144
	public function is_valid_attach_for_object( $object_id = null ) {
145
		return $this->all_conditions_pass( intval( $object_id ) );
146
	}
147
148
	/**
149
	 * Add theme options container pages.
150
	 * Hook the container saving action.
151
	 */
152
	public function attach() {
153
		// use the "read" capability because conditions will handle actual access and save capability checking
154
		// before the attach() method is called
155
156
		// Add menu page
157
		if ( ! $this->settings['parent'] ) {
158
			add_menu_page(
159
				$this->title,
160
				$this->title,
161
				'read',
162
				$this->settings['file'],
163
				array( $this, 'render' ),
164
				$this->settings['icon'],
165
				$this->settings['position']
166
			);
167
		}
168
169
		add_submenu_page(
170
			$this->settings['parent'],
171
			$this->title,
172
			$this->title,
173
			'read',
174
			$this->settings['file'],
175
			array( $this, 'render' )
176
		);
177
178
		$page_hook = get_plugin_page_hookname( $this->settings['file'], '' );
179
		add_action( 'load-' . $page_hook, array( $this, '_save' ) );
180
	}
181
182
	/**
183
	 * Whether this container is currently viewed.
184
	 *
185
	 * @return boolean
186
	 */
187
	public function should_activate() {
188
		$input = stripslashes_deep( $_GET );
189
		$request_page = isset( $input['page'] ) ? $input['page'] : '';
190
		if ( ! empty( $request_page ) && $request_page === $this->settings['file'] ) {
191
			return true;
192
		}
193
194
		return false;
195
	}
196
197
	/**
198
	 * Output the container markup
199
	 */
200
	public function render() {
201
		$input = stripslashes_deep( $_GET );
202
		$request_settings_updated = isset( $input['settings-updated'] ) ? $input['settings-updated'] : '';
203
		if ( $request_settings_updated === 'true' ) {
204
			$this->notifications[] = __( 'Settings saved.', 'carbon-fields' );
205
		}
206
207
		include \Carbon_Fields\DIR . '/templates/Container/theme_options.php';
208
	}
209
210
	/**
211
	 * Register the page while making sure it is unique.
212
	 *
213
	 * @return boolean
214
	 */
215
	public function register_page() {
216
		$file = $this->settings['file'];
217
		$parent = $this->settings['parent'];
218
219
		if ( ! $parent ) {
220
			// Register top level page
221
			if ( isset( static::$registered_pages[ $file ] ) ) {
222
				Incorrect_Syntax_Exception::raise( 'Page "' . $file . '" already registered' );
223
				return false;
224
			}
225
226
			static::$registered_pages[ $file ] = array();
227
			return true;
228
		}
229
230
		// Register sub-page
231
		if ( ! isset( static::$registered_pages[ $parent ] ) ) {
232
			static::$registered_pages[ $parent ] = array();
233
		}
234
235
		if ( in_array( $file, static::$registered_pages[ $parent ] ) ) {
236
			Incorrect_Syntax_Exception::raise( 'Page "' . $file . '" with parent "' . $parent . '" is already registered. Please set a name for the container.' );
237
			return false;
238
		}
239
240
		static::$registered_pages[ $parent ][] = $file;
241
		return true;
242
	}
243
244
	/**
245
	 * Change the parent theme options page of this container
246
	 * 
247
	 * @return Container $this
248
	 */
249
	public function set_page_parent( $parent ) {
250
		if ( is_a( $parent, 'Carbon_Container' ) ) {
251
			$parent = $parent->title;
252
		}
253
254
		$this->settings['parent'] = $parent;
255
		return $this;
256
	}
257
258
	/**
259
	 * Set the icon of this theme options page.
260
	 * Applicable only for parent theme option pages.
261
	 * 
262
	 * @return Container $this
263
	 */
264
	public function set_icon( $icon ) {
265
		$this->settings['icon'] = $icon;
266
		return $this;
267
	}
268
269
	/**
270
	 * Set the theme options file name of this container.
271
	 * 
272
	 * @return Container $this
273
	 */
274
	public function set_page_file( $file ) {
275
		$this->settings['file'] = $file;
276
		return $this;
277
	}
278
279
	/**
280
	 * Set the page position of this container in the administration menu.
281
	 * 
282
	 * @return Container $this
283
	 */
284
	public function set_page_position( $position ) {
285
		$this->settings['position'] = $position;
286
		return $this;
287
	}
288
}
289
290