Completed
Push — master ( 8e87e9...3db3b2 )
by Thierry
01:29
created

Response::getCharacterEncoding()   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 a format that is acceptable to the response handler
8
 * from the javascript library running on the client side.
9
 *
10
 * Common commands include:
11
 * - <Response->assign>: Assign a value to an element's attribute.
12
 * - <Response->append>: Append a value on to an element's attribute.
13
 * - <Response->script>: Execute a portion of javascript code.
14
 * - <Response->call>: Execute an existing javascript function.
15
 * - <Response->alert>: Display an alert dialog to the user.
16
 *
17
 * Elements are identified by the value of the HTML id attribute.
18
 * If you do not see your updates occuring on the browser side, ensure that you are using
19
 * the correct id in your response.
20
 *
21
 * @package jaxon-core
22
 * @author Jared White
23
 * @author J. Max Wilson
24
 * @author Joseph Woolley
25
 * @author Steffen Konerow
26
 * @author Thierry Feuzeu <[email protected]>
27
 * @copyright Copyright (c) 2005-2007 by Jared White & J. Max Wilson
28
 * @copyright Copyright (c) 2008-2010 by Joseph Woolley, Steffen Konerow, Jared White  & J. Max Wilson
29
 * @copyright 2016 Thierry Feuzeu <[email protected]>
30
 * @license https://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
31
 * @link https://github.com/jaxon-php/jaxon-core
32
 */
