Completed
Push — master ( 95710b...ab3a55 )
by Aimeos
01:54
created

Ezpublish::deleteItems()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2016-2017
6
 * @package MShop
7
 * @subpackage Customer
8
 */
9
10
11
namespace Aimeos\MShop\Customer\Manager;
12
13
14
/**
15
 * Customer class implementation for ezPublish
16
 *
17
 * @package MShop
18
 * @subpackage Customer
19
 */
20
class Ezpublish
21
	extends \Aimeos\MShop\Customer\Manager\Standard
22
{
23
	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...
24
		'customer.id' => array(
25
			'label' => 'Customer ID',
26
			'code' => 'customer.id',
27
			'internalcode' => 'ezu."contentobject_id"',
28
			'type' => 'integer',
29
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_INT
30
		),
31
		// customer.siteid is not available
32
		'customer.label' => array(
33
			'label' => 'Customer label',
34
			'code' => 'customer.label',
35
			'internalcode' => 'ezu."login"',
36
			'type' => 'string',
37
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR
38
		),
39
		'customer.code' => array(
40
			'label' => 'Customer username',
41
			'code' => 'customer.code',
42
			'internalcode' => 'ezu."login_normalized"',
43
			'type' => 'string',
44
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR
45
		),
46
		'customer.salutation' => array(
47
			'label' => 'Customer salutation',
48
			'code' => 'customer.salutation',
49
			'internalcode' => 'ezu."salutation"',
50
			'type' => 'string',
51
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
52
		),
53
		'customer.company'=> array(
54
			'label' => 'Customer company',
55
			'code' => 'customer.company',
56
			'internalcode' => 'ezu."company"',
57
			'type' => 'string',
58
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
59
		),
60
		'customer.vatid'=> array(
61
			'label' => 'Customer VAT ID',
62
			'code' => 'customer.vatid',
63
			'internalcode' => 'ezu."vatid"',
64
			'type' => 'string',
65
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
66
		),
67
		'customer.title' => array(
68
			'label' => 'Customer title',
69
			'code' => 'customer.title',
70
			'internalcode' => 'ezu."title"',
71
			'type' => 'string',
72
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
73
		),
74
		'customer.firstname' => array(
75
			'label' => 'Customer firstname',
76
			'code' => 'customer.firstname',
77
			'internalcode' => 'ezu."firstname"',
78
			'type' => 'string',
79
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
80
		),
81
		'customer.lastname' => array(
82
			'label' => 'Customer lastname',
83
			'code' => 'customer.lastname',
84
			'internalcode' => 'ezu."lastname"',
85
			'type' => 'string',
86
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
87
		),
88
		'customer.address1' => array(
89
			'label' => 'Customer address part one',
90
			'code' => 'customer.address1',
91
			'internalcode' => 'ezu."address1"',
92
			'type' => 'string',
93
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
94
		),
95
		'customer.address2' => array(
96
			'label' => 'Customer address part two',
97
			'code' => 'customer.address2',
98
			'internalcode' => 'ezu."address2"',
99
			'type' => 'string',
100
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
101
		),
102
		'customer.address3' => array(
103
			'label' => 'Customer address part three',
104
			'code' => 'customer.address3',
105
			'internalcode' => 'ezu."address3"',
106
			'type' => 'string',
107
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
108
		),
109
		'customer.postal' => array(
110
			'label' => 'Customer postal',
111
			'code' => 'customer.postal',
112
			'internalcode' => 'ezu."postal"',
113
			'type' => 'string',
114
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
115
		),
116
		'customer.city' => array(
117
			'label' => 'Customer city',
118
			'code' => 'customer.city',
119
			'internalcode' => 'ezu."city"',
120
			'type' => 'string',
121
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
122
		),
123
		'customer.state' => array(
124
			'label' => 'Customer state',
125
			'code' => 'customer.state',
126
			'internalcode' => 'ezu."state"',
127
			'type' => 'string',
128
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
129
		),
130
		'customer.languageid' => array(
131
			'label' => 'Customer language',
132
			'code' => 'customer.languageid',
133
			'internalcode' => 'ezu."langid"',
134
			'type' => 'string',
135
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
136
		),
137
		'customer.countryid' => array(
138
			'label' => 'Customer country',
139
			'code' => 'customer.countryid',
140
			'internalcode' => 'ezu."countryid"',
141
			'type' => 'string',
142
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
143
		),
144
		'customer.telephone' => array(
145
			'label' => 'Customer telephone',
146
			'code' => 'customer.telephone',
147
			'internalcode' => 'ezu."telephone"',
148
			'type' => 'string',
149
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
150
		),
151
		'customer.email' => array(
152
			'label' => 'Customer email',
153
			'code' => 'customer.email',
154
			'internalcode' => 'ezu."email"',
155
			'type' => 'string',
156
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
157
		),
158
		'customer.telefax' => array(
159
			'label' => 'Customer telefax',
160
			'code' => 'customer.telefax',
161
			'internalcode' => 'ezu."telefax"',
162
			'type' => 'string',
163
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
164
		),
165
		'customer.website' => array(
166
			'label' => 'Customer website',
167
			'code' => 'customer.website',
168
			'internalcode' => 'ezu."website"',
169
			'type' => 'string',
170
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
171
		),
172
		'customer.birthday' => array(
173
			'label' => 'Customer birthday',
174
			'code' => 'customer.birthday',
175
			'internalcode' => 'ezu."birthday"',
176
			'type' => 'string',
177
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
178
		),
179
		'customer.password'=> array(
180
			'label' => 'Customer password',
181
			'code' => 'customer.password',
182
			'internalcode' => 'ezu."password_hash"',
183
			'type' => 'string',
184
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
185
		),
186
		'customer.status'=> array(
187
			'label' => 'Customer status',
188
			'code' => 'customer.status',
189
			'internalcode' => 'ezs."is_enabled"',
190
			'type' => 'integer',
191
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_INT
192
		),
193
		'customer.dateverified'=> array(
194
			'label' => 'Customer verification date',
195
			'code' => 'customer.dateverified',
196
			'internalcode' => 'ezu."vdate"',
197
			'type' => 'date',
198
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
199
		),
200
		'customer.ctime'=> array(
201
			'label' => 'Customer creation time',
202
			'code' => 'customer.ctime',
203
			'internalcode' => 'ezu."ctime"',
204
			'type' => 'datetime',
205
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
206
		),
207
		'customer.mtime'=> array(
208
			'label' => 'Customer modification time',
209
			'code' => 'customer.mtime',
210
			'internalcode' => 'ezu."mtime"',
211
			'type' => 'datetime',
212
			'internaltype' => \Aimeos\MW\DB\Statement\Base::PARAM_STR,
213
		),
214
		'customer.editor'=> array(
215
			'label'=>'Customer editor',
216
			'code'=>'customer.editor',
217
			'internalcode' => 'ezu."editor"',
218
			'type'=> 'string',
219
			'internaltype'=> \Aimeos\MW\DB\Statement\Base::PARAM_STR,
220
		),
221
	);
