Passed
Push — develop ( f91847...084281 )
by Paul
03:07
created

MetaBox::action()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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