Skip to content

Commit

Permalink
Merge pull request #5 from lopes-vincent/master
Browse files Browse the repository at this point in the history
Add canonical override in seo form
  • Loading branch information
gillesbourgeat authored Jan 22, 2019
2 parents 67d90dd + 7a2d955 commit 9ae1a76
Show file tree
Hide file tree
Showing 11 changed files with 249 additions and 6 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 1.2.0

- Add canonical override in seo form

# 1.1.1

- Fix exception when Thelia was not configured
Expand Down
2 changes: 2 additions & 0 deletions CanonicalUrl.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@ class CanonicalUrl extends BaseModule
{
/** @var string */
const DOMAIN_NAME = 'canonicalurl';

const SEO_CANONICAL_META_KEY = 'seo_canonical_meta';
}
7 changes: 7 additions & 0 deletions Config/config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,19 @@
<tag name="kernel.event_subscriber"/>
<argument type="service" id="request" />
</service>
<service id="canonicalurl.seo.form.listener" class="CanonicalUrl\EventListener\SeoFormListener" scope="request">
<argument type="service" id="request"/>
<tag name="kernel.event_subscriber"/>
</service>
</services>

<hooks>
<hook id="canonicalurl.meta.hook" class="CanonicalUrl\Hook\MetaHook" scope="request">
<tag name="hook.event_listener" event="main.head-bottom" type="front" method="onMainHeadBottom" />
<argument type="service" id="event_dispatcher" />
</hook>
<hook id="canonicalurl.seo.update.form" class="CanonicalUrl\Hook\SeoUpdateFormHook">
<tag name="hook.event_listener" event="tab-seo.update-form" type="backoffice" method="addInputs"/>
</hook>
</hooks>
</config>
7 changes: 6 additions & 1 deletion Config/module.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<language>en_US</language>
<language>fr_FR</language>
</languages>
<version>1.1.1</version>
<version>1.2.0</version>
<authors>
<author>
<name>Gilles Bourgeat</name>
Expand All @@ -26,6 +26,11 @@
<email>franck@cqfdev.fr</email>
<website>www.cqfdev.fr</website>
</author>
<author>
<name>Vincent Lopes-Vicente</name>
<company>OpenStudio</company>
<email>vlopes@openstudio.fr</email>
</author>
</authors>
<type>classic</type>
<thelia>2.1.0</thelia>
Expand Down
3 changes: 1 addition & 2 deletions Event/CanonicalUrlEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

namespace CanonicalUrl\Event;

use Doctrine\Instantiator\Exception\InvalidArgumentException;
use Symfony\Component\EventDispatcher\Event;

/**
Expand Down Expand Up @@ -40,7 +39,7 @@ public function getUrl()
public function setUrl($url)
{
if ($url !== null && $url[0] !== '/' && filter_var($url, FILTER_VALIDATE_URL) === false) {
throw new InvalidArgumentException('The value "' . (string) $url . '" is not a valid Url or Uri.');
throw new \InvalidArgumentException('The value "' . (string) $url . '" is not a valid Url or Uri.');
}

$this->url = $url;
Expand Down
72 changes: 71 additions & 1 deletion EventListener/CanonicalUrlListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@

namespace CanonicalUrl\EventListener;

use CanonicalUrl\CanonicalUrl;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Thelia\Core\HttpFoundation\Session\Session;
use Thelia\Log\Tlog;
use Thelia\Model\ConfigQuery;
use Thelia\Model\LangQuery;
use CanonicalUrl\Event\CanonicalUrlEvent;
use CanonicalUrl\Event\CanonicalUrlEvents;
use Thelia\Model\MetaDataQuery;

/**
* Class CanonicalUrlListener
Expand Down Expand Up @@ -51,6 +54,15 @@ public function generateUrlCanonical(CanonicalUrlEvent $event)
if ($event->getUrl() !== null) {
return;
}

if (null !== $canonicalOverride = $this->getCanonicalOverride()) {
try {
$event->setUrl($canonicalOverride);
return;
} catch (\InvalidArgumentException $e) {
Tlog::getInstance()->addWarning($e->getMessage());
}
}

$parseUrlByCurrentLocale = $this->getParsedUrlByCurrentLocale();

Expand Down Expand Up @@ -81,7 +93,11 @@ public function generateUrlCanonical(CanonicalUrlEvent $event)
}
}

$event->setUrl($canonicalUrl);
try {
$event->setUrl($canonicalUrl);
} catch (\InvalidArgumentException $e) {
Tlog::getInstance()->addWarning($e->getMessage());
}
}

/**
Expand Down Expand Up @@ -133,4 +149,58 @@ protected function getParsedUrlByCurrentLocale()
// return current URL
return parse_url($this->request->getUri());
}

/**
* @return string|null
*/
protected function getCanonicalOverride()
{
$routeParameters = $this->getRouteParameters();

if (null === $routeParameters) {
return null;
}

$metaCanonical = MetaDataQuery::create()
->filterByMetaKey(CanonicalUrl::SEO_CANONICAL_META_KEY)
->filterByElementKey($routeParameters['view'])
->filterByElementId($routeParameters['id'])
->findOne();

if (null === $metaCanonical) {
return null;
}

$canonicalValues = json_decode($metaCanonical->getValue(), true);

$lang = $this->request->getSession()->getLang();

if (!isset($canonicalValues[$lang->getLocale()])) {
return null;
}

return $canonicalValues[$lang->getLocale()];
}

/**
* @return array|null
*/
protected function getRouteParameters()
{
$view = $this->request->get('view');
if (null === $view) {
$view = $this->request->get('_view');
}
if (null === $view) {
return null;
}

$id = $this->request->get($view.'_id');

if (null === $id) {
return null;
}

return compact('view', 'id');
}
}
103 changes: 103 additions & 0 deletions EventListener/SeoFormListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<?php

