Completed
Push — master ( c10067...263f81 )
by Aimeos
01:26
created

Typo3::saveItem()   D

Complexity

Conditions 9
Paths 349

Size

Total Lines 183

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 183
rs 4.2877
c 0
b 0
f 0
cc 9
nc 349
nop 2

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Metaways Infosystems GmbH, 2011
6
 * @copyright Aimeos (aimeos.org), 2014-2017
7
 * @package MShop
8
 * @subpackage Customer
9
 */
10
11
12
namespace Aimeos\MShop\Customer\Manager;
13
14
15
/**
16
 * Typo3 implementation of the customer class.
17
 *
18
 * @package MShop
19
 * @subpackage Customer
20
 */
21
class Typo3
22
	extends \Aimeos\MShop\Customer\Manager\Standard
23
{
24
	private $searchConfig = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
25
		// customer.siteid is only for informational purpuse, not for filtering
26
		'customer.id' => array(
27
			'label' => 'Customer ID',
28
			'code' => 'customer.id',
29
			'internalcode' => 't3feu."uid"',
30
			'type' => 'integer',
31
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_INT,
32
			'public' => false,
33
		),
34
		'customer.code' => array(
35
			'label' => 'Customer username',
36
			'code' => 'customer.code',
37
			'internalcode' => 't3feu."username"',
38
			'type' => 'string',
39
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR
40
		),
41
		'customer.label' => array(
42
			'label' => 'Customer name',
43
			'code' => 'customer.label',
44
			'internalcode' => 't3feu."name"',
45
			'type' => 'string',
46
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR
47
		),
48
		'customer.salutation' => array(
49
			'label' => 'Customer salutation',
50
			'code' => 'customer.salutation',
51
			'internalcode' => 't3feu."gender"',
52
			'type' => 'string',
53
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
54
		),
55
		'customer.company'=> array(
56
			'label' => 'Customer company',
57
			'code' => 'customer.company',
58
			'internalcode' => 't3feu."company"',
59
			'type' => 'string',
60
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
61
		),
62
		'customer.vatid'=> array(
63
			'label' => 'Customer VAT ID',
64
			'code' => 'customer.vatid',
65
			'internalcode' => 't3feu."vatid"',
66
			'type' => 'string',
67
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
68
		),
69
		'customer.title' => array(
70
			'label' => 'Customer title',
71
			'code' => 'customer.title',
72
			'internalcode' => 't3feu."title"',
73
			'type' => 'string',
74
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
75
		),
76
		'customer.firstname' => array(
77
			'label' => 'Customer firstname',
78
			'code' => 'customer.firstname',
79
			'internalcode' => 't3feu."first_name"',
80
			'type' => 'string',
81
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
82
		),
83
		'customer.lastname' => array(
84
			'label' => 'Customer lastname',
85
			'code' => 'customer.lastname',
86
			'internalcode' => 't3feu."last_name"',
87
			'type' => 'string',
88
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
89
		),
90
		'customer.address1' => array(
91
			'label' => 'Customer address part one',
92
			'code' => 'customer.address1',
93
			'internalcode' => 't3feu."address"',
94
			'type' => 'string',
95
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
96
		),
97
		'customer.address2' => array(
98
			'label' => 'Customer address part two',
99
			'code' => 'customer.address2',
100
			'internalcode' => 't3feu."address"',
101
			'type' => 'string',
102
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
103
		),
104
		'customer.address3' => array(
105
			'label' => 'Customer address part three',
106
			'code' => 'customer.address3',
107
			'internalcode' => 't3feu."address"',
108
			'type' => 'string',
109
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
110
		),
111
		'customer.postal' => array(
112
			'label' => 'Customer postal',
113
			'code' => 'customer.postal',
114
			'internalcode' => 't3feu."zip"',
115
			'type' => 'string',
116
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
117
		),
118
		'customer.city' => array(
119
			'label' => 'Customer city',
120
			'code' => 'customer.city',
121
			'internalcode' => 't3feu."city"',
122
			'type' => 'string',
123
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
124
		),
125
		'customer.state' => array(
126
			'label' => 'Customer state',
127
			'code' => 'customer.state',
128
			'internalcode' => 't3feu."zone"',
129
			'type' => 'string',
130
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
131
		),
132
		'customer.languageid' => array(
133
			'label' => 'Customer language',
134
			'code' => 'customer.languageid',
135
			'internalcode' => 't3feu."language"',
136
			'type' => 'string',
137
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
138
		),
139
		'customer.countryid' => array(
140
			'label' => 'Customer country',
141
			'code' => 'customer.countryid',
142
			'internalcode' => 'tsc."cn_iso_2"',
143
			'type' => 'string',
144
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
145
		),
146
		'customer.telephone' => array(
147
			'label' => 'Customer telephone',
148
			'code' => 'customer.telephone',
149
			'internalcode' => 't3feu."telephone"',
150
			'type' => 'string',
151
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
152
		),
153
		'customer.email' => array(
154
			'label' => 'Customer email',
155
			'code' => 'customer.email',
156
			'internalcode' => 't3feu."email"',
157
			'type' => 'string',
158
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
159
		),
160
		'customer.telefax' => array(
161
			'label' => 'Customer telefax',
162
			'code' => 'customer.telefax',
163
			'internalcode' => 't3feu."fax"',
164
			'type' => 'string',
165
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
166
		),
167
		'customer.website' => array(
168
			'label' => 'Customer website',
169
			'code' => 'customer.website',
170
			'internalcode' => 't3feu."www"',
171
			'type' => 'string',
172
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
173
		),
174
		'customer.longitude' => array(
175
			'label' => 'Customer longitude',
176
			'code' => 'customer.longitude',
177
			'internalcode' => 't3feu."longitude"',
178
			'type' => 'string',
179
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
180
		),
181
		'customer.latitude' => array(
182
			'label' => 'Customer latitude',
183
			'code' => 'customer.latitude',
184
			'internalcode' => 't3feu."latitude"',
185
			'type' => 'string',
186
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
187
		),
188
		'customer.birthday' => array(
189
			'label' => 'Customer birthday',
190
			'code' => 'customer.birthday',
191
			'internalcode' => 't3feu."date_of_birth"',
192
			'type' => 'string',
193
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
194
		),
195
		'customer.password'=> array(
196
			'label' => 'Customer password',
197
			'code' => 'customer.password',
198
			'internalcode' => 't3feu."password"',
199
			'type' => 'string',
200
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
201
		),
202
		'customer.status'=> array(
203
			'label' => 'Customer status',
204
			'code' => 'customer.status',
205
			'internalcode' => 't3feu."disable"',
206
			'type' => 'integer',
207
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_INT
208
		),
209
		'customer.dateverified'=> array(
210
			'label' => 'Customer verification date',
211
			'code' => 'customer.dateverified',
212
			'internalcode' => 't3feu."vdate"',
213
			'type' => 'date',
214
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
215
		),
216
		'customer.ctime'=> array(
217
			'label' => 'Customer creation time',
218
			'code' => 'customer.ctime',
219
			'internalcode' => 't3feu."crdate"',
220
			'type' => 'datetime',
221
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
222
		),
223
		'customer.mtime'=> array(
224
			'label' => 'Customer modification time',
225
			'code' => 'customer.mtime',
226
			'internalcode' => 't3feu."tstamp"',
227
			'type' => 'datetime',
228
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
229
		),
230
		// not available
231
		'customer.editor'=> array(
232
			'label'=>'Customer editor',
233
			'code'=>'customer.editor',
234
			'internalcode'=>'1',
235
			'type'=> 'string',
236
			'internaltype'=> \Aimeos\MW\DB\Statement\Base::PARAM_STR,
237
		),
238
	);
