Completed
Push — master ( 613b2e...a2195f )
by Nicolaas
03:28
created

EcommerceRole::IsShopAdmin()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
eloc 5
nc 2
nop 0
1
<?php
2
/**
3
 * @description EcommerceRole provides specific customisations to the {@link Member}
4
 * class for the ecommerce module.
5
 *
6
 *
7
 *
8
 * @authors: Nicolaas [at] Sunny Side Up .co.nz
9
 * @package: ecommerce
10
 * @sub-package: extensions
11
 * @inspiration: Silverstripe Ltd, Jeremy
12
 **/
13
class EcommerceRole extends DataExtension implements PermissionProvider
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
14
{
15
    private static $max_count_of_members_in_array = 1500;
0 ignored issues
show
Unused Code introduced by
The property $max_count_of_members_in_array is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
16
17
    private static $api_access = array(
0 ignored issues
show
Unused Code introduced by
The property $api_access is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
18
        'view' => array(
19
            'ID',
20
            'Orders',
21
            'PreferredCurrency',
22
        ),
23
    );
24
25
    /**
26
     * standard SS method.
27
     */
28
    private static $db = array(
0 ignored issues
show
Unused Code introduced by
The property $db is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
29
        'Notes' => 'Text',
30
    );
31
32
    private static $has_one = array(
0 ignored issues
show
Unused Code introduced by
The property $has_one is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
33
        'PreferredCurrency' => 'EcommerceCurrency',
34
    );
35
36
    private static $has_many = array(
0 ignored issues
show
Unused Code introduced by
The property $has_many is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
37
        'Orders' => 'Order',
38
    );
39
40
    /**
41
     *@return Group | NULL
0 ignored issues
show
Documentation introduced by
Should the return type not be Group|null?

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

Loading history...
42
     **/
43
    public static function get_customer_group()
44
    {
45
        $customerCode = EcommerceConfig::get('EcommerceRole', 'customer_group_code');
46
47
        return Group::get()
48
            ->Filter(array('Code' => $customerCode))->First();
49
    }
50
51
    /**
52
     * returns an aray of customers
53
     * The unselect option shows an extra line, basically allowing you to deselect the
54
     * current option.
55
     *
56
     * @param bool $showUnselectedOption
57
     *
58
     * @return array ( ID => Email (member.title) )
59
     */
60
    public static function list_of_customers($showUnselectedOption = false)
61
    {
62
        //start array
63
        $array = array();
64
        if ($showUnselectedOption) {
65
            $array[0] = _t('Member.SELECTCUSTOMER', ' --- SELECT CUSTOMER ---');
66
        }
67
        //get customer group
68
        $customerCode = EcommerceConfig::get('EcommerceRole', 'customer_group_code');
0 ignored issues
show
Unused Code introduced by
$customerCode 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 $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
69
        $group = self::get_customer_group();
70
        //fill array
71
        if ($group) {
72
            $members = $group->Members();
73
            $membersCount = $members->count();
74
            if ($membersCount > 0 && $membersCount < Config::inst()->get('EcommerceRole', 'max_count_of_members_in_array')) {
75
                foreach ($members as $member) {
76
                    if ($member->Email) {
77
                        $array[$member->ID] = $member->Email.' ('.$member->getTitle().')';
78
                    }
79
                }
80
            } else {
81
                return $array;
82
            }
83
        }
84
        //sort in a natural order
85
        natcasesort($array);
86
87
        return $array;
88
    }
89
90
    /**
91
     * returns an aray of customers
92
     * The unselect option shows an extra line, basically allowing you to deselect the
93
     * current option.
94
     *
95
     * @param bool $showUnselectedOption
96
     *
97
     * @return array ( ID => Email (member.title) )
98
     */
99
    public static function list_of_admins($showUnselectedOption = false)
100
    {
101
        //start array
102
        $array = array();
103
        if ($showUnselectedOption) {
104
            $array[0] = _t('Member.SELECT_ECOMMERCE_ADMIN', ' --- SELECT ADMIN ---');
105
        }
106
        //get customer group
107
        $customerCode = EcommerceConfig::get('EcommerceRole', 'customer_group_code');
0 ignored issues
show
Unused Code introduced by
$customerCode 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 $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
108
        $group = self::get_admin_group();
109
        //fill array
110
        if ($group) {
111
            $members = $group->Members();
112
            $membersCount = $members->count();
113
            if ($membersCount > 0) {
114
                foreach ($members as $member) {
115
                    if ($member->Email) {
116
                        $array[$member->ID] = $member->Email.' ('.$member->getTitle().')';
117
                    }
118
                }
119
            }
120
        }
121
        $group = Group::get()
122
            ->Filter(array('Code' => 'administrators'))->First();
123
        //fill array
124
        if ($group) {
125
            $members = $group->Members();
126
            $membersCount = $members->count();
127
            if ($membersCount > 0) {
128
                foreach ($members as $member) {
129
                    if ($member->Email) {
130
                        $array[$member->ID] = $member->Email.' ('.$member->getTitle().')';
131
                    }
132
                }
133
            }
134
        }
135
        //sort in a natural order
136
        natcasesort($array);
137
138
        return $array;
139
    }
140
141
    /**
142
     * tells us if the current member is in the Shop Administrators Group.
143
     *
144
     * @param Member | Null $member
145
     *
146
     * @return bool
147
     */
148
    public static function current_member_is_shop_admin($member = null)
149
    {
150
        if (!$member) {
151
            $member = Member::currentUser();
152
        }
153
        if ($member) {
154
            return $member->IsShopAdmin();
155
        }
156
157
        return false;
158
    }
159
160
    /**
161
     * tells us if the current member is in the Shop Administrators Group.
162
     *
163
     * @param Member | Null $member
164
     *
165
     * @return bool
166
     */
167
    public static function current_member_is_shop_assistant($member = null)
168
    {
169
        if (!$member) {
170
            $member = Member::currentUser();
171
        }
172
        if ($member) {
173
            return $member->IsShopAssistant();
174
        }
175
176
        return false;
177
    }
178
179
    /**
180
     * tells us if the current member can process the orders
181
     *
182
     * @param Member | Null $member
183
     *
184
     * @return bool
185
     */
186
    public static function current_member_can_process_orders($member = null)
187
    {
188
        if (!$member) {
189
            $member = Member::currentUser();
190
        }
191
        if ($member) {
192
            return $member->CanProcessOrders();
193
        }
194
195
        return false;
196
    }
197
198
    /**
199
     * @return DataObject (Group) | NULL
0 ignored issues
show
Documentation introduced by
Should the return type not be DataObject|null?

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

Loading history...
200
     **/
201
    public static function get_admin_group()
202
    {
203
        $adminCode = EcommerceConfig::get('EcommerceRole', 'admin_group_code');
204
205
        return Group::get()->Filter(array('Code' => $adminCode))->First();
206
    }
207
208
     /**
209
     * @return DataObject (Group) | NULL
0 ignored issues
show
Documentation introduced by
Should the return type not be DataObject|null?

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

Loading history...
210
     **/
211
    public static function get_assistant_group()
212
    {
213
        $assistantCode = EcommerceConfig::get('EcommerceRole', 'assistant_group_code');
214
215
        return Group::get()->Filter(array('Code' => $assistantCode))->First();
216
    }
217
218
    /**
219
     * @return DataObject (Member) | NULL
220
     **/
221
    public static function get_default_shop_admin_user()
222
    {
223
        $group = self::get_admin_group();
224
        if ($group) {
225
            return $group->Members()->First();
226
        }
227
    }
228
229
    /**
230
     * @return DataObject (Member) | NULL
231
     **/
232
    public static function get_default_shop_assistant_user()
233
    {
234
        $group = self::get_assistant_group();
235
        if ($group) {
236
            return $group->Members()->First();
237
        }
238
    }
239
240
    /**
241
     * you can't delete a Member with one or more orders.
242
     */
243
    public function canDelete($member = null)
244
    {
245
        if ($this->getOrders()->count()) {
246
            return false;
247
        }
248
    }
249
250
    /**
251
     * we need this function because $this->Orders does not return anything
252
     * that is probably because Order links the member twice (placed by and cancelled by).
253
     *
254
     * @return DataList
255
     */
256
    public function getOrders()
257
    {
258
        return Order::get()->filter(array('MemberID' => $this->owner->ID));
259
    }
260
261
    /**
262
     * creates two permission roles.
263
     * standard SS Method.
264
     *
265
     * @return array
266
     */
267
    public function providePermissions()
268
    {
269
        $category = EcommerceConfig::get('EcommerceRole', 'permission_category');
270
        $perms[EcommerceConfig::get('EcommerceRole', 'customer_permission_code')] = array(
0 ignored issues
show
Coding Style Comprehensibility introduced by
$perms was never initialized. Although not strictly required by PHP, it is generally a good practice to add $perms = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
271
            'name' => _t(
272
                'EcommerceRole.CUSTOMER_PERMISSION_ANME',
273
                'Customers'
274
            ),
275
            'category' => $category,
276
            'help' => _t(
277
                'EcommerceRole.CUSTOMERS_HELP',
278
                'Customer Permissions (usually very little)'
279
            ),
280
            'sort' => 98,
281
        );
282
        $perms[EcommerceConfig::get('EcommerceRole', 'admin_permission_code')] = array(
283
            'name' => EcommerceConfig::get('EcommerceRole', 'admin_role_title'),
284
            'category' => $category,
285
            'help' => _t(
286
                'EcommerceRole.ADMINISTRATORS_HELP',
287
                'Store Manager - can edit everything to do with the e-commerce application.'
288
            ),
289
            'sort' => 99,
290
        );
291
        $perms[EcommerceConfig::get('EcommerceRole', 'assistant_permission_code')] = array(
292
            'name' => EcommerceConfig::get('EcommerceRole', 'assistant_role_title'),
293
            'category' => $category,
294
            'help' => _t(
295
                'EcommerceRole.STORE_ASSISTANTS_HELP',
296
                'Store Assistant - can only view sales details and makes notes about orders'
297
            ),
298
            'sort' => 100,
299
        );
300
        $perms[EcommerceConfig::get('EcommerceRole', 'process_orders_permission_code')] = array(
301
           'name' => _t(
302
               'EcommerceRole.PROCESS_ORDERS_PERMISSION_NAME',
303
               'Can process orders'
304
           ),
305
           'category' => $category,
306
           'help' => _t(
307
               'EcommerceRole.PROCESS_ORDERS_PERMISSION_HELP',
308
               'Can the user progress orders through the order steps (e.g. dispatch orders)'
309
           ),
310
           'sort' => 101
311
        );
312
        return $perms;
313
    }
314
315
    /**
316
     * Update the CMS Fields
317
     * for /admin/security.
318
     *
319
     * @param FieldList $fields
320
     *
321
     * @return FieldList
322
     */
323
    public function updateCMSFields(FieldList $fields)
324
    {
325
        $orderField = $fields->dataFieldByName('Orders');
326
        if ($orderField) {
327
            $config = GridFieldConfig_RecordEditor::create();
328
            $config->removeComponentsByType('GridFieldDeleteAction');
329
            $config->removeComponentsByType('GridFieldAddNewButton');
330
            if ($orderField instanceof GridField) {
331
                $orderField->setConfig($config);
332
                $orderField->setList($this->getOrders());
333
            }
334
        } else {
335
            $orderField = new HiddenField('Orders', 'Orders');
336
        }
337
        $preferredCurrencyField = $fields->dataFieldByName('PreferredCurrencyID');
338
        $notesFields = $fields->dataFieldByName('Notes');
339
        $loginAsField = new LiteralField(
340
            'LoginAsThisCustomer',
341
            "<p class=\"actionInCMS\"><a href=\"".$this->owner->LoginAsLink()."\" target=\"_blank\">Login as this customer</a></p>"
342
        );
343
        $link = Controller::join_links(
344
            Director::baseURL(),
345
            Config::inst()->get('ShoppingCart_Controller', 'url_segment').'/placeorderformember/'.$this->owner->ID.'/'
346
        );
347
        $orderForLink = new LiteralField('OrderForCustomerLink', "<p class=\"actionInCMS\"><a href=\"$link\" target=\"_blank\">Place order for customer</a></p>");
348
        $fields->addFieldsToTab(
349
            'Root.Orders',
350
            array(
351
                $orderField,
352
                $preferredCurrencyField,
353
                $notesFields,
354
                $loginAsField,
355
                $orderForLink,
356
            )
357
        );
358
359
        return $fields;
360
    }
361
362
    /**
363
     * Save a preferred currency for a member.
364
     *
365
     * @param EcommerceCurrency $currency - object for the currency
366
     */
367
    public function SetPreferredCurrency(EcommerceCurrency $currency)
368
    {
369
        if ($this->owner->exists()) {
370
            if ($currency && $currency->exists()) {
371
                $this->owner->PreferredCurrencyID = $currency->ID;
372
                $this->owner->write();
373
            }
374
        }
375
    }
376
377
    /**
378
     * get CMS fields describing the member in the CMS when viewing the order.
379
     *
380
     * @return CompositeField
381
     **/
382
    public function getEcommerceFieldsForCMS()
383
    {
384
        $fields = new CompositeField();
385
        $memberTitle = new ReadonlyField('MemberTitle', _t('Member.TITLE', 'Name'), '<p>'._t('Member.TITLE', 'Name').': '.$this->owner->getTitle().'</p>');
386
        $memberTitle->dontEscape = true;
387
        $fields->push($memberTitle);
388
        $memberEmail = new ReadonlyField('MemberEmail', _t('Member.EMAIL', 'Email'), '<p>'._t('Member.EMAIL', 'Email').': <a href="mailto:'.$this->owner->Email.'">'.$this->owner->Email.'</a></p>');
389
        $memberEmail->dontEscape = true;
390
        $fields->push($memberEmail);
391
        $lastLogin = new ReadonlyField('MemberLastLogin', _t('Member.LASTLOGIN', 'Last Login'), '<p>'._t('Member.LASTLOGIN', 'Last Login').': '.$this->owner->dbObject('LastVisited')->Nice().'</p>');
392
        $lastLogin->dontEscape = true;
393
        $fields->push($lastLogin);
394
        $group = self::get_customer_group();
395
        if (!$group) {
396
            $group = new Group();
397
        }
398
        $headerField = HeaderField::create('MemberLinkFieldHeader', _t('Member.EDIT_CUSTOMER', 'Edit Customer'));
399
        $linkField1 = EcommerceCMSButtonField::create(
400
            'MemberLinkFieldEditThisCustomer',
401
            '/admin/security/EditForm/field/Members/item/'.$this->owner->ID.'/edit',
402
            _t('Member.EDIT', 'Edit').' <i>'.$this->owner->getTitle().'</i>'
403
        );
404
        $fields->push($headerField);
405
        $fields->push($linkField1);
406
        
407
        if (EcommerceRole::current_member_can_process_orders(Member::currentUser())) {
408
            $linkField2 = EcommerceCMSButtonField::create(
409
                'MemberLinkFieldEditAllCustomers',
410
                '/admin/security/show/'.$group->ID.'/',
411
                _t('Member.EDIT_ALL_CUSTOMERS', 'Edit All Customers')
412
            );
413
            $fields->push($linkField2);
414
        }
415
        return $fields;
416
    }
417
418
    /**
419
     * @param bool $additionalFields: add extra fields.
0 ignored issues
show
Bug introduced by
There is no parameter named $additionalFields:. 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 $italy is not defined by the method finale(...).

/**
 * @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.

Loading history...
420
     *
421
     * @return FieldList
422
     */
423
    public function getEcommerceFields($mustCreateAccount = false)
424
    {
425
        if (! EcommerceConfig::get('EcommerceRole', 'allow_customers_to_setup_accounts')) {
426
            //if no accounts are made then we simply return the basics....
427
            $fields = new FieldList(
428
                new HeaderField('PersonalInformation', _t('EcommerceRole.PERSONALINFORMATION', 'Personal Information'), 3),
429
                new TextField('FirstName', _t('EcommerceRole.FIRSTNAME', 'First Name')),
430
                new TextField('Surname', _t('EcommerceRole.SURNAME', 'Surname')),
431
                new EmailField('Email', _t('EcommerceRole.EMAIL', 'Email'))
432
            );
433
        } else {
434
            Requirements::javascript('ecommerce/javascript/EcomPasswordField.js');
435
436
            if ($this->owner->exists()) {
437
                if ($this->owner->Password) {
438
                    $passwordField = new PasswordField('PasswordCheck1', _t('Account.NEW_PASSWORD', 'New Password'));
439
                    $passwordDoubleCheckField = new PasswordField('PasswordCheck2', _t('Account.CONFIRM_NEW_PASSWORD', 'Confirm New Password'));
440
                    $updatePasswordLinkField = new LiteralField('UpdatePasswordLink', '<a href="#Password"  datano="'.Convert::raw2att(_t('Account.DO_NOT_UPDATE_PASSWORD', 'Do not update password')).'"  class="updatePasswordLink passwordToggleLink" rel="Password">'._t('Account.UPDATE_PASSWORD', 'Update Password').'</a>');
441
                } else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
442
                    //if they dont have a password then we now force them to create one.
443
                    //the fields of which are added further down the line...
444
                }
445
                //we simply hide these fields, as they add little extra ....
446
                $loginDetailsHeader = new HiddenField('LoginDetails', _t('Account.LOGINDETAILS', 'Login Details'), 5);
447
                $loginDetailsDescription = new HiddenField(
448
                    'AccountInfo',
449
                    '<p>'.
450
                    _t('OrderForm.PLEASE_REVIEW', 'Please review your log in details below.')
451
                    .'</p>'
452
                );
453
            } else {
454
                //login invite right on the top
455
                if (EcommerceConfig::get('EcommerceRole', 'must_have_account_to_purchase') || $mustCreateAccount) {
456
                    $loginDetailsHeader = new HeaderField('CreateAnAccount', _t('OrderForm.SETUPYOURACCOUNT', 'Create an account'), 3);
457
                    //dont allow people to purchase without creating a password
458
                    $loginDetailsDescription = new LiteralField(
459
                        'AccountInfo',
460
                        '<p class"password-info">'.
461
                        _t('OrderForm.MUSTCREATEPASSWORD', 'Please choose a password to create your account.')
462
                        .'</p>'
463
                    );
464
                } else {
465
                    $loginDetailsHeader = new HeaderField('CreateAnAccount', _t('OrderForm.CREATEANACCONTOPTIONAL', 'Create an account (optional)'), 3);
466
                    //allow people to purchase without creating a password
467
                    $updatePasswordLinkField = new LiteralField('UpdatePasswordLink', '<a href="#Password" datano="'.Convert::raw2att(_t('Account.DO_NOT_CREATE_ACCOUNT', 'do not create account')).'" class="choosePassword passwordToggleLink">choose a password</a>');
468
                    $loginDetailsDescription = new LiteralField(
469
                        'AccountInfo',
470
                        '<p class="password-info">'.
471
                        _t('OrderForm.SELECTPASSWORD', 'Please enter a password; this will allow you to check your order history in the future.')
472
                        .'</p>'
473
                    );
474
                    //close by default
475
                }
476
            }
477
478
            if (empty($passwordField)) {
479
                $passwordField = new PasswordField('PasswordCheck1', _t('Account.CREATE_PASSWORD', 'Password'));
480
                $passwordDoubleCheckField = new PasswordField('PasswordCheck2', _t('Account.CONFIRM_PASSWORD', 'Confirm Password'));
481
            }
482
            if (empty($updatePasswordLinkField)) {
483
                $updatePasswordLinkField = new LiteralField('UpdatePasswordLink', '');
484
            }
485
            $fields = new FieldList(
486
                new HeaderField('PersonalInformation', _t('EcommerceRole.PERSONALINFORMATION', 'Personal Information'), 3),
487
                new TextField('FirstName', _t('EcommerceRole.FIRSTNAME', 'First Name')),
488
                new TextField('Surname', _t('EcommerceRole.SURNAME', 'Surname')),
489
                new EmailField('Email', _t('EcommerceRole.EMAIL', 'Email')),
490
                $loginDetailsHeader,
491
                $loginDetailsDescription,
492
                $updatePasswordLinkField,
493
                $passwordField,
494
                $passwordDoubleCheckField
0 ignored issues
show
Bug introduced by
The variable $passwordDoubleCheckField does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
495
            );
496
        }
497
        $this->owner->extend('augmentEcommerceFields', $fields);
498
499
        return $fields;
500
    }