222
223
	private $addressManager;
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...
224
225
226
	/**
227
	 * Removes old entries from the storage.
228
	 *
229
	 * @param array $siteids List of IDs for sites whose entries should be deleted
230
	 */
231
	public function cleanup( array $siteids )
232
	{
233
		$path = 'mshop/customer/manager/submanagers';
234
		foreach( $this->getContext()->getConfig()->get( $path, ['address', 'group', 'lists', 'property'] ) as $domain ) {
235
			$this->getObject()->getSubManager( $domain )->cleanup( $siteids );
236
		}
237
	}
238
239
240
	/**
241
	 * Removes multiple items specified by ids in the array.
242
	 *
243
	 * @param array $ids List of IDs
244
	 */
245
	public function deleteItems( array $ids )
246
	{
247
		$service = $this->getContext()->getEzUserService();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\MShop\Context\Item\Iface as the method getEzUserService() does only exist in the following implementations of said interface: Aimeos\MShop\Context\Item\Ezpublish.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
248
249
		foreach( $ids as $id ) {
250
			$service->deleteUser( $service->loadUser( $id ) );
251
		}
252
	}
253
254
255
	/**
256
	 * Returns the list attributes that can be used for searching.
257
	 *
258
	 * @param boolean $withsub Return also attributes of sub-managers if true
259
	 * @return array List of attribute items implementing \Aimeos\MW\Criteria\Attribute\Iface
260
	 */
261
	public function getSearchAttributes( $withsub = true )
262
	{
263
		$path = 'mshop/customer/manager/submanagers';
264
265
		return $this->getSearchAttributesBase( $this->searchConfig, $path, ['address', 'group', 'lists', 'property'], $withsub );
266
	}
267
268
269
	/**
270
	 * Returns a new manager for customer extensions
271
	 *
272
	 * @param string $manager Name of the sub manager type in lower case
273
	 * @param string|null $name Name of the implementation, will be from configuration (or Default) if null
274
	 * @return mixed Manager for different extensions, e.g stock, tags, locations, etc.
275
	 */
276
	public function getSubManager( $manager, $name = null )
277
	{
278
		return $this->getSubManagerBase( 'customer', $manager, ( $name === null ? 'Ezpublish' : $name ) );
279
	}
280
281
282
	/**
283
	 * Saves a customer item object.
284
	 *
285
	 * @param \Aimeos\MShop\Customer\Item\Iface $item Customer item object
286
	 * @param boolean $fetch True if the new ID should be returned in the item
287
	 * @return \Aimeos\MShop\Common\Item\Iface $item Updated item including the generated ID
288
	 */
289
	public function saveItem( \Aimeos\MShop\Common\Item\Iface $item, $fetch = true )
290
	{
291
		$iface = '\\Aimeos\\MShop\\Customer\\Item\\Iface';
292
		if( !( $item instanceof $iface ) ) {
293
			throw new \Aimeos\MShop\Customer\Exception( sprintf( 'Object is not of required type "%1$s"', $iface ) );
294
		}
295
296
		if( !$item->isModified() )
297
		{
298
			$item = $this->savePropertyItems( $item, 'customer' );
0 ignored issues
show
Documentation introduced by
$item is of type object<Aimeos\MShop\Common\Item\Iface>, but the function expects a object<Aimeos\MShop\Comm...Item\PropertyRef\Iface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
299
			$item = $this->saveAddressItems( $item, 'customer' );
0 ignored issues
show
Documentation introduced by
$item is of type object<Aimeos\MShop\Comm...Item\PropertyRef\Iface>, but the function expects a object<Aimeos\MShop\Common\Item\AddressRef\Iface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
300
			return $this->saveListItems( $item, 'customer' );
0 ignored issues
show
Documentation introduced by
$item is of type object<Aimeos\MShop\Common\Item\AddressRef\Iface>, but the function expects a object<Aimeos\MShop\Common\Item\ListRef\Iface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
301
		}
302
303
		$context = $this->getContext();
304
305
		$class = '\Aimeos\MShop\Context\Item\Ezpublish';
306
		if( !is_a( $context, $class ) ) {
307
			throw new \Aimeos\MShop\Customer\Exception( sprintf( 'Object is not of required type "%1$s"', $class ) );
308
		}
309
310
		$service = $context->getEzUserService();
311
		$email = $item->getPaymentAddress()->getEmail();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\MShop\Common\Item\Iface as the method getPaymentAddress() does only exist in the following implementations of said interface: Aimeos\MShop\Customer\Item\Base, Aimeos\MShop\Customer\Item\Ezpublish, Aimeos\MShop\Customer\Item\Standard.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
312
313
		if( $item->getId() !== null )
314
		{
315
			$struct = $service->newUserUpdateStruct();
316
			$struct->password = $item->getPassword();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\MShop\Common\Item\Iface as the method getPassword() does only exist in the following implementations of said interface: Aimeos\MShop\Customer\Item\Base, Aimeos\MShop\Customer\Item\Ezpublish, Aimeos\MShop\Customer\Item\Standard.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
317
			$struct->enabled = $item->getStatus();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\MShop\Common\Item\Iface as the method getStatus() does only exist in the following implementations of said interface: Aimeos\MAdmin\Job\Item\Standard, Aimeos\MShop\Attribute\Item\Standard, Aimeos\MShop\Catalog\Item\Standard, Aimeos\MShop\Common\Item\Lists\Standard, Aimeos\MShop\Common\Item\Type\Standard, Aimeos\MShop\Coupon\Item\Standard, Aimeos\MShop\Customer\Item\Base, Aimeos\MShop\Customer\Item\Ezpublish, Aimeos\MShop\Customer\Item\Standard, Aimeos\MShop\Locale\Item\Currency\Standard, Aimeos\MShop\Locale\Item\Language\Standard, Aimeos\MShop\Locale\Item\Site\Standard, Aimeos\MShop\Locale\Item\Standard, Aimeos\MShop\Media\Item\Standard, Aimeos\MShop\Order\Item\Base\Base, Aimeos\MShop\Order\Item\Base\Product\Base, Aimeos\MShop\Order\Item\Base\Product\Standard, Aimeos\MShop\Order\Item\Base\Standard, Aimeos\MShop\Plugin\Item\Standard, Aimeos\MShop\Price\Item\Base, Aimeos\MShop\Price\Item\Standard, Aimeos\MShop\Product\Item\Standard, Aimeos\MShop\Service\Item\Standard, Aimeos\MShop\Subscription\Item\Standard, Aimeos\MShop\Supplier\Item\Standard, Aimeos\MShop\Text\Item\Standard.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
318
			$struct->email = $email;
319
320
			$user = $service->loadUser( $item->getId() );
321
			$service->updateUser( $user, $struct );
322
		}
323
		else
324
		{
325
			$struct = $service->newUserCreateStruct( $item->getCode(), $email, $item->getPassword(), 'eng-GB' );
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\MShop\Common\Item\Iface as the method getCode() does only exist in the following implementations of said interface: Aimeos\MShop\Attribute\Item\Standard, Aimeos\MShop\Catalog\Item\Standard, Aimeos\MShop\Common\Item\Type\Standard, Aimeos\MShop\Coupon\Item\Code\Standard, Aimeos\MShop\Customer\Item\Base, Aimeos\MShop\Customer\Item\Ezpublish, Aimeos\MShop\Customer\Item\Group\Standard, Aimeos\MShop\Customer\Item\Standard, Aimeos\MShop\Locale\Item\Currency\Standard, Aimeos\MShop\Locale\Item\Language\Standard, Aimeos\MShop\Locale\Item\Site\Standard, Aimeos\MShop\Order\Item\Base\Coupon\Standard, Aimeos\MShop\Order\Item\...duct\Attribute\Standard, Aimeos\MShop\Order\Item\...vice\Attribute\Standard, Aimeos\MShop\Order\Item\Base\Service\Base, Aimeos\MShop\Order\Item\Base\Service\Standard, Aimeos\MShop\Product\Item\Standard, Aimeos\MShop\Service\Item\Standard, Aimeos\MShop\Supplier\Item\Standard.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\MShop\Common\Item\Iface as the method getPassword() does only exist in the following implementations of said interface: Aimeos\MShop\Customer\Item\Base, Aimeos\MShop\Customer\Item\Ezpublish, Aimeos\MShop\Customer\Item\Standard.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
326
			$struct->enabled = $item->getStatus();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\MShop\Common\Item\Iface as the method getStatus() does only exist in the following implementations of said interface: Aimeos\MAdmin\Job\Item\Standard, Aimeos\MShop\Attribute\Item\Standard, Aimeos\MShop\Catalog\Item\Standard, Aimeos\MShop\Common\Item\Lists\Standard, Aimeos\MShop\Common\Item\Type\Standard, Aimeos\MShop\Coupon\Item\Standard, Aimeos\MShop\Customer\Item\Base, Aimeos\MShop\Customer\Item\Ezpublish, Aimeos\MShop\Customer\Item\Standard, Aimeos\MShop\Locale\Item\Currency\Standard, Aimeos\MShop\Locale\Item\Language\Standard, Aimeos\MShop\Locale\Item\Site\Standard, Aimeos\MShop\Locale\Item\Standard, Aimeos\MShop\Media\Item\Standard, Aimeos\MShop\Order\Item\Base\Base, Aimeos\MShop\Order\Item\Base\Product\Base, Aimeos\MShop\Order\Item\Base\Product\Standard, Aimeos\MShop\Order\Item\Base\Standard, Aimeos\MShop\Plugin\Item\Standard, Aimeos\MShop\Price\Item\Base, Aimeos\MShop\Price\Item\Standard, Aimeos\MShop\Product\Item\Standard, Aimeos\MShop\Service\Item\Standard, Aimeos\MShop\Subscription\Item\Standard, Aimeos\MShop\Supplier\Item\Standard, Aimeos\MShop\Text\Item\Standard.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
327
328
			$user = $service->createUser( $struct, [] );
329
			$item->setId( $user->getUserId() );
330
		}
331
332
		$dbm = $context->getDatabaseManager();
333
		$dbname = $this->getResourceName();
334
		$conn = $dbm->acquire( $dbname );
335
336
		try
337
		{
338
			$date = date( 'Y-m-d H:i:s' );
339
			$ctime = ( $item->getTimeCreated() ? $item->getTimeCreated() : $date );
340
			$billingAddress = $item->getPaymentAddress();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\MShop\Common\Item\Iface as the method getPaymentAddress() does only exist in the following implementations of said interface: Aimeos\MShop\Customer\Item\Base, Aimeos\MShop\Customer\Item\Ezpublish, Aimeos\MShop\Customer\Item\Standard.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
341
342
			$path = 'mshop/customer/manager/ezpublish/update';
343
			$stmt = $this->getCachedStatement( $conn, $path );
344
345
			$stmt->bind( 1, $billingAddress->getCompany() );
346
			$stmt->bind( 2, $billingAddress->getVatID() );
347
			$stmt->bind( 3, $billingAddress->getSalutation() );
348
			$stmt->bind( 4, $billingAddress->getTitle() );
349
			$stmt->bind( 5, $billingAddress->getFirstname() );
350
			$stmt->bind( 6, $billingAddress->getLastname() );
351
			$stmt->bind( 7, $billingAddress->getAddress1() );
352
			$stmt->bind( 8, $billingAddress->getAddress2() );
353
			$stmt->bind( 9, $billingAddress->getAddress3() );
354
			$stmt->bind( 10, $billingAddress->getPostal() );
355
			$stmt->bind( 11, $billingAddress->getCity() );
356
			$stmt->bind( 12, $billingAddress->getState() );
357
			$stmt->bind( 13, $billingAddress->getCountryId() );
358
			$stmt->bind( 14, $billingAddress->getLanguageId() );
359
			$stmt->bind( 15, $billingAddress->getTelephone() );
360
			$stmt->bind( 16, $billingAddress->getTelefax() );
361
			$stmt->bind( 17, $billingAddress->getWebsite() );
362
			$stmt->bind( 18, $item->getBirthday() );
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\MShop\Common\Item\Iface as the method getBirthday() does only exist in the following implementations of said interface: Aimeos\MShop\Customer\Item\Base, Aimeos\MShop\Customer\Item\Ezpublish, Aimeos\MShop\Customer\Item\Standard.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
363
			$stmt->bind( 19, $item->getDateVerified() );
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\MShop\Common\Item\Iface as the method getDateVerified() does only exist in the following implementations of said interface: Aimeos\MShop\Customer\Item\Base, Aimeos\MShop\Customer\Item\Ezpublish, Aimeos\MShop\Customer\Item\Standard.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
364
			$stmt->bind( 20, $date ); // Modification time
365
			$stmt->bind( 21, $context->getEditor() );
366
			$stmt->bind( 22, $ctime ); // Creation time
367
			$stmt->bind( 23, $item->getId(), \Aimeos\MW\DB\Statement\Base::PARAM_INT );
368
369
			$stmt->execute()->finish();
370
371
			$dbm->release( $conn, $dbname );
372
		}
373
		catch( \Exception $e )
374
		{
375
			$dbm->release( $conn, $dbname );
376
			throw $e;
377
		}
378
379
		$item = $this->savePropertyItems( $item, 'customer' );
0 ignored issues
show
Documentation introduced by
$item is of type object<Aimeos\MShop\Common\Item\Iface>, but the function expects a object<Aimeos\MShop\Comm...Item\PropertyRef\Iface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
380
		$item = $this->saveAddressItems( $item, 'customer' );
0 ignored issues
show
Documentation introduced by
$item is of type object<Aimeos\MShop\Comm...Item\PropertyRef\Iface>, but the function expects a object<Aimeos\MShop\Common\Item\AddressRef\Iface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
381
		return $this->saveListItems( $item, 'customer' );
0 ignored issues
show
Documentation introduced by
$item is of type object<Aimeos\MShop\Common\Item\AddressRef\Iface>, but the function expects a object<Aimeos\MShop\Common\Item\ListRef\Iface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
382
	}
