| Total Complexity | 57 | 
| Total Lines | 859 | 
| Duplicated Lines | 0 % | 
| Changes | 0 | ||
Complex classes like Standard often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Standard, and based on these observations, apply Extract Interface, too.
| 1 | <?php  | 
            ||
| 21 | class Standard  | 
            ||
| 22 | extends \Aimeos\MShop\Locale\Manager\Base  | 
            ||
| 23 | implements \Aimeos\MShop\Locale\Manager\Iface, \Aimeos\MShop\Common\Manager\Factory\Iface  | 
            ||
| 24 | { | 
            ||
| 25 | private $searchConfig = array(  | 
            ||
| 26 | 'locale.id' => array(  | 
            ||
| 27 | 'code' => 'locale.id',  | 
            ||
| 28 | 'internalcode' => 'mloc."id"',  | 
            ||
| 29 | 'label' => 'ID',  | 
            ||
| 30 | 'type' => 'integer',  | 
            ||
| 31 | 'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_INT,  | 
            ||
| 32 | 'public' => false,  | 
            ||
| 33 | ),  | 
            ||
| 34 | 'locale.siteid' => array(  | 
            ||
| 35 | 'code' => 'locale.siteid',  | 
            ||
| 36 | 'internalcode' => 'mloc."siteid"',  | 
            ||
| 37 | 'label' => 'Site ID',  | 
            ||
| 38 | 'type' => 'string',  | 
            ||
| 39 | 'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,  | 
            ||
| 40 | 'public' => false,  | 
            ||
| 41 | ),  | 
            ||
| 42 | 'locale.languageid' => array(  | 
            ||
| 43 | 'code' => 'locale.languageid',  | 
            ||
| 44 | 'internalcode' => 'mloc."langid"',  | 
            ||
| 45 | 'label' => 'Language ID',  | 
            ||
| 46 | 'type' => 'string',  | 
            ||
| 47 | 'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,  | 
            ||
| 48 | ),  | 
            ||
| 49 | 'locale.currencyid' => array(  | 
            ||
| 50 | 'code' => 'locale.currencyid',  | 
            ||
| 51 | 'internalcode' => 'mloc."currencyid"',  | 
            ||
| 52 | 'label' => 'Currency ID',  | 
            ||
| 53 | 'type' => 'string',  | 
            ||
| 54 | 'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,  | 
            ||
| 55 | ),  | 
            ||
| 56 | 'locale.status' => array(  | 
            ||
| 57 | 'code' => 'locale.status',  | 
            ||
| 58 | 'internalcode' => 'mloc."status"',  | 
            ||
| 59 | 'label' => 'Status',  | 
            ||
| 60 | 'type' => 'integer',  | 
            ||
| 61 | 'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_INT,  | 
            ||
| 62 | ),  | 
            ||
| 63 | 'locale.position' => array(  | 
            ||
| 64 | 'code' => 'locale.position',  | 
            ||
| 65 | 'internalcode' => 'mloc."pos"',  | 
            ||
| 66 | 'label' => 'Position',  | 
            ||
| 67 | 'type' => 'integer',  | 
            ||
| 68 | 'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_INT,  | 
            ||
| 69 | ),  | 
            ||
| 70 | 'locale.ctime' => array(  | 
            ||
| 71 | 'code' => 'locale.ctime',  | 
            ||
| 72 | 'internalcode' => 'mloc."ctime"',  | 
            ||
| 73 | 'label' => 'Create date/time',  | 
            ||
| 74 | 'type' => 'datetime',  | 
            ||
| 75 | 'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,  | 
            ||
| 76 | 'public' => false,  | 
            ||
| 77 | ),  | 
            ||
| 78 | 'locale.mtime' => array(  | 
            ||
| 79 | 'code' => 'locale.mtime',  | 
            ||
| 80 | 'internalcode' => 'mloc."mtime"',  | 
            ||
| 81 | 'label' => 'Modify date/time',  | 
            ||
| 82 | 'type' => 'datetime',  | 
            ||
| 83 | 'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,  | 
            ||
| 84 | 'public' => false,  | 
            ||
| 85 | ),  | 
            ||
| 86 | 'locale.editor' => array(  | 
            ||
| 87 | 'code' => 'locale.editor',  | 
            ||
| 88 | 'internalcode' => 'mloc."editor"',  | 
            ||
| 89 | 'label' => 'Editor',  | 
            ||
| 90 | 'type' => 'string',  | 
            ||
| 91 | 'internaltype' => \Aimeos\Base\DB\Statement\Base::PARAM_STR,  | 
            ||
| 92 | 'public' => false,  | 
            ||
| 93 | ),  | 
            ||
| 94 | );  | 
            ||
| 95 | |||
| 96 | |||
| 97 | /**  | 
            ||
| 98 | * Initializes the object.  | 
            ||
| 99 | *  | 
            ||
| 100 | * @param \Aimeos\MShop\ContextIface $context Context object  | 
            ||
| 101 | */  | 
            ||
| 102 | public function __construct( \Aimeos\MShop\ContextIface $context )  | 
            ||
| 103 | 	{ | 
            ||
| 104 | parent::__construct( $context );  | 
            ||
| 105 | $this->setResourceName( 'db-locale' );  | 
            ||
| 106 | }  | 
            ||
| 107 | |||
| 108 | |||
| 109 | /**  | 
            ||
| 110 | * Returns the locale item for the given site code, language code and currency code.  | 
            ||
| 111 | *  | 
            ||
| 112 | * @param string $site Site code  | 
            ||
| 113 | * @param string $lang Language code (optional)  | 
            ||
| 114 | * @param string $currency Currency code (optional)  | 
            ||
| 115 | * @param bool $active Flag to get only active items (optional)  | 
            ||
| 116 | * @param int|null $level Constant from abstract class which site ID levels should be available (optional),  | 
            ||
| 117 | * based on config or value for SITE_PATH if null  | 
            ||
| 118 | * @param bool $bare Allow locale items with sites only  | 
            ||
| 119 | * @return \Aimeos\MShop\Locale\Item\Iface Locale item for the given parameters  | 
            ||
| 120 | * @throws \Aimeos\MShop\Locale\Exception If no locale item is found  | 
            ||
| 121 | */  | 
            ||
| 122 | public function bootstrap( string $site, string $lang = '', string $currency = '', bool $active = true, int $level = null,  | 
            ||
| 123 | bool $bare = false ) : \Aimeos\MShop\Locale\Item\Iface  | 
            ||
| 124 | 	{ | 
            ||
| 125 | $siteItem = $this->object()->getSubManager( 'site' )->find( $site );  | 
            ||
| 126 | |||
| 127 | 		if( $active && $siteItem->getStatus() < 1 ) { | 
            ||
| 128 | throw new \Aimeos\MShop\Locale\Exception( 'Site not found' );  | 
            ||
| 129 | }  | 
            ||
| 130 | |||
| 131 | $siteId = $siteItem->getSiteId();  | 
            ||
| 132 | $sites = [Base::SITE_ONE => $siteId];  | 
            ||
| 133 | |||
| 134 | return $this->bootstrapBase( $site, $lang, $currency, $active, $siteItem, $siteId, $sites, $bare );  | 
            ||
| 135 | }  | 
            ||
| 136 | |||
| 137 | |||
| 138 | /**  | 
            ||
| 139 | * Removes old entries from the storage.  | 
            ||
| 140 | *  | 
            ||
| 141 | * @param iterable $siteids List of IDs for sites whose entries should be deleted  | 
            ||
| 142 | * @return \Aimeos\MShop\Locale\Manager\Iface Manager object for chaining method calls  | 
            ||
| 143 | */  | 
            ||
| 144 | public function clear( iterable $siteids ) : \Aimeos\MShop\Common\Manager\Iface  | 
            ||
| 145 | 	{ | 
            ||
| 146 | return $this->clearBase( $siteids, 'mshop/locale/manager/delete' );  | 
            ||
| 147 | }  | 
            ||
| 148 | |||
| 149 | |||
| 150 | /**  | 
            ||
| 151 | * Creates a new empty item instance  | 
            ||
| 152 | *  | 
            ||
| 153 | * @param array $values Values the item should be initialized with  | 
            ||
| 154 | * @return \Aimeos\MShop\Locale\Item\Iface New locale item object  | 
            ||
| 155 | */  | 
            ||
| 156 | public function create( array $values = [] ) : \Aimeos\MShop\Common\Item\Iface  | 
            ||
| 166 | }  | 
            ||
