22digital /
laravel-cashier-fastspring
| 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
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
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
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
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...
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
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
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
Loading history...
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
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
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
Loading history...
|
|||||||
| 200 | |||||||
| 201 | 1 | return $response->accounts[0]->url; |
|||||
|
0 ignored issues
–
show
|
|||||||
| 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
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
Loading history...
|
|||||||
| 229 | |||||||
| 230 | 2 | $this->fastspring_id = $account->account; |
|||||
|
0 ignored issues
–
show
|
|||||||
| 231 | |||||||
| 232 | 2 | $this->save(); |
|||||
|
0 ignored issues
–
show
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
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
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
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
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
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 |
This check looks for parameters that have been defined for a function or method, but which are not used in the method body.