Test Setup Failed
Branch feature/code_improvement (b0d56f)
by Thierry
02:54
created

Response::getCommandCount()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Response.php - The Jaxon Response
5
 *
6
 * This class collects commands to be sent back to the browser in response to a jaxon request.
7
 * Commands are encoded and packaged in json format.
8
 *
9
 * Common commands include:
10
 * - <Response->assign>: Assign a value to an element's attribute.
11
 * - <Response->append>: Append a value on to an element's attribute.
12
 * - <Response->script>: Execute a portion of javascript code.
13
 * - <Response->call>: Execute an existing javascript function.
14
 * - <Response->alert>: Display an alert dialog to the user.
15
 *
16
 * Elements are identified by the value of the HTML id attribute.
17
 *
18
 * @package jaxon-core
0 ignored issues
show
Coding Style introduced by
Package name "jaxon-core" is not valid; consider "Jaxoncore" instead
Loading history...
19
 * @author Jared White
0 ignored issues
show
Coding Style introduced by
Content of the @author tag must be in the form "Display Name <[email protected]>"
Loading history...
20
 * @author J. Max Wilson
0 ignored issues
show
Coding Style introduced by
Content of the @author tag must be in the form "Display Name <[email protected]>"
Loading history...
21
 * @author Joseph Woolley
0 ignored issues
show
Coding Style introduced by
Content of the @author tag must be in the form "Display Name <[email protected]>"
Loading history...
22
 * @author Steffen Konerow
0 ignored issues
show
Coding Style introduced by
Content of the @author tag must be in the form "Display Name <[email protected]>"
Loading history...
23
 * @author Thierry Feuzeu <[email protected]>
24
 * @copyright Copyright (c) 2005-2007 by Jared White & J. Max Wilson
0 ignored issues
show
Coding Style introduced by
@copyright tag must contain a year and the name of the copyright holder
Loading history...
25
 * @copyright Copyright (c) 2008-2010 by Joseph Woolley, Steffen Konerow, Jared White  & J. Max Wilson
0 ignored issues
show
Coding Style introduced by
@copyright tag must contain a year and the name of the copyright holder
Loading history...
26
 * @copyright 2016 Thierry Feuzeu <[email protected]>
27
 * @license https://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
28
 * @link https://github.com/jaxon-php/jaxon-core
29
 */
