'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{
throw new NotFoundHttpException("Сюжен не найден");
return '';
//$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 = 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->getUserIP();
$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();
}
}