Completed
Push — milestone/2_0/react-ui ( 75a435...d33541 )
by
unknown
03:48
created

Theme_Options_Container   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 284
Duplicated Lines 3.87 %

Coupling/Cohesion

Components 4
Dependencies 3

Test Coverage

Coverage 0%

Importance

Changes 5
Bugs 1 Features 0
Metric Value
dl 11
loc 284
rs 9
c 5
b 1
f 0
ccs 0
cts 122
cp 0
wmc 35
lcom 4
cbo 3

17 Methods

Rating   Name   Duplication   Size   Complexity  
A is_valid_save() 0 7 2
A get_environment_for_request() 0 3 1
A is_valid_attach_for_request() 0 3 1
A get_environment_for_object() 0 3 1
A is_valid_attach_for_object() 0 3 1
A render() 0 9 3
B register_page() 0 28 5
A __construct() 11 11 3
A title_to_filename() 0 15 1
A init() 0 10 3
A save() 0 13 3
B attach() 0 29 2
A should_activate() 0 9 4
A set_page_parent() 0 9 2
A set_page_file() 0 4 1
A set_page_position() 0 4 1
A set_icon() 0 4 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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