Ajax_Helper::extract_server_request_args()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 18
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 14
c 0
b 0
f 0
dl 0
loc 18
rs 9.7998
cc 4
nc 4
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * Helper class for working with Ajax models
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\Ajax
23
 */
24
25
namespace PinkCrab\Ajax;
26
27
use PinkCrab\Ajax\Ajax;
28
use Psr\Http\Message\ServerRequestInterface;
29
30
use PinkCrab\Nonce\Nonce;
31
use PinkCrab\Ajax\Ajax_Exception;
32
33
34
use ReflectionClass;
35
36
37
class Ajax_Helper {
38
39
	/**
40
	 * Cache of all reflected ajax class, constructed.
41
	 *
42
	 * @var array<string,Ajax>
43
	 */
44
	private static array $class_cache = array();
45
46
	/**
47
	 * Returns the admin ajax url.
48
	 *
49
	 * @return string
50
	 */
51
	public static function admin_ajax_url(): string {
52
		return admin_url( 'admin-ajax.php' );
53
	}
54
55
	/**
56
	 * Returns the reflection of an Ajax instance.
57
	 * Either from cache or created without constructor.
58
	 *
59
	 * @param string $class_string
60
	 * @return Ajax
61
	 * @throws Ajax_Exception (code 100) If non valid Ajax class passed.
62
	 */
63
	private static function get_reflected( string $class_string ): Ajax {
64
		if ( ! \is_subclass_of( $class_string, Ajax::class ) ) {
65
			throw Ajax_Exception::non_ajax_model( 'get reflection' );
66
		}
67
68
		if ( ! array_key_exists( $class_string, self::$class_cache ) ) {
69
			$reflection                         = new ReflectionClass( $class_string );
70
			self::$class_cache[ $class_string ] = $reflection->newInstanceWithoutConstructor();
71
		}
72
73
		return self::$class_cache[ $class_string ];
74
	}
75
76
	/**
77
	 * Gets the action from an Ajax class
78
	 * uses reflection to create instance without using the constructor.
79
	 *
80
	 * @param string $class_string
81
	 * @return string|null
82
	 * @throws Ajax_Exception (code 100) If non valid Ajax class passed.
83
	 * @throws Ajax_Exception (code 101) If no action defined
84
	 */
85
	public static function get_action( string $class_string ): ?string {
86
		$instance = self::get_reflected( $class_string );
87
88
		if ( ! $instance->has_valid_action() ) {
89
			throw Ajax_Exception::undefined_action( esc_attr( $class_string ) );
90
		}
91
92
		return $instance->get_action();
93
	}
94
95
	/**
96
	 * Returns if the passed ajax class  has a nonce
97
	 *
98
	 * @param string $class_string
99
	 * @return boolean
100
	 * @throws Ajax_Exception (code 100) If non valid Ajax class passed.
101
	 */
102
	public static function has_nonce( string $class_string ): bool {
103
		return self::get_reflected( $class_string )->has_nonce();
104
	}
105
106
	/**
107
	 * Returns a Nonce object if the passed class has a non handle defined.
108
	 *
109
	 * @param string $class_string
110
	 * @return Nonce|null
111
	 * @throws Ajax_Exception (code 100) If non valid Ajax class passed.
112
	 */
113
	public static function get_nonce( string $class_string ): ?Nonce {
114
		$instance = self::get_reflected( $class_string );
115
116
		return $instance->has_nonce()
117
			? new Nonce( $instance->get_nonce_handle() ?? '' ) // has_nonce conditional should catch null here
118
			: null;
119
	}
120
121
	/**
122
	 * Return the defined nonce field from the Ajax class passed
123
	 *
124
	 * @param string $class_string
125
	 * @return string
126
	 * @throws Ajax_Exception (code 100) If non valid Ajax class passed.
127
	 */
128
	public static function get_nonce_field( string $class_string ): string {
129
		return self::get_reflected( $class_string )->get_nonce_field();
130
	}
131
132
	/**
133
	 * Extracts the args from the server request.
134
	 * Based on request type GET/POST
135
	 *
136
	 * @param ServerRequestInterface $request
137
	 * @return array<string, string>
138
	 */
139
	public static function extract_server_request_args( ServerRequestInterface $request ): array {
140
		switch ( $request->getMethod() ) {
141
			case 'POST':
142
				// Return different post types.
143
				if ( str_contains( $request->getHeaderLine( 'Content-Type' ), 'application/x-www-form-urlencoded;' ) ) {
144
					$params = (array) $request->getParsedBody();
145
				} else {
146
					$params = json_decode( (string) $request->getBody(), true ) ?? array();
147
				}
148
				break;
149
			case 'GET':
150
				$params = $request->getQueryParams();
151
				break;
152
			default:
153
				$params = array();
154
				break;
155
		}
156
		return $params;
157
	}
158
}
159