501
502
    /**
503
     * Return which member fields should be required on {@link OrderForm}
504
     * and {@link ShopAccountForm}.
505
     *
506
     * @return array
507
     */
508
    public function getEcommerceRequiredFields()
509
    {
510
        $fields = array(
511
            'FirstName',
512
            'Surname',
513
            'Email',
514
        );
515
        if (EcommerceConfig::get('EcommerceRole', 'must_have_account_to_purchase')) {
516
            $passwordFieldIsRequired = true;
517
            if ($this->owner->exists()) {
518
                if ($this->owner->Password) {
519
                    $passwordFieldIsRequired = false;
520
                }
521
            }
522
        } else {
523
            $passwordFieldIsRequired = false;
524
        }
525
        if ($passwordFieldIsRequired) {
526
            $fields[] = 'PasswordCheck1';
527
            $fields[] = 'PasswordCheck2';
528
        }
529
        $this->owner->extend('augmentEcommerceRequiredFields', $fields);
530
531
        return $fields;
532
    }
533
534
    /**
535
     * Is the member a member of the ShopAdmin Group.
536
     *
537
     * @return bool
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|string|null?

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

Loading history...
538
     **/
539
    public function IsShopAdmin()
540
    {
541
        if (Permission::checkMember($this->owner, 'ADMIN')) {
542
            return true;
543
        } else {
544
            return Permission::checkMember($this->owner, EcommerceConfig::get('EcommerceRole', 'admin_permission_code'));
545
        }
546
    }
