Completed
Push — milestone/2_0/container-condit... ( af96ef...c41f81 )
by
unknown
03:01
created

Theme_Options_Container::render()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 4
nop 0
dl 0
loc 8
ccs 0
cts 7
cp 0
crap 12
rs 9.4285
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' => '',
17
		'file' => '',
18
	);
19
20
	public $icon = '';
21
22
	/**
23
	 * Create a new container
24
	 *
25
	 * @param string $unique_id Unique id of the container
26
	 * @param string $title title of the container
27
	 * @param string $type Type of the container
28
	 **/
29 View Code Duplication
	public function __construct( $unique_id, $title, $type ) {
30
		parent::__construct( $unique_id, $title, $type );
31
32
		if ( ! $this->get_datastore() ) {
33
			$this->set_datastore( Datastore::make( 'theme_options' ), $this->has_default_datastore() );
34
		}
35
	}
36
37
	/**
38
	 * Attach container as a theme options page/subpage.
39
	 **/
40
	public function init() {
41
		if ( $this->settings['parent'] !== '' && strpos( $this->settings['parent'], '.php' ) === false ) {
42
			$clear_title = $this->clear_string( $this->settings['parent'] );
43
			$this->settings['parent'] = 'crbn-' . $clear_title . '.php';
44
		}
45
46
		if ( ! $this->settings['file'] ) {
47
			$clear_title = $this->clear_string( $this->title );
48
			$this->settings['file'] .= 'crbn-' . $clear_title . '.php';
49
		}
50
51
		$this->verify_unique_page();
52
53
		add_action( 'admin_menu', array( $this, '_attach' ) );
54
	}
55
56
	/**
57
	 * Perform checks whether the current save() request is valid.
58
	 *
59
	 * @return bool
60
	 **/
61
	public function is_valid_save() {
62
		if ( ! $this->verified_nonce_in_request() ) {
63
			return false;
64
		}
65
66
		return $this->is_valid_attach_for_object();
67
	}
68
69
	/**
70
	 * Perform save operation after successful is_valid_save() check.
71
	 * The call is propagated to all fields in the container.
72
	 *
73
	 * @param mixed $user_data
74
	 **/
75
	public function save( $user_data = null ) {
76
		try {
77
			parent::save( $user_data );
78
		} catch ( Incorrect_Syntax_Exception $e ) {
79
			$this->errors[] = $e->getMessage();
80
		}
81
82
		do_action( 'carbon_after_save_theme_options', $user_data );
83
84
		if ( ! headers_sent() ) {
85
			wp_redirect( add_query_arg( array( 'settings-updated' => 'true' ) ) );
86
		}
87
	}
88
89
	/**
90
	 * Get environment array for page request (in admin)
91
	 *
92
	 * @return array
93
	 **/
94
	protected function get_environment_for_request() {
95
		return array();
96
	}
97
98
	/**
99
	 * Perform checks whether the container should be attached during the current request
100
	 *
101
	 * @return bool True if the container is allowed to be attached
102
	 **/
103 View Code Duplication
	public function is_valid_attach_for_request() {
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...
104
		$environment = $this->get_environment_for_request();
105
		$static_conditions_collection = $this->conditions_collection->evaluate( $this->get_dynamic_conditions(), true );
1 ignored issue
show
Comprehensibility Naming introduced by
The variable name $static_conditions_collection exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
106
		if ( ! $static_conditions_collection->is_fulfilled( $environment ) ) {
107
			return false;
108
		}
109
		
110
		return true;
111
	}
112
113
	/**
114
	 * Get environment array for object id
115
	 *
116
	 * @return array
117
	 */
118
	protected function get_environment_for_object( $object_id ) {
119
		return array();
120
	}
121
122
	/**
123
	 * Check container attachment rules against object id
124
	 *
125
	 * @param int $object_id
126
	 * @return bool
127
	 **/
128 View Code Duplication
	public function is_valid_attach_for_object( $object_id = null ) {
1 ignored issue
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...
129
		$environment = $this->get_environment_for_object( intval( $object_id ) );
130
		if ( ! $this->conditions_collection->is_fulfilled( $environment ) ) {
131
			return false;
132
		}
133
		return true;
134
	}