239
240
	private $plugins = [];
241
	private $reverse = [];
242
	private $helper;
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
243
	private $pid;
244
245
246
247
	/**
248
	 * Initializes a new customer manager object using the given context object.
249
	 *
250
	 * @param \Aimeos\MShop\Context\Iface $context Context object with required objects
251
	 */
252
	public function __construct( \Aimeos\MShop\Context\Item\Iface $context )
253
	{
254
		parent::__construct( $context );
255
256
		$plugin = new \Aimeos\MW\Criteria\Plugin\T3Salutation();
257
		$this->plugins['customer.salutation'] = $this->reverse['gender'] = $plugin;
258
259
		$plugin = new \Aimeos\MW\Criteria\Plugin\T3Status();
260
		$this->plugins['customer.status'] = $this->reverse['disable'] = $plugin;
261
262
		$plugin = new \Aimeos\MW\Criteria\Plugin\T3Date();
263
		$this->plugins['customer.birthday'] = $this->reverse['date_of_birth'] = $plugin;
264
265
		$plugin = new \Aimeos\MW\Criteria\Plugin\T3Datetime();
266
		$this->plugins['customer.ctime'] = $this->reverse['crdate'] = $plugin;
267
		$this->plugins['customer.mtime'] = $this->reverse['tstamp'] = $plugin;
268
269
		$this->pid = $context->getConfig()->get( 'mshop/customer/manager/typo3/pid-default', 0 );
270
	}
271
272
273
	/**
274
	 * Returns the list attributes that can be used for searching.
275
	 *
276
	 * @param boolean $withsub Return also attributes of sub-managers if true
277
	 * @return array List of attribute items implementing \Aimeos\MW\Criteria\Attribute\Iface
278
	 */
279
	public function getSearchAttributes( $withsub = true )
280
	{
281
		$path = 'mshop/customer/manager/submanagers';
282
		$default = ['address', 'group', 'lists', 'property'];
283
284
		return $this->getSearchAttributesBase( $this->searchConfig, $path, $default, $withsub );
285
	}
286
287
288
	/**
289
	 * Removes old entries from the storage.
290
	 *
291
	 * @param array $siteids List of IDs for sites whose entries should be deleted
292
	 */
293
	public function cleanup( array $siteids )
294
	{
295
		$path = 'mshop/customer/manager/submanagers';
296
		$default = ['address', 'group', 'lists', 'property'];
297
298
		foreach( $this->getContext()->getConfig()->get( $path, $default ) as $domain ) {
299
			$this->getObject()->getSubManager( $domain )->cleanup( $siteids );
300
		}
301
	}
302
303
304
	/**
305
	 * Creates a new empty item instance
306
	 *
307
	 * @param string|null Type the item should be created with
308
	 * @param string|null Domain of the type the item should be created with
309
	 * @return \Aimeos\MShop\Common\Item\Site\Iface New site item object
310
	 */
311
	public function createItem( $type = null, $domain = null )
312
	{
313
		$values = ['customer.siteid' => $this->getContext()->getLocale()->getSiteId(), 'typo3.pageid' => $this->pid];
314
		return $this->createItemBase( $values );
315
	}
316
317
318
	/**
319
	 * Deletes a customer item object from the permanent storage.
320
	 *
321
	 * @param array $ids List of customer IDs
322
	 */
323
	public function deleteItems( array $ids )
324
	{
325
		$path = 'mshop/customer/manager/typo3/delete';
326
		$this->deleteItemsBase( $ids, $path, false, 'uid' );
327
	}
328
329
330
	/**
331
	 * Saves a customer item object.
332
	 *
333
	 * @param \Aimeos\MShop\Customer\Item\Iface $item Customer item object
334
	 * @param boolean $fetch True if the new ID should be returned in the item
335
	 * @return \Aimeos\MShop\Common\Item\Iface $item Updated item including the generated ID
336
	 */
337
	public function saveItem( \Aimeos\MShop\Common\Item\Iface $item, $fetch = true )
