diff --git a/backend/config/main.php b/backend/config/main.php index dd88716..795e11e 100755 --- a/backend/config/main.php +++ b/backend/config/main.php @@ -32,9 +32,10 @@ return [ 'targetMinPixel' => 200 // Target image minimum pixel size ] ], -// 'artbox-comment' => [ -// 'class' => \common\modules\comment\Controller::className(), -// ], + 'artbox-comments' => [ + 'class' => 'common\modules\comment\controllers\ManageController', + 'viewPath' => '@common/modules/comment/views/manage', + ], ], 'layout' => 'admin', 'controllerNamespace' => 'backend\controllers', @@ -101,7 +102,11 @@ return [ ], 'gridview' => [ 'class' => '\kartik\grid\Module' - ] + ], + 'artbox-comment' => [ + 'class' => 'common\modules\comment\Module', + 'userIdentityClass' => 'common\models\Customer', + ], ], 'components' => [ 'authManager' => [ diff --git a/backend/controllers/CommentController.php b/backend/controllers/CommentController.php old mode 100644 new mode 100755 index 1023d5c..1023d5c --- a/backend/controllers/CommentController.php +++ b/backend/controllers/CommentController.php diff --git a/backend/models/CommentSearch.php b/backend/models/CommentSearch.php old mode 100644 new mode 100755 index cb831de..cb831de --- a/backend/models/CommentSearch.php +++ b/backend/models/CommentSearch.php diff --git a/backend/views/comment/_form.php b/backend/views/comment/_form.php old mode 100644 new mode 100755 index efe6e86..efe6e86 --- a/backend/views/comment/_form.php +++ b/backend/views/comment/_form.php diff --git a/backend/views/comment/_search.php b/backend/views/comment/_search.php old mode 100644 new mode 100755 index a61526e..a61526e --- a/backend/views/comment/_search.php +++ b/backend/views/comment/_search.php diff --git a/backend/views/comment/index.php b/backend/views/comment/index.php old mode 100644 new mode 100755 index 3514c68..3514c68 --- a/backend/views/comment/index.php +++ b/backend/views/comment/index.php diff --git a/backend/views/comment/update.php b/backend/views/comment/update.php old mode 100644 new mode 100755 index 3c96c8f..3c96c8f --- a/backend/views/comment/update.php +++ b/backend/views/comment/update.php diff --git a/backend/views/comment/view.php b/backend/views/comment/view.php old mode 100644 new mode 100755 index 1af38ca..1af38ca --- a/backend/views/comment/view.php +++ b/backend/views/comment/view.php diff --git a/common/config/main.php b/common/config/main.php index 3dded74..f821653 100755 --- a/common/config/main.php +++ b/common/config/main.php @@ -3,9 +3,9 @@ return [ 'language' => 'ru', 'vendorPath' => dirname(dirname(__DIR__)) . '/vendor', 'controllerMap' => [ - 'artbox-comment' => [ - 'class' => \common\modules\comment\Controller::className(), - ], +// 'artbox-comment' => [ +// 'class' => \common\modules\comment\Controller::className(), +// ], ], 'components' => [ 'assetManager' => [ @@ -42,7 +42,11 @@ return [ 'app/error' => 'error.php', ], ], - ], + 'artbox-comment' => [ + 'class' => 'yii\i18n\PhpMessageSource', + 'basePath' => '@common/modules/comment/messages', + ], + ], ], 'artboximage' => [ 'class' => 'common\components\artboximage\ArtboxImage', @@ -159,6 +163,9 @@ return [ 'file' => [ 'class' => 'common\modules\file\Module', ], + 'artbox-comment' => [ + 'class' => 'common\modules\comment\Module', + ], 'relation' => [ 'class' => 'common\modules\relation\Module', 'relations' => [ diff --git a/common/models/ProductToRating.php b/common/models/ProductToRating.php old mode 100644 new mode 100755 index ad5755e..ad5755e --- a/common/models/ProductToRating.php +++ b/common/models/ProductToRating.php diff --git a/common/modules/comment/Controller.php b/common/modules/comment/Controller.php deleted file mode 100755 index 1d7e87b..0000000 --- a/common/modules/comment/Controller.php +++ /dev/null @@ -1,237 +0,0 @@ - [ - 'class' => \yii\filters\VerbFilter::className(), - 'actions' => [ - '*' => [ 'post' ], - ], - ], - ]; - } - - public function actionDelete() - { - \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; - $post = \Yii::$app->request->post('Comment'); - $get = \Yii::$app->request->get(); - if(empty( $post[ 'comment_id' ] ) && !empty( $get[ 'comment_id' ] )) { - $post[ 'comment_id' ] = $get[ 'comment_id' ]; - } - if(!empty( $post[ 'comment_id' ] )) { - if($model = \common\modules\comment\models\Comment::findOne($post[ 'comment_id' ])) { - /** - * @var \common\modules\comment\models\Comment $model - */ - $model->scenario = is_int(\Yii::$app->user->getId()) ? \common\modules\comment\models\Comment::SCENARIO_USER : \common\modules\comment\models\Comment::SCENARIO_GUEST; - if($model->deleteComment()) { - \Yii::$app->response->data = [ 'text' => 'Comment marked as deleted and will be check by administrators' ]; - } else { - \Yii::$app->response->data = [ 'error' => $model->hasErrors('comment_id') ? $model->getFirstError('comment_id') : 'Cannot delete message' ]; - } - } else { - \Yii::$app->response->data = [ 'error' => 'Comment not found' ]; - }; - } else { - \Yii::$app->response->data = [ 'error' => 'Missing comment_id' ]; - } - \Yii::$app->response->send(); - } - - public function actionUpdate() - { - \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; - $post = \Yii::$app->request->post(); - if(!empty( $post[ 'Comment' ][ 'comment_id' ] )) { - if($model = \common\modules\comment\models\Comment::findOne($post[ 'Comment' ][ 'comment_id' ])) { - /** - * @var \common\modules\comment\models\Comment $model - */ - $model->scenario = is_int(\Yii::$app->user->getId()) ? \common\modules\comment\models\Comment::SCENARIO_USER : \common\modules\comment\models\Comment::SCENARIO_GUEST; - $model->load($post); - if(empty( $post[ 'Comment' ][ 'comment_pid' ] )) { - $model->comment_pid = NULL; - } - if($model->updateComment()) { - $model->rating->load($post); - if($model->rating->save()) { - return [ - 'result' => [ - 'text' => 'Comment successfully updated', - 'html' => $this->renderAjax('@common/modules/comment/widgets/views/_review_comment_view', [ 'model' => $model ]), - ], - ]; - } else { - return [ - 'error' => $model->hasErrors() ? $model->getFirstErrors() : 'Cannot update message', - 'form' => $this->renderAjax('@common/modules/comment/widgets/views/form-comment-review', [ - 'model' => $model, - ]), - ]; - } - } else { - return [ - 'error' => $model->hasErrors() ? $model->getFirstErrors() : 'Cannot update message', - 'form' => $this->renderAjax('@common/modules/comment/widgets/views/form-comment-review', [ - 'model' => $model, - ]), - ]; - } - } else { - return [ 'error' => 'Comment not found' ]; - } - } else { - return [ 'error' => 'Missing comment_id' ]; - } - } - - public function actionForm() - { - \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; - $post = \Yii::$app->request->post('Comment'); - if(!empty( $post[ 'comment_id' ] )) { - $model = \common\modules\comment\models\Comment::find() - ->where([ 'comment_id' => $post[ 'comment_id' ] ]) - ->with('parent', 'user') - ->one(); - if($model) { - /** - * @var \common\modules\comment\models\Comment $model - */ - $model->scenario = is_int(\Yii::$app->user->getId()) ? \common\modules\comment\models\Comment::SCENARIO_USER : \common\modules\comment\models\Comment::SCENARIO_GUEST; - if($model->checkUpdate()) { - return [ - 'result' => [ - 'form' => $this->renderAjax('@common/modules/comment/widgets/views/form-comment-review', [ - 'model' => $model, - ]), - ], - ]; - } else { - return [ 'error' => 'You are not able to update this comment' ]; - } - } else { - return [ 'error' => 'Comment not found' ]; - } - } else { - return [ 'error' => 'Missing comment_id' ]; - } - } - - public function actionUpdateAnswer() - { - \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; - $post = \Yii::$app->request->post(); - if(!empty( $post[ 'CommentProjectAnswer' ][ 'comment_id' ] )) { - if($model = \common\modules\comment\models\CommentProjectAnswer::findOne($post[ 'CommentProjectAnswer' ][ 'comment_id' ])) { - /** - * @var \common\modules\comment\models\CommentProjectAnswer $model - */ - $model->scenario = is_int(\Yii::$app->user->getId()) ? \common\modules\comment\models\CommentProjectAnswer::SCENARIO_USER : \common\modules\comment\models\CommentProjectAnswer::SCENARIO_GUEST; - $model->load($post); - if(empty( $post[ 'CommentProjectAnswer' ][ 'comment_pid' ] )) { - $model->comment_pid = NULL; - } - if($model->updateComment()) { - $model->rating->load($post); - if($model->rating->save()) { - return [ - 'result' => [ - 'text' => 'Comment successfully updated', - 'html' => $this->renderAjax('@common/modules/comment/widgets/views/_question_comment_view', [ 'model' => $model ]), - ], - ]; - } else { - return [ - 'error' => $model->hasErrors() ? $model->getFirstErrors() : 'Cannot update message', - 'form' => $this->renderAjax('@common/modules/comment/widgets/views/form-comment-answer', [ - 'model' => $model, - ]), - ]; - } - } else { - return [ - 'error' => $model->hasErrors() ? $model->getFirstErrors() : 'Cannot update message', - 'form' => $this->renderAjax('@common/modules/comment/widgets/views/form-comment-answer', [ - 'model' => $model, - ]), - ]; - } - } else { - return [ 'error' => 'Comment not found' ]; - } - } else { - return [ 'error' => 'Missing comment_id' ]; - } - } - - public function actionFormAnswer() - { - \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; - $post = \Yii::$app->request->post('CommentProjectAnswer'); - if(!empty( $post[ 'comment_id' ] )) { - $model = \common\modules\comment\models\CommentProjectAnswer::find() - ->where([ 'comment_id' => $post[ 'comment_id' ] ]) - ->with('parent', 'user') - ->one(); - if($model) { - /** - * @var \common\modules\comment\models\CommentProjectAnswer $model - */ - $model->scenario = is_int(\Yii::$app->user->getId()) ? \common\modules\comment\models\CommentProjectAnswer::SCENARIO_USER : \common\modules\comment\models\CommentProjectAnswer::SCENARIO_GUEST; - if($model->checkUpdate()) { - return [ - 'result' => [ - 'form' => $this->renderAjax('@common/modules/comment/widgets/views/form-comment-answer', [ - 'model' => $model, - ]), - ], - ]; - } else { - return [ 'error' => 'You are not able to update this comment' ]; - } - } else { - return [ 'error' => 'Comment not found' ]; - } - } else { - return [ 'error' => 'Missing comment_id' ]; - } - } - - public function actionDeleteAnswer() - { - \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; - $post = \Yii::$app->request->post('CommentProjectAnswer'); - $get = \Yii::$app->request->get(); - if(empty( $post[ 'comment_id' ] ) && !empty( $get[ 'comment_id' ] )) { - $post[ 'comment_id' ] = $get[ 'comment_id' ]; - } - if(!empty( $post[ 'comment_id' ] )) { - if($model = \common\modules\comment\models\CommentProjectAnswer::findOne($post[ 'comment_id' ])) { - /** - * @var \common\modules\comment\models\Comment $model - */ - $model->scenario = is_int(\Yii::$app->user->getId()) ? \common\modules\comment\models\CommentProjectAnswer::SCENARIO_USER : \common\modules\comment\models\CommentProjectAnswer::SCENARIO_GUEST; - if($model->deleteComment()) { - \Yii::$app->response->data = [ 'text' => 'Comment marked as deleted and will be check by administrators' ]; - } else { - \Yii::$app->response->data = [ 'error' => $model->hasErrors('comment_id') ? $model->getFirstError('comment_id') : 'Cannot delete message' ]; - } - } else { - \Yii::$app->response->data = [ 'error' => 'Comment not found' ]; - }; - } else { - \Yii::$app->response->data = [ 'error' => 'Missing comment_id' ]; - } - \Yii::$app->response->send(); - } - - } \ No newline at end of file diff --git a/common/modules/comment/Module.php b/common/modules/comment/Module.php index 6a18e72..cb0473c 100755 --- a/common/modules/comment/Module.php +++ b/common/modules/comment/Module.php @@ -1,74 +1,89 @@ - * [ - * 'rules' => [ - * \full\namapaced\ClassName, - * \another\one\ClassName, - * ], - * 'permissions' => [ - * [ - * 'name' => stringName, - * 'description' => descriptionText, - * 'ruleName' => (new \full\namespaced\ClassName())->name (optional) - * ], - * [ - * 'name' => stringName2, - * 'description' => descriptionText2, - * 'ruleName' => (new \another\one\ClassName())->name (optional) - * ], - * ] - * ] - * + * Comment model class, default to common\modules\models\CommentModel + * @var string comment model class + */ + public $commentModelClass = NULL; + + public $ratingModelClass = NULL; + + /** + * This namespace will be used to load controller classes by prepending it to the controller + * class name. + * @var string the namespace that controller classes are in. + */ + public $controllerNamespace = 'common\modules\comment\controllers'; + + /** + * @var \yii\db\Connection DB connection, default to \Yii::$app->db + */ + public $db = NULL; + + /** + * Key, used to encrypt and decrypt comment service data. * - * @var array - * @see \common\modules\comment\commands\RbacController + * @var string Encryption key */ - public $rbac = []; - + public static $encryptionKey = 'artbox-comment'; + /** - * @var \yii\db\Connection Connection to the db + * Whether to enable comment rating or not. + * + * @var bool */ - public $db = null; - + public static $enableRating = true; + /** - * @inheritdoc + * 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() { - parent::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 \yii\console\Application) { $this->controllerNamespace = 'common\modules\comment\commands'; } - if($this->db === null) { + if($this->db === NULL) { $this->db = \Yii::$app->db; - } elseif(!$this->db instanceof \yii\db\Connection) { - throw new \yii\base\InvalidConfigException('Конфиг db обязан наследоваться от'.\yii\db\Connection::className()); } + Yii::setAlias('@artbox-comment', __DIR__); + parent::init(); } - } \ No newline at end of file + + } diff --git a/common/modules/comment/Permissions.php b/common/modules/comment/Permissions.php deleted file mode 100755 index 965f0f4..0000000 --- a/common/modules/comment/Permissions.php +++ /dev/null @@ -1,12 +0,0 @@ - \yii\web\View::POS_HEAD, - ]; - - } \ No newline at end of file + +namespace common\modules\comment\assets; + +use yii\web\AssetBundle; + +/** + * Class CommentAsset + * @package common\modules\comment\assets + */ +class CommentAsset extends AssetBundle +{ + /** + * @inheritdoc + */ + public $sourcePath = '@artbox-comment/resources'; + + /** + * @inheritdoc + */ + public $js = [ + 'artbox_comment.js', + 'jquery.rateit.min.js', + ]; + + /** + * @inheritdoc + */ + public $css = [ + 'artbox_comment.css', + 'rateit.css', + ]; + + /** + * @inheritdoc + */ + public $depends = [ + 'yii\web\JqueryAsset', + 'yii\web\YiiAsset' + ]; +} \ No newline at end of file diff --git a/common/modules/comment/behaviors/ParentBehavior.php b/common/modules/comment/behaviors/ParentBehavior.php new file mode 100644 index 0000000..f93dff8 --- /dev/null +++ b/common/modules/comment/behaviors/ParentBehavior.php @@ -0,0 +1,37 @@ + '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/common/modules/comment/commands/RbacController.php b/common/modules/comment/commands/RbacController.php deleted file mode 100755 index cd9d130..0000000 --- a/common/modules/comment/commands/RbacController.php +++ /dev/null @@ -1,81 +0,0 @@ -controller->module; - if(!$module->useRbac) { - throw new \yii\base\InvalidConfigException('Please set useRbac config to TRUE in your module configs'); - } - $auth = \Yii::$app->getAuthManager(); - if(!$auth instanceof \yii\rbac\ManagerInterface) { - throw new \yii\base\InvalidConfigException('ManagerInterface is not configured'); - } - if(!empty($module->rbac['rules'])) { - foreach($module->rbac['rules'] as $rule) { - $rule_model = new $rule(); - echo "Creating rule: ".$rule_model->name."\n"; - if($auth->add($rule_model)) { - echo "Successful\n"; - } else { - echo "Failed\n"; - } - unset($rule_model); - } - } - if(!empty($module->rbac['permissions'])) { - foreach($module->rbac['permissions'] as $permission) { - echo "Creating permission: ".$permission['name']."\n"; - if($auth->add(new \yii\rbac\Permission($permission))) { - echo "Successful\n"; - } else { - echo "Failed\n"; - } - } - } - } - - public function actionUninstall() - { - /** - * @var \common\modules\comment\Module $module - */ - $module = \Yii::$app->controller->module; - if(!$module->useRbac) { - throw new \yii\base\InvalidConfigException('Please set useRbac config to TRUE in your module configs'); - } - $auth = \Yii::$app->getAuthManager(); - if(!$auth instanceof \yii\rbac\ManagerInterface) { - throw new \yii\base\InvalidConfigException('ManagerInterface is not configured'); - } - if(!empty($module->rbac['rules'])) { - foreach($module->rbac['rules'] as $rule) { - $rule_model = new $rule(); - echo "Removing rule: ".$rule_model->name."\n"; - if($auth->remove($rule_model)) { - echo "Successful\n"; - } else { - echo "Failed\n"; - } - unset($rule_model); - } - } - if(!empty($module->rbac['permissions'])) { - foreach($module->rbac['permissions'] as $permission) { - echo "Removing permission: ".$permission['name']."\n"; - if($auth->remove(new \yii\rbac\Permission($permission))) { - echo "Successful\n"; - } else { - echo "Failed\n"; - } - } - } - } - - } \ No newline at end of file diff --git a/common/modules/comment/controllers/DefaultController.php b/common/modules/comment/controllers/DefaultController.php new file mode 100644 index 0000000..ae97cda --- /dev/null +++ b/common/modules/comment/controllers/DefaultController.php @@ -0,0 +1,139 @@ + [ + 'class' => VerbFilter::className(), + 'actions' => [ + 'create' => [ 'post' ], + 'delete' => [ + 'post', + 'delete', + ], + ], + ], + 'access' => [ + 'class' => AccessControl::className(), + 'only' => [ 'delete' ], + 'rules' => [ + [ + 'allow' => true, + 'roles' => [ '@' ], + ], + ], + ], + ]; + } + + /** + * Create comment. + * @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; + 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('yii2mod.comments', 'Oops, something went wrong. Please try again later.'*/ + "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.');*/ + "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.')*/ + "Comment not found."); + } + } + } \ No newline at end of file diff --git a/common/modules/comment/controllers/ManageController.php b/common/modules/comment/controllers/ManageController.php new file mode 100755 index 0000000..3a63045 --- /dev/null +++ b/common/modules/comment/controllers/ManageController.php @@ -0,0 +1,108 @@ + [ + '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/common/modules/comment/interfaces/CommentInterface.php b/common/modules/comment/interfaces/CommentInterface.php deleted file mode 100755 index 352c423..0000000 --- a/common/modules/comment/interfaces/CommentInterface.php +++ /dev/null @@ -1,11 +0,0 @@ - __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/common/modules/comment/messages/en/artbox-comment.php b/common/modules/comment/messages/en/artbox-comment.php new file mode 100755 index 0000000..3fef9ec --- /dev/null +++ b/common/modules/comment/messages/en/artbox-comment.php @@ -0,0 +1,60 @@ + '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/common/modules/comment/messages/ru/artbox-comment.php b/common/modules/comment/messages/ru/artbox-comment.php new file mode 100755 index 0000000..9b14ee3 --- /dev/null +++ b/common/modules/comment/messages/ru/artbox-comment.php @@ -0,0 +1,56 @@ + 'Идентификатор', + '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' => 'Комментарий успешно добавлен и появится после проверки администрацией.', + ]; diff --git a/common/modules/comment/migrations/m160724_162347_artbox_comment.php b/common/modules/comment/migrations/m160724_162347_artbox_comment.php new file mode 100644 index 0000000..93028c3 --- /dev/null +++ b/common/modules/comment/migrations/m160724_162347_artbox_comment.php @@ -0,0 +1,54 @@ +createTable('{{%artbox_comment}}', [ + 'artbox_comment_id' => $this->primaryKey(), + 'text' => $this->text()->notNull(), + 'user_id' => $this->integer(), + 'username' => $this->string(), + 'email' => $this->string(), + 'date_add' => $this->integer()->notNull(), + 'date_update' => $this->integer()->notNull(), + 'date_delete' => $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(), + 'date_add' => $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/common/modules/comment/migrations/m160726_092634_add_entity_fields.php b/common/modules/comment/migrations/m160726_092634_add_entity_fields.php new file mode 100644 index 0000000..16d8193 --- /dev/null +++ b/common/modules/comment/migrations/m160726_092634_add_entity_fields.php @@ -0,0 +1,18 @@ +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/common/modules/comment/migrations/m160726_211227_create_artbox_comment_rating.php b/common/modules/comment/migrations/m160726_211227_create_artbox_comment_rating.php new file mode 100644 index 0000000..2f0848e --- /dev/null +++ b/common/modules/comment/migrations/m160726_211227_create_artbox_comment_rating.php @@ -0,0 +1,31 @@ +createTable('{{%artbox_comment_rating}}', [ + 'artbox_comment_rating_id' => $this->primaryKey(), + 'date_add' => $this->integer() + ->notNull(), + 'date_update' => $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/common/modules/comment/models/Comment.php b/common/modules/comment/models/Comment.php deleted file mode 100755 index 505168d..0000000 --- a/common/modules/comment/models/Comment.php +++ /dev/null @@ -1,446 +0,0 @@ - 1, - ], - [ - [ 'comment_pid' ], - 'exist', - 'targetAttribute' => 'comment_id', - 'filter' => [ - 'model' => $this->model, - 'model_id' => $this->model_id, - ], - ], - ]; - } - - public function scenarios() - { - return [ - self::SCENARIO_GUEST => [ - 'user_name', - 'user_email', - 'text', - 'comment_pid', - ], - self::SCENARIO_USER => [ - 'text', - 'comment_pid', - ], - ]; - } - - /** - * @inheritdoc - */ - public function behaviors() - { - return [ - [ - 'class' => \yii\behaviors\TimestampBehavior::className(), - 'createdAtAttribute' => 'date_add', - 'updatedAtAttribute' => 'date_update', - 'value' => new \yii\db\Expression('NOW()'), - ], - ]; - } - - public function afterSave($insert, $changedAttributes) - { - if($this->model == User::className()) { - if($user = User::findOne($this->model_id)) { - /** - * @var User $user - */ - $user->updateRating(); - } - } - if($this->model == Product::className()) { - if($product = Product::findOne($this->model_id)) { - $product->recalculateRating(); - } - } - parent::afterSave($insert, $changedAttributes); - } - - /** - * @inheritdoc - */ - public static function tableName() - { - return '{{%comment}}'; - } - - /** - * @inheritdoc - */ - public function attributeLabels() - { - return [ - 'text' => \Yii::t('app', 'Комментарий'), - 'user_name' => \Yii::t('app', 'Имя'), - 'user_email' => \Yii::t('app', 'Email'), - ]; - } - - public function getGuestComment() - { - return $this->guestComment; - } - - public function setGuestComment($value) - { - $this->guestComment = $value; - } - - /** - * @param string $model - * @param integer $model_id - * - * @return ActiveQuery - */ - public static function getComments($model, $model_id) - { - return self::find() - ->where([ - 'comment.model' => $model, - 'comment.model_id' => $model_id, - 'comment.status' => 1, - ]) - ->with('rating'); - } - - public function postComment() - { - if($this->checkCreate()) { - if(!empty($this->comment_pid) && !$this->checkReply()) { - $this->addError('comment_id', 'You can`t reply to this message'); - return false; - } - if($this->insert()) { - $this->clearSafe(); - return true; - } else { - return false; - } - } - $this->addError('comment_id', 'You can`t post comment here'); - return false; - } - - public function updateComment() - { - if($this->checkUpdate()) { - if(empty( $this->comment_id )) { - $this->addError('comment_id', 'Comment ID not found'); - return false; - } else { - if($this->update()) { - // $this->clearSafe(); Clears safe attributes after AJAX update - return true; - } else { - return false; - } - } - } else { - $this->addError('comment_id', 'You can`t update this post'); - return false; - } - } - - public function deleteComment() - { - if($this->checkDelete()) { - if(empty( $this->comment_id )) { - $this->addError('comment_id', 'Comment ID not found'); - return false; - } else { - if($this->user_id == \Yii::$app->user->id) { - if($this->delete()) { - return true; - } else { - $this->addError('comment_id', 'Can\'t delete post.'); - return false; - } - } else { - if($this->status == self::STATUS_DELETED) { - return false; - } - $this->status = self::STATUS_DELETED; - if($this->update()) { - $this->clearSafe(); - return true; - } else { - return false; - } - } - } - } else { - $this->addError('comment_id', 'You can`t delete this post'); - return false; - } - } - - public function checkCreate() - { - if($this->getGuestComment()) { - return true; - } else { - return \Yii::$app->user->can(\common\modules\comment\Permissions::CREATE, [ - 'model' => $this->model, - 'model_id' => $this->model_id, - 'comment_model' => $this, - ]); - } - } - - public function checkUpdate() - { - if($this->scenario == self::SCENARIO_GUEST) { - return false; - } else { - return \Yii::$app->user->can(\common\modules\comment\Permissions::UPDATE, [ - 'model' => $this->model, - 'model_id' => $this->model_id, - 'comment' => $this, - ]) || \Yii::$app->user->can(\common\modules\comment\Permissions::UPDATE_OWN, [ - 'model' => $this->model, - 'model_id' => $this->model_id, - 'comment' => $this, - ]); - } - } - - public function checkDelete() - { - if($this->scenario == self::SCENARIO_GUEST) { - return false; - } else { - return ( \Yii::$app->user->can(\common\modules\comment\Permissions::DELETE, [ - 'model' => $this->model, - 'model_id' => $this->model_id, - 'comment' => $this, - ]) || \Yii::$app->user->can(\common\modules\comment\Permissions::DELETE_OWN, [ - 'model' => $this->model, - 'model_id' => $this->model_id, - 'comment' => $this, - ]) ); - } - } - - public function checkReply() - { - if($this->scenario == self::SCENARIO_GUEST) { - return false; - } else { - return $this->allowReply; - } - } - - protected function clearSafe($setNew = true) - { - $safe = $this->safeAttributes(); - $count = count($safe); - $values = array_fill(0, $count, NULL); - $result = array_combine($safe, $values); - $this->setAttributes($result); - $this->setIsNewRecord($setNew); - } - - public function getParent() - { - return $this->hasOne(self::className(), [ 'comment_id' => 'comment_pid' ]); - } - - public function getAuthorName() - { - if(!empty( $this->author )) { - return $this->author->username; - } else { - return $this->user_name; - } - } - - public function getAuthor($guestMark = '') - { - if(!empty( $this->user )) { - return $this->user->username; - } else { - $name = $this->user_name; - if(!empty( $guestMark )) { - $name .= $guestMark; - } - return $name; - } - } - - public function checkRating() - { - $rating = $this->hasOne(\common\modules\comment\models\Rating::className(), [ - 'model_id' => 'comment_id', - ]) - ->andWhere([ - 'model' => $this->className(), - ]) - ->one(); - if(!$rating instanceof \common\modules\comment\models\Rating && !empty( $this->primaryKey )) { - $rating = new \common\modules\comment\models\Rating([ - 'model' => $this->className(), - 'model_id' => $this->comment_id, - 'user_id' => $this->user_id, - ]); - $rating->save(); - } - } - - public function getRating() - { - $this->checkRating(); - return $this->hasOne(\common\modules\comment\models\Rating::className(), [ - 'model_id' => 'comment_id', - ]) - ->andWhere([ 'rating.model' => $this->className() ]); - } - - public function hasRating($return = true) - { - $rating = $this->hasOne(\common\modules\comment\models\Rating::className(), [ - 'model_id' => 'comment_id', - ]) - ->andWhere([ 'model' => $this->className() ]) - ->andWhere([ - 'not', - [ 'value' => NULL ], - ]) - ->one(); - if($return) { - return $rating; - } else { - return $rating ? true : false; - } - } - - public function getUser() - { - return $this->hasOne(User::className(), [ 'id' => 'user_id' ]); - } - - public function buildButtons( - $buttons = [ - 'delete', - 'update', - 'reply', - ] - ) { - if(in_array('delete', $buttons)) { - if($this->checkDelete()) { - $this->buttons[ 'delete' ] = Url::to([ - 'artbox-comment/delete', - 'comment_id' => $this->comment_id, - ]); - } - } - if(in_array('update', $buttons)) { - if($this->checkUpdate()) { - $this->buttons[ 'update' ] = Url::to([ - 'artbox-comment/update', - 'comment_id' => $this->comment_id, - ]); - } - } - if(in_array('reply', $buttons)) { - if($this->checkReply()) { - $this->buttons[ 'reply' ] = Url::to([ - 'artbox-comment/reply', - 'comment_id' => $this->comment_id, - ]); - } - } - } - - public function getAllowReply() - { - return $this->hasAttribute('comment_pid'); - } - - } diff --git a/common/modules/comment/models/CommentModel.php b/common/modules/comment/models/CommentModel.php new file mode 100644 index 0000000..b2f4f3a --- /dev/null +++ b/common/modules/comment/models/CommentModel.php @@ -0,0 +1,211 @@ + 0, + ], + [ + ['artbox_comment_pid'], + 'exist', + 'targetAttribute' => 'artbox_comment_id', + 'skipOnError' => true, + ], + ]; + } + + public function behaviors() + { + return [ + [ + 'class' => TimestampBehavior::className(), + 'createdAtAttribute' => 'date_add', + 'updatedAtAttribute' => 'date_update', + ], + [ + '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(), + ], + ]; + } + + 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'), + 'date_update' => \Yii::t('artbox-comment', 'Date update'), + 'date_delete' => \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'), + ]; + } + + function setEntity(string $entity) + { + $this->entity = $entity; + } + + function getEntity(): string + { + return $this->entity; + } + + 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' => [ + 'date_add' => SORT_DESC, + ], + ], + ]); + } + + function deleteComment(): bool { + if(\Yii::$app->user->id != NULL && \Yii::$app->user->id == $this->user_id) { + if($this->delete()) { + return true; + } + } + return false; + } + + function setEntityId(int $entityId) + { + $this->entityId = $entityId; + } + + function getEntityId(): int + { + return $this->entityId; + } + + function getChildren() + { + return $this->hasMany(self::className(), [ 'artbox_comment_pid' => 'artbox_comment_id' ]) + ->andFilterWhere(['status' => self::STATUS_ACTIVE]) + ->inverseOf('parent'); + } + + function getParent() + { + return $this->hasOne(self::className(), [ 'artbox_comment_id' => 'artbox_comment_pid' ]) + ->inverseOf('children'); + } + + function getUser() + { + $module = \Yii::$app->getModule('artbox-comment'); + return $this->hasOne($module->userIdentityClass, [ 'id' => 'user_id' ]); + } + + 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/common/modules/comment/models/CommentModelSearch.php b/common/modules/comment/models/CommentModelSearch.php new file mode 100644 index 0000000..7c3b9cb --- /dev/null +++ b/common/modules/comment/models/CommentModelSearch.php @@ -0,0 +1,204 @@ + 0, + ], + [ + [ + 'rating_value', + ], + 'number', + 'min' => 1, + 'max' => 5, + ], + [ + [ + 'user_id', + 'text', + 'username', + 'email', + 'ip', + 'entity', + 'info', + ], + 'safe', + ], + ]; + } + + public function attributeLabels() + { + return array_merge(parent::attributeLabels(), [ + 'rating_value' => 'Рейтинг', + 'children_count' => 'Количество ответов', + ]); + } + + /** + * @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' => [ + 'rating_value' => [ + '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' => [ + 'date_add' => 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, + 'date_add' => $this->date_add, + 'date_update' => $this->date_update, + 'date_delete' => $this->date_delete, + '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->rating_value, + ]); + + 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/common/modules/comment/models/CommentProject.php b/common/modules/comment/models/CommentProject.php deleted file mode 100755 index d35290c..0000000 --- a/common/modules/comment/models/CommentProject.php +++ /dev/null @@ -1,460 +0,0 @@ - 0, - ], - [ - [ - 'budget_currency', - ], - 'default', - 'value' => 3, - ], - [ - [ 'budget_currency' ], - 'exist', - 'targetClass' => Currency::className(), - 'targetAttribute' => 'currency_id', - ], - [ - [ - 'files', - ], - 'string', - ], - [ - [ - 'file', - ], - 'safe', - ], - [ - [ 'status' ], - 'default', - 'value' => 1, - ], - [ - [ 'state' ], - 'integer', - 'max' => 4, - 'min' => 1, - 'on' => self::SCENARIO_STATE, - ], - [ - [ 'state' ], - 'required', - 'on' => self::SCENARIO_STATE, - ], - [ - [ 'state' ], - 'required', - 'on' => self::SCENARIO_OWNER, - ], - [ - [ 'state' ], - 'in', - 'range' => [ - 1, - 5, - ], - 'on' => self::SCENARIO_OWNER, - ], - ]; - } - - public function scenarios() - { - return [ - self::SCENARIO_USER => [ - 'text', - 'budget_from', - 'budget_to', - 'budget_currency', - 'term_from', - 'term_to', - 'file', - ], - self::SCENARIO_GUEST => [ - - ], - self::SCENARIO_STATE => [ - 'state', - ], - self::SCENARIO_OWNER => [ - 'state', - ], - ]; - } - - /** - * @inheritdoc - */ - public function behaviors() - { - return [ - [ - 'class' => \yii\behaviors\TimestampBehavior::className(), - 'createdAtAttribute' => 'date_add', - 'updatedAtAttribute' => 'date_update', - 'value' => new \yii\db\Expression('NOW()'), - ], - ]; - } - - public static function tableName() - { - return '{{%comment_project}}'; - } - - /** - * @inheritdoc - */ - public function attributeLabels() - { - return [ - 'text' => \Yii::t('app', 'Текст ответа'), - 'budget_from' => \Yii::t('app', 'от'), - 'budget_to' => \Yii::t('app', 'до'), - 'term_from' => \Yii::t('app', 'от'), - 'term_to' => \Yii::t('app', 'до'), - ]; - } - - public function getGuestComment() - { - return $this->guestComment; - } - - // public function setGuestComment($value) - // { - // $this->guestComment = $value; - // } - - /** - * @param string $model - * @param integer $model_id - * - * @return ActiveQuery - */ - public static function getComments($model, $model_id) - { - /** - * @var User $user - */ - $user = \Yii::$app->user->identity; - if(!empty($user)) { - $project = Project::findOne($model_id); - if(!empty($project) && $user->id == $project->user_id) { - return self::find() - ->where([ - 'comment_project.model' => $model, - 'comment_project.model_id' => $model_id, - 'comment_project.status' => [self::STATUS_ANONYMOUS, self::STATUS_ACTIVE, self::STATUS_PERSONAL], - ]) - ->with('currency', 'user', 'user.userInfo', 'user.companyInfo', 'user.comments'); - } - } - $query = self::find() - ->where([ - 'comment_project.model' => $model, - 'comment_project.model_id' => $model_id, - ]) - ->with('currency', 'user', 'user.userInfo', 'user.companyInfo', 'user.comments'); - if(!empty($user)) { - $query->andWhere(['or', ['comment_project.status' => self::STATUS_ACTIVE], ['comment_project.status' => self::STATUS_ANONYMOUS, 'comment_project.user_id' => $user->id]]); - } else { - $query->andWhere(['comment_project.status' => 1]); - } - return $query; - } - - public function postComment() - { - if($this->checkCreate()) { - if(!empty( \Yii::$app->request->post($this->formName())[ 'anonymous' ] )) { - $this->status = self::STATUS_ANONYMOUS; - } - $this->file = UploadedFile::getInstances($this, 'file'); - if(!empty( $this->file )) { - $file_id = [ ]; - if(is_array($this->file)) { - foreach($this->file as $file) { - if($file instanceof UploadedFile) { - $file_model = new File(); - $file_id[] = $file_model->saveFile($file); - } - } - } else { - if($this->file instanceof UploadedFile) { - $file_model = new File(); - $file_id[] = $file_model->saveFile($this->file); - } - } - $this->files = json_encode($file_id); - } - if($this->insert()) { - $this->clearSafe(); - return true; - } else { - return false; - } - } else { - $this->addError('comment_id', 'You can`t post comment here'); - return false; - } - } - - public function updateComment() - { - if($this->checkUpdate()) { - if(empty( $this->comment_id )) { - $this->addError('comment_id', 'Comment ID not found'); - return false; - } else { - if($this->update()) { - $this->clearSafe(); - return true; - } else { - return false; - } - } - } else { - $this->addError('comment_id', 'You can`t update this post'); - return false; - } - } - - public function deleteComment() - { - if($this->checkDelete()) { - if(empty( $this->comment_id )) { - $this->addError('comment_id', 'Comment ID not found'); - return false; - } else { - if($this->status == self::STATUS_DELETED) { - return false; - } - $this->status = self::STATUS_DELETED; - if($this->update()) { - $this->clearSafe(); - return true; - } else { - return false; - } - } - } else { - $this->addError('comment_id', 'You can`t delete this post'); - return false; - } - } - - public function checkCreate() - { - if($this->getGuestComment()) { - return true; - } else { - return \Yii::$app->user->can(\common\modules\comment\Permissions::CREATE, [ - 'model' => $this->model, - 'model_id' => $this->model_id, - 'comment_model' => $this->className(), - ]); - } - } - - public function checkUpdate() - { - if($this->scenario == self::SCENARIO_GUEST) { - return false; - } else { - return \Yii::$app->user->can(\common\modules\comment\Permissions::UPDATE, [ - 'model' => $this->model, - 'model_id' => $this->model_id, - ]) || \Yii::$app->user->can(\common\modules\comment\Permissions::UPDATE_OWN, [ - 'model' => $this->model, - 'model_id' => $this->model_id, - ]); - } - } - - public function checkDelete() - { - if($this->scenario == self::SCENARIO_GUEST) { - return false; - } else { - return \Yii::$app->user->can(\common\modules\comment\Permissions::DELETE, [ - 'model' => $this->model, - 'model_id' => $this->model_id, - ]) || \Yii::$app->user->can(\common\modules\comment\Permissions::DELETE_OWN, [ - 'model' => $this->model, - 'model_id' => $this->model_id, - ]); - } - } - - protected function clearSafe($setNew = true) - { - $safe = $this->safeAttributes(); - $count = count($safe); - $values = array_fill(0, $count, NULL); - $result = array_combine($safe, $values); - $this->setAttributes($result); - $this->setIsNewRecord($setNew); - } - - public function getAuthor() - { - // if($this->user_id != NULL) { - return $this->hasOne(\common\models\User::className(), [ 'id' => 'user_id' ]); - // } else { - // return ['firstname' => $this->user_name, 'email' => $this->user_email]; - // } - } - - /** - * @return ActiveQuery - */ - public function getCurrency() - { - return $this->hasOne(Currency::className(), [ 'currency_id' => 'budget_currency' ]); - } - - /** - * @return File[] - */ - public function getFilesList() - { - $files = json_decode($this->files); - if(!empty( $files )) { - return File::findAll($files); - } else { - return [ ]; - } - } - - /** - * @return ActiveRecord - * @throws \TypeError - */ - public function getOwner() - { - $model = new $this->model(); - if($model instanceof ActiveRecord) { - return $model->findOne($this->model_id); - } else { - throw new \TypeError('Model must extends Active Record Class'); - } - } - - public function getProject() - { - return $this->hasOne(Project::className(), [ 'project_id' => 'model_id' ]); - } - - /** - * @return User - */ - public function getUser() - { - return $this->hasOne(User::className(), [ 'id' => 'user_id' ]); - } - - public function changeState() - { - if($this->isAttributeChanged('state')) { - if($this->save()) { - return true; - } else { - return false; - } - } else { - return true; - } - } - - } diff --git a/common/modules/comment/models/CommentProjectAnswer.php b/common/modules/comment/models/CommentProjectAnswer.php deleted file mode 100755 index 2d0b4d1..0000000 --- a/common/modules/comment/models/CommentProjectAnswer.php +++ /dev/null @@ -1,199 +0,0 @@ - 1, - ], - [ - [ 'comment_pid' ], - 'exist', - 'targetAttribute' => 'comment_id', - 'filter' => [ - 'model' => $this->model, - 'model_id' => $this->model_id, - ], - ], - [ - ['comment_pid'], - 'required', - 'when' => function($model, $attribute) { - /** - * @var CommentProjectAnswer $model - * @var string $attribute - */ - if(!empty(\Yii::$app->user->id) && $model->isNewRecord && !empty($model->model) && !empty($model->model_id)) { - $project = Project::findOne($model->model_id); - if(!empty($project) && $project->user_id == \Yii::$app->user->id) { - return true; - } - } - return false; - } - ], - ]; - } - - /** - * @param string $model - * @param integer $model_id - * - * @return ActiveQuery - */ - public static function getComments($model, $model_id) - { - $query = self::find() - ->where([ - 'comment.model' => $model, - 'comment.model_id' => $model_id, - 'comment.status' => 1, - 'comment.comment_pid' => NULL, - ]) - ->with('parent'); - $project = Project::findOne($model_id); - $user = \Yii::$app->user; - if(empty( $user ) || $project->user_id != $user->id) { - $query->innerJoin([ 'child' => 'comment' ], 'comment.comment_id = child.comment_pid') - ->andWhere([ - 'not', - [ 'child.comment_id' => NULL ], - ]); - } - return $query; - } - - public function beforeDelete() - { - if(!empty($this->child)) { - $this->child->delete(); - } - return parent::beforeDelete(); // TODO: Change the autogenerated stub - } - - public function checkCreate() - { - if($this->getGuestComment()) { - return true; - } else { - return \Yii::$app->user->can(\common\modules\comment\Permissions::CREATE, [ - 'model' => $this->model, - 'model_id' => $this->model_id, - 'comment_model' => $this, - ]); - } - } - - public function checkUpdate() - { - if($this->scenario == self::SCENARIO_GUEST) { - return false; - } else { - if(!empty($this->comment_pid) && $this->user_id == \Yii::$app->user->id) { - return true; - } - } - return false; - } - - public function checkDelete() - { - if($this->scenario == self::SCENARIO_GUEST) { - return false; - } else { - return ( \Yii::$app->user->can(\common\modules\comment\Permissions::DELETE, [ - 'model' => $this->model, - 'model_id' => $this->model_id, - 'comment' => $this, - ]) || \Yii::$app->user->can(\common\modules\comment\Permissions::DELETE_OWN, [ - 'model' => $this->model, - 'model_id' => $this->model_id, - 'comment' => $this, - ]) ); - } - } - - public function checkReply() - { - if($this->scenario != self::SCENARIO_GUEST) { - if(!$this->isNewRecord && empty( $this->comment_pid )) { - $project = Project::findOne($this->model_id); - if($project->user_id == \Yii::$app->user->id && empty($this->child)) { - return true; - } - } elseif($this->isNewRecord && !empty($this->comment_pid)) { - $parent = self::findOne($this->comment_pid); - if(!empty($parent) && $parent->checkReply()) { - return true; - } - } - } - return false; - } - - public function getChild() - { - return $this->hasOne($this->className(), [ 'comment_pid' => 'comment_id' ]); - } - - } diff --git a/common/modules/comment/models/CommentProjectSearch.php b/common/modules/comment/models/CommentProjectSearch.php deleted file mode 100755 index aae75ab..0000000 --- a/common/modules/comment/models/CommentProjectSearch.php +++ /dev/null @@ -1,92 +0,0 @@ - 5, - 'min' => 1, - ], - [ - [ - 'state', - ], - 'default', - 'value' => self::STATE_NEW, - ], - ]; - } - - public function scenarios() - { - return array_merge(parent::scenarios(), [ - self::SCENARIO_SEARCH => [ - 'state', - ], - ]); - } - - public function search($params) - { - $query = CommentProject::find() - ->with('project') - ->with('project.budgetCurrency') - ->with('project.comments') - ->where([ 'user_id' => \Yii::$app->user->getId() ]); - - $dataProvider = new ActiveDataProvider([ - 'query' => $query, - ]); - - $this->load($params); - - if(!$this->validate()) { - $query->andWhere('0=1'); - return $dataProvider; - } - - $query->andWhere([ 'state' => $this->state ]); - - return $dataProvider; - } - - } diff --git a/common/modules/comment/models/LikeModel.php b/common/modules/comment/models/LikeModel.php new file mode 100644 index 0000000..8ad420e --- /dev/null +++ b/common/modules/comment/models/LikeModel.php @@ -0,0 +1,14 @@ + Yii::t('app', 'Rating ID'), - 'date_add' => Yii::t('app', 'Date Add'), - 'date_update' => 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(\common\models\User::className(), ['id' => 'user_id']); - } -} diff --git a/common/modules/comment/models/RatingModel.php b/common/modules/comment/models/RatingModel.php new file mode 100755 index 0000000..6be7b69 --- /dev/null +++ b/common/modules/comment/models/RatingModel.php @@ -0,0 +1,87 @@ + 0.5, 'max' => 5], + ]; + } + + public function behaviors() + { + return [ + [ + 'class' => TimestampBehavior::className(), + 'createdAtAttribute' => 'date_add', + 'updatedAtAttribute' => 'date_update', + ], + [ + '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'), + 'date_update' => 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(\common\models\User::className(), ['id' => 'user_id']); + } + + public function getModel() + { + $model = $this->model; + return $this->hasOne($model, [$model::primaryKey() => 'model_id']); + } +} diff --git a/common/modules/comment/models/interfaces/CommentInterface.php b/common/modules/comment/models/interfaces/CommentInterface.php new file mode 100644 index 0000000..4c5bd1d --- /dev/null +++ b/common/modules/comment/models/interfaces/CommentInterface.php @@ -0,0 +1,23 @@ +checkProject($user, $item, $params); - } - return true; - } - - public function checkProject($user, $item, $params) - { - $project = \common\models\Project::findOne($params['model_id']); - if($project->user_id == $user) { - return false; - } - $comment = \common\modules\comment\models\CommentProject::find() - ->where([ 'model' => $params[ 'model' ], - 'model_id' => $params[ 'model_id' ], - 'user_id' => $user, - ])->one(); - if(empty($comment)) { - return true; - } else { - return false; - } - } - - } \ No newline at end of file diff --git a/common/modules/comment/rbac/ArtboxCommentDeleteOwnRule.php b/common/modules/comment/rbac/ArtboxCommentDeleteOwnRule.php deleted file mode 100755 index b9bc3cc..0000000 --- a/common/modules/comment/rbac/ArtboxCommentDeleteOwnRule.php +++ /dev/null @@ -1,22 +0,0 @@ -user_id == \Yii::$app->user->id) { - return true; - } - } - return false; - } - - } \ No newline at end of file diff --git a/common/modules/comment/rbac/ArtboxCommentDeleteRule.php b/common/modules/comment/rbac/ArtboxCommentDeleteRule.php deleted file mode 100755 index 2fa5a63..0000000 --- a/common/modules/comment/rbac/ArtboxCommentDeleteRule.php +++ /dev/null @@ -1,33 +0,0 @@ -hasAttribute('user_id') && $model->user_id == \Yii::$app->user->id) { - return true; - } elseif($model instanceof User && $model->id == \Yii::$app->user->id) { - return true; - } - } - } - return false; - } - - } \ No newline at end of file diff --git a/common/modules/comment/rbac/ArtboxCommentUpdateOwnRule.php b/common/modules/comment/rbac/ArtboxCommentUpdateOwnRule.php deleted file mode 100755 index edfd0b2..0000000 --- a/common/modules/comment/rbac/ArtboxCommentUpdateOwnRule.php +++ /dev/null @@ -1,20 +0,0 @@ -user_id == \Yii::$app->user->id) { - return true; - } - return false; - } - - } \ No newline at end of file diff --git a/common/modules/comment/rbac/ArtboxCommentUpdateRule.php b/common/modules/comment/rbac/ArtboxCommentUpdateRule.php deleted file mode 100755 index 536ac3f..0000000 --- a/common/modules/comment/rbac/ArtboxCommentUpdateRule.php +++ /dev/null @@ -1,17 +0,0 @@ - div { - float: left; - width: 100%; - font-size: 13px -} - -.comments-name { - font-weight: 700 -} - -.comments-project-link a { - color: #0073bc; - text-decoration: underline; - -} - -.comments-status span { - color: #0072bc; - border-bottom: 1px dashed #0072bc; -} - -.comments-status, .comments-date, .proektant-comments .rating { - margin-top: 3px -} - -.comments-content { - line-height: 18px; - margin-top: 11px -} - -.comments-project-link { - margin-top: 19px -} diff --git a/common/modules/comment/resources/comment.js b/common/modules/comment/resources/comment.js deleted file mode 100755 index 65af2b1..0000000 --- a/common/modules/comment/resources/comment.js +++ /dev/null @@ -1,237 +0,0 @@ -$(function() { - - function addRemoveBlocks(data) - { - $('#overlay, .succses_comm').remove(); - $('body').append('
').append('' + data.text + '
'); - } - } else - { - $(container).prepend('') - } - } - ); - } - } - ); - - $(document).on( - 'click', '.artbox_comment_reply', function(e) - { - e.preventDefault(); - var container = $(this).parents('.artbox_comment_container').first(); - var comment_id = $(container).data('key'); - var form_name = $(container).data('form'); - var author = $(container).find('.artbox_comment_author').first().text(); - var comment_form = $(container).parents('.artbox_comment_widget').find('.artbox_comment_form').first(); - var offset = $(comment_form).offset(); - var reply_block = $(comment_form).find('.artbox_comment_reply_block').first(); - $(reply_block).empty(); - $(reply_block).append(''); - $(reply_block).append(''); - $('html, body').animate( - { - scrollTop : offset.top - 50, - } - ); - } - ); - - $(document).on( - 'click', '.artbox_comment_reply_author', function() - { - $(this).parents('.artbox_comment_reply_block').first().empty(); - } - ); - - $(document).on( - 'click', '.artbox_comment_update', function(e) - { - e.preventDefault(); - var container = $(this).parents('.artbox_comment_container').first(); - var comment_id = $(container).data('key'); - var form_name = $(container).data('form'); - var object = {}; - object[form_name] = {comment_id : comment_id}; - $.post( - '/artbox-comment/form', object, function(data, textStatus, jqXHR) - { - $(container).empty(); - $(container).append(data.result.form); - } - ); - } - ); - - // @TODO What is this - $(document).on( - 'click', '.artbox_comment_update_reply', function() - { - $(this).remove(); - } - ); - - $(document).on( - 'click', '.artbox_comment_update_submit', function(e) - { - e.preventDefault(); - var container = $(this).parents('.artbox_comment_container').first(); - $.post( - '/artbox-comment/update', $(container).find('form').serialize(), function(data) - { - $(container).empty(); - if(!data.error) - { - $(container).append(''+data.result.text+'
'); - $(container).append(data.result.html); - } else { - $(container).append(data.form); - } - } - ) - } - ); - - $(document).on( - 'click', '.artbox_comment_update_answer', function(e) - { - e.preventDefault(); - var container = $(this).parents('.artbox_comment_container').first(); - var comment_id = $(container).data('key'); - var form_name = $(container).data('form'); - var object = {}; - object[form_name] = {comment_id : comment_id}; - $.post( - '/artbox-comment/form-answer', object, function(data, textStatus, jqXHR) - { - $(container).empty(); - $(container).append(data.result.form); - } - ); - } - ); - - $(document).on( - 'click', '.artbox_comment_update_answer_submit', function(e) - { - e.preventDefault(); - var container = $(this).parents('.artbox_comment_container').first(); - $.post( - '/artbox-comment/update-answer', $(container).find('form').serialize(), function(data) - { - $(container).empty(); - if(!data.error) - { - $(container).append(''+data.result.text+'
'); - $(container).append(data.result.html); - } else { - $(container).append(data.form); - } - } - ) - } - ); - - $(document).on( - 'click', '.artbox_comment_delete_answer', function(e) - { - e.preventDefault(); - var container = $(this).parents('.artbox_comment_container'); - var comment_id = $(container).data('key'); - var form_name = $(container).data('form'); - if(confirm("Уверены, что хотите удалить вопрос?")) - { - $.post( - '/artbox-comment/delete-answer', { - CommentProjectAnswer : { - comment_id : comment_id - } - }, function(data, textStatus, jqXHR) - { - if(!data.error) - { - $(container).remove(); - addRemoveBlocks(data) - } else - { - $(container).prepend('') - } - } - ); - } - } - ); - - $(document).on('click', '.artbox_comment_reply_answer', function(e) { - e.preventDefault(); - var widget = $(this).parents('.artbox_comment_widget'); - var form = $(widget).find('.artbox_comment_form'); - $(form).removeClass('hidden'); - $(widget).find('.artbox_comment_answer_label').text('Ответ'); - }); - - $(document).on('click', '.artbox_comment_reply_answer_block', function(e) { - var form = $(this).parents('.artbox_comment_form'); - $(form).addClass('hidden'); - $(form).find('.artbox_comment_answer_label').text('Вопрос'); - }); - -}); diff --git a/common/modules/comment/resources/delete-ico.png b/common/modules/comment/resources/delete-ico.png deleted file mode 100755 index 52c3718..0000000 Binary files a/common/modules/comment/resources/delete-ico.png and /dev/null differ diff --git a/common/modules/comment/todo b/common/modules/comment/todo new file mode 100644 index 0000000..cae6e3f --- /dev/null +++ b/common/modules/comment/todo @@ -0,0 +1,51 @@ +Сделать: +1. Реализовать действия. +2. Добавить RBAC. +3. Добавить рейтинг. +4. Добавить модерацию. +5. Добавить соц сети. +6. Добавить "пожаловаться". +7. Добавить установщик. +8. Добавить PJAX. +9. Добавить приколы. +10. Добавить возможность бана. +11. Предусмотреть удаление пользователя (что делать с его комментариями). +12. Добавить базовую верстку bootstrap / nonbootstrap. +13. Добавить возможность использования кастомной модели комментариев. +14. Реализовать мультиязычность. +15. Добавить возможность изменения макета (layout) функцией (Вместо "{form}{list}" добавить возможность function($parts, $view ...)). +16. Добавить сортировку. +17. Сделать навигацию по ссылкам related как на Youtube. + +Действия: +1. Добавить +2. Редактировать +3. Ответить +4. Like / dislike +5. Удалить + +Таблица (artbox_comment): +artbox_comment_id primary_key +text text +user_id int foreign key +username string +email string +date_add int notNull +date_update int notNull +date_delete int notNull +status int notNull default(1) +comment_pid int foreign_key +related_id int foreign key +ip string notNull +info text + +Таблица (artbox_comment_like): +artbox_comment_like_id primary_key +artbox_comment_id int foreign key +user_id int foreign key +date_add int notNull +is_like int notNull default(1) + +Приколы: +1. Рандомная генерация изображений +2. Смайлы \ No newline at end of file diff --git a/common/modules/comment/views/artbox_comment_form.php b/common/modules/comment/views/artbox_comment_form.php new file mode 100644 index 0000000..4fcad7d --- /dev/null +++ b/common/modules/comment/views/artbox_comment_form.php @@ -0,0 +1,44 @@ + $formId, + 'action' => Url::to([ + 'artbox-comment/default/create', + 'entity' => $comment_model->encryptedEntity, + ]), + ]); + if(!empty( $rating_model )) { + echo $form->field($rating_model, 'value', [ 'enableClientValidation' => false ]) + ->hiddenInput() + ->label(false); + echo Html::tag('div', '', [ + 'class' => 'rateit', + 'data-rateit-backingfld' => '#' . Html::getInputId($rating_model, 'value'), + ]); + } + if(\Yii::$app->user->isGuest) { + echo $form->field($comment_model, 'username') + ->textInput(); + echo $form->field($comment_model, 'email') + ->textInput(); + } + echo $form->field($comment_model, 'text') + ->textarea(); + echo Html::submitButton(/*Yii::t('artbox-comment', 'Submit')*/ + 'Submit'); + ActiveForm::end(); \ No newline at end of file diff --git a/common/modules/comment/views/artbox_comment_item.php b/common/modules/comment/views/artbox_comment_item.php new file mode 100644 index 0000000..6d26670 --- /dev/null +++ b/common/modules/comment/views/artbox_comment_item.php @@ -0,0 +1,161 @@ + +{success}, {form}, {list}
- * to render particular parts. You are also able to use common HTML here.
+ * Entity ID for attached model
+ * @var integer Entity ID
*/
- public $template = "{success}\n{form}\n{list}";
-
+ protected $entityId;
+
/**
- * @var array Widget options
+ * Encrypted data to be passed to Controller. Consist of:
+ * * Model::className()
+ * * entityId
+ * * info (optional)
+ * @var string encrypted entity key
*/
- public $options = [ ];
-
+ protected $encryptedEntityKey;
+
/**
- * @var \yii\data\DataProviderInterface Data provider of comments
+ * Parts for widget
+ * @var array $parts
*/
- public $dataProvider;
-
+ protected $parts;
+
/**
- * @inheritdoc
+ * Initializes the widget params.
*/
public function init()
{
- parent::init();
- \common\modules\comment\assets\CommentAsset::register($this->view);
- if(is_string($this->comment_class)) {
- $this->comment_class = new $this->comment_class($this->class_options);
- } else {
- throw new \yii\base\InvalidConfigException(__CLASS__ . '->comment_class must be defined as object full class name string.');
+ // Module init
+ Yii::$app->getModule(Module::$name);
+ // Model init
+ $model = $this->getModel();
+
+ /**
+ * @todo Check if needed
+ */
+ if(empty( $this->pjaxContainerId )) {
+ $this->pjaxContainerId = 'comment-pjax-container-' . $this->getId();
}
- if(!empty( $this->rating_class ) && is_string($this->rating_class)) {
- $this->rating_class = new $this->rating_class($this->rating_options);
- } elseif(!empty( $this->rating_class )) {
- throw new \yii\base\InvalidConfigException(__CLASS__ . '->rating_class must be defined as object full class name string.');
+
+ $this->entity = $model::className();
+ // Entity ID init
+ if(!empty( $this->entityIdAttribute ) && $this->model->hasProperty($this->entityIdAttribute)) {
+ $this->entityId = $this->model->{$this->entityIdAttribute};
+ } else {
+ if($this->model instanceof \yii\db\ActiveRecord && !empty( $this->model->getPrimaryKey() )) {
+ $this->entityId = (int) $this->model->getPrimaryKey();
+ } else {
+ throw new InvalidConfigException(/*Yii::t('artbox-comment', 'The "entityIdAttribute" value for widget model cannot be empty.')*/);
+ }
}
- $this->comment_class->model = $this->model;
- $this->comment_class->model_id = $this->model_id;
- $this->createDataProvider();
- $this->process();
- ob_start();
+
+ // Generate encryptedEntityKey
+ $this->encryptedEntityKey = $this->generateEntityKey();
+
+ $this->registerAssets();
}
-
+
/**
- * @inheritdoc
- * @return string
+ * Executes the widget.
+ * @return string the result of widget execution to be outputted.
*/
public function run()
{
- $content = ob_get_clean();
- $this->createParts();
+ /* @var Module $module */
+ $module = Yii::$app->getModule(Module::$name);
+ $commentModelClass = $module->commentModelClass;
+ $commentModel = $this->createModel($commentModelClass, [
+ 'entity' => $this->entity,
+ 'entityId' => $this->entityId,
+ 'encryptedEntity' => $this->encryptedEntityKey,
+ ]);
+ if($module::$enableRating) {
+ $ratingModelClass = $module->ratingModelClass;
+ $ratingModel = $this->createRating($ratingModelClass);
+ } else {
+ $ratingModel = NULL;
+ }
+
+ $comments = $commentModelClass::getTree($this->entity, $this->entityId);
+
+ $this->buildParts($commentModel, $comments, $ratingModel);
+
return $this->renderWidget();
}
-
- public function createParts()
+
+ /**
+ * Register assets.
+ */
+ protected function registerAssets()
{
- if($this->display_comment_success && ($this->isSuccess || \Yii::$app->session->getFlash('comment-success'))) {
- $tag = ArrayHelper::remove($this->success_options, 'tag', 'div');
- if(is_callable($this->success_options[ 'content' ])) {
- $result = call_user_func(ArrayHelper::remove($this->success_options, 'content'), $this->success_text);
- } elseif($this->success_options[ 'content' ] != NULL) {
- $result = Html::encode(ArrayHelper::remove($this->success_options, 'content', $this->success_text));
- } else {
- $result = Html::encode($this->success_text);
- }
- $this->parts[ 'success' ] = Html::tag($tag, $result, $this->success_options);
- unset( $tag, $result );
- }
-
- if($this->display_comment_list) {
- $tag = ArrayHelper::remove($this->list_options, 'tag', 'div');
- $view = ArrayHelper::remove($this->list_options, 'view');
- $this->parts[ 'list' ] = Html::tag($tag, $this->renderItems($view), $this->list_options);
- }
-
- if($this->display_comment_form && $this->comment_class->checkCreate()) {
- $tag = ArrayHelper::remove($this->form_options, 'tag', 'div');
- $view = ArrayHelper::remove($this->form_options, 'view');
- if(!empty( $this->form_options[ 'class' ] )) {
- $this->form_options[ 'class' ] .= ' ' . self::$baseClass[ 'form_container' ];
- } else {
- $this->form_options[ 'class' ] = self::$baseClass[ 'form_container' ];
- }
- $this->parts[ 'form' ] = Html::tag($tag, $this->renderForm($view), $this->form_options);
- }
+ $this->clientOptions[ 'formSelector' ] = '#' . $this->formId;
+ $this->clientOptions[ 'listSelector' ] = '#' . $this->listId;
+ $options = Json::encode($this->clientOptions);
+ $view = $this->getView();
+ CommentAsset::register($view);
+ $view->registerJs("jQuery('#{$this->formId}').artbox_comment({$options})", $view::POS_END);
}
-
- public function createDataProvider()
+
+ /**
+ * Get encrypted entity key
+ * @return string
+ */
+ protected function generateEntityKey()
{
- $this->dataProvider = new \yii\data\ActiveDataProvider([
- 'query' => ArrayHelper::remove($this->provider_options, 'query', $this->comment_class->getComments($this->model, $this->model_id)),
- 'sort' => ArrayHelper::remove($this->provider_options, 'sort', new Sort([
- 'defaultOrder' => [
- 'date_add' => SORT_DESC,
- ],
- ])),
- 'pagination' => ArrayHelper::remove($this->provider_options, 'pagination', [
- 'pageSize' => 10,
- ]),
- ]);
+ return Yii::$app->getSecurity()
+ ->encryptByKey(Json::encode([
+ 'entity' => $this->entity,
+ 'entity_id' => $this->entityId,
+ 'info' => $this->info,
+ ]), Module::$encryptionKey);
}
-
- public function renderItems($view)
+
+ /**
+ * Create comment model
+ *
+ * @param string $className Full namespaced model
+ * @param array $config Init config
+ *
+ * @return CommentInterface Comment model
+ * @throws InvalidConfigException If object not instance of \yii\base\Model
+ */
+ protected function createModel(string $className, array $config = [ ]): CommentInterface
{
- if(empty( $view )) {
- throw new \yii\base\InvalidConfigException("list_options[view] must be set");
+ $options = array_merge($config, [ 'class' => $className ]);
+ $object = Yii::createObject($options);
+ if($object instanceof CommentInterface) {
+ return $object;
}
- return $this->render($view, [
- 'dataProvider' => $this->dataProvider,
- 'commentClass' => $this->comment_class,
- ]);
+ throw new InvalidConfigException(/*Yii::t(\'artbox-comment\', \'Comment model must be instance of CommentInterface.\')*/);
}
-
- public function renderForm($view)
+
+ /**
+ * Create rating model
+ *
+ * @param string $className Full namespaced model
+ * @param array $config Init config
+ *
+ * @return CommentInterface Comment model
+ * @throws InvalidConfigException If object not instance of \yii\base\Model
+ */
+ protected function createRating(string $className, array $config = [ ]): RatingModel
{
- if(empty( $view )) {
- throw new \yii\base\InvalidConfigException("form_options[view] must be set");
+ $options = array_merge($config, [ 'class' => $className ]);
+ $object = Yii::createObject($options);
+ if($object instanceof RatingModel) {
+ return $object;
}
- if($this->comment_class->guestComment || !empty( \Yii::$app->user->identity )) {
- return $this->render($view, [
- 'model' => $this->comment_class,
- 'rating' => $this->rating_class,
- 'user' => \Yii::$app->user->identity,
- 'dataProvider' => $this->dataProvider,
- ]);
- } else {
- return '';
+ throw new InvalidConfigException(/*Yii::t(\'artbox-comment\', \'Comment model must be instance of RatingModel.\')*/);
+ }
+
+ /**
+ * Build parts for rendering widget
+ *
+ * @param CommentInterface $commentModel
+ * @param ActiveDataProvider $comments
+ */
+ protected function buildParts(CommentInterface $commentModel, ActiveDataProvider $comments, $ratingModel = NULL)
+ {
+ $form_options = $this->formOptions;
+ $this->parts[ 'form' ] = Html::tag(ArrayHelper::remove($form_options, 'tag', 'div'), $this->render($this->formView, [
+ 'comment_model' => $commentModel,
+ 'form_params' => $this->formParams,
+ 'model' => $this->getModel(),
+ 'formId' => $this->formId,
+ 'rating_model' => $ratingModel,
+ ]), $form_options);
+
+ if(!\Yii::$app->user->isGuest) {
+ $reply_options = $this->replyOptions;
+ $this->parts[ 'reply_form' ] = Html::tag(ArrayHelper::remove($reply_options, 'tag', 'div'), $this->render($this->replyView, [
+ 'comment_model' => $commentModel,
+ 'form_params' => $this->formParams,
+ 'model' => $this->getModel(),
+ 'formId' => $this->formId,
+ ]), $reply_options);
}
+
+ $list_options = array_merge($this->listOptions, [ 'id' => $this->listId ]);
+ $this->parts[ 'list' ] = Html::tag(ArrayHelper::remove($list_options, 'tag', 'div'), $this->render($this->listView, [
+ 'comment_model' => $commentModel,
+ 'list_params' => $this->listParams,
+ 'model' => $this->getModel(),
+ 'comments' => $comments,
+ 'item_options' => $this->itemOptions,
+ 'item_view' => $this->itemView,
+ ]), $list_options);
}
-
- public function renderWidget()
+
+ /**
+ * @return string
+ */
+ protected function renderWidget(): string
{
- $template = $this->template;
+ $layout = $this->layout;
$parts = $this->parts;
$options = $this->options;
- $template = preg_replace('/{success}/', ArrayHelper::remove($parts, 'success', ''), $template);
- $template = preg_replace('/{list}/', ArrayHelper::remove($parts, 'list', ''), $template);
- $template = preg_replace('/{form}/', ArrayHelper::remove($parts, 'form', ''), $template);
+ $layout = preg_replace('/{list}/', ArrayHelper::getValue($parts, 'list', ''), $layout);
+ $layout = preg_replace('/{form}/', ArrayHelper::getValue($parts, 'form', ''), $layout);
+ $layout = preg_replace('/{reply_form}/', ArrayHelper::getValue($parts, 'reply_form', ''), $layout);
$tag = ArrayHelper::remove($options, 'tag', 'div');
- if(!empty( $options[ 'class' ] )) {
- $options[ 'class' ] .= ' ' . self::$baseClass[ 'widget_container' ];
- } else {
- $options[ 'class' ] = self::$baseClass[ 'widget_container' ];
- }
- return Html::tag($tag, $template, $options);
+ return Html::tag($tag, $layout, $options);
}
-
- public function process()
+
+ public function setModel(\yii\base\Model $model)
{
- $data = \Yii::$app->request->post();
- if($this->comment_class->load($data) && $this->comment_class->postComment()) {
- if(is_object($this->rating_class)) {
- $this->comment_class->checkRating();
- if($this->comment_class->rating->load($data) && $this->comment_class->rating->save()) {
- $this->isSuccess = true;
- \Yii::$app->session->setFlash('comment-success', $this->success_text);
- \Yii::$app->response->redirect('');
- }
- } else {
- $this->isSuccess = true;
- }
+ $this->model = $model;
+ }
+
+ public function getModel(): \yii\base\Model
+ {
+ if(!empty( $this->model )) {
+ return $this->model;
}
+ throw new InvalidConfigException(/*Yii::t(\'artbox-comment\', \'The "model" property must be set.\')*/);
}
-
}
\ No newline at end of file
diff --git a/common/modules/comment/widgets/views/_project_comment_view.php b/common/modules/comment/widgets/views/_project_comment_view.php
deleted file mode 100755
index e8f5ff0..0000000
--- a/common/modules/comment/widgets/views/_project_comment_view.php
+++ /dev/null
@@ -1,199 +0,0 @@
-user;
-?>
-
-= \Yii::$app->formatter->asDate($model->date_add, 'php:d.m.Y') ?>
-
";
- }
- ?>
- = date('d.m.Y', strtotime($model->date_add)) ?>
-