MetaBox   B
last analyzed

Complexity

Total Complexity 44

Size/Duplication

Total Lines 278
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 6
Bugs 2 Features 1
Metric Value
eloc 97
c 6
b 2
f 1
dl 0
loc 278
ccs 0
cts 109
cp 0
rs 8.8798
wmc 44

19 Methods

Rating   Name   Duplication   Size   Complexity  
A renderField() 0 5 3
A getMetaValue() 0 4 1
A filter() 0 3 1
A normalizeValidation() 0 10 4
A action() 0 3 1
A register() 0 12 4
A getPostId() 0 6 2
A getPostTypes() 0 7 1
A normalizeFieldName() 0 3 1
A normalizePostTypes() 0 3 1
A setDependencies() 0 18 4
A normalizeFields() 0 14 1
A normalizeId() 0 3 1
A init() 0 10 2
A normalize() 0 12 2
A show() 0 8 4
A normalizeDepends() 0 5 3
A normalizeMapField() 0 13 5
A hasPostType() 0 9 3

How to fix   Complexity   

Complex Class

Complex classes like MetaBox often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use MetaBox, and based on these observations, apply Extract Interface, too.

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;
0 ignored issues
show
Bug introduced by
The trait GeminiLabs\Pollux\MetaBox\Condition requires the property $gatekeeper which is not provided by GeminiLabs\Pollux\MetaBox\MetaBox.
Loading history...
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
		$this->normalize( $this->app->config->{static::ID}, [
37
			'post_types' => [],
38
		]);
39
		add_filter( 'rwmb_normalize_map_field', [$this, 'normalizeMapField'] );
40
		add_filter( 'rwmb_show',                [$this, 'show'], 10, 2 );
41
		add_filter( 'rwmb_meta_boxes',          [$this, 'register'] );
42
		add_filter( 'rwmb_outer_html',          [$this, 'renderField'], 10, 2 );
43
	}
44
45
	/**
46
	 * @param string $name
47
	 * @param mixed ...$args
48
	 * @return void
49
	 */
50
	public function action( $name, ...$args )
51
	{
52
		return do_action_ref_array( sprintf( 'pollux/%s/%s', static::ID, $name ), $args );
0 ignored issues
show
Bug introduced by
Are you sure the usage of do_action_ref_array(spri...tic::ID, $name), $args) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
53
	}
54
55
	/**
56
	 * @param string $name
57
	 * @param mixed ...$args
58
	 * @return mixed
59
	 */
60
	public function filter( $name, ...$args )
61
	{
62
		return apply_filters_ref_array( sprintf( 'pollux/%s/%s', static::ID, $name ), $args );
63
	}
64
65
	/**
66
	 * @param string $key
67
	 * @param mixed $fallback
68
	 * @param string $group
69
	 * @return string|array
70
	 */
71
	public function getMetaValue( $key, $fallback = '', $group = '' )
0 ignored issues
show
Unused Code introduced by
The parameter $group is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

71
	public function getMetaValue( $key, $fallback = '', /** @scrutinizer ignore-unused */ $group = '' )

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $fallback is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

71
	public function getMetaValue( $key, /** @scrutinizer ignore-unused */ $fallback = '', $group = '' )

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
72
	{
73
		return PostMeta::get( $key, [
74
			'id' => $this->getPostId(),
75
		]);
76
	}
77
78
	/**
79
	 * @param array $field
80
	 * @return array
81
	 */
82
	public function normalizeMapField( $field )
83
	{
84
		if( empty( $field['address_field'] )) {
85
			return $field;
86
		}
87
		if( !Helper::startsWith( Application::PREFIX, $field['address_field'] )) {
88
			$field['address_field'] = Application::PREFIX . $field['address_field'];
89
		}
90
		$apiKey = SiteMeta::services( $field['api_key'] );
0 ignored issues
show
Bug introduced by
The method services() does not exist on GeminiLabs\Pollux\Facades\SiteMeta. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

90
		/** @scrutinizer ignore-call */ 
91
  $apiKey = SiteMeta::services( $field['api_key'] );
Loading history...
91
		if( !empty( $apiKey ) && is_string( $apiKey )) {
92
			$field['api_key'] = $apiKey;
93
		}
94
		return $field;
95
	}