| 167 | }  | 
            ||
| 168 | |||
| 169 | |||
| 170 | /**  | 
            ||
| 171 | * Creates a filter object.  | 
            ||
| 172 | *  | 
            ||
| 173 | * @param bool|null $default Add default criteria or NULL for relaxed default criteria  | 
            ||
| 174 | * @param bool $site TRUE for adding site criteria to limit items by the site of related items  | 
            ||
| 175 | * @return \Aimeos\Base\Criteria\Iface Returns the filter object  | 
            ||
| 176 | */  | 
            ||
| 177 | public function filter( ?bool $default = false, bool $site = false ) : \Aimeos\Base\Criteria\Iface  | 
            ||
| 178 | 	{ | 
            ||
| 179 | return $this->filterBase( 'locale', $default );  | 
            ||
| 180 | }  | 
            ||
| 181 | |||
| 182 | |||
| 183 | /**  | 
            ||
| 184 | * Returns the item specified by its ID.  | 
            ||
| 185 | *  | 
            ||
| 186 | * @param string $id Unique ID of the locale item  | 
            ||
| 187 | * @param string[] $ref List of domains to fetch list items and referenced items for  | 
            ||
| 188 | * @param bool|null $default Add default criteria or NULL for relaxed default criteria  | 
            ||
| 189 | * @return \Aimeos\MShop\Locale\Item\Iface Returns the locale item of the given id  | 
            ||
| 190 | * @throws \Aimeos\MShop\Exception If item couldn't be found  | 
            ||
| 191 | */  | 
            ||
| 192 | public function get( string $id, array $ref = [], ?bool $default = false ) : \Aimeos\MShop\Common\Item\Iface  | 
            ||
| 193 | 	{ | 
            ||
| 194 | return $this->getItemBase( 'locale.id', $id, $ref, $default );  | 
            ||
| 195 | }  | 
            ||
| 196 | |||
| 197 | |||
| 198 | /**  | 
            ||
| 199 | * Searches for all items matching the given critera.  | 
            ||
| 200 | *  | 
            ||
| 201 | * @param \Aimeos\Base\Criteria\Iface $search Criteria object with conditions, sortations, etc.  | 
            ||
| 202 | * @param string[] $ref List of domains to fetch list items and referenced items for  | 
            ||
| 203 | * @param int &$total Number of items that are available in total  | 
            ||
| 204 | * @return \Aimeos\Map List of items implementing \Aimeos\MShop\Locale\Item\Iface with ids as keys  | 
            ||
| 205 | */  | 
            ||
| 206 | public function search( \Aimeos\Base\Criteria\Iface $search, array $ref = [], int &$total = null ) : \Aimeos\Map  | 
            ||
| 207 | 	{ | 
            ||
| 208 | $items = [];  | 
            ||
| 209 | $level = \Aimeos\MShop\Locale\Manager\Base::SITE_PATH;  | 
            ||
| 210 | $search = (clone $search)->add( $this->siteCondition( 'locale.siteid', $level ) );  | 
            ||
| 211 | |||
| 212 | foreach( $this->searchEntries( $search, $ref, $total ) as $row )  | 
            ||
| 213 | 		{ | 
            ||
| 214 | 			if( $item = $this->applyFilter( $this->createItemBase( $row ) ) ) { | 
            ||
| 215 | $items[$row['locale.id']] = $item;  | 
            ||
| 216 | }  | 
            ||
| 217 | }  | 
            ||
| 218 | |||
| 219 | return map( $items );  | 
            ||
| 220 | }  | 
            ||
| 221 | |||
| 222 | |||
| 223 | /**  | 
            ||
| 224 | * Removes multiple items.  | 
            ||
| 225 | *  | 
            ||
| 226 | * @param \Aimeos\MShop\Common\Item\Iface[]|string[] $itemIds List of item objects or IDs of the items  | 
            ||
| 227 | * @return \Aimeos\MShop\Locale\Manager\Iface Manager object for chaining method calls  | 
            ||
| 228 | */  | 
            ||
| 229 | public function delete( $itemIds ) : \Aimeos\MShop\Common\Manager\Iface  | 
            ||
| 264 | }  | 
            ||
| 265 | |||
| 266 | |||
| 267 | /**  | 
            ||
| 268 | * Adds or updates an item object.  | 
            ||
| 269 | *  | 
            ||
| 270 | * @param \Aimeos\MShop\Locale\Item\Iface $item Item object whose data should be saved  | 
            ||
| 271 | * @param bool $fetch True if the new ID should be returned in the item  | 
            ||
| 272 | * @return \Aimeos\MShop\Locale\Item\Iface $item Updated item including the generated ID  | 
            ||
| 273 | */  | 
            ||
| 274 | public function saveItem( \Aimeos\MShop\Locale\Item\Iface $item, bool $fetch = true ) : \Aimeos\MShop\Locale\Item\Iface  | 
            ||
| 275 | 	{ | 
            ||
| 276 | 		if( !$item->isModified() ) { | 
            ||
| 277 | return $item;  | 
            ||
| 278 | }  | 
            ||
| 279 | |||
| 280 | $context = $this->context();  | 
            ||
| 281 | $conn = $context->db( $this->getResourceName() );  | 
            ||
| 282 | |||
| 283 | $id = $item->getId();  | 
            ||
| 284 | $date = date( 'Y-m-d H:i:s' );  | 
            ||
| 285 | $columns = $this->object()->getSaveAttributes();  | 
            ||
| 286 | |||
| 287 | if( $id === null )  | 
            ||
| 288 | 			{ | 
            ||
| 289 | /** mshop/locale/manager/insert/mysql  | 
            ||
| 290 | * Inserts a new locale record into the database table  | 
            ||
| 291 | *  | 
            ||
| 292 | * @see mshop/locale/manager/insert/ansi  | 
            ||
| 293 | */  | 
            ||
| 294 | |||
| 295 | /** mshop/locale/manager/insert/ansi  | 
            ||
| 296 | * Inserts a new locale record into the database table  | 
            ||
| 297 | *  | 
            ||
| 298 | * Items with no ID yet (i.e. the ID is NULL) will be created in  | 
            ||
| 299 | * the database and the newly created ID retrieved afterwards  | 
            ||
| 300 | * using the "newid" SQL statement.  | 
            ||
| 301 | *  | 
            ||
| 302 | * The SQL statement must be a string suitable for being used as  | 
            ||
| 303 | * prepared statement. It must include question marks for binding  | 
            ||
| 304 | * the values from the locale item to the statement before they are  | 
            ||
| 305 | * sent to the database server. The number of question marks must  | 
            ||
| 306 | * be the same as the number of columns listed in the INSERT  | 
            ||
| 307 | * statement. The order of the columns must correspond to the  | 
            ||
| 308 | * order in the save() method, so the correct values are  | 
            ||
| 309 | * bound to the columns.  | 
            ||
| 310 | *  | 
            ||
| 311 | * The SQL statement should conform to the ANSI standard to be  | 
            ||
| 312 | * compatible with most relational database systems. This also  | 
            ||
| 313 | * includes using double quotes for table and column names.  | 
            ||
| 314 | *  | 
            ||
| 315 | * @param string SQL statement for inserting records  | 
            ||
| 316 | * @since 2014.03  | 
            ||
| 317 | * @category Developer  | 
            ||
| 318 | * @see mshop/locale/manager/update/ansi  | 
            ||
| 319 | * @see mshop/locale/manager/newid/ansi  | 
            ||
| 320 | * @see mshop/locale/manager/delete/ansi  | 
            ||
| 321 | * @see mshop/locale/manager/search/ansi  | 
            ||
| 322 | * @see mshop/locale/manager/count/ansi  | 
            ||
| 323 | */  | 
            ||
| 324 | $path = 'mshop/locale/manager/insert';  | 
            ||
| 325 | $sql = $this->addSqlColumns( array_keys( $columns ), $this->getSqlConfig( $path ) );  | 
            ||
| 
                                                                                                    
                        
                         | 
                |||
| 326 | }  | 
            ||
| 327 | else  | 
            ||
| 328 | 			{ | 
            ||
| 329 | /** mshop/locale/manager/update/mysql  | 
            ||
| 330 | * Updates an existing locale record in the database  | 
            ||
| 331 | *  | 
            ||
| 332 | * @see mshop/locale/manager/update/ansi  | 
            ||
| 333 | */  | 
            ||
| 334 | |||
| 335 | /** mshop/locale/manager/update/ansi  | 
            ||
| 336 | * Updates an existing locale record in the database  | 
            ||
| 337 | *  | 
            ||
| 338 | * Items which already have an ID (i.e. the ID is not NULL) will  | 
            ||
| 339 | * be updated in the database.  | 
            ||
| 340 | *  | 
            ||
| 341 | * The SQL statement must be a string suitable for being used as  | 
            ||
| 342 | * prepared statement. It must include question marks for binding  | 
            ||
| 343 | * the values from the locale item to the statement before they are  | 
            ||
| 344 | * sent to the database server. The order of the columns must  | 
            ||
| 345 | * correspond to the order in the save() method, so the  | 
            ||
| 346 | * correct values are bound to the columns.  | 
            ||
| 347 | *  | 
            ||
| 348 | * The SQL statement should conform to the ANSI standard to be  | 
            ||
| 349 | * compatible with most relational database systems. This also  | 
            ||
| 350 | * includes using double quotes for table and column names.  | 
            ||
| 351 | *  | 
            ||
| 352 | * @param string SQL statement for updating records  | 
            ||
| 353 | * @since 2014.03  | 
            ||
| 354 | * @category Developer  | 
            ||
| 355 | * @see mshop/locale/manager/insert/ansi  | 
            ||
| 356 | * @see mshop/locale/manager/newid/ansi  | 
            ||
| 357 | * @see mshop/locale/manager/delete/ansi  | 
            ||
| 358 | * @see mshop/locale/manager/search/ansi  | 
            ||
| 359 | * @see mshop/locale/manager/count/ansi  | 
            ||
| 360 | */  | 
            ||
| 361 | $path = 'mshop/locale/manager/update';  | 
            ||
| 362 | $sql = $this->addSqlColumns( array_keys( $columns ), $this->getSqlConfig( $path ), false );  | 
            ||
| 363 | }  | 
            ||
| 364 | |||
| 365 | $idx = 1;  | 
            ||
| 366 | $stmt = $this->getCachedStatement( $conn, $path, $sql );  | 
            ||
| 367 | |||
| 368 | 			foreach( $columns as $name => $entry ) { | 
            ||
| 369 | $stmt->bind( $idx++, $item->get( $name ), $entry->getInternalType() );  | 
            ||
| 370 | }  | 
            ||
| 371 | |||
| 372 | $stmt->bind( $idx++, $item->getLanguageId() );  | 
            ||
| 373 | $stmt->bind( $idx++, $item->getCurrencyId() );  | 
            ||
| 374 | $stmt->bind( $idx++, $item->getPosition(), \Aimeos\Base\DB\Statement\Base::PARAM_INT );  | 
            ||
| 375 | $stmt->bind( $idx++, $item->getStatus(), \Aimeos\Base\DB\Statement\Base::PARAM_INT );  | 
            ||
| 376 | $stmt->bind( $idx++, $date ); // mtime  | 
            ||
| 377 | $stmt->bind( $idx++, $context->editor() );  | 
            ||
| 378 | $stmt->bind( $idx++, $item->get( 'site_id' ), \Aimeos\Base\DB\Statement\Base::PARAM_INT );  | 
            ||
| 379 | $stmt->bind( $idx++, $item->getSiteId() );  | 
            ||
| 380 | |||
| 381 | 			if( $id !== null ) { | 
            ||
| 382 | $stmt->bind( $idx++, $id, \Aimeos\Base\DB\Statement\Base::PARAM_INT );  | 
            ||
| 383 | 			} else { | 
            ||
| 384 | $stmt->bind( $idx++, $date ); // ctime  | 
            ||
| 385 | }  | 
            ||
| 386 | |||
| 387 | $stmt->execute()->finish();  | 
            ||
| 388 | |||
| 389 | if( $id === null && $fetch === true )  | 
            ||
| 390 | 			{ | 
            ||
| 391 | /** mshop/locale/manager/newid/mysql  | 
            ||
| 392 | * Retrieves the ID generated by the database when inserting a new record  | 
            ||
| 393 | *  | 
            ||
| 394 | * @see mshop/locale/manager/newid/ansi  | 
            ||
| 395 | */  | 
            ||
| 396 | |||
| 397 | /** mshop/locale/manager/newid/ansi  | 
            ||
| 398 | * Retrieves the ID generated by the database when inserting a new record  | 
            ||
| 399 | *  | 
            ||
| 400 | * As soon as a new record is inserted into the database table,  | 
            ||
| 401 | * the database server generates a new and unique identifier for  | 
            ||
| 402 | * that record. This ID can be used for retrieving, updating and  | 
            ||
| 403 | * deleting that specific record from the table again.  | 
            ||
| 404 | *  | 
            ||
| 405 | * For MySQL:  | 
            ||
| 406 | * SELECT LAST_INSERT_ID()  | 
            ||
| 407 | * For PostgreSQL:  | 
            ||
| 408 | 				 *  SELECT currval('seq_mloc_id') | 
            ||
| 409 | * For SQL Server:  | 
            ||
| 410 | * SELECT SCOPE_IDENTITY()  | 
            ||
| 411 | * For Oracle:  | 
            ||
| 412 | * SELECT "seq_mloc_id".CURRVAL FROM DUAL  | 
            ||
| 413 | *  | 
            ||
| 414 | * There's no way to retrive the new ID by a SQL statements that  | 
            ||
| 415 | * fits for most database servers as they implement their own  | 
            ||
| 416 | * specific way.  | 
            ||
| 417 | *  | 
            ||
| 418 | * @param string SQL statement for retrieving the last inserted record ID  | 
            ||
| 419 | * @since 2014.03  | 
            ||
| 420 | * @category Developer  | 
            ||
| 421 | * @see mshop/locale/manager/insert/ansi  | 
            ||
| 422 | * @see mshop/locale/manager/update/ansi  | 
            ||
| 423 | * @see mshop/locale/manager/delete/ansi  | 
            ||
| 424 | * @see mshop/locale/manager/search/ansi  | 
            ||
| 425 | * @see mshop/locale/manager/count/ansi  | 
            ||
| 426 | */  | 
            ||
| 427 | $path = 'mshop/locale/manager/newid';  | 
            ||
| 428 | $id = $this->newId( $conn, $path );  | 
            ||
| 429 | }  | 
            ||
| 430 | |||
| 431 | $item->setId( $id );  | 
            ||
| 432 | |||
| 433 | return $item;  | 
            ||
| 434 | }  | 
            ||
| 435 | |||
| 436 | |||
| 437 | /**  | 
            ||
| 438 | * Returns a new manager for locale extensions  | 
            ||
| 439 | *  | 
            ||
| 440 | * @param string $manager Name of the sub manager type in lower case  | 
            ||
| 441 | * @param string|null $name Name of the implementation, will be from configuration (or Default) if null  | 
            ||
| 442 | * @return \Aimeos\MShop\Common\Manager\Iface Manager for different extensions, e.g site, language, currency.  | 
            ||
| 443 | */  | 
            ||
| 444 | public function getSubManager( string $manager, string $name = null ) : \Aimeos\MShop\Common\Manager\Iface  | 
            ||
| 445 | 	{ | 
            ||
| 446 | return $this->getSubManagerBase( 'locale', $manager, $name );  | 
            ||
| 447 | }  | 
            ||
| 448 | |||
| 449 | |||
| 450 | /**  | 
            ||
| 451 | * Returns the available manager types  | 
            ||
| 452 | *  | 
            ||
| 453 | * @param bool $withsub Return also the resource type of sub-managers if true  | 
            ||
| 454 | * @return string[] Type of the manager and submanagers, subtypes are separated by slashes  | 
            ||
| 455 | */  | 
            ||
| 456 | public function getResourceType( bool $withsub = true ) : array  | 
            ||
