Completed
Push — try/scrutinizer-wp-coding-stan... ( dcaef3...dfddad )
by
unknown
02:30
created

Theme_Options_Container::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
ccs 0
cts 6
cp 0
crap 6
1
<?php
2
3
namespace Carbon_Fields\Container;
4
5
use Carbon_Fields\Datastore\Theme_Options_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
	static protected $registered_pages = array();
13
14
	public $settings = array(
15
		'parent' => 'self',
16
		'file' => '',
17
		'permissions' => 'manage_options',
18
	);
19
20
	public $icon = '';
21
22
	/**
23
	 * Create a new theme options fields container
24
	 *
25
	 * @param string $title Unique title of the container
26
	 **/
27
	public function __construct( $title ) {
28
		parent::__construct( $title );
29
30
		if ( ! $this->get_datastore() ) {
31
			$this->set_datastore( new Theme_Options_Datastore() );
32
		}
33
	}
34
35
	/**
36
	 * Perform save operation after successful is_valid_save() check.
37
	 * The call is propagated to all fields in the container.
38
	 *
39
	 * @param mixed $user_data
40
	 **/
41
	public function save( $user_data = null ) {
42
		try {
43
			parent::save( $user_data );
44
		} catch ( Incorrect_Syntax_Exception $e ) {
45
			$this->errors[] = $e->getMessage();
46
		}
47
48
		do_action( 'carbon_after_save_theme_options', $user_data );
49
50
		if ( ! headers_sent() ) {
51
			wp_redirect( add_query_arg( array( 'settings-updated' => 'true' ) ) );
52
		}
53
	}
54
55
	/**
56
	 * Attach container as a theme options page/subpage.
57
	 **/
58
	public function init() {
59
		if ( ! $this->settings['parent'] || $this->settings['parent'] == 'self' ) {
60
			$this->settings['parent'] = '';
61
		} else if ( strpos( $this->settings['parent'], '.php' ) === false ) {
62
			$clear_title = $this->clear_string( $this->settings['parent'] );
63
			$this->settings['parent'] = 'crbn-' . $clear_title . '.php';
64
		}
65
66
		if ( ! $this->settings['file'] ) {
67
			$clear_title = $this->clear_string( $this->title );
68
			$this->settings['file'] .= 'crbn-' . $clear_title . '.php';
69
		}
70
71
		$this->verify_unique_page();
72
73
		add_action( 'admin_menu', array( $this, '_attach' ) );
74
	}
75
76
	/**
77
	 * Perform checks whether the current save() request is valid.
78
	 *
79
	 * @return bool
80
	 **/
81 View Code Duplication
	public function is_valid_save() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
82
		if ( ! isset( $_POST[ $this->get_nonce_name() ] ) || ! wp_verify_nonce( $_POST[ $this->get_nonce_name() ], $this->get_nonce_name() ) ) { // Input var okay.
0 ignored issues
show
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
83
			return false;
84
		}
85
86
		return true;
87
	}
88
89
	/**
90
	 * Add theme options container pages.
91
	 * Hook the container saving action.
92
	 **/
93
	public function attach() {
94
95
		// Add menu page
96
		if ( ! $this->settings['parent'] ) {
97
			add_menu_page(
98
				$this->title,
99
				$this->title,
100
				$this->settings['permissions'],
101
				$this->settings['file'],
102
				array( $this, 'render' ),
103
				$this->icon
104
			);
105
		}
106
107
		add_submenu_page(
108
			$this->settings['parent'],
109
			$this->title,
110
			$this->title,
111
			$this->settings['permissions'],
112
			$this->settings['file'],
113
			array( $this, 'render' ),
114
			$this->icon
115
		);
116
117
		$page_hook = get_plugin_page_hookname( $this->settings['file'], '' );
118
		add_action( 'load-' . $page_hook, array( $this, '_save' ) );
119
	}
120
121
	/**
122
	 * Whether this container is currently viewed.
123
	 **/
124
	public function is_active() {
125
		if ( isset( $_GET['page'] ) && $_GET['page'] === $this->settings['file'] ) {
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...
126
			return true;
127
		}
128
129
		return false;
130
	}
131
132
	/**
133
	 * Revert the result of attach()
134
	 **/
135
	public function detach() {
136
		parent::detach();
137
138
		$this->drop_unique_page();
139
140
		$page_hook = get_plugin_page_hookname( $this->settings['file'], '' );
141
		remove_action( 'load-' . $page_hook, array( $this, '_save' ) );
142
	}
