Billable   A
last analyzed

Complexity

Total Complexity 35

Size/Duplication

Total Lines 304
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 35
eloc 76
c 0
b 0
f 0
dl 0
loc 304
ccs 90
cts 90
cp 1
rs 9.6

17 Methods

Rating   Name   Duplication   Size   Complexity  
A subscription() 0 6 1
A subscriptions() 0 3 1
A updateAsFastspringCustomer() 0 22 3
A onPlan() 0 4 2
A invoices() 0 3 1
A refund() 0 3 1
A extractLastName() 0 13 2
A newSubscription() 0 3 1
A hasFastspringId() 0 3 1
A onTrial() 0 10 5
A extractFirstName() 0 14 2
A subscribedToPlan() 0 15 5
A subscribed() 0 14 4
A createAsFastspringCustomer() 0 24 2
A accountManagementURI() 0 5 1
A asFastspringCustomer() 0 9 2
A charge() 0 3 1
1
<?php
2
/**
3
 * This file implements Billable.
4
 *
5
 * @author    Bilal Gultekin <[email protected]>
6
 * @author    Justin Hartman <[email protected]>
7
 * @copyright 2019 22 Digital
8
 * @license   MIT
9
 * @since     v0.1
10
 */
11
12
namespace TwentyTwoDigital\CashierFastspring;
13
14
use Exception;
15
use TwentyTwoDigital\CashierFastspring\Exceptions\NotImplementedException;
16
use TwentyTwoDigital\CashierFastspring\Fastspring\Fastspring;
17
18
/**
19
 * Billable trait.
20
 *
21
 * {@inheritdoc}
22
 */