| 460 | }  | 
            ||
| 461 | |||
| 462 | |||
| 463 | /**  | 
            ||
| 464 | * Returns the attributes that can be used for searching.  | 
            ||
| 465 | *  | 
            ||
| 466 | * @param bool $withsub Return also attributes of sub-managers if true  | 
            ||
| 467 | * @return \Aimeos\Base\Criteria\Attribute\Iface[] List of search attribute items  | 
            ||
| 468 | */  | 
            ||
| 469 | public function getSearchAttributes( bool $withsub = true ) : array  | 
            ||
| 470 | 	{ | 
            ||
| 471 | /** mshop/locale/manager/submanagers  | 
            ||
| 472 | * List of manager names that can be instantiated by the locale manager  | 
            ||
| 473 | *  | 
            ||
| 474 | * Managers provide a generic interface to the underlying storage.  | 
            ||
| 475 | * Each manager has or can have sub-managers caring about particular  | 
            ||
| 476 | * aspects. Each of these sub-managers can be instantiated by its  | 
            ||
| 477 | * parent manager using the getSubManager() method.  | 
            ||
| 478 | *  | 
            ||
| 479 | * The search keys from sub-managers can be normally used in the  | 
            ||
| 480 | * manager as well. It allows you to search for items of the manager  | 
            ||
| 481 | * using the search keys of the sub-managers to further limit the  | 
            ||
| 482 | * retrieved list of items.  | 
            ||
| 483 | *  | 
            ||
| 484 | * @param array List of sub-manager names  | 
            ||
| 485 | * @since 2014.03  | 
            ||
| 486 | * @category Developer  | 
            ||
| 487 | */  | 
            ||
| 488 | $path = 'mshop/locale/manager/submanagers';  | 
            ||
| 489 | $default = array( 'language', 'currency', 'site' );  | 
            ||
| 490 | |||
| 491 | return $this->getSearchAttributesBase( $this->searchConfig, $path, $default, $withsub );  | 
            ||
| 492 | }  | 
            ||
| 493 | |||
| 494 | |||
| 495 | /**  | 
            ||
| 496 | * Returns the locale item for the given site code, language code and currency code.  | 
            ||
| 497 | *  | 
            ||
| 498 | * If the locale item is inherited from a parent site, the site ID of this locale item  | 
            ||
| 499 | * is changed to the site ID of the actual site. This ensures that items assigned to  | 
            ||
| 500 | * the same site as the site item are still used.  | 
            ||
| 501 | *  | 
            ||
| 502 | * @param string $site Site code  | 
            ||
| 503 | * @param string $lang Language code  | 
            ||
| 504 | * @param string $currency Currency code  | 
            ||
| 505 | * @param bool $active Flag to get only active items  | 
            ||
| 506 | * @param \Aimeos\MShop\Locale\Item\Site\Iface $siteItem Site item  | 
            ||
| 507 | * @param string $siteId Site ID  | 
            ||
| 508 | * @param array $sites Associative list of site constant as key and sites as values  | 
            ||
| 509 | * @param bool $bare Allow locale items with sites only  | 
            ||
| 510 | * @return \Aimeos\MShop\Locale\Item\Iface Locale item for the given parameters  | 
            ||
| 511 | * @throws \Aimeos\MShop\Locale\Exception If no locale item is found  | 
            ||
| 512 | */  | 
            ||
| 513 | protected function bootstrapBase( string $site, string $lang, string $currency, bool $active,  | 
            ||
| 514 | \Aimeos\MShop\Locale\Item\Site\Iface $siteItem, string $siteId, array $sites, bool $bare ) : \Aimeos\MShop\Locale\Item\Iface  | 
            ||