96
97
	/**
98
	 * @return array
99
	 * @filter rwmb_meta_boxes
100
	 */
101
	public function register()
102
	{
103
		if( current_user_can( 'switch_themes' )) {
104
			$instructions = $this->initInstructions();
105
			if( is_array( $instructions )) {
106
				$this->normalize( $instructions );
107
			}
108
		}
109
		$metaboxes = func_num_args()
110
			? Helper::toArray( func_get_arg(0) )
111
			: [];
112
		return array_merge( $metaboxes, $this->metaboxes );
113
	}
114
115
	/**
116
	 * @return string
117
	 * @filter rwmb_outer_html
118
	 */
119
	public function renderField( $html, $field )
120
	{
121
		return !isset( $field['condition'] ) || $this->validate( $field['condition'] )
122
			? $html
123
			: '';
124
	}
125
126
	/**
127
	 * @return bool
128
	 * @filter rwmb_show
129
	 */
130
	public function show( $bool, array $metabox )
131
	{
132
		if( defined( 'DOING_AJAX' )
133
			|| !isset( $metabox['condition'] )
134
			|| !$this->hasPostType( $metabox )) {
135
			return $bool;
136
		}
137
		return $this->validate( $metabox['condition'] );
138
	}
139
140
	/**
141
	 * @return int
142
	 */
143
	protected function getPostId()
144
	{
145
		if( !( $postId = filter_input( INPUT_GET, 'post' ))) {
146
			$postId = filter_input( INPUT_POST, 'post_ID' );
147
		}
148
		return intval( $postId );
149
	}
150
151
	/**
152
	 * @return array
153
	 */
154
	protected function getPostTypes()
155
	{
156
		return array_unique( iterator_to_array(
157
			new RecursiveIteratorIterator(
158
				new RecursiveArrayIterator( array_column( $this->metaboxes, 'post_types' ))
159
			),
160
			false
161
		));
162
	}
163
164
	/**
165
	 * @return bool
166
	 */
167
	protected function hasPostType( array $metabox )
168
	{
169
		if( !isset( $metabox['post_types'] )) {
170
			return true;
171
		}
172
		if( !( $type = filter_input( INPUT_GET, 'post_type' ))) {
173
			$type = get_post_type( $this->getPostId() );
174
		}
175
		return in_array( $type, $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 )
0 ignored issues
show
Unused Code introduced by
The parameter $data is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

222
	protected function normalizeFields( array $fields, /** @scrutinizer ignore-unused */ array $data, $parentId )

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
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 Helper::toArray( $types );
255
	}
256
257
	/**
258
	 * @return array
259
	 */
260
	protected function normalizeValidation( array $validation, array $data, $parentId )
0 ignored issues
show
Unused Code introduced by
The parameter $data is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

260
	protected function normalizeValidation( array $validation, /** @scrutinizer ignore-unused */ array $data, $parentId )

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
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
			$fields[$index]['attributes']['data-depends'] = $value;
282
			list( $key, $value ) = array_pad( explode( '|', $value ), 2, null );
283
			$dependency = array_search( $key, array_column( $fields, 'id' ));
284
			$metaValue = $this->getMetaValue( $fields[$dependency]['slug'], '', $metabox['slug'] );
285
			$isHidden = $value === null
286
				? $metaValue === ''
287
				: $metaValue != $value;
288
			if( $isHidden ) {
289
				$fields[$index]['class'] = trim( 'hidden ' . $fields[$index]['class'] );
290
			}
291
		});
292
		return $metabox;
293
	}
294
}
295