Passed
Push — develop ( a91f78...5f7986 )
by Paul
06:48 queued 03:30
created

MetaBox::normalizeMapField()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 9
nc 5
nop 1
dl 0
loc 14
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
namespace GeminiLabs\Pollux\MetaBox;
4
5
use GeminiLabs\Pollux\Application;
6
use GeminiLabs\Pollux\Component;
7
use GeminiLabs\Pollux\Facades\PostMeta;
8
use GeminiLabs\Pollux\Facades\SiteMeta;
9
use GeminiLabs\Pollux\Helper;
10
use GeminiLabs\Pollux\MetaBox\Condition;
11
use GeminiLabs\Pollux\MetaBox\Instruction;
12
use RecursiveArrayIterator;
13
use RecursiveIteratorIterator;
14
15
class MetaBox extends Component
16
{
17
	use Condition;
18
	use Instruction;
19
20
	/**
21
	 * @var string
22
	 */
23
	const ID = 'metaboxes';
24
25
	/**
26
	 * @var array
27
	 */
28
	public $metaboxes = [];
29
30
	/**
31
	 * {@inheritdoc}
32
	 */
33
	public function init()
34
	{
35
		if( empty( $this->app->config->{static::ID} ))return;
36
37
		$this->normalize( $this->app->config->{static::ID}, [
38
			'post_types' => [],
39
		]);
40
41
		add_filter( 'rwmb_normalize_map_field', [$this, 'normalizeMapField'] );
42
		add_filter( 'rwmb_show',                [$this, 'show'], 10, 2 );
43
		add_filter( 'rwmb_meta_boxes',          [$this, 'register'] );
44
		add_filter( 'rwmb_outer_html',          [$this, 'renderField'], 10, 2 );
45
46
	}
47
48
	/**
49
	 * @param string $name
50
	 * @param mixed ...$args
51
	 * @return void
52
	 */
53
	public function action( $name, ...$args )
54
	{
55
		return do_action_ref_array( sprintf( 'pollux/%s/%s', static::ID, $name ), $args );
56
	}
57
58
	/**
59
	 * @param string $name
60
	 * @param mixed ...$args
61
	 * @return mixed
62
	 */
63
	public function filter( $name, ...$args )
64
	{
65
		return apply_filters_ref_array( sprintf( 'pollux/%s/%s', static::ID, $name ), $args );
66
	}
67
68
	/**
69
	 * @param string $key
70
	 * @param mixed $fallback
71
	 * @param string $group
72
	 * @return string|array
73
	 */
74
	public function getMetaValue( $key, $fallback = '', $group = '' )
75
	{
76
		return PostMeta::get( $key, [
77
			'id' => $this->getPostId(),
78
		]);
79
	}
80
81
	/**
82
	 * @param array $field
83
	 * @return array
84
	 */
85
	public function normalizeMapField( $field )
86
	{
87
		if( empty( $field['address_field'] )) {
88
			return $field;
89
		}
90
		if( !$this->app->make( Helper::class )->startsWith( Application::PREFIX, $field['address_field'] )) {
91
			$field['address_field'] = Application::PREFIX . $field['address_field'];
92
		}
93
		$apiKey = SiteMeta::services( $field['api_key'] );
94
		if( !empty( $apiKey ) && is_string( $apiKey )) {
95
			$field['api_key'] = $apiKey;
96
		}
97
		return $field;
98
	}
99
100
	/**
101
	 * @return array
102
	 * @filter rwmb_meta_boxes
103
	 */
104
	public function register()
105
	{
106
		if( current_user_can( 'switch_themes' )) {
107
			$instructions = $this->initInstructions();
108
			if( is_array( $instructions )) {
109
				$this->normalize( $instructions );
110
			}
111
		}
112
		$metaboxes = func_num_args()
113
			? ( new Helper )->toArray( func_get_arg(0) )
114
			: [];
115
		return array_merge( $metaboxes, $this->metaboxes );
116
	}
117
118
	/**
119
	 * @return string
120
	 * @filter rwmb_outer_html
121
	 */
122
	public function renderField( $html, $field )
123
	{
124
		return $this->validate( $field['condition'] )
125
			? $html
126
			: '';
127
	}
128
129
	/**
130
	 * @return bool
131
	 * @filter rwmb_show
132
	 */
133
	public function show( $bool, array $metabox )
134
	{
135
		if( defined( 'DOING_AJAX' )
136
			|| !isset( $metabox['condition'] )
137
			|| !$this->hasPostType( $metabox )) {
138
			return $bool;
139
		}
140
		return $this->validate( $metabox['condition'] );
141
	}
142
143
	/**
144
	 * @return int
145
	 */
146
	protected function getPostId()
147
	{
148
		if( !( $postId = filter_input( INPUT_GET, 'post' ))) {
149
			$postId = filter_input( INPUT_POST, 'post_ID' );
150
		}
151
		return intval( $postId );
152
	}
153
154
	/**
155
	 * @return array
156
	 */
157
	protected function getPostTypes()
158
	{
159
		return array_unique( iterator_to_array(
160
			new RecursiveIteratorIterator(
161
				new RecursiveArrayIterator( array_column( $this->metaboxes, 'post_types' ))
162
			),
163
			false
164
		));
165
	}
166
167
	/**
168
	 * @return bool
169
	 */
170
	protected function hasPostType( array $metabox )
171
	{
172
		if( !isset( $metabox['post_types'] )) {
173
			return true;
174
		}
175
		return in_array( get_post_type( $this->getPostId() ), $metabox['post_types'] );
176
	}
177
178
	/**
179
	 * @return void
180
	 */
181
	protected function normalize( array $metaboxes, array $defaults = [] )
182
	{
183
		foreach( $metaboxes as $id => $metabox ) {
184
			$data = wp_parse_args( $defaults, [
185
				'condition' => [],
186
				'fields' => [],
187
				'id' => $id,
188
				'slug' => $id,
189
				'validation' => [],
190
			]);
191
			$this->metaboxes[] = $this->setDependencies(
192
				$this->normalizeThis( $metabox, $data, $id )
193
			);
194
		}
195
	}
196
197
	/**
198
	 * @param string $depends
199
	 * @param string $parentId
200
	 * @return string
201
	 */
202
	protected function normalizeDepends( $depends, array $data, $parentId )
203
	{
204
		return is_string( $depends ) && !empty( $depends )
205
			? $this->normalizeId( $depends, $data, $parentId )
206
			: '';
207
	}
208
209
	/**
210
	 * @param string $name
211
	 * @param string $parentId
212
	 * @return string
213
	 */
214
	protected function normalizeFieldName( $name, array $data, $parentId )
215
	{
216
		return $this->normalizeId( $name, $data, $parentId );
217
	}
218
219
	/**
220
	 * @return array
221
	 */
222
	protected function normalizeFields( array $fields, array $data, $parentId )
223
	{
224
		return array_map( function( $id, $field ) use( $parentId ) {
225
			$defaults =  [
226
				'attributes' => [],
227
				'class' => '',
228
				'condition' => [],
229
				'depends' => '',
230
				'field_name' => $id,
231
				'id' => $id,
232
				'slug' => $id,
233
			];
234
			return $this->normalizeThis( $field, $defaults, $parentId );
235
		}, array_keys( $fields ), $fields );
236
	}
237
238
	/**
239
	 * @param string $id
240
	 * @param string $parentId
241
	 * @return string
242
	 */
243
	protected function normalizeId( $id, array $data, $parentId )
244
	{
245
		return Application::prefix() . $id;
246
	}
247
248
	/**
249
	 * @param mixed $types
250
	 * @return array
251
	 */
252
	protected function normalizePostTypes( $types )
253
	{
254
		return ( new Helper )->toArray( $types );
255
	}
256
257
	/**
258
	 * @return array
259
	 */
260
	protected function normalizeValidation( array $validation, array $data, $parentId )
261
	{
262
		foreach( ['messages', 'rules'] as $key ) {
263
			if( empty( $validation[$key] ))continue;
264
			foreach( $validation[$key] as $id => $value ) {
265
				$validation[$key][$this->normalizeFieldName( $id, ['slug' => $id], $parentId )] = $value;
266
				unset( $validation[$key][$id] );
267
			}
268
		}
269
		return $validation;
270
	}
271
272
	/**
273
	 * @return array
274
	 */
275
	protected function setDependencies( array $metabox )
276
	{
277
		$fields = &$metabox['fields'];
278
		$depends = array_column( $fields, 'depends' );
279
		array_walk( $depends, function( $value, $index ) use( &$fields, $metabox ) {
280
			if( empty( $value ))return;
281
			$dependency = array_search( $value, array_column( $fields, 'id' ));
282
			$fields[$index]['attributes']['data-depends'] = $value;
283
			if( !$this->getMetaValue( $fields[$dependency]['slug'], '', $metabox['slug'] )) {
284
				$fields[$index]['class'] = trim( 'hidden ' . $fields[$index]['class'] );
285
			}
286
		});
287
		return $metabox;
288
	}
289
}
290