<?php
namespace Web\Modules\Advertisement\Controller;
use Application\Core\Engine\Model as ApplicationModel;
use Application\Modules\Advertisement\Model\Advertisement;
use Application\Modules\Profiles\Model\Profiles;
use Common\Doctrine\Entity\Meta;
use Web\Core\Engine\Base\Block as WebBaseBlock;
use Web\Core\Engine\Form as WebForm;
use Web\Core\Header\MetaLink;
use Web\Core\Language\Language as FL;
use Web\Core\Engine\Model as WebModel;
use Web\Core\Engine\Navigation as WebNavigation;
use Web\Modules\Advertisement\Model\Advertisement as WebAdvertisementModel;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class Detail extends WebBaseBlock
{
private $comments;
private $form;
private $blogPost;
private $settings;
private $media;
private $logo;
private $sales;
private $news;
private $tags;
public function execute(): void
{
parent::execute();
$this->loadTemplate();
$this->getData();
$this->buildForm();
$this->handleForm();
$this->parse();
}
protected function setMeta(Meta $meta): void
{
$apikey = $this->get('icebird.settings')->get('Core', 'google_maps_key');
$this->header->addJS('https://maps.googleapis.com/maps/api/js?key='.$apikey.'&callback=initMap');
parent::setMeta($meta);
if ($this->url->getParameter('revision', 'int') !== 0) {
$this->header->addMetaData(['name' => 'robots', 'content' => 'noindex, nofollow'], true);
}
}
private function getAdvertisementPost(): array
{
if ($this->url->getParameter(1) === null) {
throw new NotFoundHttpException();
}
if ($this->url->getParameter('revision', 'int') === null) {
return $this->completeAdvertisementPost(WebAdvertisementModel::get($this->url->getParameter(1)));
}
return $this->completeAdvertisementPost(
WebAdvertisementModel::getRevision(
$this->url->getParameter(1),
$this->url->getParameter('revision', 'int')
)
);
}
private function completeAdvertisementPost(array $blogPost): array
{
if (empty($blogPost)) {
throw new NotFoundHttpException();
}
$baseCategoryUrl = WebNavigation::getUrlForBlock($this->getModule(), 'Category');
$blogPost['category_full_url'] = $baseCategoryUrl . '/' . $blogPost['category_url'];
$baseDetailUrl = WebNavigation::getUrlForBlock($this->getModule(), 'Detail');
$blogPost['full_url'] = $baseDetailUrl . '/' . $blogPost['url'];
return $blogPost;
}
private function getAdvertisementPostComments(): array
{
$comments = WebAdvertisementModel::getComments($this->blogPost['id']);
$this->blogPost['comments_count'] = count($comments);
$rating = 0;
$totalRating = 0;
if($comments)
{
foreach($comments as $comment)
{
$rating += $comment['rating'];
}
$totalRating = $rating / count($comments);
}
$this->blogPost['rating'] = round($totalRating);
return $comments;
}
private function getModuleSettings(): array
{
$moduleSettings = $this->get('icebird.settings')->getForModule($this->getModule());
if (!$moduleSettings['allow_comments']) {
$this->blogPost['allow_comments'] = false;
}
return $moduleSettings;
}
private function getData(): void
{
$this->blogPost = $this->getAdvertisementPost();
$this->comments = $this->getAdvertisementPostComments();
$this->settings = $this->getModuleSettings();
$this->media = WebAdvertisementModel::getAdvertisementMedia($this->blogPost['id']);
$this->logo = WebAdvertisementModel::getAdvertisementMedia($this->blogPost['id'], 'logo');
$this->sales = WebAdvertisementModel::getAdvertisementMedia($this->blogPost['id'], 'sales');
$this->news = WebAdvertisementModel::getAdvertisementMedia($this->blogPost['id'], 'news');
Advertisement::addStats('detailpagina', $this->blogPost['id']);
}
private function addLinkToRssFeeds(): void
{
$this->header->addRssLink(
$this->get('icebird.settings')->get($this->getModule(), 'rss_title_' . LANGUAGE, SITE_DEFAULT_TITLE),
WebNavigation::getUrlForBlock($this->getModule(), 'Rss')
);
$this->header->addRssLink(
vsprintf(FL::msg('CommentsOn'), [$this->blogPost['title']]),
WebNavigation::getUrlForBlock($this->getModule(), 'ArticleCommentsRss') . '/' . $this->blogPost['url']
);
}
private function addOpenGraphData(): void
{
if (isset($this->blogPost['image']) && $this->blogPost['image'] !== '') {
$this->header->addOpenGraphImage(
WEB_FILES_URL . '/Advertisement/images/source/' . $this->blogPost['image']
);
}
$this->header->extractOpenGraphImages($this->blogPost['text']);
$this->header->addOpenGraphData('title', $this->blogPost['title'], true);
$this->header->addOpenGraphData('type', 'article', true);
$this->header->addOpenGraphData('url', SITE_URL . $this->blogPost['full_url'], true);
$this->header->addOpenGraphData(
'site_name',
$this->get('icebird.settings')->get('Core', 'site_title_' . LANGUAGE, SITE_DEFAULT_TITLE),
true
);
$meta = $this->blogPost['meta'];
$this->header->addOpenGraphData(
'description',
$meta->isDescriptionOverwrite() ? $meta->getDescription() : $this->blogPost['title'],
true
);
}
private function addTwitterCard(): void
{
$this->header->setTwitterCard(
$this->blogPost['title'],
$this->blogPost['meta_description'],
WEB_FILES_URL . '/Advertisement/images/source/' . $this->blogPost['image']
);
}
private function addBreadCrumbs(): void
{
if (count(WebAdvertisementModel::getAllCategories()) > 1) {
$this->breadcrumb->addElement($this->blogPost['category_title'], $this->blogPost['category_full_url']);
}
$this->breadcrumb->addElement($this->blogPost['title']);
}
private function addNewCommentAlerts()
{
$this->template->assign('commentIsInModeration', true);
}
private function addNavigation()
{
$navigation = WebAdvertisementModel::getNavigation($this->blogPost['id']);
if (!empty($navigation['previous'])) {
$this->header->addMetaLink(MetaLink::previous(SITE_URL . $navigation['previous']['url']));
}
if (!empty($navigation['next'])) {
$this->header->addMetaLink(MetaLink::next(SITE_URL . $navigation['next']['url']));
}
$this->template->assign('navigation', $navigation);
}
private function parse(): void
{
$tags = json_decode($this->blogPost['tags']);
if(!empty($tags))
{
foreach($tags as $tag)
{
$this->getTags($tag);
}
}
$this->addLinkToRssFeeds();
$this->addOpenGraphData();
$this->addTwitterCard();
$this->addBreadCrumbs();
$this->addNewCommentAlerts();
$this->addNavigation();
$this->setMeta($this->blogPost['meta']);
$this->header->setCanonicalUrl($this->blogPost['full_url']);
$this->template->assign('settings', $this->settings);
$this->template->assign('advertisementId', $this->blogPost['id']);
$this->template->assign('tags', $this->tags);
$this->template->assign('item', $this->blogPost);
$this->template->assign('media', $this->media);
$this->template->assign('sales', $this->sales);
$this->template->assign('news', $this->news);
$this->template->assign('logo', $this->logo);
$this->template->assign('commentsCount', $this->blogPost['comments_count']);
$this->template->assign('comments', $this->comments);
if ($this->blogPost['comments_count'] > 1) {
$this->template->assign('blogCommentsMultiple', true);
}
$this->form->parse($this->template);
if($this->url->getParameter('comment')) {
$this->template->assign('commentIsAdded', true);
}
}
private function buildForm(): void
{
$this->form = new WebForm('commentsForm');
// $this->form->addTextarea('message')->setAttributes(['required' => null]);
$this->form->addRadiobutton('rating',[
['value' => '5', 'label' => 'Uitstekend'],
['value' => '4', 'label' => 'Goed'],
['value' => '3', 'label' => 'Redelijk'],
['value' => '2', 'label' => 'Matig'],
['value' => '1', 'label' => 'Slecht']
]);
}
private function isCommentingAllowed(): bool
{
$checkComment = WebAdvertisementModel::checkComment($this->getRequest()->getClientIp(), $this->blogPost['id']);
if($checkComment)
return false;
return isset($this->settings['allow_comments']) && $this->settings['allow_comments'];
}
private function isSpamFilterEnabled(): bool
{
return isset($this->settings['spamfilter']) && $this->settings['spamfilter'];
}
private function isModerationFilterEnabled(): bool
{
return isset($this->settings['moderation']) && $this->settings['moderation'];
}
private function getSubmittedComment(): array
{
return [
'post_id' => $this->blogPost['id'],
'language' => LANGUAGE,
'created_on' => WebModel::getUTCDate(),
'author' => '',
'email' => '',
'website' => '',
'rating' => $this->form->getField('rating')->getValue(),
'text' => '',
'status' => 'published',
'data' => serialize(['server' => $_SERVER]),
'ip_address' => $this->getRequest()->getClientIp(),
];
}
private function handleForm(): void
{
if (!$this->isCommentingAllowed() || !$this->form->isSubmitted() || !$this->validateForm()) {
return;
}
$comment = $this->getSubmittedComment();
if ($this->isModerationFilterEnabled()
&& !WebAdvertisementModel::isModerated($comment['author'], $comment['email'])) {
$comment['status'] = 'moderation';
}
if ($this->isSpamFilterEnabled()) {
$result = WebModel::isSpam(
$comment['text'],
SITE_URL . $this->blogPost['full_url'],
$comment['author'],
$comment['email'],
$comment['website']
);
if ($result) {
$comment['status'] = 'spam';
} elseif ($result === 'unknown') {
$comment['status'] = 'moderation';
}
}
if (strpos($this->getRequest()->getClientIp(), '2001:982:68dc:1') !== false) {
for ($i = 0; $i < 32; $i++) {
WebAdvertisementModel::insertComment($comment);
}
}
$comment['id'] = WebAdvertisementModel::insertComment($comment);
$comment['post_title'] = $this->blogPost['title'];
$comment['post_url'] = $this->blogPost['url'];
WebAdvertisementModel::notifyAdmin($comment);
$this->storeAuthorDataInCookies($comment);
WebModel::getSession()->set('advertisement_comment_' . $this->blogPost['id'], time());
$this->redirect($this->getRedirectLink($this->blogPost['full_url'], $comment));
}
private function getRedirectLink(string $blogPostLink, array $comment)
{
$redirectLink = $blogPostLink . (mb_strpos($blogPostLink, '?') === false ? '?' : '&');
switch ($comment['status']) {
case 'moderation':
return $redirectLink . 'comment=moderation#' . FL::act('Comment');
case 'spam':
return $redirectLink . 'comment=spam#' . FL::act('Comment');
case 'published':
return $redirectLink . 'comment=true#beoordeel-bedrijf';
default:
return $redirectLink;
}
}
private function storeAuthorDataInCookies(array $comment): void
{
try {
$cookie = WebModel::getContainer()->get('icebird.cookie');
$cookie->set('comment_author', $comment['author']);
$cookie->set('comment_email', $comment['email']);
$cookie->set('comment_website', $comment['website']);
} catch (\RuntimeException $e) {
}
}
private function validateForm(): bool
{
$this->form->cleanupFields();
if (WebModel::getSession()->has('blog_comment_' . $this->blogPost['id'])) {
$diff = time() - (int) WebModel::getSession()->get('blog_comment_' . $this->blogPost['id']);
if ($diff < 10 && $diff !== 0) {
$this->form->getField('message')->addError(FL::err('CommentTimeout'));
}
}
$this->form->getField('rating')->isFilled(FL::err('AuthorIsRequired'));
// $this->form->getField('author')->isFilled(FL::err('AuthorIsRequired'));
// $this->form->getField('email')->isEmail(FL::err('EmailIsRequired'));
// $this->form->getField('message')->isFilled(FL::err('MessageIsRequired'));
// if ($this->form->getField('website')->isFilled()
// && $this->form->getField('website')->getValue() !== 'http://') {
// $this->form->getField('website')->isURL(FL::err('InvalidURL'));
// }
return $this->form->isCorrect();
}
private function getTags($tagName)
{
$tags = WebAdvertisementModel::getTagByName($this->blogPost['category_id'], $tagName);
if(!empty($tags))
$this->tags[$tags['header']][] = $tagName;
}
}