Completed
Push — master ( 887921...ad91dd )
by Thierry
01:28
created

Request::__construct()   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 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Request.php - The Jaxon Request
5
 *
6
 * This class is used to create client side requests to callable classes and functions.
7
 *
8
 * @package jaxon-core
9
 * @author Jared White
10
 * @author J. Max Wilson
11
 * @author Joseph Woolley
12
 * @author Steffen Konerow
13
 * @author Thierry Feuzeu <[email protected]>
14
 * @copyright Copyright (c) 2005-2007 by Jared White & J. Max Wilson
15
 * @copyright Copyright (c) 2008-2010 by Joseph Woolley, Steffen Konerow, Jared White  & J. Max Wilson
16
 * @copyright 2016 Thierry Feuzeu <[email protected]>
17
 * @license https://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
18
 * @link https://github.com/jaxon-php/jaxon-core
19
 */
20
21
namespace Jaxon\Request\Factory;
22
23
use JsonSerializable;
24
use Jaxon\Request\Factory\Parameter;
25
use Jaxon\Request\Factory\Contracts\Parameter as ParameterContract;
26
use Jaxon\Response\Plugin\JQuery\Dom\Element as DomElement;
27
28
class Request extends JsCall
29
{
30
    use Features\Condition;
31
32
    /**
33
     * The arguments of the confirm() call
34
     *
35
     * @var array
36
     */
37
    protected $aMessageArgs = [];
38
39
    /**
40
     * The constructor.
41
     *
42
     * @param string        $sName            The javascript function or method name
43
     */
44
    public function __construct($sName)
45
    {
46
        parent::__construct($sName);
47
    }
48
49
    /**
50
     * Check if the request has a parameter of type Parameter::PAGE_NUMBER
51
     *
52
     * @return boolean
53
     */
54
    public function hasPageNumber()
55
    {
56
        foreach($this->aParameters as $xParameter)
57
        {
58
            if($xParameter->getType() == Parameter::PAGE_NUMBER)
59
            {
60
                return true;
61
            }
62
        }
63
        return false;
64
    }
65
66
    /**
67
     * Set a value to the Parameter::PAGE_NUMBER parameter
68
     *
69
     * @param integer        $nPageNumber        The current page number
70
     *
71
     * @return Request
72
     */
73
    public function setPageNumber($nPageNumber)
74
    {
75
        // Set the value of the Parameter::PAGE_NUMBER parameter
76
        foreach($this->aParameters as $xParameter)
77
        {
78
            if($xParameter->getType() == Parameter::PAGE_NUMBER)
79
            {
80
                $xParameter->setValue(intval($nPageNumber));
81
                break;
82
            }
83
        }
84
        return $this;
85
    }
86
87
    /**
88
     * Create parameters for message arguments
89
     *
90
     * @param   $aArgs          The arguments
91
     *
92
     * @return void
93
     */
94
    private function setMessageArgs(array $aArgs)
95
    {
96
        array_walk($aArgs, function (&$xParameter) {
97
            $xParameter = Parameter::make($xParameter);
98
        });
99
        $this->aMessageArgs = $aArgs;
100
    }
101
102
    /**
103
     * Add a confirmation question to the request
104
     *
105
     * @param string        $sQuestion                The question to ask
106
     *
107
     * @return Request
108
     */
109
    public function confirm($sQuestion)
110
    {
111
        $this->sCondition = '__confirm__';
112
        $this->setMessageArgs(func_get_args());
113
        return $this;
114
    }
115
116
    /**
117
     * Set the message to show if the condition to send the request is not met
118
     *
119
     * The first parameter is the message to show. The followin allow to insert data from
120
     * the webpage in the message using positional placeholders.
121
     *
122
     * @param string        $sMessage                 The message to show if the request is not sent
123
     *
124
     * @return Request
125
     */
126
    public function elseShow($sMessage)
127
    {
128
        $this->setMessageArgs(func_get_args());
129
        return $this;
130
    }
131
132
    /**
133
     * Make unique js vars for parameters of type DomElement
134
     *
135
     * @var ParameterContract   $xParameter
136
     * @var array               &$aVariables
137
     * @var string              &$sVars
138
     * @var integer             &$nVarId
139
     *
140
     * @return ParameterContract
141
     */
142
    private function _makeUniqueJsVar(ParameterContract $xParameter, array &$aVariables, &$sVars, &$nVarId)
143
    {
144
        if($xParameter instanceof DomElement)
145
        {
146
            $sParameterStr = $xParameter->getScript();
147
            if(!array_key_exists($sParameterStr, $aVariables))
148
            {
149
                // The value is not yet defined. A new variable is created.
150
                $sVarName = "jxnVar$nVarId";
151
                $aVariables[$sParameterStr] = $sVarName;
152
                $sVars .= "$sVarName=$xParameter;";
153
                $nVarId++;
154
            }
155
            else
156
            {
157
                // The value is already defined. The corresponding variable is assigned.
158
                $sVarName = $aVariables[$sParameterStr];
159
            }
160
            $xParameter = new Parameter(Parameter::JS_VALUE, $sVarName);
161
        }
162
        return $xParameter;
163
    }
164
165
    /**
166
     * Returns a string representation of the script output (javascript) from this request object
167
     *
168
     * @return string
169
     */
170
    public function getScript()
171
    {
172
        /*
173
         * JQuery variables sometimes depend on the context where they are used, eg. when their value depends on $(this).
174
         * When a confirmation question is added, the Jaxon calls are made in a different context,
175
         * making those variables invalid.
176
         * To avoid issues related to these context changes, the JQuery selectors values are first saved into
177
         * local variables, which are then used in Jaxon function calls.
178
         */
179
        $sVars = ''; // Javascript code defining all the variables values.
180
        $nVarId = 1; // Position of the variables, starting from 1.
181
        // This array will avoid declaring multiple variables with the same value.
182
        // The array key is the variable value, while the array value is the variable name.
183
        $aVariables = []; // Array of local variables.
184
        foreach($this->aParameters as &$xParameter)
185
        {
186
            $xParameter = $this->_makeUniqueJsVar($xParameter, $aVariables, $sVars, $nVarId);
187
        }
188
189
        $sPhrase = '';
190
        if(count($this->aMessageArgs) > 0)
191
        {
192
            $sPhrase = array_shift($this->aMessageArgs); // The first array entry is the question.
193
            // $sPhrase = "'" . addslashes($sPhrase) . "'"; // Wrap the phrase with single quotes
194
            if(count($this->aMessageArgs) > 0)
195
            {
196
                $nParamId = 1;
197
                foreach($this->aMessageArgs as &$xParameter)
198
                {
199
                    $xParameter = $this->_makeUniqueJsVar($xParameter, $aVariables, $sVars, $nVarId);
200
                    $xParameter = "'$nParamId':" . $xParameter->getScript();
201
                    $nParamId++;
202
                }
203
                $sPhrase .= '.supplant({' . implode(',', $this->aMessageArgs) . '})';
204
            }
205
        }
206
207
        $sScript = parent::getScript();
208
        $xDialog = jaxon()->dialog();
209
        if($this->sCondition == '__confirm__')
210
        {
211
            $sScript = $xDialog->confirm($sPhrase, $sScript, '');
212
        }
213
        elseif($this->sCondition !== null)
214
        {
215
            $sScript = 'if(' . $this->sCondition . '){' . $sScript . ';}';
216
            if(($sPhrase))
217
            {
218
                $xDialog->getAlert()->setReturn(true);
219
                $sScript .= 'else{' . $xDialog->warning($sPhrase) . ';}';
220
            }
221
        }
222
        return $sVars . $sScript;
223
    }
224
225
    /**
226
     * Prints a string representation of the script output (javascript) from this request object
227
     *
228
     * @return void
229
     */
230
    public function printScript()
231
    {
232
        print $this->getScript();
233
    }
234
235
    /**
236
     * Make the pagination links for this request
237
     *
238
     * @param integer       $nCurrentPage           The current page
239
     * @param integer       $nItemsPerPage          The number of items per page page
240
     * @param integer       $nItemsTotal            The total number of items
241
     *
242
     * @return Paginator
243
     */
244
    public function pg($nCurrentPage, $nItemsPerPage, $nItemsTotal)
245
    {
246
        return jaxon()->di()->getPaginator()
247
            ->setup($nItemsTotal, $nItemsPerPage, $nCurrentPage, $this);
248
    }
249
250
    /**
251
     * Make the pagination links for this request
252
     *
253
     * @param integer       $nCurrentPage           The current page
254
     * @param integer       $nItemsPerPage          The number of items per page page
255
     * @param integer       $nItemsTotal            The total number of items
256
     *
257
     * @return Paginator
258
     */
259
    public function paginate($nCurrentPage, $nItemsPerPage, $nItemsTotal)
260
    {
261
        return $this->pg($nCurrentPage, $nItemsPerPage, $nItemsTotal);
262
    }
263
}
264