547
548
    /**
549
     * Is the member a member of the SHOPASSISTANTS Group.
550
     *
551
     * @return bool
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|string|null?

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

Loading history...
552
     **/
553
    public function IsShopAssistant()
554
    {
555
        if ($this->owner->IsShopAdmin()) {
556
            return true;
557
        }
558
559
        return Permission::checkMember($this->owner, EcommerceConfig::get('EcommerceRole', 'assistant_permission_code'));
560
    }
561
562
    /**
563
     * Is the member a member of the SHOPASSISTANTS Group.
564
     *
565
     * @return bool
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|string|null?

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

Loading history...
566
     **/
567
    public function CanProcessOrders()
568
    {
569
        if ($this->owner->IsShopAdmin()) {
570
            return true;
571
        }
572
573
        return Permission::checkMember($this->owner, EcommerceConfig::get('EcommerceRole', 'process_orders_permission_code'));
574
    }
575
576
    /**
577
     * returns the last (submitted) order  by the member.
578
     *
579
     * @param bool $includeUnsubmittedOrders - set to TRUE to include unsubmitted orders
580
     */
581
    public function LastOrder($includeUnsubmittedOrders = false)
582
    {
583
        //limit to 10
584
        if ($includeUnsubmittedOrders) {
585
            $orders = Order::get_datalist_of_orders_with_submit_record(false);
586
        } else {
587
            $orders = Order::get_datalist_of_orders_with_submit_record(true);
588
        }
589
        $lastOrder = $orders
590
            ->Filter(array('MemberID' => $this->owner->ID))
591
            ->First();
592
593
        return $lastOrder;
594
    }
