• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

aimeos / aimeos-core / be5b2722-8208-42fc-9362-4640a66e38cf

13 Sep 2024 08:05AM UTC coverage: 92.186% (-0.02%) from 92.207%
be5b2722-8208-42fc-9362-4640a66e38cf

push

circleci

aimeos
Simplified customer manager

227 of 229 new or added lines in 5 files covered. (99.13%)

15 existing lines in 2 files now uncovered.

9804 of 10635 relevant lines covered (92.19%)

72.46 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

65.22
/src/MShop/Customer/Manager/Base.php
1
<?php
2

3
/**
4
 * @license LGPLv3, https://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2015-2024
6
 * @package MShop
7
 * @subpackage Customer
8
 */
9

10

11
namespace Aimeos\MShop\Customer\Manager;
12

13

14
/**
15
 * Base class with common methods for all customer implementations.
16
 *
17
 * @package MShop
18
 * @subpackage Customer
19
 */
20
abstract class Base
21
        extends \Aimeos\MShop\Common\Manager\Base
22
{
23
        use \Aimeos\MShop\Common\Manager\ListsRef\Traits;
24
        use \Aimeos\MShop\Common\Manager\AddressRef\Traits;
25
        use \Aimeos\MShop\Common\Manager\PropertyRef\Traits;
26

27

28
        /* @deprecated 2025.01 Use $this->context()->password() instead */
29
        private ?\Aimeos\MShop\Common\Helper\Password\Iface $helper = null;
30

31

32
        /**
33
         * Counts the number items that are available for the values of the given key.
34
         *
35
         * @param \Aimeos\Base\Criteria\Iface $search Search criteria
36
         * @param array|string $key Search key or list of key to aggregate items for
37
         * @param string|null $value Search key for aggregating the value column
38
         * @param string|null $type Type of the aggregation, empty string for count or "sum" or "avg" (average)
39
         * @return \Aimeos\Map List of the search keys as key and the number of counted items as value
40
         */
41
        public function aggregate( \Aimeos\Base\Criteria\Iface $search, $key, string $value = null, string $type = null ) : \Aimeos\Map
42
        {
43
                /** mshop/customer/manager/aggregate/mysql
44
                 * Counts the number of records grouped by the values in the key column and matched by the given criteria
45
                 *
46
                 * @see mshop/customer/manager/aggregate/ansi
47
                 */
48

49
                /** mshop/customer/manager/aggregate/ansi
50
                 * Counts the number of records grouped by the values in the key column and matched by the given criteria
51
                 *
52
                 * Groups all records by the values in the key column and counts their
53
                 * occurence. The matched records can be limited by the given criteria
54
                 * from the customer database. The records must be from one of the sites
55
                 * that are configured via the context item. If the current site is part
56
                 * of a tree of sites, the statement can count all records from the
57
                 * current site and the complete sub-tree of sites.
58
                 *
59
                 * As the records can normally be limited by criteria from sub-managers,
60
                 * their tables must be joined in the SQL context. This is done by
61
                 * using the "internaldeps" property from the definition of the ID
62
                 * column of the sub-managers. These internal dependencies specify
63
                 * the JOIN between the tables and the used columns for joining. The
64
                 * ":joins" placeholder is then replaced by the JOIN strings from
65
                 * the sub-managers.
66
                 *
67
                 * To limit the records matched, conditions can be added to the given
68
                 * criteria object. It can contain comparisons like column names that
69
                 * must match specific values which can be combined by AND, OR or NOT
70
                 * operators. The resulting string of SQL conditions replaces the
71
                 * ":cond" placeholder before the statement is sent to the database
72
                 * server.
73
                 *
74
                 * This statement doesn't return any records. Instead, it returns pairs
75
                 * of the different values found in the key column together with the
76
                 * number of records that have been found for that key values.
77
                 *
78
                 * The SQL statement should conform to the ANSI standard to be
79
                 * compatible with most relational database systems. This also
80
                 * includes using double quotes for table and column names.
81
                 *
82
                 * @param string SQL statement for aggregating customer items
83
                 * @since 2021.04
84
                 * @see mshop/customer/manager/insert/ansi
85
                 * @see mshop/customer/manager/update/ansi
86
                 * @see mshop/customer/manager/newid/ansi
87
                 * @see mshop/customer/manager/delete/ansi
88
                 * @see mshop/customer/manager/search/ansi
89
                 * @see mshop/customer/manager/count/ansi
90
                 */
91

92
                $cfgkey = 'mshop/customer/manager/aggregate';
2✔
93
                return $this->aggregateBase( $search, $key, $cfgkey, ['customer'], $value, $type );
2✔
94
        }
95

96

97
        /**
98
         * Creates a filter object.
99
         *
100
         * @param bool|null $default Add default criteria or NULL for relaxed default criteria
101
         * @param bool $site TRUE for adding site criteria to limit items by the site of related items
102
         * @return \Aimeos\Base\Criteria\Iface Returns the filter object
103
         */
104
        public function filter( ?bool $default = false, bool $site = false ) : \Aimeos\Base\Criteria\Iface
105
        {
106
                return $this->filterBase( 'customer', $default );
34✔
107
        }
108

109

110
        /**
111
         * Returns the item specified by its code and domain/type if necessary
112
         *
113
         * @param string $code Code of the item
114
         * @param string[] $ref List of domains to fetch list items and referenced items for
115
         * @param string|null $domain Domain of the item if necessary to identify the item uniquely
116
         * @param string|null $type Type code of the item if necessary to identify the item uniquely
117
         * @param bool|null $default Add default criteria or NULL for relaxed default criteria
118
         * @return \Aimeos\MShop\Customer\Item\Iface Item object
119
         */
120
        public function find( string $code, array $ref = [], string $domain = null, string $type = null,
121
                ?bool $default = false ) : \Aimeos\MShop\Common\Item\Iface
122
        {
123
                return $this->findBase( ['customer.code' => $code], $ref, $default );
15✔
124
        }
125

126

127
        /**
128
         * Returns the customer item object specificed by its ID.
129
         *
130
         * @param string $id Unique customer ID referencing an existing customer
131
         * @param string[] $ref List of domains to fetch list items and referenced items for
132
         * @param bool|null $default Add default criteria or NULL for relaxed default criteria
133
         * @return \Aimeos\MShop\Customer\Item\Iface Returns the customer item of the given id
134
         * @throws \Aimeos\MShop\Exception If item couldn't be found
135
         */
136
        public function get( string $id, array $ref = [], ?bool $default = false ) : \Aimeos\MShop\Common\Item\Iface
137
        {
138
                return $this->getItemBase( 'customer.id', $id, $ref, $default );
5✔
139
        }
140

141

142
        /**
143
         * Adds the customer to the groups listed in the customer item
144
         *
145
         * @param \Aimeos\MShop\Customer\Item\Iface $item Customer item
146
         * @return \Aimeos\MShop\Customer\Item\Iface $item Modified customer item
147
         */
148
        protected function addGroups( \Aimeos\MShop\Customer\Item\Iface $item ): \Aimeos\MShop\Customer\Item\Iface
149
        {
150
                $pos = 0;
3✔
151
                $groupIds = [];
3✔
152

153
                $manager = $this->object()->getSubManager( 'lists' );
3✔
154
                $listItems = $item->getListItems( 'group', 'default', null, false );
3✔
155

156
                foreach( $item->getGroups() as $refId => $code )
3✔
157
                {
158
                        if( ( $litem = $item->getListItem( 'group', 'default', $refId, false ) ) !== null ) {
1✔
159
                                unset( $listItems[$litem->getId()], $listItems['__group_default_' . $refId] );
×
160
                        } else {
161
                                $litem = $manager->create()->setType( 'default' );
1✔
162
                        }
163

164
                        $item->addListItem( 'group', $litem->setRefId( $refId )->setPosition( $pos++ ) );
1✔
165
                }
166

167
                return $item->deleteListItems( $listItems );
3✔
168
        }
169

170

171
        /**
172
         * Creates a new customer item.
173
         *
174
         * @param array $values List of attributes for customer item
175
         * @param \Aimeos\MShop\Common\Item\Lists\Iface[] $listItems List of list items
176
         * @param \Aimeos\MShop\Common\Item\Iface[] $refItems List of referenced items
177
         * @param \Aimeos\MShop\Common\Item\Address\Iface[] $addrItems List of address items
178
         * @param \Aimeos\MShop\Common\Item\Property\Iface[] $propItems List of property items
179
         * @return \Aimeos\MShop\Customer\Item\Iface New customer item
180
         */
181
        protected function createItemBase( array $values = [], array $listItems = [], array $refItems = [],
182
                array $addrItems = [], array $propItems = [] ) : \Aimeos\MShop\Common\Item\Iface
183
        {
UNCOV
184
                $values['.listitems'] = $listItems;
×
UNCOV
185
                $values['.propitems'] = $propItems;
×
UNCOV
186
                $values['.addritems'] = $addrItems;
×
187

NEW
188
                return $this->create( $values );
×
189
        }
190

191

192
        /**
193
         * Deletes items.
194
         *
195
         * @param \Aimeos\MShop\Common\Item\Iface|\Aimeos\Map|array|string $items List of item objects or IDs of the items
196
         * @param string $cfgpath Configuration path to the SQL statement
197
         * @param bool $siteid If siteid should be used in the statement
198
         * @param string $name Name of the ID column
199
         * @return \Aimeos\MShop\Common\Manager\Iface Manager object for chaining method calls
200
         */
201
        protected function deleteItemsBase( $items, string $cfgpath, bool $siteid = true,
202
                string $name = 'id' ) : \Aimeos\MShop\Common\Manager\Iface
203
        {
204
                if( map( $items )->isEmpty() ) {
3✔
205
                        return $this;
×
206
                }
207

208
                $search = $this->object()->filter();
3✔
209
                $search->setConditions( $search->compare( '==', $name, $items ) );
3✔
210

211
                $types = array( $name => \Aimeos\Base\DB\Statement\Base::PARAM_STR );
3✔
212
                $translations = array( $name => '"' . $name . '"' );
3✔
213

214
                $cond = $search->getConditionSource( $types, $translations );
3✔
215
                $sql = str_replace( ':cond', $cond, $this->getSqlConfig( $cfgpath ) );
3✔
216

217
                $context = $this->context();
3✔
218
                $conn = $context->db( $this->getResourceName() );
3✔
219

220
                $stmt = $conn->create( $sql );
3✔
221

222
                if( $siteid )
3✔
223
                {
224
                        $stmt->bind( 1, $context->locale()->getSiteId() . '%' );
3✔
225
                        $stmt->bind( 2, $context->user()?->getSiteId() );
3✔
226
                }
227

228
                $stmt->execute()->finish();
3✔
229

230
                return $this;
3✔
231
        }
232

233

234
        /**
235
         * Returns a password helper object based on the configuration.
236
         *
237
         * @return \Aimeos\MShop\Common\Helper\Password\Iface Password helper object
238
         * @throws \LogicException If the name is invalid or the class isn't found
239
         * @deprecated 2025.01 Use $this->context()->password() instead
240
         */
241
        protected function getPasswordHelper() : \Aimeos\MShop\Common\Helper\Password\Iface
242
        {
243
                if( $this->helper ) {
×
244
                        return $this->helper;
×
245
                }
246

247
                $config = $this->context()->config();
×
248

249
                /** mshop/customer/manager/password/name
250
                 * Last part of the name for building the password helper item
251
                 *
252
                 * The password helper encode given passwords and salts using the
253
                 * implemented hashing method in the required format. String format and
254
                 * hash algorithm needs to be the same when comparing the encoded
255
                 * password to the one provided by the user after login.
256
                 *
257
                 * @param string Name of the password helper implementation
258
                 * @since 2015.01
259
                 * @see mshop/customer/manager/salt
260
                 * @see mshop/customer/manager/password/options
261
                 */
262
                $name = $config->get( 'mshop/customer/manager/password/name', 'Standard' );
×
263

264
                /** mshop/customer/manager/password/options
265
                 * List of options used by the password helper classes
266
                 *
267
                 * Each hash method may need an arbitrary number of options specific
268
                 * for the hash method. This may include the number of iterations the
269
                 * method is applied or the separator between salt and password.
270
                 *
271
                 * @param string Associative list of key/value pairs
272
                 * @since 2015.01
273
                 * @see mshop/customer/manager/password/name
274
                 * @sse mshop/customer/manager/salt
275
                 */
276
                $options = $config->get( 'mshop/customer/manager/password/options', [] );
×
277

278
                if( ctype_alnum( $name ) === false ) {
×
279
                        throw new \LogicException( sprintf( 'Invalid characters in class name "%1$s"', $name ), 400 );
×
280
                }
281

282
                $classname = '\Aimeos\MShop\Common\Helper\Password\\' . $name;
×
283
                $interface = \Aimeos\MShop\Common\Helper\Password\Iface::class;
×
284

285
                return $this->helper = \Aimeos\Utils::create( $classname, [$options], $interface );
×
286
        }
287

288

289
        /**
290
         * Returns the currently authenticated user
291
         *
292
         * @return \Aimeos\MShop\Customer\Item\Iface|null Customer item or NULL if not available
293
         * @deprecated 2025.01 Use $this->context()->user() instead
294
         */
295
        protected function getUser() : ?\Aimeos\MShop\Customer\Item\Iface
296
        {
297
                return $this->context()->user();
1✔
298
        }
299
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc