diff --git a/Module.php b/Module.php new file mode 100755 index 0000000..6b926aa --- /dev/null +++ b/Module.php @@ -0,0 +1,88 @@ +db + */ + public $db = NULL; + + /** + * Key, used to encrypt and decrypt comment service data. + * @var string Encryption key + */ + public static $encryptionKey = 'artbox-comment'; + + /** + * Whether to enable comment rating or not. + * @var bool + */ + public static $enableRating = true; + + /** + * Initializes the module. + * This method is called after the module is created and initialized with property values + * given in configuration. The default implementation will initialize + * [[controllerNamespace]] if it is not set. If you override this method, please make sure + * you call the parent implementation. + */ + public function init() + { + if($this->userIdentityClass === NULL) { + $this->userIdentityClass = Yii::$app->getUser()->identityClass; + } + if($this->commentModelClass === NULL) { + $this->commentModelClass = CommentModel::className(); + } + if(self::$enableRating && $this->ratingModelClass === NULL) { + $this->ratingModelClass = RatingModel::className(); + } + if(\Yii::$app instanceof Application) { + $this->controllerNamespace = 'artweb\artbox\comment\commands'; + } + if($this->db === NULL) { + $this->db = \Yii::$app->db; + } + Yii::setAlias('@artbox-comment', __DIR__); + parent::init(); + } + + } diff --git a/assets/CommentAsset.php b/assets/CommentAsset.php new file mode 100755 index 0000000..dff12ca --- /dev/null +++ b/assets/CommentAsset.php @@ -0,0 +1,42 @@ + 'afterValidate', + ]; + } + + /** + * @param Event $event + */ + public function afterValidate($event) + { + /** + * @var CommentModel $owner + */ + $owner = $this->owner; + if(!empty( $owner->artbox_comment_pid )) { + /** + * @var CommentModel $parent + */ + $parent = CommentModel::find() + ->where([ 'artbox_comment_id' => $owner->artbox_comment_pid ]) + ->one(); + if(!empty( $parent->artbox_comment_pid )) { + $owner->related_id = $owner->artbox_comment_pid; + $owner->artbox_comment_pid = $parent->artbox_comment_pid; + } + } + } + } \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..b8aa6ad --- /dev/null +++ b/composer.json @@ -0,0 +1,15 @@ +{ + "name": "artweb/artbox-comment", + "description": "Yii2 light-weight CMS", + "license": "BSD-3-Clause", + "require": { + "php": ">=7.0", + "yiisoft/yii2": "*", + "developeruz/yii2-db-rbac": "*" + }, + "autoload": { + "psr-4": { + "artweb\\artbox\\comment\\": "" + } + } +} \ No newline at end of file diff --git a/controllers/DefaultController.php b/controllers/DefaultController.php new file mode 100755 index 0000000..3ebecda --- /dev/null +++ b/controllers/DefaultController.php @@ -0,0 +1,142 @@ + [ + 'class' => VerbFilter::className(), + 'actions' => [ + 'create' => [ 'post' ], + 'delete' => [ + 'post', + 'delete', + ], + ], + ], + 'access' => [ + 'class' => AccessControl::className(), + 'only' => [ 'delete' ], + 'rules' => [ + [ + 'allow' => true, + 'roles' => [ '@' ], + ], + ], + ], + ]; + } + + /** + * Create comment. + * + * @param string $entity + * + * @return array|null|Response + */ + public function actionCreate(string $entity) + { + \Yii::$app->response->format = Response::FORMAT_JSON; + /* @var $module Module */ + $module = \Yii::$app->getModule(Module::$name); + $entity_data_json = \Yii::$app->getSecurity() + ->decryptByKey($entity, $module::$encryptionKey); + if($entity_data_json != false) { + $entity_data = Json::decode($entity_data_json); + $commentModelClass = $module->commentModelClass; + /** + * @var CommentModel $model + */ + $model = new $commentModelClass([ + 'scenario' => \Yii::$app->user->getIsGuest() ? $commentModelClass::SCENARIO_GUEST : $commentModelClass::SCENARIO_USER, + ]); + if($model->load(\Yii::$app->request->post())) { + $model->setAttributes($entity_data); + if($model->save()) { + if(empty( $model->artbox_comment_pid ) && $module::$enableRating) { + $ratingModelClass = $module->ratingModelClass; + /** + * @var RatingModel $rating + */ + $rating = new $ratingModelClass([ + 'model' => $model::className(), + 'model_id' => $model->primaryKey, + ]); + if($rating->load(\Yii::$app->request->post())) { + $rating->save(); + } + } + \Yii::$app->session->setFlash('artbox_comment_success', \Yii::t('artbox-comment', 'Comment posted')); + return [ 'status' => 'success' ]; + } else { + return [ + 'status' => 'error', + 'errors' => $model->getFirstErrors(), + ]; + } + } + } + return [ + 'status' => 'error', + 'message' => \Yii::t('artbox-comment', 'Oops, something went wrong. Please try again later.'), + ]; + } + + /** + * Delete comment. + * + * @param integer $id Comment ID + * + * @return string Comment text + */ + public function actionDelete($id) + { + \Yii::$app->response->format = Response::FORMAT_JSON; + $model = $this->findModel($id); + if($model->deleteComment()) { + return [ + 'status' => 'success', + 'message' => \Yii::t('yii2mod.comments', 'Comment has been deleted.'), + ]; + } else { + \Yii::$app->response->setStatusCode(500); + return \Yii::t('yii2mod.comments', 'Comment has not been deleted. Please try again!'); + } + } + + /** + * Find model by ID. + * + * @param integer|array $id Comment ID + * + * @return CommentModel + * @throws NotFoundHttpException + */ + protected function findModel(int $id): CommentModel + { + /** @var CommentModel $model */ + $commentModelClass = \Yii::$app->getModule(Module::$name)->commentModelClass; + if(( $model = $commentModelClass::findOne($id) ) !== NULL) { + return $model; + } else { + throw new NotFoundHttpException(\Yii::t('yii2mod.comments', 'The requested page does not exist.')); + } + } + } \ No newline at end of file diff --git a/controllers/ManageController.php b/controllers/ManageController.php new file mode 100755 index 0000000..a49dad1 --- /dev/null +++ b/controllers/ManageController.php @@ -0,0 +1,112 @@ + [ + 'class' => VerbFilter::className(), + 'actions' => [ + 'index' => [ 'get' ], + 'update' => [ + 'get', + 'post', + ], + 'delete' => [ 'post' ], + ], + ], + ]; + } + + /** + * Lists all comments. + * @return mixed + */ + public function actionIndex() + { + $searchModel = new CommentModelSearch(); + $dataProvider = $searchModel->search(Yii::$app->request->queryParams); + $commentModel = Yii::$app->getModule(Module::$name)->commentModelClass; + + return $this->render('index', [ + 'dataProvider' => $dataProvider, + 'searchModel' => $searchModel, + 'commentModel' => $commentModel, + ]); + } + + /** + * Updates an existing CommentModel model. + * If update is successful, the browser will be redirected to the 'view' page. + * + * @param integer $id + * + * @return mixed + */ + public function actionUpdate($id) + { + $model = $this->findModel($id); + + if($model->load(Yii::$app->request->post()) && $model->save()) { + Yii::$app->session->setFlash('artbox_comment_success', /*Yii::t('yii2mod.comments', 'Comment has been saved.')*/ + 'Comment has been saved.'); + return $this->redirect([ 'index' ]); + } + + return $this->render('update', [ + 'model' => $model, + ]); + + } + + /** + * Deletes an existing CommentModel model. + * If deletion is successful, the browser will be redirected to the 'index' page. + * + * @param integer $id + * + * @return mixed + */ + public function actionDelete($id) + { + $this->findModel($id) + ->delete(); + Yii::$app->session->setFlash('artbox_comment_success', Yii::t('artbox-comment', 'Comment has been deleted.')); + return $this->redirect([ 'index' ]); + } + + /** + * Finds the CommentModel model based on its primary key value. + * If the model is not found, a 404 HTTP exception will be thrown. + * + * @param integer $id + * + * @return CommentModel the loaded model + * @throws NotFoundHttpException if the model cannot be found + */ + protected function findModel($id) + { + if(( $model = CommentModel::findOne($id) ) !== NULL) { + return $model; + } else { + throw new NotFoundHttpException(/*Yii::t('yii2mod.comments', 'The requested page does not exist.')*/ + 'The requested page does not exist.'); + } + } + } \ No newline at end of file diff --git a/messages/config.php b/messages/config.php new file mode 100755 index 0000000..610e52d --- /dev/null +++ b/messages/config.php @@ -0,0 +1,61 @@ + __DIR__ . DIRECTORY_SEPARATOR . '..', + // array, required, list of language codes that the extracted messages + // should be translated to. For example, ['zh-CN', 'de']. + 'languages' => [ + 'en', + 'ru', + ], + // string, the name of the function for translating messages. + // Defaults to 'Yii::t'. This is used as a mark to find the messages to be + // translated. You may use a string for single function name or an array for + // multiple function names. + 'translator' => 'Yii::t', + // boolean, whether to sort messages by keys when merging new messages + // with the existing ones. Defaults to false, which means the new (untranslated) + // messages will be separated from the old (translated) ones. + 'sort' => true, + // boolean, whether to remove messages that no longer appear in the source code. + // Defaults to false, which means each of these messages will be enclosed with a pair of '@@' marks. + 'removeUnused' => false, + // array, list of patterns that specify which files (not directories) should be processed. + // If empty or not set, all files will be processed. + // Please refer to "except" for details about the patterns. + 'only' => [ '*.php' ], + // array, list of patterns that specify which files/directories should NOT be processed. + // If empty or not set, all files/directories will be processed. + // A path matches a pattern if it contains the pattern string at its end. For example, + // '/a/b' will match all files and directories ending with '/a/b'; + // the '*.svn' will match all files and directories whose name ends with '.svn'. + // and the '.svn' will match all files and directories named exactly '.svn'. + // Note, the '/' characters in a pattern matches both '/' and '\'. + // See helpers/FileHelper::findFiles() description for more details on pattern matching rules. + // If a file/directory matches both a pattern in "only" and "except", it will NOT be processed. + 'except' => [ + '.svn', + '.git', + '.gitignore', + '.gitkeep', + '.hgignore', + '.hgkeep', + '/messages', + '/tests', + '/runtime', + '/vendor', + ], + + // 'php' output format is for saving messages to php files. + 'format' => 'php', + // Root directory containing message translations. + 'messagePath' => __DIR__, + // boolean, whether the message file should be overwritten with the merged messages + 'overwrite' => true, + + // Message categories to ignore + 'ignoreCategories' => [ + 'yii', + ], + ]; diff --git a/messages/en/artbox-comment.php b/messages/en/artbox-comment.php new file mode 100755 index 0000000..b358da5 --- /dev/null +++ b/messages/en/artbox-comment.php @@ -0,0 +1,56 @@ + 'ID', + 'Text' => 'Content', + 'Entity' => 'Entity', + 'Entity ID' => 'Entity ID', + 'Parent ID' => 'Parent ID', + 'Status' => 'Status', + 'Level' => 'Level', + 'User' => 'User', + 'Username' => 'User name', + 'Date add' => 'Date add', + 'Date update' => 'Date update', + 'Date delete' => 'Date delete', + 'Comment parent' => 'Parent comment', + 'Comment related' => 'Related comment', + 'Info' => 'Additional info', + 'Created by' => 'Created by', + 'Updated by' => 'Related to', + 'Related to' => 'Related to', + 'Created date' => 'Created date', + 'Updated date' => 'Updated date', + 'Update' => 'Update', + 'Delete' => 'Delete', + 'Reply' => 'Reply', + 'Comments ({0})' => 'Comments ({0})', + 'Comment cannot be blank.' => 'Comment cannot be blank.', + 'Comment has not been deleted. Please try again!' => 'Comment has not been deleted. Please try again!', + 'Add a comment...' => 'Add a comment...', + 'Comment' => 'Comment', + 'Oops, something went wrong. Please try again later.' => 'Oops, something went wrong. Please try again later.', + 'The requested page does not exist.' => 'The requested page does not exist.', + 'Comment has been deleted.' => 'Comment has been deleted.', + 'Comment has been saved.' => 'Comment has been saved.', + 'Click here to cancel reply.' => 'Click here to cancel reply.', + 'Comments Management' => 'Comments Management', + 'Select Status' => 'Select Status', + 'Select Author' => 'Select Author', + 'Update Comment: {0}' => 'Update Comment: {0}', + 'Active' => 'Active', + 'Deleted' => 'Deleted', + 'Comment posted' => 'Comment successfully added and will appear after moderator check.', + ]; diff --git a/messages/ru/artbox-comment.php b/messages/ru/artbox-comment.php new file mode 100755 index 0000000..81b0d22 --- /dev/null +++ b/messages/ru/artbox-comment.php @@ -0,0 +1,59 @@ + 'Идентификатор', + 'Text' => 'Комментарий', + 'Entity' => 'Модель', + 'Entity ID' => 'Идентификатор модели', + 'Parent ID' => 'Родитель', + 'Status' => 'Статус', + 'Level' => 'Уровень', + 'User' => 'Пользователь', + 'Username' => 'Имя', + 'Date add' => 'Дата добавления', + 'Date update' => 'Дата обновления', + 'Date delete' => 'Дата удаления', + 'Comment parent' => 'Родитель', + 'Comment related' => 'Связзанный комментарий', + 'Info' => 'Дополнительная информация', + 'Created by' => 'Создан', + 'Updated by' => 'Обновлен', + 'Related to' => 'Относится к', + 'Created date' => 'Дата создания', + 'Updated date' => 'Дата обновления', + 'Update' => 'Обновить', + 'Delete' => 'Удалить', + 'Reply' => 'Ответить', + 'Comments ({0})' => 'Комментарии ({0})', + 'Comment cannot be blank.' => 'Комментарий не может быть пустым.', + 'Comment has not been deleted. Please try again!' => 'Не удалось удалить комментарий. Попробуйте пожалуйста еще раз!', + 'Add a comment...' => 'Добавить комментарий...', + 'Comment' => 'Опубликовать комментарий', + 'Oops, something went wrong. Please try again later.' => 'Не удалось добавить комментарий. Попробуйте пожалуйста еще раз.', + 'The requested page does not exist.' => 'Ошибка 404 - страница не найдена!', + 'Comment has been deleted.' => 'Комментарий был удалён.', + 'Comment has been saved.' => 'Комментарий был сохранён.', + 'Click here to cancel reply.' => 'Нажмите здесь, чтобы отменить ответ.', + 'Comments Management' => 'Управление Комментариями', + 'Select Status' => 'Выберите Статус', + 'Select Author' => 'Выберите Автора', + 'Update Comment: {0}' => 'Обновить комментарий: {0}', + 'Active' => 'Включён', + 'Deleted' => 'Удален', + 'Comment posted' => 'Комментарий успешно добавлен и появится после проверки администрацией.', + 'Submit' => 'Добавить комментарий', + 'Cancel' => 'Отменить', + 'Guest' => 'Гость', + ]; diff --git a/migrations/m160724_162347_artbox_comment.php b/migrations/m160724_162347_artbox_comment.php new file mode 100755 index 0000000..5183e61 --- /dev/null +++ b/migrations/m160724_162347_artbox_comment.php @@ -0,0 +1,112 @@ +createTable( + '{{%artbox_comment}}', + [ + 'artbox_comment_id' => $this->primaryKey(), + 'text' => $this->text() + ->notNull(), + 'user_id' => $this->integer(), + 'username' => $this->string(), + 'email' => $this->string(), + 'created_at' => $this->integer() + ->notNull(), + 'updated_at' => $this->integer() + ->notNull(), + 'deleted_at' => $this->integer(), + 'status' => $this->integer() + ->notNull() + ->defaultValue(1), + 'artbox_comment_pid' => $this->integer(), + 'related_id' => $this->integer(), + 'ip' => $this->string() + ->notNull(), + 'info' => $this->text(), + ] + ); + + $this->addForeignKey( + 'user_id_user', + '{{%artbox_comment}}', + 'user_id', + 'customer', + 'id', + 'CASCADE', + 'CASCADE' + ); + $this->addForeignKey( + 'artbox_comment_pid_artbox_comment', + '{{%artbox_comment}}', + 'artbox_comment_pid', + 'artbox_comment', + 'artbox_comment_id', + 'CASCADE', + 'CASCADE' + ); + $this->addForeignKey( + 'related_id_artbox_comment', + '{{%artbox_comment}}', + 'related_id', + 'artbox_comment', + 'artbox_comment_id', + 'CASCADE', + 'CASCADE' + ); + + $this->createTable( + '{{%artbox_like}}', + [ + 'artbox_like_id' => $this->primaryKey(), + 'artbox_comment_id' => $this->integer() + ->notNull(), + 'user_id' => $this->integer(), + 'created_at' => $this->integer() + ->notNull(), + 'is_like' => $this->integer() + ->notNull() + ->defaultValue(1), + ] + ); + + $this->addForeignKey( + 'artbox_comment_id_artbox_comment', + '{{%artbox_like}}', + 'artbox_comment_id', + 'artbox_comment', + 'artbox_comment_id', + 'CASCADE', + 'CASCADE' + ); + $this->addForeignKey('user_id_user', '{{%artbox_like}}', 'user_id', 'customer', 'id', 'CASCADE', 'CASCADE'); + $this->createIndex( + 'artbox_like_unique', + '{{%artbox_like}}', + [ + 'artbox_comment_id', + 'user_id', + 'is_like', + ], + true + ); + + } + + public function down() + { + $this->dropForeignKey('user_id_user', '{{%artbox_comment}}'); + $this->dropForeignKey('artbox_comment_pid_artbox_comment', '{{%artbox_comment}}'); + $this->dropForeignKey('related_id_artbox_comment', '{{%artbox_comment}}'); + $this->dropForeignKey('artbox_comment_id_artbox_comment', '{{%artbox_like}}'); + $this->dropForeignKey('user_id_user', '{{%artbox_like}}'); + $this->dropIndex('artbox_like_unique', '{{%artbox_like}}'); + $this->dropTable('{{%artbox_comment}}'); + $this->dropTable('{{%artbox_like}}'); + } + } diff --git a/migrations/m160726_092634_add_entity_fields.php b/migrations/m160726_092634_add_entity_fields.php new file mode 100755 index 0000000..43ce77e --- /dev/null +++ b/migrations/m160726_092634_add_entity_fields.php @@ -0,0 +1,23 @@ +addColumn('{{%artbox_comment}}', 'entity', $this->string() + ->notNull() + ->defaultValue('')); + $this->addColumn('{{%artbox_comment}}', 'entity_id', $this->integer() + ->notNull() + ->defaultValue(1)); + } + + public function down() + { + $this->dropColumn('{{%artbox_comment}}', 'entity'); + $this->dropColumn('{{%artbox_comment}}', 'entity_id'); + } + } diff --git a/migrations/m160726_211227_create_artbox_comment_rating.php b/migrations/m160726_211227_create_artbox_comment_rating.php new file mode 100755 index 0000000..bb1048f --- /dev/null +++ b/migrations/m160726_211227_create_artbox_comment_rating.php @@ -0,0 +1,42 @@ +createTable( + '{{%artbox_comment_rating}}', + [ + 'artbox_comment_rating_id' => $this->primaryKey(), + 'created_at' => $this->integer() + ->notNull(), + 'updated_at' => $this->integer() + ->notNull(), + 'user_id' => $this->integer(), + 'value' => $this->float(), + 'model' => $this->string() + ->notNull(), + 'model_id' => $this->integer() + ->notNull(), + ] + ); + $this->addForeignKey( + 'user_id_user', + '{{%artbox_comment_rating}}', + 'user_id', + 'customer', + 'id', + 'CASCADE', + 'CASCADE' + ); + } + + public function down() + { + $this->dropForeignKey('user_id_user', '{{%artbox_comment_rating}}'); + $this->dropTable('{{%artbox_comment_rating}}'); + } + } diff --git a/models/CommentModel.php b/models/CommentModel.php new file mode 100755 index 0000000..e93533f --- /dev/null +++ b/models/CommentModel.php @@ -0,0 +1,274 @@ + self::SCENARIO_GUEST, + ], + [ + [ + 'text', + 'entity', + 'username', + ], + 'string', + ], + [ + [ + 'email', + ], + 'email', + ], + [ + [ + 'entity_id', + 'artbox_comment_pid', + ], + 'integer', + ], + [ + [ 'status' ], + 'default', + 'value' => 0, + ], + [ + [ 'artbox_comment_pid' ], + 'exist', + 'targetAttribute' => 'artbox_comment_id', + 'skipOnError' => true, + ], + ]; + } + + public function behaviors() + { + return [ + [ + 'class' => TimestampBehavior::className(), + ], + [ + 'class' => BlameableBehavior::className(), + 'createdByAttribute' => 'user_id', + 'updatedByAttribute' => false, + ], + [ + 'class' => AttributeBehavior::className(), + 'attributes' => [ + ActiveRecord::EVENT_BEFORE_INSERT => 'ip', + ], + 'value' => function ($event) { + return \Yii::$app->request->userIP; + }, + ], + [ + 'class' => ParentBehavior::className(), + ], + [ + 'class' => RatingBehavior::className(), + ], + /* Notification: uncomment to enable notifications. + [ + 'class' => NotifyBehavior::className(), + ], + */ + ]; + } + + public function attributeLabels() + { + return [ + 'artbox_comment_id' => \Yii::t('artbox-comment', 'ID'), + 'text' => \Yii::t('artbox-comment', 'Text'), + 'user_id' => \Yii::t('artbox-comment', 'User'), + 'username' => \Yii::t('artbox-comment', 'Username'), + 'email' => 'Email', + 'date_add' => \Yii::t('artbox-comment', 'Date add'), + 'updated_at' => \Yii::t('artbox-comment', 'Date update'), + 'deleted_at' => \Yii::t('artbox-comment', 'Date delete'), + 'status' => \Yii::t('artbox-comment', 'Status'), + 'artbox_comment_pid' => \Yii::t('artbox-comment', 'Comment parent'), + 'related_id' => \Yii::t('artbox-comment', 'Comment related'), + 'ip' => 'IP', + 'entity' => \Yii::t('artbox-comment', 'Entity'), + 'info' => \Yii::t('artbox-comment', 'Info'), + 'entity_id' => \Yii::t('artbox-comment', 'Entity ID'), + ]; + } + + public function setEntity(string $entity) + { + $this->entity = $entity; + } + + public function getEntity(): string + { + return $this->entity; + } + + public static function getTree(string $entity, int $entityId): ActiveDataProvider + { + return new ActiveDataProvider( + [ + 'query' => self::find() + ->with( + [ + 'children', + 'user', + 'children.user', + ] + ) + ->where( + [ + 'entity' => $entity, + 'entity_id' => $entityId, + 'status' => 1, + 'artbox_comment_pid' => null, + ] + ), + 'pagination' => [ + 'pageSize' => 20, + ], + 'sort' => [ + 'defaultOrder' => [ + 'created_at' => SORT_DESC, + ], + ], + ] + ); + } + + public function deleteComment(): bool + { + if (\Yii::$app->user->id != null && \Yii::$app->user->id == $this->user_id) { + if ($this->delete()) { + return true; + } + } + return false; + } + + public function setEntityId(int $entityId) + { + $this->entityId = $entityId; + } + + public function getEntityId(): int + { + return $this->entityId; + } + + public function getChildren() + { + return $this->hasMany(self::className(), [ 'artbox_comment_pid' => 'artbox_comment_id' ]) + ->andFilterWhere([ 'status' => self::STATUS_ACTIVE ]) + ->inverseOf('parent'); + } + + public function getParent() + { + return $this->hasOne(self::className(), [ 'artbox_comment_id' => 'artbox_comment_pid' ]) + ->inverseOf('children'); + } + + public function getUser() + { + $module = \Yii::$app->getModule('artbox-comment'); + return $this->hasOne($module->userIdentityClass, [ 'id' => 'user_id' ]); + } + + public function getRating() + { + return $this->hasOne(RatingModel::className(), [ 'model_id' => 'artbox_comment_id' ]) + ->andWhere( + [ + 'or', + [ 'artbox_comment_rating.model' => null ], + [ 'artbox_comment_rating.model' => self::className() ], + ] + ); + } + } \ No newline at end of file diff --git a/models/CommentModelSearch.php b/models/CommentModelSearch.php new file mode 100755 index 0000000..ece993b --- /dev/null +++ b/models/CommentModelSearch.php @@ -0,0 +1,227 @@ + 0, + ], + [ + [ + 'ratingValue', + ], + 'number', + 'min' => 1, + 'max' => 5, + ], + [ + [ + 'user_id', + 'text', + 'username', + 'email', + 'ip', + 'entity', + 'info', + ], + 'safe', + ], + ]; + } + + public function attributeLabels() + { + return array_merge( + parent::attributeLabels(), + [ + 'ratingValue' => 'Рейтинг', + 'childrenCount' => 'Количество ответов', + ] + ); + } + + /** + * @inheritdoc + */ + public function scenarios() + { + // bypass scenarios() implementation in the parent class + return Model::scenarios(); + } + + /** + * Creates data provider instance with search query applied + * + * @param array $params + * + * @return ActiveDataProvider + */ + public function search($params) + { + $query = CommentModel::find() + ->joinWith( + [ + 'rating', + 'user', + ] + ); + + // add conditions that should always apply here + + $dataProvider = new ActiveDataProvider( + [ + 'query' => $query, + 'sort' => [ + 'attributes' => [ + 'ratingValue' => [ + 'asc' => [ 'artbox_comment_rating.value' => SORT_ASC ], + 'desc' => [ 'artbox_comment_rating.value' => SORT_DESC ], + ], + 'artbox_comment_id', + 'date_add', + 'text', + 'user_id', + 'status', + 'entity', + 'entity_id', + ], + 'defaultOrder' => [ + 'created_at' => SORT_DESC, + ], + ], + ] + ); + + $this->load($params); + + if (!$this->validate()) { + // uncomment the following line if you do not want to return any records when validation fails + // $query->where('0=1'); + return $dataProvider; + } + + // grid filtering conditions + $query->andFilterWhere( + [ + 'artbox_comment_id' => $this->artbox_comment_id, + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, + 'deleted_at' => $this->deleted_at, + 'artbox_comment.status' => $this->status, + 'artbox_comment_pid' => $this->artbox_comment_pid, + 'related_id' => $this->related_id, + 'entity_id' => $this->entity_id, + ] + ); + + $query->andFilterWhere( + [ + 'like', + 'text', + $this->text, + ] + ) + ->andFilterWhere( + [ + 'like', + 'username', + $this->username, + ] + ) + ->andFilterWhere( + [ + 'like', + 'email', + $this->email, + ] + ) + ->andFilterWhere( + [ + 'like', + 'ip', + $this->ip, + ] + ) + ->andFilterWhere( + [ + 'like', + 'entity', + $this->entity, + ] + ) + ->andFilterWhere( + [ + 'like', + 'info', + $this->info, + ] + ) + ->andFilterWhere( + [ + 'artbox_comment_rating.value' => $this->ratingValue, + ] + ); + + if (!empty( $this->user_id )) { + $query->andWhere( + [ + 'or', + [ 'artbox_comment.user_id' => (int) $this->user_id ], + [ + 'like', + 'user.username', + $this->user_id, + ], + [ + 'like', + 'artbox_comment.username', + $this->user_id, + ], + [ + 'like', + 'artbox_comment.email', + $this->user_id, + ], + ] + ); + } + + return $dataProvider; + } + } diff --git a/models/LikeModel.php b/models/LikeModel.php new file mode 100755 index 0000000..82534ca --- /dev/null +++ b/models/LikeModel.php @@ -0,0 +1,14 @@ + 0.5, + 'max' => 5, + ], + ]; + } + + public function behaviors() + { + return [ + [ + 'class' => TimestampBehavior::className(), + ], + [ + 'class' => BlameableBehavior::className(), + 'createdByAttribute' => 'user_id', + 'updatedByAttribute' => false, + ], + ]; + } + + /** + * @inheritdoc + */ + public function attributeLabels() + { + return [ + 'rating_id' => Yii::t('app', 'Rating ID'), + 'date_add' => Yii::t('app', 'Date Add'), + 'updated_at' => Yii::t('app', 'Date Update'), + 'user_id' => Yii::t('app', 'User ID'), + 'entity' => Yii::t('app', 'Entity'), + 'value' => Yii::t('app', 'Value'), + ]; + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getUser() + { + return $this->hasOne(User::className(), [ 'id' => 'user_id' ]); + } + + public function getModel() + { + $model = $this->model; + return $this->hasOne($model, [ $model::primaryKey() => 'model_id' ]); + } + } diff --git a/models/interfaces/CommentInterface.php b/models/interfaces/CommentInterface.php new file mode 100755 index 0000000..31d7d1c --- /dev/null +++ b/models/interfaces/CommentInterface.php @@ -0,0 +1,24 @@ +1?(f("min",isNaN(f("min"))?Number(h[0].options[0].value):f("min")),f("max",Number(h[0].options[h[0].length-1].value)),f("step",Number(h[0].options[1].value)-Number(h[0].options[0].value)),b=h.find("option[selected]"),b.length==1&&f("value",b.val())):f("value",h.val())),g=c[0].nodeName=="DIV"?"div":"span",e++,nt='