Completed
Push — master ( cfffae...fa5fd4 )
by Nic
05:44
created

FoxyCart::getAPIRequest()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 32
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 19.9289

Importance

Changes 0
Metric Value
eloc 19
dl 0
loc 32
ccs 3
cts 19
cp 0.1579
rs 9.3222
c 0
b 0
f 0
cc 5
nc 5
nop 1
crap 19.9289
1
<?php
2
3
namespace Dynamic\FoxyStripe\Model;
4
5
use Psr\Log\LoggerInterface;
6
use SilverStripe\Core\Injector\Injector;
7
use SilverStripe\SiteConfig\SiteConfig;
8
use SilverStripe\Security\Member;
9
10
/**
11
 *
12
 */
13
class FoxyCart
14
{
15
    /**
16
     * @var string
17
     */
18
    private static $keyPrefix = 'dYnm1c';
19
20
    /**
21
     * @param int $length
22
     * @param int $count
23
     *
24
     * @return string
25
     */
26 3
    public static function setStoreKey($length = 54, $count = 0)
27
    {
28 3
        $charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'.strtotime('now');
29 3
        $strLength = strlen($charset);
30 3
        $str = '';
31 3
        while ($count < $length) {
32 3
            $str .= $charset[mt_rand(0, $strLength - 1)];
33 3
            ++$count;
34
        }
35
36 3
        return self::getKeyPrefix().substr(base64_encode($str), 0, $length);
37
    }
38
39
    /**
40
     * @return mixed|null
41
     * @throws \SilverStripe\ORM\ValidationException
42
     */
43 49
    public static function getStoreKey()
44
    {
45 49
        $config = FoxyStripeSetting::current_foxystripe_setting();
46 49
        if ($config->StoreKey) {
47
            return $config->StoreKey;
48
        }
49
50 49
        return false;
51
    }
52
53
    /**
54
     * @return null|string
55
     * @throws \SilverStripe\ORM\ValidationException
56
     */
57 1
    public static function store_name_warning()
58
    {
59 1
        $warning = null;
60 1
        if (self::getFoxyCartStoreName() === null) {
61
            $warning = 'Must define FoxyCart Store Name or Store Remote Domain in your site settings in the cms';
62
        }
63
64 1
        return $warning;
65
    }
66
67
    /**
68
     * @return mixed|null
69
     * @throws \SilverStripe\ORM\ValidationException
70
     */
71 1
    public static function getFoxyCartStoreName()
72
    {
73 1
        $config = FoxyStripeSetting::current_foxystripe_setting();
74 1
        if ($config->CustomSSL) {
0 ignored issues
show
Bug Best Practice introduced by
The property CustomSSL does not exist on Dynamic\FoxyStripe\Model\FoxyStripeSetting. Since you implemented __get, consider adding a @property annotation.
Loading history...
75
            if ($config->RemoteDomain) {
0 ignored issues
show
Bug Best Practice introduced by
The property RemoteDomain does not exist on Dynamic\FoxyStripe\Model\FoxyStripeSetting. Since you implemented __get, consider adding a @property annotation.
Loading history...
76
                return $config->RemoteDomain;
77
            }
78
        } else {
79 1
            if ($config->StoreName) {
80
                return $config->StoreName;
81
            }
82
        }
83
84 1
        return false;
85
    }
86
87
    /**
88
     * @return string
89
     * @throws \SilverStripe\ORM\ValidationException
90
     */
91
    public static function FormActionURL()
92
    {
93
        $config = FoxyStripeSetting::current_foxystripe_setting();
94
        if ($config->CustomSSL) {
0 ignored issues
show
Bug Best Practice introduced by
The property CustomSSL does not exist on Dynamic\FoxyStripe\Model\FoxyStripeSetting. Since you implemented __get, consider adding a @property annotation.
Loading history...
95
            return sprintf('https://%s/cart', self::getFoxyCartStoreName());
96
        } else {
97
            return sprintf('https://%s.foxycart.com/cart', self::getFoxyCartStoreName());
98
        }
99
    }
100
101
    /**
102
     * FoxyCart API v1.1 functions.
103
     */
104
105
    /**
106
     * @param array $foxyData
107
     * @return string
108
     * @throws \SilverStripe\ORM\ValidationException
109
     */
110 49
    private static function getAPIRequest($foxyData = array())
111
    {
112 49
        if (self::getStoreKey() && self::getFoxyCartStoreName()) {
113
            $config = FoxyStripeSetting::current_foxystripe_setting();
114
            if ($config->CustomSSL) {
0 ignored issues
show
Bug Best Practice introduced by
The property CustomSSL does not exist on Dynamic\FoxyStripe\Model\FoxyStripeSetting. Since you implemented __get, consider adding a @property annotation.
Loading history...
115
                $foxy_domain = self::getFoxyCartStoreName();
116
            } else {
117
                $foxy_domain = self::getFoxyCartStoreName().'.foxycart.com';
118
            }
119
120
            $foxyData['api_token'] = self::getStoreKey();
121
122
            $ch = curl_init();
123
            curl_setopt($ch, CURLOPT_URL, 'https://'.$foxy_domain.'/api');
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_setopt() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

123
            curl_setopt(/** @scrutinizer ignore-type */ $ch, CURLOPT_URL, 'https://'.$foxy_domain.'/api');
Loading history...
124
            curl_setopt($ch, CURLOPT_POSTFIELDS, $foxyData);
125
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
126
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
127
            curl_setopt($ch, CURLOPT_TIMEOUT, 15);
128
            // If you get SSL errors, you can uncomment the following, or ask your host to add the appropriate CA bundle
129
            // curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% 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...
130
            $response = trim(curl_exec($ch));
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_exec() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

130
            $response = trim(curl_exec(/** @scrutinizer ignore-type */ $ch));
Loading history...
131
132
            // The following if block will print any CURL errors you might have
133
            if ($response == false) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $response of type string to the boolean false. If you are specifically checking for an empty string, consider using the more explicit === '' instead.
Loading history...
134
                //trigger_error("Could not connect to FoxyCart API", E_USER_ERROR);
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...
135
                Injector::inst()->get(LoggerInterface::class)->error('Could not connect to FoxyCart API');
136
            }
137
            curl_close($ch);
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_close() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

137
            curl_close(/** @scrutinizer ignore-type */ $ch);
Loading history...
138
139
            return $response;
140
        }
141 49
        return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type string.
Loading history...
142
    }
