WP_Rest_Registrar   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 111
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 37
c 2
b 0
f 0
dl 0
loc 111
rs 10
wmc 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A compose_permission_callback() 0 14 3
A parse_options() 0 19 3
A create_callback() 0 4 1
A parse_args() 0 8 1
A is_valid_method() 0 8 1
A map_to_wp_rest() 0 6 1
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * Registers routes through WP API from Route mooels.
7
 *
8
 * @package PinkCrab\Route\Route
9
 * @author Glynn Quelch [email protected]
10
 * @since 0.0.1
11
 */
12
13
namespace PinkCrab\Route\Registration;
14
15
use PinkCrab\Route\Route\Route;
16
use PinkCrab\Route\Route_Exception;
17
use PinkCrab\WP_Rest_Schema\Argument\Argument;
18
use PinkCrab\WP_Rest_Schema\Parser\Argument_Parser;
19
use function PinkCrab\FunctionConstructors\Comparisons\all;
20
21
class WP_Rest_Registrar {
22
23
	/**
24
	 * The register wp rest callback.
25
	 *
26
	 * @param \PinkCrab\Route\Route\Route $route
27
	 * @return callable
28
	 */
29
	public function create_callback( Route $route ): callable {
30
		return function() use ( $route ): void {
31
			$model = $this->map_to_wp_rest( $route );
32
			register_rest_route( $model->namespace, $model->route, $model->args );
33
		};
34
	}
35
36
	/**
37
	 * Maps a wp rest model from Route.
38
	 *
39
	 * @param \PinkCrab\Route\Route\Route $route
40
	 * @return WP_Rest_Route
41
	 */
42
	public function map_to_wp_rest( Route $route ): WP_Rest_Route {
43
		$wp_rest            = new WP_Rest_Route();
44
		$wp_rest->namespace = $route->get_namespace();
45
		$wp_rest->route     = $route->get_route();
46
		$wp_rest->args      = $this->parse_options( $route );
47
		return $wp_rest;
48
	}
49
50
	/**
51
	 * Parsed the args array used to register.
52
	 *
53
	 * @param Route $route
54
	 * @return array<mixed>
55
	 * @throws Route_Exception
56
	 */
57
	protected function parse_options( Route $route ): array {
58
59
		// If we have no callback defined for route, throw.
60
		if ( is_null( $route->get_callback() ) ) {
0 ignored issues
show
introduced by
The condition is_null($route->get_callback()) is always false.
Loading history...
61
			throw Route_Exception::callback_not_defined( $route );
62
		}
63
64
		// If we have an invlaid method, throw
65
		if ( ! $this->is_valid_method( $route->get_method() ) ) {
66
			throw Route_Exception::invalid_http_method( $route );
67
		}
68
69
		$options                        = array();
70
		$options['methods']             = $route->get_method();
71
		$options['callback']            = $route->get_callback();
72
		$options['permission_callback'] = $this->compose_permission_callback( $route );
73
		$options['args']                = $this->parse_args( $route );
74
75
		return $options;
76
	}
77
78
	/**
79
	 * Parsed the args array of options.
80
	 *
81
	 * @param Route $route
82
	 * @return array<mixed>
83
	 */
84
	protected function parse_args( Route $route ): array {
85
		return array_reduce(
86
			$route->get_arguments(),
87
			function( array $args, Argument $argument ) {
88
				$args[ $argument->get_key() ] = Argument_Parser::as_single( $argument );
89
				return $args;
90
			},
91
			array()
92
		);
93
	}
94
95
	/**
96
	 * Checks if a defined HTTP method is valid.
97
	 *
98
	 * @param string $method
99
	 * @return boolean
100
	 */
101
	protected function is_valid_method( string $method ): bool {
102
		return in_array(
103
			$method,
104
			apply_filters(
105
				'pinkcrab/route/accepted_http_methods', // phpcs:ignore WordPress.NamingConventions.ValidHookName
106
				array( Route::DELETE, Route::POST, Route::PUT, Route::PATCH, Route::GET )
107
			),
108
			true
109
		);
110
	}
111
112
	/**
113
	 * Compose the permission callback function for the route.
114
	 *
115
	 * @param Route $route
116
	 * @return callable
117
	 */
118
	protected function compose_permission_callback( Route $route ): callable {
119
		$callbacks = $route->get_authentication();
120
121
		// If we have no callback defined, use return true.
122
		if ( count( $callbacks ) === 0 ) {
123
			return '__return_true';
124
		}
125
126
		// If we only have 1, return as is.
127
		if ( count( $callbacks ) === 1 ) {
128
			return reset( $callbacks );
129
		}
130
131
		return all( ...$callbacks );
132
	}
133
134
135
}
136