Skip to content

Commit

Permalink
Code Refactoring. Added "defaultValue" option
Browse files Browse the repository at this point in the history
  • Loading branch information
shershennm committed Dec 29, 2016
1 parent ea55756 commit 9d81371
Show file tree
Hide file tree
Showing 4 changed files with 241 additions and 182 deletions.
42 changes: 23 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@ Yii2 module for easy creating meta tags
# Usage
in config file:
```sh
...
'bootstrap' => ['log', 'seo'], // add seo component to application bootstrap
...
'components' => [
...
'seo' => [
'class' => 'shershennm\seo\Seo',
'controllerMapping' => [
'app\controllers' => 'app\seo\controllers', \\controllers for seo module
'app\controllers' => 'app\seo\controllers', // controller namespace for seo module
],

],
...
'bootstrap' => ['log', 'seo'],
...
]
```
seo controller example:
Expand All @@ -29,21 +29,25 @@ use Yii;
use shershennm\seo\SeoController;

class SiteController extends SeoController
{
public function actionIndex()
{
$this->title = 'Hello world!';

return [
['name' => 'keywords', 'value' => $this->getKeywords()],
['name' => 'description', 'value' => 'Cool page!'],
];
}

private function getKeywords()
{
return implode($this->controller->words, ', ');
}
{
/**
* $viewParams array View Params from actionIndex in SiteController
**/
public function actionIndex($viewParams)
{
$this->title = 'Hello world!';

return [
['name' => 'keywords', 'content' => $this->getKeywords()], // params for Html::tag('meta', '', $params)
['name' => 'description', 'content' => 'Cool page!'],
];
}

private function getKeywords()
{
// $this->controller instance of current controller
return implode($this->controller->words, ', ');
}

....
```
270 changes: 151 additions & 119 deletions Seo.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,130 +3,162 @@
namespace shershennm\seo;

use Yii;

use yii\base\ActionEvent;
use yii\base\Component;
use yii\base\ViewEvent;

use yii\web\Controller;
use yii\web\View;

use yii\helpers\Html;

use shershennm\seo\Title;

/**
*
*/
*
*/
class Seo extends Component
{
public
$controllerMapping,

$titleAppend,
$titlePrepend;

private
$_controller,
$_reflectionController;

public function getController()
{
if ($this->_controller === null)
{
$this->_controller = Yii::$app->controller;
}

return $this->_controller;
}

public function getReflectionController()
{
if ($this->_reflectionController === null)
{
$this->_reflectionController = $this->buildReflectionController();
}

return $this->_reflectionController;
}


public function init()
{
parent::init();

if (Yii::$app->view !== null)
{
Yii::$app->view->on(yii\web\View::EVENT_BEGIN_PAGE, [$this, 'eventSetMeta']);
}
}

public function eventSetMeta()
{
if ($this->isValidController() && $this->isSeoControllerInMapping() && $this->isSeoControllerExists())
{
$seoController = Yii::createObject($this->buildSeoControllerClassName());
$actionMethod = $this->controller->action->actionMethod;

if (method_exists($seoController, $actionMethod))
{
$seoController->controller = $this->controller;

$meta = $seoController->$actionMethod();
$this->addMeta($meta);

if ($seoController->title !== null)
{
Yii::$app->view->title = $this->buildTitle($seoController->title);
}
}
}
}

private function buildTitle($title)
{
$defaults = [
'defaultPrepend' => $this->titlePrepend,
'defaultAppend' => $this->titleAppend,
];

if(is_array($title)) {
$title = new Title(array_merge($title, $defaults));
}
else
{
$title = new Title(array_merge(['title' => $title], $defaults));
}

return $title->buildTitle();
}

private function addMeta($metaArray)
{
foreach ($metaArray as $meta) {
Yii::$app->view->metaTags[] = Html::tag('meta', '', $meta);
}
}

private function buildReflectionController()
{
return (new \ReflectionClass($this->controller));
}

private function isSeoControllerInMapping()
{
return isset($this->controllerMapping[$this->reflectionController->getNamespaceName()]);
}

private function isSeoControllerExists()
{
return class_exists($this->buildSeoControllerClassName());
}

private function isValidController()
{
return (Yii::$app->controller !== null && Yii::$app->controller->action->className() !== 'yii\web\ErrorAction');
}

private function buildSeoControllerClassName()
{
return sprintf('%s\%s', $this->controllerMapping[$this->reflectionController->getNamespaceName()], $this->reflectionController->getShortName());
}

private function buildActionFunction()
{
return sprintf('action%s', ucfirst($this->controller->action->id));
}
public
$controllerMapping,

$defaultTitle,
$titleAppend,
$titlePrepend;

private
$_reflectionController;

public function getController()
{
return Yii::$app->controller;
}

public function getReflectionController()
{
if ($this->_reflectionController === null)
{
$this->_reflectionController = $this->buildReflectionController();
}

return $this->_reflectionController;
}

public function init()
{
$this->initEventBranches();

parent::init();
}

private function initEventBranches()
{
ActionEvent::on(Controller::className(), Controller::EVENT_BEFORE_ACTION, [$this, 'eventControllerBeforeAction']);
}

public function eventControllerBeforeAction($event)
{
ActionEvent::off(Controller::className(), Controller::EVENT_BEFORE_ACTION, [$this, 'eventControllerBeforeAction']);

$event->sender->view->on(View::EVENT_BEFORE_RENDER, [$this, 'eventViewBeforeRender']);
}

public function eventViewBeforeRender($event)
{
$event->sender->off(View::EVENT_BEFORE_RENDER, [$this, 'eventViewBeforeRender']);

$this->setMeta($event);
}

public function setMeta($viewEvent)
{
$set = false;

if ($this->isValidController() && $this->isSeoControllerInMapping() && $this->isSeoControllerExists())
{
$set = $this->executeSeoControllerAction($viewEvent);
}

if ($set === false)
{
$this->addTitle($viewEvent->sender);
}
}

private function executeSeoControllerAction($viewEvent)
{
$seoController = Yii::createObject($this->buildSeoControllerClassName());
$actionMethod = $this->controller->action->actionMethod;

if (method_exists($seoController, $actionMethod))
{
$seoController->controller = $this->controller;

$meta = $seoController->$actionMethod($viewEvent->params);

$this->addMeta($viewEvent->sender, $meta);
$this->addTitle($viewEvent->sender, $seoController->title);

return true;
}

return false;
}

private function buildTitle($title)
{
$defaults = [
'defaultTitle' => $this->defaultTitle,
'defaultPrepend' => $this->titlePrepend,
'defaultAppend' => $this->titleAppend,
];

if(is_array($title)) {
$title = new Title(array_merge($title, $defaults));
}
else
{
$title = new Title(array_merge(['title' => $title], $defaults));
}

return $title->buildTitle();
}

public function addMeta($view, $metaArray)
{
foreach ($metaArray as $meta) {
$view->metaTags[] = Html::tag('meta', '', $meta);
}
}

public function addTitle($view, $title = null)
{
$view->title = $this->buildTitle($title);
}

private function buildReflectionController()
{
return (new \ReflectionClass($this->controller));
}

private function isSeoControllerInMapping()
{
return isset($this->controllerMapping[$this->reflectionController->getNamespaceName()]);
}

private function isSeoControllerExists()
{
return class_exists($this->buildSeoControllerClassName());
}

private function isValidController()
{
return (Yii::$app->controller !== null && Yii::$app->controller->action->className() !== 'yii\web\ErrorAction');
}

private function buildSeoControllerClassName()
{
return sprintf('%s\%s', $this->controllerMapping[$this->reflectionController->getNamespaceName()], $this->reflectionController->getShortName());
}
}
12 changes: 9 additions & 3 deletions SeoController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@

abstract class SeoController extends Object
{
public
$controller,
$title;
/**
* @var $title string Page <title> tag value
*/
public $title;

/**
* @var $controller \yii\web\Controller Web Controller instance
*/
public $controller;
}
Loading

0 comments on commit 9d81371

Please sign in to comment.