add sitemap module

parent 3a83d078
<?php
/**
* @link https://github.com/himiklab/yii2-sitemap-module
* @copyright Copyright (c) 2014 HimikLab
* @license http://opensource.org/licenses/MIT MIT
*/
namespace frontend\modules\sitemap;
use Yii;
use yii\base\InvalidConfigException;
use yii\base\Module;
use yii\caching\Cache;
use common\modules\languages\models\Languages;
/**
* Yii2 module for automatically generating XML Sitemap.
*
* @author HimikLab
* @package himiklab\sitemap
*/
class Sitemap extends Module
{
public $controllerNamespace = 'frontend\modules\sitemap\controllers';
/** @var int */
public $cacheExpire = 86400;
/** @var Cache|string */
public $cacheProvider = 'cache';
/** @var string */
public $cacheKey = 'sitemap';
/** @var boolean Use php's gzip compressing. */
public $enableGzip = false;
/** @var array */
public $models = [];
/** @var array */
public $urls = [];
public function init()
{
parent::init();
if (is_string($this->cacheProvider)) {
$this->cacheProvider = Yii::$app->{$this->cacheProvider};
}
if (!$this->cacheProvider instanceof Cache) {
throw new InvalidConfigException('Invalid `cacheKey` parameter was specified.');
}
}
/**
* Build and cache a site map.
* @return string
* @throws \yii\base\InvalidConfigException
*/
public function buildSitemap()
{
$urls = $this->urls;
foreach ($this->models as $modelName)
{
/** @var behaviors\SitemapBehavior $model */
if (is_array($modelName))
{
$model = new $modelName['class'];
if (isset($modelName['behaviors'])) {
$model->attachBehaviors($modelName['behaviors']);
}
}
else
{
$model = new $modelName;
}
$urls = array_merge($urls, $model->generateSiteMap());
}
$langs = Languages::find()->where(['!=', 'default', 1])->all();
$sitemapData = $this->createControllerByID('default')->renderPartial('index', [
'urls' => $urls,
'langs' => $langs
]);
$this->cacheProvider->set($this->cacheKey, $sitemapData, $this->cacheExpire);
return $sitemapData;
}
}
<?php
/**
* @link https://github.com/himiklab/yii2-sitemap-module
* @copyright Copyright (c) 2014 HimikLab
* @license http://opensource.org/licenses/MIT MIT
*/
namespace frontend\modules\sitemap\behaviors;
use yii\base\Behavior;
use yii\base\InvalidConfigException;
/**
* Behavior for XML Sitemap Yii2 module.
*
* For example:
*
* ```php
* public function behaviors()
* {
* return [
* 'sitemap' => [
* 'class' => SitemapBehavior::className(),
* 'scope' => function ($model) {
* $model->select(['url', 'lastmod']);
* $model->andWhere(['is_deleted' => 0]);
* },
* 'dataClosure' => function ($model) {
* return [
* 'loc' => Url::to($model->url, true),
* 'lastmod' => strtotime($model->lastmod),
* 'changefreq' => SitemapBehavior::CHANGEFREQ_DAILY,
* 'priority' => 0.8
* ];
* }
* ],
* ];
* }
* ```
*
* @see http://www.sitemaps.org/protocol.html
* @author HimikLab
* @package himiklab\sitemap
*/
class SitemapBehavior extends Behavior
{
const CHANGEFREQ_ALWAYS = 'always';
const CHANGEFREQ_HOURLY = 'hourly';
const CHANGEFREQ_DAILY = 'daily';
const CHANGEFREQ_WEEKLY = 'weekly';
const CHANGEFREQ_MONTHLY = 'monthly';
const CHANGEFREQ_YEARLY = 'yearly';
const CHANGEFREQ_NEVER = 'never';
const BATCH_MAX_SIZE = 100;
/** @var callable */
public $dataClosure;
/** @var string|bool */
public $defaultChangefreq = false;
/** @var float|bool */
public $defaultPriority = false;
/** @var callable */
public $scope;
public function init()
{
if (!is_callable($this->dataClosure)) {
throw new InvalidConfigException('SitemapBehavior::$dataClosure isn\'t callable.');
}
}
public function generateSiteMap()
{
$result = [];
$n = 0;
/** @var \yii\db\ActiveRecord $owner */
$owner = $this->owner;
$query = $owner::find();
if (is_callable($this->scope)) {
call_user_func($this->scope, $query);
}
foreach ($query->each(self::BATCH_MAX_SIZE) as $model) {
$urlData = call_user_func($this->dataClosure, $model);
if (empty($urlData)) {
continue;
}
$result[$n]['loc'] = $urlData['loc'];
$result[$n]['lastmod'] = $urlData['lastmod'];
if (isset($urlData['changefreq'])) {
$result[$n]['changefreq'] = $urlData['changefreq'];
} elseif ($this->defaultChangefreq !== false) {
$result[$n]['changefreq'] = $this->defaultChangefreq;
}
if (isset($urlData['priority'])) {
$result[$n]['priority'] = $urlData['priority'];
} elseif ($this->defaultPriority !== false) {
$result[$n]['priority'] = $this->defaultPriority;
}
if (isset($urlData['news'])) {
$result[$n]['news'] = $urlData['news'];
}
if (isset($urlData['images'])) {
$result[$n]['images'] = $urlData['images'];
}
++$n;
}
return $result;
}
}
<?php
/**
* @link https://github.com/himiklab/yii2-sitemap-module
* @copyright Copyright (c) 2014 HimikLab
* @license http://opensource.org/licenses/MIT MIT
*/
namespace frontend\modules\sitemap\controllers;
use Yii;
use yii\web\Controller;
/**
* @author HimikLab
* @package himiklab\sitemap
*/
class DefaultController extends Controller
{
public function actionIndex()
{
/** @var \himiklab\sitemap\Sitemap $module */
$module = $this->module;
if (!$sitemapData = $module->cacheProvider->get($module->cacheKey))
{
$sitemapData = $module->buildSitemap();
}
Yii::$app->response->format = \yii\web\Response::FORMAT_RAW;
$headers = Yii::$app->response->headers;
$headers->add('Content-Type', 'application/xml');
if ($module->enableGzip)
{
$sitemapData = gzencode($sitemapData);
$headers->add('Content-Encoding', 'gzip');
$headers->add('Content-Length', strlen($sitemapData));
}
return $sitemapData;
}
}
<?php
/**
* @link https://github.com/himiklab/yii2-sitemap-module
* @copyright Copyright (c) 2014 HimikLab
* @license http://opensource.org/licenses/MIT MIT
*
* @var array $urls
*/
echo '<?xml version="1.0" encoding="UTF-8"?>' . PHP_EOL;
?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"
xmlns:news="http://www.google.com/schemas/sitemap-news/0.9"
xmlns:xhtml="http://www.w3.org/1999/xhtml">
<?php foreach ($urls as $url): ?>
<url>
<loc><?= yii\helpers\Url::to($url['loc'], true) ?></loc>
<?php if($langs) :
foreach ($langs as $lang) : ?>
<xhtml:link rel="alternate" hreflang="<?=$lang->url?>" href="<?= yii\helpers\Url::to('/'.$lang->url.'/'.$url['loc'], true) ?>"/>
<?php endforeach;
endif; ?>
<?php if (isset($url['lastmod'])): ?>
<lastmod><?= is_string($url['lastmod']) ?
$url['lastmod'] : date(DATE_W3C, $url['lastmod']) ?></lastmod>
<?php endif; ?>
<?php if (isset($url['changefreq'])): ?>
<changefreq><?= $url['changefreq'] ?></changefreq>
<?php endif; ?>
<?php if (isset($url['priority'])): ?>
<priority><?= $url['priority'] ?></priority>
<?php endif; ?>
<?php if (isset($url['news'])): ?>
<news:news>
<news:publication>
<news:name><?= $url['news']['publication']['name'] ?></news:name>
<news:language><?= $url['news']['publication']['language'] ?></news:language>
</news:publication>
<?php
echo isset($url['news']['access']) ? "<news:access>{$url['news']['access']}</news:access>" : '';
echo isset($url['news']['genres']) ? "<news:genres>{$url['news']['genres']}</news:genres>" : '';
?>
<news:publication_date>
<?= is_string($url['news']['publication_date']) ?
$url['news']['publication_date'] : date(DATE_W3C, $url['news']['publication_date']) ?>
</news:publication_date>
<news:title> <?= $url['news']['title'] ?></news:title>
<?php
echo isset($url['news']['keywords']) ?
"<news:keywords>{$url['news']['keywords']}</news:keywords>" : '';
echo isset($url['news']['stock_tickers']) ?
"<news:stock_tickers>{$url['news']['stock_tickers']}</news:stock_tickers>" : '';
?>
</news:news>
<?php endif; ?>
<?php if (isset($url['images'])):
foreach ($url['images'] as $image): ?>
<image:image>
<image:loc><?= yii\helpers\Url::to($image['loc'], true) ?></image:loc>
<?php
echo isset($image['caption']) ?
"<image:caption>{$image['caption']}</image:caption>" : '';
echo isset($image['geo_location']) ?
"<image:geo_location>{$image['geo_location']}</image:geo_location>" : '';
echo isset($image['title']) ?
"<image:title>{$image['title']}</image:title>" : '';
echo isset($image['license']) ?
"<image:license>{$image['license']}</image:license>" : '';
?>
</image:image>
<?php endforeach;
endif; ?>
</url>
<?php endforeach; ?>
</urlset>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment