diff --git a/backend/config/main.php b/backend/config/main.php
index 9b04722..d0fda70 100755
--- a/backend/config/main.php
+++ b/backend/config/main.php
@@ -1,4 +1,6 @@
false,
'rules' => [],
],
+ 'sitemap' => [
+ 'class' => Sitemap::className(),
+ 'entities' => [
+ [
+ 'class' => Page::className(),
+ 'conditions' => [
+ [ 'in_menu' => 1 ],
+ ],
+ 'url' => 'site/page',
+ ],
+ ],
+ ],
],
'params' => $params,
];
diff --git a/backend/controllers/SitemapController.php b/backend/controllers/SitemapController.php
new file mode 100755
index 0000000..0ad1fa2
--- /dev/null
+++ b/backend/controllers/SitemapController.php
@@ -0,0 +1,247 @@
+ [
+ 'class' => AccessControl::className(),
+ 'rules' => [
+ [
+ 'actions' => [
+ 'login',
+ 'error',
+ ],
+ 'allow' => true,
+ ],
+ [
+ 'allow' => true,
+ 'roles' => [ '@' ],
+ ],
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * Action to configure sitemap of the website
+ *
+ * @return string
+ */
+ public function actionIndex()
+ {
+ return $this->render('index');
+ }
+
+ /**
+ * Action to configure sitemap of the website
+ *
+ * @return string
+ */
+ public function actionUpdate()
+ {
+ /**
+ * @var Sitemap $sitemap
+ */
+ $request = \Yii::$app->request;
+ // ***** Generate SitemapDynamic models for every entity in Sitemap component
+ $sitemap = \Yii::$app->get('sitemap');
+ $entities = $sitemap->entities;
+ /**
+ * @var SitemapDynamic[] $entity_models
+ */
+ $entity_models = [];
+ foreach ($entities as $entity) {
+ $entity_model = new SitemapDynamic();
+ $entity_model->entity = $entity[ 'class' ];
+ $entity_model->status = SitemapDynamic::STATUS_DISABLED;
+ $entity_models[] = $entity_model;
+ }
+ // ***** <<< End
+ if ($request->isPost) {
+ $success = false;
+ // ***** Create SitemapStatic models from POST and delete existing
+ $models = [];
+ $index = 1;
+ foreach ($request->post('SitemapStatic') as $item) {
+ $model = new SitemapStatic();
+ if ($model->load($item, '') && $model->validate()) {
+ $model->id = $index++;
+ $models[] = $model;
+ }
+ }
+ if (!empty( $models )) {
+ $old = SitemapStatic::find()
+ ->all();
+ foreach ($old as $item) {
+ $item->delete();
+ }
+ foreach ($models as $model) {
+ $model->save(false);
+ $success = true;
+ }
+ }
+ // ***** <<< End
+ // ***** Create SitemapDynamic models from POST and delete existing
+
+ /**
+ * @var SitemapDynamic[] $old_entity_models
+ */
+ $old_entity_models = SitemapDynamic::find()
+ ->all();
+ foreach ($old_entity_models as $old_entity_model) {
+ $old_entity_model->delete();
+ }
+ $index = 1;
+ $entity_models = [];
+ foreach ($request->post('SitemapDynamic') as $item) {
+ $entity = new SitemapDynamic();
+ if ($entity->load($item, '') && $entity->validate()) {
+ $entity->id = $index++;
+ $entity->save(false);
+ $entity_models[] = $entity;
+ $success = true;
+ }
+ }
+ if ($success) {
+ if ($request->post('action', '') == 'generate') {
+ if ($sitemap->generateXML()) {
+ \Yii::$app->session->setFlash(
+ 'success',
+ \Yii::t(
+ 'core',
+ 'Sitemap generated to ' . \Yii::getAlias(
+ $sitemap->path . '.'
+ )
+ )
+ );
+ }
+ }
+ return $this->redirect([ 'index' ]);
+ }
+ // ***** <<< End
+ } else {
+ // ***** Find existing SitemapStatic models
+ $models = SitemapStatic::find()
+ ->all();
+ if (empty( $models )) {
+ $models = [ new SitemapStatic() ];
+ }
+ // ***** <<< End
+ // ***** Fill SitemapDynamic models from Sitemap component with existing models
+ /**
+ * @var SitemapDynamic[] $old_entity_models
+ */
+ $old_entity_models = SitemapDynamic::find()
+ ->indexBy('entity')
+ ->all();
+ foreach ($entity_models as $index => $entity_model) {
+ if (isset( $old_entity_models[ $entity_model->entity ] )) {
+ $entity_model->status = $old_entity_models[ $entity_model->entity ]->status;
+ $entity_model->priority = $old_entity_models[ $entity_model->entity ]->priority;
+ }
+ }
+ // ***** <<< End
+ }
+ return $this->render(
+ 'update',
+ [
+ 'models' => $models,
+ 'entity_models' => $entity_models,
+ ]
+ );
+ }
+
+ /**
+ * Create activeField for static sitemap
+ *
+ * @return string
+ */
+ public function actionCreateStatic()
+ {
+ $content = '';
+ $request = \Yii::$app->request;
+ $formId = $request->get('formId');
+ $count = $request->get('count');
+ if (empty( $formId ) || empty( $count )) {
+ return $this->renderContent($content);
+ }
+ $model = new SitemapStatic();
+ $form = new ActiveForm();
+ $content .= $form->field(
+ $model,
+ "[$count]url",
+ [
+ 'options' => [
+ 'class' => 'form-group col-xs-8 col-sm-9',
+ ],
+ ]
+ )
+ ->textInput()
+ ->render();
+ $content .= $form->field(
+ $model,
+ "[$count]priority",
+ [
+ 'options' => [
+ 'class' => 'form-group col-xs-3 col-sm-2',
+ ],
+ ]
+ )
+ ->textInput()
+ ->render();
+ $content .= Html::icon(
+ 'minus',
+ [
+ 'class' => 'col-xs-1 field-group-remove',
+ 'onclick' => 'sitemap_remove(this)',
+ ]
+ );
+ foreach ($form->attributes as $index => $attribute) {
+ $content .= Html::script("$('#w0').yiiActiveForm('add', " . Json::htmlEncode($attribute) . ");");
+ }
+ $content = Html::tag(
+ 'div',
+ $content,
+ [
+ 'class' => 'row field-group',
+ ]
+ );
+ $this->layout = false;
+ return $this->renderContent($content);
+ }
+
+ /**
+ * Generate sitemap XML to Sitemap::$path
+ *
+ * @return bool
+ */
+ public function actionGenerate()
+ {
+ $response = \Yii::$app->response;
+ $response->format = $response::FORMAT_JSON;
+ /**
+ * @var Sitemap $sitemap
+ */
+ $sitemap = \Yii::$app->get('sitemap');
+ return $sitemap->generateXML();
+ }
+ }
+
\ No newline at end of file
diff --git a/backend/views/layouts/main.php b/backend/views/layouts/main.php
index 23ac713..f22cbb6 100755
--- a/backend/views/layouts/main.php
+++ b/backend/views/layouts/main.php
@@ -172,7 +172,7 @@
],
[
'label' => \Yii::t('core', 'Sitemap'),
- 'url' => [ 'seo/sitemap' ],
+ 'url' => [ '/sitemap/index' ],
'icon' => 'map-signs',
],
],
diff --git a/backend/views/sitemap/index.php b/backend/views/sitemap/index.php
new file mode 100644
index 0000000..4ec692a
--- /dev/null
+++ b/backend/views/sitemap/index.php
@@ -0,0 +1,74 @@
+title = \Yii::t('core', 'Sitemap');
+ $this->params[ 'breadcrumbs' ][] = $this->title;
+?>
+
+ false,
+ 'title' => $this->title,
+ 'options' => [
+ 'class' => 'sitemap-buttons',
+ ],
+ ]
+ );
+ ?>
+
+
+ 'fa fa-',
+ ]
+ ) . \Yii::t('core', 'Edit'),
+ [ 'update' ],
+ [
+ 'class' => 'btn btn-app',
+ ]
+ );
+ ?>
+
+
+ 'fa fa-',
+ 'class' => 'indexed',
+ ]
+ ) . Html::tag(
+ 'span',
+ \Yii::t('core', 'Generate'),
+ [
+ 'class' => 'indexed',
+ ]
+ ) . Html::tag(
+ 'div',
+ ' ',
+ [
+ 'class' => 'spinner',
+ ]
+ ),
+ [ 'generate' ],
+ [
+ 'class' => 'btn btn-app ajax',
+ ]
+ );
+ ?>
+
+
+
+
diff --git a/backend/views/sitemap/update.php b/backend/views/sitemap/update.php
new file mode 100644
index 0000000..9a386bf
--- /dev/null
+++ b/backend/views/sitemap/update.php
@@ -0,0 +1,179 @@
+params[ 'breadcrumbs' ][] = [
+ 'label' => \Yii::t('core', 'Sitemap'),
+ 'url' => [ 'index' ],
+ ];
+ $this->title = \Yii::t('core', 'Update sitemap');
+ $this->params[ 'breadcrumbs' ][] = $this->title;
+ $form = ActiveForm::begin();
+ $xPanel = XPanel::begin(
+ [
+ 'title' => \Yii::t('core', 'Static pages'),
+ 'toolbarLayout' => '{collapse}',
+ 'options' => [
+ 'class' => 'dynamic_fields',
+ ],
+ ]
+ );
+ foreach ($models as $index => $model) {
+ echo Html::tag(
+ 'div',
+ $form->field(
+ $model,
+ "[$index]url",
+ [
+ 'options' => [
+ 'class' => 'form-group col-xs-8 col-sm-9',
+ ],
+ ]
+ )
+ ->textInput() . $form->field(
+ $model,
+ "[$index]priority",
+ [
+ 'options' => [
+ 'class' => 'form-group col-xs-3 col-sm-2',
+ ],
+ ]
+ )
+ ->textInput() . Html::icon(
+ 'minus',
+ [
+ 'class' => 'col-xs-1 field-group-remove',
+ 'onclick' => 'sitemap_remove(this)',
+ ]
+ ),
+ [
+ 'class' => 'row field-group',
+ ]
+ );
+ }
+ echo Html::button(
+ \Yii::t('core', 'Add field'),
+ [
+ 'class' => 'btn btn-default',
+ 'onclick' => 'sitemap_add(this)',
+ 'data' => [
+ 'url' => Url::to([ 'create-static' ]),
+ ],
+ ]
+ );
+ $xPanel::end();
+ $xPanel2 = XPanel::begin(
+ [
+ 'title' => \Yii::t('core', 'Dynamic pages'),
+ 'toolbarLayout' => '{collapse}',
+ ]
+ );
+?>
+
+ getAttributeLabel('priority'); ?>
+
+ $entity_model) {
+ ?>
+
+ 'form-control',
+ 'readonly' => 1,
+ ]
+ ) . Html::tag(
+ 'span',
+ Html::activeCheckbox(
+ $entity_model,
+ "[$index]status",
+ [
+ 'label' => false,
+ ]
+ ),
+ [
+ 'class' => 'input-group-addon',
+ ]
+ ),
+ [
+ 'class' => 'input-group',
+ ]
+ );
+ ?>
+
+
+ field($entity_model, "[$index]priority")
+ ->label(false)
+ ->input(
+ 'number',
+ [
+ 'step' => 0.1,
+ 'min' => 0,
+ 'max' => 1,
+ ]
+ );
+ ?>
+
+ 'btn btn-success',
+ ]
+ );
+ echo Html::submitButton(
+ \Yii::t('core', 'Save and generate'),
+ [
+ 'class' => 'btn btn-primary',
+ 'name' => 'action',
+ 'value' => 'generate',
+ ]
+ );
+ $form::end();
+ $js = << 1) {
+ $(e)
+ .parents('.field-group')
+ .remove();
+ }
+ }
+JS;
+ $this->registerJs($js, $this::POS_END);
\ No newline at end of file
diff --git a/common/components/Sitemap.php b/common/components/Sitemap.php
new file mode 100644
index 0000000..c4bfd25
--- /dev/null
+++ b/common/components/Sitemap.php
@@ -0,0 +1,122 @@
+saveXML($this->generateOneShot());
+ }
+
+ /**
+ * Save generated xml to $path file
+ *
+ * @param string $xml
+ *
+ * @return bool
+ */
+ protected function saveXML(string $xml): bool
+ {
+ $realpath = \Yii::getAlias($this->path);
+ if (file_put_contents($realpath, $xml)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Generate xml from configs
+ *
+ * @return string
+ */
+ public function generateOneShot(): string
+ {
+ $content = '';
+ $content .= '';
+ /**
+ * @var SitemapStatic[] $static
+ */
+ // ***** Begin generating static pages
+ $static = SitemapStatic::find()
+ ->all();
+ foreach ($static as $item) {
+ $content .= Html::tag(
+ 'url',
+ Html::tag('loc', $item->url) . Html::tag('lastmod', date('Y-m-d')) . Html::tag(
+ 'changefreq',
+ 'monthly'
+ ) . Html::tag('priority', $item->priority)
+ );
+ }
+ // ***** <<< End
+ /**
+ * @var SitemapDynamic $dynamic
+ */
+ $dynamic = SitemapDynamic::find()
+ ->indexBy('entity')
+ ->where([ 'status' => 1 ])
+ ->all();
+ $entities = $this->entities;
+ foreach ($entities as $entity) {
+ /**
+ * @var string $class
+ */
+ $class = $entity[ 'class' ];
+ /**
+ * @var ActiveRecord $classInstance
+ */
+ $classInstance = new $class();
+ if (is_subclass_of($classInstance, ActiveRecord::className())) {
+ if (!empty( $dynamic[ $class ] )) {
+ /**
+ * @var SitemapDynamic $model
+ */
+ $model = $dynamic[ $class ];
+ $query = $classInstance::find();
+ if (isset( $entity[ 'conditions' ] )) {
+ foreach ($entity[ 'conditions' ] as $condition) {
+ $query->where($condition);
+ }
+ }
+ $result = $query->all();
+ foreach ($result as $record) {
+ $content .= Html::tag(
+ 'url',
+ Html::tag(
+ 'loc',
+ Url::to(
+ [
+ $entity[ 'url' ],
+ 'id' => $record->getAttribute('id'),
+ ],
+ true
+ )
+ ) . Html::tag('lastmod', date('Y-m-d')) . Html::tag(
+ 'changefreq',
+ 'monthly'
+ ) . Html::tag('priority', $model->priority)
+ );
+ }
+ }
+ }
+ }
+ $content .= '';
+ return $content;
+ }
+ }
\ No newline at end of file
diff --git a/common/config/SitemapDynamic.php b/common/config/SitemapDynamic.php
new file mode 100644
index 0000000..b90b5a0
--- /dev/null
+++ b/common/config/SitemapDynamic.php
@@ -0,0 +1,10 @@
+ [
+ 'entity' => 'artbox\\core\\models\\Page',
+ 'status' => '1',
+ 'priority' => '0.6',
+ 'id' => 1,
+ ],
+ ];
\ No newline at end of file
diff --git a/common/config/SitemapStatic.php b/common/config/SitemapStatic.php
new file mode 100644
index 0000000..17cea76
--- /dev/null
+++ b/common/config/SitemapStatic.php
@@ -0,0 +1,9 @@
+ [
+ 'url' => 'http://www.artbox.dev/',
+ 'priority' => '1',
+ 'id' => 1,
+ ],
+ ];
\ No newline at end of file
diff --git a/common/config/main.php b/common/config/main.php
index ad48c82..c27e905 100644
--- a/common/config/main.php
+++ b/common/config/main.php
@@ -4,10 +4,10 @@
return [
'vendorPath' => dirname(dirname(__DIR__)) . '/vendor',
'components' => [
- 'cache' => [
+ 'cache' => [
'class' => 'yii\caching\FileCache',
],
- 'i18n' => [
+ 'i18n' => [
'translations' => [
'core' => [
'class' => 'yii\i18n\PhpMessageSource',
@@ -15,11 +15,16 @@
],
],
],
- 'filedb' => [
+ 'filedb' => [
'class' => 'yii2tech\filedb\Connection',
'path' => '@common/config',
],
- 'seo' => [
+ 'sitemapdb' => [
+ 'class' => 'yii2tech\filedb\Connection',
+ 'path' => '@common/config',
+ 'primaryKeyName' => 'id',
+ ],
+ 'seo' => [
'class' => SeoComponent::className(),
],
],
diff --git a/common/models/SitemapDynamic.php b/common/models/SitemapDynamic.php
new file mode 100644
index 0000000..2ecb05b
--- /dev/null
+++ b/common/models/SitemapDynamic.php
@@ -0,0 +1,115 @@
+get('sitemapdb');
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function attributes()
+ {
+ return [
+ 'id',
+ 'entity',
+ 'status',
+ 'priority',
+ ];
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public static function primaryKey()
+ {
+ return [ 'id' ];
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function rules()
+ {
+ return [
+ [
+ [
+ 'entity',
+ 'status',
+ 'priority',
+ ],
+ 'required',
+ ],
+ [
+ [
+ 'status',
+ ],
+ 'boolean',
+ ],
+ [
+ [
+ 'entity',
+ ],
+ 'string',
+ ],
+ [
+ [
+ 'priority',
+ ],
+ 'double',
+ 'min' => 0,
+ 'max' => 1,
+ ],
+ ];
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function attributeLabels()
+ {
+ return [
+ 'id' => Yii::t('core', 'ID'),
+ 'entity' => Yii::t('core', 'Model'),
+ 'status' => Yii::t('core', 'Status'),
+ 'priority' => Yii::t('core', 'Priority'),
+ ];
+ }
+
+ /**
+ * Find maximum ID value from SitemapStatic models
+ */
+ public static function max(): int
+ {
+ $models = self::find()
+ ->all();
+ $array = ArrayHelper::getColumn($models, self::primaryKey()[ 0 ], false);
+ if (empty( $array )) {
+ return 0;
+ } else {
+ return max($array);
+ }
+ }
+ }
\ No newline at end of file
diff --git a/common/models/SitemapStatic.php b/common/models/SitemapStatic.php
new file mode 100644
index 0000000..16af9a3
--- /dev/null
+++ b/common/models/SitemapStatic.php
@@ -0,0 +1,101 @@
+get('sitemapdb');
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function attributes()
+ {
+ return [
+ 'id',
+ 'url',
+ 'priority',
+ ];
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public static function primaryKey()
+ {
+ return [ 'id' ];
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function rules()
+ {
+ return [
+ [
+ [
+ 'url',
+ 'priority',
+ ],
+ 'required',
+ ],
+ [
+ [
+ 'priority',
+ ],
+ 'double',
+ 'min' => 0,
+ 'max' => 1,
+ ],
+ [
+ [
+ 'url',
+ ],
+ 'string',
+ ],
+ ];
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function attributeLabels()
+ {
+ return [
+ 'id' => Yii::t('core', 'ID'),
+ 'url' => Yii::t('core', 'Url'),
+ 'priority' => Yii::t('core', 'Priority'),
+ ];
+ }
+
+ /**
+ * Find maximum ID value from SitemapStatic models
+ */
+ public static function max(): int
+ {
+ $models = self::find()
+ ->all();
+ $array = ArrayHelper::getColumn($models, self::primaryKey()[ 0 ], false);
+ if (empty( $array )) {
+ return 0;
+ } else {
+ return max($array);
+ }
+ }
+ }
\ No newline at end of file
--
libgit2 0.21.4