23
trait Billable
24
{
25
    /**
26
     * Make a "one off" charge on the customer for the given amount.
27
     *
28
     * @param int   $amount  The amount to charge
29
     * @param array $options Array of options
30
     *
31
     * @throws \TwentyTwoDigital\CashierFastspring\Exceptions\NotImplementedException
32
     */
33 1
    public function charge($amount, array $options = [])
0 ignored issues
show
Unused Code introduced by
The parameter $amount is not used and could be removed. ( Ignorable by Annotation )

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

33
    public function charge(/** @scrutinizer ignore-unused */ $amount, array $options = [])

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $options is not used and could be removed. ( Ignorable by Annotation )

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

33
    public function charge($amount, /** @scrutinizer ignore-unused */ array $options = [])

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
34
    {
35 1
        throw new NotImplementedException();
36
    }
37
38
    /**
39
     * Refund a customer for a charge.
40
     *
41
     * @param string $charge  The amount to refund
42
     * @param array  $options Array of options
43
     *
44
     * @throws \TwentyTwoDigital\CashierFastspring\Exceptions\NotImplementedException
45
     */
46 1
    public function refund($charge, array $options = [])
0 ignored issues
show
Unused Code introduced by
The parameter $options is not used and could be removed. ( Ignorable by Annotation )

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

46
    public function refund($charge, /** @scrutinizer ignore-unused */ array $options = [])

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $charge is not used and could be removed. ( Ignorable by Annotation )

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

46
    public function refund(/** @scrutinizer ignore-unused */ $charge, array $options = [])

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
47
    {
48 1
        throw new NotImplementedException();
49
    }
50
51
    /**
52
     * Begin creating a new subscription.
53
     *
54
     * @param string $subscription Subscription name
55
     * @param string $plan         The plan name
56
     *
57
     * @return \TwentyTwoDigital\CashierFastspring\SubscriptionBuilder
58
     */
59 4
    public function newSubscription($subscription, $plan)
60
    {
61 4
        return new SubscriptionBuilder($this, $subscription, $plan);
62
    }
63
64
    /**
65
     * Determine if the subscription is on trial.
66
     *
67
     * @param string      $subscription Subscription name
68
     * @param string|null $plan         Plan name
69
     *
70
     * @return bool
71
     */
72 1
    public function onTrial($subscription = 'default', $plan = null)
73
    {
74 1
        $subscription = $this->subscription($subscription);
75
76 1
        if (is_null($plan)) {
77 1
            return $subscription && $subscription->onTrial();
78
        }
79
80 1
        return $subscription && $subscription->onTrial() &&
81 1
               $subscription->plan === $plan;
82
    }
83
84
    /**
85
     * Determine if the model has a given subscription.
86
     *
87
     * @param string      $subscription Subscription name
88
     * @param string|null $plan         Plan name
89
     *
90
     * @return bool
91
     */
92 1
    public function subscribed($subscription = 'default', $plan = null)
93
    {
94 1
        $subscription = $this->subscription($subscription);
95
96 1
        if (is_null($subscription)) {
97 1
            return false;
98
        }
99
100 1
        if (is_null($plan)) {
101 1
            return $subscription->valid();
102
        }
103
104 1
        return $subscription->valid() &&
105 1
               $subscription->plan === $plan;
106
    }
107
108
    /**
109
     * Get a subscription instance by name.
110
     *
111
     * @param string $subscription
112
     *
113
     * @return \TwentyTwoDigital\CashierFastspring\Subscription|null
114
     */
115 2
    public function subscription($subscription = 'default')
116
    {
117 2
        return $this->subscriptions()
118 2
            ->where('name', $subscription)
119 2
            ->orderBy('created_at', 'desc')
120 2
            ->first();
121
    }
122
123
    /**
124
     * Get all of the subscriptions for the model.
125
     *
126
     * @return \Illuminate\Database\Eloquent\Collection
127
     */
128 30
    public function subscriptions()
129
    {
130 30
        return $this->hasMany(Subscription::class, $this->getForeignKey())->orderBy('created_at', 'desc');
0 ignored issues
show
Bug introduced by
It seems like hasMany() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

130
        return $this->/** @scrutinizer ignore-call */ hasMany(Subscription::class, $this->getForeignKey())->orderBy('created_at', 'desc');
Loading history...
Bug introduced by
It seems like getForeignKey() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

130
        return $this->hasMany(Subscription::class, $this->/** @scrutinizer ignore-call */ getForeignKey())->orderBy('created_at', 'desc');
Loading history...
131
    }
132
133
    /**
134
     * Get all of the FastSpring invoices for the current user.
135
     *
136
     * @return object
137
     */
138 1
    public function invoices()
139
    {
140 1
        return $this->hasMany(Invoice::class, $this->getForeignKey())->orderBy('created_at', 'desc');
141
    }
142
143
    /**
144
     * Determine if the model is actively subscribed to one of the given plans.
145
     *
146
     * @param string|null $plans        Plan name
147
     * @param string      $subscription Subscription name
148
     *
149
     * @return bool
150
     */
151 1
    public function subscribedToPlan($plans, $subscription = 'default')
152
    {
153 1
        $subscription = $this->subscription($subscription);
154
155 1
        if (!$subscription || !$subscription->valid()) {
156 1
            return false;
157
        }
158
159 1
        foreach ((array) $plans as $plan) {
160 1
            if ($subscription->plan === $plan) {
161 1
                return true;
162
            }
163
        }
164
165 1
        return false;
166
    }
167
168
    /**
169
     * Determine if the entity is on the given plan.
170
     *
171
     * @param string $plan Plan name
172
     *
173
     * @return bool
174
     */
175 1
    public function onPlan($plan)
176
    {
177
        return !is_null($this->subscriptions->first(function ($value) use ($plan) {
178 1
            return $value->plan === $plan && $value->valid();
179 1
        }));
180
    }
181
182
    /**
183
     * Determine if the entity has a Fastspring customer ID.
184
     *
185
     * @return bool
186
     */
187 5
    public function hasFastspringId()
188
    {
189 5
        return !is_null($this->fastspring_id);
190
    }
191
192
    /**
193
     * Generate authenticated url of fastspring account management panel.
194
     *
195
     * @return \TwentyTwoDigital\CashierFastspring\Fastspring\Fastspring
196
     */
197 1
    public function accountManagementURI()
198
    {
199 1
        $response = Fastspring::getAccountManagementURI($this->fastspring_id);
0 ignored issues
show
Bug introduced by
The method getAccountManagementURI() does not exist on TwentyTwoDigital\Cashier...g\Fastspring\Fastspring. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

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

199
        /** @scrutinizer ignore-call */ 
200
        $response = Fastspring::getAccountManagementURI($this->fastspring_id);
Loading history...
200
201 1
        return $response->accounts[0]->url;
0 ignored issues
show
Bug introduced by
The property accounts does not seem to exist on TwentyTwoDigital\Cashier...g\Fastspring\Fastspring.
Loading history...
202
    }
203
204
    /**
205
     * Create a Fastspring customer for the given user model.
206
     *
207
     * @param array $options Options array of customer information
208
     *
209
     * @return \TwentyTwoDigital\CashierFastspring\Fastspring\Fastspring
210
     */
211 3
    public function createAsFastspringCustomer(array $options = [])
212
    {
213 3
        $options = empty($options) ? [
214
            'contact' => [
215 3
                'first'   => $this->extractFirstName(),
216 3
                'last'    => $this->extractLastName(),
217 3
                'email'   => $this->email,
218 3
                'company' => $this->company,
219 3
                'phone'   => $this->phone,
220
            ],
221 3
            'language' => $this->language,
222 3
            'country'  => $this->country,
223 3
        ] : $options;
224
225
        // Here we will create the customer instance on Fastspring and store the ID of the
226
        // user from Fastspring. This ID will correspond with the Fastspring user instances
227
        // and allow us to retrieve users from Fastspring later when we need to work.
228 3
        $account = Fastspring::createAccount($options);
0 ignored issues
show
Bug introduced by
The method createAccount() does not exist on TwentyTwoDigital\Cashier...g\Fastspring\Fastspring. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

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

228
        /** @scrutinizer ignore-call */ 
229
        $account = Fastspring::createAccount($options);
Loading history...
229
230 2
        $this->fastspring_id = $account->account;
0 ignored issues
show
Bug introduced by
The property account does not seem to exist on TwentyTwoDigital\Cashier...g\Fastspring\Fastspring.
Loading history...
Bug Best Practice introduced by
The property fastspring_id does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
231
232 2
        $this->save();
0 ignored issues
show
Bug introduced by
It seems like save() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

232
        $this->/** @scrutinizer ignore-call */ 
233
               save();
Loading history...
233
234 2
        return $account;
235
    }
236
237
    /**
238
     * Update the related account on Fastspring, given user-model.
239
     *
240
     * @param array $options array of customer information
241
     *
242
     * @throws Exception No valid Fastspring ID
243
     *
244
     * @return object
245
     */
246 2
    public function updateAsFastspringCustomer(array $options = [])
247
    {
248 2
        if (!$this->hasFastspringId()) {
249 1
            throw new Exception('User has no fastspring_id');
250
        }
251
252 1
        $options = empty($options) ? [
253
            'contact' => [
254 1
                'first'   => $this->extractFirstName(),
255 1
                'last'    => $this->extractLastName(),
256 1
                'email'   => $this->email,
257 1
                'company' => $this->company,
258 1
                'phone'   => $this->phone,
259
            ],
260 1
            'language' => $this->language,
261 1
            'country'  => $this->country,
262 1
        ] : $options;
263
264
        // update
265 1
        $response = Fastspring::updateAccount($this->fastspring_id, $options);
0 ignored issues
show
Bug introduced by
The method updateAccount() does not exist on TwentyTwoDigital\Cashier...g\Fastspring\Fastspring. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

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

265
        /** @scrutinizer ignore-call */ 
266
        $response = Fastspring::updateAccount($this->fastspring_id, $options);
Loading history...
266
267 1
        return $response;
268
    }
269
270
    /**
271
     * Get the Fastspring customer for the model.
272
     *
273
     * @throws Exception No valid Fastspring ID
274
     *
275
     * @return object
276
     */
277 2
    public function asFastspringCustomer()
278
    {
279
        // check the fastspring_id first
280
        // if there is non, no need to try
281 2
        if (!$this->hasFastspringId()) {
282 1
            throw new Exception('User has no fastspring_id');
283
        }
284
285 1
        return Fastspring::getAccount($this->fastspring_id);
0 ignored issues
show
Bug introduced by
The method getAccount() does not exist on TwentyTwoDigital\Cashier...g\Fastspring\Fastspring. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

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

285
        return Fastspring::/** @scrutinizer ignore-call */ getAccount($this->fastspring_id);
Loading history...
286
    }
287
288
    /**
289
     * Get the first name of the customer for the Fastspring API.
290
     *
291
     * @return object
292
     */
293 5
    public function extractFirstName()
294
    {
295 5
        $parted = explode(' ', $this->name);
296 5
        $parted = array_filter($parted);
297
298 5
        if (count($parted) == 1) {
299 1
            return $parted[0];
300
        }
301
302
        // get rid of the lastname
303 5
        array_pop($parted);
304
305
        // implode rest of it, so there may be more than one name
306 5
        return implode(' ', $parted);
307
    }
308
309
    /**
310
     * Get the last name of the customer for the Fastspring API.
311
     *
312
     * @return object
313
     */
314 5
    public function extractLastName()
315
    {
316 5
        $parted = explode(' ', $this->name);
317 5
        $parted = array_filter($parted);
318
319 5
        if (count($parted) == 1) {
320
            // unfortunately we should do this
321
            // because Fastspring create account API doesn't work without last name
322 1
            return 'Unknown';
323
        }
324
325
        // return last element
326 5
        return array_pop($parted);
327
    }
328
}
329