namespace CanonicalUrl\EventListener;

use CanonicalUrl\CanonicalUrl;
use Thelia\Core\HttpFoundation\Request;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Thelia\Action\BaseAction;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\Event\TheliaFormEvent;
use Thelia\Core\Event\UpdateSeoEvent;
use Thelia\Model\MetaDataQuery;

class SeoFormListener extends BaseAction implements EventSubscriberInterface
{
/** @var \Thelia\Core\HttpFoundation\Request */
protected $request;

/**
* @param Request $request
*/
public function __construct(Request $request)
{
$this->request = $request;
}

public static function getSubscribedEvents()
{
return array(
TheliaEvents::FORM_AFTER_BUILD.'.thelia_seo' => array('addCanonicalField', 128),
TheliaEvents::CATEGORY_UPDATE_SEO => array('saveCategorySeoFields', 128),
TheliaEvents::BRAND_UPDATE_SEO => array('saveBrandSeoFields', 128),
TheliaEvents::CONTENT_UPDATE_SEO => array('saveContentSeoFields', 128),
TheliaEvents::FOLDER_UPDATE_SEO => array('saveFolderSeoFields', 128),
TheliaEvents::PRODUCT_UPDATE_SEO => array('saveProductSeoFields', 128)
);
}

public function saveCategorySeoFields(UpdateSeoEvent $event, $eventName, EventDispatcher $dispatcher)
{
$this->saveSeoFields($event, $eventName, $dispatcher, 'category');
}

public function saveBrandSeoFields(UpdateSeoEvent $event, $eventName, EventDispatcher $dispatcher)
{
$this->saveSeoFields($event, $eventName, $dispatcher, 'brand');
}

public function saveContentSeoFields(UpdateSeoEvent $event, $eventName, EventDispatcher $dispatcher)
{
$this->saveSeoFields($event, $eventName, $dispatcher, 'content');
}

public function saveFolderSeoFields(UpdateSeoEvent $event, $eventName, EventDispatcher $dispatcher)
{
$this->saveSeoFields($event, $eventName, $dispatcher, 'folder');
}

public function saveProductSeoFields(UpdateSeoEvent $event, $eventName, EventDispatcher $dispatcher)
{
$this->saveSeoFields($event, $eventName, $dispatcher, 'product');
}

protected function saveSeoFields(UpdateSeoEvent $event, $eventName, EventDispatcher $dispatcher, $elementKey)
{
$form = $this->request->request->get('thelia_seo');


if (null === $form || !array_key_exists('id', $form) || !array_key_exists('canonical', $form)) {
return;
}

$canonicalValues = [];

$canonicalMetaData = MetaDataQuery::create()
->filterByMetaKey(CanonicalUrl::SEO_CANONICAL_META_KEY)
->filterByElementKey($elementKey)
->filterByElementId($form['id'])
->findOneOrCreate();

if (!$canonicalMetaData->isNew()) {
$canonicalValues = json_decode($canonicalMetaData->getValue(), true);
}

$locale = $form['locale'];
$canonicalValues[$locale] = $form['canonical'];

$canonicalMetaData
->setIsSerialized(0)
->setValue(json_encode($canonicalValues))
->save();
}

public function addCanonicalField(TheliaFormEvent $event)
{
$event->getForm()->getFormBuilder()
->add(
'canonical',
'text'
);
}
}
40 changes: 40 additions & 0 deletions Hook/SeoUpdateFormHook.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace CanonicalUrl\Hook;

use CanonicalUrl\CanonicalUrl;
use Thelia\Core\Event\Hook\HookRenderEvent;
use Thelia\Core\Hook\BaseHook;
use Thelia\Model\MetaDataQuery;

class SeoUpdateFormHook extends BaseHook
{
public function addInputs(HookRenderEvent $event)
{
$id = $event->getArgument('id');
$type = $event->getArgument('type');

$canonical = null;
$canonicalMetaData = MetaDataQuery::create()
->filterByMetaKey(CanonicalUrl::SEO_CANONICAL_META_KEY)
->filterByElementKey($type)
->filterByElementId($id)
->findOneOrCreate();

$canonicalMetaDataValues = json_decode($canonicalMetaData->getValue(), true);

$lang = $this->getSession()->getAdminEditionLang();

if (isset($canonicalMetaDataValues[$lang->getLocale()])) {
$canonical = $canonicalMetaDataValues[$lang->getLocale()];
}

$event->add($this->render(
'hook-seo-update-form.html',
[
'form' => $event->getArgument('form'),
'canonical' => $canonical
]
));
}
}
5 changes: 5 additions & 0 deletions I18n/backOffice/default/en_US.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

return array(
'Surcharge de l\'url canonique' => 'Canonical url override',
);
6 changes: 4 additions & 2 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,11 @@ This module generates a canonical URL for every page of your shop. Once activate
Add it in your main thelia composer.json file

```
composer require thelia/canonical-url-module:~1.1.0
composer require thelia/canonical-url-module:~1.2.0
```
## Usage
You just have to activate the module and check the meta tags of your shop.
You just have to activate the module and check the meta tags of your shop.
The canonical will be generated automatically but you can define a canonical url in seo form for each item if you want override the generated url.
6 changes: 6 additions & 0 deletions templates/backOffice/default/hook-seo-update-form.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{form_field form=$form field='canonical' }
<div class="form-group">
<label for="{$name}">{intl l="Surcharge de l'url canonique" d="canonicalurl.bo.default"}</label>
<input type="text" id="{$name}" name="{$name}" value="{$canonical}" class="form-control">
</div>
{/form_field}

0 comments on commit 9ae1a76

Please sign in to comment.