Passed
Push — master ( f1c4a0...a1a080 )
by Paul
09:23
created

Router::checkAdminNonce()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 4
nop 1
dl 0
loc 7
ccs 0
cts 6
cp 0
crap 12
rs 9.4285
c 0
b 0
f 0
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
11
class Router
12
{
13
	/**
14
	 * @return void
15
	 */
16
	public function routeAdminPostRequest()
17
	{
18
		$request = $this->getRequest();
19
		if( !$this->isValidPostRequest( $request ))return;
20
		$this->checkAdminNonce( $request['action'] );
21
		$this->routeRequest( 'admin', $request['action'], $request );
22
	}
23
24
	/**
25
	 * All ajax requests in the plugin are triggered by a single action hook (i.e. "glsr_action")
26
	 * Each route is determined by the request["action"]
27
	 * @return void
28
	 */
29
	public function routeAjaxRequest()
30
	{
31
		$request = $this->getRequest();
32
		if( !isset( $request['action'] )) {
33
			glsr_log()->error( 'The AJAX request must include an action' )->info( $request );
34
			wp_die();
35
		}
36
		if( !isset( $request['nonce'] )) {
37
			glsr_log()->error( 'The AJAX request must include a nonce' )->info( $request );
38
			wp_die();
39
		}
40
		if( !wp_verify_nonce( $request['nonce'], $request['action'] )) {
41
			glsr_log()->error( 'Nonce check failed for ajax request' )->info( $request );
42
			wp_die( -1, 403 );
43
		}
44
		$request['ajax_request'] = true;
45
		$this->routeRequest( 'ajax', $request['action'], $request );
46
		wp_die();
47
	}
48
49
	/**
50
	 * @return void
51
	 */
52
	public function routePublicPostRequest()
53
	{
54
		if( is_admin() )return;
55
		$request = $this->getRequest();
56
		if( !$this->isValidPostRequest( $request ))return;
57
		if( !wp_verify_nonce( $request['_wpnonce'], $request['action'] )) {
58
			glsr_log()->error( 'Nonce check failed for public request' )->info( $request );
59
			return;
60
		}
61
		$this->routeRequest( 'public', $request['action'], $request );
62
	}
63
64
	/**
65
	 * @return void
66
	 */
67
	public function routeWebhookRequest()
68
	{
69
		$request = filter_input( INPUT_GET, Application::PREFIX.'hook' );
70
		if( !$request )return;
71
		// @todo manage webhook here
72
	}
73
74
	/**
75
	 * @param string $action
76
	 * @return void
77
	 * @todo verify the $action-options
78
	 */
79
	protected function checkAdminNonce( $action )
80
	{
81
		$nonce = filter_input( INPUT_POST, 'option_page' ) == $action
82
			&& filter_input( INPUT_POST, 'action' ) == 'update'
83
			? $action.'-options'
84
			: $action;
85
		check_admin_referer( $nonce );
86
	}
87
88
	/**
89
	 * @return array
90
	 */
91
	protected function getRequest()
92
	{
93
		foreach( ['request', Application::ID] as $key ) {
94
			$request = filter_input( INPUT_POST, $key, FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
95
			if( !empty( $request ))break;
96
		}
97
		if( isset( $request[Application::ID]['action'] )) {
98
			$request = $request[Application::ID];
99
		}
100
		return (array)$request;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $request does not seem to be defined for all execution paths leading up to this point.
Loading history...
101
	}
102
103
	/**
104
	 * @return bool
105
	 */
106
	protected function isValidPostRequest( array $request = [] )
107
	{
108
		return !empty( $request['action'] ) && empty( filter_input( INPUT_POST, 'ajax_request' ));
109
	}
110
111
	/**
112
	 * @param string $type
113
	 * @param string $action
114
	 * @return void
115
	 */
116
	protected function routeRequest( $type, $action, array $request = [] )
117
	{
118
		$controller = glsr( glsr( Helper::class )->buildClassName( $type.'-controller', 'Controllers' ));
119
		$method = glsr( Helper::class )->buildMethodName( $action, 'router' );
120
		$request = apply_filters( 'site-reviews/route/request', $request, $action, $type );
121
		if( is_callable( [$controller, $method] )) {
122
			call_user_func( [$controller, $method], $request );
123
			return;
124
		}
125
		$actionHook = 'site-reviews/route/'.$type.'/request';
126
		do_action( $actionHook, $action, $request );
127
		if( did_action( $actionHook ) === 0 ) {
128
			glsr_log( 'Unknown '.$type.' router request: '.$action );
129
		}
130
	}
131
}
132