143
144
    /**
145
     * @param null $Member
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $Member is correct as it would always require null to be passed?
Loading history...
146
     * @return string
147
     * @throws \SilverStripe\ORM\ValidationException
148
     */
149
    public static function getCustomer(Member $Member = null)
150
    {
151
152
        // throw error if no $Member Object
153
        if (!isset($Member)) {
154
            trigger_error('No Member set', E_USER_ERROR);
155
        }
156
157
        // grab customer record from API
158
159
        $foxyData = array();
160
        $foxyData['api_action'] = 'customer_get';
161
        if ($Member->Customer_ID) {
162
            $foxyData['customer_id'] = $Member->Customer_ID;
163
        }
164
        $foxyData['customer_email'] = $Member->Email;
165
166
        return self::getAPIRequest($foxyData);
167
    }
168
169
    /**
170
     * @param null $Member
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $Member is correct as it would always require null to be passed?
Loading history...
171
     * @return string
172
     * @throws \SilverStripe\ORM\ValidationException
173
     */
174 49
    public static function putCustomer(Member $Member = null)
175
    {
176
        // throw error if no $Member Object
177 49
        if ($Member === null) {
178
//trigger_error('No Member set', E_USER_ERROR);
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...
179
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type string.
Loading history...
180
        }
181
        // send updated customer record from API
182 49
        $foxyData = array();
183 49
        $foxyData['api_action'] = 'customer_save';
184
        // customer_id will be 0 if created in SilverStripe.
185 49
        if ($Member->Customer_ID) {
186
            $foxyData['customer_id'] = $Member->Customer_ID;
187
        }
188 49
        $foxyData['customer_email'] = $Member->Email;
189 49
        $foxyData['customer_password_hash'] = $Member->Password;
190 49
        $foxyData['customer_password_salt'] = $Member->Salt;
191 49
        $foxyData['customer_first_name'] = $Member->FirstName;
192 49
        $foxyData['customer_last_name'] = $Member->Surname;
193
194 49
        return self::getAPIRequest($foxyData);
195
    }
196
197
    /**
198
     * @return string
199
     */
200 3
    public static function getKeyPrefix()
201
    {
202 3
        return self::$keyPrefix;
203
    }
204
}
205