Completed
Push — master ( 5fa653...7a841a )
by Tim
18s queued 11s
created

CustomerObserver::getStoreIdByCode()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 1
1
<?php
2
3
/**
4
 * TechDivision\Import\Customer\Observers\CustomerObserver
5
 *
6
 * NOTICE OF LICENSE
7
 *
8
 * This source file is subject to the Open Software License (OSL 3.0)
9
 * that is available through the world-wide-web at this URL:
10
 * http://opensource.org/licenses/osl-3.0.php
11
 *
12
 * PHP version 5
13
 *
14
 * @author    Tim Wagner <[email protected]>
15
 * @copyright 2018 TechDivision GmbH <[email protected]>
16
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
 * @link      https://github.com/techdivision/import-customer
18
 * @link      http://www.techdivision.com
19
 */
20
21
namespace TechDivision\Import\Customer\Observers;
22
23
use TechDivision\Import\Utils\EntityTypeCodes;
24
use TechDivision\Import\Observers\StateDetectorInterface;
25
use TechDivision\Import\Customer\Utils\GenderKeys;
26
use TechDivision\Import\Customer\Utils\ColumnKeys;
27
use TechDivision\Import\Customer\Utils\MemberNames;
28
use TechDivision\Import\Customer\Services\CustomerBunchProcessorInterface;
29
30
/**
31
 * Observer that create's the customer itself.
32
 *
33
 * @author    Tim Wagner <[email protected]>
34
 * @copyright 2018 TechDivision GmbH <[email protected]>
35
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
36
 * @link      https://github.com/techdivision/import-customer
37
 * @link      http://www.techdivision.com
38
 */
