Completed
Push — milestone/2.0 ( 2ab7a4...17042e )
by
unknown
02:47
created

Theme_Options_Container::is_valid_save()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
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
	protected static $registered_pages = array();
14
15
	public $settings = array(
16
		'parent' => 'self',
17
		'file' => '',
18
		'permissions' => 'manage_options',
19
	);
20
21
	public $icon = '';
22
23
	/**
24
	 * Create a new container
25
	 *
26
	 * @param string $unique_id Unique id of the container
27
	 * @param string $title title of the container
28
	 * @param string $type Type of the container
29
	 **/
30 View Code Duplication
	public function __construct( $unique_id, $title, $type ) {
31
		parent::__construct( $unique_id, $title, $type );
32
33
		if ( ! $this->get_datastore() ) {
34
			$this->set_datastore( Datastore::make( 'theme_options' ), $this->has_default_datastore() );
35
		}
36
	}
37
38
	/**
39
	 * Attach container as a theme options page/subpage.
40
	 **/
41
	public function init() {
42
		if ( ! $this->settings['parent'] || $this->settings['parent'] == 'self' ) {
43
			$this->settings['parent'] = '';
44
		} else if ( strpos( $this->settings['parent'], '.php' ) === false ) {
45
			$clear_title = $this->clear_string( $this->settings['parent'] );
46
			$this->settings['parent'] = 'crbn-' . $clear_title . '.php';
47
		}
48
49
		if ( ! $this->settings['file'] ) {
50
			$clear_title = $this->clear_string( $this->title );
51
			$this->settings['file'] .= 'crbn-' . $clear_title . '.php';
52
		}
53
54
		$this->verify_unique_page();
55
56
		add_action( 'admin_menu', array( $this, '_attach' ) );
57
	}
58
59
	/**
60
	 * Perform checks whether the current save() request is valid.
61
	 *
62
	 * @return bool
63
	 **/
64
	public function is_valid_save() {
65
		return $this->verified_nonce_in_request();
66
	}
67
68
	/**
69
	 * Perform save operation after successful is_valid_save() check.
70
	 * The call is propagated to all fields in the container.
71
	 *
72
	 * @param mixed $user_data
73
	 **/
74
	public function save( $user_data = null ) {
75
		try {
76
			parent::save( $user_data );
77
		} catch ( Incorrect_Syntax_Exception $e ) {
78
			$this->errors[] = $e->getMessage();
79
		}
80
81
		do_action( 'carbon_after_save_theme_options', $user_data );
82
83
		if ( ! headers_sent() ) {
84
			wp_redirect( add_query_arg( array( 'settings-updated' => 'true' ) ) );
85
		}
86
	}
87
88
	/**
89
	 * Perform checks whether the container should be attached during the current request
90
	 *
91
	 * @return bool True if the container is allowed to be attached
92
	 **/
93
	public function is_valid_attach_for_request() {
94
		return true;
95
	}
96
97
	/**
98
	 * Check container attachment rules against object id
99
	 *
100
	 * @param int $object_id
101
	 * @return bool
102
	 **/
103
	public function is_valid_attach_for_object( $object_id = null ) {
104
		return true;
105
	}
106
107
	/**
108
	 * Add theme options container pages.
109
	 * Hook the container saving action.
110
	 **/
111
	public function attach() {
112
113
		// Add menu page
114
		if ( ! $this->settings['parent'] ) {
115
			add_menu_page(
116
				$this->title,
117
				$this->title,
118
				$this->settings['permissions'],
119
				$this->settings['file'],
120
				array( $this, 'render' ),
121
				$this->icon
122
			);
123
		}
124
125
		add_submenu_page(
126
			$this->settings['parent'],
127
			$this->title,
128
			$this->title,
129
			$this->settings['permissions'],
130
			$this->settings['file'],
131
			array( $this, 'render' ),
132
			$this->icon
133
		);
134
135
		$page_hook = get_plugin_page_hookname( $this->settings['file'], '' );
136
		add_action( 'load-' . $page_hook, array( $this, '_save' ) );
137
	}
138
139
	/**
140
	 * Whether this container is currently viewed.
141
	 **/