338
	{
339
		self::checkClass( '\\Aimeos\\MShop\\Customer\\Item\\Iface', $item );
0 ignored issues
show
Bug introduced by
The method checkClass() does not seem to exist on object<Aimeos\MShop\Customer\Manager\Typo3>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
340
341
		if( !$item->isModified() )
342
		{
343
			$item = $this->savePropertyItems( $item, 'customer' );
0 ignored issues
show
Documentation Bug introduced by
The method savePropertyItems does not exist on object<Aimeos\MShop\Customer\Manager\Typo3>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
344
			$item = $this->saveAddressItems( $item, 'customer' );
0 ignored issues
show
Documentation Bug introduced by
The method saveAddressItems does not exist on object<Aimeos\MShop\Customer\Manager\Typo3>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
345
			return $this->saveListItems( $item, 'customer' );
0 ignored issues
show
Documentation Bug introduced by
The method saveListItems does not exist on object<Aimeos\MShop\Customer\Manager\Typo3>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
346
		}
347
348
		$context = $this->getContext();
349
		$dbm = $context->getDatabaseManager();
350
		$dbname = $this->getResourceName();
351
		$conn = $dbm->acquire( $dbname );
352
353
		try
354
		{
355
			$id = $item->getId();
356
			$billingAddress = $item->getPaymentAddress();
357
358
			if( $id === null )
359
			{
360
				/** mshop/customer/manager/typo3/insert
361
				 * Inserts a new customer record into the database table
362
				 *
363
				 * Items with no ID yet (i.e. the ID is NULL) will be created in
364
				 * the database and the newly created ID retrieved afterwards
365
				 * using the "newid" SQL statement.
366
				 *
367
				 * The SQL statement must be a string suitable for being used as
368
				 * prepared statement. It must include question marks for binding
369
				 * the values from the customer item to the statement before they are
370
				 * sent to the database server. The number of question marks must
371
				 * be the same as the number of columns listed in the INSERT
372
				 * statement. The order of the columns must correspond to the
373
				 * order in the saveItems() method, so the correct values are
374
				 * bound to the columns.
375
				 *
376
				 * The SQL statement should conform to the ANSI standard to be
377
				 * compatible with most relational database systems. This also
378
				 * includes using double quotes for table and column names.
379
				 *
380
				 * @param string SQL statement for inserting records
381
				 * @since 2014.03
382
				 * @category Developer
383
				 * @see mshop/customer/manager/typo3/update
384
				 * @see mshop/customer/manager/typo3/newid
385
				 * @see mshop/customer/manager/typo3/delete
386
				 * @see mshop/customer/manager/typo3/search
387
				 * @see mshop/customer/manager/typo3/count
388
				 */
389
				$path = 'mshop/customer/manager/typo3/insert';
390
			}
391
			else
392
			{
393
				/** mshop/customer/manager/typo3/update
394
				 * Updates an existing customer record in the database
395
				 *
396
				 * Items which already have an ID (i.e. the ID is not NULL) will
397
				 * be updated in the database.
398
				 *
399
				 * The SQL statement must be a string suitable for being used as
400
				 * prepared statement. It must include question marks for binding
401
				 * the values from the customer item to the statement before they are
402
				 * sent to the database server. The order of the columns must
403
				 * correspond to the order in the saveItems() method, so the
404
				 * correct values are bound to the columns.
405
				 *
406
				 * The SQL statement should conform to the ANSI standard to be
407
				 * compatible with most relational database systems. This also
408
				 * includes using double quotes for table and column names.
409
				 *
410
				 * @param string SQL statement for updating records
411
				 * @since 2014.03
412
				 * @category Developer
413
				 * @see mshop/customer/manager/typo3/insert
414
				 * @see mshop/customer/manager/typo3/newid
415
				 * @see mshop/customer/manager/typo3/delete
416
				 * @see mshop/customer/manager/typo3/search
417
				 * @see mshop/customer/manager/typo3/count
418
				 */
419
				$path = 'mshop/customer/manager/typo3/update';
420
			}
421
422
			$stmt = $this->getCachedStatement( $conn, $path );
423
424
			$address = $billingAddress->getAddress1();
425
426
			if( ( $part = $billingAddress->getAddress2() ) != '' ) {
427
				$address .= ' ' . $part;
428
			}
429
430
			if( ( $part = $billingAddress->getAddress3() ) != '' ) {
431
				$address .= ' ' . $part;
432
			}
433
434
			// TYPO3 fe_users.static_info_country is a three letter ISO code instead a two letter one
435
			$stmt->bind( 1, $context->getLocale()->getSiteId(), \Aimeos\MW\DB\Statement\Base::PARAM_INT );
436
			$stmt->bind( 2, $item->getLabel() );
437
			$stmt->bind( 3, $item->getCode() );
438
			$stmt->bind( 4, $this->plugins['customer.salutation']->translate( $billingAddress->getSalutation() ), \Aimeos\MW\DB\Statement\Base::PARAM_INT );
439
			$stmt->bind( 5, $billingAddress->getCompany() );
440
			$stmt->bind( 6, $billingAddress->getVatID() );
441
			$stmt->bind( 7, $billingAddress->getTitle() );
442
			$stmt->bind( 8, $billingAddress->getFirstname() );
443
			$stmt->bind( 9, $billingAddress->getLastname() );
444
			$stmt->bind( 10, $address );
445
			$stmt->bind( 11, $billingAddress->getPostal() );
446
			$stmt->bind( 12, $billingAddress->getCity() );
447
			$stmt->bind( 13, $billingAddress->getState() );
448
			$stmt->bind( 14, $billingAddress->getLanguageId() );
449
			$stmt->bind( 15, $billingAddress->getTelephone() );
450
			$stmt->bind( 16, $billingAddress->getEmail() );
451
			$stmt->bind( 17, $billingAddress->getTelefax() );
452
			$stmt->bind( 18, $billingAddress->getWebsite() );
453
			$stmt->bind( 19, $billingAddress->getLongitude() );
454
			$stmt->bind( 20, $billingAddress->getLatitude() );
455
			$stmt->bind( 21, $this->plugins['customer.birthday']->translate( $item->getBirthday() ), \Aimeos\MW\DB\Statement\Base::PARAM_INT );
456
			$stmt->bind( 22, $this->plugins['customer.status']->translate( $item->getStatus() ), \Aimeos\MW\DB\Statement\Base::PARAM_INT );
457
			$stmt->bind( 23, $item->getPassword() );
458
			$stmt->bind( 24, time(), \Aimeos\MW\DB\Statement\Base::PARAM_INT ); // Modification time
459
			$stmt->bind( 25, $billingAddress->getCountryId() );
460
			$stmt->bind( 26, implode( ',', $item->getGroups() ) );
461
			$stmt->bind( 27, $item->getPageId(), \Aimeos\MW\DB\Statement\Base::PARAM_INT ); // TYPO3 PID value
462
463
			if( $id !== null ) {
464
				$stmt->bind( 28, $id, \Aimeos\MW\DB\Statement\Base::PARAM_INT );
465
				$item->setId( $id );
466
			} else {
467
				$stmt->bind( 28, time(), \Aimeos\MW\DB\Statement\Base::PARAM_INT ); // Creation time
468
			}
469
470
			$stmt->execute()->finish();
471
472
			if( $id === null && $fetch === true )
473
			{
474
				/** mshop/customer/manager/typo3/newid
475
				 * Retrieves the ID generated by the database when inserting a new record
476
				 *
477
				 * As soon as a new record is inserted into the database table,
478
				 * the database server generates a new and unique identifier for
479
				 * that record. This ID can be used for retrieving, updating and
480
				 * deleting that specific record from the table again.
481
				 *
482
				 * For MySQL:
483
				 *  SELECT LAST_INSERT_ID()
484
				 * For PostgreSQL:
485
				 *  SELECT currval('seq_mcus_id')
486
				 * For SQL Server:
487
				 *  SELECT SCOPE_IDENTITY()
488
				 * For Oracle:
489
				 *  SELECT "seq_mcus_id".CURRVAL FROM DUAL
490
				 *
491
				 * There's no way to retrive the new ID by a SQL statements that
492
				 * fits for most database servers as they implement their own
493
				 * specific way.
494
				 *
495
				 * @param string SQL statement for retrieving the last inserted record ID
496
				 * @since 2014.03
497
				 * @category Developer
498
				 * @see mshop/customer/manager/typo3/insert
499
				 * @see mshop/customer/manager/typo3/update
500
				 * @see mshop/customer/manager/typo3/delete
501
				 * @see mshop/customer/manager/typo3/search
502
				 * @see mshop/customer/manager/typo3/count
503
				 */
504
				$path = 'mshop/customer/manager/typo3/newid';
505
				$item->setId( $this->newId( $conn, $path ) );
506
			}
507
508
			$dbm->release( $conn, $dbname );
509
		}
510
		catch( \Exception $e )
511
		{
512
			$dbm->release( $conn, $dbname );
513
			throw $e;
514
		}
515
516
		$item = $this->savePropertyItems( $item, 'customer' );
0 ignored issues
show
Documentation Bug introduced by
The method savePropertyItems does not exist on object<Aimeos\MShop\Customer\Manager\Typo3>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
517
		$item = $this->saveAddressItems( $item, 'customer' );
0 ignored issues
show
Documentation Bug introduced by
The method saveAddressItems does not exist on object<Aimeos\MShop\Customer\Manager\Typo3>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
518
		return $this->saveListItems( $item, 'customer' );
0 ignored issues
show
Documentation Bug introduced by
The method saveListItems does not exist on object<Aimeos\MShop\Customer\Manager\Typo3>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
519
	}