| 515 | 	{ | 
            ||
| 516 | 		if( $result = $this->bootstrapMatch( $siteId, $lang, $currency, $active, $siteItem, $sites ) ) { | 
            ||
| 517 | return $result;  | 
            ||
| 518 | }  | 
            ||
| 519 | |||
| 520 | 		if( $result = $this->bootstrapClosest( $siteId, $lang, $active, $siteItem, $sites ) ) { | 
            ||
| 521 | return $result;  | 
            ||
| 522 | }  | 
            ||
| 523 | |||
| 524 | 		if( $bare === true ) { | 
            ||
| 525 | return $this->createItemBase( ['locale.siteid' => $siteId], $siteItem, $sites );  | 
            ||
| 526 | }  | 
            ||
| 527 | |||
| 528 | $msg = $this->context()->translate( 'mshop', 'Locale item for site "%1$s" not found' );  | 
            ||
| 529 | throw new \Aimeos\MShop\Locale\Exception( sprintf( $msg, $site ) );  | 
            ||
| 530 | }  | 
            ||
| 531 | |||
| 532 | |||
| 533 | /**  | 
            ||
| 534 | * Returns the matching locale item for the given site code, language code and currency code.  | 
            ||
| 535 | *  | 
            ||
| 536 | * If the locale item is inherited from a parent site, the site ID of this locale item  | 
            ||
| 537 | * is changed to the site ID of the actual site. This ensures that items assigned to  | 
            ||
| 538 | * the same site as the site item are still used.  | 
            ||
| 539 | *  | 
            ||
| 540 | * @param string $siteId Site ID  | 
            ||
| 541 | * @param string $lang Language code  | 
            ||
| 542 | * @param string $currency Currency code  | 
            ||
| 543 | * @param bool $active Flag to get only active items  | 
            ||
| 544 | * @param \Aimeos\MShop\Locale\Item\Site\Iface $siteItem Site item  | 
            ||
| 545 | * @param array $sites Associative list of site constant as key and sites as values  | 
            ||
| 546 | * @return \Aimeos\MShop\Locale\Item\Iface|null Locale item for the given parameters or null if no item was found  | 
            ||
| 547 | */  | 
            ||
| 548 | private function bootstrapMatch( string $siteId, string $lang, string $currency, bool $active,  | 
            ||
| 549 | \Aimeos\MShop\Locale\Item\Site\Iface $siteItem, array $sites ) : ?\Aimeos\MShop\Locale\Item\Iface  | 
            ||
| 550 | 	{ | 
            ||
| 551 | // Try to find exact match  | 
            ||
| 552 | $search = $this->object()->filter( $active );  | 
            ||
| 553 | |||
| 554 | $expr = array( $search->compare( '==', 'locale.siteid', $sites[Base::SITE_PATH] ?? $sites[Base::SITE_ONE] ) );  | 
            ||
| 555 | |||
| 556 | if( !empty( $lang ) )  | 
            ||
| 557 | 		{ | 
            ||
| 558 | $langIds = strlen( $lang ) > 2 ? [$lang, substr( $lang, 0, 2 )] : [$lang];  | 
            ||
| 559 | $expr[] = $search->compare( '==', 'locale.languageid', $langIds );  | 
            ||
| 560 | }  | 
            ||
| 561 | |||
| 562 | 		if( !empty( $currency ) ) { | 
            ||
| 563 | $expr[] = $search->compare( '==', 'locale.currencyid', $currency );  | 
            ||
| 564 | }  | 
            ||
| 565 | |||
| 566 | $expr[] = $search->getConditions();  | 
            ||
| 567 | |||
| 568 | |||
| 569 | if( $active === true )  | 
            ||
| 570 | 		{ | 
            ||
| 571 | $expr[] = $search->compare( '>', 'locale.currency.status', 0 );  | 
            ||
| 572 | $expr[] = $search->compare( '>', 'locale.language.status', 0 );  | 
            ||
| 573 | $expr[] = $search->compare( '>', 'locale.site.status', 0 );  | 
            ||
| 574 | }  | 
            ||
| 575 | |||
| 576 | $search->setConditions( $search->and( $expr ) );  | 
            ||
| 577 | $search->setSortations( array( $search->sort( '+', 'locale.position' ) ) );  | 
            ||
| 578 | $result = $this->searchEntries( $search );  | 
            ||
| 579 | |||
| 580 | // Try to find first item where site matches  | 
            ||
| 581 | foreach( $result as $row )  | 
            ||
| 582 | 		{ | 
            ||
| 583 | 			if( $row['locale.siteid'] === $siteId ) { | 
            ||
| 584 | return $this->createItemBase( $row, $siteItem, $sites );  | 
            ||
| 585 | }  | 
            ||
| 586 | }  | 
            ||
| 587 | |||
| 588 | if( ( $row = reset( $result ) ) !== false )  | 
            ||
| 589 | 		{ | 
            ||
| 590 | $row['locale.siteid'] = $siteId;  | 
            ||
| 591 | return $this->createItemBase( $row, $siteItem, $sites );  | 
            ||
| 592 | }  | 
            ||
| 593 | |||
| 594 | return null;  | 
            ||
| 595 | }  | 
            ||