0 ignored issues
show
Coding Style introduced by
PHP version not specified
Loading history...
Coding Style introduced by
Missing @category tag in file comment
Loading history...
30
31
namespace Jaxon\Response;
32
33
class Response extends AbstractResponse
0 ignored issues
show
Coding Style introduced by
Missing doc comment for class Response
Loading history...
34
{
35
    use Features\DomCommands;
36
    use Features\JsCommands;
37
    use Features\DomTreeCommands;
38
39
    /**
40
     * The commands that will be sent to the browser in the response
41
     *
42
     * @var array
43
     */
44
    private $aCommands = [];
45
46
    /**
47
     * A string, array or integer value to be returned to the caller when using 'synchronous' mode requests.
48
     * See <jaxon->setMode> for details.
49
     *
50
     * @var mixed
51
     */
52
    private $returnValue;
53
54
    /**
55
     * Get the content type, which is always set to 'application/json'
56
     *
57
     * @return string
58
     */
59
    public function getContentType()
60
    {
61
        return 'application/json';
62
    }
63
64
    /**
65
     * Provides access to registered response plugins
66
     *
67
     * Pass the plugin name as the first argument and the plugin object will be returned.
68
     *
69
     * @param string        $sName                The name of the plugin
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 8 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 16 found
Loading history...
70
     *
71
     * @return null|\Jaxon\Plugin\Response
72
     */
73
    public function plugin($sName)
74
    {
75
        $xPlugin = jaxon()->di()->getPluginManager()->getResponsePlugin($sName);
76
        if(!$xPlugin)
77
        {
78
            return null;
79
        }
80
        $xPlugin->setResponse($this);
81
        return $xPlugin;
82
    }
83
84
    /**
85
     * Magic PHP function
86
     *
87
     * Used to permit plugins to be called as if they where native members of the Response instance.
88
     *
89
     * @param string        $sPluginName        The name of the plugin
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 8 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 8 found
Loading history...
90
     *
91
     * @return \Jaxon\Plugin\Response
0 ignored issues
show
Documentation introduced by
Should the return type not be \Jaxon\Plugin\Response|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
92
     */
93
    public function __get($sPluginName)
94
    {
95
        return $this->plugin($sPluginName);
96
    }
97
98
    /**
99
     * Create a JQuery Element with a given selector, and link it to the current response.
100
     *
101
     * This is a shortcut to the JQuery plugin.
102
     *
103
     * @param string        $sSelector            The jQuery selector
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 8 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 12 found
Loading history...
104
     * @param string        $sContext             A context associated to the selector
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 8 found
Loading history...
Coding Style introduced by
Expected 2 spaces after parameter name; 13 found
Loading history...
105
     *
106
     * @return \Jaxon\Response\Plugin\JQuery\Dom\Element
107
     */
108
    public function jq($sSelector = '', $sContext = '')
109
    {
110
        return $this->plugin('jquery')->element($sSelector, $sContext);
111
    }
112
113
    /**
114
     * Create a JQuery Element with a given selector, and link it to the current response.
115
     *
116
     * This is a shortcut to the JQuery plugin.
117
     *
118
     * @param string        $sSelector            The jQuery selector
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 8 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 12 found
Loading history...
119
     * @param string        $sContext             A context associated to the selector
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 8 found
Loading history...
Coding Style introduced by
Expected 2 spaces after parameter name; 13 found
Loading history...
120
     *
121
     * @return \Jaxon\Response\Plugin\JQuery\Dom\Element
122
     */
123
    public function jQuery($sSelector = '', $sContext = '')
124
    {
125
        return $this->jq($sSelector, $sContext);
126
    }
127
128
    /**
129
     * Add a response command to the array of commands that will be sent to the browser
130
     *
131
     * @param array             $aAttributes        Associative array of attributes that will describe the command
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 13 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 8 found
Loading history...
132
     * @param mixed             $mData              The data to be associated with this command
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 13 found
Loading history...
Coding Style introduced by
Expected 7 spaces after parameter name; 14 found
Loading history...
133
     *
134
     * @return Response
135
     */
136
    public function addCommand(array $aAttributes, $mData)
137
    {
138
        array_walk($aAttributes, function(&$sAttribute) {
139
            if(!is_integer($sAttribute))
140
            {
141
                $sAttribute = trim((string)$sAttribute, " \t");
142
            }
143
        });
144
145
        /* merge commands if possible */
0 ignored issues
show
Coding Style introduced by
Single line block comment not allowed; use inline ("// text") comment instead
Loading history...
146
        if(in_array($aAttributes['cmd'], ['js', 'ap']))
147
        {
148
            if(($aLastCommand = array_pop($this->aCommands)))
0 ignored issues
show
Coding Style introduced by
Variable assignment found within a condition. Did you mean to do a comparison ?
Loading history...
149
            {
150
                if($aLastCommand['cmd'] == $aAttributes['cmd'])
151
                {
152
                    if($this->getOption('core.response.merge.js') && $aLastCommand['cmd'] == 'js')
153
                    {
154
                        $mData = $aLastCommand['data'] . '; ' . $mData;
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $mData. This often makes code more readable.
Loading history...
155
                    }
156
                    elseif($this->getOption('core.response.merge.ap') &&
157
                        $aLastCommand['cmd'] == 'ap' &&
158
                        $aLastCommand['id'] == $aAttributes['id'] &&
159
                        $aLastCommand['prop'] == $aAttributes['prop'])
160
                    {
161
                        $mData = $aLastCommand['data'] . ' ' . $mData;
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $mData. This often makes code more readable.
Loading history...
162
                    }
163
                    else
164
                    {
165
                        $this->aCommands[] = $aLastCommand;
166
                    }
167
                }
168
                else
169
                {
170
                    $this->aCommands[] = $aLastCommand;
171
                }
172
            }
173
        }
174
        $aAttributes['data'] = $mData;
175
        $this->aCommands[] = $aAttributes;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
176
177
        return $this;
178
    }
179
180
    /**
181
     * Add a response command to the array of commands that will be sent to the browser
182
     *
183
     * @param string        $sName              The command name
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter type; 8 found
Loading history...
Coding Style introduced by
Expected 8 spaces after parameter name; 14 found
Loading history...
184
     * @param array         $aAttributes        Associative array of attributes that will describe the command
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter type; 9 found
Loading history...
Coding Style introduced by
Expected 2 spaces after parameter name; 8 found
Loading history...
185
     * @param mixed         $mData              The data to be associated with this command
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter type; 9 found
Loading history...
Coding Style introduced by
Expected 8 spaces after parameter name; 14 found
Loading history...
186
     * @param boolean       $bRemoveEmpty       If true, remove empty attributes
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 7 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 7 found
Loading history...
187
     *
188
     * @return Response
0 ignored issues
show
Documentation introduced by
Should the return type not be Response|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
189
     */
190
    protected function _addCommand($sName, array $aAttributes, $mData, $bRemoveEmpty = false)
191
    {
192
        if(is_array($mData))
193
        {
194
            array_walk($mData, function(&$sData) {
195
                $sData = trim((string)$sData, " \t\n");
196
            });
197
        }
198
        else
199
        {
200
            $mData = trim((string)$mData, " \t\n");
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $mData. This often makes code more readable.
Loading history...
201
        }
202
203
        if($bRemoveEmpty)
204
        {
205
            foreach(array_keys($aAttributes) as $sAttr)
206
            {
207
                if($aAttributes[$sAttr] === '')
208
                {
209
                    unset($aAttributes[$sAttr]);
210
                }
211
            }
212
        }
213
214
        $aAttributes['cmd'] = $sName;
215
        $this->addCommand($aAttributes, $mData);
216
    }
217
218
    /**
219
     * Clear all the commands already added to the response
220
     *
221
     * @return Response
222
     */
223
    public function clearCommands()
224
    {
225
        $this->aCommands[] = [];
226
227
        return $this;
228
    }
229
230
    /**
231
     * Add a response command that is generated by a plugin
232
     *
233
     * @param \Jaxon\Plugin\Response    $xPlugin            The plugin object
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 4 found
Loading history...
Coding Style introduced by
Expected 5 spaces after parameter name; 12 found
Loading history...
234
     * @param array                     $aAttributes        The attributes for this response command
0 ignored issues
show
Coding Style introduced by
Expected 18 spaces after parameter type; 21 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 8 found
Loading history...
235
     * @param string                    $mData              The data to be sent with this command
0 ignored issues
show
Coding Style introduced by
Expected 17 spaces after parameter type; 20 found
Loading history...
Coding Style introduced by
Expected 7 spaces after parameter name; 14 found
Loading history...
236
     *
237
     * @return Response
238
     */
239
    public function addPluginCommand($xPlugin, $aAttributes, $mData)
240
    {
241
        $aAttributes['plg'] = $xPlugin->getName();
242
        return $this->addCommand($aAttributes, $mData);
243
    }
244
245
    /**
246
     * Merge the response commands from the specified <Response> object with
247
     * the response commands in this <Response> object
248
     *
249
     * @param AbstractResponse  $mCommands          The <Response> object
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 2 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 10 found
Loading history...
250
     * @param boolean           $bBefore            Add the new commands to the beginning of the list
0 ignored issues
show
Coding Style introduced by
Expected 10 spaces after parameter type; 11 found
Loading history...
Coding Style introduced by
Expected 3 spaces after parameter name; 12 found
Loading history...
251
     *
252
     * @return void
253
     */
254
    public function appendResponse(AbstractResponse $mCommands, $bBefore = false)
255
    {
256
        $aCommands = [];
257
        if($mCommands instanceof Response)
258
        {
259
            $this->returnValue = $mCommands->returnValue;
260
            $aCommands = $mCommands->aCommands;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 9 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
261
        }
262
        elseif(is_array($mCommands))
263
        {
264
            $aCommands = $mCommands;
265
        }
266
        else
267
        {
268
            if(!empty($mCommands))
269
            {
270
                throw new \Jaxon\Exception\Error(jaxon_trans('errors.response.data.invalid'));
271
            }
272
        }
273
274
        if(count($aCommands) > 0)
275
        {
276
            if($bBefore)
277
            {
278
                $this->aCommands = array_merge($aCommands, $this->aCommands);
279
            }
280
            else
281
            {
282
                $this->aCommands = array_merge($this->aCommands, $aCommands);
283
            }
284
        }
285
    }
286
287
    /**
288
     * Get the number of commands in the response
289
     *
290
     * @return integer
291
     */
292
    public function getCommandCount()
293
    {
294
        return count($this->aCommands);
295
    }
296
297
    /**
298
     * Stores a value that will be passed back as part of the response
299
     *
300
     * When making synchronous requests, the calling javascript can obtain this value
301
     * immediately as the return value of the <jaxon.call> javascript function
302
     *
303
     * @param mixed        $value                Any value
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 8 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 16 found
Loading history...
304
     *
305
     * @return Response
306
     */
307
    public function setReturnValue($value)
308
    {
309
        $this->returnValue = $value;
310
        return $this;
311
    }
312
313
    /**
314
     * Return the output, generated from the commands added to the response, that will be sent to the browser
315
     *
316
     * @return string
317
     */
318
    public function getOutput()
319
    {
320
        $response = [];
321
322
        if(($this->returnValue))
323
        {
324
            $response['jxnrv'] = $this->returnValue;
325
        }
326
        $response['jxnobj'] = [];
327
328
        foreach($this->aCommands as $xCommand)
329
        {
330
            $response['jxnobj'][] = $xCommand;
331
        }
332
333
        return json_encode($response);
334
    }
335
}
336