383
384
385
	/**
386
	 * Returns the item objects matched by the given search criteria.
387
	 *
388
	 * @param \Aimeos\MW\Criteria\Iface $search Search criteria object
389
	 * @param integer &$total Number of items that are available in total
390
	 * @return array List of items implementing \Aimeos\MShop\Customer\Item\Iface
391
	 * @throws \Aimeos\MShop\Customer\Exception If creating items failed
392
	 */
393
	public function searchItems( \Aimeos\MW\Criteria\Iface $search, array $ref = [], &$total = null )
394
	{
395
		$dbm = $this->getContext()->getDatabaseManager();
396
		$dbname = $this->getResourceName();
397
		$conn = $dbm->acquire( $dbname );
398
		$map = [];
399
400
		try
401
		{
402
			$level = \Aimeos\MShop\Locale\Manager\Base::SITE_ALL;
403
			$cfgPathSearch = 'mshop/customer/manager/ezpublish/search';
404
			$cfgPathCount = 'mshop/customer/manager/ezpublish/count';
405
			$required = array( 'customer' );
406
407
			$results = $this->searchItemsBase( $conn, $search, $cfgPathSearch, $cfgPathCount, $required, $total, $level );
408
409
			while( ( $row = $results->fetch() ) !== false )
410
			{
411
				$map[ $row['customer.id'] ] = $row;
412
				$map[ $row['customer.id'] ]['groups'] = [];
413
			}
414
415
416
			$path = 'mshop/customer/manager/ezpublish/groups';
417
			$stmt = $conn->create( $this->getGroupSql( array_keys( $map ), $path ) );
418
			$results = $stmt->execute();
419
420
			while( ( $row = $results->fetch() ) !== false ) {
421
				$map[ $row['contentobject_id'] ]['groups'][] = $row['role_id'];
422
			}
423
424
			$dbm->release( $conn, $dbname );
425
		}
426
		catch( \Exception $e )
427
		{
428
			$dbm->release( $conn, $dbname  );
429
			throw $e;
430
		}
431
432
		return $this->buildItems( $map, $ref, 'customer' );
433
	}