520
521
522
	/**
523
	 * Returns the item objects matched by the given search criteria.
524
	 *
525
	 * @param \Aimeos\MW\Criteria\Iface $search Search criteria object
526
	 * @param integer &$total Number of items that are available in total
527
	 * @return array List of items implementing \Aimeos\MShop\Customer\Item\Iface
528
	 * @throws \Aimeos\MShop\Customer\Exception If creating items failed
529
	 */
530
	public function searchItems( \Aimeos\MW\Criteria\Iface $search, array $ref = [], &$total = null )
531
	{
532
		$dbm = $this->getContext()->getDatabaseManager();
533
		$dbname = $this->getResourceName();
534
		$conn = $dbm->acquire( $dbname );
535
		$map = [];
536
537
		try
538
		{
539
			$level = \Aimeos\MShop\Locale\Manager\Base::SITE_ALL;
540
			$cfgPathSearch = 'mshop/customer/manager/typo3/search';
541
			$cfgPathCount = 'mshop/customer/manager/typo3/count';
542
			$required = array( 'customer' );
543
544
			$results = $this->searchItemsBase( $conn, $search, $cfgPathSearch, $cfgPathCount, $required, $total, $level, $this->plugins );
545
			while( ( $row = $results->fetch() ) !== false ) {
546
				$map[ $row['customer.id'] ] = $row;
547
			}
548
549
			$dbm->release( $conn, $dbname );
550
		}
551
		catch( \Exception $e )
552
		{
553
			$dbm->release( $conn, $dbname  );
554
			throw $e;
555
		}
556
557
		$addrItems = [];
558
		if( in_array( 'customer/address', $ref, true ) ) {
559
			$addrItems = $this->getAddressItems( array_keys( $map ), 'customer' );
0 ignored issues
show
Unused Code introduced by
The call to Typo3::getAddressItems() has too many arguments starting with 'customer'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
560
		}
561
562
		$propItems = [];
563
		if( in_array( 'customer/property', $ref, true ) ) {
564
			$propItems = $this->getPropertyItems( array_keys( $map ), 'customer' );
0 ignored issues
show
Documentation Bug introduced by
The method getPropertyItems does not exist on object<Aimeos\MShop\Customer\Manager\Typo3>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
565
		}
566
567
		return $this->buildItems( $map, $ref, 'customer', $addrItems, $propItems );
0 ignored issues
show
Unused Code introduced by
The call to Typo3::buildItems() has too many arguments starting with $propItems.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
568
	}
