1 | <?php |
||
2 | |||
3 | use Apps\ActiveRecord\ProfileField; |
||
4 | use Ffcms\Core\Helper\Date; |
||
5 | use Ffcms\Core\Helper\Type\Any; |
||
6 | use Ffcms\Core\Helper\Type\Str; |
||
7 | use Ffcms\Templex\Url\Url; |
||
0 ignored issues
–
show
|
|||
8 | |||
9 | /** @var Apps\ActiveRecord\User $user Target user object */ |
||
10 | /** @var Apps\ActiveRecord\User $viewer Viewer user object */ |
||
11 | /** @var Apps\ActiveRecord\WallPost $wallRecords */ |
||
12 | /** @var \Apps\Model\Front\Profile\FormWallPost $wall */ |
||
13 | /** @var array $notify */ |
||
14 | /** @var bool $isSelf */ |
||
15 | /** @var bool $ratingOn */ |
||
16 | /** @var array $pagination */ |
||
17 | /** @var Ffcms\Templex\Template\Template $this */ |
||
18 | |||
19 | // $user is a target profile depended object(not current user!!!) |
||
20 | |||
21 | $name = $user->profile === null ? __('Unknown') : $user->profile->getNickname(); |
||
22 | |||
23 | $this->layout('_layouts/default', [ |
||
24 | 'title' => __('Profile') . ': ' . $name, |
||
25 | 'breadcrumbs' => [ |
||
26 | Url::to('/') => __('Home'), |
||
27 | __('Profile') . ': ' . $name |
||
28 | ] |
||
29 | ]); |
||
30 | |||
31 | ?> |
||
32 | <?php $this->start('body') ?> |
||
33 | <div class="row"> |
||
34 | <div class="col-md-12"> |
||
35 | <h1><?= $name ?> <sup><small>id: <?= $user->id; ?></small></sup></h1> |
||
36 | </div> |
||
37 | </div> |
||
38 | <hr/> |
||
39 | <?php if (\App::$User->isAuth() && $user->inBlacklist($viewer->getId())): ?> |
||
40 | <p class="alert alert-danger"><?= __('You are in blacklist of this user. Your access is limited.') ?></p> |
||
41 | <?php endif; ?> |
||
42 | <div class="row"> |
||
43 | <div class="col-md-4"> |
||
44 | <img src="<?= $user->profile->getAvatarUrl('big') ?>" class="img-fluid img-thumbnail" /> |
||
45 | <?php if ($ratingOn): |
||
46 | $rateClass = 'btn-secondary'; |
||
47 | $rateValue = (int)$user->profile->rating; |
||
48 | if ($user->profile->rating > 0) { |
||
49 | $rateClass = 'btn-info'; |
||
50 | } elseif ($user->profile->rating < 0) { |
||
51 | $rateClass = 'btn-warning'; |
||
52 | } |
||
53 | ?> |
||
54 | <?php if ($isSelf): ?> |
||
55 | <div class="row"> |
||
56 | <div class="col-md-12"> |
||
57 | <button type="button" href="javascript:void(0);" class="btn btn-block <?= $rateClass ?>"> |
||
58 | <?= __('Rating') ?>: <span class="badge"><?= $rateValue ?></span> |
||
59 | </button> |
||
60 | </div> |
||
61 | </div> |
||
62 | <?php else: ?> |
||
63 | <div class="row"> |
||
64 | <div class="col-md-8" style="padding-right: 0;"> |
||
65 | <a href="javascript:void(0);" class="btn btn-block <?= $rateClass ?>"> |
||
66 | <?= __('Rating') ?>: |
||
67 | <span class="badge"><?= $rateValue > 0 ? '+' : null ?> |
||
68 | <span id="ratingValue"><?= $rateValue ?></span> |
||
69 | </span> |
||
70 | </a> |
||
71 | </div> |
||
72 | <div class="col-md-2" style="padding-left: 1px;padding-right: 0;"> |
||
73 | <button id="addRating" class="btn btn-block btn-success">+</button> |
||
74 | </div> |
||
75 | <div class="col-md-2" style="padding-left: 1px; padding-right: 0;"> |
||
76 | <button class="btn btn-block btn-danger" id="reduceRating">-</button> |
||
77 | </div> |
||
78 | </div> |
||
79 | <?php endif; ?> |
||
80 | <?php endif; ?> |
||
81 | <?php |
||
82 | $userMenu = $this->bootstrap()->nav('ul', ['class' => 'nav-tabs flex-column']); |
||
83 | if ($isSelf) { |
||
84 | $userMenu->menu(['link' => ['profile/feed'], 'text' => '<i class="fa fa-rss-square"></i> ' . __('Feed'), 'html' => true]); |
||
85 | $userMenu->menu(['link' => ['profile/avatar'], 'text' => '<i class="fa fa-camera"></i> ' . __('Avatar'), 'html' => true]); |
||
86 | $userMenu->menu(['link' => ['profile/messages'], 'text' => '<i class="fa fa-envelope"></i> ' . __('Messages') . ' <span class="badge pm-count-block">0</span>', 'html' => true]); |
||
87 | $userMenu->menu(['link' => ['profile/settings'], 'text' => '<i class="fa fa-cogs"></i> ' . __('Settings'), 'html' => true]); |
||
88 | } else if(\App::$User->isAuth()) { |
||
89 | $userMenu->menu(['link' => ['profile/messages', null, ['newdialog' => $user->id]], 'text' => __('Write message')]); |
||
90 | $userMenu->menu(['link' => ['profile/ignore', null, ['id' => $user->id]], 'text' => __('Block')]); |
||
91 | } |
||
92 | echo $userMenu->display(); |
||
93 | ?> |
||
94 | </div> |
||
95 | <div class="col-md-8"> |
||
96 | <h2><?= __('Profile data'); ?></h2> |
||
97 | <div class="table-responsive"> |
||
98 | <table class="table table-striped"> |
||
99 | <tr> |
||
100 | <td><?= __('Group') ?></td> |
||
101 | <td><span class="badge badge-secondary" style="background-color: <?= $user->role->color ?>;"><?= $user->role->name ?></span></td> |
||
102 | </tr> |
||
103 | <tr> |
||
104 | <td><?= __('Join date'); ?></td> |
||
105 | <td><?= Date::convertToDatetime($user->created_at, Date::FORMAT_TO_DAY); ?></td> |
||
106 | </tr> |
||
107 | <?php if ($user->profile->birthday !== null && !Str::startsWith('0000-', $user->profile->birthday)): ?> |
||
108 | <tr> |
||
109 | <td><?= __('Birthday'); ?></td> |
||
110 | <td> |
||
111 | <?= Url::a( |
||
112 | ['profile/index', ['born', Date::convertToDatetime($user->profile->birthday, 'Y')]], |
||
113 | Date::convertToDatetime($user->profile->birthday, Date::FORMAT_TO_DAY) |
||
114 | ) ?> |
||
115 | </td> |
||
116 | </tr> |
||
117 | <?php endif; ?> |
||
118 | <?php $sex = $user->profile->sex ?> |
||
119 | <tr> |
||
120 | <td><?= __('Sex'); ?></td> |
||
121 | <td> |
||
122 | <?php |
||
123 | if ($sex == 1) { // could be string(1) "1" or int(1) 1 |
||
124 | echo __('Male'); |
||
125 | } elseif ($sex == 2) { |
||
126 | echo __('Female'); |
||
127 | } else { |
||
128 | echo __('Unknown'); |
||
129 | } |
||
130 | ?> |
||
131 | </td> |
||
132 | </tr> |
||
133 | <?php if (!Str::likeEmpty($user->profile->phone)): ?> |
||
134 | <tr> |
||
135 | <td><?= __('Phone'); ?></td> |
||
136 | <td><?= $user->profile->phone ?></td> |
||
137 | </tr> |
||
138 | <?php endif; ?> |
||
139 | <?php if (!Str::likeEmpty($user->profile->url)): ?> |
||
140 | <tr> |
||
141 | <td><?= __('Website'); ?></td> |
||
142 | <td> |
||
143 | <a rel="nofollow" target="_blank" href="<?= $user->profile->url ?>"><?= __('Visit'); ?></a> |
||
144 | </td> |
||
145 | </tr> |
||
146 | <?php endif; ?> |
||
147 | <?php if (!Str::likeEmpty($user->profile->city)): |
||
148 | $city = trim($user->profile->city); |
||
149 | ?> |
||
150 | <tr> |
||
151 | <td><?= __('City') ?></td> |
||
152 | <td><?= Url::a(['profile/index', ['city', $city]], $city) ?></td> |
||
153 | </tr> |
||
154 | <?php endif; ?> |
||
155 | <?php if (!Str::likeEmpty($user->profile->hobby)): ?> |
||
156 | <tr> |
||
157 | <td><?= __('Interests'); ?></td> |
||
158 | <td> |
||
159 | <?php |
||
160 | $hobbyArray = explode(',', $user->profile->hobby); |
||
161 | foreach ($hobbyArray as $item) { |
||
162 | $item = \App::$Security->strip_tags($item); |
||
163 | if (!Str::likeEmpty($item)) { |
||
164 | echo Url::a(['profile/index', ['hobby', trim($item, ' ')]], $item, ['class' => 'badge badge-secondary']) . ' '; |
||
165 | } |
||
166 | } |
||
167 | ?> |
||
168 | </td> |
||
169 | </tr> |
||
170 | <?php endif; ?> |
||
171 | <?php |
||
172 | $customFields = $user->profile->custom_data; |
||
173 | if ($customFields !== null && Any::isArray($customFields) && count($customFields) > 0): ?> |
||
174 | <?php foreach ($customFields as $cid => $value): ?> |
||
175 | <?php if (!Str::likeEmpty($value)): ?> |
||
176 | <tr> |
||
177 | <td><?= ProfileField::getNameById($cid) ?></td> |
||
178 | <td> |
||
179 | <?php |
||
180 | if (ProfileField::getTypeById($cid) === 'link') { |
||
181 | echo Url::a($value, Str::sub($value, 30)); |
||
182 | } else { |
||
183 | echo \App::$Security->strip_tags($value); |
||
184 | } |
||
185 | ?> |
||
186 | </td> |
||
187 | </tr> |
||
188 | <?php endif; ?> |
||
189 | <?php endforeach; ?> |
||
190 | <?php endif; ?> |
||
191 | </table> |
||
192 | </div> |
||
193 | <h2><?= __('Wall') ?></h2> |
||
194 | <?php if ($wall !== null): ?> |
||
195 | <?php $form = $this->form($wall) ?> |
||
196 | <?= $form->start() ?> |
||
197 | <?= $form->field()->textarea('message', ['class' => 'form-control wysiwyg']) ?> |
||
198 | <input type="submit" name="<?= $wall->getFormName() ?>[submit]" value="<?= __('Send') ?>" class="btn btn-primary" /> |
||
199 | |||
200 | <?php //Ffcms\Widgets\Ckeditor\Ckeditor::widget(['targetClass' => 'wysiwyg', 'config' => 'config-small', 'jsConfig' => ['height' => '80']]); ?> |
||
201 | <?= $form->stop() ?> |
||
202 | <?php endif; ?> |
||
203 | <?php |
||
204 | if ($wallRecords !== null): |
||
205 | foreach ($wallRecords as $post): |
||
206 | /** @var \Apps\ActiveRecord\WallPost $post */ |
||
207 | ?> |
||
208 | <div class="row object-lightborder" id="wall-post-<?= $post->id ?>"> |
||
209 | <div class="col-xs-4 col-md-2"> |
||
210 | <div class="text-center"> |
||
211 | <img class="img-fluid img-rounded" alt="Avatar of <?= $post->senderUser->profile->getNickname() ?>" src="<?= $post->senderUser->profile->getAvatarUrl('small') ?>" /> |
||
212 | </div> |
||
213 | </div> |
||
214 | <div class="col-xs-8 col-md-10"> |
||
215 | <div class="h5" style="margin-top: 0;margin-bottom: 5px;"> |
||
216 | <i class="glyphicon glyphicon-user"></i> |
||
217 | <?= Url::a(['profile/show', [$post->sender_id]], $post->senderUser->profile->getNickname(), ['style' => 'color: ' . $post->senderUser->role->color]) ?> |
||
218 | <small class="float-right"><?= Date::humanize($post->updated_at); ?></small> |
||
219 | </div> |
||
220 | <div class="object-text"> |
||
221 | <?= $post->message ?> |
||
222 | </div> |
||
223 | <hr style="margin: 5px;" /> |
||
224 | <div><i class="fa fa-comment"></i> |
||
225 | <a href="#wall-post-<?= $post->id ?>" id="wall-post-response-<?= $post->id ?>" class="show-wall-response"> |
||
226 | <?= __('Answers') ?> (<span id="wall-post-response-count-<?= $post->id ?>">0</span>) |
||
227 | </a> |
||
228 | <?php if ($post->target_id === $viewer->id || $post->sender_id === $viewer->id): ?> |
||
229 | <?= Url::a(['profile/walldelete', [$post->id]], __('Delete'), ['class' => 'float-right']) ?> |
||
230 | <?php endif; ?> |
||
231 | </div> |
||
232 | <div id="wall-answer-dom-<?= $post->id; ?>" class="d-none"></div> |
||
233 | </div> |
||
234 | </div> |
||
235 | <?php |
||
236 | endforeach; |
||
237 | endif; |
||
238 | ?> |
||
239 | <?= $this->bootstrap()->pagination(['profile/show', [$user->id]], ['class' => 'pagination justify-content-center']) |
||
240 | ->size($pagination['total'], $pagination['page'], $pagination['step']) |
||
241 | ->display() ?> |
||
242 | </div> |
||
243 | </div> |
||
244 | |||
245 | <!-- add answer dom template --> |
||
246 | <div id="add-answer-field" class="d-none"> |
||
247 | <hr style="margin: 5px;"/> |
||
248 | <input type="text" id="make-answer" placeHolder="<?= __('Write comment') ?>" class="form-control wall-answer-text" maxlength="200"/> |
||
249 | <a style="margin-top: 5px;" href="#wall-post" class="send-wall-answer btn btn-primary btn-sm" id="send-wall"> |
||
250 | <?= __('Send') ?> |
||
251 | </a> |
||
252 | <span class="float-right" id="answer-counter">200</span> |
||
253 | </div> |
||
254 | <div id="show-answer-list" class="d-none"> |
||
255 | <div class="row wall-answer"> |
||
256 | <div class="col-md-2 col-xs-4"><img id="wall-answer-avatar" src="<?= \App::$Alias->scriptUrl ?>/upload/user/avatar/small/default.jpg" alt="avatar" class="img-fluid img-rounded avatar" /></div> |
||
257 | <div class="col-md-10 col-xs-8"> |
||
258 | <div class="answer-header"> |
||
259 | <a href="<?= \App::$Alias->baseUrl ?>/profile/index" id="wall-answer-userlink">unknown</a> |
||
260 | <small class="float-right"><span id="wall-answer-date">01.01.1970</span> |
||
261 | <a href="#send-wall-object" class="delete-answer d-none" id="delete-answer"><i class="glyphicon glyphicon-remove"></i></a> |
||
262 | </small> |
||
263 | </div> |
||
264 | <div id="wall-answer-text"></div> |
||
265 | </div> |
||
266 | </div> |
||
267 | </div> |
||
268 | |||
269 | |||
270 | <script> |
||
271 | var hideAnswers = []; |
||
272 | $(document).ready(function () { |
||
273 | var elements = $('.object-lightborder'); |
||
274 | var viewer_id = 0; |
||
275 | var target_id = 0; |
||
276 | var is_self_profile = <?= $isSelf === true ? 'true' : 'false' ?>; |
||
277 | <?php if (\App::$User->isAuth()): ?> |
||
278 | viewer_id = <?= $viewer->getId() ?>; |
||
279 | <?php endif; ?> |
||
280 | target_id = <?= $user->getId() ?>; |
||
281 | var postIds = []; |
||
282 | $.each(elements, function (key, val) { |
||
283 | postIds.push(val.id.replace('wall-post-', '')); |
||
284 | }); |
||
285 | |||
286 | // load answers count via JSON |
||
287 | if (postIds.length > 0) { |
||
288 | $.getJSON(script_url + '/api/profile/wallanswercount/' + postIds.join(',') + '?lang=' + script_lang, function (json) { |
||
289 | // data is successful loaded, lets parse it and set to exist dom elements as text value |
||
290 | if (json.status === 1) { |
||
291 | $.each(json.data, function (key, val) { |
||
292 | $('#wall-post-response-count-' + key).text(val); |
||
293 | }); |
||
294 | } |
||
295 | }); |
||
296 | } |
||
297 | |||
298 | // load answers via JSON and add to current DOM |
||
299 | loadAnswers = function (postId) { |
||
300 | $.getJSON(script_url + '/api/profile/showwallanswers/' + postId + '?lang=' + script_lang, function (json) { |
||
301 | if (json.status !== 1) { |
||
302 | return null; |
||
303 | } |
||
304 | |||
305 | var answerField = $('#add-answer-field').clone(); |
||
306 | var answerDom = $('#show-answer-list').clone(); |
||
307 | answerField.removeAttr('id').removeClass('d-none'); |
||
308 | answerDom.removeAttr('id').removeClass('d-none'); |
||
309 | // add hidden div with wall post object id |
||
310 | answerField.prepend($('<div></div>').attr('id', 'send-wall-object-' + postId)); |
||
311 | // set make answer wall post object id |
||
312 | answerField.find('#make-answer').attr('id', 'make-answer-' + postId); |
||
313 | // build send submit button - set id and href to wall post object anchor |
||
314 | answerField.find('#send-wall').attr('id', 'send-wall-' + postId).attr('href', '#wall-post-' + postId); |
||
315 | // build counter (max chars in input = 200) |
||
316 | answerField.find('#answer-counter').attr('id', 'answer-counter-' + postId); |
||
317 | |||
318 | var addAnswerField = ''; |
||
319 | if (viewer_id > 0) { |
||
320 | addAnswerField = answerField.html(); |
||
321 | } |
||
322 | |||
323 | var answers = ''; |
||
324 | $.each(json.data, function (idx, row) { |
||
325 | // clone general dom element |
||
326 | var dom = answerDom.clone(); |
||
327 | // set avatar src |
||
328 | dom.find('#wall-answer-avatar') |
||
329 | .attr('src', row.user_avatar) |
||
330 | .removeAttr('id'); |
||
331 | // set user link |
||
332 | dom.find('#wall-answer-userlink') |
||
333 | .attr('href', '<?= Url::to('profile/show') ?>/' + row.user_id).text(row.user_nick) |
||
334 | .attr('style', 'color: '+row.user_color) |
||
335 | .removeAttr('id'); |
||
336 | // set date |
||
337 | dom.find('#wall-answer-date').text(row.answer_date).removeAttr('id'); |
||
338 | // set message text |
||
339 | dom.find('#wall-answer-text').text(row.answer_message); |
||
340 | // check if this user can remove answers - answer writer or target user profile |
||
341 | if (is_self_profile || row.user_id === viewer_id) { |
||
342 | dom.find('#delete-answer') |
||
343 | .attr('href', '#send-wall-object-' + postId) |
||
344 | .attr('id', 'delete-answer-' + row.answer_id + '-' + postId) |
||
345 | .removeClass('d-none'); |
||
346 | } |
||
347 | |||
348 | answers += dom.html(); |
||
349 | }); |
||
350 | $('#wall-answer-dom-' + postId).html(addAnswerField + answers); |
||
351 | }) |
||
352 | }; |
||
353 | |||
354 | addAnswer = function (postId, message) { |
||
355 | $.post(script_url + '/api/profile/sendwallanswer/' + postId + '?lang=' + script_lang, {message: message}, function (response) { |
||
356 | if (response.status === 1) { |
||
357 | loadAnswers(postId); |
||
358 | } else { |
||
359 | $('#send-wall-object-' + postId).html('<p class="alert alert-warning"><?= __('Comment send was failed! Try to send it later.') ?></p>'); |
||
360 | } |
||
361 | }, 'json'); |
||
362 | }; |
||
363 | |||
364 | |||
365 | // if clicked on "Answers" - show it and send form |
||
366 | $('.show-wall-response').on('click', function () { |
||
367 | var postId = this.id.replace('wall-post-response-', ''); |
||
368 | // control hide-display on clicking to "Answers" link |
||
369 | if (hideAnswers[postId] === true) { |
||
370 | hideAnswers[postId] = false; |
||
371 | $('#wall-answer-dom-' + postId).addClass('d-none'); |
||
372 | return null; |
||
373 | } else { |
||
374 | hideAnswers[postId] = true; |
||
375 | $('#wall-answer-dom-' + postId).removeClass('d-none'); |
||
376 | } |
||
377 | // load data and set html |
||
378 | loadAnswers(postId); |
||
379 | }); |
||
380 | |||
381 | // calc entered symbols |
||
382 | $(document).on('keyup', '.wall-answer-text', function () { |
||
383 | var postId = this.id.replace('make-answer-', ''); |
||
384 | var msglimit = 200; |
||
385 | var msglength = $(this).val().length; |
||
386 | |||
387 | var limitObject = $('#answer-counter-' + postId); |
||
388 | |||
389 | if (msglength >= msglimit) { |
||
390 | limitObject.html('<span class="badge badge-danger">0</span>'); |
||
391 | } else { |
||
392 | limitObject.text(msglimit - msglength); |
||
393 | } |
||
394 | }); |
||
395 | |||
396 | $(document).on('click', '.delete-answer', function () { |
||
397 | var answerIdPostId = this.id.replace('delete-answer-', '').split('-'); |
||
398 | $.getJSON(script_url + '/api/profile/deleteanswerowner/' + answerIdPostId[0] + '?lang=' + script_lang, function (response) { |
||
399 | loadAnswers(answerIdPostId[1]); |
||
400 | }); |
||
401 | }); |
||
402 | |||
403 | // delegate live event simple for add-ed dom element |
||
404 | $(document).on('click', '.send-wall-answer', function () { |
||
405 | var answerToId = this.id.replace('send-wall-', ''); |
||
406 | var message = $('#make-answer-' + answerToId).val(); |
||
407 | if (message == null || message.length < 3) { |
||
408 | alert('<?= __('Message is too short') ?>'); |
||
409 | return null; |
||
410 | } |
||
411 | |||
412 | addAnswer(answerToId, message); |
||
413 | }); |
||
414 | |||
415 | // work with + and - rating clicks |
||
416 | changeRating = function (type) { |
||
417 | // prevent some shits |
||
418 | if (is_self_profile || viewer_id == 0) { |
||
419 | return false; |
||
420 | } |
||
421 | |||
422 | $.post(script_url + '/api/profile/changerating?lang=' + script_lang, {type: type, target: target_id}, function (resp) { |
||
423 | if (resp.status === 1) { |
||
424 | var rV = parseInt($('#ratingValue').text()); |
||
425 | if (type == '+') { |
||
426 | $('#ratingValue').text(rV + 1); |
||
427 | } else { |
||
428 | $('#ratingValue').text(rV - 1); |
||
429 | } |
||
430 | alert('<?= __('Rating was successful changed') ?>'); |
||
431 | } else { |
||
432 | alert('<?= __('Rating cannot be changed') ?>'); |
||
433 | } |
||
434 | $('#addRating').addClass('disabled'); |
||
435 | $('#reduceRating').addClass('disabled'); |
||
436 | }, 'json'); |
||
437 | }; |
||
438 | |||
439 | $('#addRating').on('click', function () { |
||
440 | changeRating('+'); |
||
441 | }); |
||
442 | $('#reduceRating').on('click', function () { |
||
443 | changeRating('-'); |
||
444 | }); |
||
445 | }); |
||
446 | </script> |
||
447 | <?php $this->stop() ?> |
Let?s assume that you have a directory layout like this:
and let?s assume the following content of
Bar.php
:If both files
OtherDir/Foo.php
andSomeDir/Foo.php
are loaded in the same runtime, you will see a PHP error such as the following:PHP Fatal error: Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php
However, as
OtherDir/Foo.php
does not necessarily have to be loaded and the error is only triggered if it is loaded beforeOtherDir/Bar.php
, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias: