X-Git-Url: https://git.rapsys.eu/blogbundle/blobdiff_plain/c7d84bc01ab357783cfc548fedba566ead9a8fbc..d3028f63781ff2767401e31e36ee1c99e6fc484b:/Controller/AbstractController.php diff --git a/Controller/AbstractController.php b/Controller/AbstractController.php index 0bf792a..fca2be9 100644 --- a/Controller/AbstractController.php +++ b/Controller/AbstractController.php @@ -15,21 +15,23 @@ use Doctrine\ORM\EntityManagerInterface; use Doctrine\Persistence\ManagerRegistry; use Psr\Log\LoggerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController as BaseAbstractController; -use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; +use Symfony\Bundle\SecurityBundle\Security; use Symfony\Component\Asset\PackageInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\Filesystem\Exception\IOExceptionInterface; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Form\FormFactoryInterface; -use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Mailer\MailerInterface; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Routing\RouterInterface; use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface; -use Symfony\Contracts\Translation\TranslatorInterface; +use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; +use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Contracts\Service\ServiceSubscriberInterface; +use Symfony\Contracts\Translation\TranslatorInterface; use Twig\Environment; use Rapsys\BlogBundle\Entity\Dance; @@ -48,70 +50,129 @@ use Rapsys\PackBundle\Util\SluggerUtil; * {@inheritdoc} */ abstract class AbstractController extends BaseAbstractController implements ServiceSubscriberInterface { - ///AuthorizationCheckerInterface instance - protected AuthorizationCheckerInterface $checker; - - ///Config array + /** + * Config array + */ protected array $config; - ///Context array + /** + * Count integer + */ + protected int $count; + + /** + * Context array + */ protected array $context; - ///AccessDecisionManagerInterface instance + /** + * Limit integer + */ + protected int $limit; + + /** + * Locale string + */ + protected string $locale; + + /** + * Modified DateTime + */ + protected \DateTime $modified; + + /** + * Page integer + */ + protected int $page; + + /** + * Route string + */ + protected string $route; + + /** + * Route params array + */ + protected array $routeParams; + + /** + * AuthorizationCheckerInterface instance + */ + protected AuthorizationCheckerInterface $checker; + + /** + * AccessDecisionManagerInterface instance + */ protected AccessDecisionManagerInterface $decision; - ///ManagerRegistry instance + /** + * ManagerRegistry instance + */ protected ManagerRegistry $doctrine; - ///FacebookUtil instance + /** + * FacebookUtil instance + */ protected FacebookUtil $facebook; - ///FormFactoryInterface instance + /** + * FormFactoryInterface instance + */ protected FormFactoryInterface $factory; - ///Image util instance + /** + * Image util instance + */ protected ImageUtil $image; - ///Limit integer - protected int $limit; - - ///Locale string - protected string $locale; - - ///MailerInterface instance + /** + * MailerInterface instance + */ protected MailerInterface $mailer; - ///EntityManagerInterface instance + /** + * EntityManagerInterface instance + */ protected EntityManagerInterface $manager; - ///Modified DateTime - protected \DateTime $modified; - - ///PackageInterface instance + /** + * PackageInterface instance + */ protected PackageInterface $package; - ///Request instance + /** + * Request instance + */ protected Request $request; - ///Route string - protected string $route; - - ///Route params array - protected array $routeParams; - - ///Router instance + /** + * Router instance + */ protected RouterInterface $router; - ///Slugger util instance + /** + * Slugger util instance + */ protected SluggerUtil $slugger; - ///RequestStack instance + /** + * Security instance + */ + protected Security $security; + + /** + * RequestStack instance + */ protected RequestStack $stack; - ///Translator instance + /** + * Translator instance + */ protected TranslatorInterface $translator; - ///Twig\Environment instance + /** + * Twig\Environment instance + */ protected Environment $twig; /** @@ -129,6 +190,7 @@ abstract class AbstractController extends BaseAbstractController implements Serv * @param PackageInterface $package The package instance * @param RouterInterface $router The router instance * @param SluggerUtil $slugger The slugger instance + * @param Security $security The security instance * @param RequestStack $stack The stack instance * @param TranslatorInterface $translator The translator instance * @param Environment $twig The twig environment instance @@ -137,7 +199,7 @@ abstract class AbstractController extends BaseAbstractController implements Serv * @TODO move all that stuff to setSlugger('@slugger') setters with a calls: [ setSlugger: [ '@slugger' ] ] to unbload classes ??? * @TODO add a calls: [ ..., prepare: ['@???'] ] that do all the logic that can't be done in constructor because various things are not available */ - public function __construct(AuthorizationCheckerInterface $checker, ContainerInterface $container, AccessDecisionManagerInterface $decision, ManagerRegistry $doctrine, FacebookUtil $facebook, FormFactoryInterface $factory, ImageUtil $image, MailerInterface $mailer, EntityManagerInterface $manager, PackageInterface $package, RouterInterface $router, SluggerUtil $slugger, RequestStack $stack, TranslatorInterface $translator, Environment $twig, int $limit = 5) { + public function __construct(AuthorizationCheckerInterface $checker, ContainerInterface $container, AccessDecisionManagerInterface $decision, ManagerRegistry $doctrine, FacebookUtil $facebook, FormFactoryInterface $factory, ImageUtil $image, MailerInterface $mailer, EntityManagerInterface $manager, PackageInterface $package, RouterInterface $router, SluggerUtil $slugger, Security $security, RequestStack $stack, TranslatorInterface $translator, Environment $twig, int $limit = 5) { //Set checker $this->checker = $checker; @@ -180,6 +242,9 @@ abstract class AbstractController extends BaseAbstractController implements Serv //Set slugger $this->slugger = $slugger; + //Set security + $this->security = $security; + //Set stack $this->stack = $stack; @@ -190,7 +255,7 @@ abstract class AbstractController extends BaseAbstractController implements Serv $this->twig = $twig; //Get main request - $this->request = $this->stack->getMainRequest(); + $this->request = $this->stack->getCurrentRequest(); //Get current locale $this->locale = $this->request->getLocale(); @@ -201,6 +266,14 @@ abstract class AbstractController extends BaseAbstractController implements Serv //Set alternates $alternates = []; + //Get current page + $this->page = (int) $this->request->query->get('page'); + + //With negative page + if ($this->page < 0) { + $this->page = 0; + } + //Set route //TODO: default to not found route ??? //TODO: when url not found, this attribute is not defined, how do we handle it ??? @@ -221,45 +294,11 @@ abstract class AbstractController extends BaseAbstractController implements Serv //Set the context $this->context = [ - //TODO: review the structure - #'title' => $this->translator->trans($this->config['title']), - #'og:site_name' => $this->translator->trans($this->config['title']), - #'site' => [ - # 'donate' => $this->config['donate'], - # 'title' => $title = $this->translator->trans($this->config['site']['title']), - #], - 'head' => [ - 'alternates' => $alternates, - 'canonical' => $canonical, - 'icon' => $this->config['icon'], - 'keywords' => null, - 'locale' => str_replace('_', '-', $this->locale), - 'logo' => [ - 'png' => $this->config['logo']['png'], - 'svg' => $this->config['logo']['svg'], - 'alt' => $this->translator->trans($this->config['logo']['alt']) - ], - 'root' => $this->config['root'], - 'title' => null, - 'facebook' => [ - 'og:type' => 'article', - 'og:site_name' => $this->translator->trans($this->config['title']), - 'og:url' => $canonical, - //TODO: review this value - 'fb:app_id' => $this->config['facebook']['apps'] - ], - 'fbimage' => [ - 'texts' => [ - $this->translator->trans($this->config['title']) => [ - 'font' => 'irishgrover', - 'size' => 110 - ] - ] - ] - ], + 'alternates' => $alternates, + 'canonical' => $canonical, 'contact' => [ - 'name' => $this->translator->trans($this->config['contact']['name']), - 'mail' => $this->config['contact']['mail'] + 'address' => $this->config['contact']['address'], + 'name' => $this->translator->trans($this->config['contact']['name']) ], 'copy' => [ 'by' => $this->translator->trans($this->config['copy']['by']), @@ -268,20 +307,41 @@ abstract class AbstractController extends BaseAbstractController implements Serv 'short' => $this->translator->trans($this->config['copy']['short']), 'title' => $this->config['copy']['title'] ], - 'forms' => [], - 'title' => null, 'description' => null, - 'section' => null, - 'site' => [ - 'icon' => $this->config['icon'], - 'logo' => [ - 'png' => $this->config['logo']['png'], - 'svg' => $this->config['logo']['svg'], - 'alt' => $this->translator->trans($this->config['logo']['alt']) - ], - 'path' => $this->config['path'], - 'root' => $this->config['root'], - 'title' => $this->translator->trans($this->config['title']) + 'donate' => $this->config['donate'], + 'facebook' => [ + 'og:type' => 'article', + 'og:site_name' => $title = $this->translator->trans($this->config['title']), + 'og:url' => $canonical, + #'fb:admins' => $this->config['facebook']['admins'], + 'fb:app_id' => $this->config['facebook']['apps'] + ], + //XXX: TODO: only generate it when fb robot request the url ??? + 'fbimage' => [ + 'texts' => [ + $title => [ + //'font' => 'irishgrover', + //'size' => 110 + ] + ] + ], + 'forms' => [], + 'icon' => $this->config['icon'], + 'keywords' => null, + 'locale' => str_replace('_', '-', $this->locale), + #'logo' => [ + # 'png' => $this->config['logo']['png'], + # 'svg' => $this->config['logo']['svg'], + # 'alt' => $this->translator->trans($this->config['logo']['alt']) + #], + 'logo' => $this->config['logo'], + 'next' => null, + 'prev' => null, + 'root' => $this->config['root'], + 'title' => [ + 'page' => null, + 'section' => null, + 'site' => $title ] ]; } @@ -293,10 +353,10 @@ abstract class AbstractController extends BaseAbstractController implements Serv */ protected function render(string $view, array $parameters = [], Response $response = null): Response { //Create response when null - $response ??= new Response(); + $response ??= new Response(); //Without alternates - if (empty($parameters['head']['alternates'])) { + if (count($parameters['alternates']) <= 1) { //Iterate on locales excluding current one foreach($this->config['locales'] as $locale) { //Set routeParams @@ -321,7 +381,7 @@ abstract class AbstractController extends BaseAbstractController implements Serv } //Set locale locales context - $parameters['head']['alternates'][str_replace('_', '-', $locale)] = [ + $parameters['alternates'][str_replace('_', '-', $locale)] = [ 'absolute' => $this->router->generate($this->route, $routeParams, UrlGeneratorInterface::ABSOLUTE_URL), 'relative' => $this->router->generate($this->route, $routeParams), 'title' => implode('/', $titles), @@ -329,12 +389,12 @@ abstract class AbstractController extends BaseAbstractController implements Serv ]; //Add shorter locale - if (empty($parameters['head']['alternates'][$shortCurrent = substr($locale, 0, 2)])) { + if (empty($parameters['alternates'][$shortCurrent = substr($locale, 0, 2)])) { //Set locale locales context - $parameters['head']['alternates'][$shortCurrent] = $parameters['head']['alternates'][str_replace('_', '-', $locale)]; + $parameters['alternates'][$shortCurrent] = $parameters['alternates'][str_replace('_', '-', $locale)]; } //Add shorter locale - } elseif (empty($parameters['head']['alternates'][$shortCurrent = substr($locale, 0, 2)])) { + } elseif (empty($parameters['alternates'][$shortCurrent = substr($locale, 0, 2)])) { //Set titles $titles = []; @@ -348,7 +408,7 @@ abstract class AbstractController extends BaseAbstractController implements Serv } //Set locale locales context - $parameters['head']['alternates'][$shortCurrent] = [ + $parameters['alternates'][$shortCurrent] = [ 'absolute' => $this->router->generate($this->route, $routeParams, UrlGeneratorInterface::ABSOLUTE_URL), 'relative' => $this->router->generate($this->route, $routeParams), 'title' => implode('/', $titles), @@ -358,77 +418,83 @@ abstract class AbstractController extends BaseAbstractController implements Serv } } - //With empty head title and section - if (empty($parameters['head']['title']) && !empty($parameters['section'])) { - //Set head title - $parameters['head']['title'] = implode(' - ', [$parameters['title'], $parameters['section'], $this->translator->trans($this->config['title'])]); - //With empty head title - } elseif (empty($parameters['head']['title'])) { - //Set head title - $parameters['head']['title'] = implode(' - ', [$parameters['title'], $this->translator->trans($this->config['title'])]); - } - - //With empty head description and description - if (empty($parameters['head']['description']) && !empty($parameters['description'])) { - //Set head description - $parameters['head']['description'] = $parameters['description']; + //With canonical + if (!empty($parameters['canonical'])) { + //Set facebook url + $parameters['facebook']['og:url'] = $parameters['canonical']; } //With empty facebook title and title - if (empty($parameters['head']['facebook']['og:title']) && !empty($parameters['title'])) { + if (empty($parameters['facebook']['og:title']) && !empty($parameters['title']['page'])) { //Set facebook title - $parameters['head']['facebook']['og:title'] = $parameters['title']; + $parameters['facebook']['og:title'] = $parameters['title']['page']; } //With empty facebook description and description - if (empty($parameters['head']['facebook']['og:description']) && !empty($parameters['description'])) { + if (empty($parameters['facebook']['og:description']) && !empty($parameters['description'])) { //Set facebook description - $parameters['head']['facebook']['og:description'] = $parameters['description']; + $parameters['facebook']['og:description'] = $parameters['description']; } //With locale if (!empty($this->locale)) { //Set facebook locale - $parameters['head']['facebook']['og:locale'] = $this->locale; + $parameters['facebook']['og:locale'] = $this->locale; //With alternates //XXX: locale change when fb_locale=xx_xx is provided is done in FacebookSubscriber //XXX: see https://stackoverflow.com/questions/20827882/in-open-graph-markup-whats-the-use-of-oglocalealternate-without-the-locati - if (!empty($parameters['head']['alternates'])) { + if (!empty($parameters['alternates'])) { //Iterate on alternates - foreach($parameters['head']['alternates'] as $lang => $alternate) { + foreach($parameters['alternates'] as $lang => $alternate) { if (strlen($lang) == 5) { //Set facebook locale alternate - $parameters['head']['facebook']['og:locale:alternate'] = str_replace('-', '_', $lang); + $parameters['facebook']['og:locale:alternate'] = str_replace('-', '_', $lang); } } } } //Without facebook image defined and texts - if (empty($parameters['head']['facebook']['og:image']) && !empty($this->request) && !empty($parameters['head']['fbimage']['texts']) && !empty($this->modified)) { + if (empty($parameters['facebook']['og:image']) && !empty($this->request) && !empty($parameters['fbimage']['texts']) && !empty($this->modified)) { //Get facebook image - $parameters['head']['facebook'] += $this->facebook->getImage($this->request->getPathInfo(), $parameters['head']['fbimage']['texts'], $this->modified->getTimestamp()); + //XXX: decode getPathInfo (see https://github.com/symfony/symfony/issues/2579) + $parameters['facebook'] += $this->image->getFacebook(urldecode($this->request->getPathInfo()), $parameters['fbimage']['texts'], $this->modified->getTimestamp()); + } + + //With count + if (!empty($this->count)) { + //With prev link + if ($this->page > 0) { + //Set head prev + $parameters['prev'] = $this->generateUrl($this->request->get('_route'), ['page' => $this->page - 1]+$this->request->get('_route_params')); + } + + //With next link + if ($this->count > ($this->page + 1) * $this->limit) { + //Set head next + $parameters['next'] = $this->generateUrl($this->request->get('_route'), ['page' => $this->page + 1]+$this->request->get('_route_params')); + } } //Call twig render method $content = $this->twig->render($view, $parameters); //Invalidate OK response on invalid form - if (200 === $response->getStatusCode()) { - foreach ($parameters as $v) { - if ($v instanceof FormInterface && $v->isSubmitted() && !$v->isValid()) { - $response->setStatusCode(422); - break; - } - } - } + if (200 === $response->getStatusCode()) { + foreach ($parameters as $v) { + if ($v instanceof FormInterface && $v->isSubmitted() && !$v->isValid()) { + $response->setStatusCode(422); + break; + } + } + } //Store content in response - $response->setContent($content); + $response->setContent($content); //Return response - return $response; + return $response; } /** @@ -451,7 +517,8 @@ abstract class AbstractController extends BaseAbstractController implements Serv 'rapsys_pack.path_package' => PackageInterface::class, 'router' => RouterInterface::class, 'rapsys_pack.slugger_util' => SluggerUtil::class, - 'request_stack' => RequestStack::class, + 'security' => Security::class, + 'stack' => RequestStack::class, 'translator' => TranslatorInterface::class, 'twig' => Environment::class, ];