* @copyright 2007-2015 PrestaShop SA * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) * International Registered Trademark & Property of PrestaShop SA */ class TagCore extends ObjectModel { /** @var int Language id */ public $id_lang; /** @var string Name */ public $name; /** * @see ObjectModel::$definition */ public static $definition = array( 'table' => 'tag', 'primary' => 'id_tag', 'fields' => array( 'id_lang' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true), 'name' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => true, 'size' => 32), ), ); protected $webserviceParameters = array( 'fields' => array( 'id_lang' => array('xlink_resource' => 'languages'), ), ); public function __construct($id = null, $name = null, $id_lang = null) { $this->def = Tag::getDefinition($this); $this->setDefinitionRetrocompatibility(); if ($id) { parent::__construct($id); } elseif ($name && Validate::isGenericName($name) && $id_lang && Validate::isUnsignedId($id_lang)) { $row = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow(' SELECT * FROM `'._DB_PREFIX_.'tag` t WHERE `name` = \''.pSQL($name).'\' AND `id_lang` = '.(int)$id_lang); if ($row) { $this->id = (int)$row['id_tag']; $this->id_lang = (int)$row['id_lang']; $this->name = $row['name']; } } } public function add($autodate = true, $null_values = false) { if (!parent::add($autodate, $null_values)) { return false; } elseif (isset($_POST['products'])) { return $this->setProducts(Tools::getValue('products')); } return true; } /** * Add several tags in database and link it to a product * * @param int $id_lang Language id * @param int $id_product Product id to link tags with * @param string|array $tag_list List of tags, as array or as a string with comas * @return bool Operation success */ public static function addTags($id_lang, $id_product, $tag_list, $separator = ',') { if (!Validate::isUnsignedId($id_lang)) { return false; } if (!is_array($tag_list)) { $tag_list = array_filter(array_unique(array_map('trim', preg_split('#\\'.$separator.'#', $tag_list, null, PREG_SPLIT_NO_EMPTY)))); } $list = array(); if (is_array($tag_list)) { foreach ($tag_list as $tag) { if (!Validate::isGenericName($tag)) { return false; } $tag = trim(Tools::substr($tag, 0, self::$definition['fields']['name']['size'])); $tag_obj = new Tag(null, $tag, (int)$id_lang); /* Tag does not exist in database */ if (!Validate::isLoadedObject($tag_obj)) { $tag_obj->name = $tag; $tag_obj->id_lang = (int)$id_lang; $tag_obj->add(); } if (!in_array($tag_obj->id, $list)) { $list[] = $tag_obj->id; } } } $data = ''; foreach ($list as $tag) { $data .= '('.(int)$tag.','.(int)$id_product.','.(int)$id_lang.'),'; } $data = rtrim($data, ','); $result = Db::getInstance()->execute(' INSERT INTO `'._DB_PREFIX_.'product_tag` (`id_tag`, `id_product`, `id_lang`) VALUES '.$data); self::updateTagCount(); return $result; } public static function updateTagCount() { if (!Module::getBatchMode()) { Db::getInstance()->execute('REPLACE INTO `'._DB_PREFIX_.'tag_count` (id_group, id_tag, id_lang, id_shop, counter) SELECT cg.id_group, t.id_tag, t.id_lang, ps.id_shop, COUNT(pt.id_tag) AS times FROM `'._DB_PREFIX_.'product_tag` pt LEFT JOIN `'._DB_PREFIX_.'tag` t ON (t.id_tag = pt.id_tag) LEFT JOIN `'._DB_PREFIX_.'product` p ON (p.id_product = pt.id_product) INNER JOIN `'._DB_PREFIX_.'product_shop` product_shop ON (product_shop.id_product = p.id_product) JOIN (SELECT DISTINCT id_group FROM `'._DB_PREFIX_.'category_group`) cg JOIN (SELECT DISTINCT id_shop FROM `'._DB_PREFIX_.'shop`) ps WHERE pt.`id_lang` = 1 AND product_shop.`active` = 1 AND EXISTS(SELECT 1 FROM `'._DB_PREFIX_.'category_product` cp LEFT JOIN `'._DB_PREFIX_.'category_group` cgo ON (cp.`id_category` = cgo.`id_category`) WHERE cgo.`id_group` = cg.id_group AND p.`id_product` = cp.`id_product`) AND product_shop.id_shop = ps.id_shop GROUP BY pt.id_tag, cg.id_group'); Db::getInstance()->execute('REPLACE INTO `'._DB_PREFIX_.'tag_count` (id_group, id_tag, id_lang, id_shop, counter) SELECT 0, t.id_tag, t.id_lang, ps.id_shop, COUNT(pt.id_tag) AS times FROM `'._DB_PREFIX_.'product_tag` pt LEFT JOIN `'._DB_PREFIX_.'tag` t ON (t.id_tag = pt.id_tag) LEFT JOIN `'._DB_PREFIX_.'product` p ON (p.id_product = pt.id_product) INNER JOIN `'._DB_PREFIX_.'product_shop` product_shop ON (product_shop.id_product = p.id_product) JOIN (SELECT DISTINCT id_shop FROM `'._DB_PREFIX_.'shop`) ps WHERE pt.`id_lang` = 1 AND product_shop.`active` = 1 AND product_shop.id_shop = ps.id_shop GROUP BY pt.id_tag'); } } public static function getMainTags($id_lang, $nb = 10) { $context = Context::getContext(); if (Group::isFeatureActive()) { $groups = FrontController::getCurrentCustomerGroups(); return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' SELECT t.name, counter AS times FROM `'._DB_PREFIX_.'tag_count` pt LEFT JOIN `'._DB_PREFIX_.'tag` t ON (t.id_tag = pt.id_tag) WHERE pt.`id_group` '.(count($groups) ? 'IN ('.implode(',', $groups).')' : '= 1').' AND pt.`id_lang` = '.(int)$id_lang.' AND pt.`id_shop` = '.(int)$context->shop->id.' ORDER BY times DESC LIMIT '.(int)$nb); } else { return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' SELECT t.name, counter AS times FROM `'._DB_PREFIX_.'tag_count` pt LEFT JOIN `'._DB_PREFIX_.'tag` t ON (t.id_tag = pt.id_tag) WHERE pt.id_group = 0 AND pt.`id_lang` = '.(int)$id_lang.' AND pt.`id_shop` = '.(int)$context->shop->id.' ORDER BY times DESC LIMIT '.(int)$nb); } } public static function getProductTags($id_product) { if (!$tmp = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' SELECT t.`id_lang`, t.`name` FROM '._DB_PREFIX_.'tag t LEFT JOIN '._DB_PREFIX_.'product_tag pt ON (pt.id_tag = t.id_tag) WHERE pt.`id_product`='.(int)$id_product)) { return false; } $result = array(); foreach ($tmp as $tag) { $result[$tag['id_lang']][] = $tag['name']; } return $result; } public function getProducts($associated = true, Context $context = null) { if (!$context) { $context = Context::getContext(); } $id_lang = $this->id_lang ? $this->id_lang : $context->language->id; if (!$this->id && $associated) { return array(); } $in = $associated ? 'IN' : 'NOT IN'; return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' SELECT pl.name, pl.id_product FROM `'._DB_PREFIX_.'product` p LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON p.id_product = pl.id_product'.Shop::addSqlRestrictionOnLang('pl').' '.Shop::addSqlAssociation('product', 'p').' WHERE pl.id_lang = '.(int)$id_lang.' AND product_shop.active = 1 '.($this->id ? ('AND p.id_product '.$in.' (SELECT pt.id_product FROM `'._DB_PREFIX_.'product_tag` pt WHERE pt.id_tag = '.(int)$this->id.')') : '').' ORDER BY pl.name'); } public function setProducts($array) { $result = Db::getInstance()->delete('product_tag', 'id_tag = '.(int)$this->id); if (is_array($array)) { $array = array_map('intval', $array); $result &= ObjectModel::updateMultishopTable('Product', array('indexed' => 0), 'a.id_product IN ('.implode(',', $array).')'); $ids = array(); foreach ($array as $id_product) { $ids[] = '('.(int)$id_product.','.(int)$this->id.','.(int)$this->id_lang.')'; } if ($result) { $result &= Db::getInstance()->execute('INSERT INTO '._DB_PREFIX_.'product_tag (id_product, id_tag, id_lang) VALUES '.implode(',', $ids)); if (Configuration::get('PS_SEARCH_INDEXATION')) { $result &= Search::indexation(false); } } } self::updateTagCount(); return $result; } public static function deleteTagsForProduct($id_product) { $result = Db::getInstance()->delete('product_tag', 'id_product = '.(int)$id_product); self::updateTagCount(); return $result; } }