569
570
571
	/**
572
	 * Returns a new manager for customer extensions
573
	 *
574
	 * @param string $manager Name of the sub manager type in lower case
575
	 * @param string|null $name Name of the implementation, will be from configuration (or Default) if null
576
	 * @return mixed Manager for different extensions, e.g stock, tags, locations, etc.
577
	 */
578
	public function getSubManager( $manager, $name = null )
579
	{
580
		return $this->getSubManagerBase( 'customer', $manager, ( $name === null ? 'Typo3' : $name ) );
581
	}
582
583
584
	/**
585
	 * Creates a new customer item.
586
	 *
587
	 * @param array $values List of attributes for customer item
588
	 * @param array $listItems List items associated to the customer item
589
	 * @param array $refItems Items referenced by the customer item via the list items
590
	 * @param array $addresses List of address items of the customer item
591
	 * @param array $propItems List of property items of the customer item
592
	 * @return \Aimeos\MShop\Customer\Item\Iface New customer item
593
	 */
594
	protected function createItemBase( array $values = [], array $listItems = [], array $refItems = [],
595
		array $addresses = [], array $propItems = [] )
596
	{
597
		$helper = $this->getPasswordHelper();
598
		$address = $this->getAddressManager()->createItem();
599
		$values['customer.siteid'] = $this->getContext()->getLocale()->getSiteId();
600
601
		if( array_key_exists( 'date_of_birth', $values ) ) {
602
			$values['customer.birthday'] = $this->reverse['date_of_birth']->reverse( $values['date_of_birth'] );
603
		}
604
605
		if( array_key_exists( 'gender', $values ) ) {
606
			$values['customer.salutation'] = $this->reverse['gender']->reverse( $values['gender'] );
607
		}
608
609
		if( array_key_exists( 'disable', $values ) ) {
610
			$values['customer.status'] = $this->reverse['disable']->reverse( $values['disable'] );
611
		}
612
613
		if( array_key_exists( 'tstamp', $values ) ) {
614
			$values['customer.mtime'] = $this->reverse['tstamp']->reverse( $values['tstamp'] );
615
		}
616
617
		if( array_key_exists( 'crdate', $values ) ) {
618
			$values['customer.ctime'] = $this->reverse['crdate']->reverse( $values['crdate'] );
619
		}
620
621
		if( array_key_exists( 'groups', $values ) ) {
622
			$values['groups'] = explode( ',', $values['groups'] );
623
		}
624
625
		return new \Aimeos\MShop\Customer\Item\Typo3(
626
			$address, $values, $listItems, $refItems,
0 ignored issues
show
Compatibility introduced by
$address of type object<Aimeos\MShop\Common\Item\Iface> is not a sub-type of object<Aimeos\MShop\Common\Item\Address\Iface>. It seems like you assume a child interface of the interface Aimeos\MShop\Common\Item\Iface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
627
			null, $helper, $addresses, $propItems
628
		);
629
	}
