Completed
Push — master ( 7fc1f3...a124f0 )
by Thierry
01:30
created

Response::_addCommand()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 3
dl 0
loc 5
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
19
 * @author Jared White
20
 * @author J. Max Wilson
21
 * @author Joseph Woolley
22
 * @author Steffen Konerow
23
 * @author Thierry Feuzeu <[email protected]>
24
 * @copyright Copyright (c) 2005-2007 by Jared White & J. Max Wilson
25
 * @copyright Copyright (c) 2008-2010 by Joseph Woolley, Steffen Konerow, Jared White  & J. Max Wilson
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
 */
30
31
namespace Jaxon\Response;
32
33
class Response extends AbstractResponse
34
{
35
    use \Jaxon\Features\Translator;
36
37
    /**
38
     * The commands that will be sent to the browser in the response
39
     *
40
     * @var array
41
     */
42
    private $aCommands = [];
43
44
    /**
45
     * A string, array or integer value to be returned to the caller when using 'synchronous' mode requests.
46
     * See <jaxon->setMode> for details.
47
     *
48
     * @var mixed
49
     */
50
    private $returnValue;
51
52
    /**
53
     * Get the content type, which is always set to 'application/json'
54
     *
55
     * @return string
56
     */
57
    public function getContentType()
58
    {
59
        return 'application/json';
60
    }
61
62
    /**
63
     * Provides access to registered response plugins
64
     *
65
     * Pass the plugin name as the first argument and the plugin object will be returned.
66
     *
67
     * @param string        $sName                The name of the plugin
68
     *
69
     * @return null|\Jaxon\Plugin\Response
70
     */
71
    public function plugin($sName)
72
    {
73
        $xPlugin = jaxon()->di()->getPluginManager()->getResponsePlugin($sName);
74
        if(!$xPlugin)
75
        {
76
            return null;
77
        }
78
        $xPlugin->setResponse($this);
79
        return $xPlugin;
80
    }
81
82
    /**
83
     * Create a JQuery Element with a given selector, and link it to the current response.
84
     *
85
     * This is a shortcut to the JQuery plugin.
86
     *
87
     * @param string        $sSelector            The jQuery selector
88
     * @param string        $sContext             A context associated to the selector
89
     *
90
     * @return Jaxon\Response\Plugin\JQuery\Dom\Element
91
     */
92
    public function jq($sSelector = '', $sContext = '')
93
    {
94
        return $this->plugin('jquery')->element($sSelector, $sContext);
95
    }
96
97
    /**
98
     * Create a JQuery Element with a given selector, and link it to the current response.
99
     *
100
     * This is a shortcut to the JQuery plugin.
101
     *
102
     * @param string        $sSelector            The jQuery selector
103
     * @param string        $sContext             A context associated to the selector
104
     *
105
     * @return Jaxon\Response\Plugin\JQuery\Dom\Element
106
     */
107
    public function jQuery($sSelector = '', $sContext = '')
108
    {
109
        return $this->jq($sSelector, $sContext);
110
    }
111
112
    /**
113
     * Magic PHP function
114
     *
115
     * Used to permit plugins to be called as if they where native members of the Response instance.
116
     *
117
     * @param string        $sPluginName        The name of the plugin
118
     *
119
     * @return \Jaxon\Plugin\Response
120
     */
121
    public function __get($sPluginName)
122
    {
123
        return $this->plugin($sPluginName);
124
    }
125
126
    /**
127
     * Add a response command to the array of commands that will be sent to the browser
128
     *
129
     * @param array         $aAttributes        Associative array of attributes that will describe the command
130
     * @param mixed            $mData                The data to be associated with this command
131
     *
132
     * @return AbstractResponse
133
     */
134
    public function addCommand($aAttributes, $mData)
135
    {
136
        /* merge commands if possible */
137
        if(in_array($aAttributes['cmd'], ['js', 'ap']))
138
        {
139
            if(($aLastCommand = array_pop($this->aCommands)))
140
            {
141
                if($aLastCommand['cmd'] == $aAttributes['cmd'])
142
                {
143
                    if($this->getOption('core.response.merge.js') &&
144
                            $aLastCommand['cmd'] == 'js')
145
                    {
146
                        $mData = $aLastCommand['data'] . '; ' . $mData;
147
                    }
148
                    elseif($this->getOption('core.response.merge.ap') &&
149
                            $aLastCommand['cmd'] == 'ap' &&
150
                            $aLastCommand['id'] == $aAttributes['id'] &&
151
                            $aLastCommand['prop'] == $aAttributes['prop'])
152
                    {
153
                        $mData = $aLastCommand['data'] . ' ' . $mData;
154
                    }
155
                    else
156
                    {
157
                        $this->aCommands[] = $aLastCommand;
158
                    }
159
                }
160
                else
161
                {
162
                    $this->aCommands[] = $aLastCommand;
163
                }
164
            }
165
        }
166
        $aAttributes['data'] = $mData;
167
        $this->aCommands[] = $aAttributes;
168
169
        return $this;
170
    }
171
172
    /**
173
     * Add a response command to the array of commands that will be sent to the browser
174
     *
175
     * @param string        $sName              The command name
176
     * @param array         $aAttributes        Associative array of attributes that will describe the command
177
     * @param mixed         $mData              The data to be associated with this command
178
     *
179
     * @return AbstractResponse
180
     */
181
    private function _addCommand($sName, $aAttributes, $mData)
182
    {
183
        $aAttributes['cmd'] = $sName;
184
        $this->addCommand($aAttributes, $mData);
185
    }
186
187
    /**
188
     * Clear all the commands already added to the response
189
     *
190
     * @return Response
191
     */
192
    public function clearCommands()
193
    {
194
        $this->aCommands[] = [];
195
196
        return $this;
197
    }
198
199
    /**
200
     * Add a response command that is generated by a plugin
201
     *
202
     * @param \Jaxon\Plugin\Plugin  $xPlugin            The plugin object
203
     * @param array                 $aAttributes        The attributes for this response command
204
     * @param string                 $mData              The data to be sent with this command
205
     *
206
     * @return Response
207
     */
208
    public function addPluginCommand($xPlugin, $aAttributes, $mData)
209
    {
210
        $aAttributes['plg'] = $xPlugin->getName();
211
        return $this->addCommand($aAttributes, $mData);
212
    }
213
214
    /**
215
     * Merge the response commands from the specified <Response> object with
216
     * the response commands in this <Response> object
217
     *
218
     * @param AbstractResponse  $mCommands          The <Response> object
219
     * @param boolean           $bBefore            Add the new commands to the beginning of the list
220
     *
221
     * @return void
222
     */
223
    public function appendResponse(AbstractResponse $mCommands, $bBefore = false)
224
    {
225
        $aCommands = [];
226
        if($mCommands instanceof Response)
227
        {
228
            $this->returnValue = $mCommands->returnValue;
229
            $aCommands = $mCommands->aCommands;
230
        }
231
        elseif(is_array($mCommands))
232
        {
233
            $aCommands = $mCommands;
234
        }
235
        else
236
        {
237
            if(!empty($mCommands))
238
            {
239
                throw new \Jaxon\Exception\Error($this->trans('errors.response.data.invalid'));
240
            }
241
        }
242
243
        if(count($aCommands) > 0)
244
        {
245
            if($bBefore)
246
            {
247
                $this->aCommands = array_merge($aCommands, $this->aCommands);
248
            }
249
            else
250
            {
251
                $this->aCommands = array_merge($this->aCommands, $aCommands);
252
            }
253
        }
254
    }
255
256
    /**
257
     * Response command that prompts user with [ok] [cancel] style message box
258
     *
259
     * If the user clicks cancel, the specified number of response commands
260
     * following this one, will be skipped.
261
     *
262
     * @param integer        $iCmdNumber            The number of commands to skip upon cancel
263
     * @param string        $sMessage            The message to display to the user
264
     *
265
     * @return Response
266
     */
267
    public function confirmCommands($iCmdNumber, $sMessage)
268
    {
269
        $aAttributes = [
270
            'id' => $iCmdNumber
271
        ];
272
        return $this->_addCommand('cc', $aAttributes, trim((string)$sMessage, " \t\n"));
273
    }
274
275
    /**
276
     * Add a command to assign the specified value to the given element's attribute
277
     *
278
     * @param string        $sTarget              The id of the html element on the browser
279
     * @param string        $sAttribute           The attribute to be assigned
280
     * @param string        $sData                The value to be assigned to the attribute
281
     *
282
     * @return Response
283
     */
284 View Code Duplication
    public function assign($sTarget, $sAttribute, $sData)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
285
    {
286
        $aAttributes = [
287
            'id' => trim((string)$sTarget, " \t"),
288
            'prop' => trim((string)$sAttribute, " \t")
289
        ];
290
        return $this->_addCommand('as', $aAttributes, trim((string)$sData, " \t\n"));
291
    }
292
293
    /**
294
     * Add a command to assign the specified HTML content to the given element
295
     *
296
     * This is a shortcut for assign() on the innerHTML attribute.
297
     *
298
     * @param string        $sTarget              The id of the html element on the browser
299
     * @param string        $sData                The value to be assigned to the attribute
300
     *
301
     * @return Response
302
     */
303
    public function html($sTarget, $sData)
304
    {
305
        return $this->assign($sTarget, 'innerHTML', $sData);
306
    }
307
308
    /**
309
     * Add a command to append the specified data to the given element's attribute
310
     *
311
     * @param string        $sTarget            The id of the element to be updated
312
     * @param string        $sAttribute            The name of the attribute to be appended to
313
     * @param string        $sData                The data to be appended to the attribute
314
     *
315
     * @return Response
316
     */
317 View Code Duplication
    public function append($sTarget, $sAttribute, $sData)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
318
    {
319
        $aAttributes = [
320
            'id' => trim((string)$sTarget, " \t"),
321
            'prop' => trim((string)$sAttribute, " \t")
322
        ];
323
        return $this->_addCommand('ap', $aAttributes, trim((string)$sData, " \t\n"));
324
    }
325
326
    /**
327
     * Add a command to prepend the specified data to the given element's attribute
328
     *
329
     * @param string        $sTarget            The id of the element to be updated
330
     * @param string        $sAttribute            The name of the attribute to be prepended to
331
     * @param string        $sData                The value to be prepended to the attribute
332
     *
333
     * @return Response
334
     */
335 View Code Duplication
    public function prepend($sTarget, $sAttribute, $sData)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
336
    {
337
        $aAttributes = [
338
            'id' => trim((string)$sTarget, " \t"),
339
            'prop' => trim((string)$sAttribute, " \t")
340
        ];
341
        return $this->_addCommand('pp', $aAttributes, trim((string)$sData, " \t\n"));
342
    }
343
344
    /**
345
     * Add a command to replace a specified value with another value within the given element's attribute
346
     *
347
     * @param string        $sTarget            The id of the element to update
348
     * @param string        $sAttribute            The attribute to be updated
349
     * @param string        $sSearch            The needle to search for
350
     * @param string        $sData                The data to use in place of the needle
351
     *
352
     * @return Response
353
     */
354
    public function replace($sTarget, $sAttribute, $sSearch, $sData)
355
    {
356
        $aAttributes = [
357
            'id' => trim((string)$sTarget, " \t"),
358
            'prop' => trim((string)$sAttribute, " \t")
359
        ];
360
        $aData = [
361
            's' => trim((string)$sSearch, " \t\n"),
362
            'r' => trim((string)$sData, " \t\n")
363
        ];
364
        return $this->_addCommand('rp', $aAttributes, $aData);
365
    }
366
367
    /**
368
     * Add a command to clear the specified attribute of the given element
369
     *
370
     * @param string        $sTarget            The id of the element to be updated.
371
     * @param string        $sAttribute            The attribute to be cleared
372
     *
373
     * @return Response
374
     */
375
    public function clear($sTarget, $sAttribute)
376
    {
377
        return $this->assign(trim((string)$sTarget, " \t"), trim((string)$sAttribute, " \t"), '');
378
    }
379
380
    /**
381
     * Add a command to assign a value to a member of a javascript object (or element)
382
     * that is specified by the context member of the request
383
     *
384
     * The object is referenced using the 'this' keyword in the sAttribute parameter.
385
     *
386
     * @param string        $sAttribute            The attribute to be updated
387
     * @param string        $sData                The value to assign
388
     *
389
     * @return Response
390
     */
391 View Code Duplication
    public function contextAssign($sAttribute, $sData)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
392
    {
393
        $aAttributes = [
394
            'prop' => trim((string)$sAttribute, " \t")
395
        ];
396
        return $this->_addCommand('c:as', $aAttributes, trim((string)$sData, " \t\n"));
397
    }
398
399
    /**
400
     * Add a command to append a value onto the specified member of the javascript
401
     * context object (or element) specified by the context member of the request
402
     *
403
     * The object is referenced using the 'this' keyword in the sAttribute parameter.
404
     *
405
     * @param string        $sAttribute            The attribute to be appended to
406
     * @param string        $sData                The value to append
407
     *
408
     * @return Response
409
     */
410 View Code Duplication
    public function contextAppend($sAttribute, $sData)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
411
    {
412
        $aAttributes = [
413
            'prop' => trim((string)$sAttribute, " \t")
414
        ];
415
        return $this->_addCommand('c:ap', $aAttributes, trim((string)$sData, " \t\n"));
416
    }
417
418
    /**
419
     * Add a command to prepend the speicified data to the given member of the current
420
     * javascript object specified by context in the current request
421
     *
422
     * The object is access via the 'this' keyword in the sAttribute parameter.
423
     *
424
     * @param string        $sAttribute            The attribute to be updated
425
     * @param string        $sData                The value to be prepended
426
     *
427
     * @return Response
428
     */
429 View Code Duplication
    public function contextPrepend($sAttribute, $sData)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
430
    {
431
        $aAttributes = [
432
            'prop' => trim((string)$sAttribute, " \t")
433
        ];
434
        return $this->_addCommand('c:pp', $aAttributes, trim((string)$sData, " \t\n"));
435
    }
436
437
    /**
438
     * Add a command to to clear the value of the attribute specified in the sAttribute parameter
439
     *
440
     * The member is access via the 'this' keyword and can be used to update a javascript
441
     * object specified by context in the request parameters.
442
     *
443
     * @param string        $sAttribute            The attribute to be cleared
444
     *
445
     * @return Response
446
     */
447
    public function contextClear($sAttribute)
448
    {
449
        return $this->contextAssign(trim((string)$sAttribute, " \t"), '');
450
    }
451
452
    /**
453
     * Add a command to display an alert message to the user
454
     *
455
     * @param string        $sMessage            The message to be displayed
456
     *
457
     * @return Response
458
     */
459
    public function alert($sMessage)
460
    {
461
        return $this->_addCommand('al', [], trim((string)$sMessage, " \t\n"));
462
    }
463
464
    /**
465
     * Add a command to display a debug message to the user
466
     *
467
     * @param string        $sMessage            The message to be displayed
468
     *
469
     * @return Response
470
     */
471
    public function debug($sMessage)
472
    {
473
        return $this->_addCommand('dbg', [], trim((string)$sMessage, " \t\n"));
474
    }
475
476
    /**
477
     * Add a command to ask the browser to navigate to the specified URL
478
     *
479
     * @param string        $sURL                The relative or fully qualified URL
480
     * @param integer        $iDelay                Number of seconds to delay before the redirect occurs
481
     *
482
     * @return Response
483
     */
484
    public function redirect($sURL, $iDelay = 0)
485
    {
486
        // we need to parse the query part so that the values are rawurlencode()'ed
487
        // can't just use parse_url() cos we could be dealing with a relative URL which
488
        // parse_url() can't deal with.
489
        $queryStart = strpos($sURL, '?', strrpos($sURL, '/'));
490
        if($queryStart !== false)
491
        {
492
            $queryStart++;
493
            $queryEnd = strpos($sURL, '#', $queryStart);
494
            if($queryEnd === false)
495
                $queryEnd = strlen($sURL);
496
            $queryPart = substr($sURL, $queryStart, $queryEnd - $queryStart);
497
            parse_str($queryPart, $queryParts);
498
            $newQueryPart = "";
499
            if($queryParts)
500
            {
501
                $first = true;
502
                foreach($queryParts as $key => $value)
503
                {
504
                    if($first)
505
                        $first = false;
506
                    else
507
                        $newQueryPart .= '&';
508
                    $newQueryPart .= rawurlencode($key) . '=' . rawurlencode($value);
509
                }
510
            } elseif($_SERVER['QUERY_STRING']) {
511
                    //couldn't break up the query, but there's one there
512
                    //possibly "http://url/page.html?query1234" type of query?
513
                    //just encode it and hope it works
514
                    $newQueryPart = rawurlencode($_SERVER['QUERY_STRING']);
515
                }
516
            $sURL = str_replace($queryPart, $newQueryPart, $sURL);
517
        }
518
        if($iDelay)
519
            $this->script('window.setTimeout("window.location = \'' . $sURL . '\';",' . ($iDelay * 1000) . ');');
520
        else
521
            $this->script('window.location = "' . $sURL . '";');
522
        return $this;
523
    }
524
525
    /**
526
     * Add a command to execute a portion of javascript on the browser
527
     *
528
     * The script runs in it's own context, so variables declared locally, using the 'var' keyword,
529
     * will no longer be available after the call.
530
     * To construct a variable that will be accessable globally, even after the script has executed,
531
     * leave off the 'var' keyword.
532
     *
533
     * @param string        $sJS                The script to execute
534
     *
535
     * @return Response
536
     */
537
    public function script($sJS)
538
    {
539
        return $this->_addCommand('js', [], trim((string)$sJS, " \t\n"));
540
    }
541
542
    /**
543
     * Add a command to call the specified javascript function with the given (optional) parameters
544
     *
545
     * @param string        $sFunc                The name of the function to call
546
     *
547
     * @return Response
548
     */
549
    public function call($sFunc)
550
    {
551
        $aArgs = func_get_args();
552
        array_shift($aArgs);
553
        $aAttributes = [
554
            'func' => $sFunc
555
        ];
556
        return $this->_addCommand('jc', $aAttributes, $aArgs);
557
    }
558
559
    /**
560
     * Add a command to remove an element from the document
561
     *
562
     * @param string        $sTarget            The id of the element to be removed
563
     *
564
     * @return Response
565
     */
566
    public function remove($sTarget)
567
    {
568
        $aAttributes = [
569
            'id' => trim((string)$sTarget, " \t")
570
        ];
571
        return $this->_addCommand('rm', $aAttributes, '');
572
    }
573
574
    /**
575
     * Add a command to create a new element on the browser
576
     *
577
     * @param string        $sParent            The id of the parent element
578
     * @param string        $sTag                The tag name to be used for the new element
579
     * @param string        $sId                The id to assign to the new element
580
     *
581
     * @return Response
582
     */
583
    public function create($sParent, $sTag, $sId)
584
    {
585
        $aAttributes = [
586
            'id' => trim((string)$sParent, " \t"),
587
            'prop' => trim((string)$sId, " \t")
588
        ];
589
        return $this->_addCommand('ce', $aAttributes, trim((string)$sTag, " \t\n"));
590
    }
591
592
    /**
593
     * Add a command to insert a new element just prior to the specified element
594
     *
595
     * @param string        $sBefore            The id of the element used as a reference point for the insertion
596
     * @param string        $sTag               The tag name to be used for the new element
597
     * @param string        $sId                The id to assign to the new element
598
     *
599
     * @return Response
600
     */
601
    public function insert($sBefore, $sTag, $sId)
602
    {
603
        $aAttributes = [
604
            'id' => trim((string)$sBefore, " \t"),
605
            'prop' => trim((string)$sId, " \t")
606
        ];
607
        return $this->_addCommand('ie', $aAttributes, trim((string)$sTag, " \t\n"));
608
    }
609
610
    /**
611
     * Add a command to insert a new element after the specified
612
     *
613
     * @param string        $sAfter             The id of the element used as a reference point for the insertion
614
     * @param string        $sTag               The tag name to be used for the new element
615
     * @param string        $sId                The id to assign to the new element
616
     *
617
     * @return Response
618
     */
619
    public function insertAfter($sAfter, $sTag, $sId)
620
    {
621
        $aAttributes = [
622
            'id' => trim((string)$sAfter, " \t"),
623
            'prop' => trim((string)$sId, " \t")
624
        ];
625
        return $this->_addCommand('ia', $aAttributes, trim((string)$sTag, " \t\n"));
626
    }
627
628
    /**
629
     * Add a command to create an input element on the browser
630
     *
631
     * @param string        $sParent            The id of the parent element
632
     * @param string        $sType                The type of the new input element
633
     * @param string        $sName                The name of the new input element
634
     * @param string        $sId                The id of the new element
635
     *
636
     * @return Response
637
     */
638 View Code Duplication
    public function createInput($sParent, $sType, $sName, $sId)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
639
    {
640
        $aAttributes = [
641
            'id' => trim((string)$sParent, " \t"),
642
            'prop' => trim((string)$sId, " \t"),
643
            'type' => trim((string)$sType, " \t")
644
        ];
645
        return $this->_addCommand('ci', $aAttributes, trim((string)$sName, " \t\n"));
646
    }
647
648
    /**
649
     * Add a command to insert a new input element preceding the specified element
650
     *
651
     * @param string        $sBefore            The id of the element to be used as the reference point for the insertion
652
     * @param string        $sType                The type of the new input element
653
     * @param string        $sName                The name of the new input element
654
     * @param string        $sId                The id of the new element
655
     *
656
     * @return Response
657
     */
658 View Code Duplication
    public function insertInput($sBefore, $sType, $sName, $sId)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
659
    {
660
        $aAttributes = [
661
            'id' => trim((string)$sBefore, " \t"),
662
            'prop' => trim((string)$sId, " \t"),
663
            'type' => trim((string)$sType, " \t")
664
        ];
665
        return $this->_addCommand('ii', $aAttributes, trim((string)$sName, " \t\n"));
666
    }
667
668
    /**
669
     * Add a command to insert a new input element after the specified element
670
     *
671
     * @param string        $sAfter                The id of the element to be used as the reference point for the insertion
672
     * @param string        $sType                The type of the new input element
673
     * @param string        $sName                The name of the new input element
674
     * @param string        $sId                The id of the new element
675
     *
676
     * @return Response
677
     */
678 View Code Duplication
    public function insertInputAfter($sAfter, $sType, $sName, $sId)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
679
    {
680
        $aAttributes = [
681
            'id' => trim((string)$sAfter, " \t"),
682
            'prop' => trim((string)$sId, " \t"),
683
            'type' => trim((string)$sType, " \t")
684
        ];
685
        return $this->_addCommand('iia', $aAttributes, trim((string)$sName, " \t\n"));
686
    }
687
688
    /**
689
     * Add a command to set an event handler on the browser
690
     *
691
     * @param string        $sTarget            The id of the element that contains the event
692
     * @param string        $sEvent                The name of the event
693
     * @param string        $sScript            The javascript to execute when the event is fired
694
     *
695
     * @return Response
696
     */
697 View Code Duplication
    public function setEvent($sTarget, $sEvent, $sScript)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
698
    {
699
        $aAttributes = [
700
            'id' => trim((string)$sTarget, " \t"),
701
            'prop' => trim((string)$sEvent, " \t")
702
        ];
703
        return $this->_addCommand('ev', $aAttributes, trim((string)$sScript, " \t\n"));
704
    }
705
706
    /**
707
     * Add a command to set a click handler on the browser
708
     *
709
     * @param string        $sTarget            The id of the element that contains the event
710
     * @param string        $sScript            The javascript to execute when the event is fired
711
     *
712
     * @return Response
713
     */
714
    public function onClick($sTarget, $sScript)
715
    {
716
        return $this->setEvent($sTarget, 'onclick', $sScript);
717
    }
718
719
    /**
720
     * Add a command to install an event handler on the specified element
721
     *
722
     * You can add more than one event handler to an element's event using this method.
723
     *
724
     * @param string        $sTarget             The id of the element
725
     * @param string        $sEvent              The name of the event
726
     * @param string        $sHandler            The name of the javascript function to call when the event is fired
727
     *
728
     * @return Response
729
     */
730 View Code Duplication
    public function addHandler($sTarget, $sEvent, $sHandler)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
731
    {
732
        $aAttributes = [
733
            'id' => trim((string)$sTarget, " \t"),
734
            'prop' => trim((string)$sEvent, " \t")
735
        ];
736
        return $this->_addCommand('ah', $aAttributes, trim((string)$sHandler, " \t\n"));
737
    }
738
739
    /**
740
     * Add a command to remove an event handler from an element
741
     *
742
     * @param string        $sTarget             The id of the element
743
     * @param string        $sEvent              The name of the event
744
     * @param string        $sHandler            The name of the javascript function called when the event is fired
745
     *
746
     * @return Response
747
     */
748 View Code Duplication
    public function removeHandler($sTarget, $sEvent, $sHandler)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
749
    {
750
        $aAttributes = [
751
            'id' => trim((string)$sTarget, " \t"),
752
            'prop' => trim((string)$sEvent, " \t")
753
        ];
754
        return $this->_addCommand('rh', $aAttributes, trim((string)$sHandler, " \t\n"));
755
    }
756
757
    /**
758
     * Add a command to construct a javascript function on the browser
759
     *
760
     * @param string        $sFunction            The name of the function to construct
761
     * @param string        $sArgs                Comma separated list of parameter names
762
     * @param string        $sScript            The javascript code that will become the body of the function
763
     *
764
     * @return Response
765
     */
766 View Code Duplication
    public function setFunction($sFunction, $sArgs, $sScript)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
767
    {
768
        $aAttributes = [
769
            'func' => trim((string)$sFunction, " \t"),
770
            'prop' => trim((string)$sArgs, " \t")
771
        ];
772
        return $this->_addCommand('sf', $aAttributes, trim((string)$sScript, " \t\n"));
773
    }
774
775
    /**
776
     * Add a command to construct a wrapper function around an existing javascript function on the browser
777
     *
778
     * @param string        $sFunction            The name of the existing function to wrap
779
     * @param string        $sArgs                The comma separated list of parameters for the function
780
     * @param array            $aScripts            An array of javascript code snippets that will be used to build
781
     *                                             the body of the function
782
     *                                             The first piece of code specified in the array will occur before
783
     *                                             the call to the original function, the second will occur after
784
     *                                             the original function is called.
785
     * @param string        $sReturnValueVar    The name of the variable that will retain the return value
786
     *                                             from the call to the original function
787
     *
788
     * @return Response
789
     */
790 View Code Duplication
    public function wrapFunction($sFunction, $sArgs, $aScripts, $sReturnValueVar)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
791
    {
792
        $aAttributes = [
793
            'func' => trim((string)$sFunction, " \t"),
794
            'prop' => trim((string)$sArgs, " \t"),
795
            'type' => trim((string)$sReturnValueVar, " \t")
796
        ];
797
        return $this->_addCommand('wpf', $aAttributes, $aScripts);
798
    }
799
800
    /**
801
     * Add a command to load a javascript file on the browser
802
     *
803
     * @param string        $sFileName            The relative or fully qualified URI of the javascript file
804
     * @param string        $sType                Determines the script type. Defaults to 'text/javascript'
805
     *
806
     * @return Response
807
     */
808 View Code Duplication
    public function includeScript($sFileName, $sType = null, $sId = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
809
    {
810
        $command = ['cmd'  =>  'in'];
811
812
        if(($sType))
813
        {
814
            $command['type'] = trim((string)$sType, " \t");
815
        }
816
        if(($sId))
817
        {
818
            $command['elm_id'] = trim((string)$sId, " \t");
819
        }
820
821
        return $this->addCommand($command, trim((string)$sFileName, " \t"));
822
    }
823
824
    /**
825
     * Add a command to include a javascript file on the browser if it has not already been loaded
826
     *
827
     * @param string        $sFileName            The relative or fully qualified URI of the javascript file
828
     * @param string        $sType                Determines the script type. Defaults to 'text/javascript'
829
     *
830
     * @return Response
831
     */
832 View Code Duplication
    public function includeScriptOnce($sFileName, $sType = null, $sId = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
833
    {
834
        $command = ['cmd' => 'ino'];
835
836
        if(($sType))
837
        {
838
            $command['type'] = trim((string)$sType, " \t");
839
        }
840
        if(($sId))
841
        {
842
            $command['elm_id'] = trim((string)$sId, " \t");
843
        }
844
845
        return $this->addCommand($command, trim((string)$sFileName, " \t"));
846
    }
847
848
    /**
849
     * Add a command to remove a SCRIPT reference to a javascript file on the browser
850
     *
851
     * Optionally, you can call a javascript function just prior to the file being unloaded (for cleanup).
852
     *
853
     * @param string        $sFileName            The relative or fully qualified URI of the javascript file
854
     * @param string        $sUnload            Name of a javascript function to call prior to unlaoding the file
855
     *
856
     * @return Response
857
     */
858
    public function removeScript($sFileName, $sUnload = '')
859
    {
860
        $aAttributes = [
861
            'unld' => trim((string)$sUnload, " \t")
862
        ];
863
        return $this->_addCommand('rjs', $aAttributes, trim((string)$sFileName, " \t"));
864
    }
865
866
    /**
867
     * Add a command to include a LINK reference to the specified CSS file on the browser.
868
     *
869
     * This will cause the browser to load and apply the style sheet.
870
     *
871
     * @param string        $sFileName            The relative or fully qualified URI of the css file
872
     * @param string        $sMedia                The media type of the CSS file. Defaults to 'screen'
873
     *
874
     * @return Response
875
     */
876 View Code Duplication
    public function includeCSS($sFileName, $sMedia = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
877
    {
878
        $command = ['cmd' => 'css'];
879
880
        if(($sMedia))
881
        {
882
            $command['media'] = trim((string)$sMedia, " \t");
883
        }
884
885
        return $this->addCommand($command, trim((string)$sFileName, " \t"));
886
    }
887
888
    /**
889
     * Add a command to remove a LINK reference to a CSS file on the browser
890
     *
891
     * This causes the browser to unload the style sheet, effectively removing the style changes it caused.
892
     *
893
     * @param string        $sFileName            The relative or fully qualified URI of the css file
894
     *
895
     * @return Response
896
     */
897 View Code Duplication
    public function removeCSS($sFileName, $sMedia = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
898
    {
899
        $command = ['cmd' => 'rcss'];
900
901
        if(($sMedia))
902
        {
903
            $command['media'] = trim((string)$sMedia, " \t");
904
        }
905
906
        return $this->addCommand($command, trim((string)$sFileName, " \t"));
907
    }
908
909
    /**
910
     * Add a command to make Jaxon pause while the CSS files are loaded
911
     *
912
     * The browser is not typically a multi-threading application, with regards to javascript code.
913
     * Therefore, the CSS files included or removed with <Response->includeCSS> and
914
     * <Response->removeCSS> respectively, will not be loaded or removed until the browser regains
915
     * control from the script.
916
     * This command returns control back to the browser and pauses the execution of the response
917
     * until the CSS files, included previously, are loaded.
918
     *
919
     * @param integer        $iTimeout            The number of 1/10ths of a second to pause before timing out
920
     *                                             and continuing with the execution of the response commands
921
     *
922
     * @return Response
923
     */
924
    public function waitForCSS($iTimeout = 600)
925
    {
926
        $aAttributes = [
927
            'prop' => $iTimeout
928
        ];
929
        return $this->_addCommand('wcss', $aAttributes, '');
930
    }
931
932
    /**
933
     * Add a command to make Jaxon to delay execution of the response commands until a specified condition is met
934
     *
935
     * Note, this returns control to the browser, so that other script operations can execute.
936
     * Jaxon will continue to monitor the specified condition and, when it evaulates to true,
937
     * will continue processing response commands.
938
     *
939
     * @param string        $script                A piece of javascript code that evaulates to true or false
940
     * @param integer        $tenths                The number of 1/10ths of a second to wait before timing out
941
     *                                             and continuing with the execution of the response commands.
942
     *
943
     * @return Response
944
     */
945
    public function waitFor($script, $tenths)
946
    {
947
        $aAttributes = [
948
            'prop' => $tenths
949
        ];
950
        return $this->_addCommand('wf', $aAttributes, trim((string)$script, " \t\n"));
951
    }
952
953
    /**
954
     * Add a command to make Jaxon to pause execution of the response commands,
955
     * returning control to the browser so it can perform other commands asynchronously.
956
     *
957
     * After the specified delay, Jaxon will continue execution of the response commands.
958
     *
959
     * @param integer        $tenths                The number of 1/10ths of a second to sleep
960
     *
961
     * @return Response
962
     */
963
    public function sleep($tenths)
964
    {
965
        $aAttributes = [
966
            'prop' => $tenths
967
        ];
968
        return $this->_addCommand('s', $aAttributes, '');
969
    }
970
971
    /**
972
     * Add a command to start a DOM response
973
     *
974
     * @return \Jaxon\Plugin\Response
975
     */
976
    public function domStartResponse()
977
    {
978
        $this->script('jxnElm = []');
979
    }
980
981
    /**
982
     * Add a command to create a DOM element
983
     *
984
     * @param string        $variable            The DOM element name (id or class)
985
     * @param string        $tag                The HTML tag of the new DOM element
986
     *
987
     * @return Response
988
     */
989
    public function domCreateElement($variable, $tag)
990
    {
991
        $aAttributes = [
992
            'tgt' => $variable
993
        ];
994
        return $this->_addCommand('DCE', $aAttributes, $tag);
995
    }
996
997
    /**
998
     * Add a command to set an attribute on a DOM element
999
     *
1000
     * @param string        $variable            The DOM element name (id or class)
1001
     * @param string        $key                The name of the attribute
1002
     * @param string        $value                The value of the attribute
1003
     *
1004
     * @return Response
1005
     */
1006
    public function domSetAttribute($variable, $key, $value)
1007
    {
1008
        $aAttributes = [
1009
            'tgt' => $variable,
1010
            'key' => $key
1011
        ];
1012
        return $this->_addCommand('DSA', $aAttributes, $value);
1013
    }
1014
1015
    /**
1016
     * Add a command to remove children from a DOM element
1017
     *
1018
     * @param string        $parent                The DOM parent element
1019
     * @param string        $skip                The ??
1020
     * @param string        $remove                The ??
1021
     *
1022
     * @return Response
1023
     */
1024
    public function domRemoveChildren($parent, $skip = null, $remove = null)
1025
    {
1026
        $command = ['cmd' => 'DRC'];
1027
1028
        if(($skip))
1029
        {
1030
            $command['skip'] = $skip;
1031
        }
1032
        if(($remove))
1033
        {
1034
            $command['remove'] = $remove;
1035
        }
1036
1037
        return $this->addCommand($command, $parent);
1038
    }
1039
1040
    /**
1041
     * Add a command to append a child to a DOM element
1042
     *
1043
     * @param string        $parent                The DOM parent element
1044
     * @param string        $variable            The DOM element name (id or class)
1045
     *
1046
     * @return Response
1047
     */
1048
    public function domAppendChild($parent, $variable)
1049
    {
1050
        $aAttributes = [
1051
            'par' => $parent
1052
        ];
1053
        return $this->_addCommand('DAC', $aAttributes, $variable);
1054
    }
1055
1056
    /**
1057
     * Add a command to insert a DOM element before another
1058
     *
1059
     * @param string        $target                The DOM target element
1060
     * @param string        $variable            The DOM element name (id or class)
1061
     *
1062
     * @return Response
1063
     */
1064
    public function domInsertBefore($target, $variable)
1065
    {
1066
        $aAttributes = [
1067
            'tgt' => $target
1068
        ];
1069
        return $this->_addCommand('DIB', $aAttributes, $variable);
1070
    }
1071
1072
    /**
1073
     * Add a command to insert a DOM element after another
1074
     *
1075
     * @param string        $target                The DOM target element
1076
     * @param string        $variable            The DOM element name (id or class)
1077
     *
1078
     * @return Response
1079
     */
1080
    public function domInsertAfter($target, $variable)
1081
    {
1082
        $aAttributes = [
1083
            'tgt' => $target
1084
        ];
1085
        return $this->_addCommand('DIA', $aAttributes, $variable);
1086
    }
1087
1088
    /**
1089
     * Add a command to append a text to a DOM element
1090
     *
1091
     * @param string        $parent                The DOM parent element
1092
     * @param string        $text                The HTML text to append
1093
     *
1094
     * @return Response
1095
     */
1096
    public function domAppendText($parent, $text)
1097
    {
1098
        $aAttributes = [
1099
            'par' => $parent
1100
        ];
1101
        return $this->_addCommand('DAT', $aAttributes, $text);
1102
    }
1103
1104
    /**
1105
     * Add a command to end a DOM response
1106
     *
1107
     * @return \Jaxon\Plugin\Response
1108
     */
1109
    public function domEndResponse()
1110
    {
1111
        $this->script('jxnElm = []');
1112
    }
1113
1114
    /**
1115
     * Get the number of commands in the response
1116
     *
1117
     * @return integer
1118
     */
1119
    public function getCommandCount()
1120
    {
1121
        return count($this->aCommands);
1122
    }
1123
1124
    /**
1125
     * Stores a value that will be passed back as part of the response
1126
     *
1127
     * When making synchronous requests, the calling javascript can obtain this value
1128
     * immediately as the return value of the <jaxon.call> javascript function
1129
     *
1130
     * @param mixed        $value                Any value
1131
     *
1132
     * @return Response
1133
     */
1134
    public function setReturnValue($value)
1135
    {
1136
        $this->returnValue = $value;
1137
        return $this;
1138
    }
1139
1140
    /**
1141
     * Return the output, generated from the commands added to the response, that will be sent to the browser
1142
     *
1143
     * @return string
1144
     */
1145
    public function getOutput()
1146
    {
1147
        $response = [];
1148
1149
        if(($this->returnValue))
1150
        {
1151
            $response['jxnrv'] = $this->returnValue;
1152
        }
1153
        $response['jxnobj'] = [];
1154
1155
        foreach($this->aCommands as $xCommand)
1156
        {
1157
            $response['jxnobj'][] = $xCommand;
1158
        }
1159
1160
        return json_encode($response);
1161
    }
1162
}
1163