/** * Build search results * @return array[AbstractSearchResult] */ public function getResult() { // relevant search by string query $records = Content::where('display', '=', 1)->search($this->query)->take($this->limit)->get(); // check if result is not empty if ($records->count() < 1) { return []; } // build result items $result = []; foreach ($records as $item) { /** @var \Apps\ActiveRecord\Content $item */ $title = $item->getLocaled('title'); $text = App::$Security->strip_tags($item->getLocaled('text')); $snippet = Text::snippet($text); // prevent empty items if (Str::likeEmpty($title)) { continue; } // initialize abstract response pattern $res = new AbstractSearchResult(); $res->setTitle($title); $res->setSnippet($snippet); $res->setDate($item->created_at); $res->setRelevance((int) $item->relevance); $res->setUri('/content/read/' . $item->getPath()); // accumulate response var $result[] = $res; } return $result; }
/** * Build search results. Should return array collection: [AbstractSearchResult] * @return array */ public function getResult() { // search in comments post $query = CommentPost::where('moderate', '=', 0)->search($this->query)->take($this->limit)->get(); // check if response is empty if ($query->count() < 1) { return []; } // build output $result = []; foreach ($query as $item) { /** @var CommentPost $item */ $snippet = App::$Security->strip_tags($item->message); $snippet = Text::snippet($snippet); // make unique instance object $instance = new AbstractSearchResult(); $instance->setTitle(App::$Translate->get('Search', 'Comment on the page')); $instance->setSnippet($snippet); $instance->setUri($item->pathway . '#comments-list'); $instance->setDate($item->created_at); $instance->setRelevance((int) $item->relevance); // add instance to result set $result[] = $instance; } return $result; }
/** * @inheritdoc */ public function make() { // update readed marker $this->_post->readed = 1; $this->_post->save(); // add new answer row in database $record = new FeedbackAnswer(); $record->feedback_id = $this->_post->id; $record->name = $this->name; $record->email = $this->email; $record->message = $this->message; $record->user_id = $this->_userId; $record->is_admin = 1; $record->ip = $this->_ip; $record->save(); // add user notification if ((int) $this->_post->user_id > 0 && $this->_userId !== (int) $this->_post->user_id) { $notify = new EntityAddNotification((int) $this->_post->user_id); $uri = '/feedback/read/' . $this->_post->id . '/' . $this->_post->hash . '#feedback-answer-' . $record->id; $notify->add($uri, EntityAddNotification::MSG_ADD_FEEDBACKANSWER, ['snippet' => Text::snippet($this->message, 50), 'post' => Text::snippet($this->_post->message, 50)]); } // send email notification $this->sendEmail($this->_post); // unset message data $this->message = null; }
/** * Make post to user wall from $viewer to $target instance of iUser interface objects * @param iUser $target * @param iUser $viewer * @param int $delay * @return bool */ public function makePost(iUser $target, iUser $viewer, $delay = 60) { if ($target === null || $viewer === null) { return false; } $find = WallRecords::where('sender_id', '=', $viewer->id)->orderBy('updated_at', 'desc')->first(); if ($find !== null) { $lastPostTime = Date::convertToTimestamp($find->updated_at); if (time() - $lastPostTime < static::POST_GLOBAL_DELAY) { // past time was less then default delay return false; } } // save new post to db $record = new WallRecords(); $record->target_id = $target->id; $record->sender_id = $viewer->id; $record->message = $this->message; $record->save(); // add user notification if ($target->id !== $viewer->id) { $notify = new EntityAddNotification($target->id); $notify->add('profile/show/' . $target->id . '#wall-post-' . $record->id, EntityAddNotification::MSG_ADD_WALLPOST, ['snippet' => Text::snippet($this->message, 50)]); } // cleanup message $this->message = null; return true; }
/** * Build content items as array */ private function buildContent() { if ($this->_records->count() < 1) { return; } foreach ($this->_records as $item) { /** @var \Apps\ActiveRecord\Content $item */ // full text $text = $item->getLocaled('text'); // remove html $text = App::$Security->strip_tags($text); // build items $this->items[] = ['title' => $item->getLocaled('title'), 'snippet' => Text::snippet($text), 'uri' => '/content/read/' . $item->getPath(), 'thumb' => $item->getPosterThumbUri()]; } }
/** * Add new row to database and set post is unreaded */ public function make() { // update readed marker $this->_post->readed = 0; $this->_post->save(); // add new answer row in database $record = new FeedbackAnswer(); $record->feedback_id = $this->_post->id; $record->name = $this->name; $record->email = $this->email; $record->message = $this->message; if ($this->_userId > 0) { $record->user_id = $this->_userId; } $record->ip = $this->_ip; $record->save(); // add notification msg $targetId = $this->_post->user_id; if ($targetId !== null && (int) $targetId > 0 && $targetId !== $this->_userId) { $notify = new EntityAddNotification($targetId); $uri = '/feedback/read/' . $this->_post->id . '/' . $this->_post->hash . '#feedback-answer-' . $record->id; $notify->add($uri, EntityAddNotification::MSG_ADD_FEEDBACKANSWER, ['snippet' => Text::snippet($this->message, 50), 'post' => Text::snippet($this->_post->message, 50)]); } }
<?php /** @var object $records */ use Ffcms\Core\Helper\Date; use Ffcms\Core\Helper\Text; use Ffcms\Core\Helper\Type\Str; foreach ($records as $record) { $title = \App::$Translate->getLocaleText($record->title); if (Str::likeEmpty($title)) { continue; } $title = Text::snippet($title, 50); $date = Date::humanize($record->created_at); $categoryUrl = \App::$Alias->baseUrl . '/content/list/' . $record->cpath; $categoryLink = '<a href="' . $categoryUrl . '">' . \App::$Translate->getLocaleText($record->ctitle) . '</a>'; $newsLink = \App::$Alias->baseUrl . '/content/read/' . $record->cpath; $newsLink = rtrim($newsLink, '/') . '/' . $record->path; echo '<div class="row"><div class="col-md-12">'; echo '<a href="' . $newsLink . '">→ ' . $title . '</a><br />'; echo '<small class="pull-left">' . $categoryLink . '</small>'; echo '<small class="pull-right">' . $date . '</small>'; echo '</div></div>'; echo '<hr class="pretty" />'; }
/** * Add comment answer to database and return active record object * @return CommentAnswer */ public function buildRecord() { $record = new CommentAnswer(); $record->comment_id = $this->replayTo; $record->user_id = $this->_userId; $record->guest_name = $this->guestName; $record->message = $this->message; $record->lang = App::$Request->getLanguage(); $record->ip = $this->ip; // check if premoderation is enabled and user is guest if ((bool) $this->_configs['guestModerate'] && $this->_userId < 1) { $record->moderate = 1; } $record->save(); // add notification for comment post owner $commentPost = $record->getCommentPost(); if ($commentPost !== null && (int) $commentPost->user_id !== 0 && (int) $commentPost->user_id !== $this->_userId) { $notify = new EntityAddNotification((int) $commentPost->user_id); $notify->add($commentPost->pathway, EntityAddNotification::MSG_ADD_COMMENTANSWER, ['snippet' => Text::snippet($this->message, 50), 'post' => Text::snippet($commentPost->message, 50)]); } return $record; }
<h1><?php echo __('Feedback requests'); ?> </h1> <?php echo $this->render('feedback/_authTabs'); ?> <?php if ($records->count() < 1) { echo '<p class="alert alert-warning">' . __('No requests is founded') . '</p>'; return; } $items = []; foreach ($records as $item) { $items[] = [['text' => $item->id], ['text' => Url::link(['feedback/read', $item->id, $item->hash], Text::cut($item->message, 0, 40)), 'html' => true], ['text' => (int) $item->closed === 1 ? '<span class="label label-danger">' . __('Closed') . '</span>' : '<span class="label label-success">' . __('Opened') . '</span>', 'html' => true, '!secure' => true], ['text' => Date::convertToDatetime($item->created_at, Date::FORMAT_TO_HOUR)], ['text' => Date::convertToDatetime($item->updated_at, Date::FORMAT_TO_HOUR)]]; } ?> <?php echo \Ffcms\Core\Helper\HTML\Table::display(['table' => ['class' => 'table table-bordered'], 'thead' => ['titles' => [['text' => '#'], ['text' => __('Message')], ['text' => __('Status')], ['text' => __('Created')], ['text' => __('Updated')]]], 'tbody' => ['items' => $items]]); ?> <div class="text-center"> <?php echo $pagination->display(['class' => 'pagination pagination-centered']); ?> </div>
?> <h1><?php echo __('Feedback list'); ?> </h1> <hr /> <?php if ($records === null || $records->count() < 1) { echo '<p class="alert alert-warning">' . __('Feedback requests is empty now!') . '</p>'; return; } $items = []; foreach ($records as $item) { /** @var \Apps\ActiveRecord\FeedbackPost $item*/ $items[] = [['text' => $item->id . ((int) $item->readed !== 1 ? ' <i class="fa fa-bell alert-info"></i>' : null), 'html' => true], ['text' => Url::link(['feedback/read', $item->id], Text::snippet($item->message, 40, false)), 'html' => true], ['text' => $item->getAnswers()->count()], ['text' => $item->email], ['text' => (int) $item->closed === 1 ? '<span class="label label-danger">' . __('Closed') . '</span>' : '<span class="label label-success">' . __('Opened') . '</span>', 'html' => true, '!secure' => true], ['text' => Date::convertToDatetime($item->updated_at, Date::FORMAT_TO_HOUR)], ['text' => Url::link(['feedback/read', $item->id], '<i class="fa fa-list fa-lg"></i> ') . Url::link(['feedback/delete', 'post', $item->id], '<i class="fa fa-trash-o fa-lg"></i>'), 'html' => true, 'property' => ['class' => 'text-center']]]; } ?> <div class="table table-responsive"> <?php echo Table::display(['table' => ['class' => 'table table-bordered'], 'thead' => ['titles' => [['text' => '#'], ['text' => __('Text')], ['text' => __('Answers')], ['text' => __('Author')], ['text' => __('Status')], ['text' => __('Date')], ['text' => __('Actions')]]], 'tbody' => ['items' => $items]]); ?> </div> <p><i class="fa fa-bell alert-info"></i> = <?php echo __('New request or new answer in feedback topic'); ?> </p> <div class="text-center">
/** * Build content data to model properties * @param $records * @throws ForbiddenException * @throws NotFoundException */ private function buildContent($records) { $nullItems = 0; foreach ($records as $row) { /** @var Content $row */ // check title length on current language locale $localeTitle = $row->getLocaled('title'); if (Str::likeEmpty($localeTitle)) { ++$nullItems; continue; } // get snippet from full text for current locale $text = Text::snippet($row->getLocaled('text')); $itemPath = $this->categories[$row->category_id]->path; if (!Str::likeEmpty($itemPath)) { $itemPath .= '/'; } $itemPath .= $row->path; // prepare tags data $tags = $row->getLocaled('meta_keywords'); if (!Str::likeEmpty($tags)) { $tags = explode(',', $tags); } else { $tags = null; } $owner = App::$User->identity($row->author_id); // make a fake if user is not exist over id if ($owner === null) { $owner = new User(); } // check if current user can rate item $ignoredRate = App::$Session->get('content.rate.ignore'); $canRate = true; if (Obj::isArray($ignoredRate) && Arr::in((string) $row->id, $ignoredRate)) { $canRate = false; } if (!App::$User->isAuth()) { $canRate = false; } elseif ($owner->getId() === App::$User->identity()->getId()) { // own item $canRate = false; } // build result array $this->items[] = ['id' => $row->id, 'title' => $localeTitle, 'text' => $text, 'date' => Date::humanize($row->created_at), 'updated' => $row->updated_at, 'author' => $owner, 'poster' => $row->getPosterUri(), 'thumb' => $row->getPosterThumbUri(), 'thumbSize' => File::size($row->getPosterThumbUri()), 'views' => (int) $row->views, 'rating' => (int) $row->rating, 'canRate' => $canRate, 'category' => $this->categories[$row->category_id], 'uri' => '/content/read/' . $itemPath, 'tags' => $tags]; } if ($nullItems === $this->_contentCount) { throw new NotFoundException(__('Content is not founded')); } }
<h1><?php echo __('Answers list'); ?> </h1> <hr /> <?php if ($records === null || $records->count() < 1) { echo '<p class="alert alert-warning">' . __('Answers is not founded') . '</p>'; return; } $items = []; $moderateIsFound = false; foreach ($records as $item) { $commentObject = $item->getCommentPost(); $message = Text::cut(\App::$Security->strip_tags($item->message), 0, 75); $moderate = (bool) $item->moderate; if ($moderate) { $moderateIsFound = true; } $items[] = [1 => ['text' => $item->id], 2 => ['text' => ($moderate ? '<i class="fa fa-exclamation text-warning"></i> ' : null) . Url::link(['comments/read', $commentObject->id, null, ['#' => '#answer-' . $item->id]], $message), 'html' => true], 3 => ['text' => Simplify::parseUserLink((int) $item->user_id, $item->guest_name, 'user/update'), 'html' => true], 4 => ['text' => '<a href="' . App::$Alias->scriptUrl . $commentObject->pathway . '" target="_blank">' . Str::sub($commentObject->pathway, 0, 20) . '...</a>', 'html' => true], 5 => ['text' => Date::convertToDatetime($item->created_at, Date::FORMAT_TO_HOUR)], 6 => ['text' => Url::link(['comments/read', $commentObject->id], '<i class="fa fa-list fa-lg"></i>') . ' ' . Url::link(['comments/delete', 'answer', $item->id], '<i class="fa fa-trash-o fa-lg"></i>'), 'html' => true, 'property' => ['class' => 'text-center']], 'property' => ['class' => 'checkbox-row' . ($moderate !== false ? ' alert-warning' : null)]]; } $moderateAccept = false; if ($moderateIsFound) { $moderateAccept = ['type' => 'submit', 'class' => 'btn btn-warning', 'value' => __('Publish'), 'formaction' => Url::to('comments/publish', 'answer')]; } ?> <div class="table-responsive"> <?php echo Table::display(['table' => ['class' => 'table table-bordered table-hover'], 'thead' => ['titles' => [['text' => '#'], ['text' => __('Answer')], ['text' => __('Author')], ['text' => __('Page')], ['text' => __('Date')], ['text' => __('Actions')]]], 'tbody' => ['items' => $items], 'selectableBox' => ['attachOrder' => 1, 'form' => ['method' => 'GET', 'class' => 'form-horizontal', 'action' => Url::to('comments/delete', 'answer')], 'selector' => ['type' => 'checkbox', 'name' => 'selected[]', 'class' => 'massSelectId'], 'buttons' => [['type' => 'submit', 'class' => 'btn btn-danger', 'value' => __('Delete selected'), 'formaction' => Url::to('comment/delete', 'answer')], $moderateAccept]]]);
/** * Add new post answer from AJAX post * @param int $postId * @return string * @throws ForbiddenException * @throws NativeException */ public function actionSendwallanswer($postId) { // not auth? what are you doing there? ;) if (!App::$User->isAuth()) { throw new ForbiddenException('Auth required'); } // no post id? wtf you doing man! if (!Obj::isLikeInt($postId) || $postId < 1) { throw new NativeException('Wrong input data'); } // get current(sender) user object $viewer = App::$User->identity(); // get message from post and validate minlength $message = $this->request->get('message'); $message = App::$Security->strip_tags($message); if (!Obj::isString($message) || Str::length($message) < 3) { throw new ForbiddenException('Wrong input data'); } // try to find this post $wallPost = WallPost::where('id', '=', $postId); if ($wallPost->count() < 1) { throw new NativeException('Wrong input data'); } $wallRow = $wallPost->first(); $target_id = $wallRow->target_id; // check if in blacklist if (!Blacklist::check($viewer->id, $target_id)) { throw new ForbiddenException('User is blocked!'); } // check delay between user last post and current $lastAnswer = WallAnswer::where('user_id', '=', App::$User->identity()->getId())->orderBy('created_at', 'DESC')->first(); if (null !== $lastAnswer && false !== $lastAnswer) { $now = time(); $answerTime = Date::convertToTimestamp($lastAnswer->created_at); $cfgs = \Apps\ActiveRecord\App::getConfigs('app', 'Profile'); // hmm, maybe past less then delay required? if ($now - (int) $cfgs['delayBetweenPost'] < $answerTime) { throw new ForbiddenException('Delay between answers not pass'); } } // make new row ;) $answers = new WallAnswer(); $answers->post_id = $postId; $answers->user_id = $viewer->id; $answers->message = $message; $answers->save(); // add notification for target user if ($viewer->id !== $target_id) { $notify = new EntityAddNotification($target_id); $notify->add('/profile/show/' . $target_id . '#wall-post-' . $wallRow->id, EntityAddNotification::MSG_ADD_WALLANSWER, ['snippet' => Text::snippet($message, 50), 'post' => $wallRow->message]); } // send "ok" response $this->setJsonHeader(); return json_encode(['status' => 1, 'message' => 'ok']); }