diff --git a/backend/config/main.php b/backend/config/main.php index 8706b53..64ca3e4 100644 --- a/backend/config/main.php +++ b/backend/config/main.php @@ -8,7 +8,7 @@ $params = array_merge( return [ 'id' => 'app-backend', - 'language' => 'ru_RU', + 'language' => 'ru', 'basePath' => dirname(__DIR__), 'aliases' => [ '@staticRoot' => $params['staticPath'], diff --git a/backend/controllers/SliderController.php b/backend/controllers/SliderController.php index ee5762a..a2df221 100644 --- a/backend/controllers/SliderController.php +++ b/backend/controllers/SliderController.php @@ -30,7 +30,7 @@ class SliderController extends Controller { return [ 'access' => [ - 'class' => AccessControl::className(), + 'class' => AccessControl::class, 'rules' => [ [ 'actions' => ['create', 'view', 'index', 'update', 'delete'], diff --git a/common/bootstrap/SetUp.php b/common/bootstrap/SetUp.php index 7a6d0aa..532b76d 100644 --- a/common/bootstrap/SetUp.php +++ b/common/bootstrap/SetUp.php @@ -147,9 +147,5 @@ class SetUp implements BootstrapInterface } } - // todo move that to pages module - // pages search - $app->params['search_rules'][] = "SELECT title, content, CONCAT('/page/', id) AS url FROM {{pages}}"; - } } \ No newline at end of file diff --git a/common/modules/banners/BannersModule.php b/common/modules/banners/BannersModule.php index d022e41..657f209 100644 --- a/common/modules/banners/BannersModule.php +++ b/common/modules/banners/BannersModule.php @@ -32,7 +32,7 @@ class BannersModule extends \yii\base\Module implements ModuleInterface $app->controllerMap['migrate']['migrationPath'][] = '@common/modules/banners/migrations'; // add search rules - $app->params['search_rules'][] = "SELECT title, CONCAT('/banners/manage/banner/view/', id) AS url FROM {{banners}}"; + $app->params['search_rules'][] = "SELECT title, title as content, CONCAT('/banners/manage/banner/view/', id) AS url FROM {{banners}}"; $app->getUrlManager()->addRules([ 'banners/manage/banner/view/' => 'banners/manage/banner/view', @@ -44,19 +44,28 @@ class BannersModule extends \yii\base\Module implements ModuleInterface 'class' => 'yii\i18n\PhpMessageSource', 'basePath' => '@common/modules/banners/messages', ], - 'banners_public' => [ - 'class' => 'yii\i18n\PhpMessageSource', - 'basePath' => '@common/modules/banners/messages', - ], ]); // add menu items - if (basename($app->getBasePath()) === 'backend') { + if (basename(\Yii::$app->getBasePath()) === 'backend') { $app->params['adminMenu'][] = [ 'label' => \Yii::t( 'banners', 'Banners' ), 'icon' => 'flag', - 'url' => [ '/banners/manage/banner/index' ], - 'visible' => \Yii::$app->user->can( 'admin' ) || \Yii::$app->user->can( 'BannersManagement' ) + 'items' => [ + [ + 'label' => \Yii::t( 'banners', 'Banners' ), + 'icon' => 'caret-right', + 'url' => [ '/banners/manage/banner/index' ], + //'active' => \Yii::$app->controller->getUniqueId() == 'banners/manage/banner' + ], + [ + 'label' => \Yii::t( 'banners', 'Places' ), + 'icon' => 'caret-right', + 'url' => [ '/banners/manage/place/index' ], + //'active' => \Yii::$app->controller->getUniqueId() == 'banners/manage/place' + ], + ], + 'visible' => $app->user->can( 'admin' ) || \Yii::$app->user->can( 'BannersManagement' ), ]; } } diff --git a/common/modules/banners/controllers/manage/BannerController.php b/common/modules/banners/controllers/manage/BannerController.php new file mode 100644 index 0000000..fac3c1c --- /dev/null +++ b/common/modules/banners/controllers/manage/BannerController.php @@ -0,0 +1,156 @@ +service = $service; + } + + public function behaviors(): array + { + return [ + 'access' => [ + 'class' => AccessControl::class, + 'rules' => [ + [ + 'allow' => true, + 'roles' => ['BannersManagement'], + ], + [ // all the action are accessible to admin + 'allow' => true, + 'roles' => ['admin'], + ], + ], + ], + 'verbs' => [ + 'class' => VerbFilter::class, + 'actions' => [ + 'delete' => ['POST'], + ], + ], + ]; + } + + /** + * @return mixed + */ + public function actionIndex() + { + $searchModel = new BannerSearch(); + $dataProvider = $searchModel->search(Yii::$app->request->queryParams); + + return $this->render('index', [ + 'searchModel' => $searchModel, + 'dataProvider' => $dataProvider, + ]); + } + + /** + * @param $id + * + * @return string + * @throws NotFoundHttpException + */ + public function actionView($id) + { + return $this->render('view', [ + 'banner' => $this->findModel($id), + ]); + } + + /** + * @return mixed + */ + public function actionCreate() + { + $form = new BannerForm(); + + if ($form->load(Yii::$app->request->post()) && $form->validate()) { + try { + $form = $this->service->create($form); + return $this->redirect(['view', 'id' => $form->id]); + } catch (\DomainException $e) { + Yii::$app->errorHandler->logException($e); + Yii::$app->session->setFlash('error', $e->getMessage()); + } + } + else { + $form->active = $form->active ?: Banner::STATUS_ACTIVE; + } + return $this->render('create', [ + 'model' => $form, + ]); + } + + /** + * @param $id + * + * @return string|\yii\web\Response + * @throws NotFoundHttpException + */ + public function actionUpdate($id) + { + $banner = $this->findModel($id); + $form = new BannerForm($banner); + $form->start_at = date('d.m.Y H:i:s', $form->start_at); + $form->end_at = date('d.m.Y H:i:s', $form->end_at); + if ($form->load(Yii::$app->request->post()) && $form->validate()) { + try { + $this->service->edit($banner->id, $form); + return $this->redirect(['view', 'id' => $banner->id]); + } catch (\DomainException $e) { + Yii::$app->errorHandler->logException($e); + Yii::$app->session->setFlash('error', $e->getMessage()); + } + } + + return $this->render('update', [ + 'model' => $form, + 'banner' => $banner, + ]); + } + + /** + * @param integer $id + * @return mixed + */ + public function actionDelete($id) + { + try { + $this->service->remove($id); + } catch (\DomainException $e) { + Yii::$app->errorHandler->logException($e); + Yii::$app->session->setFlash('error', $e->getMessage()); + } + return $this->redirect(['index']); + } + + /** + * @param integer $id + * @return Banner the loaded model + * @throws NotFoundHttpException if the model cannot be found + */ + protected function findModel($id): Banner + { + if (($model = Banner::findOne($id)) !== null) { + return $model; + } + throw new NotFoundHttpException('The requested banner does not exist.'); + } +} diff --git a/common/modules/banners/controllers/manage/PlaceController.php b/common/modules/banners/controllers/manage/PlaceController.php new file mode 100644 index 0000000..be2b5d5 --- /dev/null +++ b/common/modules/banners/controllers/manage/PlaceController.php @@ -0,0 +1,154 @@ +service = $service; + } + + public function behaviors(): array + { + return [ + 'access' => [ + 'class' => AccessControl::class, + 'rules' => [ + [ + 'allow' => true, + 'roles' => ['BannersManagement'], + ], + [ // all the action are accessible to admin + 'allow' => true, + 'roles' => ['admin'], + ], + ], + ], + 'verbs' => [ + 'class' => VerbFilter::class, + 'actions' => [ + 'delete' => ['POST'], + ], + ], + ]; + } + + /** + * @return mixed + */ + public function actionIndex() + { + $searchModel = new PlaceSearch(); + $dataProvider = $searchModel->search(Yii::$app->request->queryParams); + + return $this->render('index', [ + 'searchModel' => $searchModel, + 'dataProvider' => $dataProvider, + ]); + } + + /** + * @param $id + * + * @return string + * @throws NotFoundHttpException + */ + public function actionView($id) + { + return $this->render('view', [ + 'place' => $this->findModel($id), + ]); + } + + /** + * @return mixed + */ + public function actionCreate() + { + $form = new BannerPlaceForm(); + if ($form->load(Yii::$app->request->post()) && $form->validate()) { + try { + $form = $this->service->create($form); + return $this->redirect(['view', 'id' => $form->id]); + } catch (\DomainException $e) { + Yii::$app->errorHandler->logException($e); + Yii::$app->session->setFlash('error', $e->getMessage()); + } + } + else { + $form->active = $form->active ?: BannerPlace::STATUS_ACTIVE; + } + return $this->render('create', [ + 'model' => $form, + ]); + } + + /** + * @param $id + * + * @return string|\yii\web\Response + * @throws NotFoundHttpException + */ + public function actionUpdate($id) + { + $place = $this->findModel($id); + + $form = new BannerPlaceForm($place); + if ($form->load(Yii::$app->request->post()) && $form->validate()) { + try { + $this->service->edit($place->id, $form); + return $this->redirect(['view', 'id' => $place->id]); + } catch (\DomainException $e) { + Yii::$app->errorHandler->logException($e); + Yii::$app->session->setFlash('error', $e->getMessage()); + } + } + + return $this->render('update', [ + 'model' => $form, + 'place' => $place, + ]); + } + + /** + * @param integer $id + * @return mixed + */ + public function actionDelete($id) + { + try { + $this->service->remove($id); + } catch (\DomainException $e) { + Yii::$app->errorHandler->logException($e); + Yii::$app->session->setFlash('error', $e->getMessage()); + } + return $this->redirect(['index']); + } + + /** + * @param integer $id + * @return BannerPlace the loaded model + * @throws NotFoundHttpException if the model cannot be found + */ + protected function findModel($id): BannerPlace + { + if (($model = BannerPlace::findOne($id)) !== null) { + return $model; + } + throw new NotFoundHttpException('The requested place does not exist.'); + } +} diff --git a/common/modules/banners/entities/Banner.php b/common/modules/banners/entities/Banner.php new file mode 100644 index 0000000..7a5f1df --- /dev/null +++ b/common/modules/banners/entities/Banner.php @@ -0,0 +1,156 @@ +title = $title; + $banner->image = $image; + $banner->url = $url; + $banner->target = $target; + $banner->start_at = $start_at; + $banner->end_at = $end_at; + $banner->include_urls = $include_urls; + $banner->exclude_urls = $exclude_urls; + $banner->active = $active; + $banner->place_id = $place_id; + return $banner; + } + + public function setImage(UploadedFile $image): void + { + $this->image = $image; + } + + + public function edit($title, $image, $url, $target, $start_at, $end_at, $include_urls, $exclude_urls, $active, $place_id): void + { + $this->title = $title; + $this->image = $image; + $this->url = $url; + $this->target = $target; + $this->start_at = $start_at; + $this->end_at = $end_at; + $this->include_urls = $include_urls; + $this->exclude_urls = $exclude_urls; + $this->active = $active; + $this->place_id = $place_id; + } + + /** + * @inheritdoc + */ + public static function tableName() + { + return 'banners'; + } + + /** + * @inheritdoc + */ + public function attributeLabels() + { + return [ + 'id' => Yii::t('banners', 'ID'), + 'title' => Yii::t('banners', 'Title'), + 'url' => Yii::t('banners', 'URL'), + 'image' => Yii::t('banners', 'Image'), + 'target' => Yii::t('banners', 'Target'), + 'active' => Yii::t('banners', 'Status'), + 'start_at' => Yii::t('banners', 'Start At'), + 'end_at' => Yii::t('banners', 'End At'), + 'created_at' => Yii::t('banners', 'Created At'), + 'updated_at' => Yii::t('banners', 'Updated At'), + 'include_urls' => Yii::t('banners', 'Show only on URLs'), + 'exclude_urls' => Yii::t('banners', 'Not show on URLs'), + 'views' => Yii::t('banners', 'Views'), + 'clicks' => Yii::t('banners', 'Visits'), + 'place_id' => Yii::t('banners', 'Place'), + ]; + } + + public function activate(): void + { + if ($this->isActive()) { + throw new \DomainException('Banner is already active.'); + } + $this->active = self::STATUS_ACTIVE; + } + + public function draft(): void + { + if ($this->isDraft()) { + throw new \DomainException('Banner is already draft.'); + } + $this->active = self::STATUS_DRAFT; + } + + public function isActive(): bool + { + return $this->active == self::STATUS_ACTIVE; + } + + + public function isDraft(): bool + { + return $this->active == self::STATUS_DRAFT; + } + + public function getPlace() + { + return $this->hasOne(BannerPlace::class, ['id' => 'place_id']); + } + + ###################################### + + public function behaviors(): array + { + return [ + TimestampBehavior::class, + ]; + } + + public static function find(): BannerQuery + { + return new BannerQuery(static::class); + } +} diff --git a/common/modules/banners/entities/BannerPlace.php b/common/modules/banners/entities/BannerPlace.php new file mode 100644 index 0000000..83faaaf --- /dev/null +++ b/common/modules/banners/entities/BannerPlace.php @@ -0,0 +1,108 @@ +title = $title; + $place->width = $width; + $place->height = $height; + $place->active = $active; + return $place; + } + + public function edit($title, $width, $height, $active): void + { + $this->title = $title; + $this->width = $width; + $this->height = $height; + $this->active = $active; + } + + /** + * @inheritdoc + */ + public static function tableName() + { + return 'banners_places'; + } + + /** + * @inheritdoc + */ + public function attributeLabels() + { + return [ + 'id' => Yii::t('banners', 'ID'), + 'title' => Yii::t('banners', 'Title'), + 'width' => Yii::t('banners', 'Width'), + 'height' => Yii::t('banners', 'Height'), + 'active' => Yii::t('banners', 'Status'), + ]; + } + + public function activate(): void + { + if ($this->isActive()) { + throw new \DomainException('Place is already active.'); + } + $this->active = self::STATUS_ACTIVE; + } + + public function draft(): void + { + if ($this->isDraft()) { + throw new \DomainException('Place is already draft.'); + } + $this->active = self::STATUS_DRAFT; + } + + public function isActive(): bool + { + return $this->active == self::STATUS_ACTIVE; + } + + public function isDraft(): bool + { + return $this->active == self::STATUS_DRAFT; + } + + public function getBanners() + { + return $this->hasMany(Banner::class, ['place_id' => 'id']); + } + + public function getActiveBanners() + { + return $this->hasMany(Banner::class, ['place_id' => 'id'])->andWhere(['active' => Banner::STATUS_ACTIVE]); + } + + public static function find(): BannerPlaceQuery + { + return new BannerPlaceQuery(static::class); + } +} diff --git a/common/modules/banners/entities/queries/BannerPlaceQuery.php b/common/modules/banners/entities/queries/BannerPlaceQuery.php new file mode 100644 index 0000000..f25c43e --- /dev/null +++ b/common/modules/banners/entities/queries/BannerPlaceQuery.php @@ -0,0 +1,20 @@ +andWhere([ + ($alias ? $alias . '.' : '') . 'active' => BannerPlace::STATUS_ACTIVE, + ]); + } +} \ No newline at end of file diff --git a/common/modules/banners/entities/queries/BannerQuery.php b/common/modules/banners/entities/queries/BannerQuery.php new file mode 100644 index 0000000..e0b7fa8 --- /dev/null +++ b/common/modules/banners/entities/queries/BannerQuery.php @@ -0,0 +1,30 @@ +andWhere(['active' => Banner::STATUS_ACTIVE]); + } + + public function showTime() + { + return $this->andWhere(['<', 'start_at', time()])->andWhere(['>', 'end_at', time()]); + } + + /*public function excludeFree() + { + $current = Url::current([]); + return $this->andWhere(['not rlike', 'exclude_urls', '^'.$current.'$']); + }*/ +} \ No newline at end of file diff --git a/common/modules/banners/forms/BannerForm.php b/common/modules/banners/forms/BannerForm.php new file mode 100644 index 0000000..29e1f57 --- /dev/null +++ b/common/modules/banners/forms/BannerForm.php @@ -0,0 +1,100 @@ +title = $banner->title; + $this->image = $banner->image; + $this->url = $banner->url; + $this->target = $banner->target; + $this->active = $banner->active; + $this->start_at = $banner->start_at; + $this->end_at = $banner->end_at; + $this->include_urls = $banner->include_urls; + $this->exclude_urls = $banner->exclude_urls; + $this->place_id = $banner->place_id; + $this->_banner = $banner; + } + parent::__construct($config); + } + + public function rules(): array + { + return [ + [['title', 'place_id', 'start_at', 'end_at'], 'required'], + [['active', 'place_id', 'active'], 'integer'], + [['title', 'target', 'url'], 'string', 'max' => 255], + [['include_urls', 'exclude_urls'], 'string'], + [['image'], 'file', 'extensions' => 'png, jpg, gif'], + [['start_at','end_at'],'safe'], + /*[['start_at', 'end_at'], 'date', + 'format' => 'php:d.m.Y H:i' + ],*/ + ]; + } + + public function attributeLabels() { + return [ + 'id' => Yii::t('banners', 'ID'), + 'title' => Yii::t('banners', 'Title'), + 'url' => Yii::t('banners', 'URL'), + 'image' => Yii::t('banners', 'Image'), + 'target' => Yii::t('banners', 'Target'), + 'active' => Yii::t('banners', 'Status'), + 'start_at' => Yii::t('banners', 'Start At'), + 'end_at' => Yii::t('banners', 'End At'), + 'created_at' => Yii::t('banners', 'Created At'), + 'updated_at' => Yii::t('banners', 'Updated At'), + 'include_urls' => Yii::t('banners', 'Show only on URLs'), + 'exclude_urls' => Yii::t('banners', 'Not show on URLs'), + 'views' => Yii::t('banners', 'Views'), + 'clicks' => Yii::t('banners', 'Visits'), + 'place_id' => Yii::t('banners', 'Place'), + ]; + } + + public function beforeValidate() { + if (parent::beforeValidate()) { + $this->image = UploadedFile::getInstance($this, 'image'); + $this->start_at = strtotime($this->start_at); + $this->end_at = strtotime($this->end_at); + return true; + } + return false; + } + + /*public function afterValidate() { + if (parent::afterValidate()) { + $this->start_at = strtotime($this->start_at); + $this->end_at = strtotime($this->end_at); + return true; + } + return false; + }*/ +} diff --git a/common/modules/banners/forms/BannerPlaceForm.php b/common/modules/banners/forms/BannerPlaceForm.php new file mode 100644 index 0000000..248c478 --- /dev/null +++ b/common/modules/banners/forms/BannerPlaceForm.php @@ -0,0 +1,47 @@ +title = $place->title; + $this->width = $place->width; + $this->height = $place->height; + $this->active = $place->active; + $this->_place = $place; + } + parent::__construct($config); + } + + public function rules(): array + { + return [ + [['title'], 'required'], + [['width', 'height', 'active'], 'integer'], + ]; + } + + public function attributeLabels() { + return [ + 'id' => Yii::t('banners', 'ID'), + 'title' => Yii::t('banners', 'Title'), + 'width' => Yii::t('banners', 'Width'), + 'height' => Yii::t('banners', 'Height'), + 'active' => Yii::t('banners', 'Status'), + ]; + } +} \ No newline at end of file diff --git a/common/modules/banners/forms/search/BannerSearch.php b/common/modules/banners/forms/search/BannerSearch.php new file mode 100644 index 0000000..e46fb62 --- /dev/null +++ b/common/modules/banners/forms/search/BannerSearch.php @@ -0,0 +1,58 @@ + $query, + 'sort' => [ + 'defaultOrder' => ['id' => SORT_DESC] + ] + ]); + + $this->load($params); + + if (!$this->validate()) { + $query->where('0=1'); + return $dataProvider; + } + + $query->andFilterWhere([ + 'id' => $this->id, + 'active' => $this->active, + 'place_id' => $this->place_id, + 'target' => $this->target + ]); + + $query + ->andFilterWhere(['like', 'title', $this->title]); + return $dataProvider; + } +} diff --git a/common/modules/banners/forms/search/PlaceSearch.php b/common/modules/banners/forms/search/PlaceSearch.php new file mode 100644 index 0000000..b4b8913 --- /dev/null +++ b/common/modules/banners/forms/search/PlaceSearch.php @@ -0,0 +1,58 @@ + $query, + 'sort' => [ + 'defaultOrder' => ['id' => SORT_DESC] + ] + ]); + + $this->load($params); + + if (!$this->validate()) { + $query->where('0=1'); + return $dataProvider; + } + + $query->andFilterWhere([ + 'id' => $this->id, + 'active' => $this->active, + 'width' => $this->width, + 'height' => $this->height + ]); + + $query + ->andFilterWhere(['like', 'title', $this->title]); + return $dataProvider; + } +} diff --git a/common/modules/banners/helpers/BannerHelper.php b/common/modules/banners/helpers/BannerHelper.php new file mode 100644 index 0000000..54cde37 --- /dev/null +++ b/common/modules/banners/helpers/BannerHelper.php @@ -0,0 +1,61 @@ + Yii::t('banners', 'Self window'), + Banner::TARGET_BLANK => Yii::t('banners', 'Blank window'), + ]; + } + + public static function targetName($target): string + { + return ArrayHelper::getValue(self::targetList(), $target); + } + + public static function statusList(): array + { + return [ + Banner::STATUS_DRAFT => Yii::t('banners', 'Draft'), + Banner::STATUS_ACTIVE => Yii::t('banners', 'Active'), + ]; + } + + public static function statusName($status): string + { + return ArrayHelper::getValue(self::statusList(), $status); + } + + public static function statusLabel($status): string + { + switch ($status) { + case Banner::STATUS_DRAFT: + $class = 'label label-default'; + break; + case Banner::STATUS_ACTIVE: + $class = 'label label-success'; + break; + default: + $class = 'label label-default'; + } + + return Html::tag('span', ArrayHelper::getValue(self::statusList(), $status), [ + 'class' => $class, + ]); + } +} diff --git a/common/modules/banners/manifest.php b/common/modules/banners/manifest.php index 185c75e..8d61728 100644 --- a/common/modules/banners/manifest.php +++ b/common/modules/banners/manifest.php @@ -3,6 +3,6 @@ return [ 'version' => '1.0.1', 'name' => 'banners', - 'description' => 'Banners widget for site', + 'description' => 'Banners management and rotation system for site', 'module' => 'BannersModule', ]; \ No newline at end of file diff --git a/common/modules/banners/messages/ru/banners.php b/common/modules/banners/messages/ru/banners.php new file mode 100644 index 0000000..77ff365 --- /dev/null +++ b/common/modules/banners/messages/ru/banners.php @@ -0,0 +1,36 @@ + 'Баннеры', + 'Banners management and rotation system for site' => 'Система управления ротацией баннеров', + 'Banners' => 'Баннеры', + 'Places' => 'Расположения', + 'Title' => 'Название', + 'Width' => 'Ширина', + 'Height' => 'Высота', + 'Create Place' => 'Новое расположение', + 'Create Banner' => 'Новый баннер', + 'Status' => 'Статус', + 'Active' => 'Опубликовано', + 'Draft' => 'Черновик', + 'Publish' => 'Публикация', + 'Update Place: {name}' => 'Редактирование расположения: {name}', + 'Update Banner: {name}' => 'Редактирование баннера: {name}', + 'Place' => 'Расположение', + 'URL' => 'Ссылка', + 'Target' => 'Цель', + 'Self window' => 'Текущее окно', + 'Blank window' => 'Новое окно', + 'Image' => 'Изображение', + 'Start At' => 'Начало показов', + 'End At' => 'Окончание показов', + 'Show only on URLs' => 'Показывать по ссылкам', + 'Not show on URLs' => 'Не показывать по ссылкам', + 'Views' => 'Просмотры', + 'Visits' => 'Переходы', + 'Created At' => 'Создан', + 'Updated At' => 'Обновлен', + 'Insert Code' => 'Код вставки', + 'For template' => 'Для шаблона', + 'For editor' => 'Для редактора', +]; \ No newline at end of file diff --git a/common/modules/banners/migrations/m180821_084231_create_banners_table.php b/common/modules/banners/migrations/m180821_084231_create_banners_table.php new file mode 100644 index 0000000..cec4388 --- /dev/null +++ b/common/modules/banners/migrations/m180821_084231_create_banners_table.php @@ -0,0 +1,42 @@ +createTable('{{%banners}}', [ + 'id' => $this->primaryKey(), + 'title' => $this->string(255)->notNull(), + 'image' => $this->string(255)->notNull(), + 'url' => $this->string(255), + 'target' => $this->string(15)->defaultValue('_blank'), + 'active' => $this->integer(1)->defaultValue(1), + 'start_at' => $this->integer()->unsigned(), + 'end_at' => $this->integer()->unsigned(), + 'created_at' => $this->integer()->unsigned(), + 'updated_at' => $this->integer()->unsigned(), + 'include_urls' => 'LONGTEXT', + 'exclude_urls' => 'LONGTEXT', + 'views' => $this->integer()->unsigned()->defaultValue(0), + 'clicks' => $this->integer()->unsigned()->defaultValue(0), + ], $tableOptions); + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + $this->dropTable('{{%banners}}'); + } +} diff --git a/common/modules/banners/migrations/m180821_100724_create_banners_places_table.php b/common/modules/banners/migrations/m180821_100724_create_banners_places_table.php new file mode 100644 index 0000000..be50d72 --- /dev/null +++ b/common/modules/banners/migrations/m180821_100724_create_banners_places_table.php @@ -0,0 +1,33 @@ +createTable('{{%banners_places}}', [ + 'id' => $this->primaryKey(), + 'title' => $this->string(255)->notNull(), + 'width' => $this->integer(), + 'height' => $this->integer(), + 'active' => $this->integer(1)->defaultValue(1) + ], $tableOptions); + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + $this->dropTable('{{%banners_places}}'); + } +} diff --git a/common/modules/banners/migrations/m180821_100959_add_banners_place_id_field.php b/common/modules/banners/migrations/m180821_100959_add_banners_place_id_field.php new file mode 100644 index 0000000..a1c8ebd --- /dev/null +++ b/common/modules/banners/migrations/m180821_100959_add_banners_place_id_field.php @@ -0,0 +1,31 @@ +addColumn('{{%banners}}', 'place_id', $this->integer()); + + $this->createIndex('idx_banners_place_id', '{{%banners}}', 'place_id'); + $this->addForeignKey('frg_banners_place_id_banners_places_id', '{{%banners}}', 'place_id', 'banners_places', 'id', 'CASCADE'); + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + $this->dropForeignKey('frg_banners_place_id_banners_places_id', '{{%banners}}'); + $this->dropIndex('idx_banners_place_id', '{{%banners}}'); + + $this->dropColumn('{{%banners}}', 'place_id'); + } +} diff --git a/common/modules/banners/repositories/BannerPlaceRepository.php b/common/modules/banners/repositories/BannerPlaceRepository.php new file mode 100644 index 0000000..b9e2769 --- /dev/null +++ b/common/modules/banners/repositories/BannerPlaceRepository.php @@ -0,0 +1,31 @@ +save()) { + throw new \RuntimeException('Saving error.'); + } + } + + public function remove(BannerPlace $place): void + { + if (!$place->delete()) { + throw new \RuntimeException('Removing error.'); + } + } +} \ No newline at end of file diff --git a/common/modules/banners/repositories/BannerRepository.php b/common/modules/banners/repositories/BannerRepository.php new file mode 100644 index 0000000..ebdfdd7 --- /dev/null +++ b/common/modules/banners/repositories/BannerRepository.php @@ -0,0 +1,31 @@ +save()) { + throw new \RuntimeException('Saving error.'); + } + } + + public function remove(Banner $banner): void + { + if (!$banner->delete()) { + throw new \RuntimeException('Removing error.'); + } + } +} \ No newline at end of file diff --git a/common/modules/banners/services/BannerManageService.php b/common/modules/banners/services/BannerManageService.php new file mode 100644 index 0000000..8d33153 --- /dev/null +++ b/common/modules/banners/services/BannerManageService.php @@ -0,0 +1,82 @@ +repository = $repository; + } + + public function create(BannerForm $form): Banner + { + if ($form->image) { + $filename = $form->image->baseName . '_' . (new Security())->generateRandomString(5) . '.' . $form->image->extension; + $path = \Yii::getAlias(Banner::FILE_ORIGINAL_PATH); + if (!file_exists($path)) + { + mkdir($path, 0777, true); + } + $form->image->saveAs($path . '/' . $filename); + $form->image = $filename; + } + + $banner = Banner::create( + $form->title, + $form->image, + $form->url, + $form->target, + $form->start_at, + $form->end_at, + $form->include_urls, + $form->exclude_urls, + $form->active, + $form->place_id + ); + $this->repository->save($banner); + return $banner; + } + + public function edit($id, BannerForm $form): void + { + $banner = $this->repository->get($id); + + if ($form->image) { + $filename = $form->image->baseName . '_' . (new Security())->generateRandomString(5) . '.' . $form->image->extension; + $path = \Yii::getAlias(Banner::FILE_ORIGINAL_PATH); + $form->image->saveAs($path . '/' . $filename); + $form->image = $filename; + } + else { + $form->image = $banner->image; + } + + $banner->edit( + $form->title, + $form->image, + $form->url, + $form->target, + $form->start_at, + $form->end_at, + $form->include_urls, + $form->exclude_urls, + $form->active, + $form->place_id + ); + $this->repository->save($banner); + } + + public function remove($id): void + { + $banner = $this->repository->get($id); + $this->repository->remove($banner); + } +} diff --git a/common/modules/banners/services/BannerPlaceManageService.php b/common/modules/banners/services/BannerPlaceManageService.php new file mode 100644 index 0000000..c205d66 --- /dev/null +++ b/common/modules/banners/services/BannerPlaceManageService.php @@ -0,0 +1,47 @@ +repository = $repository; + } + + public function create(BannerPlaceForm $form): BannerPlace + { + $place = BannerPlace::create( + $form->title, + $form->width, + $form->height, + $form->active + ); + $this->repository->save($place); + return $place; + } + + public function edit($id, BannerPlaceForm $form): void + { + $place = $this->repository->get($id); + $place->edit( + $form->title, + $form->width, + $form->height, + $form->active + ); + $this->repository->save($place); + } + + public function remove($id): void + { + $place = $this->repository->get($id); + $this->repository->remove($place); + } +} diff --git a/common/modules/banners/views/manage/banner/_form.php b/common/modules/banners/views/manage/banner/_form.php new file mode 100644 index 0000000..e1e11d0 --- /dev/null +++ b/common/modules/banners/views/manage/banner/_form.php @@ -0,0 +1,131 @@ +\'); + label.addClass("help").popover({ + html: true, + trigger: "hover", + placement: "bottom", + content: $hint.html() + }); + $(this).hide(); +}); +'; +$this->registerJs($js2); +?> + +
+ + + +
+
+ +
+
+ +
+
+ field($model, 'place_id')->dropDownList(ArrayHelper::map(BannerPlace::find()->all(), 'id', 'title')) ?> +
+
+ field($model, 'title')->textInput(['maxlength' => true]) ?> +
+
+ +
+
+ field($model, 'url')->textInput(['maxlength' => true]) ?> +
+
+ field($model, 'target')->dropDownList(BannerHelper::targetList()) ?> +
+
+ +
+
+ field($model, 'image')->widget(FileInput::class, [ + 'options' => [ + 'accept' => 'image/*', + ], + 'pluginOptions' => [ + 'showUpload' => false, + 'showPreview' => false, + ], + ]) ?> +
+
+ +
+
+ field($model, 'start_at')->widget(DateTimePicker::class, [ + 'options' => [], + 'removeButton' => false, + 'pluginOptions' => [ + 'autoclose' => true, + 'format' => 'dd.mm.yyyy hh:ii:ss', + ] + ]); ?> +
+
+ field($model, 'end_at')->widget(DateTimePicker::class, [ + 'options' => [], + 'removeButton' => false, + 'pluginOptions' => [ + 'autoclose' => true, + //'format' => 'dd.MM.yyyy hh:i', + 'format' => 'dd.mm.yyyy hh:ii:ss', + ] + ]); ?> +
+
+ + + +
+
+ +
+ 'btn btn-success']) ?> +
+ +
+ +
+
+
+
+ + field($model, 'active')->radioList(BannerHelper::statusList()) ?> + +
+
+
+ +
+ + + +
diff --git a/common/modules/banners/views/manage/banner/create.php b/common/modules/banners/views/manage/banner/create.php new file mode 100644 index 0000000..5d7eb6a --- /dev/null +++ b/common/modules/banners/views/manage/banner/create.php @@ -0,0 +1,16 @@ +title = Yii::t('banners', 'Create Banner'); +$this->params['breadcrumbs'][] = ['label' => Yii::t('banners', 'Banners'), 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +?> + diff --git a/common/modules/banners/views/manage/banner/index.php b/common/modules/banners/views/manage/banner/index.php new file mode 100644 index 0000000..caa1d10 --- /dev/null +++ b/common/modules/banners/views/manage/banner/index.php @@ -0,0 +1,86 @@ +title = Yii::t('banners', 'Banners'); +$this->params['breadcrumbs'][] = $this->title; +?> +
+ +

+ 'btn btn-success']) ?> +

+ +
+
+ $dataProvider, + 'filterModel' => $searchModel, + 'columns' => [ + [ + 'attribute' => 'title', + 'value' => function (Banner $model) { + return Html::a(Html::encode($model->title), ['view', 'id' => $model->id]); + }, + 'format' => 'raw', + ], + 'url:url', + [ + 'attribute' => 'start_at', + 'value' => function(Banner $banner) { + return date('d.m.Y H:i', $banner->start_at); + }, + 'options' => ['style' => 'width: 180px;'], + ], + [ + 'attribute' => 'end_at', + 'value' => function(Banner $banner) { + return date('d.m.Y H:i', $banner->end_at); + }, + 'options' => ['style' => 'width: 180px;'], + ], + [ + 'attribute' => 'place_id', + 'filter' => ArrayHelper::map(BannerPlace::find()->all(), 'id', 'title'), + 'value' => 'place.title', + 'label' => Yii::t('banners', 'Place'), + ], + [ + 'attribute' => 'target', + 'filter' => BannerHelper::targetList(), + 'value' => function(Banner $banner) { + return BannerHelper::targetName($banner->target); + }, + 'options' => ['style' => 'width: 150px;'], + 'contentOptions' => ['class' => 'text-center'], + ], + [ + 'attribute' => 'active', + 'filter' => BannerHelper::statusList(), + 'format' => 'raw', + 'value' => function(Banner $banner) { + return BannerHelper::statusLabel($banner->active); + }, + 'options' => ['style' => 'width: 150px;'], + 'contentOptions' => ['class' => 'text-center'], + ], + [ + 'class' => ActionColumn::class, + 'options' => ['style' => 'width: 100px;'], + 'contentOptions' => ['class' => 'text-center'], + ], + ], + ]); ?> +
+
+
diff --git a/common/modules/banners/views/manage/banner/update.php b/common/modules/banners/views/manage/banner/update.php new file mode 100644 index 0000000..cdf268e --- /dev/null +++ b/common/modules/banners/views/manage/banner/update.php @@ -0,0 +1,18 @@ +title = Yii::t('banners', 'Update Banner: {name}', ['name' => $banner->title]); +$this->params['breadcrumbs'][] = ['label' => Yii::t('banners', 'Banners'), 'url' => ['index']]; +$this->params['breadcrumbs'][] = ['label' => $banner->title, 'url' => ['view', 'id' => $banner->id]]; +$this->params['breadcrumbs'][] = Yii::t('buttons', 'Editing'); +?> + diff --git a/common/modules/banners/views/manage/banner/view.php b/common/modules/banners/views/manage/banner/view.php new file mode 100644 index 0000000..058d91d --- /dev/null +++ b/common/modules/banners/views/manage/banner/view.php @@ -0,0 +1,95 @@ +title = $banner->title; +$this->params['breadcrumbs'][] = ['label' => Yii::t('banners', 'Banners'), 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +?> + diff --git a/common/modules/banners/views/manage/place/_form.php b/common/modules/banners/views/manage/place/_form.php new file mode 100644 index 0000000..9b962e3 --- /dev/null +++ b/common/modules/banners/views/manage/place/_form.php @@ -0,0 +1,74 @@ +\'); + label.addClass("help").popover({ + html: true, + trigger: "hover", + placement: "bottom", + content: $hint.html() + }); + $(this).hide(); +}); +'; +$this->registerJs($js2); +?> + +
+ + + +
+
+ +
+
+ field($model, 'title')->textInput(['maxlength' => true]) ?> + +
+
+ field($model, 'width')->textInput(['maxlength' => true]) ?> +
+
+ field($model, 'height')->textInput(['maxlength' => true]) ?> +
+
+ + +
+
+ + +
+ 'btn btn-success']) ?> +
+ +
+ +
+
+
+
+ + field($model, 'active')->radioList(BannerHelper::statusList()) ?> + +
+
+
+ +
+ + + +
diff --git a/common/modules/banners/views/manage/place/create.php b/common/modules/banners/views/manage/place/create.php new file mode 100644 index 0000000..a657459 --- /dev/null +++ b/common/modules/banners/views/manage/place/create.php @@ -0,0 +1,16 @@ +title = Yii::t('banners', 'Create Place'); +$this->params['breadcrumbs'][] = ['label' => Yii::t('banners', 'Places'), 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +?> +
+ + render('_form', [ + 'model' => $model, + ]) ?> + +
diff --git a/common/modules/banners/views/manage/place/index.php b/common/modules/banners/views/manage/place/index.php new file mode 100644 index 0000000..97624fd --- /dev/null +++ b/common/modules/banners/views/manage/place/index.php @@ -0,0 +1,56 @@ +title = Yii::t('banners', 'Places'); +$this->params['breadcrumbs'][] = $this->title; +?> +
+ +

+ 'btn btn-success']) ?> +

+ +
+
+ $dataProvider, + 'filterModel' => $searchModel, + 'columns' => [ + [ + 'attribute' => 'title', + 'value' => function (BannerPlace $model) { + return Html::a(Html::encode($model->title), ['view', 'id' => $model->id]); + }, + 'format' => 'raw', + ], + 'width', + 'height', + [ + 'attribute' => 'active', + 'filter' => BannerHelper::statusList(), + 'format' => 'raw', + 'value' => function(BannerPlace $place) { + return BannerHelper::statusLabel($place->active); + }, + 'options' => ['style' => 'width: 150px;'], + 'contentOptions' => ['class' => 'text-center'], + ], + [ + 'class' => ActionColumn::class, + 'options' => ['style' => 'width: 100px;'], + 'contentOptions' => ['class' => 'text-center'], + ], + ], + ]); ?> +
+
+
diff --git a/common/modules/banners/views/manage/place/update.php b/common/modules/banners/views/manage/place/update.php new file mode 100644 index 0000000..bd85fc6 --- /dev/null +++ b/common/modules/banners/views/manage/place/update.php @@ -0,0 +1,18 @@ +title = Yii::t('banners', 'Update Place: {name}', ['name' => $place->title]); +$this->params['breadcrumbs'][] = ['label' => Yii::t('banners', 'Places'), 'url' => ['index']]; +$this->params['breadcrumbs'][] = ['label' => $place->title, 'url' => ['view', 'id' => $place->id]]; +$this->params['breadcrumbs'][] = Yii::t('buttons', 'Editing'); +?> +
+ + render('_form', [ + 'model' => $model, + ]) ?> + +
diff --git a/common/modules/banners/views/manage/place/view.php b/common/modules/banners/views/manage/place/view.php new file mode 100644 index 0000000..17efd1c --- /dev/null +++ b/common/modules/banners/views/manage/place/view.php @@ -0,0 +1,76 @@ +title = $place->title; +$this->params['breadcrumbs'][] = ['label' => Yii::t('banners', 'Places'), 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +?> +
+ +

+ 'btn btn-default']) ?> + $place->id], ['class' => 'btn btn-primary']) ?> + $place->id], [ + 'class' => 'btn btn-danger', + 'data' => [ + 'confirm' => Yii::t('buttons', 'Are you sure you want to delete this item?'), + 'method' => 'post', + ], + ]) ?> +

+ +
+
+ +
+
+ $place, + 'attributes' => [ + 'id', + 'title', + 'width', + 'height', + [ + 'attribute' => 'active', + 'format' => 'raw', + 'value' => function(BannerPlace $place) { + return BannerHelper::statusLabel($place->active); + } + ], + ], + ]) ?> +
+
+
+ +
+
+
+
+ + ".$place->id."]) ?>"); + ?> +

+
+ + ".$place->id."]) ?]"); + ?> +

+
+
+
+
+
+
diff --git a/common/modules/banners/widgets/BannerWidget.php b/common/modules/banners/widgets/BannerWidget.php new file mode 100644 index 0000000..2f1ca5d --- /dev/null +++ b/common/modules/banners/widgets/BannerWidget.php @@ -0,0 +1,42 @@ +id); + if (!$place) { + return 'Place is not found'; + } + + $banners = Banner::find() + ->active() + ->showTime() + //->excludeFree() + ->andWhere(['place_id' => $place->id]) + ->all(); + + if (!$banners || $place->isDraft()) { + return ''; + } + + /* @var $banner Banner */ + $banner = $banners[array_rand($banners)]; + + return $this->render('banner', [ + 'banner' => $banner, + ]); + } +} \ No newline at end of file diff --git a/common/modules/banners/widgets/views/banner.php b/common/modules/banners/widgets/views/banner.php new file mode 100644 index 0000000..5104645 --- /dev/null +++ b/common/modules/banners/widgets/views/banner.php @@ -0,0 +1,18 @@ + + +image), $banner->url, [ + 'target' => $banner->target +]) ?> diff --git a/core/entities/post/Post.php b/core/entities/post/Post.php index 55b352e..a1e5bf4 100644 --- a/core/entities/post/Post.php +++ b/core/entities/post/Post.php @@ -279,7 +279,7 @@ class Post extends ActiveRecord */ public function getPostComments() { - return $this->hasMany(PostComment::className(), ['post_id' => 'id']); + return $this->hasMany(PostComment::class, ['post_id' => 'id']); } /** @@ -287,7 +287,7 @@ class Post extends ActiveRecord */ public function getPostTagAssignments() { - return $this->hasMany(PostTagAssignment::className(), ['post_id' => 'id']); + return $this->hasMany(PostTagAssignment::class, ['post_id' => 'id']); } /** diff --git a/frontend/web/themes/start/layouts/home.php b/frontend/web/themes/start/layouts/home.php index f374d48..eefa03c 100644 --- a/frontend/web/themes/start/layouts/home.php +++ b/frontend/web/themes/start/layouts/home.php @@ -43,7 +43,7 @@
- 1]) ?> + 1]) ?>

Welcome to Modern Business