| 596 | |||
| 597 | |||
| 598 | /**  | 
            ||
| 599 | * Returns the locale item for the given site code, language code and currency code.  | 
            ||
| 600 | *  | 
            ||
| 601 | * If the locale item is inherited from a parent site, the site ID of this locale item  | 
            ||
| 602 | * is changed to the site ID of the actual site. This ensures that items assigned to  | 
            ||
| 603 | * the same site as the site item are still used.  | 
            ||
| 604 | *  | 
            ||
| 605 | * @param string $siteId Site ID  | 
            ||
| 606 | * @param string $lang Language code  | 
            ||
| 607 | * @param bool $active Flag to get only active items  | 
            ||
| 608 | * @param \Aimeos\MShop\Locale\Item\Site\Iface $siteItem Site item  | 
            ||
| 609 | * @param array $sites Associative list of site constant as key and sites as values  | 
            ||
| 610 | * @return \Aimeos\MShop\Locale\Item\Iface|null Locale item for the given parameters or null if no item was found  | 
            ||
| 611 | */  | 
            ||
| 612 | private function bootstrapClosest( string $siteId, string $lang, bool $active,  | 
            ||
| 670 | }  | 
            ||
| 671 | |||
| 672 | |||
| 673 | /**  | 
            ||
| 674 | * Instances a new locale item object.  | 
            ||
| 675 | *  | 
            ||
| 676 | * @param array $values Parameter to initialise the item  | 
            ||
| 677 | * @param \Aimeos\MShop\Locale\Item\Site\Iface|null $site Site item  | 
            ||
| 678 | * @param array $sites Associative list of site constant as key and sites as values  | 
            ||
| 679 | * @return \Aimeos\MShop\Locale\Item\Iface Locale item  | 
            ||
| 680 | */  | 
            ||
| 681 | protected function createItemBase( array $values = [], \Aimeos\MShop\Locale\Item\Site\Iface $site = null,  | 
            ||
| 685 | }  | 
            ||
| 686 | |||
| 687 | |||
| 688 | /**  | 
            ||
| 689 | * Returns the search results for the given SQL statement.  | 
            ||
| 690 | *  | 
            ||
| 691 | * @param \Aimeos\Base\DB\Connection\Iface $conn Database connection  | 
            ||
| 692 | * @param string $sql SQL statement  | 
            ||
| 693 | * @return \Aimeos\Base\DB\Result\Iface Search result object  | 
            ||
| 694 | */  | 
            ||
| 695 | protected function getSearchResults( \Aimeos\Base\DB\Connection\Iface $conn, string $sql ) : \Aimeos\Base\DB\Result\Iface  | 
            ||
| 696 | 	{ | 
            ||
| 697 | $time = microtime( true );  | 
            ||
| 698 | |||
| 699 | $stmt = $conn->create( $sql );  | 
            ||
| 700 | $result = $stmt->execute();  | 
            ||
| 701 | |||
| 702 | $msg = 'Time: ' . ( microtime( true ) - $time ) * 1000 . "ms\n"  | 
            ||
| 703 | . 'Class: ' . get_class( $this ) . "\n"  | 
            ||
| 704 | . str_replace( ["\t", "\n\n"], ['', "\n"], trim( (string) $stmt ) );  | 
            ||
| 705 | |||
| 706 | $this->context()->logger()->debug( $msg, 'core/sql' );  | 
            ||
| 707 | |||
| 708 | return $result;  | 
            ||
| 709 | }  | 
            ||
| 710 | |||
| 711 | |||
| 712 | /**  | 
            ||
| 713 | * Searches for all items matching the given critera.  | 
            ||
| 714 | *  | 
            ||
| 715 | * @param \Aimeos\Base\Criteria\Iface $search Criteria object with conditions, sortations, etc.  | 
            ||
| 716 | * @param string[] $ref List of domains to fetch list items and referenced items for  | 
            ||
| 717 | * @param int &$total Number of items that are available in total  | 
            ||
| 718 | * @return array Associative list of key/value pairs  | 
            ||
| 719 | */  | 
            ||
| 720 | protected function searchEntries( \Aimeos\Base\Criteria\Iface $search, array $ref = [], int &$total = null ) : array  | 
            ||
| 880 | }  | 
            ||
| 881 | }  | 
            ||
| 882 |