Test Failed
Push — hotfix/fix-counts ( 1fe4ce...872cd6 )
by Paul
03:14
created

Router::routeAjaxRequest()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1.0046

Importance

Changes 4
Bugs 2 Features 0
Metric Value
cc 1
eloc 5
c 4
b 2
f 0
nc 1
nop 0
dl 0
loc 7
ccs 5
cts 6
cp 0.8333
crap 1.0046
rs 10
1
<?php
2
3
namespace GeminiLabs\SiteReviews;
4
5
use GeminiLabs\SiteReviews\Application;
6
use GeminiLabs\SiteReviews\Controllers\AdminController;
7
use GeminiLabs\SiteReviews\Controllers\AjaxController;
8
use GeminiLabs\SiteReviews\Controllers\PublicController;
9
use GeminiLabs\SiteReviews\Helper;
10
use GeminiLabs\SiteReviews\Modules\Notice;
11
12
class Router
13
{
14
	/**
15
	 * @return void
16
	 */
17 1
	public function routeAdminPostRequest()
18
	{
19 1
		$request = $this->getRequest();
20 1
		if( !$this->isValidPostRequest( $request ))return;
21
		check_admin_referer( $request['_action'] );
22
		$this->routeRequest( 'admin', $request['_action'], $request );
23
	}
24
25
	/**
26
	 * @return void
27
	 */
28 1
	public function routeAjaxRequest()
29
	{
30 1
		$request = $this->getRequest();
31 1
		$this->checkAjaxRequest( $request );
32 1
		$this->checkAjaxNonce( $request );
33 1
		$this->routeRequest( 'ajax', $request['_action'], $request );
34
		wp_die();
35
	}
36
37
	/**
38
	 * @return void
39
	 */
40
	public function routePublicPostRequest()
41
	{
42
		if( is_admin() )return;
43
		$request = $this->getRequest();
44
		if( !$this->isValidPostRequest( $request ))return;
45
		if( !$this->isValidPublicNonce( $request ))return;
46
		$this->routeRequest( 'public', $request['_action'], $request );
47
	}
48
49
	/**
50
	 * @return void
51
	 */
52 1
	protected function checkAjaxNonce( array $request )
53
	{
54 1
		if( !is_user_logged_in() )return;
55
		if( !isset( $request['_nonce'] )) {
56
			$this->sendAjaxError( 'request is missing a nonce', $request );
57
		}
58
		if( !wp_verify_nonce( $request['_nonce'], $request['_action'] )) {
59
			$this->sendAjaxError( 'request failed the nonce check', $request, 403 );
60
		}
61
	}
62
63
	/**
64
	 * @return void
65
	 */
66 1
	protected function checkAjaxRequest( array $request )
67
	{
68 1
		if( !isset( $request['_action'] )) {
69
			$this->sendAjaxError( 'request must include an action', $request );
70
		}
71 1
		if( empty( $request['_ajax_request'] )) {
72
			$this->sendAjaxError( 'request is invalid', $request );
73
		}
74 1
	}
75
76
	/**
77
	 * All ajax requests in the plugin are triggered by a single action hook: glsr_action,
78
	 * while each ajax route is determined by $_POST[request][_action]
79
	 * @return array
80
	 */
81 1
	protected function getRequest()
82
	{
83 1
		$request = glsr( Helper::class )->filterInputArray( Application::ID );
84 1
		if( glsr( Helper::class )->filterInput( 'action' ) == Application::PREFIX.'action' ) {
85 1
			$request['_ajax_request'] = true;
86
		}
87 1
		if( glsr( Helper::class )->filterInput( '_action', $request ) == 'submit-review' ) {
88 1
			$request['_recaptcha-token'] = glsr( Helper::class )->filterInput( 'g-recaptcha-response' );
89
		}
90 1
		return $request;
91
	}
92
93
	/**
94
	 * @return bool
95
	 */
96 1
	protected function isValidPostRequest( array $request = [] )
97
	{
98 1
		return !empty( $request['_action'] ) && empty( $request['_ajax_request'] );
99
	}
100
101
	/**
102
	 * @return bool
103
	 */
104
	protected function isValidPublicNonce( array $request )
105
	{
106
		if( is_user_logged_in() && !wp_verify_nonce( $request['_nonce'], $request['_action'] )) {
107
			glsr_log()->error( 'nonce check failed for public request' )->debug( $request );
108
			return false;
109
		}
110
		return true;
111
	}
112
113
	/**
114
	 * @param string $type
115
	 * @param string $action
116
	 * @return void
117
	 */
118 1
	protected function routeRequest( $type, $action, array $request = [] )
119
	{
120 1
		$actionHook = 'site-reviews/route/'.$type.'/request';
121 1
		$controller = glsr( glsr( Helper::class )->buildClassName( $type.'-controller', 'Controllers' ));
122 1
		$method = glsr( Helper::class )->buildMethodName( $action, 'router' );
123 1
		$request = apply_filters( 'site-reviews/route/request', $request, $action, $type );
124 1
		do_action( $actionHook, $action, $request );
125 1
		if( is_callable( [$controller, $method] )) {
126 1
			call_user_func( [$controller, $method], $request );
127
			return;
128
		}
129
		if( did_action( $actionHook ) === 0 ) {
130
			glsr_log( 'Unknown '.$type.' router request: '.$action );
131
		}
132
	}
133
134
	/**
135
	 * @param string $error
136
	 * @param int $statusCode
137
	 * @return void
138
	 */
139
	protected function sendAjaxError( $error, array $request, $statusCode = 400 )
140
	{
141
		glsr_log()->error( $error )->debug( $request );
142
		glsr( Notice::class )->addError( __( 'There was an error (try refreshing the page).', 'site-reviews' ).' <code>'.$error.'</code>' );
143
		wp_send_json_error([
144
			'message' => __( 'The form could not be submitted. Please notify the site administrator.', 'site-reviews' ),
145
			'notices' => glsr( Notice::class )->get(),
146
			'error' => $error,
147
		]);
148
	}
149
}
150