143
144
	/**
145
	 * Output the container markup
146
	 **/
147
	public function render() {
148
		if ( isset( $_GET['settings-updated'] ) && $_GET['settings-updated'] == 'true' ) {
149
			$this->notifications[] = __( 'Settings saved.', 'carbon-fields' );
150
		}
151
152
		include \Carbon_Fields\DIR . '/templates/Container/theme_options.php';
153
	}
154
155
	/**
156
	 * Make sure that there are no duplicate containers with the same name.
157
	 **/
158
	public function verify_unique_page() {
159
		$file = $this->settings['file'];
160
		$parent = $this->settings['parent'];
161
162
		// Register top level page
163
		if ( ! $parent ) {
164
			if ( isset( self::$registered_pages[ $file ] ) ) {
165
				Incorrect_Syntax_Exception::raise( 'Page "' . $file . '" already registered' );
166
			}
167
168
			self::$registered_pages[ $file ] = array();
169
			return;
170
		}
171
172
		// Register sub-page
173
		if ( ! isset( self::$registered_pages[ $parent ] ) ) {
174
			self::$registered_pages[ $parent ] = array( $file );
175
		} elseif ( in_array( $file, self::$registered_pages[ $parent ] ) ) {
176
			Incorrect_Syntax_Exception::raise( 'Page "' . $file . '" with parent "' . $parent . '" is already registered. Please set a different file name using setup()' );
177
		} else {
178
			self::$registered_pages[ $parent ][] = $file;
179
		}
180
	}
181
182
	/**
183
	 * Unregister the container parent and child pages.
184
	 **/
185
	public function drop_unique_page() {
186
		$file = $this->settings['file'];
187
		$parent = $this->settings['parent'];
188
189
		// Register top level page
190
		if ( ! $parent ) {
191
			if ( isset( self::$registered_pages[ $file ] ) && empty( self::$registered_pages[ $file ] ) ) {
192
				unset( self::$registered_pages[ $file ] );
193
			}
194
195
			return;
196
		}
197
198
		// Register sub-page
199
		if ( isset( self::$registered_pages[ $parent ] ) && in_array( $file, self::$registered_pages[ $parent ] ) ) {
200
201
			$index = array_search( $file, self::$registered_pages[ $parent ] );
202
			if ( $index !== false ) {
203
				unset( self::$registered_pages[ $parent ][ $index ] );
204
			}
205
		}
206
	}
207
208
	/**
209
	 * Append array of fields to the current fields set. All items of the array
210
	 * must be instances of Field and their names should be unique for all
211
	 * Carbon containers.
212
	 * If a field does not have DataStore already, the container data store is
213
	 * assigned to them instead.
214
	 *
215
	 * @param array $fields
216
	 **/
217
	public function add_fields( $fields ) {
218
		parent::add_fields( $fields );
219
220
		foreach ( $this->fields as $field ) {
221
			$field->set_prefix( '' );
222
		}
223
224
		return $this;
225
	}
226
227
	/**
228
	 * Change the parent theme options page of this container
229
	 **/
230
	public function set_page_parent( $parent ) {
231
		if ( is_a( $parent, 'Carbon_Container' ) ) {
232
			$parent = $parent->title;
233
		}
234
235
		$this->settings['parent'] = $parent;
236
		return $this;
237
	}
238
239
	/**
240
	 * Set the icon of this theme options page.
241
	 * Applicable only for parent theme option pages.
242
	 **/
243
	public function set_icon( $icon ) {
244
		$this->icon = $icon;
245
		return $this;
246
	}
247
248
	/**
249
	 * Set the theme options file name of this container.
250
	 **/
251
	public function set_page_file( $file ) {
252
		$this->settings['file'] = $file;
253
		return $this;
254
	}
255
256
	/**
257
	 * Set the permissions necessary to view
258
	 * the corresponding theme options page
259
	 **/
260
	public function set_page_permissions( $permissions ) {
261
		$this->settings['permissions'] = $permissions;
262
		return $this;
263
	}
264
265
	/**
266
	 * Sanitize the container title for use in
267
	 * the theme options file name.
268
	 **/
269
	protected function clear_string( $string ) {
270
		return preg_replace( array( '~ +~', '~[^\w\d-]+~u', '~-+~' ), array( '-', '-', '-' ), strtolower( remove_accents( $string ) ) );
271
	}
272
}
273
274