Passed
Pull Request — master (#309)
by Jason
06:15 queued 01:51
created

FoxyStripeSiteConfig::updateCMSFields()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 157
Code Lines 101

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 102
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 157
ccs 102
cts 102
cp 1
rs 8.2857
cc 2
eloc 101
nc 2
nop 1
crap 2

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Dynamic\FoxyStripe\ORM;
4
5
use Dynamic\CountryDropdownField\Fields\CountryDropdownField;
6
use Dynamic\FoxyStripe\Model\FoxyCart;
7
use Dynamic\FoxyStripe\Model\FoxyStripeClient;
8
use Dynamic\FoxyStripe\Model\OptionGroup;
9
use Dynamic\FoxyStripe\Model\ProductCategory;
10
use Psr\Log\LoggerInterface;
11
use SilverStripe\Control\Director;
12
use SilverStripe\Core\Injector\Injector;
13
use SilverStripe\Forms\CheckboxField;
14
use SilverStripe\Forms\DropdownField;
15
use SilverStripe\Forms\FieldList;
16
use SilverStripe\Forms\GridField\GridField;
17
use SilverStripe\Forms\GridField\GridFieldConfig_RecordEditor;
18
use SilverStripe\Forms\HeaderField;
19
use SilverStripe\Forms\LiteralField;
20
use SilverStripe\Forms\NumericField;
21
use SilverStripe\Forms\ReadonlyField;
22
use SilverStripe\Forms\TabSet;
23
use SilverStripe\Forms\TextField;
24
use SilverStripe\ORM\DataExtension;
25
use SilverStripe\ORM\DB;
26
use SilverStripe\SiteConfig\SiteConfig;
27
28
class FoxyStripeSiteConfig extends DataExtension
29
{
30
    private static $db = array(
0 ignored issues
show
introduced by
The private property $db is not used, and could be removed.
Loading history...
31
        'StoreTitle' => 'Varchar(255)',
32
        'StoreName' => 'Varchar(255)',
33
        'StoreURL' => 'Varchar(255)',
34
        'ReceiptURL' => 'Varchar(255)',
35
        'StoreEmail' => 'Varchar(255)',
36
        'FromEmail' => 'Varchar(255)',
37
        'StorePostalCode' => 'Varchar(10)',
38
        'StoreCountry' => 'Varchar(100)',
39
        'StoreRegion' => 'Varchar(100)',
40
        'StoreLocaleCode' => 'Varchar(10)',
41
        'StoreLogoURL' => 'Varchar(255)',
42
        'CheckoutType' => 'Varchar(50)',
43
        'BccEmail' => 'Boolean',
44
        'UseWebhook' => 'Boolean',
45
        'StoreKey' => 'Varchar(60)',
46
        'CartValidation' => 'Boolean',
47
        'UseSingleSignOn' => 'Boolean',
48
        'AllowMultiship' => 'Boolean',
49
        'StoreTimezone' => 'Varchar(100)',
50
        'MultiGroup' => 'Boolean',
51
        'ProductLimit' => 'Int',
52
        'MaxQuantity' => 'Int',
53
        'client_id' => 'Varchar(255)',
54
        'client_secret' => 'Varchar(255)',
55
        'access_token' => 'Varchar(255)',
56
        'refresh_token' => 'Varchar(255)',
57
    );
58
59
    // Set Default values
60
    private static $defaults = array(
0 ignored issues
show
introduced by
The private property $defaults is not used, and could be removed.
Loading history...
61
        'ProductLimit' => 10,
62
    );
63
64 1
    public function updateCMSFields(FieldList $fields)
65
    {
66
67
        // set TabSet names to avoid spaces from camel case
68 1
        $fields->addFieldToTab('Root', new TabSet('FoxyStripe', 'FoxyStripe'));
69
70
        // settings tab
71 1
        $fields->addFieldsToTab('Root.FoxyStripe.Settings', array(
72
            // Store Details
73 1
            HeaderField::create('StoreDetails', _t('FoxyStripeSiteConfig.StoreDetails', 'Store Settings'), 3),
0 ignored issues
show
Bug introduced by
3 of type integer is incompatible with the type array expected by parameter $args of SilverStripe\View\ViewableData::create(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

73
            HeaderField::create('StoreDetails', _t('FoxyStripeSiteConfig.StoreDetails', 'Store Settings'), /** @scrutinizer ignore-type */ 3),
Loading history...
Bug introduced by
'StoreDetails' of type string is incompatible with the type array expected by parameter $args of SilverStripe\View\ViewableData::create(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

73
            HeaderField::create(/** @scrutinizer ignore-type */ 'StoreDetails', _t('FoxyStripeSiteConfig.StoreDetails', 'Store Settings'), 3),
Loading history...
74 1
            LiteralField::create('DetailsIntro', _t(
75 1
                'FoxyStripeSiteConfig.DetailsIntro',
76 1
                '<p>Maps to data in your <a href="https://admin.foxycart.com/admin.php?ThisAction=EditStore" target="_blank">FoxyCart store settings</a>.'
77
            )),
78 1
            TextField::create('StoreTitle')
79 1
                ->setTitle(_t('FoxyStripeSiteConfig.StoreTitle', 'Store Name'))
80 1
                ->setDescription(_t('FoxyStripeSiteConfig.StoreTitleDescription', 'The name of your store as you\'d like it displayed to your customers')),
81 1
            TextField::create('StoreName')
82 1
                ->setTitle(_t('FoxyStripeSiteConfig.StoreName', 'Store Domain'))
83 1
                ->setDescription(_t('FoxyStripeSiteConfig.StoreNameDescription', 'This is a unique FoxyCart subdomain for your cart, checkout, and receipt')),
84 1
            TextField::create('StoreURL')
85 1
                ->setTitle(_t('FoxyStripeSiteConfig.StoreURL', 'Store URL'))
86 1
                ->setDescription(_t('FoxyStripeSiteConfig.StoreURLDescription', 'The URL of your online store')),
87 1
            TextField::create('ReceiptURL')
88 1
                ->setTitle(_t('FoxyStripeSiteConfig.ReceiptURL', 'Receipt URL'))
89 1
                ->setDescription(_t('FoxyStripeSiteConfig.ReceiptURLDescription', 'By default, FoxyCart sends customers back to the page referrer after completing a purchase. Instead, you can set a specific URL here')),
90 1
            TextField::create('StoreEmail')
91 1
                ->setTitle(_t('FoxyStripeSiteConfig.StoreEmail', 'Store Email'))
92 1
                ->setDescription(_t('FoxyStripeSiteConfig.StoreEmailDescription', 'This is the email address of your store. By default, this will be the from address for your store receipts. ')),
93 1
            TextField::create('FromEmail')
94 1
                ->setTitle(_t('FoxyStripeSiteConfig.FromEmail', 'From Email'))
95 1
                ->setDescription(_t('FoxyStripeSiteConfig.FromEmailDescription', 'Used for when you want to specify a different from email than your store\'s email address')),
96 1
            TextField::create('StorePostalCode', 'Postal Code'),
97 1
            CountryDropdownField::create('StoreCountry', 'Country'),
98 1
            TextField::create('StoreRegion', 'State/Region'),
99 1
            TextField::create('StoreLocaleCode', 'Locale Code')
100 1
                ->setDescription('example: en_US'),
101 1
            TextField::create('StoreTimezone', 'Store timezone'),
102 1
            TextField::create('StoreLogoURL', 'Logo URL')
103 1
                ->setAttribute('placeholder', 'http://'),
104
105
            // Advanced Settings
106
            /*
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
107
            HeaderField::create('AdvanceHeader', _t('FoxyStripeSiteConfig.AdvancedHeader', 'Advanced Settings'), 3),
108
            LiteralField::create('AdvancedIntro', _t(
109
                'FoxyStripeSiteConfig.AdvancedIntro',
110
                '<p>Maps to data in your <a href="https://admin.foxycart.com/admin.php?ThisAction=EditAdvancedFeatures" target="_blank">FoxyCart advanced store settings</a>.</p>'
111
            )),
112
            ReadonlyField::create('DataFeedLink', _t('FoxyStripeSiteConfig.DataFeedLink', 'FoxyCart DataFeed URL'), self::getDataFeedLink())
113
                ->setDescription(_t('FoxyStripeSiteConfig.DataFeedLinkDescription', 'copy/paste to FoxyCart')),
114
            CheckboxField::create('CartValidation')
115
                ->setTitle(_t('FoxyStripeSiteConfig.CartValidation', 'Enable Cart Validation'))
116
                ->setDescription(_t(
117
                    'FoxyStripeSiteConfig.CartValidationDescription',
118
                    'You must <a href="https://admin.foxycart.com/admin.php?ThisAction=EditAdvancedFeatures#use_cart_validation" target="_blank">enable cart validation</a> in the FoxyCart admin.'
119
            )),
120
            ReadonlyField::create('StoreKey')
121
                ->setTitle(_t('FoxyStripeSiteConfig.StoreKey', 'FoxyCart API Key'))
122
                ->setDescription(_t('FoxyStripeSiteConfig.StoreKeyDescription', 'copy/paste to FoxyCart')),
123
            ReadonlyField::create('SSOLink', _t('FoxyStripeSiteConfig.SSOLink', 'Single Sign On URL'), self::getSSOLink())
124
                ->setDescription(_t('FoxyStripeSiteConfig.SSOLinkDescription', 'copy/paste to FoxyCart'))
125
            */
126
        ));
127
128 1
        $fields->addFieldsToTab('Root.FoxyStripe.Advanced', [
129 1
            HeaderField::create('AdvanceHeader', _t('FoxyStripeSiteConfig.AdvancedHeader', 'Advanced Settings'), 3),
130 1
            LiteralField::create('AdvancedIntro', _t(
131 1
                'FoxyStripeSiteConfig.AdvancedIntro',
132 1
                '<p>Maps to data in your <a href="https://admin.foxycart.com/admin.php?ThisAction=EditAdvancedFeatures" target="_blank">FoxyCart advanced store settings</a>.</p>'
133
            )),
134 1
            DropdownField::create('CheckoutType', 'Checkout Type', $this->getCheckoutTypes()),
135 1
            CheckboxField::create('BccEmail', 'BCC Admin Email')
136 1
                ->setDescription('bcc all receipts to store\'s email address'),
137 1
            CheckboxField::create('UseWebhook', 'Use Webhook')
138 1
                ->setDescription('record order history in CMS, allows customers to view their order history'),
139 1
            ReadonlyField::create('WebhookURL', 'Webhook URL', self::getDataFeedLink()),
140 1
            ReadonlyField::create('StoreKey', 'Webhook Key', self::getDataFeedLink()),
141 1
            CheckboxField::create('CartValidation', 'Use cart validation'),
142 1
            CheckboxField::create('UseSingleSignOn', 'Use single sign on')
143 1
                ->setDescription('Sync user accounts between FoxyCart and your website'),
144 1
            ReadonlyField::create('SingleSignOnURL', 'Single sign on URL', self::getSSOLink()),
145 1
            CheckboxField::create('AllowMultiship', 'Allow multiple shipments per order'),
146
        ]);
147
148
        // configuration warning
149 1
        if (FoxyCart::store_name_warning() !== null) {
150 1
            $fields->insertBefore(LiteralField::create(
151 1
                'StoreSubDomainHeaderWarning',
152 1
                _t(
153 1
                    'FoxyStripeSiteConfig.StoreSubDomainHeadingWarning',
154 1
                    '<p class="message error">Store sub-domain must be entered in the <a href="/admin/settings/">site settings</a></p>'
155
                )
156 1
            ), 'StoreDetails');
0 ignored issues
show
Bug introduced by
'StoreDetails' of type string is incompatible with the type SilverStripe\Forms\FormField expected by parameter $item of SilverStripe\Forms\FieldList::insertBefore(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

156
            ), /** @scrutinizer ignore-type */ 'StoreDetails');
Loading history...
157
        }
158
159
        // products tab
160 1
        $fields->addFieldsToTab('Root.FoxyStripe.Products', array(
161 1
            HeaderField::create('ProductHeader', _t('FoxyStripeSiteConfig.ProductHeader', 'Products'), 3),
162 1
            CheckboxField::create('MultiGroup')
163 1
                ->setTitle(_t('FoxyStripeSiteConfig.MultiGroup', 'Multiple Groups'))
164 1
                ->setDescription(_t(
165 1
                    'FoxyStripeSiteConfig.MultiGroupDescription',
166 1
                    'Allows products to be shown in multiple Product Groups'
167
                )),
168 1
            HeaderField::create('ProductGroupHD', _t('FoxyStripeSiteConfig.ProductGroupHD', 'Product Groups'), 3),
169 1
            NumericField::create('ProductLimit')
170 1
                ->setTitle(_t('FoxyStripeSiteConfig.ProductLimit', 'Products per Page'))
171 1
                ->setDescription(_t(
172 1
                    'FoxyStripeSiteConfig.ProductLimitDescription',
173 1
                    'Number of Products to show per page on a Product Group'
174
                )),
175 1
            HeaderField::create('ProductQuantityHD', _t('FoxyStripeSiteConfig.ProductQuantityHD', 'Product Form Max Quantity'), 3),
176 1
            NumericField::create('MaxQuantity')
177 1
                ->setTitle(_t('FoxyStripeSiteConfig.MaxQuantity', 'Max Quantity'))
178 1
                ->setDescription(_t(
179 1
                    'FoxyStripeSiteConfig.MaxQuantityDescription',
180 1
                    'Sets max quantity for product form dropdown (add to cart form - default 10)'
181
                )),
182
        ));
183
184
        // categories tab
185 1
        $fields->addFieldsToTab('Root.FoxyStripe.Categories', array(
186 1
            HeaderField::create('CategoryHD', _t('FoxyStripeSiteConfig.CategoryHD', 'FoxyStripe Categories'), 3),
187 1
            LiteralField::create('CategoryDescrip', _t(
188 1
                'FoxyStripeSiteConfig.CategoryDescrip',
189 1
                '<p>FoxyCart Categories offer a way to give products additional behaviors that cannot be accomplished by product options alone, including category specific coupon codes, shipping and handling fees, and email receipts. <a href="https://wiki.foxycart.com/v/2.0/categories" target="_blank">Learn More</a></p><p>Categories you\'ve created in FoxyStripe must also be created in your <a href="https://admin.foxycart.com/admin.php?ThisAction=ManageProductCategories" target="_blank">FoxyCart Categories</a> admin panel.</p>'
190
            )),
191 1
            GridField::create(
192 1
                'ProductCategory',
193 1
                _t('FoxyStripeSiteConfig.ProductCategory', 'FoxyCart Categories'),
194 1
                ProductCategory::get(),
0 ignored issues
show
Bug introduced by
Dynamic\FoxyStripe\Model\ProductCategory::get() of type SilverStripe\ORM\DataList is incompatible with the type array expected by parameter $args of SilverStripe\View\ViewableData::create(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

194
                /** @scrutinizer ignore-type */ ProductCategory::get(),
Loading history...
195 1
                GridFieldConfig_RecordEditor::create()
196
            ),
197
        ));
198
199
        // option groups tab
200 1
        $fields->addFieldsToTab('Root.FoxyStripe.Groups', array(
201 1
            HeaderField::create('OptionGroupsHead', _t('FoxyStripeSiteConfig', 'Product Option Groups'), 3),
202 1
            LiteralField::create('OptionGroupsDescrip', _t(
203 1
                'FoxyStripeSiteConfig.OptionGroupsDescrip',
204 1
                '<p>Product Option Groups allow you to name a set of product options.</p>'
205
            )),
206 1
            GridField::create(
207 1
                'OptionGroup',
208 1
                _t('FoxyStripeSiteConfig.OptionGroup', 'Product Option Groups'),
209 1
                OptionGroup::get(),
210 1
                GridFieldConfig_RecordEditor::create()
211
            ),
212
        ));
213
214
        // api tab
215 1
        $fields->addFieldsToTab('Root.FoxyStripe.API', [
216 1
            HeaderField::create('APIHD', 'FoxyCart API Settings', 3),
217 1
            TextField::create('client_id', 'FoxyCart Client ID'),
218 1
            TextField::create('client_secret', 'FoxyCart Client Secret'),
219 1
            TextField::create('access_token', 'FoxyCart Access Token'),
220 1
            TextField::create('refresh_token', 'FoxyCart Refresh Token'),
221
        ]);
222
    }
223
224
    /**
225
     * @return string
226
     */
227 2
    private static function getSSOLink()
228
    {
229 2
        return Director::absoluteBaseURL().'foxystripe/sso/';
230
    }
231
232
    /**
233
     * @return string
234
     */
235 2
    private static function getDataFeedLink()
236
    {
237 2
        return Director::absoluteBaseURL().'foxystripe/';
238
    }
239
240
    /**
241
     * generate key on install.
242
     *
243
     * @throws \SilverStripe\ORM\ValidationException
244
     */
245 3
    public function requireDefaultRecords()
246
    {
247 3
        parent::requireDefaultRecords();
248
249 3
        $siteConfig = SiteConfig::current_site_config();
250
251 3
        if (!$siteConfig->StoreKey) {
252 3
            $key = FoxyCart::setStoreKey();
253 3
            while (!ctype_alnum($key)) {
254
                $key = FoxyCart::setStoreKey();
255
            }
256 3
            $siteConfig->StoreKey = $key;
257 3
            $siteConfig->write();
258 3
            DB::alteration_message($siteConfig->ClassName.': created FoxyCart Store Key '.$key, 'created');
259
        }
260
    }
261
262
    /**
263
     * @return array
264
     */
265 1
    public function getCheckoutTypes()
266
    {
267
        return [
268 1
            'default_account' => 'Allow guest and customer accounts, default to account',
269
            'default_guest' => 'Allow guest and customer accounts, default to guest',
270
            'account_only' => 'Allow customer accounts only',
271
            'guest_only' => 'Allow guests only',
272
        ];
273
    }
274
275
    /**
276
     * @return array
277
     */
278 1
    public function getDataMap()
279
    {
280
        return [
281 1
            'store_name' => $this->owner->StoreTitle,
282 1
            'store_domain' => $this->owner->StoreName,
283 1
            'store_url' => $this->owner->StoreURL,
284 1
            'receipt_continue_url' => $this->owner->ReceiptURL,
285 1
            'store_email' => $this->owner->StoreEmail,
286 1
            'from_email' => $this->owner->FromEmail,
287 1
            'postal_code' => $this->owner->StorePostalCode,
288 1
            'country' => $this->owner->StoreCountry,
289 1
            'region' => $this->owner->StoreRegion,
290 1
            'locale_code' => $this->owner->StoreLocaleCode,
291 1
            'logo_url' => $this->owner->StoreLogoURL,
292 1
            'checkout_type' => $this->owner->CheckoutType,
293 1
            'bcc_on_receipt_email' => $this->owner->BccEmail,
294 1
            'use_webhook' => $this->owner->UseWebhook,
295 1
            'webhook_url' => $this->getDataFeedLink(),
296 1
            'webhook_key' => $this->owner->StoreKey,
297 1
            'use_cart_validation' => $this->owner->CartValidation,
298 1
            'use_single_sign_on' => $this->owner->UseSingleSignOn,
299 1
            'single_sign_on_url' => $this->getSSOLink(),
300 1
            'customer_password_hash_type' => 'sha1_salted_suffix',
301 1
            'customer_password_hash_config' => 40,
302 1
            'features_multiship' => $this->owner->AllowMultiship,
303
            //'timezone' => $this->StoreTimezone,
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
304
        ];
305
    }
306
307
    /**
308
     * if StoreTitle is empty, grab values from FoxyCart.
309
     *
310
     * example of 2 way sync for future reference
311
     *
312
     * @throws \Psr\Container\NotFoundExceptionInterface
313
     */
314 49
    public function onBeforeWrite()
315
    {
316 49
        parent::onBeforeWrite();
317
318 49
        if ($this->owner->ID && !$this->owner->StoreTitle && $this->owner->access_token) {
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...
319
            /*
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
320
            if ($fc = new FoxyStripeClient()) {
321
                $client = $fc->getClient();
322
                $errors = [];
323
324
                $result = $client->get($fc->getCurrentStore());
325
                $this->owner->StoreTitle = $result['store_name'];
326
327
                $errors = array_merge($errors, $client->getErrors($result));
328
                if (count($errors)) {
329
                    Injector::inst()->get(LoggerInterface::class)
330
                        ->error('FoxyStripeSiteConfig::onBeforeWrite errors - ' . json_encode($errors));
331
                }
332
            }
333
            */
334
        }
335
    }
336
337
    /**
338
     * @throws \Psr\Container\NotFoundExceptionInterface
339
     */
340 49
    public function onAfterWrite()
341
    {
342 49
        parent::onAfterWrite();
343
344 49
        if ($this->owner->isChanged() && $this->owner->access_token) {
345
            if ($fc = new FoxyStripeClient()) {
346
                $fc->updateStore($this->getDataMap());
347
            }
348
        }
349
    }
350
}
351