Passed
Push — master ( 06feff...e4a90e )
by Paul
02:34
created

MetaBox::normalizeCondition()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 17
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 12
nc 2
nop 1
dl 0
loc 17
rs 9.2
c 0
b 0
f 0
1
<?php
2
3
namespace GeminiLabs\Pollux;
4
5
use GeminiLabs\Pollux\Application;
6
use GeminiLabs\Pollux\Component;
7
use RecursiveArrayIterator;
8
use RecursiveIteratorIterator;
9
10
class MetaBox extends Component
11
{
12
	const CONDITIONS = [
13
		'hook', 'is_front_page', 'is_home', 'is_page_template', 'is_plugin_active',
14
		'is_plugin_inactive',
15
	];
16
17
	/**
18
	 * @var array
19
	 */
20
	public $metaboxes;
21
22
	/**
23
	 * {@inheritdoc}
24
	 */
25
	public function init()
26
	{
27
		$this->normalize();
28
29
		add_filter( 'rwmb_show',       [$this, 'isVisible'], 10, 2 );
30
		add_action( 'rwmb_meta_boxes', [$this, 'register'] );
31
	}
32
33
	/**
34
	 * @return array
35
	 */
36
	public function register( $metaboxes = [] )
37
	{
38
		if( current_user_can( 'switch_themes' )) {
39
			$this->addInstructions();
40
		}
41
		return array_merge( $metaboxes, $this->metaboxes );
42
	}
43
44
	/**
45
	 * @return bool
46
	 */
47
	public function isVisible( $bool, array $metabox )
48
	{
49
		if( defined( 'DOING_AJAX' ) && DOING_AJAX
50
			|| !isset( $metabox['condition'] )
51
			|| !$this->hasPostType( $metabox )) {
52
			return $bool;
53
		}
54
		return $this->verifyMetaBoxCondition( $metabox['condition'] );
55
	}
56
57
	/**
58
	 * @return bool
59
	 */
60
	public function verifyMetaBoxCondition( array $conditions )
61
	{
62
		array_walk( $conditions, function( &$value, $key ) {
63
			$method = $this->app->buildMethodName( $key, 'validate' );
64
			$value = method_exists( $this, $method )
65
				? $this->$method( $value )
66
				: $this->validateUnknown( $key, $value );
67
		});
68
		return !in_array( false, $conditions );
69
	}
70
71
	protected function addInstructions()
72
	{
73
		if( !count( array_filter( $this->metaboxes, function( $metabox ) {
74
			return $this->isVisible( false, $metabox );
75
		})))return;
76
		$this->metaboxes[] = [
77
			'id' => 'infodiv',
78
			'post_types' => $this->getPostTypes(),
79
			'title' => __( 'How to use in your theme', 'pollux' ),
80
			'context' => 'side',
81
			'priority' => 'low',
82
			'fields' => [[
83
				'type' => 'custom_html',
84
				'std' => $this->generateInstructions(),
85
			]],
86
		];
87
	}
88
89
	/**
90
	 * @return string
91
	 */
92
	protected function generateInstructions()
93
	{
94
		return array_reduce( $this->getInstructions(), function( $html, $metabox ) {
95
			$fields = array_reduce( array_column( $metabox['fields'], 'slug' ), function( $html, $slug ) use( $metabox ) {
96
				$hook = sprintf( 'pollux/%s/instruction', $this->getClassname() );
97
				return $html . apply_filters( $hook, "PostMeta::get('{$slug}');", $slug, $metabox['slug'] ) . PHP_EOL;
98
			});
99
			return $html . sprintf( '<p><strong>%s</strong></p><pre class="my-sites nav-tab-active misc-pub-section">%s</pre>',
100
				$metabox['title'],
101
				$fields
102
			);
103
		});
104
	}
105
106
	/**
107
	 * @return array
108
	 */
109
	protected function getInstructions()
110
	{
111
		return array_filter( $this->metaboxes, function( $metabox ) {
112
			return $this->verifyMetaBoxCondition( $metabox['condition'] )
113
				&& $this->hasPostType( $metabox );
114
		});
115
	}
116
117
	/**
118
	 * @return int
119
	 */
120
	protected function getPostId()
121
	{
122
		if( !( $postId = filter_input( INPUT_GET, 'post' ))) {
123
			$postId = filter_input( INPUT_POST, 'post_ID' );
124
		}
125
		return intval( $postId );
126
	}
127
128
	/**
129
	 * @return array
130
	 */
131
	protected function getPostTypes()
132
	{
133
		return array_unique( iterator_to_array(
134
			new RecursiveIteratorIterator(
135
				new RecursiveArrayIterator( array_column( $this->metaboxes, 'post_types' ))
136
			),
137
			false
138
		));
139
	}
140
141
	/**
142
	 * @return bool
143
	 */
144
	protected function hasPostType( array $metabox )
145
	{
146
		if( !isset( $metabox['post_types'] )) {
147
			return true;
148
		}
149
		return in_array( get_post_type( $this->getPostId() ), $metabox['post_types'] );
150
	}
151
152
	/**
153
	 * {@inheritdoc}
154
	 */
155
	protected function normalize()
156
	{
157
		$this->metaboxes = [];
158
		foreach( $this->app->config['meta_boxes'] as $id => $metabox ) {
159
			$defaults = [
160
				'condition' => [],
161
				'fields' => [],
162
				'id' => $id,
163
				'post_types' => [],
164
				'slug' => $id,
165
			];
166
			$this->metaboxes[] = $this->normalizeThis( $metabox, $defaults, $id );
167
		}
168
	}
169
170
	/**
171
	 * @param mixed $conditions
172
	 * @return array
173
	 */
174
	protected function normalizeCondition( $conditions )
175
	{
176
		$conditions = $this->toArray( $conditions );
177
		if( count( array_filter( array_keys( $conditions ), 'is_string' )) == 0 ) {
178
			foreach( $conditions as $key ) {
179
				$conditions[str_replace( '!', '', $key )] = substr( $key, 0, 1 ) == '!' ? 0 : 1;
180
			}
181
			$conditions = array_filter( $conditions, function( $key ) {
182
				return !is_numeric( $key );
183
			}, ARRAY_FILTER_USE_KEY );
184
		}
185
		$hook = sprintf( 'pollux/%s/conditions', $this->getClassname() );
186
		return array_intersect_key(
187
			$conditions,
188
			array_flip( apply_filters( $hook, self::CONDITIONS ))
189
		);
190
	}
191
192
	/**
193
	 * @return array
194
	 */
195
	protected function normalizeFields( array $fields, array $data, $parentId )
196
	{
197
		return array_map( function( $id, $field ) use( $parentId ) {
198
			$defaults =  [
199
				'id' => $id,
200
				'field_name' => '',
201
				'slug' => $id,
202
				// 'condition' => [],
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
203
				// 'depends' => [];
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
204
			];
205
			return $this->normalizeThis( $field, $defaults, $parentId );
206
		}, array_keys( $fields ), $fields );
207
	}
208
209
	/**
210
	 * @param string $id
211
	 * @param string $parentId
212
	 * @return string
213
	 */
214
	protected function normalizeId( $id, array $data, $parentId )
215
	{
216
		return Application::PREFIX . $id;
217
	}
218
219
	/**
220
	 * @param mixed $types
221
	 * @return array
222
	 */
223
	protected function normalizePostTypes( $types )
224
	{
225
		return $this->toArray( $types );
226
	}
227
228
	/**
229
	 * @param string $value
230
	 * @return bool
231
	 */
232
	protected function validateHook( $value )
233
	{
234
		return apply_filters( $value, true );
235
	}
236
237
	/**
238
	 * @param bool $value
239
	 * @return bool
240
	 */
241
	protected function validateIsFrontPage( $value )
242
	{
243
		return $value == ( $this->getPostId() == get_option( 'page_on_front' ));
244
	}
245
246
	/**
247
	 * @param bool $value
248
	 * @return bool
249
	 */
250
	protected function validateIsHome( $value )
251
	{
252
		return $value == ( $this->getPostId() == get_option( 'page_for_posts' ));
253
	}
254
255
	/**
256
	 * @param string $value
257
	 * @return bool
258
	 */
259
	protected function validateIsPageTemplate( $value )
260
	{
261
		return basename( get_page_template_slug( $this->getPostId() )) == $value;
262
	}
263
264
	/**
265
	 * @param string $value
266
	 * @return bool
267
	 */
268
	protected function validateIsPluginActive( $value )
269
	{
270
		return is_plugin_active( $value );
271
	}
272
273
	/**
274
	 * @param string $value
275
	 * @return bool
276
	 */
277
	protected function validateIsPluginInactive( $value )
278
	{
279
		return is_plugin_inactive( $value );
280
	}
281
282
	/**
283
	 * @param string $key
284
	 * @param mixed $value
285
	 * @return bool
286
	 */
287
	protected function validateUnknown( $key, $value )
288
	{
289
		return apply_filters( 'pollux/metabox/condition', true, $key, $value );
290
	}
291
}
292