Passed
Push — master ( 199ece...6bc7da )
by y
02:13
created

Customer::getPoolKeys()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 6
rs 10
1
<?php
2
3
namespace Helix\Shopify;
4
5
use Helix\Shopify\Base\AbstractEntity;
6
use Helix\Shopify\Base\AbstractEntity\CrudTrait;
7
use Helix\Shopify\Base\AbstractEntity\MetafieldTrait;
8
use Helix\Shopify\Customer\Address;
9
use Helix\Shopify\Customer\Invite;
10
11
/**
12
 * A customer.
13
 *
14
 * @see https://shopify.dev/docs/admin-api/rest/reference/customers/customer
15
 *
16
 * @see Shop::newCustomer()
17
 *
18
 * @method $this        setState                    (string $status) @depends create-only, see the constants
19
 * @method $this        setSendEmailInvite          (bool $invite) @depends create-only
20
 * @method $this        setSendEmailWelcome         (bool $welcome) @depends create-only
21
 * @method $this        setAddresses                (Address[] $addresses) @depends create-only, bulk
22
 * @method $this        setEmail                    (string $email) required, unique
23
 * @method $this        setFirstName                (string $name) required
24
 * @method $this        setLastName                 (string $name) required
25
 *
26
 * @method bool         getAcceptsMarketing         ()
27
 * @method string       getAcceptsMarketingUpdatedAt()
28
 * @method Address[]    getAddresses                ()
29
 * @method string       getCurrency                 () read-only
30
 * @method string       getCreatedAt                () ISO8601
31
 * @method string       getEmail                    ()
32
 * @method string       getFirstName                ()
33
 * @method string       getLastName                 ()
34
 * @method string       getLastOrderId              () read-only
35
 * @method string       getLastOrderName            () read-only
36
 * @method string       getMarketingOptInLevel      () read-only
37
 * @method null|string  getMultipassIdentifier      ()
38
 * @method string       getNote                     ()
39
 * @method int          getOrdersCount              () read-only
40
 * @method string       getPhone                    ()
41
 * @method string       getTags                     ()
42
 * @method bool         isTaxExempt                 ()
43
 * @method string[]     getTaxExemptions            () @depends canada-only
44
 * @method bool         hasTaxExemptions            () @depends canada-only
45
 * @method string       getTotalSpent               ()
46
 * @method string       getUpdatedAt                ()
47
 * @method bool         isVerifiedEmail             ()
48
 *
49
 * @method bool         hasAddresses                ()
50
 * @method bool         hasPhone                    ()
51
 *
52
 * @method $this        setAcceptsMarketing         (bool $opted)
53
 * @method $this        setAcceptsMarketingUpdatedAt(string $iso8601)
54
 * @method $this        setMultipassIdentifier      (?string $ident)
55
 * @method $this        setNote                     (string $note)
56
 * @method $this        setPhone                    (string $e164) unique
57
 * @method $this        setTags                     (string $csv)
58
 * @method $this        setTaxExempt                (bool $exempt)
59
 *
60
 * @method Address[]    selectAddresses (callable $filter) `fn( Address $address ): bool`
61
 */
62
class Customer extends AbstractEntity {
63
64
    use CrudTrait;
65
    use MetafieldTrait;
66
67
    const TYPE = 'customer';
68
    const DIR = 'customers';
69
70
    const MAP = [
71
        'addresses' => [Address::class],
72
    ];
73
74
    /**
75
     * Customer can't log in. This is the default.
76
     */
77
    const IS_DISABLED = 'disabled';
78
79
    /**
80
     * Customer needs to activate their account via invite link before logging in.
81
     */
82
    const IS_INVITED = 'invited';
83
84
    /**
85
     * Customer can log in and shop.
86
     */
87
    const IS_ENABLED = 'enabled';
88
89
    /**
90
     * Customer declined the invite, has no account.
91
     */
92
    const IS_DECLINED = 'declined';
93
94
    /**
95
     * @var string
96
     */
97
    protected $activationUrl;
98
99
    protected function _setData (array $data) {
100
        // redundant
101
        unset($data['default_address']);
102
103
        return parent::_setData($data);
104
    }
105
106
    /**
107
     * @return string
108
     */
109
    public function getActivationUrl (): string {
110
        assert($this->hasId());
111
        return $this->activationUrl
112
            ?? $this->activationUrl = $this->api->post("{$this}/account_activation_url")['account_activation_url'];
113
    }
114
115
    /**
116
     * @return null|Address
117
     */
118
    public function getDefaultAddress () {
119
        return $this->selectAddresses(function(Address $address) {
0 ignored issues
show
Bug introduced by
The method selectAddresses() does not exist on Helix\Shopify\Customer. Since you implemented __call, 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

119
        return $this->/** @scrutinizer ignore-call */ selectAddresses(function(Address $address) {
Loading history...
120
                return $address->isDefault();
121
            })[0] ?? null;
122
    }
123
124
    /**
125
     * @return Order[]
126
     */
127
    public function getOrders () {
128
        assert($this->hasId());
129
        return Order::loadAll($this, "{$this}/orders");
130
    }
131
132
    /**
133
     * @return string[]
134
     */
135
    public function getPoolKeys () {
136
        $keys = parent::getPoolKeys();
137
        $keys[] = $this->data['email'] ?? null;
138
        $keys[] = $this->data['phone'] ?? null;
139
        $keys[] = $this->data['multipass_identifier'] ?? null;
140
        return array_filter($keys);
141
    }
142
143
    /**
144
     * @return bool
145
     */
146
    final public function isDeclined (): bool {
147
        return $this->data['state'] === self::IS_DECLINED;
148
    }
149
150
    /**
151
     * @return bool
152
     */
153
    final public function isDisabled (): bool {
154
        return $this->data['state'] === self::IS_DISABLED;
155
    }
156
157
    /**
158
     * @return bool
159
     */
160
    final public function isEnabled (): bool {
161
        return $this->data['state'] === self::IS_ENABLED;
162
    }
163
164
    /**
165
     * @return bool
166
     */
167
    final public function isInvited (): bool {
168
        return $this->data['state'] === self::IS_INVITED;
169
    }
170
171
    /**
172
     * @return Address
173
     */
174
    public function newAddress () {
175
        return $this->api->factory($this, Address::class, [
176
            'customer_id' => $this->getId()
177
        ]);
178
    }
179
180
    /**
181
     * Creates an invite for an existing customer.
182
     *
183
     * @return Invite
184
     */
185
    public function newInvite () {
186
        return new Invite($this);
187
    }
188
189
    /**
190
     * @param string $password
191
     * @return $this
192
     */
193
    public function setPassword (string $password) {
194
        $this->_set('password', $password);
195
        $this->_set('password_confirmation', $password);
196
        return $this;
197
    }
198
}
199