39
class CustomerObserver extends AbstractCustomerImportObserver
40
{
41
42
    /**
43
     * The customer bunch processor instance.
44
     *
45
     * @var \TechDivision\Import\Customer\Services\CustomerBunchProcessorInterface
46
     */
47
    protected $customerBunchProcessor;
48
49
    /**
50
     * The array with the available gender keys.
51
     *
52
     * @var array
53
     */
54
    protected $availableGenders = array(
55
        'Male'          => GenderKeys::GENDER_MALE,
56
        'Female'        => GenderKeys::GENDER_FEMALE,
57
        'Not Specified' => GenderKeys::GENDER_NOT_SPECIFIED
58
    );
59
60
    /**
61
     * Initializes the observer with the state detector instance.
62
     *
63
     * @param \TechDivision\Import\Customer\Services\CustomerBunchProcessorInterface $customerBunchProcessor The customer bunch processor instance
64
     * @param \TechDivision\Import\Observers\StateDetectorInterface                  $stateDetector          The state detector instance
65
     */
66
    public function __construct(
67
        CustomerBunchProcessorInterface $customerBunchProcessor,
68
        StateDetectorInterface $stateDetector = null
69
    ) {
70
71
        // set the customer processor and the raw entity loader
72
        $this->customerBunchProcessor = $customerBunchProcessor;
73
74
        // pass the state detector to the parent constructor
75
        parent::__construct($stateDetector);
76
    }
77
78
    /**
79
     * Return's the customer bunch processor instance.
80
     *
81
     * @return \TechDivision\Import\Customer\Services\CustomerBunchProcessorInterface The customer bunch processor instance
82
     */
83
    protected function getCustomerBunchProcessor()
84
    {
85
        return $this->customerBunchProcessor;
86
    }
87
88
    /**
89
     * Process the observer's business logic.
90
     *
91
     * @return void
92
     */
93
    protected function process()
94
    {
95
96
        // load email and website code
97
        $email = $this->getValue(ColumnKeys::EMAIL);
98
        $website = $this->getValue(ColumnKeys::WEBSITE);
99
100
        // query whether or not, we've found a new SKU => means we've found a new customer
101
        if ($this->hasBeenProcessed(array($email, $website))) {
102
            return;
103
        }
104
105
        // prepare the static entity values
106
        $customer = $this->initializeCustomer($this->prepareAttributes());
107
108
        // insert the entity and set the entity ID
109
        $this->setLastEntityId($this->persistCustomer($customer));
110
    }
111
112
    /**
113
     * Prepare the attributes of the entity that has to be persisted.
114
     *
115
     * @return array The prepared attributes
116
     */
117
    protected function prepareAttributes()
118
    {
119
120
        // initialize the customer values
121
        $email = $this->getValue(ColumnKeys::EMAIL);
122
        $groupId = $this->getValue(ColumnKeys::GROUP_ID);
123
        $storeId = $this->getValue(ColumnKeys::STORE_ID);
124
        $disableAutoGroupChange = $this->getValue(ColumnKeys::DISABLE_AUTO_GROUP_CHANGE);
125
        $prefix = $this->getValue(ColumnKeys::PREFIX);
126
        $firstname = $this->getValue(ColumnKeys::FIRSTNAME);
127
        $middlename = $this->getValue(ColumnKeys::MIDDLENAME);
128
        $lastname = $this->getValue(ColumnKeys::LASTNAME);
129
        $suffix = $this->getValue(ColumnKeys::SUFFIX);
130
        $passwordHash = $this->getValue(ColumnKeys::PASSWORD_HASH);
131
        $rpToken = $this->getValue(ColumnKeys::RP_TOKEN);
132
        $defaultShipping = $this->getValue(ColumnKeys::ADDRESS_DEFAULT_SHIPPING);
133
        $defaultBilling = $this->getValue(ColumnKeys::ADDRESS_DEFAULT_BILLING);
134
        $taxvat = $this->getValue(ColumnKeys::TAXVAT);
135
        $confirmation = $this->getValue(ColumnKeys::CONFIRMATION);
136
        $gender = $this->getGenderByValue($this->getValue(ColumnKeys::GENDER));
137
138
        // load the store id if a store code is present in the current row
139
        if (($storeCode = $this->getValue(ColumnKeys::STORE))) {
140
            $storeId = $this->getStoreIdByCode($storeCode);
141
        }
142
143
        // throw exception if neither the store id nor the store code are available
144
        if ($storeId === null) {
145
            throw new \Exception(
146
                sprintf(
147
                    'Expected value for either _store or store_id, none found in file %s on line %d',
148
                    $this->getFilename(),
149
                    $this->getLineNumber()
150
                )
151
            );
152
        }
153
154
        // load the customer's additional attributes
155
        $createdIn = $this->getValue(ColumnKeys::CREATED_IN);
156
        $incrementId = null;
157
        $isActive = 1;
158
        $failuresNum = 0;
159
        $firstFailure = null;
160
        $lockExpires = null;
161
162
        // prepare the date format for the created at/updated at dates
163
        $websiteId = $this->getStoreWebsiteIdByCode($this->getValue(ColumnKeys::WEBSITE));
164
        $dob = $this->getValue(ColumnKeys::DOB, date('Y-m-d H:i:s'), array($this, 'formatDate'));
165
        $createdAt = $this->getValue(ColumnKeys::CREATED_AT, date('Y-m-d H:i:s'), array($this, 'formatDate'));
166
        $updatedAt = $this->getValue(ColumnKeys::UPDATED_AT, date('Y-m-d H:i:s'), array($this, 'formatDate'));
167
        $rpTokenCreatedAt = $this->getValue(ColumnKeys::RP_TOKEN_CREATED_AT, date('Y-m-d H:i:s'), array($this, 'formatDate'));
168
169
        // return the prepared customer
170
        return $this->initializeEntity(
171
            $this->loadRawEntity(
172
                array(
173
                    MemberNames::WEBSITE_ID                => $websiteId,
174
                    MemberNames::EMAIL                     => $email,
175
                    MemberNames::GROUP_ID                  => $groupId,
176
                    MemberNames::INCREMENT_ID              => $incrementId,
177
                    MemberNames::STORE_ID                  => $storeId,
178
                    MemberNames::CREATED_AT                => $createdAt,
179
                    MemberNames::UPDATED_AT                => $updatedAt,
180
                    MemberNames::IS_ACTIVE                 => $isActive,
181
                    MemberNames::DISABLE_AUTO_GROUP_CHANGE => $disableAutoGroupChange,
182
                    MemberNames::CREATED_IN                => $createdIn,
183
                    MemberNames::PREFIX                    => $prefix,
184
                    MemberNames::FIRSTNAME                 => $firstname,
185
                    MemberNames::MIDDLENAME                => $middlename,
186
                    MemberNames::LASTNAME                  => $lastname,
187
                    MemberNames::SUFFIX                    => $suffix,
188
                    MemberNames::DOB                       => $dob,
189
                    MemberNames::PASSWORD_HASH             => $passwordHash,
190
                    MemberNames::RP_TOKEN                  => $rpToken,
191
                    MemberNames::RP_TOKEN_CREATED_AT       => $rpTokenCreatedAt,
192
                    MemberNames::DEFAULT_BILLING           => $defaultBilling,
193
                    MemberNames::DEFAULT_SHIPPING          => $defaultShipping,
194
                    MemberNames::TAXVAT                    => $taxvat,
195
                    MemberNames::CONFIRMATION              => $confirmation,
196
                    MemberNames::GENDER                    => $gender,
197
                    MemberNames::FAILURES_NUM              => $failuresNum,
198
                    MemberNames::FIRST_FAILURE             => $firstFailure,
199
                    MemberNames::LOCK_EXPIRES              => $lockExpires
200
                )
201
            )
202
        );
203
    }
204
205
    /**
206
     * Load's and return's a raw customer entity without primary key but the mandatory members only and nulled values.
207
     *
208
     * @param array $data An array with data that will be used to initialize the raw entity with
209
     *
210
     * @return array The initialized entity
211
     */
212
    protected function loadRawEntity(array $data = array())
213
    {
214
        return $this->getCustomerBunchProcessor()->loadRawEntity(EntityTypeCodes::CUSTOMER, $data);
215
    }
216
217
    /**
218
     * Initialize the customer with the passed attributes and returns an instance.
219
     *
220
     * @param array $attr The customer attributes
221
     *
222
     * @return array The initialized customer
223
     */
224
    protected function initializeCustomer(array $attr)
225
    {
226
227
        // load the customer with the passed SKU and merge it with the attributes
228
        if ($entity = $this->loadCustomerByEmailAndWebsiteId($attr[MemberNames::EMAIL], $attr[MemberNames::WEBSITE_ID])) {
229
            return $this->mergeEntity($entity, $attr);
230
        }
231
232
        // otherwise simply return the attributes
233
        return $attr;
234
    }
235
236
    /**
237
     * Return's the gender ID for the passed value.
238
     *
239
     * @param string $value The value to return the gender ID for
240
     *
241
     * @return integer The gender ID
242
     * @throws \Exception Is thrown, if the gender ID with the requested value is not available
243
     */
244
    protected function getGenderByValue($value)
245
    {
246
247
        // query whether or not, the requested gender ID is available
248
        if (isset($this->availableGenders[$value])) {
249
            return (integer) $this->availableGenders[$value];
250
        }
251
252
        // allow null values and empty strings
253
        if ($value === null || $value === '') {
254
            return null;
255
        }
256
257
        // throw an exception, if not
258
        throw new \Exception(
259
            $this->appendExceptionSuffix(
260
                sprintf('Found invalid gender %s', $value)
261
            )
262
        );
263
    }
264
265
    /**
266
     * Returns the store id for the specified store code.
267
     *
268
     * @param string $code The store code
269
     *
270
     * @return integer The store id
271
     */
272
    protected function getStoreIdByCode($code)
273
    {
274
        return $this->getSubject()->getStoreId($code);
275
    }
276
277
    /**
278
     * Return's the store website for the passed code.
279
     *
280
     * @param string $code The code of the store website to return the ID for
281
     *
282
     * @return integer The store website ID
283
     */
284
    protected function getStoreWebsiteIdByCode($code)
285
    {
286
        return $this->getSubject()->getStoreWebsiteIdByCode($code);
287
    }
288
289
    /**
290
     * Return's the customer with the passed email and website ID.
291
     *
292
     * @param string $email     The email of the customer to return
293
     * @param string $websiteId The website ID of the customer to return
294
     *
295
     * @return array|null The customer
296
     */
297
    protected function loadCustomerByEmailAndWebsiteId($email, $websiteId)
298
    {
299
        return $this->getCustomerBunchProcessor()->loadCustomerByEmailAndWebsiteId($email, $websiteId);
300
    }
301
302
    /**
303
     * Persist's the passed customer data and return's the ID.
304
     *
305
     * @param array $customer The customer data to persist
306
     *
307
     * @return string The ID of the persisted entity
308
     */
309
    protected function persistCustomer($customer)
310
    {
311
        return $this->getCustomerBunchProcessor()->persistCustomer($customer);
312
    }
313
314
    /**
315
     * Return's the attribute set of the product that has to be created.
316
     *
317
     * @return array The attribute set
318
     */
319
    protected function getAttributeSet()
320
    {
321
        return $this->getSubject()->getAttributeSet();
322
    }
323
324
    /**
325
     * Set's the ID of the customer that has been created recently.
326
     *
327
     * @param string $lastEntityId The entity ID
328
     *
329
     * @return void
330
     */
331
    protected function setLastEntityId($lastEntityId)
332
    {
333
        $this->getSubject()->setLastEntityId($lastEntityId);
334
    }
335
}
336