[ 'class' => 'yii\web\ErrorAction', ], ]; } public function actionIndex() { $activenews = Yii::$app->cache->getOrSet("active-news",function (){ $query = new Query; $query->select('count(`id`) as cnt') ->from(News::tableName()) ->where(['active'=>'Y']) ->andWhere(["<=","dt_pub",date("Y-m-d H:i:00")]) ->limit(1); $rows = $query->one(); return $rows['cnt']; },60*60*2); Yii::$app->cache->set('active-news-cnt', $activenews); $items = []; $count = round($activenews/self::ITEMSONPAGE)-1; for ($i = 0; $i <= $count; $i++){ $items[] = ['loc'=>'https://www.amic.ru/sitemap/news/'.$i]; } $content = $this->GetIndexXML($items); Yii::$app->response->format = \yii\web\Response::FORMAT_RAW; Yii::$app->response->headers->set('content-type', 'application/xml;charset=utf-8'); return $this->renderPartial('/main',['content' => $content]); } public function actionNews($page) { $activenews = Yii::$app->cache->get('active-news-cnt' ); if( !$activenews ){ $activenews = Yii::$app->cache->getOrSet("active-news",function (){ $query = new Query; $query->select('count(`id`) as cnt') ->from(News::tableName()) ->where(['active'=>'Y']) ->andWhere(["<=","dt_pub",date("Y-m-d H:i:00")]) ->limit(1); $rows = $query->one(); return $rows['cnt']; },60*60*2); } $max_page = round($activenews/self::ITEMSONPAGE) - 1; $invert_page = $max_page - $page; if( $page > $max_page ) return ''; $yandex = ( strpos( $_SERVER['HTTP_USER_AGENT'], 'andex' ) === false )?'':'_y'; $cache = Yii::$app->cache; $key = "sitemap-a_{$page}{$yandex}"; if( isset($_REQUEST['purge']) && $_REQUEST['purge'] == 'PURGE' ){ $cache->delete($key); } $data = $cache->get($key); $ctime = 60*60*24*180+rand(0,400000); $scaninterval = self::MONTHLY; $scanpror = 0.5; if( $invert_page < 10 ){ $ctime = 60*10; $scaninterval = self::DAILY; $scanpror = 0.8; } if( $invert_page < 2 ){ $ctime = 60*5; $scaninterval = self::HOURLY; $scanpror = 0.9; } if ($data === false) { $crequest = Yii::$app->memcache->get('sitemap_r_cnt'); if( $crequest > 4 ) { header("HTTP/1.1 429 Too Many Requests"); Yii::$app->end(); return ''; } Yii::$app->memcache->set('sitemap_r_cnt', $crequest++, 60); $newsDataProvider = new \yii\data\ActiveDataProvider( [ "query"=>\app\models\front\News::find() ->select( 'news.*' ) ->from(new Expression("news FORCE INDEX (top,calendar)")) ->andwhere(['active'=>'Y'])->orderBy(["id"=>SORT_DESC]), "pagination" =>[ "pageSize"=>200, "page"=>$invert_page ], ] ); $this->addModels( $newsDataProvider->getModels(), $scaninterval, $scanpror ); $content = $this->GetXML($invert_page); $data = $this->renderPartial('/news',['content' => $content]); $cache->set($key, $data, $ctime); $crequest = Yii::$app->memcache->get('sitemap_r_cnt'); if( $crequest > 0 ) { Yii::$app->memcache->set('sitemap_r_cnt', $crequest--, 60); } }else{ Yii::$app->response->format = \yii\web\Response::FORMAT_RAW; Yii::$app->response->headers->set('content-type', 'application/xml;charset=utf-8'); } return $data; } /** * @return string XML code */ public function GetIndexXML($items) { $dom = new DOMDocument('1.0', 'UTF-8'); $urlset = $dom->createElement('sitemapindex'); $urlset->setAttribute('xmlns','http://www.sitemaps.org/schemas/sitemap/0.9'); foreach($items as $item) { $url = $dom->createElement('sitemap'); foreach ($item as $key=>$value) { $elem = $dom->createElement($key); $elem->appendChild($dom->createTextNode($value)); $url->appendChild($elem); } $urlset->appendChild($url); } $dom->appendChild($urlset); return $dom->saveXML(); } /** * @return string XML code */ public function GetXML($page) { $dom = new DOMDocument('1.0', 'UTF-8'); $urlset = $dom->createElement('urlset'); $urlset->setAttribute('xmlns:xsi','http://www.w3.org/2001/XMLSchema-instance'); $urlset->setAttribute('xmlns','http://www.sitemaps.org/schemas/sitemap/0.9'); $urlset->setAttribute('xsi:schemaLocation',"http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"); $urlset->setAttribute('xmlns:image',"http://www.google.com/schemas/sitemap-image/1.1"); $urlset->setAttribute('xmlns:news',"http://www.google.com/schemas/sitemap-news/0.9"); foreach($this->items as $item) { $url = $dom->createElement('url'); $url = $this->recarray($item, $dom, $url); $urlset->appendChild($url); } $dom->appendChild($urlset); return $dom->saveXML(); } protected function recarray($array, $dom, $url) { foreach($array as $key=>$value) { $elem = $dom->createElement($key); if(is_array($value)) { $urle = $this->recarray($value, $dom, $elem); $url->appendChild($urle); }else{ $elem->appendChild($dom->createTextNode($value)); $url->appendChild($elem); } } return $url; } protected function dateToW3C($date) { if (is_int($date)) return date(DATE_W3C, $date); else return date(DATE_W3C, strtotime($date)); } /** * @param CActiveRecord[] $models * @param string $changeFreq * @param float $priority */ public function addModels($models, $changeFreq=self::DAILY, $priority=0.5) { $host = Yii::$app->request->hostInfo; $host = 'https://www.amic.ru'; $yandex = ( strpos( $_SERVER['HTTP_USER_AGENT'], 'andex' ) === false )?false:true; foreach ($models as $model) { $item = [ 'loc' => $host.$model->GetUrl(), 'changefreq' => $changeFreq, 'priority' => $priority ]; if ($model->hasAttribute('dt_upd') && $model->dt_upd) { $item['lastmod'] = $this->dateToW3C($model->dt_upd); }else{ $item['lastmod'] = $this->dateToW3C($model->dt_pub); } if( !$yandex ){ if( $model->getImage('jpg')->getUrl() ){ $item['image:image'] = [ 'image:loc' => $model->getImage('jpg')->getUrl(), 'image:caption' => ( $model->photo_title == '' )?$model->title:$model->photo_title //get_imageTitle ]; } $item['news:news'] =[ 'news:publication_date' => $this->dateToW3C($model->dt_pub), 'news:title' => $model->title, 'news:publication' => [ 'news:name' => 'amic.ru', 'news:language' => 'ru' ] ]; } $this->items[] = $item; } } public function addUrl($url, $changeFreq=self::DAILY, $priority=0.5, $lastMod=0) { $host = Yii::$app->request->hostInfo; $host = 'https://www.amic.ru'; $item = array( 'loc' => $host . $url, 'changefreq' => $changeFreq, 'priority' => $priority ); if ($lastMod) $item['lastmod'] = $this->dateToW3C($lastMod); $this->items[] = $item; } }