123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 |
- <?php
- namespace sitemap\controllers;
- use Yii;
- use yii\web\Controller;
- use yii\web\Response;
- use yii\helpers\ArrayHelper;
- use yii\helpers\Url;
- use DOMDocument;
- use app\models\front\News;
- use yii\db\ActiveQuery;
- use yii\db\Query;
- use yii\db\Expression;
- /**
- * DefaultController implements actions
- */
- class DefaultController extends Controller
- {
- const ALWAYS = 'always';
- const HOURLY = 'hourly';
- const DAILY = 'daily';
- const WEEKLY = 'weekly';
- const MONTHLY = 'monthly';
- const YEARLY = 'yearly';
- const NEVER = 'never';
- const ITEMSONPAGE = 200;
- protected $items = array();
- public $defaultAction = 'index';
- public function actions()
- {
- return [
- 'error' => [
- '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','https://www.w3.org/2001/XMLSchema-instance');
- $urlset->setAttribute('xmlns','https://www.sitemaps.org/schemas/sitemap/0.9');
- $urlset->setAttribute('xsi:schemaLocation',"https://www.sitemaps.org/schemas/sitemap/0.9 https://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd");
- $urlset->setAttribute('xmlns:image',"https://www.google.com/schemas/sitemap-image/1.1");
- $urlset->setAttribute('xmlns:news',"https://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 ){
- $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' => $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;
- }
- }
|