595
596
    /**
597
     * standard SS method
598
     * Make sure the member is added as a customer.
599
     */
600
    public function onAfterWrite()
601
    {
602
        $customerGroup = self::get_customer_group();
603
        if ($customerGroup) {
604
            $existingMembers = $customerGroup->Members();
605
            if ($existingMembers) {
606
                $existingMembers->add($this->owner);
607
            }
608
        }
609
    }
610
611
    /**
612
     * Finds previous addresses from the member of the current address.
613
     *
614
     * @param string $type
615
     * @param int    $excludeID      - the ID of the record to exlcude (if any)
616
     * @param bool   $onlyLastRecord - only select one
617
     * @param bool   $keepDoubles    - keep addresses that are the same (if set to false, only unique addresses are returned)
618
     *
619
     * @return ArrayList (BillingAddresses | ShippingAddresses)
620
     **/
621
    public function previousOrderAddresses($type = 'BillingAddress', $excludeID = 0, $onlyLastRecord = false, $keepDoubles = false)
622
    {
623
        $returnArrayList = new ArrayList();
624
        if ($this->owner->exists()) {
625
            $fieldName = $type.'ID';
626
            $limit = 999;
0 ignored issues
show
Unused Code introduced by
$limit 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 $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
627
            if ($onlyLastRecord) {
628
                $limit = 1;
0 ignored issues
show
Unused Code introduced by
$limit 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 $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
629
            }
630
            $addresses = $type::get()
631
                ->where(
632
                    '"Obsolete" = 0 AND "Order"."MemberID" = '.$this->owner->ID
633
                )
634
                ->sort('LastEdited', 'DESC')
635
                ->exclude(array('ID' => $excludeID))
636
                //->limit($limit)
637
                ->innerJoin('Order', '"Order"."'.$fieldName.'" = "OrderAddress"."ID"');
638
            if ($addresses->count()) {
639
                if ($keepDoubles) {
640
                    foreach ($addresses as $address) {
641
                        $returnArrayList->push($address);
642
                    }
643
                } else {
644
                    $addressCompare = array();
645
                    foreach ($addresses as $address) {
646
                        $comparisonString = $address->comparisonString();
647
                        if (in_array($comparisonString, $addressCompare)) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
648
                            //do nothing
649
                        } else {
650
                            $addressCompare[$address->ID] = $comparisonString;
651
                            $returnArrayList->push($address);
652
                        }
653
                    }
654
                }
655
            }
656
        }
657
658
        return $returnArrayList;
659
    }
660
661
    /**
662
     * Finds the last address used by this member.
663
     *
664
     * @param string $type
665
     * @param int    $excludeID - the ID of the record to exlcude (if any)
666
     **/
667
    public function previousOrderAddress($type = 'BillingAddress', $excludeID = 0)
668
    {
669
        $addresses = $this->previousOrderAddresses($type, $excludeID, true, false);
670
        if ($addresses->count()) {
671
            return $addresses->First();
672
        }
673
    }
674
675
    public function LoginAsLink()
676
    {
677
        return Controller::join_links(
678
            Director::baseURL(),
679
            Config::inst()->get('ShoppingCart_Controller', 'url_segment').
680
            '/loginas/'.$this->owner->ID.'/'
681
        );
682
    }
683
684
    public function CMSEditLink()
685
    {
686
        return Controller::join_links(
687
            Director::baseURL(),
688
            'admin/security/EditForm/field/Members/item/'.$this->owner->ID.'/edit'
689
        );
690
    }
691
}
692