142 View Code Duplication
	public function should_activate() {
143
		$request_page = isset( $_GET['page'] ) ? $_GET['page'] : '';
1 ignored issue
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
144
		if ( ! empty( $request_page ) && $request_page === $this->settings['file'] ) {
145
			return true;
146
		}
147
148
		return false;
149
	}
150
151
	/**
152
	 * Output the container markup
153
	 **/
154
	public function render() {
155
		$request_settings_updated = isset( $_GET['settings-updated'] ) ? $_GET['settings-updated'] : '';
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
156
		if ( $request_settings_updated === 'true' ) {
157
			$this->notifications[] = __( 'Settings saved.', \Carbon_Fields\TEXT_DOMAIN );
158
		}
159
160
		include \Carbon_Fields\DIR . '/templates/Container/theme_options.php';
161
	}
162
163
	/**
164
	 * Make sure that there are no duplicate containers with the same name.
165
	 **/
166
	public function verify_unique_page() {
167
		$file = $this->settings['file'];
168
		$parent = $this->settings['parent'];
169
170
		// Register top level page
171
		if ( ! $parent ) {
172
			if ( isset( static::$registered_pages[ $file ] ) ) {
173
				Incorrect_Syntax_Exception::raise( 'Page "' . $file . '" already registered' );
174
			}
175
176
			static::$registered_pages[ $file ] = array();
177
			return;
178
		}
179
180
		// Register sub-page
181
		if ( ! isset( static::$registered_pages[ $parent ] ) ) {
182
			static::$registered_pages[ $parent ] = array( $file );
183
		} elseif ( in_array( $file, static::$registered_pages[ $parent ] ) ) {
184
			Incorrect_Syntax_Exception::raise( 'Page "' . $file . '" with parent "' . $parent . '" is already registered. Please set a name for the container.' );
185
		} else {
186
			static::$registered_pages[ $parent ][] = $file;
187
		}
188
	}
189
190
	/**
191
	 * Unregister the container parent and child pages.
192
	 **/
193
	public function drop_unique_page() {
194
		$file = $this->settings['file'];
195
		$parent = $this->settings['parent'];
196
197
		// Register top level page
198
		if ( ! $parent ) {
199
			if ( isset( static::$registered_pages[ $file ] ) && empty( static::$registered_pages[ $file ] ) ) {
200
				unset( static::$registered_pages[ $file ] );
201
			}
202
203
			return;
204
		}
205
206
		// Register sub-page
207
		if ( isset( static::$registered_pages[ $parent ] ) && in_array( $file, static::$registered_pages[ $parent ] ) ) {
208
209
			$index = array_search( $file, static::$registered_pages[ $parent ] );
210
			if ( $index !== false ) {
211
				unset( static::$registered_pages[ $parent ][ $index ] );
212
			}
213
		}
214
	}
215
216
	/**
217
	 * Sanitize the container title for use in
218
	 * the theme options file name.
219
	 **/
220
	protected function clear_string( $string ) {
221
		return preg_replace( array( '~ +~', '~[^\w\d-]+~u', '~-+~' ), array( '-', '-', '-' ), strtolower( remove_accents( $string ) ) );
222
	}
223
224
	/**
225
	 * COMMON USAGE METHODS
226
	 */
227
228
	/**
229
	 * Change the parent theme options page of this container
230
	 **/
231
	public function set_page_parent( $parent ) {
232
		if ( is_a( $parent, 'Carbon_Container' ) ) {
233
			$parent = $parent->title;
234
		}
235
236
		$this->settings['parent'] = $parent;
237
		return $this;
238
	}
239
240
	/**
241
	 * Set the icon of this theme options page.
242
	 * Applicable only for parent theme option pages.
243
	 **/
244
	public function set_icon( $icon ) {
245
		$this->icon = $icon;
246
		return $this;
247
	}
248
249
	/**
250
	 * Set the theme options file name of this container.
251
	 **/
252
	public function set_page_file( $file ) {
253
		$this->settings['file'] = $file;
254
		return $this;
255
	}
256
257
	/**
258
	 * Set the permissions necessary to view
259
	 * the corresponding theme options page
260
	 **/
261
	public function set_page_permissions( $permissions ) {
262
		$this->settings['permissions'] = $permissions;
263
		return $this;
264
	}
265
}
266
267