33
34
namespace Jaxon\Response;
35
36
class Response extends AbstractResponse
37
{
38
    use \Jaxon\Features\Translator;
39
40
    /**
41
     * The commands that will be sent to the browser in the response
42
     *
43
     * @var array
44
     */
45
    private $aCommands = [];
46
47
    /**
48
     * A string, array or integer value to be returned to the caller when using 'synchronous' mode requests.
49
     * See <jaxon->setMode> for details.
50
     *
51
     * @var mixed
52
     */
53
    private $returnValue;
54
55
    /**
56
     * Get the content type, which is always set to 'application/json'
57
     *
58
     * @return string
59
     */
60
    public function getContentType()
61
    {
62
        return 'application/json';
63
    }
64
65
    /**
66
     * Provides access to registered response plugins
67
     *
68
     * Pass the plugin name as the first argument and the plugin object will be returned.
69
     * You can then access the methods of the plugin directly.
70
     *
71
     * @param string        $sName                The name of the plugin
72
     *
73
     * @return null|\Jaxon\Plugin\Response
74
     */
75
    public function plugin($sName)
76
    {
77
        $xPlugin = $this->getPluginManager()->getResponsePlugin($sName);
78
        if(!$xPlugin)
79
        {
80
            return null;
81
        }
82
        $xPlugin->setResponse($this);
83
        return $xPlugin;
84
    }
85
86
    /**
87
     * Create a JQuery Element with a given selector, and link it to the current response.
88
     *
89
     * This is a shortcut to the JQuery plugin.
90
     *
91
     * @param string        $sSelector            The jQuery selector
92
     * @param string        $sContext             A context associated to the selector
93
     *
94
     * @return Jaxon\Response\Plugin\JQuery\Dom\Element
95
     */
96
    public function jq($sSelector = '', $sContext = '')
97
    {
98
        return $this->plugin('jquery')->element($sSelector, $sContext);
99
    }
100
101
    /**
102
     * Create a JQuery Element with a given selector, and link it to the current response.
103
     *
104
     * This is a shortcut to the JQuery plugin.
105
     *
106
     * @param string        $sSelector            The jQuery selector
107
     * @param string        $sContext             A context associated to the selector
108
     *
109
     * @return Jaxon\Response\Plugin\JQuery\Dom\Element
110
     */
111
    public function jQuery($sSelector = '', $sContext = '')
112
    {
113
        return $this->jq($sSelector, $sContext);
114
    }
115
116
    /**
117
     * Magic PHP function
118
     *
119
     * Used to permit plugins to be called as if they where native members of the Response instance.
120
     *
121
     * @param string        $sPluginName        The name of the plugin
122
     *
123
     * @return \Jaxon\Plugin\Response
124
     */
125
    public function __get($sPluginName)
126
    {
127
        return $this->plugin($sPluginName);
128
    }
129
130
    /**
131
     * Add a response command to the array of commands that will be sent to the browser
132
     *
133
     * @param array         $aAttributes        Associative array of attributes that will describe the command
134
     * @param mixed            $mData                The data to be associated with this command
135
     *
136
     * @return AbstractResponse
137
     */
138
    public function addCommand($aAttributes, $mData)
139
    {
140
        /* merge commands if possible */
141
        if(in_array($aAttributes['cmd'], ['js', 'ap']))
142
        {
143
            if(($aLastCommand = array_pop($this->aCommands)))
144
            {
145
                if($aLastCommand['cmd'] == $aAttributes['cmd'])
146
                {
147
                    if($this->getOption('core.response.merge.js') &&
148
                            $aLastCommand['cmd'] == 'js')
149
                    {
150
                        $mData = $aLastCommand['data'].'; '.$mData;
151
                    }
152
                    elseif($this->getOption('core.response.merge.ap') &&
153
                            $aLastCommand['cmd'] == 'ap' &&
154
                            $aLastCommand['id'] == $aAttributes['id'] &&
155
                            $aLastCommand['prop'] == $aAttributes['prop'])
156
                    {
157
                        $mData = $aLastCommand['data'].' '.$mData;
158
                    }
159
                    else
160
                    {
161
                        $this->aCommands[] = $aLastCommand;
162
                    }
163
                }
164
                else
165
                {
166
                    $this->aCommands[] = $aLastCommand;
167
                }
168
            }
169
        }
170
        $aAttributes['data'] = $mData;
171
        $this->aCommands[] = $aAttributes;
172
173
        return $this;
174
    }
175
176
    /**
177
     * Clear all the commands already added to the response
178
     *
179
     * @return \Jaxon\Plugin\Response
180
     */
181
    public function clearCommands()
182
    {
183
        $this->aCommands[] = [];
184
185
        return $this;
186
    }
187
188
    /**
189
     * Add a response command that is generated by a plugin
190
     *
191
     * @param \Jaxon\Plugin\Plugin  $xPlugin            The plugin object
192
     * @param array                 $aAttributes        The attributes for this response command
193
     * @param mixed                 $mData              The data to be sent with this command
194
     *
195
     * @return \Jaxon\Plugin\Response
196
     */
197
    public function addPluginCommand($xPlugin, $aAttributes, $mData)
198
    {
199
        $aAttributes['plg'] = $xPlugin->getName();
200
        return $this->addCommand($aAttributes, $mData);
201
    }
202
203
    /**
204
     * Merge the response commands from the specified <Response> object with
205
     * the response commands in this <Response> object
206
     *
207
     * @param AbstractResponse  $mCommands          The <Response> object
208
     * @param boolean           $bBefore            Add the new commands to the beginning of the list
209
     *
210
     * @return void
211
     */
212
    public function appendResponse(AbstractResponse $mCommands, $bBefore = false)
213
    {
214
        $aCommands = [];
215
        if($mCommands instanceof Response)
216
        {
217
            $this->returnValue = $mCommands->returnValue;
218
            $aCommands = $mCommands->aCommands;
219
        }
220
        elseif(is_array($mCommands))
221
        {
222
            $aCommands = $mCommands;
223
        }
224
        else
225
        {
226
            if(!empty($mCommands))
227
            {
228
                throw new \Jaxon\Exception\Error($this->trans('errors.response.data.invalid'));
229
            }
230
        }
231
232
        if(count($aCommands) > 0)
233
        {
234
            if($bBefore)
235
            {
236
                $this->aCommands = array_merge($aCommands, $this->aCommands);
237
            }
238
            else
239
            {
240
                $this->aCommands = array_merge($this->aCommands, $aCommands);
241
            }
242
        }
243
    }
244
245
    /**
246
     * Response command that prompts user with [ok] [cancel] style message box
247
     *
248
     * If the user clicks cancel, the specified number of response commands
249
     * following this one, will be skipped.
250
     *
251
     * @param integer        $iCmdNumber            The number of commands to skip upon cancel
252
     * @param string        $sMessage            The message to display to the user
253
     *
254
     * @return \Jaxon\Plugin\Response
255
     */
256
    public function confirmCommands($iCmdNumber, $sMessage)
257
    {
258
        return $this->addCommand(
259
            [
260
                'cmd' => 'cc',
261
                'id' => $iCmdNumber
262
            ],
263
            trim((string)$sMessage, " \t\n")
264
        );
265
    }
266
267
    /**
268
     * Add a command to assign the specified value to the given element's attribute
269
     *
270
     * @param string        $sTarget              The id of the html element on the browser
271
     * @param string        $sAttribute           The attribute to be assigned
272
     * @param string        $sData                The value to be assigned to the attribute
273
     *
274
     * @return \Jaxon\Plugin\Response
275
     */
276 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...
277
    {
278
        return $this->addCommand(
279
            [
280
                'cmd' => 'as',
281
                'id' => trim((string)$sTarget, " \t"),
282
                'prop' => trim((string)$sAttribute, " \t")
283
            ],
284
            trim((string)$sData, " \t\n")
285
        );
286
    }
287
288
    /**
289
     * Add a command to assign the specified HTML content to the given element
290
     *
291
     * This is a shortcut for assign() on the innerHTML attribute.
292
     *
293
     * @param string        $sTarget              The id of the html element on the browser
294
     * @param string        $sData                The value to be assigned to the attribute
295
     *
296
     * @return \Jaxon\Plugin\Response
297
     */
298
    public function html($sTarget, $sData)
299
    {
300
        return $this->assign($sTarget, 'innerHTML', $sData);
301
    }
302
303
    /**
304
     * Add a command to append the specified data to the given element's attribute
305
     *
306
     * @param string        $sTarget            The id of the element to be updated
307
     * @param string        $sAttribute            The name of the attribute to be appended to
308
     * @param string        $sData                The data to be appended to the attribute
309
     *
310
     * @return \Jaxon\Plugin\Response
311
     */
312 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...
313
    {
314
        return $this->addCommand(
315
            [
316
                'cmd' => 'ap',
317
                'id' => trim((string)$sTarget, " \t"),
318
                'prop' => trim((string)$sAttribute, " \t")
319
            ],
320
            trim((string)$sData, " \t\n")
321
        );
322
    }
323
324
    /**
325
     * Add a command to prepend the specified data to the given element's attribute
326
     *
327
     * @param string        $sTarget            The id of the element to be updated
328
     * @param string        $sAttribute            The name of the attribute to be prepended to
329
     * @param string        $sData                The value to be prepended to the attribute
330
     *
331
     * @return \Jaxon\Plugin\Response
332
     */
333 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...
334
    {
335
        return $this->addCommand(
336
            [
337
                'cmd' => 'pp',
338
                'id' => trim((string)$sTarget, " \t"),
339
                'prop' => trim((string)$sAttribute, " \t")
340
            ],
341
            trim((string)$sData, " \t\n")
342
        );
343
    }
344
345
    /**
346
     * Add a command to replace a specified value with another value within the given element's attribute
347
     *
348
     * @param string        $sTarget            The id of the element to update
349
     * @param string        $sAttribute            The attribute to be updated
350
     * @param string        $sSearch            The needle to search for
351
     * @param string        $sData                The data to use in place of the needle
352
     *
353
     * @return \Jaxon\Plugin\Response
354
     */
355
    public function replace($sTarget, $sAttribute, $sSearch, $sData)
356
    {
357
        return $this->addCommand(
358
            [
359
                'cmd' => 'rp',
360
                'id' => trim((string)$sTarget, " \t"),
361
                'prop' => trim((string)$sAttribute, " \t")
362
            ],
363
            [
364
                's' => trim((string)$sSearch, " \t\n"),
365
                'r' => trim((string)$sData, " \t\n")
366
            ]
367
        );
368
    }
369
370
    /**
371
     * Add a command to clear the specified attribute of the given element
372
     *
373
     * @param string        $sTarget            The id of the element to be updated.
374
     * @param string        $sAttribute            The attribute to be cleared
375
     *
376
     * @return \Jaxon\Plugin\Response
377
     */
378
    public function clear($sTarget, $sAttribute)
379
    {
380
        return $this->assign(trim((string)$sTarget, " \t"), trim((string)$sAttribute, " \t"), '');
381
    }
382
383
    /**
384
     * Add a command to assign a value to a member of a javascript object (or element)
385
     * that is specified by the context member of the request
386
     *
387
     * The object is referenced using the 'this' keyword in the sAttribute parameter.
388
     *
389
     * @param string        $sAttribute            The attribute to be updated
390
     * @param string        $sData                The value to assign
391
     *
392
     * @return \Jaxon\Plugin\Response
393
     */
394 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...
395
    {
396
        return $this->addCommand(
397
            [
398
                'cmd' => 'c:as',
399
                'prop' => trim((string)$sAttribute, " \t")
400
            ],
401
            trim((string)$sData, " \t\n")
402
        );
403
    }
404
405
    /**
406
     * Add a command to append a value onto the specified member of the javascript
407
     * context object (or element) specified by the context member of the request
408
     *
409
     * The object is referenced using the 'this' keyword in the sAttribute parameter.
410
     *
411
     * @param string        $sAttribute            The attribute to be appended to
412
     * @param string        $sData                The value to append
413
     *
414
     * @return \Jaxon\Plugin\Response
415
     */
416 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...
417
    {
418
        return $this->addCommand(
419
            [
420
                'cmd' => 'c:ap',
421
                'prop' => trim((string)$sAttribute, " \t")
422
            ],
423
            trim((string)$sData, " \t\n")
424
        );
425
    }
426
427
    /**
428
     * Add a command to prepend the speicified data to the given member of the current
429
     * javascript object specified by context in the current request
430
     *
431
     * The object is access via the 'this' keyword in the sAttribute parameter.
432
     *
433
     * @param string        $sAttribute            The attribute to be updated
434
     * @param string        $sData                The value to be prepended
435
     *
436
     * @return \Jaxon\Plugin\Response
437
     */
438 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...
439
    {
440
        return $this->addCommand(
441
            [
442
                'cmd' => 'c:pp',
443
                'prop' => trim((string)$sAttribute, " \t")
444
            ],
445
            trim((string)$sData, " \t\n")
446
        );
447
    }
448
449
    /**
450
     * Add a command to to clear the value of the attribute specified in the sAttribute parameter
451
     *
452
     * The member is access via the 'this' keyword and can be used to update a javascript
453
     * object specified by context in the request parameters.
454
     *
455
     * @param string        $sAttribute            The attribute to be cleared
456
     *
457
     * @return \Jaxon\Plugin\Response
458
     */
459
    public function contextClear($sAttribute)
460
    {
461
        return $this->contextAssign(trim((string)$sAttribute, " \t"), '');
462
    }
463
464
    /**
465
     * Add a command to display an alert message to the user
466
     *
467
     * @param string        $sMessage            The message to be displayed
468
     *
469
     * @return \Jaxon\Plugin\Response
470
     */
471
    public function alert($sMessage)
472
    {
473
        return $this->addCommand(
474
            [
475
                'cmd' => 'al'
476
            ],
477
            trim((string)$sMessage, " \t\n")
478
        );
479
    }
480
481
    /**
482
     * Add a command to display a debug message to the user
483
     *
484
     * @param string        $sMessage            The message to be displayed
485
     *
486
     * @return \Jaxon\Plugin\Response
487
     */
488
    public function debug($sMessage)
489
    {
490
        return $this->addCommand(
491
            [
492
                'cmd' => 'dbg'
493
            ],
494
            trim((string)$sMessage, " \t\n")
495
        );
496
    }
497
498
    /**
499
     * Add a command to ask the browser to navigate to the specified URL
500
     *
501
     * @param string        $sURL                The relative or fully qualified URL
502
     * @param integer        $iDelay                Number of seconds to delay before the redirect occurs
503
     *
504
     * @return \Jaxon\Plugin\Response
505
     */
506
    public function redirect($sURL, $iDelay=0)
507
    {
508
        // we need to parse the query part so that the values are rawurlencode()'ed
509
        // can't just use parse_url() cos we could be dealing with a relative URL which
510
        // parse_url() can't deal with.
511
        $queryStart = strpos($sURL, '?', strrpos($sURL, '/'));
512
        if($queryStart !== false)
513
        {
514
            $queryStart++;
515
            $queryEnd = strpos($sURL, '#', $queryStart);
516
            if($queryEnd === false)
517
                $queryEnd = strlen($sURL);
518
            $queryPart = substr($sURL, $queryStart, $queryEnd-$queryStart);
519
            parse_str($queryPart, $queryParts);
520
            $newQueryPart = "";
521
            if($queryParts)
522
            {
523
                $first = true;
524
                foreach($queryParts as $key => $value)
525
                {
526
                    if($first)
527
                        $first = false;
528
                    else
529
                        $newQueryPart .= '&';
530
                    $newQueryPart .= rawurlencode($key).'='.rawurlencode($value);
531
                }
532
            } elseif($_SERVER['QUERY_STRING']) {
533
                    //couldn't break up the query, but there's one there
534
                    //possibly "http://url/page.html?query1234" type of query?
535
                    //just encode it and hope it works
536
                    $newQueryPart = rawurlencode($_SERVER['QUERY_STRING']);
537
                }
538
            $sURL = str_replace($queryPart, $newQueryPart, $sURL);
539
        }
540
        if($iDelay)
541
            $this->script('window.setTimeout("window.location = \'' . $sURL . '\';",' . ($iDelay*1000) . ');');
542
        else
543
            $this->script('window.location = "' . $sURL . '";');
544
        return $this;
545
    }
546
547
    /**
548
     * Add a command to execute a portion of javascript on the browser
549
     *
550
     * The script runs in it's own context, so variables declared locally, using the 'var' keyword,
551
     * will no longer be available after the call.
552
     * To construct a variable that will be accessable globally, even after the script has executed,
553
     * leave off the 'var' keyword.
554
     *
555
     * @param string        $sJS                The script to execute
556
     *
557
     * @return \Jaxon\Plugin\Response
558
     */
559
    public function script($sJS)
560
    {
561
        return $this->addCommand(
562
            [
563
                'cmd' => 'js'
564
            ],
565
            trim((string)$sJS, " \t\n")
566
        );
567
    }
568
569
    /**
570
     * Add a command to call the specified javascript function with the given (optional) parameters
571
     *
572
     * @param string        $sFunc                The name of the function to call
573
     *
574
     * @return \Jaxon\Plugin\Response
575
     */
576
    public function call($sFunc)
577
    {
578
        $aArgs = func_get_args();
579
        array_shift($aArgs);
580
        return $this->addCommand(
581
            [
582
                'cmd' => 'jc',
583
                'func' => $sFunc
584
            ],
585
            $aArgs
586
        );
587
    }
588
589
    /**
590
     * Add a command to remove an element from the document
591
     *
592
     * @param string        $sTarget            The id of the element to be removed
593
     *
594
     * @return \Jaxon\Plugin\Response
595
     */
596
    public function remove($sTarget)
597
    {
598
        return $this->addCommand(
599
            [
600
                'cmd' => 'rm',
601
                'id' => trim((string)$sTarget, " \t")
602
            ],
603
            ''
604
        );
605
    }
606
607
    /**
608
     * Add a command to create a new element on the browser
609
     *
610
     * @param string        $sParent            The id of the parent element
611
     * @param string        $sTag                The tag name to be used for the new element
612
     * @param string        $sId                The id to assign to the new element
613
     *
614
     * @return \Jaxon\Plugin\Response
615
     */
616
    public function create($sParent, $sTag, $sId)
617
    {
618
        return $this->addCommand(
619
            [
620
                'cmd' => 'ce',
621
                'id' => trim((string)$sParent, " \t"),
622
                'prop' => trim((string)$sId, " \t")
623
            ],
624
            trim((string)$sTag, " \t\n")
625
        );
626
    }
627
628
    /**
629
     * Add a command to insert a new element just prior to the specified element
630
     *
631
     * @param string        $sBefore            The id of the element used as a reference point for the insertion
632
     * @param string        $sTag               The tag name to be used for the new element
633
     * @param string        $sId                The id to assign to the new element
634
     *
635
     * @return \Jaxon\Plugin\Response
636
     */
637
    public function insert($sBefore, $sTag, $sId)
638
    {
639
        return $this->addCommand(
640
            [
641
                'cmd' => 'ie',
642
                'id' => trim((string)$sBefore, " \t"),
643
                'prop' => trim((string)$sId, " \t")
644
            ],
645
            trim((string)$sTag, " \t\n")
646
        );
647
    }
648
649
    /**
650
     * Add a command to insert a new element after the specified
651
     *
652
     * @param string        $sAfter             The id of the element used as a reference point for the insertion
653
     * @param string        $sTag               The tag name to be used for the new element
654
     * @param string        $sId                The id to assign to the new element
655
     *
656
     * @return \Jaxon\Plugin\Response
657
     */
658
    public function insertAfter($sAfter, $sTag, $sId)
659
    {
660
        return $this->addCommand(
661
            [
662
                'cmd' => 'ia',
663
                'id' => trim((string)$sAfter, " \t"),
664
                'prop' => trim((string)$sId, " \t")
665
            ],
666
            trim((string)$sTag, " \t\n")
667
        );
668
    }
669
670
    /**
671
     * Add a command to create an input element on the browser
672
     *
673
     * @param string        $sParent            The id of the parent element
674
     * @param string        $sType                The type of the new input element
675
     * @param string        $sName                The name of the new input element
676
     * @param string        $sId                The id of the new element
677
     *
678
     * @return \Jaxon\Plugin\Response
679
     */
680 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...
681
    {
682
        return $this->addCommand(
683
            [
684
                'cmd' => 'ci',
685
                'id' => trim((string)$sParent, " \t"),
686
                'prop' => trim((string)$sId, " \t"),
687
                'type' => trim((string)$sType, " \t")
688
            ],
689
            trim((string)$sName, " \t\n")
690
        );
691
    }
692
693
    /**
694
     * Add a command to insert a new input element preceding the specified element
695
     *
696
     * @param string        $sBefore            The id of the element to be used as the reference point for the insertion
697
     * @param string        $sType                The type of the new input element
698
     * @param string        $sName                The name of the new input element
699
     * @param string        $sId                The id of the new element
700
     *
701
     * @return \Jaxon\Plugin\Response
702
     */
703 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...
704
    {
705
        return $this->addCommand(
706
            [
707
                'cmd' => 'ii',
708
                'id' => trim((string)$sBefore, " \t"),
709
                'prop' => trim((string)$sId, " \t"),
710
                'type' => trim((string)$sType, " \t")
711
            ],
712
            trim((string)$sName, " \t\n")
713
        );
714
    }
715
716
    /**
717
     * Add a command to insert a new input element after the specified element
718
     *
719
     * @param string        $sAfter                The id of the element to be used as the reference point for the insertion
720
     * @param string        $sType                The type of the new input element
721
     * @param string        $sName                The name of the new input element
722
     * @param string        $sId                The id of the new element
723
     *
724
     * @return \Jaxon\Plugin\Response
725
     */
726 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...
727
    {
728
        return $this->addCommand(
729
            [
730
                'cmd' => 'iia',
731
                'id' => trim((string)$sAfter, " \t"),
732
                'prop' => trim((string)$sId, " \t"),
733
                'type' => trim((string)$sType, " \t")
734
            ],
735
            trim((string)$sName, " \t\n")
736
        );
737
    }
738
739
    /**
740
     * Add a command to set an event handler on the browser
741
     *
742
     * @param string        $sTarget            The id of the element that contains the event
743
     * @param string        $sEvent                The name of the event
744
     * @param string        $sScript            The javascript to execute when the event is fired
745
     *
746
     * @return \Jaxon\Plugin\Response
747
     */
748 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...
749
    {
750
        return $this->addCommand(
751
            [
752
                'cmd' => 'ev',
753
                'id' => trim((string)$sTarget, " \t"),
754
                'prop' => trim((string)$sEvent, " \t")
755
            ],
756
            trim((string)$sScript, " \t\n")
757
        );
758
    }
759
760
    /**
761
     * Add a command to set a click handler on the browser
762
     *
763
     * @param string        $sTarget            The id of the element that contains the event
764
     * @param string        $sScript            The javascript to execute when the event is fired
765
     *
766
     * @return \Jaxon\Plugin\Response
767
     */
768
    public function onClick($sTarget, $sScript)
769
    {
770
        return $this->setEvent($sTarget, 'onclick', $sScript);
771
    }
772
773
    /**
774
     * Add a command to install an event handler on the specified element
775
     *
776
     * You can add more than one event handler to an element's event using this method.
777
     *
778
     * @param string        $sTarget             The id of the element
779
     * @param string        $sEvent              The name of the event
780
     * @param string        $sHandler            The name of the javascript function to call when the event is fired
781
     *
782
     * @return \Jaxon\Plugin\Response
783
     */
784 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...
785
    {
786
        return $this->addCommand(
787
            [
788
                'cmd' => 'ah',
789
                'id' => trim((string)$sTarget, " \t"),
790
                'prop' => trim((string)$sEvent, " \t")
791
            ],
792
            trim((string)$sHandler, " \t\n")
793
        );
794
    }
795
796
    /**
797
     * Add a command to remove an event handler from an element
798
     *
799
     * @param string        $sTarget             The id of the element
800
     * @param string        $sEvent              The name of the event
801
     * @param string        $sHandler            The name of the javascript function called when the event is fired
802
     *
803
     * @return \Jaxon\Plugin\Response
804
     */
805 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...
806
    {
807
        return $this->addCommand(
808
            [
809
                'cmd' => 'rh',
810
                'id' => trim((string)$sTarget, " \t"),
811
                'prop' => trim((string)$sEvent, " \t")
812
            ],
813
            trim((string)$sHandler, " \t\n")
814
        );
815
    }
816
817
    /**
818
     * Add a command to construct a javascript function on the browser
819
     *
820
     * @param string        $sFunction            The name of the function to construct
821
     * @param string        $sArgs                Comma separated list of parameter names
822
     * @param string        $sScript            The javascript code that will become the body of the function
823
     *
824
     * @return \Jaxon\Plugin\Response
825
     */
826 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...
827
    {
828
        return $this->addCommand(
829
            [
830
                'cmd' => 'sf',
831
                'func' => trim((string)$sFunction, " \t"),
832
                'prop' => trim((string)$sArgs, " \t")
833
            ],
834
            trim((string)$sScript, " \t\n")
835
        );
836
    }
837
838
    /**
839
     * Add a command to construct a wrapper function around an existing javascript function on the browser
840
     *
841
     * @param string        $sFunction            The name of the existing function to wrap
842
     * @param string        $sArgs                The comma separated list of parameters for the function
843
     * @param array            $aScripts            An array of javascript code snippets that will be used to build
844
     *                                             the body of the function
845
     *                                             The first piece of code specified in the array will occur before
846
     *                                             the call to the original function, the second will occur after
847
     *                                             the original function is called.
848
     * @param string        $sReturnValueVar    The name of the variable that will retain the return value
849
     *                                             from the call to the original function
850
     *
851
     * @return \Jaxon\Plugin\Response
852
     */
853 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...
854
    {
855
        return $this->addCommand(
856
            [
857
                'cmd' => 'wpf',
858
                'func' => trim((string)$sFunction, " \t"),
859
                'prop' => trim((string)$sArgs, " \t"),
860
                'type' => trim((string)$sReturnValueVar, " \t")
861
            ],
862
            $aScripts
863
        );
864
    }
865
866
    /**
867
     * Add a command to load a javascript file on the browser
868
     *
869
     * @param string        $sFileName            The relative or fully qualified URI of the javascript file
870
     * @param string        $sType                Determines the script type. Defaults to 'text/javascript'
871
     *
872
     * @return \Jaxon\Plugin\Response
873
     */
874 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...
875
    {
876
        $command = ['cmd'  =>  'in'];
877
878
        if(($sType))
879
            $command['type'] = trim((string)$sType, " \t");
880
881
        if(($sId))
882
            $command['elm_id'] = trim((string)$sId, " \t");
883
884
        return $this->addCommand($command, trim((string)$sFileName, " \t"));
885
    }
886
887
    /**
888
     * Add a command to include a javascript file on the browser if it has not already been loaded
889
     *
890
     * @param string        $sFileName            The relative or fully qualified URI of the javascript file
891
     * @param string        $sType                Determines the script type. Defaults to 'text/javascript'
892
     *
893
     * @return \Jaxon\Plugin\Response
894
     */
895 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...
896
    {
897
        $command = ['cmd' => 'ino'];
898
899
        if(($sType))
900
            $command['type'] = trim((string)$sType, " \t");
901
902
        if(($sId))
903
            $command['elm_id'] = trim((string)$sId, " \t");
904
905
        return $this->addCommand($command, trim((string)$sFileName, " \t"));
906
    }
907
908
    /**
909
     * Add a command to remove a SCRIPT reference to a javascript file on the browser
910
     *
911
     * Optionally, you can call a javascript function just prior to the file being unloaded (for cleanup).
912
     *
913
     * @param string        $sFileName            The relative or fully qualified URI of the javascript file
914
     * @param string        $sUnload            Name of a javascript function to call prior to unlaoding the file
915
     *
916
     * @return \Jaxon\Plugin\Response
917
     */
918
    public function removeScript($sFileName, $sUnload = '')
919
    {
920
        return $this->addCommand(
921
            [
922
                'cmd' => 'rjs',
923
                'unld' => trim((string)$sUnload, " \t")
924
            ],
925
            trim((string)$sFileName, " \t")
926
        );
927
    }
928
929
    /**
930
     * Add a command to include a LINK reference to the specified CSS file on the browser.
931
     *
932
     * This will cause the browser to load and apply the style sheet.
933
     *
934
     * @param string        $sFileName            The relative or fully qualified URI of the css file
935
     * @param string        $sMedia                The media type of the CSS file. Defaults to 'screen'
936
     *
937
     * @return \Jaxon\Plugin\Response
938
     */
939 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...
940
    {
941
        $command = ['cmd' => 'css'];
942
943
        if(($sMedia))
944
            $command['media'] = trim((string)$sMedia, " \t");
945
946
        return $this->addCommand($command, trim((string)$sFileName, " \t"));
947
    }
948
949
    /**
950
     * Add a command to remove a LINK reference to a CSS file on the browser
951
     *
952
     * This causes the browser to unload the style sheet, effectively removing the style changes it caused.
953
     *
954
     * @param string        $sFileName            The relative or fully qualified URI of the css file
955
     *
956
     * @return \Jaxon\Plugin\Response
957
     */
958 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...
959
    {
960
        $command = ['cmd' => 'rcss'];
961
962
        if(($sMedia))
963
            $command['media'] = trim((string)$sMedia, " \t");
964
965
        return $this->addCommand($command, trim((string)$sFileName, " \t"));
966
    }
967
968
    /**
969
     * Add a command to make Jaxon pause while the CSS files are loaded
970
     *
971
     * The browser is not typically a multi-threading application, with regards to javascript code.
972
     * Therefore, the CSS files included or removed with <Response->includeCSS> and
973
     * <Response->removeCSS> respectively, will not be loaded or removed until the browser regains
974
     * control from the script.
975
     * This command returns control back to the browser and pauses the execution of the response
976
     * until the CSS files, included previously, are loaded.
977
     *
978
     * @param integer        $iTimeout            The number of 1/10ths of a second to pause before timing out
979
     *                                             and continuing with the execution of the response commands
980
     *
981
     * @return \Jaxon\Plugin\Response
982
     */
983
    public function waitForCSS($iTimeout = 600)
984
    {
985
        $sData = "";
986
        return $this->addCommand(
987
            [
988
                'cmd' => 'wcss',
989
                'prop' => $iTimeout
990
            ],
991
            $sData
992
        );
993
    }
994
995
    /**
996
     * Add a command to make Jaxon to delay execution of the response commands until a specified condition is met
997
     *
998
     * Note, this returns control to the browser, so that other script operations can execute.
999
     * Jaxon will continue to monitor the specified condition and, when it evaulates to true,
1000
     * will continue processing response commands.
1001
     *
1002
     * @param string        $script                A piece of javascript code that evaulates to true or false
1003
     * @param integer        $tenths                The number of 1/10ths of a second to wait before timing out
1004
     *                                             and continuing with the execution of the response commands.
1005
     *
1006
     * @return \Jaxon\Plugin\Response
1007
     */
1008
    public function waitFor($script, $tenths)
1009
    {
1010
        return $this->addCommand(
1011
            [
1012
                'cmd' => 'wf',
1013
                'prop' => $tenths
1014
            ],
1015
            trim((string)$script, " \t\n")
1016
        );
1017
    }
1018
1019
    /**
1020
     * Add a command to make Jaxon to pause execution of the response commands,
1021
     * returning control to the browser so it can perform other commands asynchronously.
1022
     *
1023
     * After the specified delay, Jaxon will continue execution of the response commands.
1024
     *
1025
     * @param integer        $tenths                The number of 1/10ths of a second to sleep
1026
     *
1027
     * @return \Jaxon\Plugin\Response
1028
     */
1029
    public function sleep($tenths)
1030
    {
1031
        return $this->addCommand(
1032
            [
1033
                'cmd' => 's',
1034
                'prop' => $tenths
1035
            ],
1036
            ''
1037
        );
1038
    }
1039
1040
    /**
1041
     * Add a command to start a DOM response
1042
     *
1043
     * @return \Jaxon\Plugin\Response
1044
     */
1045
    public function domStartResponse()
1046
    {
1047
        $this->script('jxnElm = []');
1048
    }
1049
1050
    /**
1051
     * Add a command to create a DOM element
1052
     *
1053
     * @param string        $variable            The DOM element name (id or class)
1054
     * @param string        $tag                The HTML tag of the new DOM element
1055
     *
1056
     * @return \Jaxon\Plugin\Response
1057
     */
1058
    public function domCreateElement($variable, $tag)
1059
    {
1060
        return $this->addCommand(
1061
            [
1062
                'cmd' => 'DCE',
1063
                'tgt' => $variable
1064
            ],
1065
            $tag
1066
        );
1067
    }
1068
1069
    /**
1070
     * Add a command to set an attribute on a DOM element
1071
     *
1072
     * @param string        $variable            The DOM element name (id or class)
1073
     * @param string        $key                The name of the attribute
1074
     * @param string        $value                The value of the attribute
1075
     *
1076
     * @return \Jaxon\Plugin\Response
1077
     */
1078
    public function domSetAttribute($variable, $key, $value)
1079
    {
1080
        return $this->addCommand(
1081
            [
1082
                'cmd' => 'DSA',
1083
                'tgt' => $variable,
1084
                'key' => $key
1085
            ],
1086
            $value
1087
        );
1088
    }
1089
1090
    /**
1091
     * Add a command to remove children from a DOM element
1092
     *
1093
     * @param string        $parent                The DOM parent element
1094
     * @param string        $skip                The ??
1095
     * @param string        $remove                The ??
1096
     *
1097
     * @return \Jaxon\Plugin\Response
1098
     */
1099
    public function domRemoveChildren($parent, $skip = null, $remove = null)
1100
    {
1101
        $command = ['cmd' => 'DRC'];
1102
1103
        if(($skip))
1104
            $command['skip'] = $skip;
1105
1106
        if(($remove))
1107
            $command['remove'] = $remove;
1108
1109
        return $this->addCommand($command, $parent);
1110
    }
1111
1112
    /**
1113
     * Add a command to append a child to a DOM element
1114
     *
1115
     * @param string        $parent                The DOM parent element
1116
     * @param string        $variable            The DOM element name (id or class)
1117
     *
1118
     * @return \Jaxon\Plugin\Response
1119
     */
1120
    public function domAppendChild($parent, $variable)
1121
    {
1122
        return $this->addCommand(
1123
            [
1124
                'cmd' => 'DAC',
1125
                'par' => $parent
1126
            ],
1127
            $variable
1128
        );
1129
    }
1130
1131
    /**
1132
     * Add a command to insert a DOM element before another
1133
     *
1134
     * @param string        $target                The DOM target element
1135
     * @param string        $variable            The DOM element name (id or class)
1136
     *
1137
     * @return \Jaxon\Plugin\Response
1138
     */
1139
    public function domInsertBefore($target, $variable)
1140
    {
1141
        return $this->addCommand(
1142
            [
1143
                'cmd' => 'DIB',
1144
                'tgt' => $target
1145
            ],
1146
            $variable
1147
        );
1148
    }
1149
1150
    /**
1151
     * Add a command to insert a DOM element after another
1152
     *
1153
     * @param string        $target                The DOM target element
1154
     * @param string        $variable            The DOM element name (id or class)
1155
     *
1156
     * @return \Jaxon\Plugin\Response
1157
     */
1158
    public function domInsertAfter($target, $variable)
1159
    {
1160
        return $this->addCommand(
1161
            [
1162
                'cmd' => 'DIA',
1163
                'tgt' => $target
1164
            ],
1165
            $variable
1166
        );
1167
    }
1168
1169
    /**
1170
     * Add a command to append a text to a DOM element
1171
     *
1172
     * @param string        $parent                The DOM parent element
1173
     * @param string        $text                The HTML text to append
1174
     *
1175
     * @return \Jaxon\Plugin\Response
1176
     */
1177
    public function domAppendText($parent, $text)
1178
    {
1179
        return $this->addCommand(
1180
            [
1181
                'cmd' => 'DAT',
1182
                'par' => $parent
1183
            ],
1184
            $text
1185
        );
1186
    }
1187
1188
    /**
1189
     * Add a command to end a DOM response
1190
     *
1191
     * @return \Jaxon\Plugin\Response
1192
     */
1193
    public function domEndResponse()
1194
    {
1195
        $this->script('jxnElm = []');
1196
    }
1197
1198
    /**
1199
     * Get the number of commands in the response
1200
     *
1201
     * @return integer
1202
     */
1203
    public function getCommandCount()
1204
    {
1205
        return count($this->aCommands);
1206
    }
1207
1208
    /**
1209
     * Stores a value that will be passed back as part of the response
1210
     *
1211
     * When making synchronous requests, the calling javascript can obtain this value
1212
     * immediately as the return value of the <jaxon.call> javascript function
1213
     *
1214
     * @param mixed        $value                Any value
1215
     *
1216
     * @return \Jaxon\Plugin\Response
1217
     */
1218
    public function setReturnValue($value)
1219
    {
1220
        $this->returnValue = $value;
1221
        return $this;
1222
    }
1223
1224
    /**
1225
     * Return the output, generated from the commands added to the response, that will be sent to the browser
1226
     *
1227
     * @return string
1228
     */
1229
    public function getOutput()
1230
    {
1231
        $response = [];
1232
1233
        if(($this->returnValue))
1234
        {
1235
            $response['jxnrv'] = $this->returnValue;
1236
        }
1237
        $response['jxnobj'] = [];
1238
1239
        foreach($this->aCommands as $xCommand)
1240
        {
1241
            $response['jxnobj'][] = $xCommand;
1242
        }
1243
1244
        return json_encode($response);
1245
    }
1246
}
1247