434
435
436
	/**
437
	 * Creates a new customer item.
438
	 *
439
	 * @param array $values List of attributes for customer item
440
	 * @param array $listItems List items associated to the customer item
441
	 * @param array $refItems Items referenced by the customer item via the list items
442
	 * @param array $addresses List of address items of the customer item
443
	 * @return \Aimeos\MShop\Customer\Item\Iface New customer item
444
	 */
445
	protected function createItemBase( array $values = [], array $listItems = [], array $refItems = [],
446
		array $addresses = [], array $propItems = [] )
447
	{
448
		if( !isset( $this->addressManager ) ) {
449
			$this->addressManager = $this->getObject()->getSubManager( 'address' );
450
		}
451
452
		$address = $this->addressManager->createItem();
453
454
		return new \Aimeos\MShop\Customer\Item\Ezpublish(
455
			$address, $values, $listItems, $refItems,
456
			null, null, $addresses, $propItems
457
		);
458
	}
459
460
461
	/**
462
	 * Returns the SQL statement for retrieving the customer group IDs
463
	 *
464
	 * @param array $ids List of customer IDs
465
	 * @param string $cfgpath Configuration path to the SQL statement
466
	 * @return string SQL statement ready for execution
467
	 */
468
	protected function getGroupSql( array $ids, $cfgpath )
469
	{
470
		if( empty( $ids ) ) { return '1=1'; }
471
472
		$search = $this->getObject()->createSearch();
473
		$search->setConditions( $search->compare( '==', 'id', $ids ) );
474
475
		$types = array( 'id' => \Aimeos\MW\DB\Statement\Base::PARAM_INT );
476
		$translations = array( 'id' => '"contentobject_id"' );
477
478
		$cond = $search->getConditionString( $types, $translations );
479
480
		return str_replace( ':cond', $cond, $this->getSqlConfig( $cfgpath ) );
481
	}
482
}
483