<?php
namespace App\Controller\Web;
use App\Entity\Articles;
use App\Entity\Pages;
use App\Entity\Sitewide;
use App\Entity\Tags;
use DateTime;
use Doctrine\ORM\EntityManagerInterface;
use Eko\FeedBundle\Feed\FeedManager;
use Exception;
use Pagerfanta\Adapter\ArrayAdapter;
use Pagerfanta\Pagerfanta;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class BlogController extends AbstractController
{
/**
* @var Sitewide|object|null
*/
private $sitewide;
/**
* @var EntityManagerInterface
*/
private EntityManagerInterface $em;
/**
* DefaultController constructor.
*
* @param EntityManagerInterface $em
*/
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
$this->sitewide = $this->em->getRepository(Sitewide::class)->findOneBy([], ['id' => 'asc']);
}
/**
* @Route("/blog/{slug}/{date}", name="Blog_Article", requirements={
* "date" = "\d{8}"
* })
* @param Request $request
* @param $slug
* @param $date
*
* @return RedirectResponse|Response
* @throws Exception
*/
public function blogAction(Request $request, $slug, $date)
{
$session = $request->getSession();
$mainNav = $this->em->getRepository(Pages::class)->findPubMainNavPageNames();
$otherNav = $this->em->getRepository(Pages::class)->findPubOtherNavPageNames();
$pageEntity = $this->em->getRepository(Pages::class)->findOneBy(['name' => 'Blog'], []);
$articles = $this->em->getRepository(Articles::class)->findBy(['publish' => true],
['datePublished' => 'DESC']);
$articleEntity = $this->em->getRepository(Articles::class)->findOneBy(['slug' => $slug], []);
// if there is a slug but no article
if (($slug != '') && !$articleEntity) {
$session->getFlashBag()->add(
'error',
'Sorry!! We couldn\'t find the blog you were looking for. You can see all our blogs below.'
);
return $this->redirect($this->generateUrl('blog'), 301);
}
// if there is an article, but it hasn't been published
if (!$articleEntity->getPublish()) {
//return 'This blog is not published';
if (count($articleEntity->getTags()) == 0) {
//if blog has no tag
$session->getFlashBag()->add(
'error',
'Sorry!! We couldn\'t find the blog you were looking for. You can see all our blogs below.'
);
return $this->redirect($this->generateUrl('blog'), 301);
} else { // if blog has tag
$i = 0;
$tagName = null;
foreach ($articleEntity->getTags() as $tag) {
if ($i < 1) {
$tagName = $tag->getName();
}
$i++;
}
$session->getFlashBag()->add(
'error',
'Sorry!! We couldn\'t find the blog you were looking for. You can see other blogs tagged '.$tagName.' below.'
);
return $this->redirect(
$this->generateUrl('blog_tag', [
'tag' => $tagName,
]),
301
);
}
}
//set cookies permission cookie
$cookies = $request->cookies->get('cookies');
if (!$cookies) {
$cookie = new Cookie('cookies', 'true', time() + 3600 * 24 * 90);
$response = new Response();
$response->headers->setCookie($cookie);
$response->sendHeaders();
}
// increase count for a view
$articlesViews = $articleEntity->getCount();
$articlesViews++;
$articleEntity->setCount($articlesViews);
$this->em->flush();
// set metaKeywords
$article = $articleEntity->getTitle().' ';
$article .= $articleEntity->getContent().' ';
$metaKeywords = $this->extractCommonWords2(strip_tags($article));
foreach ($metaKeywords as $key => $value) {
$metaKeywords[] = $key;
unset($metaKeywords[$key]);
}
$pageEntity->setMetaKeywords(implode(',', $metaKeywords));
$monthsArray = [];
foreach ($articles as $value) {
$monthYear = $value->getDatePublished()->format('\0\1 M Y');
$monthsArray[$monthYear][] = $value->getId();
}
$url = $request->headers->get('referer');
return $this->render('web/Default/blog.html.twig', [
'pageEntity' => $pageEntity,
'sitewide' => $this->sitewide,
'mainNav' => $mainNav,
'otherNav' => $otherNav,
'article' => $articleEntity,
'tags' => $this->fetchTagsArray(),
'monthsArray' => $monthsArray,
'url' => $url,
]);
}
/**
* * @Route("/blog/{year}/{month}/{page}", name="blog_month", defaults={
* "date" = "",
* "tag" = "",
* "page" = "1"
* }, requirements={
* "month" = "\d{2}",
* "year" = "\d{4}",
* "page" = "\d+",
* "date" = "\d{8}"
* })
* @Route("/blog/{page}", name="blog", defaults={
* "date" = "",
* "year" = "",
* "month" = "",
* "tag" = "",
* "page" = "1"
* }, requirements={
* "month" = "\d{2}",
* "year" = "\d{4}",
* "page" = "\d+",
* "date" = "\d{8}"
* }, options={"sitemap" = true})
* @Route("/blog/{tag}/{page}", name="blog_tag", defaults={
* "date" = "",
* "year" = "",
* "month" = "",
* "page" = "1"
* }, requirements={
* "month" = "\d{2}",
* "year" = "\d{4}",
* "page" = "\d+",
* "date" = "\d{8}"
* })
* @param Request $request
* @param $page
* @param $date
* @param $month
* @param $year
* @param $tag
*
* @return RedirectResponse|Response
* @throws Exception
*/
public function blogsAction(Request $request, $page, $date, $month, $year, $tag)
{
$mainNav = $this->em->getRepository(Pages::class)->findPubMainNavPageNames();
$otherNav = $this->em->getRepository(Pages::class)->findPubOtherNavPageNames();
$pageEntity = $this->em->getRepository(Pages::class)->findOneBy(['name' => 'Blog'], []);
$articles = $this->em->getRepository(Articles::class)->findBy(['publish' => true],
['datePublished' => 'DESC']);
$articlesRep = $this->em->getRepository(Articles::class);
$tagEntity = $this->em->getRepository(Tags::class)->findOneBy(['slug' => $tag], []);
// redirect if no tag exists
if ($tag) {
if (!$tagEntity) {
$request->getSession()->getFlashBag()->add(
'error',
'Sorry!! We couldn\'t find the tag you were looking for. You can see all our blogs below.'
);
return $this->redirect($this->generateUrl('blog'), 301);
}
}
//set cookies permission cookie
$cookies = $request->cookies->get('cookies');
if (!$cookies) {
$cookie = new Cookie('cookies', 'true', time() + 3600 * 24 * 90);
$response = new Response();
$response->headers->setCookie($cookie);
$response->sendHeaders();
}
$monthsArray = [];
foreach ($articles as $key => $value) {
$monthYear = $value->getDatePublished()->format('\0\1 M Y');
$monthsArray[$monthYear][] = $value->getId();
}
$queryBuilder = $articlesRep->createQueryBuilder('a')
->where('a.publish = true')
->select('a')
->leftjoin('a.tags', 't')
->orderby('a.datePublished', 'desc');
if ($tag != null) {
$queryBuilder = $queryBuilder->andwhere('t.slug = :tag')->setParameter('tag', $tag);
}
if (($month !== '') && ($year !== '')) {
$monthStart = new DateTime($month.'/01/'.$year);
$monthEnd = new DateTime(date("m/t/Y", strtotime($month.'/01/'.$year)));
$queryBuilder = $queryBuilder->andwhere('a.datePublished >= :monthStart')->setParameter(
'monthStart',
$monthStart
);
$queryBuilder = $queryBuilder->andwhere('a.datePublished <= :monthEnd')->setParameter(
'monthEnd',
$monthEnd
);
}
$articlesQuery = $queryBuilder->getQuery();
$articlesArray = $articlesQuery->getResult();
$adapter = new ArrayAdapter($articlesArray);
//$adapter = new DoctrineORMAdapter($queryBuilder);
$pagerfanta = new Pagerfanta($adapter);
$pagerfanta->setMaxPerPage(8); // 10 by default
$pagerfanta->setCurrentPage($page);
$nbResults = $pagerfanta->getNbResults();
$url = $request->headers->get('referer');
return $this->render('web/Default/blogs.html.twig', [
'pageEntity' => $pageEntity,
'sitewide' => $this->sitewide,
'mainNav' => $mainNav,
'otherNav' => $otherNav,
'articles' => $pagerfanta,
'page' => $page,
'nbResults' => $nbResults,
'tags' => $this->fetchTagsArray(),
'tag' => $tagEntity,
'monthsArray' => $monthsArray,
'monthYear' => $month.'/01/'.$year,
'url' => $url,
]);
}
private function fetchTagsArray(): array
{
$tags = $this->em->getRepository(Tags::class)->findBy([], ['name' => 'asc']);
$tagsArray = [];
/** @var Tags $value */
foreach ($tags as $value) {
$i = 1;
foreach ($value->getArticles() as $keyart => $valart) {
if ($valart->getPublish()) {
$tagsArray[$value->getName()] = ['slug' => $value->getSlug()];
$tagsArray[$value->getName()]['articles'] = $i;
$i++;
}
}
}
ksort($tagsArray);
return $tagsArray;
}
private function extractCommonWords2(
$string
): array {
// maybe take out phrases in first pass, and individual words in second pass, if it is possible
$findWords = [
'account',
'ad',
'ado',
'adobe',
'adobe-air',
'akamai',
'amazon',
'analyst',
'android',
'desktop',
];
$string = preg_replace('/\s\s+/i', ' ', $string); // replace whitespace - why do we do this?
$string = trim($string); // trim the string
$string = preg_replace(
'/[^a-zA-Z0-9 -]/',
'',
$string
); // only take alphanumerical characters, but keep the spaces and dashes too…
$string = strtolower($string); // make it lowercase
// preg_match_all('/\s.*?\s/i', $string, $matchWords); //somehwere here escapes out dashes
preg_match_all(
"/(?(?=[\-\w'])(?<![\-\w'])|(?<![^\-\w']))([\-\w']+)(?(?<=[\-\w'])(?![\-\w'])|(?![^\-\w']))/i",
$string,
$matchWords
); //somehwere here escapes out dashes
$matchWords = $matchWords[0];
$matches = [];
foreach ($matchWords as $item) {
if (in_array(strtolower(trim($item)), $findWords)) {
$matches[] = $item;
}
}
$wordCountArr = [];
if (is_array($matches)) {
foreach ($matches as $val) {
$val = strtolower(trim($val));
if (isset($wordCountArr[$val])) {
$wordCountArr[$val]++;
} else {
$wordCountArr[$val] = 1;
}
}
}
arsort($wordCountArr);
$wordCountArr = array_slice($wordCountArr, 0, 10);
return $wordCountArr;
}
/**
* Generate the article feed
* @Route("/blog-feed/{tag}", name="Blog_Feed")
*
* @param FeedManager $feedManager
* @param $tag
*
* @return Response XML Feed
*/
public function feedAction(
FeedManager $feedManager,
$tag
): Response {
$articles = $this->em->getRepository(Articles::class)->findAll();
$feed = $feedManager->get('article');
$feed->addFromArray($articles);
return new Response($feed->render('rss')); // or 'atom'
}
}