135
136
	/**
137
	 * Add theme options container pages.
138
	 * Hook the container saving action.
139
	 **/
140
	public function attach() {
141
		// use the "read" capability because conditions will handle actual access and save capability checking
142
		// before the attach() method is called
143
144
		// Add menu page
145
		if ( ! $this->settings['parent'] ) {
146
			add_menu_page(
147
				$this->title,
148
				$this->title,
149
				'read',
150
				$this->settings['file'],
151
				array( $this, 'render' ),
152
				$this->icon
153
			);
154
		}
155
156
		add_submenu_page(
157
			$this->settings['parent'],
158
			$this->title,
159
			$this->title,
160
			'read',
161
			$this->settings['file'],
162
			array( $this, 'render' ),
163
			$this->icon
164
		);
165
166
		$page_hook = get_plugin_page_hookname( $this->settings['file'], '' );
167
		add_action( 'load-' . $page_hook, array( $this, '_save' ) );
168
	}
169
170
	/**
171
	 * Whether this container is currently viewed.
172
	 **/
173
	public function should_activate() {
174
		$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...
175
		if ( ! empty( $request_page ) && $request_page === $this->settings['file'] ) {
176
			return true;
177
		}
178
179
		return false;
180
	}
181
182
	/**
183
	 * Output the container markup
184
	 **/
185
	public function render() {
186
		$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...
187
		if ( $request_settings_updated === 'true' ) {
188
			$this->notifications[] = __( 'Settings saved.', \Carbon_Fields\TEXT_DOMAIN );
189
		}
190
191
		include \Carbon_Fields\DIR . '/templates/Container/theme_options.php';
192
	}
193
194
	/**
195
	 * Make sure that there are no duplicate containers with the same name.
196
	 **/
197
	public function verify_unique_page() {
198
		$file = $this->settings['file'];
199
		$parent = $this->settings['parent'];
200
201
		if ( ! $parent ) {
202
			// Register top level page
203
			if ( isset( static::$registered_pages[ $file ] ) ) {
204
				Incorrect_Syntax_Exception::raise( 'Page "' . $file . '" already registered' );
205
			}
206
207
			static::$registered_pages[ $file ] = array();
208
			return;
209
		}
210
211
		// Register sub-page
212
		if ( ! isset( static::$registered_pages[ $parent ] ) ) {
213
			static::$registered_pages[ $parent ] = array();
214
		}
215
216
		if ( in_array( $file, static::$registered_pages[ $parent ] ) ) {
217
			Incorrect_Syntax_Exception::raise( 'Page "' . $file . '" with parent "' . $parent . '" is already registered. Please set a name for the container.' );
218
		}
219
220
		static::$registered_pages[ $parent ][] = $file;
221
	}
222
223
	/**
224
	 * Sanitize the container title for use in
225
	 * the theme options file name.
226
	 **/
227
	protected function clear_string( $string ) {
228
		return preg_replace( array( '~ +~', '~[^\w\d-]+~u', '~-+~' ), array( '-', '-', '-' ), strtolower( remove_accents( $string ) ) );
229
	}
230
231
	/**
232
	 * COMMON USAGE METHODS
233
	 */
234
235
	/**
236
	 * Change the parent theme options page of this container
237
	 **/
238
	public function set_page_parent( $parent ) {
239
		if ( is_a( $parent, 'Carbon_Container' ) ) {
240
			$parent = $parent->title;
241
		}
242
243
		$this->settings['parent'] = $parent;
244
		return $this;
245
	}
246
247
	/**
248
	 * Set the icon of this theme options page.
249
	 * Applicable only for parent theme option pages.
250
	 **/
251
	public function set_icon( $icon ) {
252
		$this->icon = $icon;
253
		return $this;
254
	}
255
256
	/**
257
	 * Set the theme options file name of this container.
258
	 **/
259
	public function set_page_file( $file ) {
260
		$this->settings['file'] = $file;
261
		return $this;
262
	}
263
}
264
265