'yii\filters\HttpCache', 'only' => ['index'], 'enabled' => true, 'cacheControlHeader' => 'public, max-age=120', 'lastModified' => function ($action, $params) { return time(); } ], ]; } public function actionIndex($topic=NULL) { $url = \Yii::$app->request->pathInfo; if( $url == 'news/' ){ $queryString = \Yii::$app->request->queryString?'?'.\Yii::$app->request->queryString:''; $this->redirect('/news'.$queryString, 301); return ''; } $gets = \Yii::$app->request->get(); $valid_get = array_filter($gets, function($k) { $valid = ['page'=>true,'daterange'=>true,'topic'=>true]; return isset( $valid[$k] ); }, ARRAY_FILTER_USE_KEY); if( count($gets) != count($valid_get) ){ $url = Url::toRoute(['news/index']+$valid_get); $this->redirect($url, 301); return ''; } if(\Yii::$app->request->get("page",0)>500) { \Yii::$app->request->setQueryParams(["page"=>500]); } $url = $topic; $topic = NewsTopic::findOne(['url'=>$topic,'active'=>1]); if(!$topic instanceof NewsTopic){ $topic = new \stdClass(); $topic->id = NULL; } if( $url && !$topic->id ) throw new NotFoundHttpException("Раздел не найден"); $pages = null; if( $topic->id ){ // $news_query = \app\models\front\News::find()->leftJoin('news_topic_relation t', 't.news_id = id')->andWhere(['t.topic_id'=>$topic->id]); $news_query = News::find() ->from(new Expression("news FORCE INDEX (top,calendar) , news_topic_relation t USE index(news_id)")) ->andWhere(new Expression('t.news_id=id')) ->andWhere(['t.topic_id'=>$topic->id]); $dateRange = \Yii::$app->request->get('daterange',NULL); $dateRanges = $dateRange; if(!is_null($dateRange) && $dateRange!=""){ $dateRange = explode(" — ",$dateRange); $dateRange[0] = date("Y-m-d 00:00:01",strtotime($dateRange[0])); $dateRange[1] = isset($dateRange[1])?date("Y-m-d 23:59:59",strtotime($dateRange[1])):date("Y-m-d 23:59:59",strtotime($dateRange[0])); $news_query->andWhere(["BETWEEN","dt_pub",$dateRange[0],$dateRange[1]]); } $cnt = \Yii::$app->cache->getOrSet('topic_cnt_'.$topic->id."_$dateRanges", function () use ($news_query){ return $news_query->count(); },7200); /* * Оптимизировано но не понятно как убрать автоматический offset при пагинации во внешнем селекте 4с->0.7c $sub_query = News::find()->select('news.id')->from(new Expression("news as news USE INDEX (calendar)")) ->join('inner join', 'news_topic_relation', 'news_topic_relation.news_id=news.id AND news_topic_relation.topic_id='.$topic->id)->offset($pages->offset)->limit($pages->limit); $news_query = News::find() ->from( 'news' ) ->join( 'join',['nl'=>$sub_query], 'news.id=nl.id' ); */ }else{ $news_query = \app\models\front\News::findFilter(); $keyadd = \app\models\front\News::keyFilter(); $dateRange = \Yii::$app->request->get('daterange',NULL); $dateRanges = crc32($dateRange); if(!is_null($dateRange) && $dateRange!=""){ $dateRange = explode(" — ",$dateRange); $dateRange[0] = date("Y-m-d 00:00:01",strtotime($dateRange[0])); $dateRange[1] = isset($dateRange[1])?date("Y-m-d 23:59:59",strtotime($dateRange[1])):date("Y-m-d 23:59:59",strtotime($dateRange[0])); $news_query->andWhere(["BETWEEN","dt_pub",$dateRange[0],$dateRange[1]]); } $cnt = \Yii::$app->cache->getOrSet('topic_cnt'.$keyadd."_$dateRanges", function () use ($news_query){ return $news_query->count(); },7200); } $cnt = ($cnt/20 > 500)?500*20:$cnt; $pages = new \yii\data\Pagination(['totalCount' => $cnt, 'pageSize'=>20]); if($topic instanceof NewsTopic){ /* Приведение к каноническому маршруту в пагинации */ unset($valid_get['topic']); $pages->params = $valid_get; $pages->route = 'news/'.$topic->url; // // Нормализация к каноническому URL // $queryString = \Yii::$app->request->queryString?'?'.\Yii::$app->request->queryString:''; if( \Yii::$app->request->url != '/'.$pages->route.$queryString ){ $url = Url::toRoute(['news/'.$topic->url]+$valid_get); /* echo \Yii::$app->request->url.'
'; echo $pages->route.$queryString.'
'; echo $url; */ $this->redirect($url, 301); return ''; } } //$pages->urlManager = Url::toRoute(['news/index']+$valid_get); // $headers = Yii::$app->response->headers; // $headers->set('Expires', gmdate('D, d M Y H:i:s \G\M\T', time() + (60 * 2))); return $this->render("index",["topic"=>$topic,"daterange"=>$dateRange,"news_query"=>$news_query,"pages"=>$pages,"keycahe"=>isset($keyadd)?$keyadd:'']); } public function actionStory($topic=NULL) { $topic = Story::findOne(['url'=>$topic]); if(!$topic instanceof Story){ $topic = new \stdClass(); $topic->id = NULL; } if( $topic->id ){ $news_query = \app\models\front\News::find()->leftJoin('story_relation t', 't.news_id = id')->andWhere(['t.topic_id'=>$topic->id]); //joinWith('topics t')->andFilterWhere(['t.id'=>$topic->id]); // print_r($news_query->createCommand()->rawSQL);exit; }else{ $news_query = \app\models\front\News::find(); // optimized } $cnt = \Yii::$app->cache->getOrSet('story_cnt_'.$topic->id, function () use ($news_query){ return $news_query->count(); },7200); $pages = new \yii\data\Pagination(['totalCount' => $cnt, 'pageSize'=>20]); $dateRange = \Yii::$app->request->get('daterange',NULL); if(!is_null($dateRange) && $dateRange!=""){ $dateRange = explode(" — ",$dateRange); $dateRange[0] = date("Y-m-d 00:00:01",strtotime($dateRange[0])); $dateRange[1] = isset($dateRange[1])?date("Y-m-d 23:59:59",strtotime($dateRange[1])):date("Y-m-d 23:59:59",strtotime($dateRange[0])); $news_query->andWhere(["BETWEEN","dt_pub",$dateRange[0],$dateRange[1]]); } return $this->render("index",["topic"=>$topic,"daterange"=>$dateRange,"news_query"=>$news_query,"pages"=>$pages]); } /** * @param int $id */ public function actionView(int $id) { $model = $this->findModel($id); if(!$model instanceof News) throw new NotFoundHttpException("Новость не найдена"); if( $link = trim( $model->link ) ){ $link = str_replace( 'http://www.amic.ru', '', $link); $this->redirect($link, 301); return ''; } $queryString = \Yii::$app->request->queryString?'?'.\Yii::$app->request->queryString:''; if( \Yii::$app->request->url != $model->getUrl().$queryString ){ $this->redirect($model->getUrl(true).$queryString, 301); return ''; } if(\Yii::$app->request->isPost){ $capcha_result = ceil(base64_decode(\Yii::$app->request->post('capcha_salt'))*3.14); if( \Yii::$app->request->post('capcha')=="" || \Yii::$app->request->post('capcha')!= $capcha_result ){ \Yii::$app->session->setFlash('danger','Ошибка размещения комментария, пример решен неверно. Правильный ответ был: '.$capcha_result); } else { if(\Yii::$app->request->post('message')!=""){ $comment = new Comments(); if( $comment::$conf->isActive() ){ $comment->fakename = str_replace('"',"'", (\Yii::$app->request->post('fakename'))); $comment->message = strip_tags(\Yii::$app->request->post('message'),''); $comment->news_id = $model->id; $comment->visible = ( $comment::$conf->isPreModerate() )?'N':'Y'; //если пользователь зареген поставить true $comment->ip_address = \Yii::$app->request->getRemoteIP().",".\Yii::$app->request->userIP; $comment->user_agent = \Yii::$app->request->userAgent; $comment->created_at = date("Y-m-d H:i:s"); $comment->parent_id = \Yii::$app->request->post('parent_id'); $res = $comment->save(); if($res){ \Yii::$app->session->setFlash('success','Комментарий успешно отправлен на модерацию'); $this->redirect($model->getUrl()."#comments"); \Yii::$app->end(); } else { \Yii::$app->session->setFlash('danger','Ошибка размещения комментария'); } } } } } return $this->render('view',['model'=>$model]); } /** * @param string $uid * @return string */ public function actionUidView(string $uid):string { if( Uuid::isvalid($uid) ){ $model = \app\models\News::find()->andWhere(['uid'=>$uid])->one(); if(!$model instanceof \app\models\News) throw new NotFoundHttpException("Новость не найдена"); if( $model->active == 'N' || strtotime($model->dt_pub) > time() ){ return $this->render('view',['model'=>$model]); }else{ $this->redirect($model->geturl()); return ''; } }else{ throw new NotFoundHttpException("Новость не найдена"); } } public function actionStoryslugView($storyslug):string { $model = News::find()->andWhere(['alias'=>$storyslug])->one(); if(!$model instanceof News) throw new NotFoundHttpException("Новость не найдена"); return $this->render('view',['model'=>$model]); } public function actionInfinityNewsfeed($post_id,$last_post_id=NULL,$amount=0){ if($last_post_id=="null"){ $last_post = News::find()->limit(1)->one(); } else { $last_post = News::findOne(["id"=>$last_post_id]); } $feed = News::find() ->andWhere(['!=','id',$post_id]) //->andFilterWhere(['<','id',$last_post_id]) ->andFilterWhere(['<','dt_pub',$last_post->dt_pub]) ->limit(1) ->one(); if(!is_null($feed)){ return $this->asJson([ "id"=>$feed->id, "html"=>$this->renderPartial('/news/view/infinity_newsfeed/_item',["model"=>$feed,"index"=>$amount]) ]); } return NULL; } public function actionClike(){ if(\Yii::$app->request->isPost){ if(\Yii::$app->request->post('id') && \Yii::$app->request->post('grd') ){ $id = (int) \Yii::$app->request->post('id'); //комент $nid = (int) \Yii::$app->request->post('nid'); //новость $grd = (int) \Yii::$app->request->post('grd'); //градиент if( Comments::isUserLike($id) ) return $this->asJson(['err']); if( $id > 0 && ( $grd == 1 || $grd == -1 ) ){ $comment = Comments::findOne($id); $comment->likeed += $grd; if( $comment->save() ){ Comments::setUserLike($nid, $id); } } } } return $this->asJson(['ok']); } public function actionSsearch() { if (Yii::$app->request->isGet && $get = Yii::$app->request->get('query')){ $model = new Story(); $gets = mb_strlen( $get ) < 6?$get.'*':$get; $items = $model->search($gets, 10); $res = array(); $json = '{}'; $resj = json_decode($json); $resj->query = $get; if( $items && is_array( $items ) ){ foreach( $items as $item ){ $res[] = array( 'data'=>$item['id']*1, 'value'=>$item['title'] ); } $resj->suggestions = $res; return json_encode( $resj ); } } $json = '{}'; $resj = json_decode($json); $resj->query = $get; $resj->suggestions = []; return json_encode( $resj ); } private function findModel($id) { return News::find()->andWhere(['id'=>$id])->limit(1)->one(); } }