1<?php 2/** 3 * 2007-2016 PrestaShop 4 * 5 * thirty bees is an extension to the PrestaShop e-commerce software developed by PrestaShop SA 6 * Copyright (C) 2017-2018 thirty bees 7 * 8 * NOTICE OF LICENSE 9 * 10 * This source file is subject to the Open Software License (OSL 3.0) 11 * that is bundled with this package in the file LICENSE.txt. 12 * It is also available through the world-wide-web at this URL: 13 * http://opensource.org/licenses/osl-3.0.php 14 * If you did not receive a copy of the license and are unable to 15 * obtain it through the world-wide-web, please send an email 16 * to license@thirtybees.com so we can send you a copy immediately. 17 * 18 * DISCLAIMER 19 * 20 * Do not edit or add to this file if you wish to upgrade PrestaShop to newer 21 * versions in the future. If you wish to customize PrestaShop for your 22 * needs please refer to https://www.thirtybees.com for more information. 23 * 24 * @author thirty bees <contact@thirtybees.com> 25 * @author PrestaShop SA <contact@prestashop.com> 26 * @copyright 2017-2018 thirty bees 27 * @copyright 2007-2016 PrestaShop SA 28 * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 29 * PrestaShop is an internationally registered trademark & property of PrestaShop SA 30 */ 31 32/** 33 * Class ShopCore 34 * 35 * @since 1.0.0 36 */ 37class ShopCore extends ObjectModel 38{ 39 // @codingStandardsIgnoreStart 40 /** 41 * @see ObjectModel::$definition 42 */ 43 public static $definition = [ 44 'table' => 'shop', 45 'primary' => 'id_shop', 46 'fields' => [ 47 'active' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool' ], 48 'deleted' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool' ], 49 'name' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => true, 'size' => 64], 50 'id_theme' => ['type' => self::TYPE_INT, 'required' => true ], 51 'id_category' => ['type' => self::TYPE_INT, 'required' => true ], 52 'id_shop_group' => ['type' => self::TYPE_INT, 'required' => true ], 53 ], 54 ]; 55 protected $webserviceParameters = [ 56 'fields' => [ 57 'id_shop_group' => ['xlink_resource' => 'shop_groups'], 58 'id_category' => [], 59 'id_theme' => [], 60 ], 61 ]; 62 /** @var int ID of shop group */ 63 public $id_shop_group; 64 /** @var int ID of shop category */ 65 public $id_category; 66 /** @var int ID of shop theme */ 67 public $id_theme; 68 /** @var string Shop name */ 69 public $name; 70 /** @var bool $active */ 71 public $active = true; 72 /** @var bool $deleted */ 73 public $deleted; 74 /** @var string Shop theme name (read only) */ 75 public $theme_name; 76 /** @var string Shop theme directory (read only) */ 77 public $theme_directory; 78 /** @var string Physical uri of main url (read only) */ 79 public $physical_uri; 80 /** @var string Virtual uri of main url (read only) */ 81 public $virtual_uri; 82 /** @var string Domain of main url (read only) */ 83 public $domain; 84 /** @var string Domain SSL of main url (read only) */ 85 public $domain_ssl; 86 /** @var ShopGroup Shop group object */ 87 protected $group; 88 /** @var array List of shops cached */ 89 protected static $shops; 90 /** @var array $asso_tables */ 91 protected static $asso_tables = []; 92 /** @var array $id_shop_default_tables */ 93 protected static $id_shop_default_tables = []; 94 /** @var bool $initialized */ 95 protected static $initialized = false; 96 /** 97 * Store the current context of shop (CONTEXT_ALL, CONTEXT_GROUP, CONTEXT_SHOP) 98 * 99 * @var int $context ; 100 */ 101 protected static $context; 102 /** 103 * ID shop in the current context (will be empty if context is not CONTEXT_SHOP) 104 * 105 * @var int $context_id_shop 106 */ 107 protected static $context_id_shop; 108 /** 109 * ID shop group in the current context (will be empty if context is CONTEXT_ALL) 110 * 111 * @var int $context_id_shop_group 112 */ 113 protected static $context_id_shop_group; 114 // @codingStandardsIgnoreEnd 115 116 /** 117 * There are 3 kinds of shop context : shop, group shop and general 118 */ 119 const CONTEXT_SHOP = 1; 120 const CONTEXT_GROUP = 2; 121 const CONTEXT_ALL = 4; 122 123 /** 124 * Some data can be shared between shops, like customers or orders 125 */ 126 const SHARE_CUSTOMER = 'share_customer'; 127 const SHARE_ORDER = 'share_order'; 128 const SHARE_STOCK = 'share_stock'; 129 130 /** 131 * On shop instance, get its theme and URL data too 132 * 133 * @param int $id 134 * @param int $idLang 135 * @param int $idShop 136 * 137 * 138 * @throws PrestaShopDatabaseException 139 * @throws PrestaShopException 140 * @since 1.0.0 141 * @version 1.0.0 Initial version 142 */ 143 public function __construct($id = null, $idLang = null, $idShop = null) 144 { 145 parent::__construct($id, $idLang, $idShop); 146 if ($this->id) { 147 $this->setUrl(); 148 } 149 } 150 151 /** 152 * @return bool 153 * 154 * @throws PrestaShopDatabaseException 155 * @throws PrestaShopException 156 * @since 1.0.0 157 * @version 1.0.0 Initial version 158 */ 159 public function setUrl() 160 { 161 $cacheId = 'Shop::setUrl_'.(int) $this->id; 162 if (!Cache::isStored($cacheId)) { 163 $row = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow( 164 (new DbQuery()) 165 ->select('su.physical_uri, su.virtual_uri, su.domain, su.domain_ssl, t.id_theme, t.name, t.directory') 166 ->from('shop', 's') 167 ->leftJoin('shop_url', 'su', 's.`id_shop` = su.`id_shop`') 168 ->leftJoin('theme', 't', 't.`id_theme` = s.`id_theme`') 169 ->where('s.`id_shop` = '.(int) $this->id) 170 ->where('s.`active` = 1') 171 ->where('s.`deleted` = 0') 172 ->where('su.`main` = 1') 173 ); 174 Cache::store($cacheId, $row); 175 } else { 176 $row = Cache::retrieve($cacheId); 177 } 178 if (!$row) { 179 return false; 180 } 181 182 $this->theme_id = $row['id_theme']; 183 $this->theme_name = $row['name']; 184 $this->theme_directory = $row['directory']; 185 $this->physical_uri = $row['physical_uri']; 186 $this->virtual_uri = $row['virtual_uri']; 187 $this->domain = $row['domain']; 188 $this->domain_ssl = $row['domain_ssl']; 189 190 return true; 191 } 192 193 /** 194 * Add a shop, and clear the cache 195 * 196 * @param bool $autoDate 197 * @param bool $nullValues 198 * 199 * @return bool 200 * @throws PrestaShopDatabaseException 201 * @throws PrestaShopException 202 */ 203 public function add($autoDate = true, $nullValues = false) 204 { 205 $res = parent::add($autoDate, $nullValues); 206 // Set default language routes 207 $langs = Language::getLanguages(false, $this->id, true); 208 // @codingStandardsIgnoreStart 209 Configuration::updateValue('PS_ROUTE_product_rule', array_map(function() {return '{categories:/}{rewrite}';}, $langs)); 210 Configuration::updateValue('PS_ROUTE_category_rule', array_map(function() {return '{rewrite}';}, $langs)); 211 Configuration::updateValue('PS_ROUTE_supplier_rule', array_map(function() {return '{rewrite}';}, $langs)); 212 Configuration::updateValue('PS_ROUTE_manufacturer_rule', array_map(function() {return '{rewrite}';}, $langs)); 213 Configuration::updateValue('PS_ROUTE_cms_rule', array_map(function() {return '{categories:/}{rewrite}';}, $langs)); 214 Configuration::updateValue('PS_ROUTE_cms_category_rule', array_map(function() {return '{categories:/}{rewrite}';}, $langs)); 215 // @codingStandardsIgnoreEnd 216 217 static::cacheShops(true); 218 219 return $res; 220 } 221 222 /** 223 * @since 1.0.0 224 * @version 1.0.0 Initial version 225 */ 226 public function associateSuperAdmins() 227 { 228 $superAdmins = Employee::getEmployeesByProfile(_PS_ADMIN_PROFILE_); 229 foreach ($superAdmins as $superAdmin) { 230 $employee = new Employee((int) $superAdmin['id_employee']); 231 $employee->associateTo((int) $this->id); 232 } 233 } 234 235 /** 236 * Remove a shop only if it has no dependencies, and remove its associations 237 * 238 * @return bool 239 * 240 * @throws PrestaShopDatabaseException 241 * @throws PrestaShopException 242 * @since 1.0.0 243 * @version 1.0.0 Initial version 244 */ 245 public function delete() 246 { 247 if (static::hasDependency($this->id) || !$res = parent::delete()) { 248 return false; 249 } 250 251 foreach (static::getAssoTables() as $tableName => $row) { 252 $id = 'id_'.$row['type']; 253 if ($row['type'] == 'fk_shop') { 254 $id = 'id_shop'; 255 } else { 256 $tableName .= '_'.$row['type']; 257 } 258 $res &= Db::getInstance()->delete(bqSQL($tableName), '`'.bqSQL($id).'`='.(int) $this->id); 259 } 260 261 // removes stock available 262 $res &= Db::getInstance()->delete('stock_available', '`id_shop` = '.(int) $this->id); 263 264 // Remove urls 265 $res &= Db::getInstance()->delete('shop_url', '`id_shop` = '.(int) $this->id); 266 267 // Remove currency restrictions 268 $res &= Db::getInstance()->delete('module_currency', '`id_shop` = '.(int) $this->id); 269 270 // Remove group restrictions 271 $res &= Db::getInstance()->delete('module_group', '`id_shop` = '.(int) $this->id); 272 273 // Remove country restrictions 274 $res &= Db::getInstance()->delete('module_country', '`id_shop` = '.(int) $this->id); 275 276 // Remove carrier restrictions 277 $res &= Db::getInstance()->delete('module_carrier', '`id_shop` = '.(int) $this->id); 278 279 static::cacheShops(true); 280 281 return $res; 282 } 283 284 /** 285 * Detect dependency with customer or orders 286 * 287 * @param int $idShop 288 * 289 * @return bool 290 * 291 * @since 1.0.0 292 * @version 1.0.0 Initial version 293 * @throws PrestaShopException 294 */ 295 public static function hasDependency($idShop) 296 { 297 $hasDependency = false; 298 $nbrCustomer = (int) Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue( 299 (new DbQuery()) 300 ->select('COUNT(*)') 301 ->from('customer') 302 ->where('`id_shop` = '.(int) $idShop) 303 ); 304 if ($nbrCustomer) { 305 $hasDependency = true; 306 } else { 307 $nbrOrder = (int) Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue( 308 (new DbQuery()) 309 ->select('COUNT(*)') 310 ->from('orders') 311 ->where('`id_shop` = '.(int) $idShop) 312 ); 313 if ($nbrOrder) { 314 $hasDependency = true; 315 } 316 } 317 318 return $hasDependency; 319 } 320 321 /** 322 * Find the shop from current domain / uri and get an instance of this shop 323 * 324 * @return Shop 325 * @throws PrestaShopException 326 * @since 1.0.0 327 * @version 1.0.0 Initial version 328 */ 329 public static function initialize() 330 { 331 // Find current shop from URL 332 if (!($idShop = Tools::getValue('id_shop')) || defined('_PS_ADMIN_DIR_')) { 333 $foundUri = ''; 334 $isMainUri = false; 335 $host = Tools::getHttpHost(); 336 $requestUri = rawurldecode($_SERVER['REQUEST_URI']); 337 338 $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS( 339 (new DbQuery()) 340 ->select('s.`id_shop`, CONCAT(su.`physical_uri`, su.`virtual_uri`) AS `uri`, su.`domain`, su.`main`') 341 ->from('shop_url', 'su') 342 ->leftJoin('shop', 's', 's.`id_shop` = su.`id_shop`') 343 ->where('su.domain = \''.pSQL($host).'\' OR su.domain_ssl = \''.pSQL($host).'\'') 344 ->where('s.`active` = 1') 345 ->where('s.`deleted` = 0') 346 ->orderBy('LENGTH(CONCAT(su.`physical_uri`, su.`virtual_uri`)) DESC') 347 ); 348 349 $through = false; 350 foreach ($result as $row) { 351 // An URL matching current shop was found 352 if (preg_match('#^'.preg_quote($row['uri'], '#').'#i', $requestUri)) { 353 $through = true; 354 $idShop = $row['id_shop']; 355 $foundUri = $row['uri']; 356 if ($row['main']) { 357 $isMainUri = true; 358 } 359 break; 360 } 361 } 362 363 // If an URL was found but is not the main URL, redirect to main URL 364 if ($through && $idShop && !$isMainUri) { 365 foreach ($result as $row) { 366 if ($row['id_shop'] == $idShop && $row['main']) { 367 $requestUri = substr($requestUri, strlen($foundUri)); 368 $url = str_replace('//', '/', $row['domain'].$row['uri'].$requestUri); 369 $redirectType = Configuration::get('PS_CANONICAL_REDIRECT'); 370 $redirectCode = ($redirectType == 1 ? '302' : '301'); 371 $redirectHeader = ($redirectType == 1 ? 'Found' : 'Moved Permanently'); 372 header('HTTP/1.0 '.$redirectCode.' '.$redirectHeader); 373 header('Cache-Control: no-cache'); 374 header('Location: '.Tools::getShopProtocol().$url); 375 exit; 376 } 377 } 378 } 379 } 380 381 $httpHost = Tools::getHttpHost(); 382 $allMedia = array_merge(Configuration::getMultiShopValues('PS_MEDIA_SERVER_1'), Configuration::getMultiShopValues('PS_MEDIA_SERVER_2'), Configuration::getMultiShopValues('PS_MEDIA_SERVER_3')); 383 384 if ((!$idShop && defined('_PS_ADMIN_DIR_')) || Tools::isPHPCLI() || in_array($httpHost, $allMedia)) { 385 // If in admin, we can access to the shop without right URL 386 if ((!$idShop && Tools::isPHPCLI()) || defined('_PS_ADMIN_DIR_')) { 387 $idShop = (int) Configuration::get('PS_SHOP_DEFAULT'); 388 } 389 390 $shop = new Shop((int) $idShop); 391 if (!Validate::isLoadedObject($shop)) { 392 $shop = new Shop((int) Configuration::get('PS_SHOP_DEFAULT')); 393 } 394 395 $shop->virtual_uri = ''; 396 397 // Define some $_SERVER variables like HTTP_HOST if PHP is launched with php-cli 398 if (Tools::isPHPCLI()) { 399 if (!isset($_SERVER['HTTP_HOST']) || empty($_SERVER['HTTP_HOST'])) { 400 $_SERVER['HTTP_HOST'] = $shop->domain; 401 } 402 if (!isset($_SERVER['SERVER_NAME']) || empty($_SERVER['SERVER_NAME'])) { 403 $_SERVER['SERVER_NAME'] = $shop->domain; 404 } 405 if (!isset($_SERVER['REMOTE_ADDR']) || empty($_SERVER['REMOTE_ADDR'])) { 406 $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; 407 } 408 } 409 } else { 410 $shop = new Shop($idShop); 411 if (!Validate::isLoadedObject($shop) || !$shop->active) { 412 // No shop found ... too bad, let's redirect to default shop 413 $defaultShop = new Shop(Configuration::get('PS_SHOP_DEFAULT')); 414 415 // Hmm there is something really bad in your Prestashop ! 416 if (!Validate::isLoadedObject($defaultShop)) { 417 throw new PrestaShopException('Shop not found'); 418 } 419 420 $params = $_GET; 421 unset($params['id_shop']); 422 $url = $defaultShop->domain; 423 if (!Configuration::get('PS_REWRITING_SETTINGS')) { 424 $url .= $defaultShop->getBaseURI().'index.php?'.http_build_query($params); 425 } else { 426 // Catch url with subdomain "www" 427 if (strpos($url, 'www.') === 0 && 'www.'.$_SERVER['HTTP_HOST'] === $url || $_SERVER['HTTP_HOST'] === 'www.'.$url) { 428 $url .= $_SERVER['REQUEST_URI']; 429 } else { 430 $url .= $defaultShop->getBaseURI(); 431 } 432 433 if (count($params)) { 434 $url .= '?'.http_build_query($params); 435 } 436 } 437 438 $redirectType = Configuration::get('PS_CANONICAL_REDIRECT'); 439 $redirectCode = ($redirectType == 1 ? '302' : '301'); 440 $redirectHeader = ($redirectType == 1 ? 'Found' : 'Moved Permanently'); 441 header('HTTP/1.0 '.$redirectCode.' '.$redirectHeader); 442 header('Location: '.Tools::getShopProtocol().$url); 443 exit; 444 } elseif (defined('_PS_ADMIN_DIR_') && empty($shop->physical_uri)) { 445 $shopDefault = new Shop((int) Configuration::get('PS_SHOP_DEFAULT')); 446 $shop->physical_uri = $shopDefault->physical_uri; 447 $shop->virtual_uri = $shopDefault->virtual_uri; 448 } 449 } 450 451 // @codingStandardsIgnoreStart 452 static::$context_id_shop = $shop->id; 453 static::$context_id_shop_group = $shop->id_shop_group; 454 static::$context = static::CONTEXT_SHOP; 455 // @codingStandardsIgnoreEnd 456 457 return $shop; 458 } 459 460 /** 461 * @return Address the current shop address 462 * 463 * @since 1.0.0 464 * @version 1.0.0 Initial version 465 * @throws PrestaShopException 466 */ 467 public function getAddress() 468 { 469 if (!isset($this->address)) { 470 $address = new Address(); 471 $address->company = Configuration::get('PS_SHOP_NAME'); 472 $address->id_country = Configuration::get('PS_SHOP_COUNTRY_ID') ? Configuration::get('PS_SHOP_COUNTRY_ID') : Configuration::get('PS_COUNTRY_DEFAULT'); 473 $address->id_state = Configuration::get('PS_SHOP_STATE_ID'); 474 $address->address1 = Configuration::get('PS_SHOP_ADDR1'); 475 $address->address2 = Configuration::get('PS_SHOP_ADDR2'); 476 $address->postcode = Configuration::get('PS_SHOP_CODE'); 477 $address->city = Configuration::get('PS_SHOP_CITY'); 478 479 $this->address = $address; 480 } 481 482 return $this->address; 483 } 484 485 /** 486 * Get shop theme name 487 * 488 * @return string 489 * 490 * @since 1.0.0 491 * @version 1.0.0 Initial version 492 */ 493 public function getTheme() 494 { 495 return $this->theme_directory; 496 } 497 498 /** 499 * Get shop URI 500 * 501 * @return string 502 * 503 * @since 1.0.0 504 * @version 1.0.0 Initial version 505 */ 506 public function getBaseURI() 507 { 508 return $this->physical_uri.$this->virtual_uri; 509 } 510 511 /** 512 * Get shop URL 513 * 514 * @param bool|string $autoSecureMode if set to true, secure mode will be checked 515 * @param bool|string $addBaseUri if set to true, shop base uri will be added 516 * 517 * @return string complete base url of current shop 518 * 519 * @since 1.0.0 520 * @version 1.0.0 Initial version 521 */ 522 public function getBaseURL($autoSecureMode = false, $addBaseUri = true) 523 { 524 if (($autoSecureMode && Tools::usingSecureMode() && !$this->domain_ssl) || !$this->domain) { 525 return false; 526 } 527 528 $url = []; 529 $url['protocol'] = $autoSecureMode && Tools::usingSecureMode() ? 'https://' : 'http://'; 530 $url['domain'] = $autoSecureMode && Tools::usingSecureMode() ? $this->domain_ssl : $this->domain; 531 532 if ($addBaseUri) { 533 $url['base_uri'] = $this->getBaseURI(); 534 } 535 536 return implode('', $url); 537 } 538 539 /** 540 * Get group of current shop 541 * 542 * @return ShopGroup 543 * 544 * @since 1.0.0 545 * @version 1.0.0 Initial version 546 */ 547 public function getGroup() 548 { 549 if (!$this->group) { 550 $this->group = new ShopGroup($this->id_shop_group); 551 } 552 553 return $this->group; 554 } 555 556 /** 557 * Get root category of current shop 558 * 559 * @return int 560 * 561 * @since 1.0.0 562 * @version 1.0.0 Initial version 563 * @throws PrestaShopException 564 */ 565 public function getCategory() 566 { 567 return (int) ($this->id_category ? $this->id_category : Configuration::get('PS_ROOT_CATEGORY')); 568 } 569 570 /** 571 * Get list of shop's urls 572 * 573 * @return array 574 * 575 * @throws PrestaShopDatabaseException 576 * @throws PrestaShopException 577 * @since 1.0.0 578 * @version 1.0.0 Initial version 579 */ 580 public function getUrls() 581 { 582 return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS( 583 (new DbQuery()) 584 ->select('*') 585 ->from('shop_url') 586 ->where('`active` = 1') 587 ->where('`id_shop` = '.(int) $this->id) 588 ); 589 } 590 591 /** 592 * Check if current shop ID is the same as default shop in configuration 593 * 594 * @return bool 595 * 596 * @since 1.0.0 597 * @version 1.0.0 Initial version 598 * @throws PrestaShopException 599 */ 600 public function isDefaultShop() 601 { 602 return $this->id == Configuration::get('PS_SHOP_DEFAULT'); 603 } 604 605 /** 606 * Get the associated table if available 607 * 608 * @param string $table 609 * 610 * @return false|array 611 * @since 1.0.0 612 * @version 1.0.0 Initial version 613 */ 614 public static function getAssoTable($table) 615 { 616 if (!static::$initialized) { 617 static::init(); 618 } 619 620 // @codingStandardsIgnoreStart 621 return (isset(static::$asso_tables[$table]) ? static::$asso_tables[$table] : false); 622 // @codingStandardsIgnoreEnd 623 } 624 625 /** 626 * check if the table has an id_shop_default 627 * 628 * @param string $table 629 * 630 * @return bool 631 * @since 1.0.0 632 * @version 1.0.0 Initial version 633 */ 634 public static function checkIdShopDefault($table) 635 { 636 if (!static::$initialized) { 637 static::init(); 638 } 639 640 // @codingStandardsIgnoreStart 641 return in_array($table, static::$id_shop_default_tables); 642 // @codingStandardsIgnoreEnd 643 } 644 645 /** 646 * Get list of associated tables to shop 647 * 648 * @return array 649 * 650 * @since 1.0.0 651 * @version 1.0.0 Initial version 652 */ 653 public static function getAssoTables() 654 { 655 if (!static::$initialized) { 656 static::init(); 657 } 658 659 // @codingStandardsIgnoreStart 660 return static::$asso_tables; 661 // @codingStandardsIgnoreEnd 662 } 663 664 /** 665 * Add table associated to shop 666 * 667 * @param string $tableName 668 * @param array $tableDetails 669 * 670 * @return bool 671 * 672 * @since 1.0.0 673 * @version 1.0.0 Initial version 674 */ 675 public static function addTableAssociation($tableName, $tableDetails) 676 { 677 // @codingStandardsIgnoreStart 678 if (!isset(static::$asso_tables[$tableName])) { 679 static::$asso_tables[$tableName] = $tableDetails; 680 } else { 681 return false; 682 } 683 // @codingStandardsIgnoreEnd 684 685 return true; 686 } 687 688 /** 689 * Check if given table is associated to shop 690 * 691 * @param string $table 692 * 693 * @return bool 694 * 695 * @since 1.0.0 696 * @version 1.0.0 Initial version 697 */ 698 public static function isTableAssociated($table) 699 { 700 if (!static::$initialized) { 701 static::init(); 702 } 703 704 // @codingStandardsIgnoreStart 705 return isset(static::$asso_tables[$table]) && static::$asso_tables[$table]['type'] == 'shop'; 706 // @codingStandardsIgnoreEnd 707 } 708 709 /** 710 * Load list of groups and shops, and cache it 711 * 712 * @param bool $refresh 713 * 714 * @throws PrestaShopDatabaseException 715 * @throws PrestaShopException 716 * @since 1.0.0 717 * @version 1.0.0 Initial version 718 */ 719 public static function cacheShops($refresh = false) 720 { 721 if (!is_null(static::$shops) && !$refresh) { 722 return; 723 } 724 725 static::$shops = []; 726 727 $employee = Context::getContext()->employee; 728 729 $sql = (new DbQuery()) 730 ->select('gs.*, s.*, gs.`name` AS `group_name`, s.`name` AS `shop_name`, s.`active`') 731 ->select('su.`domain`, su.`domain_ssl`, su.`physical_uri`, su.`virtual_uri`') 732 ->from('shop_group', 'gs') 733 ->leftJoin('shop', 's', 's.`id_shop_group` = gs.`id_shop_group`') 734 ->leftJoin('shop_url', 'su', 's.`id_shop` = su.`id_shop` AND su.`main` = 1') 735 ->where('s.`deleted` = 0') 736 ->where('gs.`deleted` = 0') 737 ->orderBy('gs.`name`, s.`name`') 738 ; 739 740 // If the profile isn't a superAdmin 741 if (Validate::isLoadedObject($employee) && $employee->id_profile != _PS_ADMIN_PROFILE_) { 742 $sql->leftJoin('employee_shop', 'es', 'es.`id_shop` = s.`id_shop`'); 743 $sql->where('es.`id_employee` = '.(int) $employee->id); 744 } 745 746 if ($results = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql)) { 747 foreach ($results as $row) { 748 if (!isset(static::$shops[$row['id_shop_group']])) { 749 static::$shops[$row['id_shop_group']] = [ 750 'id' => $row['id_shop_group'], 751 'name' => $row['group_name'], 752 'share_customer' => $row['share_customer'], 753 'share_order' => $row['share_order'], 754 'share_stock' => $row['share_stock'], 755 'shops' => [], 756 ]; 757 } 758 759 static::$shops[$row['id_shop_group']]['shops'][$row['id_shop']] = [ 760 'id_shop' => $row['id_shop'], 761 'id_shop_group' => $row['id_shop_group'], 762 'name' => $row['shop_name'], 763 'id_theme' => $row['id_theme'], 764 'id_category' => $row['id_category'], 765 'domain' => $row['domain'], 766 'domain_ssl' => $row['domain_ssl'], 767 'uri' => $row['physical_uri'].$row['virtual_uri'], 768 'active' => $row['active'], 769 ]; 770 } 771 } 772 } 773 774 /** 775 * @return array|null 776 * 777 * @throws PrestaShopDatabaseException 778 * @throws PrestaShopException 779 * @since 1.0.0 780 * @version 1.0.0 Initial version 781 */ 782 public static function getCompleteListOfShopsID() 783 { 784 $cacheId = 'Shop::getCompleteListOfShopsID'; 785 if (!Cache::isStored($cacheId)) { 786 $list = []; 787 foreach (Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS((new DbQuery())->select('`id_shop`')->from('shop')) as $row) { 788 $list[] = $row['id_shop']; 789 } 790 791 Cache::store($cacheId, $list); 792 793 return $list; 794 } 795 796 return Cache::retrieve($cacheId); 797 } 798 799 /** 800 * Get shops list 801 * 802 * @param bool $active 803 * @param int $idShopGroup 804 * @param bool $getAsListId 805 * 806 * @return array 807 * 808 * @throws PrestaShopDatabaseException 809 * @throws PrestaShopException 810 * @since 1.0.0 811 * @version 1.0.0 Initial version 812 */ 813 public static function getShops($active = true, $idShopGroup = null, $getAsListId = false) 814 { 815 static::cacheShops(); 816 817 $results = []; 818 foreach (static::$shops as $idGroup => $groupData) { 819 foreach ($groupData['shops'] as $id => $shopData) { 820 if ((!$active || $shopData['active']) && (!$idShopGroup || $idShopGroup == $idGroup)) { 821 if ($getAsListId) { 822 $results[$id] = $id; 823 } else { 824 $results[$id] = $shopData; 825 } 826 } 827 } 828 } 829 830 return $results; 831 } 832 833 /** 834 * @return array|bool 835 * 836 * @throws PrestaShopDatabaseException 837 * @throws PrestaShopException 838 * @since 1.0.0 839 * @version 1.0.0 Initial version 840 */ 841 public function getUrlsSharedCart() 842 { 843 if (!$this->getGroup()->share_order) { 844 return false; 845 } 846 847 $query = new DbQuery(); 848 $query->select('domain'); 849 $query->from('shop_url'); 850 $query->where('main = 1'); 851 $query->where('active = 1'); 852 $query .= $this->addSqlRestriction(self::SHARE_ORDER); 853 $domains = []; 854 foreach (Db::getInstance()->executeS($query) as $row) { 855 $domains[] = $row['domain']; 856 } 857 858 return $domains; 859 } 860 861 /** 862 * Get a collection of shops 863 * 864 * @param bool $active 865 * @param int $idShopGroup 866 * 867 * @return PrestaShopCollection Collection of Shop 868 * 869 * @since 1.0.0 870 * @version 1.0.0 Initial version 871 * @throws PrestaShopException 872 */ 873 public static function getShopsCollection($active = true, $idShopGroup = null) 874 { 875 $shops = new PrestaShopCollection('Shop'); 876 if ($active) { 877 $shops->where('active', '=', 1); 878 } 879 880 if ($idShopGroup) { 881 $shops->where('id_shop_group', '=', (int) $idShopGroup); 882 } 883 884 return $shops; 885 } 886 887 /** 888 * Return some informations cached for one shop 889 * 890 * @param int $shopId 891 * 892 * @return false|array 893 * 894 * @throws PrestaShopDatabaseException 895 * @throws PrestaShopException 896 * @since 1.0.0 897 * @version 1.0.0 Initial version 898 */ 899 public static function getShop($shopId) 900 { 901 static::cacheShops(); 902 foreach (static::$shops as $idGroup => $groupData) { 903 if (array_key_exists($shopId, $groupData['shops'])) { 904 return $groupData['shops'][$shopId]; 905 } 906 } 907 908 return false; 909 } 910 911 /** 912 * Return a shop ID from shop name 913 * 914 * @param string $name 915 * 916 * @return int 917 * 918 * @throws PrestaShopDatabaseException 919 * @throws PrestaShopException 920 * @since 1.0.0 921 * @version 1.0.0 Initial version 922 */ 923 public static function getIdByName($name) 924 { 925 static::cacheShops(); 926 foreach (static::$shops as $groupData) { 927 foreach ($groupData['shops'] as $idShop => $shopData) { 928 if (mb_strtolower($shopData['name']) == mb_strtolower($name)) { 929 return $idShop; 930 } 931 } 932 } 933 934 return false; 935 } 936 937 /** 938 * @param bool $active 939 * @param int $idShopGroup 940 * 941 * @return int Total of shops 942 * 943 * @since 1.0.0 944 * @version 1.0.0 Initial version 945 */ 946 public static function getTotalShops($active = true, $idShopGroup = null) 947 { 948 return count(static::getShops($active, $idShopGroup)); 949 } 950 951 /** 952 * Retrieve group ID of a shop 953 * 954 * @param int $shopId Shop ID 955 * @param bool $asId 956 * 957 * @return int Group ID 958 * 959 * @throws PrestaShopDatabaseException 960 * @throws PrestaShopException 961 * @since 1.0.0 962 * @version 1.0.0 Initial version 963 */ 964 public static function getGroupFromShop($shopId, $asId = true) 965 { 966 static::cacheShops(); 967 foreach (static::$shops as $groupId => $groupData) { 968 if (array_key_exists($shopId, $groupData['shops'])) { 969 return ($asId) ? $groupId : $groupData; 970 } 971 } 972 973 return false; 974 } 975 976 /** 977 * If the shop group has the option $type activated, get all shops ID of this group, else get current shop ID 978 * 979 * @param int $shopId 980 * @param int $type self::SHARE_CUSTOMER | self::SHARE_ORDER 981 * 982 * @return array 983 * @throws PrestaShopException 984 * @since 1.0.0 985 * @version 1.0.0 Initial version 986 */ 987 public static function getSharedShops($shopId, $type) 988 { 989 if (!in_array($type, [self::SHARE_CUSTOMER, self::SHARE_ORDER, self::SHARE_STOCK])) { 990 throw new PrestaShopException('Wrong argument ($type) in Shop::getSharedShops() method'); 991 } 992 993 static::cacheShops(); 994 foreach (static::$shops as $groupData) { 995 if (array_key_exists($shopId, $groupData['shops']) && $groupData[$type]) { 996 return array_keys($groupData['shops']); 997 } 998 } 999 1000 return [$shopId]; 1001 } 1002 1003 /** 1004 * Get a list of ID concerned by the shop context (E.g. if context is shop group, get list of children shop ID) 1005 * 1006 * @param bool|string $share If false, dont check share datas from group. Else can take a Shop::SHARE_* constant value 1007 * 1008 * @return array 1009 * 1010 * @since 1.0.0 1011 * @version 1.0.0 Initial version 1012 * @throws PrestaShopException 1013 */ 1014 public static function getContextListShopID($share = false) 1015 { 1016 if (static::getContext() == self::CONTEXT_SHOP) { 1017 $list = ($share) ? static::getSharedShops(static::getContextShopID(), $share) : [static::getContextShopID()]; 1018 } elseif (static::getContext() == self::CONTEXT_GROUP) { 1019 $list = static::getShops(true, static::getContextShopGroupID(), true); 1020 } else { 1021 $list = static::getShops(true, null, true); 1022 } 1023 1024 return $list; 1025 } 1026 1027 /** 1028 * Return the list of shop by id 1029 * 1030 * @param int $id 1031 * @param string $identifier 1032 * @param string $table 1033 * 1034 * @return array 1035 * 1036 * @throws PrestaShopDatabaseException 1037 * @throws PrestaShopException 1038 * @since 1.0.0 1039 * @version 1.0.0 Initial version 1040 */ 1041 public static function getShopById($id, $identifier, $table) 1042 { 1043 return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS( 1044 (new DbQuery()) 1045 ->select('`id_shop`, `'.bqSQL($identifier).'`') 1046 ->from(bqSQL($table).'_shop') 1047 ->where('`'.bqSQL($identifier).'` = '.(int) $id) 1048 ); 1049 } 1050 1051 /** 1052 * Change the current shop context 1053 * 1054 * @param int $type Shop::CONTEXT_ALL | Shop::CONTEXT_GROUP | Shop::CONTEXT_SHOP 1055 * @param int $id ID shop if CONTEXT_SHOP or id shop group if CONTEXT_GROUP 1056 * 1057 * @throws PrestaShopException 1058 * @since 1.0.0 1059 * @version 1.0.0 Initial version 1060 */ 1061 public static function setContext($type, $id = null) 1062 { 1063 // @codingStandardsIgnoreStart 1064 switch ($type) { 1065 case static::CONTEXT_ALL : 1066 static::$context_id_shop = null; 1067 static::$context_id_shop_group = null; 1068 break; 1069 1070 case static::CONTEXT_GROUP : 1071 static::$context_id_shop = null; 1072 static::$context_id_shop_group = (int) $id; 1073 break; 1074 1075 case static::CONTEXT_SHOP : 1076 static::$context_id_shop = (int) $id; 1077 static::$context_id_shop_group = static::getGroupFromShop($id); 1078 break; 1079 1080 default : 1081 throw new PrestaShopException('Unknown context for shop'); 1082 } 1083 // @codingStandardsIgnoreEnd 1084 1085 static::$context = $type; 1086 } 1087 1088 /** 1089 * Get current context of shop 1090 * 1091 * @return int 1092 * 1093 * @since 1.0.0 1094 * @version 1.0.0 Initial version 1095 */ 1096 public static function getContext() 1097 { 1098 return static::$context; 1099 } 1100 1101 /** 1102 * Get current ID of shop if context is CONTEXT_SHOP 1103 * 1104 * @param bool $nullValueWithoutMultishop 1105 * 1106 * @return int 1107 * @since 1.0.0 1108 * @version 1.0.0 Initial version 1109 */ 1110 public static function getContextShopID($nullValueWithoutMultishop = false) 1111 { 1112 if ($nullValueWithoutMultishop && !static::isFeatureActive()) { 1113 return null; 1114 } 1115 1116 // @codingStandardsIgnoreStart 1117 return static::$context_id_shop; 1118 // @codingStandardsIgnoreEnd 1119 } 1120 1121 /** 1122 * Get current ID of shop group if context is CONTEXT_SHOP or CONTEXT_GROUP 1123 * 1124 * @param bool $nullValueWithoutMultishop 1125 * 1126 * @return int 1127 * @since 1.0.0 1128 * @version 1.0.0 Initial version 1129 */ 1130 public static function getContextShopGroupID($nullValueWithoutMultishop = false) 1131 { 1132 if ($nullValueWithoutMultishop && !static::isFeatureActive()) { 1133 return null; 1134 } 1135 1136 // @codingStandardsIgnoreStart 1137 return static::$context_id_shop_group; 1138 // @codingStandardsIgnoreEnd 1139 } 1140 1141 public static function getContextShopGroup() 1142 { 1143 static $contextShopGroup = null; 1144 if ($contextShopGroup === null) { 1145 // @codingStandardsIgnoreStart 1146 $contextShopGroup = new ShopGroup((int) static::$context_id_shop_group); 1147 // @codingStandardsIgnoreEnd 1148 } 1149 1150 return $contextShopGroup; 1151 } 1152 1153 /** 1154 * Add an sql restriction for shops fields 1155 * 1156 * @param bool $share If false, dont check share datas from group. Else can take a Shop::SHARE_* constant value 1157 * @param string $alias 1158 * 1159 * @return string 1160 * @throws PrestaShopDatabaseException 1161 * @throws PrestaShopException 1162 * @since 1.0.0 1163 * @version 1.0.0 Initial version 1164 */ 1165 public static function addSqlRestriction($share = false, $alias = null) 1166 { 1167 if ($alias) { 1168 $alias .= '.'; 1169 } 1170 1171 $group = static::getGroupFromShop(static::getContextShopID(), false); 1172 if ($share == self::SHARE_CUSTOMER && static::getContext() == self::CONTEXT_SHOP && $group['share_customer']) { 1173 $restriction = ' AND '.$alias.'id_shop_group = '.(int) static::getContextShopGroupID().' '; 1174 } else { 1175 $restriction = ' AND '.$alias.'id_shop IN ('.implode(', ', static::getContextListShopID($share)).') '; 1176 } 1177 1178 return $restriction; 1179 } 1180 1181 /** 1182 * Add an SQL JOIN in query between a table and its associated table in multishop 1183 * 1184 * @param string $table Table name (E.g. product, module, etc.) 1185 * @param string $alias Alias of table 1186 * @param bool $innerJoin Use or not INNER JOIN 1187 * @param string $on 1188 * 1189 * @return string 1190 * 1191 * @since 1.0.0 1192 * @version 1.0.0 Initial version 1193 * @throws PrestaShopException 1194 */ 1195 public static function addSqlAssociation($table, $alias, $innerJoin = true, $on = null, $forceNotDefault = false) 1196 { 1197 $tableAlias = $table.'_shop'; 1198 if (strpos($table, '.') !== false) { 1199 list($tableAlias, $table) = explode('.', $table); 1200 } 1201 1202 $assoTable = static::getAssoTable($table); 1203 if ($assoTable === false || $assoTable['type'] != 'shop') { 1204 return ''; 1205 } 1206 $sql = (($innerJoin) ? ' INNER' : ' LEFT').' JOIN '._DB_PREFIX_.$table.'_shop '.$tableAlias.' 1207 ON ('.$tableAlias.'.id_'.$table.' = '.$alias.'.id_'.$table; 1208 // @codingStandardsIgnoreStart 1209 if ((int) static::$context_id_shop) {$sql .= ' AND '.$tableAlias.'.id_shop = '.(int) static::$context_id_shop; 1210 } elseif (static::checkIdShopDefault($table) && !$forceNotDefault) { 1211 $sql .= ' AND '.$tableAlias.'.id_shop = '.$alias.'.id_shop_default'; 1212 } else { 1213 $sql .= ' AND '.$tableAlias.'.id_shop IN ('.implode(', ', static::getContextListShopID()).')'; 1214 } 1215 $sql .= (($on) ? ' AND '.$on : '').')'; 1216 // @codingStandardsIgnoreEnd 1217 1218 return $sql; 1219 } 1220 1221 /** 1222 * Add a restriction on id_shop for multishop lang table 1223 * 1224 * @param string $alias 1225 * @param null $idShop 1226 * 1227 * @return string 1228 * 1229 * @since 1.0.0 1230 * @version 1.0.0 Initial version 1231 * @throws PrestaShopException 1232 */ 1233 public static function addSqlRestrictionOnLang($alias = null, $idShop = null) 1234 { 1235 if (isset(Context::getContext()->shop) && is_null($idShop)) { 1236 $idShop = (int) Context::getContext()->shop->id; 1237 } 1238 if (!$idShop) { 1239 $idShop = (int) Configuration::get('PS_SHOP_DEFAULT'); 1240 } 1241 1242 return ' AND '.(($alias) ? $alias.'.' : '').'id_shop = '.$idShop.' '; 1243 } 1244 1245 /** 1246 * Get all groups and associated shops as subarrays 1247 * 1248 * @return array 1249 * 1250 * @throws PrestaShopDatabaseException 1251 * @throws PrestaShopException 1252 * @since 1.0.0 1253 * @version 1.0.0 Initial version 1254 */ 1255 public static function getTree() 1256 { 1257 static::cacheShops(); 1258 1259 return static::$shops; 1260 } 1261 1262 /** 1263 * @return bool Return true if multishop feature is active and at last 2 shops have been created 1264 * 1265 * @since 1.0.0 1266 * @version 1.0.0 Initial version 1267 * @throws PrestaShopException 1268 */ 1269 public static function isFeatureActive() 1270 { 1271 static $featureActive = null; 1272 1273 if ($featureActive === null) { 1274 $featureActive = (bool) Db::getInstance()->getValue('SELECT value FROM `'._DB_PREFIX_.'configuration` WHERE `name` = "PS_MULTISHOP_FEATURE_ACTIVE"') 1275 && (Db::getInstance()->getValue('SELECT COUNT(*) FROM '._DB_PREFIX_.'shop') > 1); 1276 } 1277 1278 return $featureActive; 1279 } 1280 1281 /** 1282 * @param int $oldId 1283 * @param bool $tablesImport 1284 * @param bool $deleted 1285 * 1286 * @throws PrestaShopDatabaseException 1287 * @throws PrestaShopException 1288 * @since 1.0.0 1289 * @version 1.0.0 Initial version 1290 */ 1291 public function copyShopData($oldId, $tablesImport = false, $deleted = false) 1292 { 1293 // If we duplicate some specific data, automatically duplicate other data linked to the first 1294 // E.g. if carriers are duplicated for the shop, duplicate carriers langs too 1295 1296 if (!$oldId) { 1297 $oldId = Configuration::get('PS_SHOP_DEFAULT'); 1298 } 1299 1300 if (isset($tablesImport['carrier'])) { 1301 $tablesImport['carrier_tax_rules_group_shop'] = true; 1302 $tablesImport['carrier_lang'] = true; 1303 } 1304 1305 if (isset($tablesImport['cms'])) { 1306 $tablesImport['cms_lang'] = true; 1307 $tablesImport['cms_category'] = true; 1308 $tablesImport['cms_category_lang'] = true; 1309 } 1310 1311 $tablesImport['category_lang'] = true; 1312 if (isset($tablesImport['product'])) { 1313 $tablesImport['product_lang'] = true; 1314 } 1315 1316 if (isset($tablesImport['module'])) { 1317 $tablesImport['module_currency'] = true; 1318 $tablesImport['module_country'] = true; 1319 $tablesImport['module_group'] = true; 1320 } 1321 1322 if (isset($tablesImport['hook_module'])) { 1323 $tablesImport['hook_module_exceptions'] = true; 1324 } 1325 1326 if (isset($tablesImport['attribute_group'])) { 1327 $tablesImport['attribute'] = true; 1328 } 1329 1330 // Browse and duplicate data 1331 foreach (static::getAssoTables() as $tableName => $row) { 1332 if ($tablesImport && !isset($tablesImport[$tableName])) { 1333 continue; 1334 } 1335 1336 // Special case for stock_available if current shop is in a share stock group 1337 if ($tableName == 'stock_available') { 1338 $group = new ShopGroup($this->id_shop_group); 1339 if ($group->share_stock && $group->haveShops()) { 1340 continue; 1341 } 1342 } 1343 1344 $id = 'id_'.$row['type']; 1345 if ($row['type'] == 'fk_shop') { 1346 $id = 'id_shop'; 1347 } else { 1348 $tableName .= '_'.$row['type']; 1349 } 1350 1351 if (!$deleted) { 1352 $res = Db::getInstance()->getRow('SELECT * FROM `'._DB_PREFIX_.$tableName.'` WHERE `'.$id.'` = '.(int) $oldId); 1353 if ($res) { 1354 unset($res[$id]); 1355 if (isset($row['primary'])) { 1356 unset($res[$row['primary']]); 1357 } 1358 1359 $categories = Tools::getValue('categoryBox'); 1360 if ($tableName == 'product_shop' && count($categories) == 1) { 1361 unset($res['id_category_default']); 1362 $keys = implode('`, `', array_keys($res)); 1363 $sql = 'INSERT IGNORE INTO `'._DB_PREFIX_.$tableName.'` (`'.$keys.'`, `id_category_default`, '.$id.') 1364 (SELECT `'.$keys.'`, '.(int) $categories[0].', '.(int) $this->id.' FROM '._DB_PREFIX_.$tableName.' 1365 WHERE `'.$id.'` = '.(int) $oldId.')'; 1366 } else { 1367 $keys = implode('`, `', array_keys($res)); 1368 $sql = 'INSERT IGNORE INTO `'._DB_PREFIX_.$tableName.'` (`'.$keys.'`, '.$id.') 1369 (SELECT `'.$keys.'`, '.(int) $this->id.' FROM '._DB_PREFIX_.$tableName.' 1370 WHERE `'.$id.'` = '.(int) $oldId.')'; 1371 } 1372 Db::getInstance()->execute($sql); 1373 } 1374 } 1375 } 1376 1377 // Hook for duplication of shop data 1378 $modulesList = Hook::getHookModuleExecList('actionShopDataDuplication'); 1379 if (is_array($modulesList) && count($modulesList) > 0) { 1380 foreach ($modulesList as $m) { 1381 if (!$tablesImport || isset($tablesImport['Module'.ucfirst($m['module'])])) { 1382 Hook::exec( 1383 'actionShopDataDuplication', 1384 [ 1385 'old_id_shop' => (int) $oldId, 1386 'new_id_shop' => (int) $this->id, 1387 ], 1388 $m['id_module'] 1389 ); 1390 } 1391 } 1392 } 1393 } 1394 1395 /** 1396 * @param int $id 1397 * @param bool $onlyId 1398 * 1399 * @return array 1400 * @throws PrestaShopDatabaseException 1401 * @throws PrestaShopException 1402 * @since 1.0.0 1403 * @version 1.0.0 Initial version 1404 */ 1405 public static function getCategories($id = 0, $onlyId = true) 1406 { 1407 // build query 1408 $query = new DbQuery(); 1409 if ($onlyId) { 1410 $query->select('cs.`id_category`'); 1411 } else { 1412 $query->select('DISTINCT cs.`id_category`, cl.`name`, cl.`link_rewrite`'); 1413 } 1414 $query->from('category_shop', 'cs'); 1415 $query->leftJoin('category_lang', 'cl', 'cl.`id_category` = cs.`id_category` AND cl.`id_lang` = '.(int) Context::getContext()->language->id); 1416 $query->where('cs.`id_shop` = '.(int) $id); 1417 $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($query); 1418 1419 if ($onlyId) { 1420 $array = []; 1421 foreach ($result as $row) { 1422 $array[] = $row['id_category']; 1423 } 1424 $array = array_unique($array); 1425 } else { 1426 return $result; 1427 } 1428 1429 return $array; 1430 } 1431 1432 /** 1433 * @deprecated 2.0.0 Use shop->id 1434 */ 1435 public static function getCurrentShop() 1436 { 1437 Tools::displayAsDeprecated(); 1438 1439 return Context::getContext()->shop->id; 1440 } 1441 1442 /** 1443 * @param string $entity 1444 * @param int $idShop 1445 * @param bool $active 1446 * @param bool $delete 1447 * 1448 * @return array|bool 1449 * @throws PrestaShopDatabaseException 1450 * @throws PrestaShopException 1451 * @since 1.0.0 1452 * @version 1.0.0 Initial version 1453 */ 1454 public static function getEntityIds($entity, $idShop, $active = false, $delete = false) 1455 { 1456 if (!static::isTableAssociated($entity)) { 1457 return false; 1458 } 1459 1460 return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS( 1461 (new DbQuery()) 1462 ->select('entity.`id_'.bqSQL($entity).'`') 1463 ->from(bqSQL($entity).'_shop', 'es') 1464 ->leftJoin(bqSQL($entity), 'entity', 'entity.`id_'.bqSQL($entity).'` = es.`id_'.bqSQL($entity).'`') 1465 ->where('es.`id_shop` = '.(int) $idShop) 1466 ->where($active ? 'entity.`active` = 1' : '') 1467 ->where($delete ? 'entity.deleted = 0' : '') 1468 ); 1469 } 1470 1471 /** 1472 * Initialize an array with all the multistore associations in the database 1473 * 1474 * @since 1.0.0 1475 * @version 1.0.0 Initial version 1476 */ 1477 protected static function init() 1478 { 1479 // @codingStandardsIgnoreStart 1480 static::$id_shop_default_tables = ['product', 'category']; 1481 // @codingStandardsIgnoreEnd 1482 1483 $assoTables = [ 1484 'carrier' => ['type' => 'shop'], 1485 'carrier_lang' => ['type' => 'fk_shop'], 1486 'category' => ['type' => 'shop'], 1487 'category_lang' => ['type' => 'fk_shop'], 1488 'cms' => ['type' => 'shop'], 1489 'cms_lang' => ['type' => 'fk_shop'], 1490 'cms_category' => ['type' => 'shop'], 1491 'cms_category_lang' => ['type' => 'fk_shop'], 1492 'contact' => ['type' => 'shop'], 1493 'country' => ['type' => 'shop'], 1494 'currency' => ['type' => 'shop'], 1495 'employee' => ['type' => 'shop'], 1496 'hook_module' => ['type' => 'fk_shop'], 1497 'hook_module_exceptions' => ['type' => 'fk_shop', 'primary' => 'id_hook_module_exceptions'], 1498 'image' => ['type' => 'shop'], 1499 'lang' => ['type' => 'shop'], 1500 'meta_lang' => ['type' => 'fk_shop'], 1501 'module' => ['type' => 'shop'], 1502 'module_currency' => ['type' => 'fk_shop'], 1503 'module_country' => ['type' => 'fk_shop'], 1504 'module_group' => ['type' => 'fk_shop'], 1505 'product' => ['type' => 'shop'], 1506 'product_attribute' => ['type' => 'shop'], 1507 'product_lang' => ['type' => 'fk_shop'], 1508 'referrer' => ['type' => 'shop'], 1509 'scene' => ['type' => 'shop'], 1510 'store' => ['type' => 'shop'], 1511 'webservice_account' => ['type' => 'shop'], 1512 'warehouse' => ['type' => 'shop'], 1513 'stock_available' => ['type' => 'fk_shop', 'primary' => 'id_stock_available'], 1514 'carrier_tax_rules_group_shop' => ['type' => 'fk_shop'], 1515 'attribute' => ['type' => 'shop'], 1516 'feature' => ['type' => 'shop'], 1517 'group' => ['type' => 'shop'], 1518 'attribute_group' => ['type' => 'shop'], 1519 'tax_rules_group' => ['type' => 'shop'], 1520 'zone' => ['type' => 'shop'], 1521 'manufacturer' => ['type' => 'shop'], 1522 'supplier' => ['type' => 'shop'], 1523 ]; 1524 1525 foreach ($assoTables as $tableName => $tableDetails) { 1526 static::addTableAssociation($tableName, $tableDetails); 1527 } 1528 1529 static::$initialized = true; 1530 } 1531} 1532