This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /** |
||
4 | * @description: |
||
5 | * The Order Confirmation page shows order history. |
||
6 | * It also serves as the end point for the current order... |
||
7 | * once submitted, the Order Confirmation page shows the |
||
8 | * finalised detail of the order. |
||
9 | * |
||
10 | * |
||
11 | * @authors: Nicolaas [at] Sunny Side Up .co.nz |
||
12 | * @package: ecommerce |
||
13 | * @sub-package: Pages |
||
14 | * @inspiration: Silverstripe Ltd, Jeremy |
||
15 | **/ |
||
16 | class OrderConfirmationPage extends CartPage |
||
17 | { |
||
18 | /** |
||
19 | * Standard SS variable. |
||
20 | * |
||
21 | * @var string |
||
22 | */ |
||
23 | private static $icon = 'ecommerce/images/icons/OrderConfirmationPage'; |
||
0 ignored issues
–
show
Comprehensibility
introduced
by
![]() |
|||
24 | |||
25 | /** |
||
26 | * Standard SS variable. |
||
27 | * |
||
28 | * @var array |
||
29 | */ |
||
30 | private static $db = array( |
||
0 ignored issues
–
show
|
|||
31 | 'StartNewOrderLinkLabel' => 'Varchar(100)', |
||
32 | 'CopyOrderLinkLabel' => 'Varchar(100)', |
||
33 | 'OrderCancelledHeader' => 'Varchar(255)', |
||
34 | 'PaymentSuccessfulHeader' => 'Varchar(255)', |
||
35 | 'PaymentNotSuccessfulHeader' => 'Varchar(255)', |
||
36 | 'PaymentPendingHeader' => 'Varchar(255)', |
||
37 | 'OrderCancelledMessage' => 'HTMLText', |
||
38 | 'PaymentSuccessfulMessage' => 'HTMLText', |
||
39 | 'PaymentNotSuccessfulMessage' => 'HTMLText', |
||
40 | 'PaymentPendingMessage' => 'HTMLText', |
||
41 | 'EnableGoogleAnalytics' => 'Boolean', |
||
42 | 'IsFeedbackEnabled' => 'Boolean', |
||
43 | 'FeedbackFormLinkText' => 'Varchar(255)', |
||
44 | 'FeedbackHeader' => 'Varchar(255)', |
||
45 | 'FeedbackValuesFieldLabel' => 'Varchar(255)', |
||
46 | 'FeedbackValuesOptions' => 'Text', |
||
47 | 'FeedbackNotesFieldLabel' => 'Varchar(255)', |
||
48 | 'FeedbackFormSubmitLabel' => 'Varchar(255)', |
||
49 | 'FeedbackFormThankYou' => 'Varchar(255)' |
||
50 | ); |
||
51 | |||
52 | /** |
||
53 | * Standard SS variable. |
||
54 | * |
||
55 | * @var array |
||
56 | */ |
||
57 | private static $defaults = array( |
||
0 ignored issues
–
show
|
|||
58 | 'ShowInMenus' => false, |
||
59 | 'ShowInSearch' => false, |
||
60 | 'StartNewOrderLinkLabel' => 'start new order', |
||
61 | 'CopyOrderLinkLabel' => 'copy order items into a new order', |
||
62 | 'OrderCancelledHeader' => 'Order has been cancelled', |
||
63 | 'PaymentSuccessfulHeader' => 'Payment Successful', |
||
64 | 'PaymentNotSuccessfulHeader' => 'Payment not Completed', |
||
65 | 'PaymentPendingHeader' => 'Payment Pending', |
||
66 | 'OrderCancelledMessage' => '<p>This order is no longer valid.</p>', |
||
67 | 'PaymentSuccessfulMessage' => '<p>Your order will be processed.</p>', |
||
68 | 'PaymentNotSuccessfulMessage' => '<p>Your order will not be processed until your payment has been completed.</p>', |
||
69 | 'PaymentPendingMessage' => '<p>Please complete your payment before the order can be processed.</p>', |
||
70 | 'FeedbackHeader' => 'Feedback', |
||
71 | 'FeedbackValuesFieldLabel' => 'How likely are you to recommend us to your friends?', |
||
72 | 'FeedbackValuesOptions' => 'Not At All, Not Likely, Not Sure, Likely, Very Likely', |
||
73 | 'FeedbackNotesFieldLabel' => 'What can we do to improve the ordering experience?', |
||
74 | 'FeedbackFormSubmitLabel' => 'Submit Your Feedback', |
||
75 | 'FeedbackFormThankYou' => 'Thank you for taking the time to submit your feedback, we appreciate it!' |
||
76 | ); |
||
77 | |||
78 | private static $casting = array( |
||
0 ignored issues
–
show
|
|||
79 | "PaymentMessage" => "HTMLText" |
||
80 | ); |
||
81 | |||
82 | /** |
||
83 | * standard SS variable. |
||
84 | * |
||
85 | * @Var String |
||
86 | */ |
||
87 | private static $singular_name = 'Order Confirmation Page'; |
||
0 ignored issues
–
show
|
|||
88 | public function i18n_singular_name() |
||
89 | { |
||
90 | return _t('OrderConfirmationpage.SINGULARNAME', 'Order Confirmation Page'); |
||
91 | } |
||
92 | |||
93 | /** |
||
94 | * standard SS variable. |
||
95 | * |
||
96 | * @Var String |
||
97 | */ |
||
98 | private static $plural_name = 'Order Confirmation Pages'; |
||
0 ignored issues
–
show
|
|||
99 | public function i18n_plural_name() |
||
100 | { |
||
101 | return _t('OrderConfirmationpage.PLURALNAME', 'Order Confirmation Pages'); |
||
102 | } |
||
103 | |||
104 | /** |
||
105 | * Standard SS variable. |
||
106 | * |
||
107 | * @var string |
||
108 | */ |
||
109 | private static $description = 'A page where the customer can view her or his submitted order. Every e-commerce site needs an Order Confirmation Page.'; |
||
0 ignored issues
–
show
|
|||
110 | |||
111 | /** |
||
112 | * Standard SS function, we only allow for one OrderConfirmation Page to exist |
||
113 | * but we do allow for extensions to exist at the same time. |
||
114 | * |
||
115 | * @param Member $member |
||
0 ignored issues
–
show
Should the type for parameter
$member not be Member|null ?
This check looks for It makes a suggestion as to what type it considers more descriptive. Most often this is a case of a parameter that can be null in addition to its declared types. ![]() |
|||
116 | * |
||
117 | * @return bool |
||
118 | */ |
||
119 | public function canCreate($member = null) |
||
120 | { |
||
121 | return OrderConfirmationPage::get()->filter(array('ClassName' => 'OrderConfirmationPage'))->Count() ? false : $this->canEdit($member); |
||
122 | } |
||
123 | |||
124 | /** |
||
125 | * Shop Admins can edit. |
||
126 | * |
||
127 | * @param Member $member |
||
0 ignored issues
–
show
Should the type for parameter
$member not be Member|null ?
This check looks for It makes a suggestion as to what type it considers more descriptive. Most often this is a case of a parameter that can be null in addition to its declared types. ![]() |
|||
128 | * |
||
129 | * @return bool |
||
130 | */ |
||
131 | public function canEdit($member = null) |
||
132 | { |
||
133 | if (Permission::checkMember($member, Config::inst()->get('EcommerceRole', 'admin_permission_code'))) { |
||
134 | return true; |
||
135 | } |
||
136 | |||
137 | return parent::canEdit($member); |
||
138 | } |
||
139 | |||
140 | /** |
||
141 | * Standard SS method. |
||
142 | * |
||
143 | * @param Member $member |
||
0 ignored issues
–
show
Should the type for parameter
$member not be Member|null ?
This check looks for It makes a suggestion as to what type it considers more descriptive. Most often this is a case of a parameter that can be null in addition to its declared types. ![]() |
|||
144 | * |
||
145 | * @return bool |
||
146 | */ |
||
147 | public function canDelete($member = null) |
||
148 | { |
||
149 | return false; |
||
150 | } |
||
151 | |||
152 | /** |
||
153 | * Standard SS method. |
||
154 | * |
||
155 | * @param Member $member |
||
0 ignored issues
–
show
Should the type for parameter
$member not be Member|null ?
This check looks for It makes a suggestion as to what type it considers more descriptive. Most often this is a case of a parameter that can be null in addition to its declared types. ![]() |
|||
156 | * |
||
157 | * @return bool |
||
158 | */ |
||
159 | public function canPublish($member = null) |
||
160 | { |
||
161 | return $this->canEdit($member); |
||
162 | } |
||
163 | |||
164 | public function customFieldLabels() |
||
165 | { |
||
166 | $newLabels = array( |
||
167 | 'StartNewOrderLinkLabel' => _t('OrderConfirmationPage.STARTNEWORDERLINKLABEL', 'Label for starting new order - e.g. click here to start new order.'), |
||
168 | 'CopyOrderLinkLabel' => _t('OrderConfirmationPage.COPYORDERLINKLABEL', 'Label for copying order items into a new one - e.g. click here start a new order with the current order items.'), |
||
169 | 'OrderCancelledHeader' => _t('OrderConfirmationPage.ORDERCANCELLEDHEADER', 'Header showing when order has been cancelled.'), |
||
170 | 'PaymentSuccessfulHeader' => _t('OrderConfirmationPage.PAYMENTSUCCESSFULHEADER', 'Header showing when order has been paid in full.'), |
||
171 | 'PaymentNotSuccessfulHeader' => _t('OrderConfirmationPage.PAYMENTNOTSUCCESSFULHEADER', 'Header showing when the order has not been paid in full.'), |
||
172 | 'PaymentPendingHeader' => _t('OrderConfirmationPage.PAYMENTPENDINGHEADER', 'Header showing when the order has not been paid in full - but the payment is pending.'), |
||
173 | 'OrderCancelledMessage' => _t('OrderConfirmationPage.ORDERCANCELLEDMESSAGE', 'Message showing when order has been paid cancelled.'), |
||
174 | 'PaymentSuccessfulMessage' => _t('OrderConfirmationPage.PAYMENTSUCCESSFULMESSAGE', 'Message showing when order has been paid in full.'), |
||
175 | 'PaymentNotSuccessfulMessage' => _t('OrderConfirmationPage.PAYMENTNOTSUCCESSFULMESSAGE', 'Message showing when the order has not been paid in full.'), |
||
176 | 'PaymentPendingMessage' => _t('OrderConfirmationPage.PAYMENTPENDINGMESSAGE', 'Message showing when the order has not been paid in full - but the payment is pending.'), |
||
177 | 'EnableGoogleAnalytics' => _t('OrderConfirmationPage.ENABLEGOOGLEANALYTICS', 'Enable E-commerce Google Analytics. Make sure it is turned on in your Google Analytics account.'), |
||
178 | 'IsFeedbackEnabled' => _t('OrderConfirmationPage.ISFEEDBACKENABLED', 'Enable Feedback Form'), |
||
179 | 'FeedbackHeader' => _t('OrderConfirmationPage.FEEDBACKHEADER', 'Feedback Form Header'), |
||
180 | 'FeedbackValuesFieldLabel' => _t('OrderConfirmationPage.FEEDBACKVALUESFIELDLABEL', 'Feedback Form Options Label'), |
||
181 | 'FeedbackValuesOptions' => _t('OrderConfirmationPage.FEEDBACKVALUESOPTIONS', 'Feedback Form Options'), |
||
182 | 'FeedbackNotesFieldLabel' => _t('OrderConfirmationPage.FEEDBACKVALUESFIELDLABEL', 'Feedback Form Notes Label'), |
||
183 | 'FeedbackFormSubmitLabel' => _t('OrderConfirmationPage.FEEDBACKFORMSUBMITLABEL', 'Feedback Form Submit Button Text'), |
||
184 | 'FeedbackFormThankYou' => _t('OrderConfirmationPage.FEEDBACKFORMTHANKYOU', 'Feedback Form Thank you Message') |
||
185 | ); |
||
186 | |||
187 | return $newLabels; |
||
188 | } |
||
189 | |||
190 | /** |
||
191 | * standard SS method for decorators. |
||
192 | * |
||
193 | * @param bool - $includerelations: array of fields to start with |
||
194 | * |
||
195 | * @return array |
||
196 | */ |
||
197 | public function fieldLabels($includerelations = true) |
||
198 | { |
||
199 | $defaultLabels = parent::fieldLabels(); |
||
200 | $newLabels = $this->customFieldLabels(); |
||
201 | $labels = array_merge($defaultLabels, $newLabels); |
||
202 | $extendedArray = $this->extend('updateFieldLabels', $labels); |
||
203 | if ($extendedArray !== null && is_array($extendedArray) && count($extendedArray)) { |
||
204 | foreach ($extendedArray as $extendedResult) { |
||
205 | $labels = array_merge($labels, $extendedResult); |
||
206 | } |
||
207 | } |
||
208 | |||
209 | return $labels; |
||
210 | } |
||
211 | |||
212 | /** |
||
213 | *@return FieldList |
||
214 | **/ |
||
215 | public function getCMSFields() |
||
216 | { |
||
217 | $fields = parent::getCMSFields(); |
||
218 | $fields->removeFieldFromTab('Root.Messages.Messages.Actions', 'ProceedToCheckoutLabel'); |
||
219 | $fields->removeFieldFromTab('Root.Messages.Messages.Actions', 'ContinueShoppingLabel'); |
||
220 | $fields->removeFieldFromTab('Root.Messages.Messages.Actions', 'ContinuePageID'); |
||
221 | $fields->removeFieldFromTab('Root.Messages.Messages.Actions', 'SaveOrderLinkLabel'); |
||
222 | $fields->removeFieldFromTab('Root.Messages.Messages.Errors', 'NoItemsInOrderMessage'); |
||
223 | $fieldLabels = $this->fieldLabels(); |
||
224 | $fields->addFieldToTab('Root.Messages.Messages.Actions', TextField::create('StartNewOrderLinkLabel', $fieldLabels['StartNewOrderLinkLabel'])); |
||
225 | $fields->addFieldToTab('Root.Messages.Messages.Actions', TextField::create('CopyOrderLinkLabel', $fieldLabels['CopyOrderLinkLabel'])); |
||
226 | $fields->addFieldsToTab('Root.Messages.Messages.Payment', array( |
||
227 | HeaderField::create('Successful'), |
||
228 | TextField::create('PaymentSuccessfulHeader', $fieldLabels['PaymentSuccessfulHeader']), |
||
229 | HTMLEditorField::create('PaymentSuccessfulMessage', $fieldLabels['PaymentSuccessfulMessage'])->setRows(3), |
||
230 | HeaderField::create('Unsuccessful'), |
||
231 | TextField::create('PaymentNotSuccessfulHeader', $fieldLabels['PaymentNotSuccessfulHeader']), |
||
232 | HTMLEditorField::create('PaymentNotSuccessfulMessage', $fieldLabels['PaymentNotSuccessfulMessage'])->setRows(3), |
||
233 | HeaderField::create('Pending'), |
||
234 | TextField::create('PaymentPendingHeader', $fieldLabels['PaymentPendingHeader']), |
||
235 | HTMLEditorField::create('PaymentPendingMessage', $fieldLabels['PaymentPendingMessage'])->setRows(3), |
||
236 | HeaderField::create('Cancelled'), |
||
237 | TextField::create('OrderCancelledHeader', $fieldLabels['OrderCancelledHeader']), |
||
238 | HTMLEditorField::create('OrderCancelledMessage', $fieldLabels['OrderCancelledMessage'])->setRows(3), |
||
239 | )); |
||
240 | $fields->addFieldToTab('Root.Analytics', CheckboxField::create('EnableGoogleAnalytics', $fieldLabels['EnableGoogleAnalytics'])); |
||
241 | if ($this->IsFeedbackEnabled) { |
||
242 | $fields->addFieldsToTab( |
||
243 | 'Root.FeedbackForm', |
||
244 | array( |
||
245 | CheckboxField::create('IsFeedbackEnabled', $fieldLabels['IsFeedbackEnabled']) |
||
246 | ->setDescription(_t('OrderConfirmationPage.IsFeedbackEnabled_RIGHT', 'Enabling this option will display a feedback form on the order confirmation page and include links to the form in all order emails')), |
||
247 | TextField::create('FeedbackHeader', $fieldLabels['FeedbackHeader']) |
||
248 | ->setRightTitle(_t('OrderConfirmationPage.FeedbackHeader_RIGHT', 'e.g. Please let us know what you think')), |
||
249 | TextField::create('FeedbackValuesFieldLabel', $fieldLabels['FeedbackValuesFieldLabel']) |
||
250 | ->setRightTitle(_t('OrderConfirmationPage.FeedbackValuesFieldLabel_RIGHT', 'e.g. Please rate our service')), |
||
251 | TextField::create('FeedbackValuesOptions', $fieldLabels['FeedbackValuesOptions']) |
||
252 | ->setRightTitle(_t('OrderConfirmationPage.FeedbackValuesOptions_RIGHT', 'Comma separated list of feedback rating options (eg Good, Neutral, Bad)')), |
||
253 | TextField::create('FeedbackNotesFieldLabel', $fieldLabels['FeedbackNotesFieldLabel']) |
||
254 | ->setRightTitle(_t('OrderConfirmationPage.FeedbackNotesFieldLabel_RIGHT', 'e.g. Please add any comments')), |
||
255 | TextField::create('FeedbackFormSubmitLabel', $fieldLabels['FeedbackFormSubmitLabel']) |
||
256 | ->setRightTitle(_t('OrderConfirmationPage.FeedbackFormSubmitLabel_RIGHT', 'e.g. Submit Feedback Now')), |
||
257 | TextField::create('FeedbackFormThankYou', $fieldLabels['FeedbackFormThankYou']) |
||
258 | ->setRightTitle(_t('OrderConfirmationPage.FeedbackFormThankYou_RIGHT', 'Thank you message displayed to user after submitting the feedback form')) |
||
259 | ) |
||
260 | ); |
||
261 | } else { |
||
262 | $fields->addFieldsToTab( |
||
263 | 'Root.FeedbackForm', |
||
264 | array( |
||
265 | CheckboxField::create('IsFeedbackEnabled', $fieldLabels['IsFeedbackEnabled']) |
||
266 | ->setDescription('Enabling this option will display a feedback form on the order confirmation page and include links to the form in all order emails') |
||
267 | ) |
||
268 | ); |
||
269 | } |
||
270 | return $fields; |
||
271 | } |
||
272 | |||
273 | /** |
||
274 | * Returns the link or the Link to the OrderConfirmationPage page on this site. |
||
275 | * @param string $action [optional] |
||
276 | * @return string (URLSegment) |
||
277 | */ |
||
278 | public static function find_link($action = null) |
||
279 | { |
||
280 | if ($page = DataObject::get_one('OrderConfirmationPage', array('ClassName' => 'OrderConfirmationPage'))) { |
||
281 | return $page->Link($action); |
||
282 | } elseif ($page = DataObject::get_one('OrderConfirmationPage')) { |
||
283 | return $page->Link($action); |
||
284 | } |
||
285 | |||
286 | return CartPage::find_link(); |
||
287 | } |
||
288 | |||
289 | /** |
||
290 | * Return a link to view the order on this page. |
||
291 | * |
||
292 | * @param int|string $orderID ID of the order |
||
293 | * |
||
294 | * @return string (URLSegment) |
||
295 | */ |
||
296 | public static function get_order_link($orderID) |
||
297 | { |
||
298 | return OrderConfirmationPage::find_link().'showorder/'.$orderID.'/'; |
||
299 | } |
||
300 | |||
301 | /** |
||
302 | * Return a link to view the order on this page. |
||
303 | * |
||
304 | * @param int|string $orderID ID of the order |
||
305 | * @param string $type - the type of email you want to send. |
||
0 ignored issues
–
show
There is no parameter named
$type . Was it maybe removed?
This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. Consider the following example. The parameter /**
* @param array $germany
* @param array $island
* @param array $italy
*/
function finale($germany, $island) {
return "2:1";
}
The most likely cause is that the parameter was removed, but the annotation was not. ![]() |
|||
306 | * @param bool $actuallySendEmail - do we actually send the email |
||
307 | * @param int $alternativeOrderStepID - OrderStep to use |
||
308 | * |
||
309 | * @return string (URLSegment) |
||
310 | */ |
||
311 | public static function get_email_link($orderID, $emailClassName = 'Order_StatusEmail', $actuallySendEmail = false, $alternativeOrderStepID = 0) |
||
312 | { |
||
313 | $link = OrderConfirmationPage::find_link().'sendemail/'.$orderID.'/'.$emailClassName; |
||
314 | $getParams = array(); |
||
315 | if ($actuallySendEmail) { |
||
316 | $getParams['send'] = 1; |
||
317 | } |
||
318 | if ($alternativeOrderStepID) { |
||
319 | $getParams['test'] = $alternativeOrderStepID; |
||
320 | } |
||
321 | $getParams = http_build_query($getParams); |
||
322 | $link .= '?'.$getParams; |
||
323 | |||
324 | return $link; |
||
325 | } |
||
326 | |||
327 | /** |
||
328 | * Return a link to view the order on this page. |
||
329 | * |
||
330 | * @param int|string $orderID ID of the order |
||
331 | * |
||
332 | * @return string (URLSegment) |
||
333 | */ |
||
334 | public function getOrderLink($orderID) |
||
335 | { |
||
336 | return OrderConfirmationPage::get_order_link($orderID); |
||
337 | } |
||
338 | |||
339 | /** |
||
340 | * returns the Checkout_StepDescription assocatiated with the final step: the order confirmation. |
||
341 | * |
||
342 | * @param bool $isCurrentStep |
||
343 | * |
||
344 | * @return Checkout_StepDescription |
||
0 ignored issues
–
show
|
|||
345 | */ |
||
346 | public function CurrentCheckoutStep($isCurrentStep = false) |
||
347 | { |
||
348 | $do = new CheckoutPage_StepDescription(); |
||
349 | $do->Link = $this->Link; |
||
0 ignored issues
–
show
The property
Link does not exist on object<CheckoutPage_StepDescription> . Since you implemented __set , maybe consider adding a @property annotation.
Since your code implements the magic setter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
Since the property has write access only, you can use the @property-write annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. ![]() |
|||
350 | $do->Heading = $this->MenuTitle; |
||
0 ignored issues
–
show
The property
Heading does not exist on object<CheckoutPage_StepDescription> . Since you implemented __set , maybe consider adding a @property annotation.
Since your code implements the magic setter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
Since the property has write access only, you can use the @property-write annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. ![]() |
|||
351 | $do->Code = $this->URLSegment; |
||
0 ignored issues
–
show
The property
Code does not exist on object<CheckoutPage_StepDescription> . Since you implemented __set , maybe consider adding a @property annotation.
Since your code implements the magic setter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
Since the property has write access only, you can use the @property-write annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. ![]() |
|||
352 | $do->LinkingMode = 'notCompleted'; |
||
0 ignored issues
–
show
The property
LinkingMode does not exist on object<CheckoutPage_StepDescription> . Since you implemented __set , maybe consider adding a @property annotation.
Since your code implements the magic setter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
Since the property has write access only, you can use the @property-write annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. ![]() |
|||
353 | if ($isCurrentStep) { |
||
354 | $do->LinkingMode .= ' current'; |
||
0 ignored issues
–
show
The property
LinkingMode does not exist on object<CheckoutPage_StepDescription> . Since you implemented __set , maybe consider adding a @property annotation.
Since your code implements the magic setter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
Since the property has write access only, you can use the @property-write annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. ![]() |
|||
355 | } |
||
356 | $do->Completed = 0; |
||
0 ignored issues
–
show
The property
Completed does not exist on object<CheckoutPage_StepDescription> . Since you implemented __set , maybe consider adding a @property annotation.
Since your code implements the magic setter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
Since the property has write access only, you can use the @property-write annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. ![]() |
|||
357 | $do->ID = 99; |
||
358 | |||
359 | return $do; |
||
360 | } |
||
361 | |||
362 | /** |
||
363 | * standard SS method for use in templates |
||
364 | * we are overriding the code from the Cart Page here. |
||
365 | * |
||
366 | * @return string |
||
367 | */ |
||
368 | public function LinkingMode() |
||
369 | { |
||
370 | return parent::LinkingMode(); |
||
371 | } |
||
372 | |||
373 | /** |
||
374 | * standard SS method for use in templates |
||
375 | * we are overriding the code from the Cart Page here. |
||
376 | * |
||
377 | * @return string |
||
378 | */ |
||
379 | public function LinkOrSection() |
||
380 | { |
||
381 | return parent::LinkOrSection(); |
||
382 | } |
||
383 | |||
384 | /** |
||
385 | * standard SS method for use in templates |
||
386 | * we are overriding the code from the Cart Page here. |
||
387 | * |
||
388 | * @return string |
||
389 | */ |
||
390 | public function LinkOrCurrent() |
||
391 | { |
||
392 | return parent::LinkOrCurrent(); |
||
393 | } |
||
394 | |||
395 | public function requireDefaultRecords() |
||
396 | { |
||
397 | parent::requireDefaultRecords(); |
||
398 | $checkoutPage = DataObject::get_one('CheckoutPage'); |
||
399 | if ($checkoutPage) { |
||
400 | $orderConfirmationPage = DataObject::get_one('OrderConfirmationPage'); |
||
401 | if (!$orderConfirmationPage) { |
||
402 | $orderConfirmationPage = OrderConfirmationPage::create(); |
||
403 | $orderConfirmationPage->Title = 'Order Confirmation'; |
||
404 | $orderConfirmationPage->MenuTitle = 'Order Confirmation'; |
||
405 | $orderConfirmationPage->URLSegment = 'order-confirmation'; |
||
406 | $orderConfirmationPage->writeToStage('Stage'); |
||
407 | $orderConfirmationPage->publish('Stage', 'Live'); |
||
408 | } |
||
409 | } |
||
410 | } |
||
411 | } |
||
412 | |||
413 | class OrderConfirmationPage_Controller extends CartPage_Controller |
||
414 | { |
||
415 | /** |
||
416 | * @static array |
||
417 | * standard SS variable |
||
418 | * it is important that we list all the options here |
||
419 | */ |
||
420 | private static $allowed_actions = array( |
||
0 ignored issues
–
show
|
|||
421 | 'saveorder', |
||
422 | 'CreateAccountForm', |
||
423 | 'retrieveorder', |
||
424 | 'loadorder', |
||
425 | 'startneworder', |
||
426 | 'showorder', |
||
427 | 'copyorder', |
||
428 | 'sendemail', |
||
429 | 'CancelForm', |
||
430 | 'FeedbackForm', |
||
431 | 'PaymentForm', |
||
432 | ); |
||
433 | |||
434 | /** |
||
435 | * standard controller function. |
||
436 | **/ |
||
437 | public function init() |
||
438 | { |
||
439 | //we retrieve the order in the parent page |
||
440 | //the parent page also takes care of the security |
||
441 | if ($sessionOrderID = Session::get('CheckoutPageCurrentOrderID')) { |
||
442 | $this->currentOrder = Order::get()->byID($sessionOrderID); |
||
443 | if ($this->currentOrder) { |
||
444 | $this->overrideCanView = true; |
||
445 | //more than an hour has passed... |
||
446 | $validUntil = intval(Session::get('CheckoutPageCurrentRetrievalTime')) - 0; |
||
447 | if ($validUntil < time()) { |
||
448 | $this->clearRetrievalOrderID(); |
||
449 | $this->overrideCanView = false; |
||
450 | $this->currentOrder = null; |
||
451 | } |
||
452 | } |
||
453 | } |
||
454 | parent::init(); |
||
455 | Requirements::themedCSS('Order', 'ecommerce'); |
||
456 | Requirements::themedCSS('Order_Print', 'ecommerce', 'print'); |
||
457 | Requirements::themedCSS('CheckoutPage', 'ecommerce'); |
||
458 | Requirements::javascript('ecommerce/javascript/EcomPayment.js'); |
||
459 | Requirements::javascript('ecommerce/javascript/EcomPrintAndMail.js'); |
||
460 | $this->includeGoogleAnalyticsCode(); |
||
461 | } |
||
462 | |||
463 | /** |
||
464 | * This method exists just so that template |
||
465 | * sets CurrentOrder variable. |
||
466 | * |
||
467 | * @param HTTPRequest |
||
468 | * |
||
469 | * @return array |
||
470 | **/ |
||
471 | public function showorder(SS_HTTPRequest $request) |
||
472 | { |
||
473 | isset($project) ? $themeBaseFolder = $project : $themeBaseFolder = 'mysite'; |
||
0 ignored issues
–
show
The variable
$project seems to never exist, and therefore isset should always return false . Did you maybe rename this variable?
This check looks for calls to This is most likely caused by the renaming of a variable or the removal of a function/method parameter. ![]() |
|||
474 | if (isset($_REQUEST['print'])) { |
||
475 | Requirements::clear(); |
||
476 | Requirements::themedCSS('typography', $themeBaseFolder); // LEAVE HERE - NOT EASY TO INCLUDE VIA TEMPLATE |
||
477 | Requirements::themedCSS('OrderReport', 'ecommerce'); // LEAVE HERE - NOT EASY TO INCLUDE VIA TEMPLATE |
||
478 | Requirements::themedCSS('Order_Invoice', 'ecommerce'); // LEAVE HERE - NOT EASY TO INCLUDE VIA TEMPLATE |
||
479 | Requirements::themedCSS('Order_Invoice_Print_Only', 'ecommerce', 'print'); // LEAVE HERE - NOT EASY TO INCLUDE VIA TEMPLATE |
||
480 | Config::nest(); |
||
481 | Config::inst()->update('SSViewer', 'theme_enabled', true); |
||
482 | $html = $this->renderWith('Invoice'); |
||
483 | Config::unnest(); |
||
484 | |||
485 | return $html; |
||
486 | } elseif (isset($_REQUEST['packingslip'])) { |
||
487 | Requirements::clear(); |
||
488 | Requirements::themedCSS('typography', $themeBaseFolder); // LEAVE HERE - NOT EASY TO INCLUDE VIA TEMPLATE |
||
489 | Requirements::themedCSS('OrderReport', 'ecommerce'); // LEAVE HERE - NOT EASY TO INCLUDE VIA TEMPLATE |
||
490 | Requirements::themedCSS('Order_PackingSlip', 'ecommerce'); // LEAVE HERE - NOT EASY TO INCLUDE VIA TEMPLATE |
||
491 | Config::nest(); |
||
492 | Config::inst()->update('SSViewer', 'theme_enabled', true); |
||
493 | $html = $this->renderWith('PackingSlip'); |
||
494 | Config::unnest(); |
||
495 | |||
496 | return $html; |
||
497 | } |
||
498 | |||
499 | return array(); |
||
500 | } |
||
501 | |||
502 | /** |
||
503 | * This is an additional way to look at an order. |
||
504 | * The order is already retrieved from the init function. |
||
505 | * |
||
506 | * @return array |
||
507 | **/ |
||
508 | public function retrieveorder(SS_HTTPRequest $request) |
||
509 | { |
||
510 | return array(); |
||
511 | } |
||
512 | |||
513 | /** |
||
514 | * copies either the current order into the shopping cart. |
||
515 | * |
||
516 | * TO DO: untested |
||
517 | * TO DO: what to do with old order |
||
518 | * |
||
519 | * @param SS_HTTPRequest |
||
520 | * |
||
521 | * @return array |
||
522 | */ |
||
523 | public function copyorder(SS_HTTPRequest $request) |
||
524 | { |
||
525 | self::set_message(_t('CartPage.ORDERLOADED', 'Order has been loaded.')); |
||
526 | ShoppingCart::singleton()->copyOrder($this->currentOrder->ID); |
||
527 | |||
528 | return $this->redirect(CheckoutPage::find_link()); |
||
529 | } |
||
530 | |||
531 | /** |
||
532 | * Returns a dataobject set of the checkout steps if |
||
533 | * the OrderConfirmationPage is shown as part of the checkout process |
||
534 | * We repeat these here so that you can show the user that (s)he has reached the last step. |
||
535 | * |
||
536 | * @param int $number - if set, it returns that one step. |
||
537 | */ |
||
538 | public function CheckoutSteps($number = 0) |
||
539 | { |
||
540 | $where = ''; |
||
541 | if ($number) { |
||
542 | $where = "\"CheckoutPage_StepDescription\".\"ID\" = $number"; |
||
543 | } |
||
544 | if (EcommerceConfig::get('OrderConfirmationPage_Controller', 'include_as_checkout_step')) { |
||
545 | if ($this->currentOrder->IsInSession()) { |
||
546 | $dos = CheckoutPage_StepDescription::get()->where($where)->sort('ID', 'ASC'); |
||
547 | if ($number) { |
||
548 | if ($dos && $dos->count()) { |
||
549 | return $dos->First(); |
||
550 | } |
||
551 | } |
||
552 | $arrayList = new ArrayList(array()); |
||
553 | foreach ($dos as $do) { |
||
554 | $do->LinkingMode = 'link completed'; |
||
555 | $do->Completed = 1; |
||
556 | $do->Link = ''; |
||
557 | $arrayList->push($do); |
||
558 | } |
||
559 | $do = $this->CurrentCheckoutStep(true); |
||
560 | if ($do) { |
||
561 | $arrayList->push($do); |
||
562 | } |
||
563 | |||
564 | return $arrayList; |
||
565 | } |
||
566 | } |
||
567 | } |
||
568 | |||
569 | /** |
||
570 | * returns the percentage of checkout steps done (0 - 100). |
||
571 | * |
||
572 | * @return int |
||
573 | */ |
||
574 | public function PercentageDone() |
||
575 | { |
||
576 | return 100; |
||
577 | } |
||
578 | |||
579 | /** |
||
580 | * @return string |
||
581 | */ |
||
582 | public function PaymentHeader() |
||
583 | { |
||
584 | if ($order = $this->Order()) { |
||
0 ignored issues
–
show
$order is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
585 | if ($this->OrderIsCancelled()) { |
||
586 | return $this->OrderCancelledHeader; |
||
587 | } elseif ($this->PaymentIsPending()) { |
||
588 | return $this->PaymentPendingHeader; |
||
589 | } elseif ($this->IsPaid()) { |
||
590 | return $this->PaymentSuccessfulHeader; |
||
591 | } else { |
||
592 | return $this->PaymentNotSuccessfulHeader; |
||
593 | } |
||
594 | } |
||
595 | } |
||
596 | |||
597 | /** |
||
598 | * @return string | null |
||
599 | */ |
||
600 | public function PaymentMessage() |
||
601 | { |
||
602 | if ($order = $this->Order()) { |
||
0 ignored issues
–
show
$order is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
603 | if ($this->OrderIsCancelled()) { |
||
604 | return $this->OrderCancelledMessage; |
||
605 | } elseif ($this->PaymentIsPending()) { |
||
606 | return $this->PaymentPendingMessage; |
||
607 | } elseif ($this->IsPaid()) { |
||
608 | return $this->PaymentSuccessfulMessage; |
||
609 | } else { |
||
610 | return $this->PaymentNotSuccessfulMessage; |
||
611 | } |
||
612 | } |
||
613 | } |
||
614 | |||
615 | /** |
||
616 | * @return string | null |
||
0 ignored issues
–
show
|
|||
617 | */ |
||
618 | public function PaymentMessageType() |
||
619 | { |
||
620 | if ($order = $this->Order()) { |
||
0 ignored issues
–
show
$order is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
621 | if ($this->OrderIsCancelled()) { |
||
622 | return "bad"; |
||
623 | } elseif ($this->PaymentIsPending()) { |
||
624 | return "warning"; |
||
625 | } elseif ($this->IsPaid()) { |
||
626 | return "good"; |
||
627 | } else { |
||
628 | return "bad"; |
||
629 | } |
||
630 | } |
||
631 | } |
||
632 | |||
633 | /** |
||
634 | * @return bool |
||
635 | */ |
||
636 | public function OrderIsCancelled() |
||
637 | { |
||
638 | if ($order = $this->Order()) { |
||
639 | return $order->getIsCancelled(); |
||
640 | } |
||
641 | } |
||
642 | |||
643 | /** |
||
644 | * Is the Order paid? |
||
645 | * This can be useful for choosing what header to show. |
||
646 | * |
||
647 | * @return bool |
||
648 | */ |
||
649 | public function IsPaid() |
||
650 | { |
||
651 | if ($order = $this->Order()) { |
||
652 | return $order->IsPaid(); |
||
653 | } |
||
654 | } |
||
655 | |||
656 | /** |
||
657 | * Are there any order Payments Pending |
||
658 | * This can be useful for choosing what header to show. |
||
659 | * |
||
660 | * @return bool |
||
661 | */ |
||
662 | public function PaymentIsPending() |
||
663 | { |
||
664 | if ($order = $this->Order()) { |
||
665 | return $order->PaymentIsPending(); |
||
666 | } |
||
667 | } |
||
668 | |||
669 | /** |
||
670 | * Returns the form to cancel the current order, |
||
671 | * checking to see if they can cancel their order |
||
672 | * first of all. |
||
673 | * |
||
674 | * @return OrderForm_Cancel |
||
0 ignored issues
–
show
|
|||
675 | */ |
||
676 | public function CancelForm() |
||
677 | { |
||
678 | if ($this->Order()) { |
||
679 | if ($this->currentOrder->canCancel()) { |
||
680 | return OrderForm_Cancel::create($this, 'CancelForm', $this->currentOrder); |
||
681 | } |
||
682 | } |
||
683 | //once cancelled, you will be redirected to main page - hence we need this... |
||
684 | if ($this->orderID) { |
||
685 | return array(); |
||
686 | } |
||
687 | } |
||
688 | |||
689 | /** |
||
690 | * Returns the form for providing feedback about current order, |
||
691 | * checking to see if IsFeedbackEnabled is true |
||
692 | * first of all. |
||
693 | * |
||
694 | * @return OrderForm_Feedback |
||
695 | */ |
||
696 | public function FeedbackForm() |
||
697 | { |
||
698 | if ($this->Order()) { |
||
699 | if ($this->IsFeedbackEnabled) { |
||
700 | return OrderForm_Feedback::create($this, 'FeedbackForm', $this->currentOrder); |
||
701 | } |
||
702 | } |
||
703 | } |
||
704 | |||
705 | /** |
||
706 | * show the payment form. |
||
707 | * |
||
708 | * @return Form (OrderForm_Payment) or Null |
||
0 ignored issues
–
show
|
|||
709 | **/ |
||
710 | public function PaymentForm() |
||
711 | { |
||
712 | if ($this->currentOrder) { |
||
713 | if ($this->currentOrder->canPay()) { |
||
714 | Requirements::javascript('ecommerce/javascript/EcomPayment.js'); |
||
715 | |||
716 | return OrderForm_Payment::create($this, 'PaymentForm', $this->currentOrder); |
||
717 | } |
||
718 | } |
||
719 | |||
720 | return array(); |
||
721 | } |
||
722 | |||
723 | /** |
||
724 | * Can this page only show Submitted Orders (e.g. OrderConfirmationPage) ? |
||
725 | * |
||
726 | * @return bool |
||
727 | */ |
||
728 | protected function onlyShowSubmittedOrders() |
||
729 | { |
||
730 | return true; |
||
731 | } |
||
732 | |||
733 | /** |
||
734 | * Can this page only show Unsubmitted Orders (e.g. CartPage) ? |
||
735 | * |
||
736 | * @return bool |
||
737 | */ |
||
738 | protected function onlyShowUnsubmittedOrders() |
||
739 | { |
||
740 | return false; |
||
741 | } |
||
742 | |||
743 | /** |
||
744 | * sends an order email, which can be specified in the URL |
||
745 | * and displays a sample email |
||
746 | * typically this link is opened in a new window. |
||
747 | * |
||
748 | * @param SS_HTTPRequest $request |
||
749 | * |
||
750 | * @return HTML |
||
751 | **/ |
||
752 | public function sendemail(SS_HTTPRequest $request) |
||
753 | { |
||
754 | if ($this->currentOrder) { |
||
755 | $subject = ''; |
||
756 | $message = ''; |
||
757 | $emailClassName = 'Order_ReceiptEmail'; |
||
758 | if (class_exists($request->param('OtherID'))) { |
||
759 | if (is_a(singleton($request->param('OtherID')), Object::getCustomClass('Order_Email'))) { |
||
760 | $emailClassName = $request->param('OtherID'); |
||
761 | } |
||
762 | } |
||
763 | if ($statusID = intval($request->getVar('test'))) { |
||
764 | $step = OrderStep::get()->byID($statusID); |
||
765 | $subject = $step->CalculatedEmailSubject($this->currentOrder); |
||
766 | $message = $step->CalculatedCustomerMessage($this->currentOrder); |
||
767 | if ($step) { |
||
768 | $emailClassName = $step->getEmailClassName(); |
||
769 | } |
||
770 | if ($request->getVar('send')) { |
||
771 | $email = filter_var($request->getVar('send'), FILTER_SANITIZE_EMAIL); |
||
772 | if (! $email) { |
||
773 | $email = true; |
||
774 | } |
||
775 | $this->currentOrder->sendEmail( |
||
776 | $emailClassName, |
||
777 | _t('Account.TEST_ONLY', '--- TEST ONLY ---') . ' ' . $subject, |
||
778 | $message, |
||
779 | $resend = true, |
||
780 | $adminOnlyOrToEmail = $email |
||
781 | ); |
||
782 | } |
||
783 | } elseif ($request->getVar('send')) { |
||
784 | if ($email = $this->currentOrder->getOrderEmail()) { |
||
785 | $step = OrderStep::get()->byID($this->currentOrder->StatusID); |
||
786 | $ecomConfig = $this->EcomConfig(); |
||
787 | $subject = $ecomConfig->InvoiceTitle ? $ecomConfig->InvoiceTitle : _t('OrderConfirmationPage.INVOICE', 'Invoice'); |
||
788 | $message = $ecomConfig->InvoiceMessage ? $ecomConfig->InvoiceMessage : _t('OrderConfirmationPage.MESSAGE', '<p>Thank you for your order.</p>'); |
||
789 | $emailClassName = 'Order_InvoiceEmail'; |
||
790 | if ( |
||
791 | $this->currentOrder->sendEmail( |
||
792 | $emailClassName, |
||
793 | $subject, |
||
794 | $message, |
||
795 | $resend = true, |
||
796 | $adminOnlyOrToEmail = false |
||
797 | ) |
||
798 | ) { |
||
799 | $message = _t('OrderConfirmationPage.RECEIPTSENT', 'An email has been sent to: ').$email.'.'; |
||
800 | } else { |
||
801 | $message = _t('OrderConfirmationPage.RECEIPT_NOT_SENT', 'Email could NOT be sent to: ').$email; |
||
802 | } |
||
803 | } else { |
||
804 | $message = _t('OrderConfirmationPage.RECEIPTNOTSENTNOEMAIL', 'No customer details found. EMAIL NOT SENT.'); |
||
805 | } |
||
806 | } |
||
807 | //display same data... |
||
808 | Requirements::clear(); |
||
809 | return $this->currentOrder->renderOrderInEmailFormat( |
||
810 | $emailClassName, |
||
811 | $subject, |
||
812 | $message |
||
813 | ); |
||
814 | } else { |
||
815 | return _t('OrderConfirmationPage.RECEIPTNOTSENTNOORDER', 'Order could not be found.'); |
||
816 | } |
||
817 | } |
||
818 | |||
819 | protected function includeGoogleAnalyticsCode() |
||
820 | { |
||
821 | if ($this->EnableGoogleAnalytics && $this->currentOrder && (Director::isLive() || isset($_GET['testanalytics']))) { |
||
822 | $var = EcommerceConfig::get('OrderConfirmationPage_Controller', 'google_analytics_variable'); |
||
823 | if ($var) { |
||
824 | $currencyUsedObject = $this->currentOrder->CurrencyUsed(); |
||
825 | if ($currencyUsedObject) { |
||
826 | $currencyUsedString = $currencyUsedObject->Code; |
||
827 | } |
||
828 | if (empty($currencyUsedString)) { |
||
829 | $currencyUsedString = EcommerceCurrency::default_currency_code(); |
||
830 | } |
||
831 | $js = ' |
||
832 | jQuery(document).ready( |
||
833 | function(){ |
||
834 | '.$var.'(\'require\', \'ecommerce\'); |
||
835 | '.$var.'( |
||
836 | \'ecommerce:addTransaction\', |
||
837 | { |
||
838 | \'id\': \''.$this->currentOrder->ID.'\', |
||
839 | \'revenue\': \''.$this->currentOrder->getSubTotal().'\', |
||
840 | \'currency\': \''.$currencyUsedString.'\' |
||
841 | } |
||
842 | ); |
||
843 | '.$var.'(\'ecommerce:send\'); |
||
844 | } |
||
845 | ); |
||
846 | '; |
||
847 | Requirements::customScript($js, 'GoogleAnalyticsEcommerce'); |
||
848 | } |
||
849 | } |
||
850 | } |
||
851 | } |
||
852 |