Passed
Push — master ( 3c388a...58b85c )
by Sebastian
05:02
created

Request_RefreshParams   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 242
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 24
eloc 48
c 1
b 0
f 0
dl 0
loc 242
rs 10

14 Methods

Rating   Name   Duplication   Size   Complexity  
A overrideParam() 0 5 1
A getParams() 0 13 2
A overrideParams() 0 8 2
A getDefaultOptions() 0 5 1
A setExcludeQuickform() 0 4 1
A autoExcludeQuickform() 0 7 2
A removeExcluded() 0 15 3
A excludeParamByName() 0 8 2
A setExcludeSessionName() 0 4 1
A isExcluded() 0 13 3
A resolveExcludes() 0 8 1
A excludeParamsByName() 0 8 2
A excludeParamByCallback() 0 5 1
A autoExcludeSessionName() 0 5 2
1
<?php
2
/**
3
 * File containing the {@link Request_RefreshParams} class.
4
 * @package Application Utils
5
 * @subpackage Request
6
 * @see Request_RefreshParams
7
 */
8
9
declare(strict_types=1);
10
11
namespace AppUtils;
12
13
/**
14
 * Collects request parameters that can be used to refresh
15
 * a page, maintaining all parameters needed to return to
16
 * the same page.
17
 *
18
 * @package Application Utils
19
 * @subpackage Request
20
 * @author Sebastian Mordziol <[email protected]>
21
 */