630
631
632
	/**
633
	 * Returns the address sub-manager.
634
	 *
635
	 * @return \Aimeos\MShop\Common\Manager\Iface Customer address manager
636
	 */
637
	protected function getAddressManager()
638
	{
639
		if( !isset( $this->addressManager ) ) {
0 ignored issues
show
Bug introduced by
The property addressManager cannot be accessed from this context as it is declared private in class Aimeos\MShop\Customer\Manager\Base.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
640
			$this->addressManager = $this->getObject()->getSubManager( 'address' );
0 ignored issues
show
Bug introduced by
The property addressManager cannot be accessed from this context as it is declared private in class Aimeos\MShop\Customer\Manager\Base.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
641
		}
642
643
		return $this->addressManager;
0 ignored issues
show
Bug introduced by
The property addressManager cannot be accessed from this context as it is declared private in class Aimeos\MShop\Customer\Manager\Base.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
644
	}
645
646
647
	/**
648
	 * Returns a password helper object based on the configuration.
649
	 *
650
	 * @return \Aimeos\MShop\Common\Item\Helper\Password\Iface Password helper object
651
	 * @throws \Aimeos\MShop\Exception If the name is invalid or the class isn't found
652
	 */
653
	protected function getPasswordHelper()
654
	{
655
		if( $this->helper ) {
656
			return $this->helper;
657
		}
658
659
		$classname = '\\Aimeos\\MShop\\Common\\Item\\Helper\\Password\\Typo3';
660
661
		if( class_exists( $classname ) === false ) {
662
			throw new \Aimeos\MShop\Exception( sprintf( 'Class "%1$s" not available', $classname ) );
663
		}
664
665
		$context = $this->getContext();
666
		$object = ( method_exists( $context, 'getHasherTypo3' ) ? $context->getHasherTypo3() : null );
667
668
		$helper = new $classname( array( 'object' => $object ) );
669
670
		self::checkClass( '\\Aimeos\\MShop\\Common\\Item\\Helper\\Password\\Iface', $helper );
0 ignored issues
show
Bug introduced by
The method checkClass() does not seem to exist on object<Aimeos\MShop\Customer\Manager\Typo3>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
671
672
		$this->helper = $helper;
673
674
		return $helper;
675
	}
676
}
677