SiteMapController.php 14.1 KB
<?php
    
    namespace artweb\artbox\ecommerce\console;
    
    use artweb\artbox\ecommerce\models\Brand;
    use artweb\artbox\ecommerce\models\Product;
    use artweb\artbox\ecommerce\models\ProductVariant;
    use artweb\artbox\language\components\LanguageUrlManager;
    use artweb\artbox\language\models\Language;
    use artweb\artbox\seo\models\Seo;
    use artweb\artbox\ecommerce\models\Category;
    use Yii;
    use artweb\artbox\models\Page;
    use yii\helpers\ArrayHelper;
    use yii\helpers\Console;
    use yii\helpers\Url;
    use yii\console\Controller;
    
    class SiteMapController extends Controller
    {
        
        private $urlList = [ 'https://extremstyle.ua/ru' ];
        private $count = 1;
        public $fileName;
        public $handle;
        public $mapNumber = 1;
        public $mainMap = '';
        public $content = '';
        public $robots = [];
        
        public function getAddStatic()
        {
            return [
                Yii::$app->urlManager->baseUrl . '/ru',
            ];
        }
        
        public function getHost()
        {
            return Yii::$app->urlManager->baseUrl . '/ru';
        }
        
        public function getVariants()
        {
            return Product::find()->select('product.*', 'DISTINCT ON (product_id)')
                ->with('lang')
                ->innerJoinWith('enabledVariants.lang');
        }
        
        public function getProducts()
        {
            $products = Product::find()
                               ->innerJoinWith('variant')
                               ->innerJoinWith('brand.lang')->with('lang')
                               ->where([
                                               '!=',
                                               'product_variant.price',
                                               0
                                           ])
                ->andWhere([
                               '!=',
                               'product_variant.stock',
                               0
                           ])
                               ->all();
            
            return $products;
        }
        
        public function getSeoLinks()
        {
            return Seo::find()
                      ->where(
                          [
                              '!=',
                              'meta',
                              'noindex,nofollow',
                          ]
                      )
                      ->all();
            
        }
        
        public function getStaticPages()
        {
            return Page::find()
                       ->with('lang')
                       ->all();
        }
        
        public function getCategories()
        {
            return Category::find()
                           ->joinWith('lang')
                           ->where(
                               [
                                   '!=',
                                   'parent_id',
                                   0,
                               ]
                           )
                           ->andWhere(
                               [
                                   'not',
                                   [
                                       'meta_robots' => [
                                           'noindex,nofollow',
                                           'noindex, nofollow',
                                           'noindex,follow',
                                           'noindex, follow',
                                       ],
                                   ],
                               ]
                           )
                           ->all();
        }
        
        public function getCategoriesWithFilters()
        {
            return Category::find()
                           ->with('lang')
                           ->joinWith('taxGroups.lang')
                           ->with('taxGroups.taxOptions.lang')
                           ->where(
                               [
                                   '!=',
                                   'parent_id',
                                   0,
                               ]
                           )
                           ->andWhere(
                               [
                                   'not',
                                   [
                                       'tax_group.meta_robots' => [
                                           'noindex,nofollow',
                                           'noindex, nofollow',
                                           'noindex,follow',
                                           'noindex, follow',
                                       ],
                                   ],
                               ]
                           )
                           ->andWhere([ 'tax_group.is_filter' => true ])
                           ->all();
        }
        
        public function getBrands()
        {
            return Brand::find()
                        ->joinWith('lang')
                        ->andWhere(
                            [
                                'not',
                                [
                                    'meta_robots' => [
                                        'noindex,nofollow',
                                        'noindex, nofollow',
                                        'noindex,follow',
                                        'noindex, follow',
                                    ],
                                ],
                            ]
                        )
                        ->all();
        }
        
        public function checkUrl($url)
        {
            if (!in_array($url, $this->urlList)) {
                $this->urlList[] = $url;
                return true;
            } else {
                return false;
            }
        }
        
        public function createRow($url, $priority, $freq = 'Weekly')
        {
            if(in_array($url, $this->robots)) {
                return;
            }
            //            if ($this->checkUrl($url)) {
            if ($this->count % 500 == 0) {
                $this->stdout($this->count . " : ", Console::BOLD);
                $this->stdout($url . "\n", Console::FG_YELLOW);
            }
            $this->content .= '<url>' . '<loc>' . $url . '</loc>' . '<lastmod>' . date(
                    'Y-m-d'
                ) . '</lastmod>' . '<changefreq>' . $freq . '</changefreq>' . '<priority>' . $priority . '</priority>' . '</url>';
            $this->count++;
            if ($this->count % 10000 == 0) {
                $this->content .= '</urlset>';
                $this->stdout('Added unset' . "\n", Console::FG_CYAN);
                fwrite($this->handle, $this->content);
                fclose($this->handle);
                $this->mapNumber++;
                
                $this->mainMap .= '<sitemap>' . '<loc>https://extremstyle.ua/' . $this->fileName . '</loc>' . '<lastmod>' . date(
                        'Y-m-d'
                    ) . '</lastmod>' . '</sitemap>';
                
                $this->fileName = 'sitemap' . $this->mapNumber . '.xml';
                $this->handle = fopen(Yii::getAlias('@frontend') . '/web' . '/' . $this->fileName, "w");
                
                $this->content = '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
            }
            //            }
        }
        
        public function actionProcess()
        {
            
            Language::setCurrent('ru');
            
            $config = ArrayHelper::merge(
                require( \Yii::getAlias('@frontend/config/') . 'main.php' ),
                require( \Yii::getAlias('@common/config/') . 'main.php' ),
                [ 'components' => [ 'urlManager' => [ 'hostInfo' => 'https://extremstyle.ua' ] ] ]
            );
            
            if (isset($config[ 'components' ][ 'urlManager' ][ 'class' ])) {
                unset($config[ 'components' ][ 'urlManager' ][ 'class' ]);
            }
            //Yii::$app->urlManager = new LanguageUrlManager($config['components']['urlManager']);
            
            $urlManager = new LanguageUrlManager($config[ 'components' ][ 'urlManager' ]);
            
            $this->mainMap = '<?xml version="1.0" encoding="UTF-8"?>';
            $this->mainMap .= '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
            $this->fileName = 'sitemap' . $this->mapNumber . '.xml';
            setlocale(LC_ALL, 'ru_RU.CP1251');
            $this->handle = fopen(Yii::getAlias('@frontend') . '/web' . '/' . $this->fileName, "w");
            
            $this->content = '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
            
            $robots = file_get_contents(\Yii::getAlias('@frontend/web/robots.txt'));
            if (preg_match_all('/Disallow: (.*)\n/', $robots, $matches)) {
                foreach ($matches[ 1 ] as $match) {
                    $this->robots[] = $this->getHost() . $match;
                }
            }
            
            $this->stdout('Add static' . PHP_EOL, Console::FG_BLUE);
            foreach ($this->getAddStatic() as $page) {
                $this->createRow($page, 1, 'Daily');
            }
    
            $this->stdout('Add pages' . PHP_EOL, Console::FG_BLUE);
    
            foreach ($this->getStaticPages() as $page) {
                $url = $urlManager->createAbsoluteUrl(
                    [
                        'site/page',
                        'slug' => $page->lang->alias,
                    ]
                );
                $this->createRow($url, 0.5);
            }
    
            $this->stdout('Add categories' . PHP_EOL, Console::FG_BLUE);
    
            foreach ($this->getCategories() as $category) {
                $url = $urlManager->createAbsoluteUrl(
                    [
                        'catalog/category',
                        'category' => $category->lang->alias,
                    ]
                );
                $this->createRow($url, 0.9, 'Daily');
            }
            
//            foreach ($this->getVariants()
//                          ->each(1000) as $row) {
//                /**
//                 * @var Product $row
//                 */
//                if(!empty($row->enabledVariants)) {
//                    $variant = $row->enabledVariants[0];
//                }
//                if(!empty($variant)) {
//                    if (!preg_match("@^[a-zA-Z\d]+$@i", $variant->sku)) {
//                        continue;
//                    }
//                    $url = $urlManager->createAbsoluteUrl(
//                        [
//                            'catalog/product',
//                            'product' => $row->lang->alias,
//                        ]
//                    );
//                    $this->createRow($url, 0.7, 'Daily');
//                }
//            }
            /**
             * New products generation
             */
    
            $this->stdout('Add products' . PHP_EOL, Console::FG_BLUE);
    
            foreach ($this->getProducts() as $product) {
                /**
                 * @var Product $product
                 */
                $url = $urlManager->createAbsoluteUrl(
                    [
                                'catalog/product',
                                'product' => $product->lang->alias,
                            ]
                );
                $this->createRow($url, 0.7, 'Daily');
            }
    
            $this->stdout('Add brands' . PHP_EOL, Console::FG_BLUE);
    
            foreach ($this->getBrands() as $brand) {
                
                $url = $urlManager->createAbsoluteUrl(
                    [
                        'brand/view',
                        'slug' => $brand->lang->alias,
                    ]
                );
                $this->createRow($url, 0.5);
                
            }
    
            $this->stdout('Add filters' . PHP_EOL, Console::FG_BLUE);
    
            foreach ($this->getCategoriesWithFilters() as $category) {
                foreach ($category->taxGroups as $group) {
                    if (in_array(
                        $group->meta_robots,
                        [
                            'noindex,nofollow',
                            'noindex, nofollow',
                            'noindex,follow',
                            'noindex, follow',
                        ]
                    )) {
                        continue;
                    }
                    if ($group->is_filter) {
                        foreach ($group->options as $option) {
                            $url = $urlManager->createAbsoluteUrl(
                                [
                                    'catalog/category',
                                    'category' => $category,
                                    'filters'  => [ $group->lang->alias => [ $option->lang->alias ] ],
                                ]
                            );
                            $this->createRow($url, 0.8, 'Daily');
                        }
                    }
                    
                }
            }
    
            $this->stdout('Add seo links' . PHP_EOL, Console::FG_BLUE);
    
            foreach ($this->getSeoLinks() as $link) {
                $url = Yii::$app->urlManager->baseUrl . $link->url;
                $this->createRow($url, 0.7);
                
            }
            
            $this->content .= '</urlset>';
            
            fwrite($this->handle, $this->content);
            fclose($this->handle);
            
            $this->mainMap .= '<sitemap>' . '<loc>' . 'https://extremstyle.ua/' . $this->fileName . '</loc>' . '<lastmod>' . date(
                    'Y-m-d'
                ) . '</lastmod>' . '</sitemap>' . '</sitemapindex>';
            
            $mainHandle = fopen(Yii::getAlias('@frontend') . '/web/sitemap.xml', "w");
            fwrite($mainHandle, $this->mainMap);
            fclose($mainHandle);
            
            $this->stdout(Yii::getAlias('@frontend') . '/web' . '/' . $this->fileName . "\n", Console::FG_GREEN);
        }
        
    }