Meta_Box_Registrar::is_active()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 4
c 1
b 0
f 0
dl 0
loc 6
rs 10
cc 3
nc 3
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * Registration Registrar for all post types.
7
 *
8
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
9
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
10
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
11
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
12
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
13
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
14
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
15
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
16
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
18
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19
 *
20
 * @author Glynn Quelch <[email protected]>
21
 * @license http://www.opensource.org/licenses/mit-license.html  MIT License
22
 * @package PinkCrab\Registerables
23
 */
24
25
namespace PinkCrab\Registerables\Registrar;
26
27
use Exception;
28
use PinkCrab\Loader\Hook_Loader;
29
use PinkCrab\Registerables\Meta_Box;
30
use PinkCrab\Perique\Services\View\View;
31
use PinkCrab\Perique\Interfaces\DI_Container;
32
use PinkCrab\Registerables\Validator\Meta_Box_Validator;
33
34
class Meta_Box_Registrar {
35
36
	protected Meta_Box_Validator $validator;
37
	protected DI_Container $container;
38
	protected Hook_Loader $loader;
39
40
	public function __construct(
41
		Meta_Box_Validator $validator,
42
		DI_Container $container,
43
		Hook_Loader $loader
44
	) {
45
		$this->validator = $validator;
46
		$this->container = $container;
47
		$this->loader    = $loader;
48
	}
49
50
	/**
51
	 * Register a meta box.
52
	 *
53
	 * @param Meta_Box $meta_box
54
	 * @return void
55
	 */
56
	public function register( Meta_Box $meta_box ): void {
57
58
		if ( ! $this->validator->verify_meta_box( $meta_box ) ) {
59
			throw new Exception(
60
				sprintf(
61
					'Failed validating meta box model(%s) with errors: %s',
62
					esc_html( get_class( $meta_box ) ),
63
					esc_html( join( ', ', $this->validator->get_errors() ) )
64
				)
65
			);
66
		}
67
68
		// Set the view using View, if not traditional callback supplied and a defined template.
69
		if ( ! \is_callable( $meta_box->view ) && is_string( $meta_box->view_template ) ) {
70
			$meta_box = $this->set_view_callback_from_renderable( $meta_box );
71
		}
72
		if ( \is_callable( $meta_box->view ) ) {
73
			$meta_box = $this->set_view_callback_from_callable( $meta_box );
74
		}
75
76
		// Add meta_box to loader.
77
		$this->loader->action(
78
			'add_meta_boxes',
79
			function () use ( $meta_box ): void {
80
				\add_meta_box(
81
					$meta_box->key,
82
					$meta_box->label,
83
					$meta_box->view ?? fn( $e ) => '', // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found
0 ignored issues
show
Unused Code introduced by
The parameter $e 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

83
					$meta_box->view ?? fn( /** @scrutinizer ignore-unused */ $e ) => '', // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found

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...
84
					/***
85
					* @phpstan-ignore-line, is validated above
86
					*/
87
					$meta_box->screen,
88
					$meta_box->context,
89
					$meta_box->priority,
90
					$meta_box->view_vars
91
				);
92
			}
93
		);
94
95
		// Deffer adding meta box hooks until we can asses the current screen.
96
		$this->loader->action(
97
			'current_screen',
98
			function () use ( $meta_box ) {
99
				// If we have any hook calls, add them to the loader.
100
				if ( $this->is_active( $meta_box ) && ! empty( $meta_box->actions ) ) {
101
					foreach ( $meta_box->actions as $handle => $hook ) {
102
						add_action( (string) $handle, $hook['callback'], $hook['priority'], $hook['params'] );
103
					}
104
				}
105
			}
106
		);
107
	}
108
109
	/**
110
	 * Sets the view callback for a view which is defined as a callback.
111
	 *
112
	 * @param \PinkCrab\Registerables\Meta_Box $meta_box
113
	 * @return \PinkCrab\Registerables\Meta_Box
114
	 */
115
	protected function set_view_callback_from_callable( Meta_Box $meta_box ): Meta_Box {
116
117
		// Get the current view callback.
118
		$current_callback = $meta_box->view;
119
120
		$meta_box->view(
121
			function ( \WP_Post $post, array $args ) use ( $meta_box, $current_callback ) {
122
123
				// Set the view args
124
				$args['args']['post'] = $post;
125
				$args['args']         = $this->filter_view_args( $meta_box, $post, $args['args'] );
126
127
				// Render the callback.
128
				if ( \is_callable( $current_callback ) ) {
129
					call_user_func( $current_callback, $post, $args );
0 ignored issues
show
Bug introduced by
It seems like $current_callback can also be of type null; however, parameter $callback of call_user_func() does only seem to accept callable, maybe add an additional type check? ( Ignorable by Annotation )

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

129
					call_user_func( /** @scrutinizer ignore-type */ $current_callback, $post, $args );
Loading history...
130
				}
131
			}
132
		);
133
134
		return $meta_box;
135
	}
136
137
	/**
138
	 * Apply rendering the view using View to a meta_box
139
	 *
140
	 * @param \PinkCrab\Registerables\Meta_Box $meta_box
141
	 * @return \PinkCrab\Registerables\Meta_Box
142
	 */
143
	protected function set_view_callback_from_renderable( Meta_Box $meta_box ): Meta_Box {
144
145
		// Create View(View)
146
		$view = $this->container->create( View::class );
147
		if ( is_null( $view ) || ! is_a( $view, View::class ) ) {
148
			throw new Exception( 'View not defined' );
149
		}
150
151
		$meta_box->view(
152
			function ( \WP_Post $post, array $args ) use ( $meta_box, $view ) {
153
154
				$args['args']['post'] = $post;
155
				$args['args']         = $this->filter_view_args( $meta_box, $post, $args['args'] );
156
157
				// @phpstan-ignore-next-line, template should already be checked for valid template path in register() method (which calls this)
158
				$view->render( $meta_box->view_template, $args['args'] );
0 ignored issues
show
Bug introduced by
It seems like $meta_box->view_template can also be of type null; however, parameter $view of PinkCrab\Perique\Services\View\View::render() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

158
				$view->render( /** @scrutinizer ignore-type */ $meta_box->view_template, $args['args'] );
Loading history...
159
			}
160
		);
161
162
		return $meta_box;
163
	}
164
165
	/**
166
	 * Checks if the checkbox should be active.
167
	 *
168
	 * @return boolean
169
	 */
170
	protected function is_active( Meta_Box $meta_box ): bool {
171
		global $current_screen;
172
173
		return ! is_null( $current_screen )
174
		&& ! empty( $current_screen->post_type )
175
		&& in_array( $current_screen->post_type, $meta_box->screen, true );
176
	}
177
178
	/**
179
	 * Filters the render time args through the optional
180
	 * callback definition in model class.
181
	 *
182
	 * @param \PinkCrab\Registerables\Meta_Box $meta_box
183
	 * @param array<string, mixed>             $view_args
184
	 * @return array<string, mixed>
185
	 */
186
	public function filter_view_args( Meta_Box $meta_box, \WP_Post $post, array $view_args ): array {
187
		if ( is_callable( $meta_box->view_data_filter ) ) {
188
			$view_args = ( $meta_box->view_data_filter )( $post, $view_args );
189
		}
190
		return $view_args;
191
	}
192
}
193