Commit 2d107e9e171d497711b3129ece88b25676c96a15
1 parent
d7d32bb2
test
Showing
18 changed files
with
880 additions
and
259 deletions
Show diff stats
common/config/main.php
@@ -24,7 +24,10 @@ | @@ -24,7 +24,10 @@ | ||
24 | 'targetType' => IMG_GIF|IMG_JPG|IMG_PNG|IMG_WBMP, // Target image formats ( bit-field ) | 24 | 'targetType' => IMG_GIF|IMG_JPG|IMG_PNG|IMG_WBMP, // Target image formats ( bit-field ) |
25 | 'targetMinPixel' => 200 // Target image minimum pixel size | 25 | 'targetMinPixel' => 200 // Target image minimum pixel size |
26 | ] | 26 | ] |
27 | - ] | 27 | + ], |
28 | + 'artbox-comment' => [ | ||
29 | + 'class' => \common\modules\comment\Controller::className(), | ||
30 | + ], | ||
28 | ], | 31 | ], |
29 | 32 | ||
30 | 'modules' => [ | 33 | 'modules' => [ |
common/models/Blog.php
1 | +<?php | ||
2 | + namespace common\modules\comment; | ||
3 | + | ||
4 | + class Controller extends \yii\web\Controller | ||
5 | + { | ||
6 | + public function behaviors() | ||
7 | + { | ||
8 | + return [ | ||
9 | + 'verbs' => [ | ||
10 | + 'class' => \yii\filters\VerbFilter::className(), | ||
11 | + 'actions' => [ | ||
12 | + '*' => ['post'], | ||
13 | + ], | ||
14 | + ], | ||
15 | + ]; | ||
16 | + } | ||
17 | + | ||
18 | + public function actionDelete() | ||
19 | + { | ||
20 | + \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; | ||
21 | + $post = \Yii::$app->request->post('Comment'); | ||
22 | + if(!empty($post['comment_id'])) { | ||
23 | + if($model = \common\modules\comment\models\Comment::findOne($post['comment_id'])) { | ||
24 | + /** | ||
25 | + * @var \common\modules\comment\models\Comment $model | ||
26 | + */ | ||
27 | + $model->scenario = is_int(\Yii::$app->user->getId()) ? \common\modules\comment\models\Comment::SCENARIO_USER : \common\modules\comment\models\Comment::SCENARIO_GUEST; | ||
28 | + if($model->deleteComment()) { | ||
29 | + \Yii::$app->response->data = ['text' => 'Comment marked as deleted and will be check by administrators']; | ||
30 | + } else { | ||
31 | + \Yii::$app->response->data = ['error' => $model->hasErrors('comment_id')?$model->getFirstError('comment_id'):'Cannot delete message']; | ||
32 | + } | ||
33 | + }else { | ||
34 | + \Yii::$app->response->data = ['error' => 'Comment not found']; | ||
35 | + }; | ||
36 | + } else { | ||
37 | + \Yii::$app->response->data = ['error' => 'Missing comment_id']; | ||
38 | + } | ||
39 | + \Yii::$app->response->send(); | ||
40 | + } | ||
41 | + | ||
42 | + public function actionUpdate() | ||
43 | + { | ||
44 | + \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; | ||
45 | + $post = \Yii::$app->request->post(); | ||
46 | + if(!empty($post['Comment']['comment_id'])) { | ||
47 | + if($model = \common\modules\comment\models\Comment::findOne($post['Comment']['comment_id'])) { | ||
48 | + /** | ||
49 | + * @var \common\modules\comment\models\Comment $model | ||
50 | + */ | ||
51 | + $model->scenario = is_int(\Yii::$app->user->getId()) ? \common\modules\comment\models\Comment::SCENARIO_USER : \common\modules\comment\models\Comment::SCENARIO_GUEST; | ||
52 | + $model->load($post); | ||
53 | + if(empty($post['Comment']['comment_pid'])) { | ||
54 | + $model->comment_pid = null; | ||
55 | + } | ||
56 | + if($model->updateComment()) { | ||
57 | + \Yii::$app->response->data = ['text' => 'Comment successfully updated']; | ||
58 | + } else { | ||
59 | + \Yii::$app->response->data = ['error' => $model->hasErrors()?$model->getFirstErrors():'Cannot update message']; | ||
60 | + } | ||
61 | + }else { | ||
62 | + \Yii::$app->response->data = ['error' => 'Comment not found']; | ||
63 | + }; | ||
64 | + } else { | ||
65 | + \Yii::$app->response->data = ['error' => 'Missing comment_id']; | ||
66 | + } | ||
67 | + \Yii::$app->response->send(); | ||
68 | + } | ||
69 | + | ||
70 | + public function actionForm() | ||
71 | + { | ||
72 | + $post = \Yii::$app->request->post('Comment'); | ||
73 | + if(!empty($post['comment_id'])) { | ||
74 | + $model = \common\modules\comment\models\Comment::find()->where(['comment_id' => $post['comment_id']])->with('parent', 'author')->one(); | ||
75 | + if($model) { | ||
76 | + /** | ||
77 | + * @var \common\modules\comment\models\Comment $model | ||
78 | + */ | ||
79 | + $model->scenario = is_int(\Yii::$app->user->getId()) ? \common\modules\comment\models\Comment::SCENARIO_USER : \common\modules\comment\models\Comment::SCENARIO_GUEST; | ||
80 | + if($model->checkUpdate()) { | ||
81 | + return $this->renderAjax('@common/modules/comment/views/comment_form', [ | ||
82 | + 'model' => $model, | ||
83 | + ]); | ||
84 | + } else { | ||
85 | + \Yii::$app->response->data = ['error' => 'You are not able to update this comment']; | ||
86 | + } | ||
87 | + }else { | ||
88 | + \Yii::$app->response->data = ['error' => 'Comment not found']; | ||
89 | + }; | ||
90 | + } else { | ||
91 | + \Yii::$app->response->data = ['error' => 'Missing comment_id']; | ||
92 | + } | ||
93 | + \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; | ||
94 | + \Yii::$app->response->send(); | ||
95 | + } | ||
96 | + } | ||
0 | \ No newline at end of file | 97 | \ No newline at end of file |
common/modules/comment/Permissions.php
@@ -8,5 +8,5 @@ | @@ -8,5 +8,5 @@ | ||
8 | const UPDATE = 'artbox_comment.update'; | 8 | const UPDATE = 'artbox_comment.update'; |
9 | const DELETE = 'artbox_comment.delete'; | 9 | const DELETE = 'artbox_comment.delete'; |
10 | const UPDATE_OWN = 'artbox_comment.update_own'; | 10 | const UPDATE_OWN = 'artbox_comment.update_own'; |
11 | - const DELETE_OWN = 'artbox_comment.delete.own'; | 11 | + const DELETE_OWN = 'artbox_comment.delete_own'; |
12 | } | 12 | } |
13 | \ No newline at end of file | 13 | \ No newline at end of file |
1 | +<?php | ||
2 | + namespace common\modules\comment\assets; | ||
3 | + | ||
4 | + class CommentAsset extends \yii\web\AssetBundle | ||
5 | + { | ||
6 | + public $sourcePath = '@common/modules/comment/resources'; | ||
7 | + | ||
8 | + public $css = [ | ||
9 | + 'comment.css', | ||
10 | + ]; | ||
11 | + | ||
12 | + public $js = [ | ||
13 | + 'comment.js', | ||
14 | + ]; | ||
15 | + | ||
16 | + public $depends = [ | ||
17 | + '\yii\web\YiiAsset', | ||
18 | + '\yii\web\JqueryAsset', | ||
19 | + ]; | ||
20 | + | ||
21 | + } | ||
0 | \ No newline at end of file | 22 | \ No newline at end of file |
common/modules/comment/interfaces/CommentInterface.php
@@ -5,7 +5,7 @@ | @@ -5,7 +5,7 @@ | ||
5 | public function load($data, $formName = null); | 5 | public function load($data, $formName = null); |
6 | public function formName(); | 6 | public function formName(); |
7 | public function getComments($entity); | 7 | public function getComments($entity); |
8 | - public function postComment($data); | ||
9 | - public function deleteComment($comment_id); | ||
10 | - public function updateComment($comment_id); | 8 | + public function postComment(); |
9 | + public function deleteComment(); | ||
10 | + public function updateComment(); | ||
11 | } | 11 | } |
common/modules/comment/models/Comment.php
@@ -3,7 +3,8 @@ | @@ -3,7 +3,8 @@ | ||
3 | 3 | ||
4 | /** | 4 | /** |
5 | * Class Comment | 5 | * Class Comment |
6 | - * @property bool $guestComment | 6 | + * @property bool $guestComment |
7 | + * @property integer $comment_id | ||
7 | * @package common\modules\comment\models | 8 | * @package common\modules\comment\models |
8 | */ | 9 | */ |
9 | class Comment extends \yii\db\ActiveRecord | 10 | class Comment extends \yii\db\ActiveRecord |
@@ -18,29 +19,87 @@ | @@ -18,29 +19,87 @@ | ||
18 | const SCENARIO_USER = 'user'; | 19 | const SCENARIO_USER = 'user'; |
19 | const SCENARIO_GUEST = 'guest'; | 20 | const SCENARIO_GUEST = 'guest'; |
20 | 21 | ||
22 | + /** | ||
23 | + * @var bool | ||
24 | + */ | ||
25 | + public $guestComment = true; | ||
26 | + | ||
21 | public function rules() | 27 | public function rules() |
22 | { | 28 | { |
23 | return [ | 29 | return [ |
24 | [ | 30 | [ |
25 | - ['text'], | 31 | + [ |
32 | + 'text', | ||
33 | + 'user_name', | ||
34 | + 'user_email', | ||
35 | + ], | ||
26 | 'required', | 36 | 'required', |
27 | ], | 37 | ], |
28 | [ | 38 | [ |
29 | - ['user_email'], | 39 | + [ |
40 | + 'rating', | ||
41 | + ], | ||
42 | + 'safe', | ||
43 | + ], | ||
44 | + [ | ||
45 | + [ 'user_email' ], | ||
30 | 'email', | 46 | 'email', |
31 | ], | 47 | ], |
32 | [ | 48 | [ |
33 | - ['user_name'], | 49 | + [ 'user_name' ], |
34 | 'string', | 50 | 'string', |
35 | ], | 51 | ], |
52 | + [ | ||
53 | + [ | ||
54 | + 'comment_id', | ||
55 | + 'comment_pid', | ||
56 | + ], | ||
57 | + 'integer', | ||
58 | + ], | ||
59 | + [ | ||
60 | + [ 'status' ], | ||
61 | + 'default', | ||
62 | + 'value' => 1, | ||
63 | + ], | ||
64 | + [ | ||
65 | + [ 'comment_pid' ], | ||
66 | + 'exist', | ||
67 | + 'targetAttribute' => 'comment_id', | ||
68 | + 'filter' => [ | ||
69 | + 'entity' => $this->entity, | ||
70 | + ], | ||
71 | + ], | ||
36 | ]; | 72 | ]; |
37 | } | 73 | } |
38 | 74 | ||
39 | public function scenarios() | 75 | public function scenarios() |
40 | { | 76 | { |
41 | return [ | 77 | return [ |
42 | - self::SCENARIO_GUEST => ['user_name', 'user_email', 'text'], | ||
43 | - self::SCENARIO_USER => ['text'], | 78 | + self::SCENARIO_GUEST => [ |
79 | + 'user_name', | ||
80 | + 'user_email', | ||
81 | + 'text', | ||
82 | + 'comment_pid', | ||
83 | + ], | ||
84 | + self::SCENARIO_USER => [ | ||
85 | + 'text', | ||
86 | + 'comment_pid', | ||
87 | + ], | ||
88 | + ]; | ||
89 | + } | ||
90 | + | ||
91 | + /** | ||
92 | + * @inheritdoc | ||
93 | + */ | ||
94 | + public function behaviors() | ||
95 | + { | ||
96 | + return [ | ||
97 | + [ | ||
98 | + 'class' => \yii\behaviors\TimestampBehavior::className(), | ||
99 | + 'createdAtAttribute' => 'date_add', | ||
100 | + 'updatedAtAttribute' => 'date_update', | ||
101 | + 'value' => new \yii\db\Expression('NOW()'), | ||
102 | + ], | ||
44 | ]; | 103 | ]; |
45 | } | 104 | } |
46 | 105 | ||
@@ -55,52 +114,119 @@ | @@ -55,52 +114,119 @@ | ||
55 | public function attributeLabels() | 114 | public function attributeLabels() |
56 | { | 115 | { |
57 | return [ | 116 | return [ |
58 | - 'text' => \Yii::t('app', 'Комментарий'), | ||
59 | - 'user_name' => \Yii::t('app', 'Имя'), | 117 | + 'text' => \Yii::t('app', 'Комментарий'), |
118 | + 'user_name' => \Yii::t('app', 'Имя'), | ||
60 | 'user_email' => \Yii::t('app', 'Email'), | 119 | 'user_email' => \Yii::t('app', 'Email'), |
61 | ]; | 120 | ]; |
62 | } | 121 | } |
63 | 122 | ||
64 | - public function getGuestComment($entity) | 123 | + public function getGuestComment() |
124 | + { | ||
125 | + return $this->guestComment; | ||
126 | + } | ||
127 | + | ||
128 | + public function setGuestComment($value) | ||
65 | { | 129 | { |
66 | - return true; | 130 | + $this->guestComment = $value; |
67 | } | 131 | } |
68 | 132 | ||
69 | public function getComments($entity) | 133 | public function getComments($entity) |
70 | { | 134 | { |
71 | - return $this->find()->where(['entity' => $this->entity]); | 135 | + return $this->find() |
136 | + ->where([ | ||
137 | + 'entity' => $this->entity, | ||
138 | + 'status' => 1, | ||
139 | + ]); | ||
72 | } | 140 | } |
73 | 141 | ||
74 | - public function postComment($data) | 142 | + public function postComment() |
75 | { | 143 | { |
76 | - if($this->load($data) && $this->insert($data)) { | ||
77 | - $this->clearSafe(); | ||
78 | - return true; | 144 | + if($this->checkCreate()) { |
145 | + if($this->insert()) { | ||
146 | + $this->clearSafe(); | ||
147 | + return true; | ||
148 | + } else { | ||
149 | + return false; | ||
150 | + } | ||
79 | } else { | 151 | } else { |
152 | + $this->addError('comment_id', 'You can`t post comment here'); | ||
80 | return false; | 153 | return false; |
81 | } | 154 | } |
82 | } | 155 | } |
83 | 156 | ||
84 | - public function updateComment($comment_id) | 157 | + public function updateComment() |
85 | { | 158 | { |
86 | - // TODO: Implement updateComment() method. | 159 | + if($this->checkUpdate()) { |
160 | + if(empty( $this->comment_id )) { | ||
161 | + $this->addError('comment_id', 'Comment ID not found'); | ||
162 | + return false; | ||
163 | + } else { | ||
164 | + if($this->update()) { | ||
165 | + $this->clearSafe(); | ||
166 | + return true; | ||
167 | + } else { | ||
168 | + return false; | ||
169 | + } | ||
170 | + } | ||
171 | + } else { | ||
172 | + $this->addError('comment_id', 'You can`t update this post'); | ||
173 | + return false; | ||
174 | + } | ||
87 | } | 175 | } |
88 | 176 | ||
89 | - public function deleteComment($comment_id) | 177 | + public function deleteComment() |
90 | { | 178 | { |
91 | - // TODO: Implement deleteComment() method. | 179 | + if($this->checkDelete()) { |
180 | + if(empty( $this->comment_id )) { | ||
181 | + $this->addError('comment_id', 'Comment ID not found'); | ||
182 | + return false; | ||
183 | + } else { | ||
184 | + if($this->status == self::STATUS_DELETED) { | ||
185 | + return false; | ||
186 | + } | ||
187 | + $this->status = self::STATUS_DELETED; | ||
188 | + if($this->update()) { | ||
189 | + $this->clearSafe(); | ||
190 | + return true; | ||
191 | + } else { | ||
192 | + return false; | ||
193 | + } | ||
194 | + } | ||
195 | + } else { | ||
196 | + $this->addError('comment_id', 'You can`t delete this post'); | ||
197 | + return false; | ||
198 | + } | ||
92 | } | 199 | } |
93 | 200 | ||
94 | - public function checkCreate($entity) | 201 | + public function checkCreate() |
95 | { | 202 | { |
96 | - if($this->getGuestComment($entity)) { | 203 | + if($this->getGuestComment()) { |
97 | return true; | 204 | return true; |
98 | } else { | 205 | } else { |
99 | - return \Yii::$app->user->can(\common\modules\comment\Permissions::CREATE, ['entity' => $entity]); | 206 | + return \Yii::$app->user->can(\common\modules\comment\Permissions::CREATE, [ 'entity' => $this->entity ]); |
100 | } | 207 | } |
101 | } | 208 | } |
102 | 209 | ||
103 | - protected function clearSafe($setNew = true) { | 210 | + public function checkUpdate() |
211 | + { | ||
212 | + if($this->scenario == self::SCENARIO_GUEST) { | ||
213 | + return false; | ||
214 | + } else { | ||
215 | + return \Yii::$app->user->can(\common\modules\comment\Permissions::UPDATE, [ 'entity' => $this->entity ]) || \Yii::$app->user->can(\common\modules\comment\Permissions::UPDATE_OWN, [ 'entity' => $this->entity ]); | ||
216 | + } | ||
217 | + } | ||
218 | + | ||
219 | + public function checkDelete() | ||
220 | + { | ||
221 | + if($this->scenario == self::SCENARIO_GUEST) { | ||
222 | + return false; | ||
223 | + } else { | ||
224 | + return \Yii::$app->user->can(\common\modules\comment\Permissions::DELETE, [ 'entity' => $this->entity ]) || \Yii::$app->user->can(\common\modules\comment\Permissions::DELETE_OWN, [ 'entity' => $this->entity ]); | ||
225 | + } | ||
226 | + } | ||
227 | + | ||
228 | + protected function clearSafe($setNew = true) | ||
229 | + { | ||
104 | $safe = $this->safeAttributes(); | 230 | $safe = $this->safeAttributes(); |
105 | $count = count($safe); | 231 | $count = count($safe); |
106 | $values = array_fill(0, $count, NULL); | 232 | $values = array_fill(0, $count, NULL); |
@@ -109,4 +235,56 @@ | @@ -109,4 +235,56 @@ | ||
109 | $this->setIsNewRecord($setNew); | 235 | $this->setIsNewRecord($setNew); |
110 | } | 236 | } |
111 | 237 | ||
112 | - } | ||
113 | \ No newline at end of file | 238 | \ No newline at end of file |
239 | + public function getParent() | ||
240 | + { | ||
241 | + return $this->hasOne(self::className(), [ 'comment_id' => 'comment_pid' ]); | ||
242 | + } | ||
243 | + | ||
244 | + public function getAuthor() | ||
245 | + { | ||
246 | + // if($this->user_id != NULL) { | ||
247 | + return $this->hasOne(\common\models\User::className(), [ 'id' => 'user_id' ]); | ||
248 | + // } else { | ||
249 | + // return ['firstname' => $this->user_name, 'email' => $this->user_email]; | ||
250 | + // } | ||
251 | + } | ||
252 | + | ||
253 | + public function checkRating() | ||
254 | + { | ||
255 | + $rating = $this->hasOne(\common\modules\comment\models\Rating::className(), [ 'entity' => 'entityId' ]) | ||
256 | + ->one(); | ||
257 | + if(!$rating instanceof \common\modules\comment\models\Rating) { | ||
258 | + $rating = new \common\modules\comment\models\Rating([ | ||
259 | + 'entity' => $this->entityId, | ||
260 | + 'user_id' => $this->user_id, | ||
261 | + ]); | ||
262 | + $rating->save(); | ||
263 | + } | ||
264 | + } | ||
265 | + | ||
266 | + public function getRating() | ||
267 | + { | ||
268 | + $this->checkRating(); | ||
269 | + return $this->hasOne(\common\modules\comment\models\Rating::className(), [ 'entity' => 'entityId' ]); | ||
270 | + } | ||
271 | + | ||
272 | + public function hasRating($return = true) | ||
273 | + { | ||
274 | + $rating = $this->hasOne(\common\modules\comment\models\Rating::className(), [ 'entity' => 'entityId' ]) | ||
275 | + ->andWhere([ | ||
276 | + 'not', | ||
277 | + [ 'value' => NULL ], | ||
278 | + ]) | ||
279 | + ->one(); | ||
280 | + if($return) { | ||
281 | + return $rating; | ||
282 | + } else { | ||
283 | + return $rating ? true : false; | ||
284 | + } | ||
285 | + } | ||
286 | + | ||
287 | + public function getEntityId() | ||
288 | + { | ||
289 | + return $this->formName() . '-' . $this->getPrimaryKey(); | ||
290 | + } | ||
291 | + } |
1 | +<?php | ||
2 | + | ||
3 | +namespace common\modules\comment\models; | ||
4 | + | ||
5 | +use Yii; | ||
6 | + | ||
7 | +/** | ||
8 | + * This is the model class for table "rating". | ||
9 | + * | ||
10 | + * @property integer $rating_id | ||
11 | + * @property string $date_add | ||
12 | + * @property string $date_update | ||
13 | + * @property integer $user_id | ||
14 | + * @property string $entity | ||
15 | + * @property integer $value | ||
16 | + * | ||
17 | + * @property \common\models\User $user | ||
18 | + */ | ||
19 | +class Rating extends \yii\db\ActiveRecord | ||
20 | +{ | ||
21 | + /** | ||
22 | + * @inheritdoc | ||
23 | + */ | ||
24 | + public static function tableName() | ||
25 | + { | ||
26 | + return 'rating'; | ||
27 | + } | ||
28 | + | ||
29 | + /** | ||
30 | + * @inheritdoc | ||
31 | + */ | ||
32 | + public function rules() | ||
33 | + { | ||
34 | + return [ | ||
35 | + [['value'], 'integer'], | ||
36 | + ]; | ||
37 | + } | ||
38 | + | ||
39 | + /** | ||
40 | + * @inheritdoc | ||
41 | + */ | ||
42 | + public function attributeLabels() | ||
43 | + { | ||
44 | + return [ | ||
45 | + 'rating_id' => Yii::t('app', 'Rating ID'), | ||
46 | + 'date_add' => Yii::t('app', 'Date Add'), | ||
47 | + 'date_update' => Yii::t('app', 'Date Update'), | ||
48 | + 'user_id' => Yii::t('app', 'User ID'), | ||
49 | + 'entity' => Yii::t('app', 'Entity'), | ||
50 | + 'value' => Yii::t('app', 'Value'), | ||
51 | + ]; | ||
52 | + } | ||
53 | + | ||
54 | + /** | ||
55 | + * @return \yii\db\ActiveQuery | ||
56 | + */ | ||
57 | + public function getUser() | ||
58 | + { | ||
59 | + return $this->hasOne(\common\models\User::className(), ['id' => 'user_id']); | ||
60 | + } | ||
61 | +} |
1 | +.artbox_comment_reply_author, .artbox_comment_update_reply { | ||
2 | + position: relative; | ||
3 | + width: 25%; | ||
4 | +} | ||
5 | +.artbox_comment_update_reply { | ||
6 | + width: 25%; | ||
7 | + float: none; | ||
8 | +} | ||
9 | +.artbox_comment_reply_author:after, .artbox_comment_update_reply:after { | ||
10 | + content: ''; | ||
11 | + background-image: url('delete-ico.png'); | ||
12 | + display: block; | ||
13 | + position: absolute; | ||
14 | + right: -13px; | ||
15 | + width: 13px; | ||
16 | + height: 13px; | ||
17 | + top: 0; | ||
18 | + cursor: pointer; | ||
19 | +} | ||
0 | \ No newline at end of file | 20 | \ No newline at end of file |
1 | +$(function() { | ||
2 | + | ||
3 | + $(document).on('click', '.artbox_comment_delete', function() { | ||
4 | + var container = $(this).parents('.artbox_comment_container'); | ||
5 | + var comment_id = $(container).data('comment_id'); | ||
6 | + var form_name = $(container).data('form_name'); | ||
7 | + if(confirm("Уверены, что хотите удалить комментарий?")) { | ||
8 | + $.post( | ||
9 | + '/artbox-comment/delete', | ||
10 | + { | ||
11 | + Comment: { | ||
12 | + comment_id: comment_id | ||
13 | + } | ||
14 | + }, | ||
15 | + function(data, textStatus, jqXHR) { | ||
16 | + if(!data.error) { | ||
17 | + $(container).after('<p class="removeable">'+data.text+'</p>'); | ||
18 | + $(container).remove(); | ||
19 | + } else { | ||
20 | + $(container).prepend('<p class="removeable error_message">'+data.error+'</p>') | ||
21 | + } | ||
22 | + } | ||
23 | + ); | ||
24 | + } | ||
25 | + }); | ||
26 | + | ||
27 | + $(document).on('click', '.artbox_comment_reply', function() { | ||
28 | + var container = $(this).parents('.artbox_comment_container').first(); | ||
29 | + var comment_id = $(container).data('comment_id'); | ||
30 | + var form_name = $(container).data('form_name'); | ||
31 | + var author = $(container).find('.artbox_comment_author').first().text(); | ||
32 | + var comment_form = $('.artbox_comment_form').first(); | ||
33 | + var offset = $(comment_form).offset(); | ||
34 | + var reply_block = $(comment_form).find('.artbox_comment_reply_block').first(); | ||
35 | + $(reply_block).empty(); | ||
36 | + $(reply_block).append('<input type="hidden" name="'+form_name+'[comment_pid]" value="'+comment_id+'">'); | ||
37 | + $(reply_block).append('<p class="artbox_comment_reply_author">'+author+'</p>'); | ||
38 | + $('html, body').animate({ | ||
39 | + scrollTop: offset.top - 50, | ||
40 | + }); | ||
41 | + }); | ||
42 | + | ||
43 | + $(document).on('click', '.artbox_comment_reply_author', function() { | ||
44 | + $(this).parents('.artbox_comment_reply_block').first().empty(); | ||
45 | + }); | ||
46 | + | ||
47 | + $(document).on('click', '.artbox_comment_update', function() { | ||
48 | + $(this).removeClass('artbox_comment_update'); | ||
49 | + $(this).text('Сохранить'); | ||
50 | + $(this).addClass('artbox_comment_update_submit'); | ||
51 | + var container = $(this).parents('.artbox_comment_container').first(); | ||
52 | + var comment_id = $(container).data('comment_id'); | ||
53 | + var form_name = $(container).data('form_name'); | ||
54 | + var text = $(container).find('.artbox_comment_text'); | ||
55 | + var object = {}; | ||
56 | + object[form_name] = {comment_id: comment_id}; | ||
57 | + $.post( | ||
58 | + '/artbox-comment/form', | ||
59 | + object, | ||
60 | + function(data, textStatus, jqXHR) { | ||
61 | + $(text).hide(); | ||
62 | + $(text).after( | ||
63 | + '<div class="artbox_comment_text_edit new-portf-answer">' | ||
64 | + + data | ||
65 | + + '</div>' | ||
66 | + ); | ||
67 | + } | ||
68 | + ); | ||
69 | + }); | ||
70 | + | ||
71 | + $(document).on('click', '.artbox_comment_update_reply', function() { | ||
72 | + $(this).remove(); | ||
73 | + }); | ||
74 | + | ||
75 | + $(document).on('click', '.artbox_comment_update_submit', function(e) { | ||
76 | + e.preventDefault(); | ||
77 | + var container = $(this).parents('.artbox_comment_container').first(); | ||
78 | + var edit = $(container).find('.artbox_comment_text_edit').first(); | ||
79 | + $.post( | ||
80 | + '/artbox-comment/update', | ||
81 | + $(edit).find('form').serialize(), | ||
82 | + function(data) { | ||
83 | + if(!data.error) { | ||
84 | + location.reload(true); | ||
85 | + } | ||
86 | + } | ||
87 | + ) | ||
88 | + }); | ||
89 | +}); | ||
0 | \ No newline at end of file | 90 | \ No newline at end of file |
368 Bytes
1 | +<?php | ||
2 | + /** | ||
3 | + * @var \common\modules\comment\models\Comment $model | ||
4 | + */ | ||
5 | + use yii\widgets\ActiveForm; | ||
6 | + | ||
7 | + $form = ActiveForm::begin(); | ||
8 | + | ||
9 | +?> | ||
10 | +<?php | ||
11 | + echo $form->field($model, 'comment_id') | ||
12 | + ->label(false) | ||
13 | + ->hiddenInput(); | ||
14 | + if(!empty( $model->parent )) { | ||
15 | + ?> | ||
16 | + <div class="artbox_comment_update_reply"> | ||
17 | + <?php | ||
18 | + echo "<span>"; | ||
19 | + if(!empty( $model->parent->author )) { | ||
20 | + echo $model->parent->author->firstname . ' ' . $model->parent->author->lastname; | ||
21 | + } else { | ||
22 | + echo $model->parent->user_name; | ||
23 | + } | ||
24 | + echo "</span>"; | ||
25 | + echo $form->field($model, 'comment_pid') | ||
26 | + ->label(false) | ||
27 | + ->hiddenInput(); | ||
28 | + ?> | ||
29 | + </div> | ||
30 | + <?php | ||
31 | + } | ||
32 | + echo $form->field($model, 'text') | ||
33 | + ->label(false) | ||
34 | + ->textarea(); | ||
35 | +?> | ||
36 | +<?php | ||
37 | + $form->end(); | ||
38 | +?> | ||
0 | \ No newline at end of file | 39 | \ No newline at end of file |
common/modules/comment/widgets/CommentWidget.php
@@ -8,9 +8,18 @@ | @@ -8,9 +8,18 @@ | ||
8 | { | 8 | { |
9 | 9 | ||
10 | /** | 10 | /** |
11 | + * @var null|\yii\web\View | ||
12 | + */ | ||
13 | + public $context = NULL; | ||
14 | + | ||
15 | + /** | ||
11 | * @var array Parts of widgets that can be rendered | 16 | * @var array Parts of widgets that can be rendered |
12 | */ | 17 | */ |
13 | - public $parts = []; | 18 | + public $parts = [ ]; |
19 | + | ||
20 | + public $rating_class = NULL; | ||
21 | + | ||
22 | + public $rating_options = [ ]; | ||
14 | 23 | ||
15 | /** | 24 | /** |
16 | * @var string|\common\modules\comment\models\Comment | 25 | * @var string|\common\modules\comment\models\Comment |
@@ -20,7 +29,7 @@ | @@ -20,7 +29,7 @@ | ||
20 | /** | 29 | /** |
21 | * @var array | 30 | * @var array |
22 | */ | 31 | */ |
23 | - public $class_options = []; | 32 | + public $class_options = [ ]; |
24 | 33 | ||
25 | /** | 34 | /** |
26 | * @var bool Wheather to display comment list | 35 | * @var bool Wheather to display comment list |
@@ -28,44 +37,72 @@ | @@ -28,44 +37,72 @@ | ||
28 | public $display_comment_list = true; | 37 | public $display_comment_list = true; |
29 | 38 | ||
30 | /** | 39 | /** |
31 | - * @var bool Wheather to display comment form | 40 | + * @var bool Whether to display comment form |
32 | */ | 41 | */ |
33 | public $display_comment_form = true; | 42 | public $display_comment_form = true; |
34 | 43 | ||
44 | + /** | ||
45 | + * @var bool Whether to display success text | ||
46 | + */ | ||
35 | public $display_comment_success = true; | 47 | public $display_comment_success = true; |
36 | 48 | ||
49 | + /** | ||
50 | + * @var bool Whether to allow one user post multiple comments | ||
51 | + */ | ||
37 | public $allow_multiple = true; | 52 | public $allow_multiple = true; |
38 | 53 | ||
39 | - public $success_text = "Comment posted successfully"; | ||
40 | - | 54 | + /** |
55 | + * @var array Options sent to list part | ||
56 | + */ | ||
41 | public $list_options = [ | 57 | public $list_options = [ |
42 | - 'tag' => 'div', | ||
43 | - 'view' => 'list-comment', | 58 | + 'tag' => 'div', |
59 | + 'view' => 'list-comment', | ||
44 | 'class' => 'test-class', | 60 | 'class' => 'test-class', |
45 | ]; | 61 | ]; |
46 | 62 | ||
63 | + /** | ||
64 | + * @var array Options sent to success part | ||
65 | + */ | ||
47 | public $success_options = [ | 66 | public $success_options = [ |
48 | - 'tag' => 'div', | ||
49 | - 'content' => null, | ||
50 | - 'class' => 'test-class-success', | 67 | + 'tag' => 'div', |
68 | + 'content' => NULL, | ||
69 | + 'class' => 'test-class-success', | ||
51 | ]; | 70 | ]; |
52 | 71 | ||
72 | + /** | ||
73 | + * @var array Options sent to form part | ||
74 | + */ | ||
53 | public $form_options = [ | 75 | public $form_options = [ |
54 | - 'tag' => 'div', | ||
55 | - 'view' => 'form-comment', | 76 | + 'tag' => 'div', |
77 | + 'view' => 'form-comment', | ||
56 | 'class' => 'test-class-form', | 78 | 'class' => 'test-class-form', |
57 | ]; | 79 | ]; |
58 | 80 | ||
81 | + /** | ||
82 | + * @var bool Indicates whether any successful action happened | ||
83 | + */ | ||
59 | protected $isSuccess = false; | 84 | protected $isSuccess = false; |
60 | 85 | ||
86 | + public $success_text = 'Comment successfully added'; | ||
87 | + | ||
88 | + /** | ||
89 | + * @var string Entity, to which comments attached | ||
90 | + */ | ||
61 | public $entity; | 91 | public $entity; |
62 | 92 | ||
93 | + /** | ||
94 | + * @var string Template of the widget. You may use <code>{success}, {form}, {list}</code> | ||
95 | + * to render particular parts. You are also able to use common HTML here. | ||
96 | + */ | ||
63 | public $template = "{success}\n{form}\n{list}"; | 97 | public $template = "{success}\n{form}\n{list}"; |
64 | 98 | ||
65 | - public $options = []; | 99 | + /** |
100 | + * @var array Widget options | ||
101 | + */ | ||
102 | + public $options = [ ]; | ||
66 | 103 | ||
67 | /** | 104 | /** |
68 | - * @var \yii\data\DataProviderInterface | 105 | + * @var \yii\data\DataProviderInterface Data provider of comments |
69 | */ | 106 | */ |
70 | public $dataProvider; | 107 | public $dataProvider; |
71 | 108 | ||
@@ -75,16 +112,20 @@ | @@ -75,16 +112,20 @@ | ||
75 | public function init() | 112 | public function init() |
76 | { | 113 | { |
77 | parent::init(); | 114 | parent::init(); |
115 | + \common\modules\comment\assets\CommentAsset::register($this->view); | ||
78 | if(is_string($this->comment_class)) { | 116 | if(is_string($this->comment_class)) { |
79 | $this->comment_class = new $this->comment_class($this->class_options); | 117 | $this->comment_class = new $this->comment_class($this->class_options); |
80 | - } elseif(!is_object($this->comment_class)) { | ||
81 | - throw new \yii\base\InvalidConfigException(__CLASS__.'->comment_class must be defined as string or object.'); | 118 | + } else { |
119 | + throw new \yii\base\InvalidConfigException(__CLASS__ . '->comment_class must be defined as object full class name string.'); | ||
120 | + } | ||
121 | + if(!empty( $this->rating_class ) && is_string($this->rating_class)) { | ||
122 | + $this->rating_class = new $this->rating_class($this->rating_options); | ||
123 | + } elseif(!empty( $this->rating_class )) { | ||
124 | + throw new \yii\base\InvalidConfigException(__CLASS__ . '->rating_class must be defined as object full class name string.'); | ||
82 | } | 125 | } |
83 | $this->comment_class->entity = $this->entity; | 126 | $this->comment_class->entity = $this->entity; |
84 | $this->createDataProvider(); | 127 | $this->createDataProvider(); |
85 | - if($this->comment_class->checkCreate($this->entity)) { | ||
86 | - $this->handleCreate(); | ||
87 | - } | 128 | + $this->process(); |
88 | ob_start(); | 129 | ob_start(); |
89 | } | 130 | } |
90 | 131 | ||
@@ -99,62 +140,67 @@ | @@ -99,62 +140,67 @@ | ||
99 | return $this->renderWidget(); | 140 | return $this->renderWidget(); |
100 | } | 141 | } |
101 | 142 | ||
102 | - public function createParts() { | 143 | + public function createParts() |
144 | + { | ||
103 | if($this->display_comment_success && $this->isSuccess) { | 145 | if($this->display_comment_success && $this->isSuccess) { |
104 | $tag = ArrayHelper::remove($this->success_options, 'tag', 'div'); | 146 | $tag = ArrayHelper::remove($this->success_options, 'tag', 'div'); |
105 | - if(is_callable($this->success_options['content'])) { | 147 | + if(is_callable($this->success_options[ 'content' ])) { |
106 | $result = call_user_func(ArrayHelper::remove($this->success_options, 'content'), $this->success_text); | 148 | $result = call_user_func(ArrayHelper::remove($this->success_options, 'content'), $this->success_text); |
107 | - } elseif($this->success_options['content'] != NULL) { | 149 | + } elseif($this->success_options[ 'content' ] != NULL) { |
108 | $result = Html::encode(ArrayHelper::remove($this->success_options, 'content', $this->success_text)); | 150 | $result = Html::encode(ArrayHelper::remove($this->success_options, 'content', $this->success_text)); |
109 | } else { | 151 | } else { |
110 | $result = Html::encode($this->success_text); | 152 | $result = Html::encode($this->success_text); |
111 | } | 153 | } |
112 | - $this->parts['success'] = Html::tag($tag, $result, $this->success_options); | ||
113 | - unset($tag, $result); | 154 | + $this->parts[ 'success' ] = Html::tag($tag, $result, $this->success_options); |
155 | + unset( $tag, $result ); | ||
114 | } | 156 | } |
115 | 157 | ||
116 | if($this->display_comment_list) { | 158 | if($this->display_comment_list) { |
117 | $tag = ArrayHelper::remove($this->list_options, 'tag', 'div'); | 159 | $tag = ArrayHelper::remove($this->list_options, 'tag', 'div'); |
118 | $view = ArrayHelper::remove($this->list_options, 'view'); | 160 | $view = ArrayHelper::remove($this->list_options, 'view'); |
119 | - $this->parts['list'] = Html::tag($tag, $this->renderItems($view), $this->list_options); | 161 | + $this->parts[ 'list' ] = Html::tag($tag, $this->renderItems($view), $this->list_options); |
120 | } | 162 | } |
121 | 163 | ||
122 | if($this->display_comment_form) { | 164 | if($this->display_comment_form) { |
123 | $tag = ArrayHelper::remove($this->form_options, 'tag', 'div'); | 165 | $tag = ArrayHelper::remove($this->form_options, 'tag', 'div'); |
124 | $view = ArrayHelper::remove($this->form_options, 'view'); | 166 | $view = ArrayHelper::remove($this->form_options, 'view'); |
125 | - $this->parts['form'] = Html::tag($tag, $this->renderForm($view), $this->list_options); | 167 | + $this->parts[ 'form' ] = Html::tag($tag, $this->renderForm($view), $this->form_options); |
126 | } | 168 | } |
127 | } | 169 | } |
128 | 170 | ||
129 | public function createDataProvider() | 171 | public function createDataProvider() |
130 | { | 172 | { |
131 | $this->dataProvider = new \yii\data\ActiveDataProvider([ | 173 | $this->dataProvider = new \yii\data\ActiveDataProvider([ |
132 | - 'query' => $this->comment_class->getComments($this->entity), | 174 | + 'query' => $this->comment_class->getComments($this->entity), |
133 | 'pagination' => [ | 175 | 'pagination' => [ |
134 | 'pageSize' => 10, | 176 | 'pageSize' => 10, |
135 | ], | 177 | ], |
136 | ]); | 178 | ]); |
137 | } | 179 | } |
138 | 180 | ||
139 | - public function renderItems($view) { | ||
140 | - if(empty($view)) { | 181 | + public function renderItems($view) |
182 | + { | ||
183 | + if(empty( $view )) { | ||
141 | throw new \yii\base\InvalidConfigException("list_options[view] must be set"); | 184 | throw new \yii\base\InvalidConfigException("list_options[view] must be set"); |
142 | } | 185 | } |
143 | - return $this->render($view, ['dataProvider' => $this->dataProvider]); | 186 | + return $this->render($view, [ 'dataProvider' => $this->dataProvider ]); |
144 | } | 187 | } |
145 | 188 | ||
146 | - public function renderForm($view) { | ||
147 | - if(empty($view)) { | 189 | + public function renderForm($view) |
190 | + { | ||
191 | + if(empty( $view )) { | ||
148 | throw new \yii\base\InvalidConfigException("form_options[view] must be set"); | 192 | throw new \yii\base\InvalidConfigException("form_options[view] must be set"); |
149 | } | 193 | } |
150 | return $this->render($view, [ | 194 | return $this->render($view, [ |
151 | - 'model' => $this->comment_class, | ||
152 | - 'user' => \Yii::$app->user->identity, | 195 | + 'model' => $this->comment_class, |
196 | + 'rating' => $this->rating_class, | ||
197 | + 'user' => \Yii::$app->user->identity, | ||
153 | 'dataProvider' => $this->dataProvider, | 198 | 'dataProvider' => $this->dataProvider, |
154 | ]); | 199 | ]); |
155 | } | 200 | } |
156 | 201 | ||
157 | - public function renderWidget() { | 202 | + public function renderWidget() |
203 | + { | ||
158 | $template = $this->template; | 204 | $template = $this->template; |
159 | $parts = $this->parts; | 205 | $parts = $this->parts; |
160 | $options = $this->options; | 206 | $options = $this->options; |
@@ -165,11 +211,13 @@ | @@ -165,11 +211,13 @@ | ||
165 | return Html::tag($tag, $template, $options); | 211 | return Html::tag($tag, $template, $options); |
166 | } | 212 | } |
167 | 213 | ||
168 | - public function handleCreate() | 214 | + public function process() |
169 | { | 215 | { |
170 | $data = \Yii::$app->request->post(); | 216 | $data = \Yii::$app->request->post(); |
171 | - if($this->comment_class->postComment($data)) { | ||
172 | - $this->isSuccess = true; | ||
173 | - }; | 217 | + if($this->comment_class->load($data) && $this->comment_class->postComment()) { |
218 | + if(is_object($this->rating_class) && $this->comment_class->rating->load($data) && $this->comment_class->rating->save()) { | ||
219 | + $this->isSuccess = true; | ||
220 | + } | ||
221 | + } | ||
174 | } | 222 | } |
175 | } | 223 | } |
176 | \ No newline at end of file | 224 | \ No newline at end of file |
common/modules/comment/widgets/views/form-comment.php
1 | <?php | 1 | <?php |
2 | /** | 2 | /** |
3 | - * @var \common\modules\comment\models\Comment $model | ||
4 | - * @var \common\models\User $user | ||
5 | - * @var \yii\data\ActiveDataProvider $dataProvider | 3 | + * @var \common\modules\comment\models\Comment $model |
4 | + * @var \common\models\User $user | ||
5 | + * @var \yii\data\ActiveDataProvider $dataProvider | ||
6 | + * @var null|\common\modules\comment\models\Rating $rating | ||
6 | */ | 7 | */ |
7 | use yii\widgets\ActiveForm; | 8 | use yii\widgets\ActiveForm; |
8 | use yii\helpers\Html; | 9 | use yii\helpers\Html; |
@@ -11,42 +12,59 @@ | @@ -11,42 +12,59 @@ | ||
11 | <div class="new-portf-comm-count">Комментарии: <?= $dataProvider->totalCount ?></div> | 12 | <div class="new-portf-comm-count">Комментарии: <?= $dataProvider->totalCount ?></div> |
12 | 13 | ||
13 | <div class="new-portf-add-comm style"> | 14 | <div class="new-portf-add-comm style"> |
15 | + | ||
14 | <?php | 16 | <?php |
15 | $form = ActiveForm::begin(); | 17 | $form = ActiveForm::begin(); |
16 | - ?> | ||
17 | 18 | ||
18 | - <?php | 19 | + echo $form->field($rating, 'value') |
20 | + ->label(false) | ||
21 | + ->radioList([ | ||
22 | + 1 => 1, | ||
23 | + 2 => 2, | ||
24 | + 3 => 3, | ||
25 | + 4 => 4, | ||
26 | + 5 => 5, | ||
27 | + ]); | ||
28 | + | ||
19 | if($model->scenario == $model::SCENARIO_GUEST) { | 29 | if($model->scenario == $model::SCENARIO_GUEST) { |
20 | echo $form->field($model, 'user_name', [ | 30 | echo $form->field($model, 'user_name', [ |
21 | - 'options' => [ | 31 | + 'options' => [ |
22 | 'class' => 'input-blocks-comm', | 32 | 'class' => 'input-blocks-comm', |
23 | ], | 33 | ], |
24 | 'inputOptions' => [ | 34 | 'inputOptions' => [ |
25 | 'class' => 'custom-input-4', | 35 | 'class' => 'custom-input-4', |
26 | ], | 36 | ], |
27 | - ])->textInput(); | 37 | + ]) |
38 | + ->textInput(); | ||
28 | echo $form->field($model, 'user_email', [ | 39 | echo $form->field($model, 'user_email', [ |
29 | - 'options' => [ | 40 | + 'options' => [ |
30 | 'class' => 'input-blocks-comm', | 41 | 'class' => 'input-blocks-comm', |
31 | ], | 42 | ], |
32 | 'inputOptions' => [ | 43 | 'inputOptions' => [ |
33 | 'class' => 'custom-input-4', | 44 | 'class' => 'custom-input-4', |
34 | ], | 45 | ], |
35 | - ])->textInput(); | 46 | + ]) |
47 | + ->textInput(); | ||
36 | } | 48 | } |
49 | + | ||
50 | + ?> | ||
51 | + <div class="artbox_comment_reply_block"></div> | ||
52 | + <?php | ||
53 | + | ||
37 | echo $form->field($model, 'text', [ | 54 | echo $form->field($model, 'text', [ |
38 | - 'options' => [ | 55 | + 'options' => [ |
39 | 'class' => 'input-blocks-comm area-comm', | 56 | 'class' => 'input-blocks-comm area-comm', |
40 | ], | 57 | ], |
41 | 'inputOptions' => [ | 58 | 'inputOptions' => [ |
42 | 'class' => 'custom-area-4', | 59 | 'class' => 'custom-area-4', |
43 | ], | 60 | ], |
44 | - ])->textarea(); | 61 | + ]) |
62 | + ->textarea(); | ||
45 | ?> | 63 | ?> |
46 | - <div class="input-blocks-comm-button style"> | ||
47 | - <?= Html::submitButton('Добавить комментарий') ?> | ||
48 | - </div> | ||
49 | - <?php | 64 | + <div class="input-blocks-comm-button style"> |
65 | + <?= Html::submitButton('Добавить комментарий') ?> | ||
66 | + </div> | ||
67 | + <?php | ||
50 | $form->end(); | 68 | $form->end(); |
51 | ?> | 69 | ?> |
52 | </div> | 70 | </div> |
53 | \ No newline at end of file | 71 | \ No newline at end of file |
common/modules/comment/widgets/views/project_comment_view.php
@@ -3,9 +3,9 @@ | @@ -3,9 +3,9 @@ | ||
3 | use yii\helpers\Html; | 3 | use yii\helpers\Html; |
4 | 4 | ||
5 | /** | 5 | /** |
6 | - * @var \common\modules\comment\models\Comment $model Current comment model | ||
7 | - * @var integer $key ID of current comment | ||
8 | - * @var integer $index index of current element according to | 6 | + * @var \common\modules\comment\models\Comment $model Current comment model |
7 | + * @var integer $key ID of current comment | ||
8 | + * @var integer $index index of current element according to | ||
9 | * current page, starting from 0 | 9 | * current page, starting from 0 |
10 | * @var \yii\widgets\ListView $widget current ListView instance | 10 | * @var \yii\widgets\ListView $widget current ListView instance |
11 | * @var User $user | 11 | * @var User $user |
@@ -18,7 +18,7 @@ | @@ -18,7 +18,7 @@ | ||
18 | ->one(); | 18 | ->one(); |
19 | } | 19 | } |
20 | ?> | 20 | ?> |
21 | -<div class="new-portf-comm-read"> | 21 | +<div class="new-portf-comm-read artbox_comment_container" data-comment_id="<?= $model->comment_id ?>" data-form_name="<?= $model->formName() ?>"> |
22 | <div class="style"> | 22 | <div class="style"> |
23 | <div class="header-cabinet-foto"> | 23 | <div class="header-cabinet-foto"> |
24 | <?php | 24 | <?php |
@@ -32,23 +32,29 @@ | @@ -32,23 +32,29 @@ | ||
32 | <div class="new-prof-wrapper-read"> | 32 | <div class="new-prof-wrapper-read"> |
33 | <div class="new-portf-comm-read-title"> | 33 | <div class="new-portf-comm-read-title"> |
34 | <?php | 34 | <?php |
35 | - if(!empty($user)) { | ||
36 | - echo Html::a($user->firstname . ' ' . $user->lastname, [ | ||
37 | - 'performer/common', | ||
38 | - 'performer_id' => $user->id, | ||
39 | - ]); | ||
40 | - } else { | ||
41 | - echo $model->user_name . '(Гость)'; | ||
42 | - } | 35 | + if(!empty( $user )) { |
36 | + echo Html::a('<span class="artbox_comment_author">' . $user->firstname . ' ' . $user->lastname . '</span>', [ | ||
37 | + 'performer/common', | ||
38 | + 'performer_id' => $user->id, | ||
39 | + ]); | ||
40 | + } else { | ||
41 | + echo '<span class="artbox_comment_author">' . $model->user_name . '</span>' . '(Гость)'; | ||
42 | + } | ||
43 | ?> | 43 | ?> |
44 | </div> | 44 | </div> |
45 | <div class="new-portf-comm-read-rating"> | 45 | <div class="new-portf-comm-read-rating"> |
46 | - <div class="rating"> | ||
47 | - <!--оценка--> | ||
48 | - <input type="hidden" class="val" value="3"/> | ||
49 | - <!--количество голосов--> | ||
50 | - <input type="hidden" class="votes" value="12"/> | ||
51 | - </div> | 46 | + <?php |
47 | + if($rating = $model->hasRating()) { | ||
48 | + ?> | ||
49 | + <div class="rating"> | ||
50 | + <!--оценка--> | ||
51 | + <input type="hidden" class="val" value="<?= $rating->value ?>"/> | ||
52 | + <!--количество голосов--> | ||
53 | + <input type="hidden" class="votes" value="1"/> | ||
54 | + </div> | ||
55 | + <?php | ||
56 | + } | ||
57 | + ?> | ||
52 | </div> | 58 | </div> |
53 | <div class="blog-post-date"> | 59 | <div class="blog-post-date"> |
54 | <span></span> | 60 | <span></span> |
@@ -56,10 +62,23 @@ | @@ -56,10 +62,23 @@ | ||
56 | </div> | 62 | </div> |
57 | </div> | 63 | </div> |
58 | 64 | ||
59 | - <div class="new-portf-answer"> | 65 | + <div class="new-portf-answer artbox_comment_text"> |
60 | <?= Html::encode($model->text) ?> | 66 | <?= Html::encode($model->text) ?> |
61 | </div> | 67 | </div> |
62 | - | 68 | + <div style="clear:both"></div> |
69 | + <?php | ||
70 | + /* | ||
71 | + ?> | ||
72 | + <div class="action_panel"> | ||
73 | + <ul> | ||
74 | + <li style="display:inline-block" class="artbox_comment_reply">Ответить</li> | ||
75 | + <li style="display:inline-block" class="artbox_comment_update">Редактировать</li> | ||
76 | + <li style="display:inline-block" class="artbox_comment_delete">Удалить</li> | ||
77 | + </ul> | ||
78 | + </div> | ||
79 | + <?php | ||
80 | + */ | ||
81 | + ?> | ||
63 | </div> | 82 | </div> |
64 | <div class="style"></div> | 83 | <div class="style"></div> |
65 | </div> | 84 | </div> |
66 | \ No newline at end of file | 85 | \ No newline at end of file |
1 | +<?php | ||
2 | + | ||
3 | +use yii\db\Migration; | ||
4 | + | ||
5 | +class m160304_081817_rating_table extends Migration | ||
6 | +{ | ||
7 | + public function up() | ||
8 | + { | ||
9 | + $this->createTable('{{%rating}}', [ | ||
10 | + 'rating_id' => $this->primaryKey(), | ||
11 | + 'date_add' => $this->timestamp()->notNull()->defaultExpression('NOW()'), | ||
12 | + 'date_update' => $this->timestamp()->notNull()->defaultExpression('NOW()'), | ||
13 | + 'user_id' => $this->integer(), | ||
14 | + 'entity' => $this->string(), | ||
15 | + 'value' => $this->integer(), | ||
16 | + ]); | ||
17 | + | ||
18 | + $this->addForeignKey('rating_user', '{{%rating}}', 'user_id', '{{%user}}', 'id', 'CASCADE', 'CASCADE'); | ||
19 | + } | ||
20 | + | ||
21 | + public function down() | ||
22 | + { | ||
23 | + $this->dropForeignKey('rating_user', '{{%rating}}'); | ||
24 | + $this->dropTable('{{%rating}}'); | ||
25 | + } | ||
26 | + | ||
27 | +} |
frontend/views/performer/portfolio-view.php
@@ -2,13 +2,15 @@ | @@ -2,13 +2,15 @@ | ||
2 | 2 | ||
3 | use common\models\Portfolio; | 3 | use common\models\Portfolio; |
4 | use common\models\User; | 4 | use common\models\User; |
5 | -use yii\helpers\Html; | ||
6 | -use yii\web\ViewAction; | 5 | + use yii\helpers\Html; |
6 | + use yii\web\ViewAction; | ||
7 | + use yii\web\View; | ||
7 | 8 | ||
8 | /** | 9 | /** |
9 | * @var ViewAction $this | 10 | * @var ViewAction $this |
10 | * @var User $user | 11 | * @var User $user |
11 | * @var Portfolio $portfolio | 12 | * @var Portfolio $portfolio |
13 | + * @var View $this | ||
12 | */ | 14 | */ |
13 | $this->params[ 'user' ] = $user; | 15 | $this->params[ 'user' ] = $user; |
14 | 16 | ||
@@ -16,7 +18,7 @@ use yii\web\ViewAction; | @@ -16,7 +18,7 @@ use yii\web\ViewAction; | ||
16 | ?> | 18 | ?> |
17 | <div class="portfolio-new-page-wrapper style"> | 19 | <div class="portfolio-new-page-wrapper style"> |
18 | <div class="new-portfolio-bg style "> | 20 | <div class="new-portfolio-bg style "> |
19 | - <?= Html::img($portfolio->minImg($portfolio->cover,'720', '280')) ?> | 21 | + <?= Html::img($portfolio->minImg($portfolio->cover, '720', '280')) ?> |
20 | </div> | 22 | </div> |
21 | <div class="new-portfolio-icons-rating-wr style"> | 23 | <div class="new-portfolio-icons-rating-wr style"> |
22 | <div class="new-portfolio-icons"> | 24 | <div class="new-portfolio-icons"> |
@@ -40,7 +42,7 @@ use yii\web\ViewAction; | @@ -40,7 +42,7 @@ use yii\web\ViewAction; | ||
40 | <div class="portfolio-project-views-img"> | 42 | <div class="portfolio-project-views-img"> |
41 | <img src="/images/portfolio-project/ico-3.png"></div> | 43 | <img src="/images/portfolio-project/ico-3.png"></div> |
42 | </div> | 44 | </div> |
43 | - <div class="portfolio-project-views-txt">XX</div> | 45 | + <div class="portfolio-project-views-txt"></div> |
44 | </div> | 46 | </div> |
45 | </div> | 47 | </div> |
46 | </div> | 48 | </div> |
@@ -109,209 +111,213 @@ use yii\web\ViewAction; | @@ -109,209 +111,213 @@ use yii\web\ViewAction; | ||
109 | } | 111 | } |
110 | ?> | 112 | ?> |
111 | </div> | 113 | </div> |
112 | - | ||
113 | <?php | 114 | <?php |
114 | echo \common\modules\comment\widgets\CommentWidget::widget([ | 115 | echo \common\modules\comment\widgets\CommentWidget::widget([ |
115 | - 'entity' => $portfolio::tableName().'-'.$portfolio->portfolio_id, | 116 | + 'context' => $this, |
117 | + 'entity' => $portfolio::tableName() . '-' . $portfolio->portfolio_id, | ||
116 | 'comment_class' => \common\modules\comment\models\Comment::className(), | 118 | 'comment_class' => \common\modules\comment\models\Comment::className(), |
119 | + 'rating_class' => \common\modules\comment\models\Rating::className(), | ||
117 | 'class_options' => [ | 120 | 'class_options' => [ |
118 | - 'scenario' => is_int(\Yii::$app->user->getId())?\common\modules\comment\models\Comment::SCENARIO_USER:\common\modules\comment\models\Comment::SCENARIO_GUEST, | ||
119 | - 'user_id' => \Yii::$app->user->getId(), | 121 | + 'scenario' => is_int(\Yii::$app->user->getId()) ? \common\modules\comment\models\Comment::SCENARIO_USER : \common\modules\comment\models\Comment::SCENARIO_GUEST, |
122 | + 'user_id' => \Yii::$app->user->getId(), | ||
123 | + 'guestComment' => true, | ||
124 | + 'status' => \common\modules\comment\models\Comment::STATUS_ACTIVE, | ||
120 | ], | 125 | ], |
121 | - 'list_options' => [ | 126 | + 'list_options' => [ |
122 | 'view' => 'list-comment', | 127 | 'view' => 'list-comment', |
123 | ], | 128 | ], |
124 | - 'form_options' => [ | 129 | + 'form_options' => [ |
125 | 'view' => 'form-comment', | 130 | 'view' => 'form-comment', |
126 | - 'tag' => false, | 131 | + 'tag' => 'div', |
132 | + 'class' => 'artbox_comment_form', | ||
127 | ], | 133 | ], |
128 | - 'options' => [ | 134 | + 'options' => [ |
129 | 'class' => 'new-portf-comments-wr style', | 135 | 'class' => 'new-portf-comments-wr style', |
130 | ], | 136 | ], |
131 | ]); | 137 | ]); |
132 | ?> | 138 | ?> |
133 | 139 | ||
134 | <?php | 140 | <?php |
135 | - /* | ||
136 | - ?> | ||
137 | - <div class="new-portf-comments-wr style"> | ||
138 | - <div class="new-portf-comm-count">Комментарии: 3</div> | ||
139 | - <div class="new-portf-add-comm style"> | 141 | + /* |
142 | + ?> | ||
143 | + <div class="new-portf-comments-wr style"> | ||
144 | + <div class="new-portf-comm-count">Комментарии: 3</div> | ||
145 | + <div class="new-portf-add-comm style"> | ||
140 | 146 | ||
141 | - <form action=""> | ||
142 | - <div class="input-blocks-comm"> | ||
143 | - <label for="input-txt-5">Имя</label> | ||
144 | - <input class="custom-input-4" id="input-txt-5" type="text"> | ||
145 | - </div> | ||
146 | - <div class="input-blocks-comm"> | 147 | + <form action=""> |
148 | + <div class="input-blocks-comm"> | ||
149 | + <label for="input-txt-5">Имя</label> | ||
150 | + <input class="custom-input-4" id="input-txt-5" type="text"> | ||
151 | + </div> | ||
152 | + <div class="input-blocks-comm"> | ||
147 | 153 | ||
148 | - <label for="input-txt-6">e-mail</label> | ||
149 | - <input class="custom-input-4" id="input-txt-6" type="text"> | ||
150 | - </div> | ||
151 | - <div class="input-blocks-comm area-comm"> | ||
152 | - <label for="input-txt-7">Комментарий</label> | ||
153 | - <textarea class="custom-area-4" id="input-txt-7"></textarea> | ||
154 | - </div> | ||
155 | - <div class="input-blocks-comm-button style"> | ||
156 | - <button type="submit" class="">Добавить комментраий</button> | ||
157 | - </div> | ||
158 | - </form> | 154 | + <label for="input-txt-6">e-mail</label> |
155 | + <input class="custom-input-4" id="input-txt-6" type="text"> | ||
156 | + </div> | ||
157 | + <div class="input-blocks-comm area-comm"> | ||
158 | + <label for="input-txt-7">Комментарий</label> | ||
159 | + <textarea class="custom-area-4" id="input-txt-7"></textarea> | ||
160 | + </div> | ||
161 | + <div class="input-blocks-comm-button style"> | ||
162 | + <button type="submit" class="">Добавить комментраий</button> | ||
163 | + </div> | ||
164 | + </form> | ||
159 | 165 | ||
160 | - </div> | 166 | + </div> |
161 | 167 | ||
162 | - <div class="new-portf-comm-read-wr style"> | ||
163 | - <div class="new-portf-comm-read"> | ||
164 | - <div class="style"> | ||
165 | - <div class="header-cabinet-foto"> | ||
166 | - <img src="/images/ded-ico.png" alt=""> | ||
167 | - </div> | ||
168 | - <div class="new-prof-wrapper-read"> | ||
169 | - <div class="new-portf-comm-read-title"><a href="#">Петер Цумтор</a></div> | ||
170 | - <div class="new-portf-comm-read-rating"> | ||
171 | - <div class="rating"> | ||
172 | - <!--оценка--> | ||
173 | - <input type="hidden" class="val" value="3"/> | ||
174 | - <!--количество голосов--> | ||
175 | - <input type="hidden" class="votes" value="12"/> | 168 | + <div class="new-portf-comm-read-wr style"> |
169 | + <div class="new-portf-comm-read"> | ||
170 | + <div class="style"> | ||
171 | + <div class="header-cabinet-foto"> | ||
172 | + <img src="/images/ded-ico.png" alt=""> | ||
173 | + </div> | ||
174 | + <div class="new-prof-wrapper-read"> | ||
175 | + <div class="new-portf-comm-read-title"><a href="#">Петер Цумтор</a></div> | ||
176 | + <div class="new-portf-comm-read-rating"> | ||
177 | + <div class="rating"> | ||
178 | + <!--оценка--> | ||
179 | + <input type="hidden" class="val" value="3"/> | ||
180 | + <!--количество голосов--> | ||
181 | + <input type="hidden" class="votes" value="12"/> | ||
182 | + </div> | ||
183 | + </div> | ||
184 | + <div class="blog-post-date"> | ||
185 | + <span></span> | ||
186 | + <p>22.09.2015</p> | ||
176 | </div> | 187 | </div> |
177 | </div> | 188 | </div> |
178 | - <div class="blog-post-date"> | ||
179 | - <span></span> | ||
180 | - <p>22.09.2015</p> | 189 | + |
190 | + <div class="new-portf-answer"> | ||
191 | + <p>Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p> | ||
192 | + <p>Евровагонка — удобная в монтаже фасонная доска, которая позволяет создать обшивку из плотно пригнанных элементов с качественно обработанной поверхностью. Толщина евровагонки составляет 125 мм, общая ширина (с гребнем) 960 мм, рабочая ширина 880 мм.Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p> | ||
181 | </div> | 193 | </div> |
182 | - </div> | ||
183 | 194 | ||
184 | - <div class="new-portf-answer"> | ||
185 | - <p>Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p> | ||
186 | - <p>Евровагонка — удобная в монтаже фасонная доска, которая позволяет создать обшивку из плотно пригнанных элементов с качественно обработанной поверхностью. Толщина евровагонки составляет 125 мм, общая ширина (с гребнем) 960 мм, рабочая ширина 880 мм.Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p> | ||
187 | </div> | 195 | </div> |
188 | - | 196 | + <div class="style"></div> |
189 | </div> | 197 | </div> |
190 | - <div class="style"></div> | ||
191 | - </div> | ||
192 | 198 | ||
193 | - <div class="new-portf-comm-read"> | ||
194 | - <div class="style"> | ||
195 | - <div class="header-cabinet-foto"> | ||
196 | - <img src="/images/ded-ico.png" alt=""> | ||
197 | - </div> | ||
198 | - <div class="new-prof-wrapper-read"> | ||
199 | - <div class="new-portf-comm-read-title"><a href="#">Петер Цумтор</a></div> | ||
200 | - <div class="new-portf-comm-read-rating"> | ||
201 | - <div class="rating"> | ||
202 | - <!--оценка--> | ||
203 | - <input type="hidden" class="val" value="4"/> | ||
204 | - <!--количество голосов--> | ||
205 | - <input type="hidden" class="votes" value="12"/> | 199 | + <div class="new-portf-comm-read"> |
200 | + <div class="style"> | ||
201 | + <div class="header-cabinet-foto"> | ||
202 | + <img src="/images/ded-ico.png" alt=""> | ||
203 | + </div> | ||
204 | + <div class="new-prof-wrapper-read"> | ||
205 | + <div class="new-portf-comm-read-title"><a href="#">Петер Цумтор</a></div> | ||
206 | + <div class="new-portf-comm-read-rating"> | ||
207 | + <div class="rating"> | ||
208 | + <!--оценка--> | ||
209 | + <input type="hidden" class="val" value="4"/> | ||
210 | + <!--количество голосов--> | ||
211 | + <input type="hidden" class="votes" value="12"/> | ||
212 | + </div> | ||
213 | + </div> | ||
214 | + <div class="blog-post-date"> | ||
215 | + <span></span> | ||
216 | + <p>22.09.2015</p> | ||
206 | </div> | 217 | </div> |
207 | </div> | 218 | </div> |
208 | - <div class="blog-post-date"> | ||
209 | - <span></span> | ||
210 | - <p>22.09.2015</p> | 219 | + |
220 | + <div class="new-portf-answer"> | ||
221 | + <p>Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p> | ||
222 | + <p>Евровагонка — удобная в монтаже фасонная доска, которая позволяет создать обшивку из плотно пригнанных элементов с качественно обработанной поверхностью. Толщина евровагонки составляет 125 мм, общая ширина (с гребнем) 960 мм, рабочая ширина 880 мм.Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p> | ||
211 | </div> | 223 | </div> |
212 | - </div> | ||
213 | 224 | ||
214 | - <div class="new-portf-answer"> | ||
215 | - <p>Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p> | ||
216 | - <p>Евровагонка — удобная в монтаже фасонная доска, которая позволяет создать обшивку из плотно пригнанных элементов с качественно обработанной поверхностью. Толщина евровагонки составляет 125 мм, общая ширина (с гребнем) 960 мм, рабочая ширина 880 мм.Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p> | ||
217 | </div> | 225 | </div> |
218 | - | 226 | + <div class="style"></div> |
219 | </div> | 227 | </div> |
220 | - <div class="style"></div> | ||
221 | - </div> | ||
222 | 228 | ||
223 | - <div class="new-portf-comm-read"> | ||
224 | - <div class="style"> | ||
225 | - <div class="header-cabinet-foto"> | ||
226 | - <img src="/images/ded-ico.png" alt=""> | ||
227 | - </div> | ||
228 | - <div class="new-prof-wrapper-read"> | ||
229 | - <div class="new-portf-comm-read-title"><a href="#">Петер Цумтор</a></div> | ||
230 | - <div class="new-portf-comm-read-rating"> | ||
231 | - <div class="rating"> | ||
232 | - <!--оценка--> | ||
233 | - <input type="hidden" class="val" value="5"/> | ||
234 | - <!--количество голосов--> | ||
235 | - <input type="hidden" class="votes" value="12"/> | 229 | + <div class="new-portf-comm-read"> |
230 | + <div class="style"> | ||
231 | + <div class="header-cabinet-foto"> | ||
232 | + <img src="/images/ded-ico.png" alt=""> | ||
233 | + </div> | ||
234 | + <div class="new-prof-wrapper-read"> | ||
235 | + <div class="new-portf-comm-read-title"><a href="#">Петер Цумтор</a></div> | ||
236 | + <div class="new-portf-comm-read-rating"> | ||
237 | + <div class="rating"> | ||
238 | + <!--оценка--> | ||
239 | + <input type="hidden" class="val" value="5"/> | ||
240 | + <!--количество голосов--> | ||
241 | + <input type="hidden" class="votes" value="12"/> | ||
242 | + </div> | ||
243 | + </div> | ||
244 | + <div class="blog-post-date"> | ||
245 | + <span></span> | ||
246 | + <p>22.09.2015</p> | ||
236 | </div> | 247 | </div> |
237 | </div> | 248 | </div> |
238 | - <div class="blog-post-date"> | ||
239 | - <span></span> | ||
240 | - <p>22.09.2015</p> | 249 | + |
250 | + <div class="new-portf-answer"> | ||
251 | + <p>Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p> | ||
252 | + <p>Евровагонка — удобная в монтаже фасонная доска, которая позволяет создать обшивку из плотно пригнанных элементов с качественно обработанной поверхностью. Толщина евровагонки составляет 125 мм, общая ширина (с гребнем) 960 мм, рабочая ширина 880 мм.Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p> | ||
241 | </div> | 253 | </div> |
242 | - </div> | ||
243 | 254 | ||
244 | - <div class="new-portf-answer"> | ||
245 | - <p>Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p> | ||
246 | - <p>Евровагонка — удобная в монтаже фасонная доска, которая позволяет создать обшивку из плотно пригнанных элементов с качественно обработанной поверхностью. Толщина евровагонки составляет 125 мм, общая ширина (с гребнем) 960 мм, рабочая ширина 880 мм.Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p> | ||
247 | </div> | 255 | </div> |
248 | - | 256 | + <div class="style"></div> |
249 | </div> | 257 | </div> |
250 | - <div class="style"></div> | ||
251 | - </div> | ||
252 | 258 | ||
253 | - <div class="new-portf-comm-read"> | ||
254 | - <div class="style"> | ||
255 | - <div class="header-cabinet-foto"> | ||
256 | - <img src="/images/ded-ico.png" alt=""> | ||
257 | - </div> | ||
258 | - <div class="new-prof-wrapper-read"> | ||
259 | - <div class="new-portf-comm-read-title"><a href="#">Петер Цумтор</a></div> | ||
260 | - <div class="new-portf-comm-read-rating"> | ||
261 | - <div class="rating"> | ||
262 | - <!--оценка--> | ||
263 | - <input type="hidden" class="val" value="1"/> | ||
264 | - <!--количество голосов--> | ||
265 | - <input type="hidden" class="votes" value="12"/> | 259 | + <div class="new-portf-comm-read"> |
260 | + <div class="style"> | ||
261 | + <div class="header-cabinet-foto"> | ||
262 | + <img src="/images/ded-ico.png" alt=""> | ||
263 | + </div> | ||
264 | + <div class="new-prof-wrapper-read"> | ||
265 | + <div class="new-portf-comm-read-title"><a href="#">Петер Цумтор</a></div> | ||
266 | + <div class="new-portf-comm-read-rating"> | ||
267 | + <div class="rating"> | ||
268 | + <!--оценка--> | ||
269 | + <input type="hidden" class="val" value="1"/> | ||
270 | + <!--количество голосов--> | ||
271 | + <input type="hidden" class="votes" value="12"/> | ||
272 | + </div> | ||
273 | + </div> | ||
274 | + <div class="blog-post-date"> | ||
275 | + <span></span> | ||
276 | + <p>22.09.2015</p> | ||
266 | </div> | 277 | </div> |
267 | </div> | 278 | </div> |
268 | - <div class="blog-post-date"> | ||
269 | - <span></span> | ||
270 | - <p>22.09.2015</p> | 279 | + |
280 | + <div class="new-portf-answer"> | ||
281 | + <p>Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p> | ||
282 | + <p>Евровагонка — удобная в монтаже фасонная доска, которая позволяет создать обшивку из плотно пригнанных элементов с качественно обработанной поверхностью. Толщина евровагонки составляет 125 мм, общая ширина (с гребнем) 960 мм, рабочая ширина 880 мм.Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p> | ||
271 | </div> | 283 | </div> |
272 | - </div> | ||
273 | 284 | ||
274 | - <div class="new-portf-answer"> | ||
275 | - <p>Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p> | ||
276 | - <p>Евровагонка — удобная в монтаже фасонная доска, которая позволяет создать обшивку из плотно пригнанных элементов с качественно обработанной поверхностью. Толщина евровагонки составляет 125 мм, общая ширина (с гребнем) 960 мм, рабочая ширина 880 мм.Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p> | ||
277 | </div> | 285 | </div> |
278 | - | 286 | + <div class="style"></div> |
279 | </div> | 287 | </div> |
280 | - <div class="style"></div> | ||
281 | - </div> | ||
282 | - <div class="new-portf-comm-read"> | ||
283 | - <div class="style"> | ||
284 | - <div class="header-cabinet-foto"> | ||
285 | - <img src="/images/ded-ico.png" alt=""> | ||
286 | - </div> | ||
287 | - <div class="new-prof-wrapper-read"> | ||
288 | - <div class="new-portf-comm-read-title"><a href="#">Петер Цумтор</a></div> | ||
289 | - <div class="new-portf-comm-read-rating"> | ||
290 | - <div class="rating"> | ||
291 | - <!--оценка--> | ||
292 | - <input type="hidden" class="val" value="2"/> | ||
293 | - <!--количество голосов--> | ||
294 | - <input type="hidden" class="votes" value="12"/> | 288 | + <div class="new-portf-comm-read"> |
289 | + <div class="style"> | ||
290 | + <div class="header-cabinet-foto"> | ||
291 | + <img src="/images/ded-ico.png" alt=""> | ||
292 | + </div> | ||
293 | + <div class="new-prof-wrapper-read"> | ||
294 | + <div class="new-portf-comm-read-title"><a href="#">Петер Цумтор</a></div> | ||
295 | + <div class="new-portf-comm-read-rating"> | ||
296 | + <div class="rating"> | ||
297 | + <!--оценка--> | ||
298 | + <input type="hidden" class="val" value="2"/> | ||
299 | + <!--количество голосов--> | ||
300 | + <input type="hidden" class="votes" value="12"/> | ||
301 | + </div> | ||
302 | + </div> | ||
303 | + <div class="blog-post-date"> | ||
304 | + <span></span> | ||
305 | + <p>22.09.2015</p> | ||
295 | </div> | 306 | </div> |
296 | </div> | 307 | </div> |
297 | - <div class="blog-post-date"> | ||
298 | - <span></span> | ||
299 | - <p>22.09.2015</p> | 308 | + |
309 | + <div class="new-portf-answer"> | ||
310 | + <p>Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p> | ||
311 | + <p>Евровагонка — удобная в монтаже фасонная доска, которая позволяет создать обшивку из плотно пригнанных элементов с качественно обработанной поверхностью. Толщина евровагонки составляет 125 мм, общая ширина (с гребнем) 960 мм, рабочая ширина 880 мм.Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p> | ||
300 | </div> | 312 | </div> |
301 | - </div> | ||
302 | 313 | ||
303 | - <div class="new-portf-answer"> | ||
304 | - <p>Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p> | ||
305 | - <p>Евровагонка — удобная в монтаже фасонная доска, которая позволяет создать обшивку из плотно пригнанных элементов с качественно обработанной поверхностью. Толщина евровагонки составляет 125 мм, общая ширина (с гребнем) 960 мм, рабочая ширина 880 мм.Балкон, обшитый вагонкой, выглядит аккуратно, стильно и уютно. Монтаж обшивки вполне возможно выполнить своими силами — достаточно иметь в распоряжении необходимые инструменты и владеть базовыми навыками строительно-ремонтных работ.</p> | ||
306 | </div> | 314 | </div> |
307 | - | 315 | + <div class="style"></div> |
308 | </div> | 316 | </div> |
309 | - <div class="style"></div> | ||
310 | - </div> | ||
311 | 317 | ||
318 | + </div> | ||
312 | </div> | 319 | </div> |
313 | - </div> | ||
314 | - */ | 320 | + */ |
315 | ?> | 321 | ?> |
316 | </div> | 322 | </div> |
317 | <script> | 323 | <script> |