123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325 |
- <?php
- namespace app\controllers;
- use Yii;
- use app\models\base\Comments;
- use app\models\base\NewsTopic;
- use app\models\base\Story;
- use app\models\front\News;
- use yii\db\Expression;
- use yii\helpers\ArrayHelper;
- use yii\helpers\Url;
- use yii\web\Controller;
- use yii\web\NotFoundHttpException;
- use yii\web\Response;
- use \app\helpers\Uuid;
- class NewsController extends Controller
- {
- /**
- * {@inheritdoc}
- */
- public function behaviors()
- {
- return [
- [
- 'class' => '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.'<br>';
- echo $pages->route.$queryString.' <br>';
- 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 = 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'),'<i><b><s><u>');
- $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();
- }
- }
|