protected function productsSitemap($categoryId, $categoryUrl) { $product = Product::find()->select(['id', 'slug'])->where(['main_category_id' => $categoryId, 'active' => 1])->asArray(true)->all(); array_reduce($product, function ($carry, $item) use($categoryUrl) { $this->sitemap->addUrl($categoryUrl . '/' . $item['slug']); }); }
public function search($params) { $query = Product::find()->with('prices'); $dataProvider = new ActiveDataProvider(['query' => $query, 'sort' => new \yii\data\Sort(['attributes' => ['name', 'id', 'available']])]); $this->load($params); if (!$this->validate()) { return $dataProvider; } $query->andFilterWhere(['id' => $this->id, 'category_id' => $this->category_id, 'available' => $this->available, 'producer_id' => $this->producer_id]); $query->andFilterWhere(['like', 'name', $this->name])->andFilterWhere(['like', 'text', $this->text])->andFilterWhere(['like', 'code', $this->code])->andFilterWhere(['like', 'short_text', $this->short_text])->andFilterWhere(['like', 'category_id', $this->category_id]); return $dataProvider; }
public function getData() { if ($this->data === []) { $event = new ModificationDataEvent(); $query = Product::find()->where(['active' => 1]); foreach ($query->each() as $product) { $event->model = $product; $this->trigger(self::MODIFICATION_DATA, $event); $this->data[] = $event->dataArray; } } return $this->data; }
/** * @param $term * @return string JSON */ public function actionAutoCompleteSearch($term) { Yii::$app->response->format = Response::FORMAT_JSON; $query = Product::find()->select(['id', 'name', 'main_category_id', 'slug', 'sku'])->orderBy(['sort_order' => SORT_ASC, 'id' => SORT_DESC]); foreach (['name', 'content', 'sku'] as $attribute) { $query->orWhere(['like', $attribute, $term]); } $query->andWhere(['active' => 1]); $products = $query->limit(Yii::$app->getModule('core')->autoCompleteResultsCount)->all(); $result = []; foreach ($products as $product) { /** @var Product $product */ $result[] = ['id' => $product->id, 'name' => $product->name, 'url' => Url::toRoute(['@product', 'model' => $product, 'category_group_id' => $product->getMainCategory()->category_group_id], true)]; } return $result; }
/** * @param $term * @return string JSON */ public function actionAutoCompleteSearch($term) { Yii::$app->response->format = Response::FORMAT_JSON; $search = new Search(); $search->q = $term; $search->on(Search::QUERY_SEARCH_PRODUCTS_BY_DESCRIPTION, function (SearchEvent $event) { $event->setFunctionSearch(function ($activeQuery) { $activeQuery->limit(Yii::$app->getModule('core')->autoCompleteResultsCount); return Product::find()->select(['id', 'name', 'main_category_id', 'slug', 'sku'])->where(['id' => $activeQuery->all()])->all(); }); }); $products = $search->searchProductsByDescription(); $result = []; foreach ($products as $product) { /** @var Product $product */ $result[] = ['id' => $product->id, 'name' => $product->name, 'url' => Url::toRoute(['@product', 'model' => $product, 'category_group_id' => $product->getMainCategory()->category_group_id], true)]; } return $result; }
/** * Preparation to delete category. * Deleting related products and inserted categories. * @return bool */ public function beforeDelete() { if (!parent::beforeDelete()) { return false; } $productObject = Object::getForClass(Product::className()); switch ($this->deleteMode) { case self::DELETE_MODE_ALL: $products = !is_null($productObject) ? Product::find()->join('INNER JOIN', $productObject->categories_table_name . ' pc', 'pc.object_model_id = product.id')->where('pc.category_id = :id', [':id' => $this->id])->all() : []; break; case self::DELETE_MODE_MAIN_CATEGORY: $products = Product::findAll(['main_category_id' => $this->id]); break; default: $products = !is_null($productObject) ? Product::find()->join('INNER JOIN', $productObject->categories_table_name . ' pc', 'pc.object_model_id = product.id')->join('INNER JOIN', $productObject->categories_table_name . ' pc2', 'pc2.object_model_id = product.id')->where('pc.category_id = :id', [':id' => $this->id])->groupBy('pc2.object_model_id')->having('COUNT(*) = 1')->all() : []; break; } foreach ($products as $product) { $product->delete(); } foreach ($this->children as $child) { $child->deleteMode = $this->deleteMode; $child->delete(); } if (!is_null($productObject)) { Yii::$app->db->createCommand()->delete($productObject->categories_table_name, ['category_id' => $this->id])->execute(); } return true; }
/** * Search handler * @return array * @throws ForbiddenHttpException */ public function actionSearch() { $headers = Yii::$app->response->getHeaders(); $headers->set('X-Robots-Tag', 'none'); $headers->set('X-Frame-Options', 'SAMEORIGIN'); $headers->set('X-Content-Type-Options', 'nosniff'); if (!Yii::$app->request->isAjax) { throw new ForbiddenHttpException(); } $model = new Search(); $model->load(Yii::$app->request->get()); $cacheKey = 'ProductSearchIds: ' . $model->q; $ids = Yii::$app->cache->get($cacheKey); if ($ids === false) { $ids = ArrayHelper::merge($model->searchProductsByDescription(), $model->searchProductsByProperty()); Yii::$app->cache->set($cacheKey, $ids, 86400, new TagDependency(['tags' => ActiveRecordHelper::getCommonTag(Product::className())])); } /** @var \app\modules\shop\ShopModule $module */ $module = Yii::$app->modules['shop']; $pages = new Pagination(['defaultPageSize' => $module->searchResultsLimit, 'forcePageParam' => false, 'totalCount' => count($ids)]); $cacheKey .= ' : ' . $pages->offset; $products = Yii::$app->cache->get($cacheKey); if ($products === false) { $products = Product::find()->where(['in', '`id`', array_slice($ids, $pages->offset, $pages->limit)])->addOrderBy('sort_order')->with('images')->all(); Yii::$app->cache->set($cacheKey, $products, 86400, new TagDependency(['tags' => ActiveRecordHelper::getCommonTag(Product::className())])); } Yii::$app->response->format = Response::FORMAT_JSON; return ['view' => $this->renderAjax('search', ['model' => $model, 'pages' => $pages, 'products' => $products]), 'totalCount' => count($ids)]; }
public function actionAutoCompleteSearch($orderId, $term, $parentId = 0) { Yii::$app->response->format = Response::FORMAT_JSON; $query = Product::find()->orderBy('sort_order'); foreach (['name', 'content'] as $attribute) { $query->orWhere(['like', $attribute, $term]); } $products = $query->limit(20)->all(); $result = []; /** @var Product $product */ foreach ($products as $product) { $result[] = ['name' => $product->name, 'url' => Url::toRoute(['add-product', 'orderId' => $orderId, 'productId' => $product->id, 'parentId' => $parentId])]; } return $result; }
/** * @param $parent_id * @return \yii\web\Response * @throws \Exception */ public function actionRemoveAll($parent_id) { $items = Yii::$app->request->post('items', []); if (!empty($items)) { $items = Product::find()->where(['in', 'id', $items])->all(); foreach ($items as $item) { $item->delete(); } } return $this->redirect(['index', 'parent_id' => $parent_id]); }
echo \app\modules\shop\widgets\OptionGenerate::widget(['model' => $model, 'form' => $form, 'footer' => $this->blocks['submit']]); ?> <?php } ?> <?php if (!empty($model->options)) { ?> <?php BackendWidget::begin(['title' => Yii::t('app', 'Product Options'), 'icon' => 'shopping-cart', 'footer' => $this->blocks['submit']]); ?> <?php echo GridView::widget(['dataProvider' => $dataProvider = new ActiveDataProvider(['query' => Product::find()->where(['parent_id' => $model->id])]), 'columns' => [['class' => 'yii\\grid\\DataColumn', 'attribute' => 'id'], ['class' => 'app\\backend\\columns\\TextWrapper', 'attribute' => 'name', 'callback_wrapper' => function ($content, $model, $key, $index, $parent) { return $content; }], 'price', 'old_price', ['class' => 'app\\backend\\components\\ActionColumn', 'buttons' => function ($model, $key, $index, $parent) { return null; }]], 'hover' => true]); ?> <?php BackendWidget::end(); ?> <?php } ?> </article> </div> </section> <?php
/** * renders product item and list. * possible can render all objects, but need for few logic change * @param array $chunkData params for select and render * @param TagDependency $dependency * @return mixed */ private static function renderProducts($chunkData, &$dependency) { $params = ['itemView' => Yii::$app->getModule('shop')->itemView, 'type' => 'show', 'object' => 'product', 'where' => [], 'limit' => 0, 'listView' => Yii::$app->getModule('shop')->listView]; switch ($chunkData['key']) { case 'product': if (ArrayHelper::keyExists('sku', $chunkData)) { $params['where'] = ['sku' => $chunkData['sku']]; } break; case 'productList': $params['type'] = 'list'; break; default: $expression = '%(?P<objectName>[^#]+?)#(?P<objectId>[\\d]+?)$%'; if (preg_match($expression, $chunkData['key'], $matches)) { $params['where']['id'] = $matches['objectId']; } break; } switch ($params['object']) { case 'product': $dependency->tags[] = ActiveRecordHelper::getCommonTag(Product::className()); $query = Product::find(); if (!empty($chunkData['categoryId'])) { $query->leftJoin('{{%product_category}}', Product::tableName() . '.id = {{%product_category}}.object_model_id')->andWhere(['{{%product_category}}.category_id' => $chunkData['categoryId']]); $dependency->tags[] = ActiveRecordHelper::getCommonTag(Category::className()); $dependency->tags[] = ActiveRecordHelper::getObjectTag(Category::className(), $chunkData['categoryId']); } if (!empty($chunkData['property'])) { $expression = '%(?P<propertyKey>[^:]+?):(?P<propertyValue>.+?)$%'; if (preg_match($expression, $chunkData['property'], $matches)) { $property = Property::findOne(['key' => $matches['propertyKey']]); if (!is_null($property)) { /** @var Property $property */ $dependency->tags[] = ActiveRecordHelper::getCommonTag(Property::className()); $dependency->tags[] = $property->objectTag(); if ($property->is_eav == 1) { $query->leftJoin('{{%product_eav}}', Product::tableName() . '.id = {{%product_eav}}.object_model_id')->andWhere(['{{%product_eav}}.key' => $matches['propertyKey'], '{{%product_eav}}.value' => $matches['propertyValue']]); } elseif ($property->has_static_values == 1) { $psv = PropertyStaticValues::findOne(['property_id' => $property->id, 'value' => $matches['propertyValue']]); if (!is_null($psv)) { $dependency->tags[] = ActiveRecordHelper::getCommonTag(PropertyStaticValues::className()); $dependency->tags[] = $psv->objectTag(); $query->leftJoin('{{%object_static_values}}', Product::tableName() . '.id = {{%object_static_values}}.object_model_id')->andWhere(['object_id' => 3, '{{%object_static_values}}.property_static_value_id' => $psv->id]); } else { return ''; } } /** @todo add column_stored */ } else { return ''; } } } break; default: $query = Product::find(); break; } $params = ArrayHelper::merge($params, array_intersect_key($chunkData, $params)); if (!empty($params['where'])) { $query->andWhere($params['where']); } if (!empty($params['limit'])) { $query->limit($params['limit']); } if ($params['type'] === 'list') { $view = $params['listView']; $objects = $query->all(); foreach ($objects as $object) { $dependency->tags[] = $object->objectTag(); } switch ($params['object']) { case 'product': $viewParams = ['products' => $objects]; break; default: $viewParams = ['products' => $objects]; break; } } else { $view = $params['itemView']; $object = $query->one(); if (is_null($object)) { return ''; } $dependency->tags[] = $object->objectTag(); switch ($params['object']) { case 'product': $viewParams = ['product' => $object, 'url' => Url::to(['@product', 'model' => $object, 'category_group_id' => $object->getMainCategory()->category_group_id])]; break; default: $viewParams = ['product' => $object, 'url' => Url::to(['@product', 'model' => $object, 'category_group_id' => $object->getMainCategory()->category_group_id])]; break; } } return Yii::$app->view->render($view, $viewParams); }
public function actionGenerate() { $ymlConfig = new Yml(); if (!$ymlConfig->loadConfig()) { return false; } static::$noimg = Yii::$app->getModule('image')->noImageSrc; if (1 == $ymlConfig->offer_param) { $this->prepareProperties(); } \Yii::$app->urlManager->setHostInfo($ymlConfig->shop_url); $filePath = \Yii::getAlias('@webroot') . '/' . $ymlConfig->general_yml_filename; $tpl = <<<'TPL' <name>%s</name> <company>%s</company> <url>%s</url> <currencies> <currency id="%s" rate="1" plus="0"/> </currencies> <categories> %s </categories> <store>%s</store> <pickup>%s</pickup> <delivery>%s</delivery> <local_delivery_cost>%s</local_delivery_cost> <adult>%s</adult> TPL; $section_categories = ''; $categories = Category::find()->where(['active' => 1])->asArray(); /** @var Category $row */ foreach ($categories->each(500) as $row) { $section_categories .= '<category id="' . $row['id'] . '" ' . (0 != $row['parent_id'] ? 'parentId="' . $row['parent_id'] . '"' : '') . '>' . htmlspecialchars(trim(strip_tags($row['name']))) . '</category>' . PHP_EOL; } unset($row, $categories); $section_shop = sprintf($tpl, $ymlConfig->shop_name, $ymlConfig->shop_company, $ymlConfig->shop_url, $ymlConfig->currency_id, $section_categories, 1 == $ymlConfig->shop_store ? 'true' : 'false', 1 == $ymlConfig->shop_pickup ? 'true' : 'false', 1 == $ymlConfig->shop_delivery ? 'true' : 'false', $ymlConfig->shop_local_delivery_cost, 1 == $ymlConfig->shop_adult ? 'true' : 'false'); $section_offers = ''; // $offer_type = ('simplified' === $ymlConfig->general_yml_type) ? '' : 'type="'.$ymlConfig->general_yml_type.'"'; $offer_type = ''; // временно, пока не будет окончательно дописан механизм для разных типов $products = Product::find()->where(['active' => 1]); /** @var Product $row */ foreach ($products->each(100) as $row) { $price = $this->getByYmlParam($ymlConfig, 'offer_price', $row, 0); $price = intval($price); if ($price <= 0 || $price >= 1000000000) { continue; } $offer = '<offer id="' . $row->id . '" ' . $offer_type . ' available="true">' . PHP_EOL; /** @var Category $category */ $category = $row->category; $category = empty($category) ? 1 : $category->category_group_id; $offer .= '<url>' . Url::to(['/shop/product/show', 'model' => $row, 'category_group_id' => $category], true) . '</url>' . PHP_EOL; $offer .= $this->wrapByYmlParam($ymlConfig, 'offer_price', $row, '<price>%s</price>' . PHP_EOL); $offer .= '<currencyId>' . $ymlConfig->currency_id . '</currencyId>' . PHP_EOL; $offer .= $this->wrapByYmlParam($ymlConfig, 'offer_category', $row, '<categoryId>%s</categoryId>' . PHP_EOL); $offer .= $this->wrapByYmlParam($ymlConfig, 'offer_picture', $row, function ($value) use($ymlConfig) { if (empty($value)) { return $value; } $value = '<picture>' . rtrim($ymlConfig->shop_url, '/') . $value . '</picture>' . PHP_EOL; return $value; }); $offer .= $this->wrapByYmlParam($ymlConfig, 'offer_name', $row, function ($value) use($ymlConfig) { if (mb_strlen($value) > 120) { $value = mb_substr($value, 0, 120); $value = mb_substr($value, 0, mb_strrpos($value, ' ')); } $value = '<name>' . htmlspecialchars(trim(strip_tags($value))) . '</name>' . PHP_EOL; return $value; }); $offer .= $this->wrapByYmlParam($ymlConfig, 'offer_description', $row, function ($value) use($ymlConfig) { if (mb_strlen($value) > 175) { $value = mb_substr($value, 0, 175); $value = mb_substr($value, 0, mb_strrpos($value, ' ')); } $value = '<description>' . htmlspecialchars(trim(strip_tags($value))) . '</description>' . PHP_EOL; return $value; }); if (1 == $ymlConfig->offer_param) { $offer .= $this->getValues($row); } $offer .= '</offer>'; $section_offers .= $offer . PHP_EOL; } unset($row, $products); $ymlFileTpl = <<<'TPL' <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE yml_catalog SYSTEM "shops.dtd"> <yml_catalog date="%s"> <shop> %s <offers> %s </offers> </shop> </yml_catalog> TPL; $fileString = sprintf($ymlFileTpl, date('Y-m-d H:i'), $section_shop, $section_offers); if (1 == $ymlConfig->use_gzip) { file_put_contents($filePath . '.gz', gzencode($fileString, 5)); } file_put_contents($filePath, $fileString); }
/** * @return bool */ public function generate() { if (false === $this->model instanceof YmlModel) { return false; } /** @var \app\modules\shop\models\Yml $yml */ $config = $this->model; /** @var View $view */ $view = \Yii::$app->getView(); $outputParams = []; $outputParams['shop'] = $this->generateSectionShop($config); $outputParams['offers'] = []; $eventOffer = new YmlOffersEvent(); /** @var Product $model */ foreach (Product::find()->where(['active' => 1])->batch() as $offers) { $eventOffer->clearHandled()->setOffers(array_reduce($offers, function ($r, $i) use($config) { if (null !== ($o = $this->generateSingleOffer($config, $i))) { $r[] = $o; } return $r; }, [])); $this->trigger(static::EVENT_PROCESS_OFFER, $eventOffer); $outputParams['offers'] = array_merge($outputParams['offers'], array_column($eventOffer->getOffers(), 'result')); } $output = $view->renderFile($this->viewFile, $outputParams); $fileName = \Yii::getAlias('@webroot') . '/' . $config->general_yml_filename; $result = static::USE_GZIP === $config->use_gzip ? file_put_contents($fileName . '.gz', gzencode($output), 5) : file_put_contents($fileName, $output); return false !== $result; }