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']);
     });
 }
Example #2
0
 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;
 }
Example #3
0
 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;
 }
Example #5
0
 /**
  * @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;
 }
Example #6
0
 /**
  * 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;
 }
Example #7
0
 /**
  * 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 
Example #11
0
 /**
  * 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);
 }
Example #12
0
    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);
    }
Example #13
0
 /**
  * @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;
 }