22
class Request_RefreshParams implements Interface_Optionable
23
{
24
    use Traits_Optionable;
25
    
26
   /**
27
    * @var array<string,mixed>
28
    */
29
    private $overrides = array();
30
    
31
   /**
32
    * @var Request_RefreshParams_Exclude[]
33
    */
34
    private $excludes = array();
35
    
36
    public function getDefaultOptions() : array
37
    {
38
        return array(
39
            'exclude-session-name' => true,
40
            'exclude-quickform-submitter' => true
41
        );
42
    }
43
    
44
   /**
45
    * Whether to automatically exclude the session variable
46
    * from the parameters.
47
    * 
48
    * @param bool $exclude
49
    * @return Request_RefreshParams
50
    */
51
    public function setExcludeSessionName(bool $exclude=true) : Request_RefreshParams
52
    {
53
        $this->setOption('exclude-session-name', $exclude);
54
        return $this;
55
    }
56
    
57
   /**
58
    * Whether to automatically exclude the HTML_QuickForm2
59
    * request variable used to track whether a form has been
60
    * submitted.
61
    * 
62
    * @param bool $exclude
63
    * @return Request_RefreshParams
64
    */
65
    public function setExcludeQuickform(bool $exclude) : Request_RefreshParams
66
    {
67
        $this->setOption('exclude-quickform-submitter', $exclude);
68
        return $this;
69
    }
70
    
71
    public function excludeParamByName(string $paramName) : Request_RefreshParams
72
    {
73
        if($paramName !== '')
74
        {
75
            $this->excludes[] = new Request_RefreshParams_Exclude_Name($paramName);
76
        }
77
        
78
        return $this;
79
    }
80
    
81
   /**
82
    * Exclude a request using a callback function.
83
    * 
84
    * The function gets two parameters:
85
    * 
86
    * - The name of the request parameter
87
    * - The value of the request parameter
88
    * 
89
    * If the callback returns a boolean true, the
90
    * parameter will be excluded.
91
    * 
92
    * @param callable $callback
93
    * @return Request_RefreshParams
94
    */
95
    public function excludeParamByCallback($callback) : Request_RefreshParams
96
    {
97
        $this->excludes[] = new Request_RefreshParams_Exclude_Callback($callback);
98
        
99
        return $this;
100
    }
101
    
102
   /**
103
    * Excludes a request parameter by name.
104
    * 
105
    * @param array $paramNames
106
    * @return Request_RefreshParams
107
    */
108
    public function excludeParamsByName(array $paramNames) : Request_RefreshParams
109
    {
110
        foreach($paramNames as $name)
111
        {
112
            $this->excludeParamByName((string)$name);
113
        }
114
        
115
        return $this;
116
    }
117
    
118
   /**
119
    * Overrides a parameter: even if it exists, this
120
    * value will be used instead - even if it is on 
121
    * the list of excluded parameters.
122
    * 
123
    * @param string $paramName
124
    * @param mixed $paramValue
125
    * @return Request_RefreshParams
126
    */
127
    public function overrideParam(string $paramName, $paramValue) : Request_RefreshParams
128
    {
129
        $this->overrides[$paramName] = $paramValue;
130
        
131
        return $this;
132
    }
133
    
134
   /**
135
    * Overrides an array of parameters. 
136
    * 
137
    * @param array $params
138
    * @return Request_RefreshParams
139
    */
140
    public function overrideParams(array $params) : Request_RefreshParams
141
    {
142
        foreach($params as $name => $value)
143
        {
144
            $this->overrideParam((string)$name, $value);
145
        }
146
        
147
        return $this;
148
    }
149
    
150
   /**
151
    * Resolves all the parameter exclusions that should
152
    * be applied to the list of parameters. This includes
153
    * the manually added exclusions and the dynamic exclusions
154
    * like the session name.
155
    * 
156
    * @return Request_RefreshParams_Exclude[]
157
    */
158
    private function resolveExcludes() : array
159
    {
160
        $excludes = $this->excludes;
161
        
162
        $this->autoExcludeSessionName($excludes);
163
        $this->autoExcludeQuickform($excludes);
164
        
165
        return $excludes;
166
    }
167
    
168
   /**
169
    * Automatically excludes the session name from the
170
    * parameters, if present.
171
    * 
172
    * @param Request_RefreshParams_Exclude[] $excludes
173
    */
174
    private function autoExcludeSessionName(array &$excludes) : void
175
    {
176
        if($this->getBoolOption('exclude-session-name'))
177
        {
178
            $excludes[] = new Request_RefreshParams_Exclude_Name(session_name());
179
        }
180
    }
181
   
182
   /**
183
    * Automatically excludes the HTML_QuickForm2 submit
184
    * tracking variable, when enabled.
185
    * 
186
    * @param Request_RefreshParams_Exclude[] $excludes
187
    */
188
    private function autoExcludeQuickform(array &$excludes) : void
189
    {
190
        if($this->getBoolOption('exclude-quickform-submitter'))
191
        {
192
            $excludes[] = new Request_RefreshParams_Exclude_Callback(function(string $paramName)
193
            {
194
                return strstr($paramName, '_qf__') !== false;
195
            });
196
        }
197
    }
198
    
199
   /**
200
    * Retrieves the list of parameters matching the 
201
    * current settings.
202
    * 
203
    * @return array<string,mixed>
204
    */
205
    public function getParams() : array
206
    {
207
        $params = $this->removeExcluded($_REQUEST);
208
        
209
        // Note: using this loop instead of array_merge,
210
        // because array_merge has weird behavior when
211
        // using numeric keys.
212
        foreach($this->overrides as $name => $val)
213
        {
214
            $params[$name] = $val;
215
        }
216
        
217
        return $params;
218
    }
219
    
220
   /**
221
    * Removes all excluded parameters from the array.
222
    * 
223
    * @param array<string,mixed> $params
224
    * @return array<string,mixed>
225
    */
226
    private function removeExcluded(array $params) : array
227
    {
228
        $result = array();
229
        
230
        foreach($params as $name => $value)
231
        {
232
            $name = (string)$name;
233
            
234
            if(!$this->isExcluded($name, $value))
235
            {
236
                $result[$name] = $value;
237
            }
238
        }
239
        
240
        return $result;
241
    }
242
    
243
   /**
244
    * Checks all configured exclusions to see if the 
245
    * parameter should be excluded or not.
246
    * 
247
    * @param string $paramName
248
    * @param mixed $paramValue
249
    * @return bool
250
    */
251
    public function isExcluded(string $paramName, $paramValue) : bool
252
    {
253
        $excludes = $this->resolveExcludes();
254
        
255
        foreach($excludes as $exclude)
256
        {
257
            if($exclude->isExcluded($paramName, $paramValue))
258
            {
259
                return true;
260
            }
261
        }
262
        
263
        return false;
264
    }
265
}
266