Completed
Pull Request — master (#304)
by Jason
11:13
created

FoxyStripeSiteConfig::onBeforeWrite()   B

Complexity

Conditions 6
Paths 4

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
dl 0
loc 19
ccs 0
cts 0
cp 0
rs 8.8571
c 0
b 0
f 0
cc 6
eloc 11
nc 4
nop 0
crap 42
1
<?php
2
3
use Dynamic\FoxyStripe\Model\FoxyStripeClient;
4
5
class FoxyStripeSiteConfig extends DataExtension{
6
7
	private static $db = array(
8
	    'StoreTitle' => 'Varchar(255)',
9
		'StoreName' => 'Varchar(255)',
10
        'StoreURL' => 'Varchar(255)',
11
		'StoreKey' => 'Varchar(60)',
12
        'ReceiptURL' => 'Varchar(255)',
13
        'StoreEmail' => 'Varchar(255)',
14
        'FromEmail' => 'Varchar(255)',
15
		'MultiGroup' => 'Boolean',
16
		'ProductLimit' => 'Int',
17
		//'CartValidation' => 'Boolean',
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
18
		'MaxQuantity' => 'Int',
19
        'client_id' => 'Varchar(255)',
20
        'client_secret' => 'Varchar(255)',
21
        'access_token' => 'Varchar(255)',
22
        'refresh_token' => 'Varchar(255)',
23
	);
24
25
    // Set Default values
26
    private static $defaults = array(
27
        'ProductLimit' => 10
28
    );
29
30
	public function updateCMSFields(FieldList $fields){
31
32
        // set TabSet names to avoid spaces from camel case
33
        $fields->addFieldToTab('Root', new TabSet('FoxyStripe', 'FoxyStripe'));
34
35
        // settings tab
36
        $fields->addFieldsToTab('Root.FoxyStripe.Settings', array(
37
            // Store Details
38
			HeaderField::create('StoreDetails', _t('FoxyStripeSiteConfig.StoreDetails', 'Store Settings'), 3),
39
			LiteralField::create('DetailsIntro', _t(
40
				'FoxyStripeSiteConfig.DetailsIntro',
41
                '<p>Maps to data in your <a href="https://admin.foxycart.com/admin.php?ThisAction=EditStore" target="_blank">FoxyCart store settings</a>.'
42
            )),
43
            TextField::create('StoreTitle')
44
                ->setTitle(_t('FoxyStripeSiteConfig.StoreTitle', 'Store Name'))
45
                ->setDescription(_t('FoxyStripeSiteConfig.StoreTitleDescription', 'The name of your store as you\'d like it displayed to your customers')),
46
			TextField::create('StoreName')
47
				->setTitle(_t('FoxyStripeSiteConfig.StoreName', 'Store Domain'))
48
				->setDescription(_t('FoxyStripeSiteConfig.StoreNameDescription', 'This is a unique FoxyCart subdomain for your cart, checkout, and receipt')),
49
            TextField::create('StoreURL')
50
                ->setTitle(_t('FoxyStripeSiteConfig.StoreURL', 'Store URL'))
51
                ->setDescription(_t('FoxyStripeSiteConfig.StoreURLDescription', 'The URL of your online store')),
52
            TextField::create('ReceiptURL')
53
                ->setTitle(_t('FoxyStripeSiteConfig.ReceiptURL', 'Receipt URL'))
54
                ->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')),
55
            TextField::create('StoreEmail')
56
                ->setTitle(_t('FoxyStripeSiteConfig.StoreEmail', 'Store Email'))
57
                ->setDescription(_t('FoxyStripeSiteConfig.StoreEmailDescription', 'This is the email address of your store. By default, this will be the from address for your store receipts. ')),
58
            TextField::create('FromEmail')
59
                ->setTitle(_t('FoxyStripeSiteConfig.FromEmail', 'From Email'))
60
                ->setDescription(_t('FoxyStripeSiteConfig.FromEmailDescription', 'Used for when you want to specify a different from email than your store\'s email address')),
61
62
			// Advanced Settings
63
            /*
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...
64
			HeaderField::create('AdvanceHeader', _t('FoxyStripeSiteConfig.AdvancedHeader', 'Advanced Settings'), 3),
65
			LiteralField::create('AdvancedIntro', _t(
66
                'FoxyStripeSiteConfig.AdvancedIntro',
67
				'<p>Maps to data in your <a href="https://admin.foxycart.com/admin.php?ThisAction=EditAdvancedFeatures" target="_blank">FoxyCart advanced store settings</a>.</p>'
68
			)),
69
			ReadonlyField::create('DataFeedLink', _t('FoxyStripeSiteConfig.DataFeedLink', 'FoxyCart DataFeed URL'), self::getDataFeedLink())
70
				->setDescription(_t('FoxyStripeSiteConfig.DataFeedLinkDescription', 'copy/paste to FoxyCart')),
71
			CheckboxField::create('CartValidation')
72
				->setTitle(_t('FoxyStripeSiteConfig.CartValidation', 'Enable Cart Validation'))
73
				->setDescription(_t(
74
                    'FoxyStripeSiteConfig.CartValidationDescription',
75
                    '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.'
76
            )),
77
			ReadonlyField::create('StoreKey')
78
				->setTitle(_t('FoxyStripeSiteConfig.StoreKey', 'FoxyCart API Key'))
79
				->setDescription(_t('FoxyStripeSiteConfig.StoreKeyDescription', 'copy/paste to FoxyCart')),
80
			ReadonlyField::create('SSOLink', _t('FoxyStripeSiteConfig.SSOLink', 'Single Sign On URL'), self::getSSOLink())
81
				->setDescription(_t('FoxyStripeSiteConfig.SSOLinkDescription', 'copy/paste to FoxyCart'))
82
            */
83
        ));
84
85
        // configuration warning
86 View Code Duplication
		if(FoxyCart::store_name_warning()!==null){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
87
			$fields->insertBefore(LiteralField::create(
88
                "StoreSubDomainHeaderWarning",
89
                _t(
90
                    'FoxyStripeSiteConfig.StoreSubDomainHeadingWarning',
91
                    "<p class=\"message error\">Store sub-domain must be entered in the <a href=\"/admin/settings/\">site settings</a></p>"
92
                )
93
            ), 'StoreDetails');
0 ignored issues
show
Documentation introduced by
'StoreDetails' is of type string, but the function expects a object<FormField>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
94
		}
95
96
        // products tab
97
		$fields->addFieldsToTab('Root.FoxyStripe.Products', array(
98
			HeaderField::create('ProductHeader', _t('FoxyStripeSiteConfig.ProductHeader', 'Products'), 3),
99
			CheckboxField::create('MultiGroup')
100
				->setTitle(_t('FoxyStripeSiteConfig.MultiGroup', 'Multiple Groups'))
101
				->setDescription(_t(
102
                    'FoxyStripeSiteConfig.MultiGroupDescription',
103
                    'Allows products to be shown in multiple Product Groups'
104
                )),
105
			HeaderField::create('ProductGroupHD', _t('FoxyStripeSiteConfig.ProductGroupHD', 'Product Groups'), 3),
106
			NumericField::create('ProductLimit')
107
				->setTitle(_t('FoxyStripeSiteConfig.ProductLimit', 'Products per Page'))
108
				->setDescription(_t(
109
                    'FoxyStripeSiteConfig.ProductLimitDescription',
110
                    'Number of Products to show per page on a Product Group'
111
                )),
112
			HeaderField::create('ProductQuantityHD', _t('FoxyStripeSiteConfig.ProductQuantityHD', 'Product Form Max Quantity'), 3),
113
			NumericField::create('MaxQuantity')
114
				->setTitle(_t('FoxyStripeSiteConfig.MaxQuantity', 'Max Quantity'))
115
				->setDescription(_t(
116
                    'FoxyStripeSiteConfig.MaxQuantityDescription',
117
                    'Sets max quantity for product form dropdown (add to cart form - default 10)'
118
                ))
119
		));
120
121
        // categories tab
122
		$fields->addFieldsToTab('Root.FoxyStripe.Categories', array(
123
			HeaderField::create('CategoryHD', _t('FoxyStripeSiteConfig.CategoryHD', 'FoxyStripe Categories'), 3),
124
			LiteralField::create('CategoryDescrip', _t(
125
                'FoxyStripeSiteConfig.CategoryDescrip',
126
                '<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>'
127
            )),
128
			GridField::create(
129
                'ProductCategory',
130
                _t('FoxyStripeSiteConfig.ProductCategory', 'FoxyCart Categories'),
131
                ProductCategory::get(),
132
                GridFieldConfig_RecordEditor::create()
133
            )
134 3
		));
135
136 3
        // option groups tab
137
		$fields->addFieldsToTab('Root.FoxyStripe.Groups', array(
138 3
			HeaderField::create('OptionGroupsHead', _t('FoxyStripeSiteConfig', 'Product Option Groups'), 3),
139
			LiteralField::create('OptionGroupsDescrip', _t(
140 3
                'FoxyStripeSiteConfig.OptionGroupsDescrip',
141 3
                '<p>Product Option Groups allow you to name a set of product options.</p>'
142 3
            )),
143
			GridField::create(
144
                'OptionGroup',
145 3
                _t('FoxyStripeSiteConfig.OptionGroup', 'Product Option Groups'),
146 3
                OptionGroup::get(),
147 3
                GridFieldConfig_RecordEditor::create()
148 3
            )
149 3
		));
150
151
		// api tab
152 1
        $fields->addFieldsToTab('Root.FoxyStripe.API', [
153
            HeaderField::create('APIHD', 'FoxyCart API Settings', 3),
154
            TextField::create('client_id', 'FoxyCart Client ID'),
155
            TextField::create('client_secret', 'FoxyCart Client Secret'),
156
            TextField::create('access_token', 'FoxyCart Access Token'),
157
            TextField::create('refresh_token', 'FoxyCart Refresh Token'),
158
        ]);
159
160
	}
161
162
    private static function getSSOLink() {
163
        return Director::absoluteBaseURL()."foxystripe/sso/";
164
    }
165
166
    private static function getDataFeedLink() {
167
        return Director::absoluteBaseURL()."foxystripe/";
168
    }
169
170
    // generate key on install
171
    public function requireDefaultRecords() {
172
173
        parent::requireDefaultRecords();
174
175
        $siteConfig = SiteConfig::current_site_config();
176
177
        if(!$siteConfig->StoreKey) {
178
            $key = FoxyCart::setStoreKey();
179
            while(!ctype_alnum($key)){
180
                $key = FoxyCart::setStoreKey();
181
            }
182
            $siteConfig->StoreKey = $key;
183
            $siteConfig->write();
184
            DB::alteration_message($siteConfig->ClassName.": created FoxyCart Store Key " . $key, 'created');
185
        }
186
    }
187
188
    /**
189
     * @return array
190
     */
191
    public function getDataMap()
192
    {
193
        return [
194
            'store_name' => $this->owner->StoreTitle,
195
            'store_domain' => $this->owner->StoreName,
196
            'store_url' => $this->owner->StoreURL,
197
            'receipt_continue_url' => $this->owner->ReceiptURL,
198
            'store_email' => $this->owner->StoreEmail,
199
            'from_email' => $this->owner->FromEmail,
200
            //'store_postal_code' => $_POST['store_postal_code'],
0 ignored issues
show
Unused Code Comprehensibility introduced by
78% 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...
201
            //'store_country' => $_POST['store_country'],
0 ignored issues
show
Unused Code Comprehensibility introduced by
78% 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...
202
            //'store_state' => $_POST['store_state'],
0 ignored issues
show
Unused Code Comprehensibility introduced by
78% 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...
203
            'use_webhook' => 1,
204
            'webhook_url' => $this->getDataFeedLink(),
205
            'webhook_key' => $this->owner->StoreKey,
206
            'use_cart_validation' => 1,
207
            'use_single_sign_on' => 1,
208
            'single_sign_on_url' => $this->getSSOLink(),
209
            'customer_password_hash_type' => 'sha1_salted_suffix',
210
            'customer_password_hash_config' => 40,
211
        ];
212
    }
213
214
    /**
215
     * if StoreTitle is empty, grab values from FoxyCart
216
     *
217
     * example of 2 way sync for future reference
218
     */
219
    public function onBeforeWrite()
220
    {
221
        parent::onBeforeWrite();
222
223
        if ($this->owner->ID && !$this->owner->StoreTitle && $this->owner->access_token) {
224
            if ($fc = new FoxyStripeClient()) {
225
                $client = $fc->getClient();
226
                $errors = [];
227
228
                $result = $client->get($fc->getCurrentStore());
229
                $this->owner->StoreTitle = $result['store_name'];
230
231
                $errors = array_merge($errors, $client->getErrors($result));
232
                if (count($errors)) {
233
                    \SS_Log::log('FoxyStripeSiteConfig::onBeforeWrite errors - ' . json_encode($errors), \SS_Log::WARN);
234
                }
235
            }
236
        }
237
    }
238
239
    /**
240
     * push updated data to FoxyCart
241
     */
242
    public function onAfterWrite()
243
    {
244
        parent::onAfterWrite();
245
246
        if ($this->owner->isChanged() && $this->owner->access_token) {
247
            if ($fc = new FoxyStripeClient()) {
248
                $fc->updateStore($this->getDataMap());
249
            }
250
        }
251
    }
252
}
253