Passed
Push — master ( 21a725...52b46c )
by Aimeos
04:59
created

lib/mshoplib/src/MShop/Customer/Manager/Base.php (1 issue)

Severity
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), 2015-2018
7
 * @package MShop
8
 * @subpackage Customer
9
 */
10
11
12
namespace Aimeos\MShop\Customer\Manager;
13
14
15
/**
16
 * Base class with common methods for all customer implementations.
17
 *
18
 * @package MShop
19
 * @subpackage Customer
20
 */
21
abstract class Base
22
	extends \Aimeos\MShop\Common\Manager\ListRef\Base
23
{
24
	private $salt;
25
	private $helper;
26
	private $addressManager;
0 ignored issues
show
The private property $addressManager is not used, and could be removed.
Loading history...
27
28
29
	/**
30
	 * Initializes a new customer manager object using the given context object.
31
	 *
32
	 * @param \Aimeos\MShop\Context\Item\Iface $context Context object with required objects
33
	 */
34
	public function __construct( \Aimeos\MShop\Context\Item\Iface $context )
35
	{
36
		parent::__construct( $context );
37
		$this->setResourceName( 'db-customer' );
38
39
		/** mshop/customer/manager/salt
40
		 * Password salt for all customer passwords of the installation
41
		 *
42
		 * The default password salt is used if no user-specific salt can be
43
		 * stored in the database along with the user data. It's highly recommended
44
		 * to set the salt to a random string of at least eight chars using
45
		 * characters, digits and special characters
46
		 *
47
		 * @param string Installation wide password salt
48
		 * @since 2014.03
49
		 * @category Developer
50
		 * @category User
51
		 * @see mshop/customer/manager/password/name
52
		 * @sse mshop/customer/manager/password/options
53
		 */
54
		$this->salt = $context->getConfig()->get( 'mshop/customer/manager/salt', 'mshop' );
55
	}
56
57
58
	/**
59
	 * Creates a criteria object for searching.
60
	 *
61
	 * @param boolean $default Include default criteria like the status
62
	 * @return \Aimeos\MW\Criteria\Iface Search criteria object
63
	 */
64
	public function createSearch( $default = false )
65
	{
66
		if( $default === true ) {
67
			return $this->createSearchBase( 'customer' );
68
		}
69
70
		return parent::createSearch();
71
	}
72
73
74
	/**
75
	 * Returns the item specified by its code and domain/type if necessary
76
	 *
77
	 * @param string $code Code of the item
78
	 * @param string[] $ref List of domains to fetch list items and referenced items for
79
	 * @param string|null $domain Domain of the item if necessary to identify the item uniquely
80
	 * @param string|null $type Type code of the item if necessary to identify the item uniquely
81
	 * @param boolean $default True to add default criteria
82
	 * @return \Aimeos\MShop\Common\Item\Iface Item object
83
	 */
84
	public function findItem( $code, array $ref = [], $domain = null, $type = null, $default = false )
85
	{
86
		return $this->findItemBase( array( 'customer.code' => $code ), $ref, $default );
87
	}
88
89
90
	/**
91
	 * Returns the customer item object specificed by its ID.
92
	 *
93
	 * @param integer $id Unique customer ID referencing an existing customer
94
	 * @param string[] $ref List of domains to fetch list items and referenced items for
95
	 * @param boolean $default Add default criteria
96
	 * @return \Aimeos\MShop\Customer\Item\Iface Returns the customer item of the given id
97
	 * @throws \Aimeos\MShop\Exception If item couldn't be found
98
	 */
99
	public function getItem( $id, array $ref = [], $default = false )
100
	{
101
		return $this->getItemBase( 'customer.id', $id, $ref, $default );
102
	}
103
104
105
	/**
106
	 * Adds the customer to the groups listed in the customer item
107
	 *
108
	 * @param \Aimeos\MShop\Customer\Item\Iface $item Customer item
109
	 */
110
	protected function addGroups( \Aimeos\MShop\Customer\Item\Iface $item )
111
	{
112
		$listMap = [];
113
		$manager = $this->getObject()->getSubManager( 'lists' );
114
115
		$search = $manager->createSearch()->setSlice( 0, 0x7fffffff );
116
		$expr = array(
117
			$search->compare( '==', 'customer.lists.parentid', $item->getId() ),
118
			$search->compare( '==', 'customer.lists.domain', 'customer/group' ),
119
			$search->compare( '==', 'customer.lists.type.domain', 'customer/group' ),
120
			$search->compare( '==', 'customer.lists.type.code', 'default' ),
121
		);
122
		$search->setConditions( $search->combine( '&&', $expr ) );
123
124
		foreach( $manager->searchItems( $search ) as $listid => $listItem ) {
125
			$listMap[ $listItem->getRefId() ] = $listid;
126
		}
127
128
129
		if( $item->getGroups() !== [] )
130
		{
131
			$typeManager = $manager->getSubManager( 'type' );
132
			$typeId = $typeManager->findItem( 'default', [], 'customer/group', 'default' )->getId();
133
134
			$listItem = $manager->createItem();
135
			$listItem->setParentId( $item->getId() );
136
			$listItem->setDomain( 'customer/group' );
137
			$listItem->setTypeId( $typeId );
138
			$listItem->setStatus( 1 );
139
140
			$pos = count( $listMap ) ;
141
142
			foreach( $item->getGroups() as $gid )
143
			{
144
				if( isset( $listMap[$gid] ) )
145
				{
146
					unset( $listMap[$gid] );
147
					continue;
148
				}
149
150
				$listItem->setId( null );
151
				$listItem->setRefId( $gid );
152
				$listItem->setPosition( $pos++ );
153
154
				$manager->saveItem( $listItem, false );
155
			}
156
		}
157
158
		$manager->deleteItems( $listMap );
159
	}
160
161
162
	/**
163
	 * Creates a new customer item.
164
	 *
165
	 * @param array $values List of attributes for customer item
166
	 * @param array $listItems List items associated to the customer item
167
	 * @param array $refItems Items referenced by the customer item via the list items
168
	 * @param array $addresses List of address items of the customer item
169
	 * @param array $propItems List of property items of the customer item
170
	 * @return \Aimeos\MShop\Customer\Item\Iface New customer item
171
	 */
172
	protected function createItemBase( array $values = [], array $listItems = [], array $refItems = [],
173
		array $addresses = [], array $propItems = [] )
174
	{
175
		$helper = $this->getPasswordHelper();
176
		$address = new \Aimeos\MShop\Common\Item\Address\Simple( 'customer.', $values );
177
178
		return new \Aimeos\MShop\Customer\Item\Standard(
179
			$address, $values, $listItems, $refItems,
180
			$this->salt, $helper, $addresses, $propItems
181
		);
182
	}
183
184
185
	/**
186
	 * Returns a password helper object based on the configuration.
187
	 *
188
	 * @return \Aimeos\MShop\Common\Item\Helper\Password\Iface Password helper object
189
	 * @throws \Aimeos\MShop\Exception If the name is invalid or the class isn't found
190
	 */
191
	protected function getPasswordHelper()
192
	{
193
		if( $this->helper ) {
194
			return $this->helper;
195
		}
196
197
		$config = $this->getContext()->getConfig();
198
199
		/** mshop/customer/manager/password/name
200
		 * Last part of the name for building the password helper item
201
		 *
202
		 * The password helper encode given passwords and salts using the
203
		 * implemented hashing method in the required format. String format and
204
		 * hash algorithm needs to be the same when comparing the encoded
205
		 * password to the one provided by the user after login.
206
		 *
207
		 * @param string Name of the password helper implementation
208
		 * @since 2015.01
209
		 * @category Developer
210
		 * @see mshop/customer/manager/salt
211
		 * @see mshop/customer/manager/password/options
212
		 */
213
		$name = $config->get( 'mshop/customer/manager/password/name', 'Standard' );
214
215
		/** mshop/customer/manager/password/options
216
		 * List of options used by the password helper classes
217
		 *
218
		 * Each hash method may need an arbitrary number of options specific
219
		 * for the hash method. This may include the number of iterations the
220
		 * method is applied or the separator between salt and password.
221
		 *
222
		 * @param string Associative list of key/value pairs
223
		 * @since 2015.01
224
		 * @category Developer
225
		 * @see mshop/customer/manager/password/name
226
		 * @sse mshop/customer/manager/salt
227
		 */
228
		$options = $config->get( 'mshop/customer/manager/password/options', [] );
229
230
		if( ctype_alnum( $name ) === false )
231
		{
232
			$classname = is_string( $name ) ? '\\Aimeos\\MShop\\Common\\Item\\Helper\\Password\\' . $name : '<not a string>';
233
			throw new \Aimeos\MShop\Exception( sprintf( 'Invalid characters in class name "%1$s"', $classname ) );
234
		}
235
236
		$classname = '\\Aimeos\\MShop\\Common\\Item\\Helper\\Password\\' . $name;
237
238
		if( class_exists( $classname ) === false ) {
239
			throw new \Aimeos\MShop\Exception( sprintf( 'Class "%1$s" not available', $classname ) );
240
		}
241
242
		$helper = new $classname( $options );
243
244
		self::checkClass( '\\Aimeos\\MShop\\Common\\Item\\Helper\\Password\\Iface', $helper );
245
246
		$this->helper = $helper;
247
248
		return $helper;
249
	}
250
}