From 20d3b478563164bd1bfeef3add2750d6aaecc016 Mon Sep 17 00:00:00 2001
From: Egorka
Date: Sun, 29 Jul 2018 12:58:42 +0300
Subject: [PATCH] Pages revisions, on fly preview
---
common/modules/blog/controllers/PostController.php | 7 -
common/modules/blog/entities/BlogPost.php | 4 +-
common/modules/blog/forms/BlogPostForm.php | 1 -
.../m180725_091725_add_blog_posts_type_field.php | 1 -
..._113503_remove_blog_posts_slug_unique_index.php | 1 -
.../modules/pages/controllers/PageController.php | 16 +++
.../pages/controllers/manage/PageController.php | 52 ++++++-
common/modules/pages/entities/Page.php | 37 ++++-
.../modules/pages/entities/queries/PageQuery.php | 21 +++
common/modules/pages/forms/PageForm.php | 20 ++-
common/modules/pages/forms/PageSearch.php | 2 +-
common/modules/pages/helpers/PageHelper.php | 40 ++++++
common/modules/pages/messages/ru/page.php | 10 ++
.../m180720_051253_create_pages_table.php | 43 ------
.../m180727_110132_create_pages_table.php | 61 ++++++++
.../m180727_110133_add_pages_revision_fields.php | 35 +++++
.../pages/repositories/read/PageReadRepository.php | 9 +-
.../modules/pages/services/PageManageService.php | 48 ++++++-
common/modules/pages/views/manage/page/_form.php | 68 ++++++---
common/modules/pages/views/manage/page/view.php | 157 ++++++++++++++-------
20 files changed, 488 insertions(+), 145 deletions(-)
create mode 100644 common/modules/pages/entities/queries/PageQuery.php
create mode 100644 common/modules/pages/helpers/PageHelper.php
delete mode 100644 common/modules/pages/migrations/m180720_051253_create_pages_table.php
create mode 100644 common/modules/pages/migrations/m180727_110132_create_pages_table.php
create mode 100644 common/modules/pages/migrations/m180727_110133_add_pages_revision_fields.php
diff --git a/common/modules/blog/controllers/PostController.php b/common/modules/blog/controllers/PostController.php
index 05ec42a..c4e3f39 100644
--- a/common/modules/blog/controllers/PostController.php
+++ b/common/modules/blog/controllers/PostController.php
@@ -2,21 +2,14 @@
namespace common\modules\blog\controllers;
-use common\modules\blog\entities\BlogPost;
use common\modules\blog\forms\BlogCommentForm;
-use common\modules\blog\forms\BlogPostForm;
-use common\modules\blog\helpers\BlogPostHelper;
use common\modules\blog\repositories\read\BlogCategoryReadRepository;
use common\modules\blog\repositories\read\BlogPostReadRepository;
use common\modules\blog\repositories\read\BlogTagReadRepository;
use common\modules\blog\services\BlogCommentService;
-use core\entities\Meta;
use frontend\components\FrontendController;
use Yii;
-use yii\base\Security;
use yii\data\ActiveDataProvider;
-use yii\helpers\FileHelper;
-use yii\helpers\Json;
use yii\web\NotFoundHttpException;
use yii\filters\AccessControl;
diff --git a/common/modules/blog/entities/BlogPost.php b/common/modules/blog/entities/BlogPost.php
index d622613..22abb1c 100644
--- a/common/modules/blog/entities/BlogPost.php
+++ b/common/modules/blog/entities/BlogPost.php
@@ -57,7 +57,7 @@ class BlogPost extends ActiveRecord
public $meta;
- public static function create($categoryId, $title, $slug, $description, $content, $published_at, $video, $type = 0, Meta $meta): self
+ public static function create($categoryId, $title, $slug, $description, $content, $published_at, $video, $type = BlogPost::TYPE_PUBLIC, Meta $meta): self
{
$post = new static();
$post->category_id = $categoryId;
@@ -82,7 +82,7 @@ class BlogPost extends ActiveRecord
}
- public function edit($categoryId, $title, $slug, $description, $content, $published_at, $video, $type = 0, Meta $meta): void
+ public function edit($categoryId, $title, $slug, $description, $content, $published_at, $video, $type = BlogPost::TYPE_PUBLIC, Meta $meta): void
{
$this->category_id = $categoryId;
$this->title = $title;
diff --git a/common/modules/blog/forms/BlogPostForm.php b/common/modules/blog/forms/BlogPostForm.php
index ae209d8..e41fab9 100644
--- a/common/modules/blog/forms/BlogPostForm.php
+++ b/common/modules/blog/forms/BlogPostForm.php
@@ -70,7 +70,6 @@ class BlogPostForm extends CompositeForm
//[['slug'], 'unique', 'targetClass' => BlogPost::class, 'filter' => $this->_post ? ['<>', 'id', $this->_post->id] : ['type' => BlogPost::TYPE_PUBLIC]],
//[['slug'], 'unique', 'targetClass' => BlogPost::class, 'filter' => $this->_post ? ['AND', ['<>', 'id', $this->_post->id], ['type' => BlogPost::TYPE_PUBLIC]] : ['type' => BlogPost::TYPE_PUBLIC]],
[['slug'], 'unique', 'targetClass' => BlogPost::class, 'filter' => function (ActiveQuery $query) {
-
if ($this->type != BlogPost::TYPE_PUBLIC) {
$query->andWhere($this->type . '=' . BlogPost::TYPE_PUBLIC);
}
diff --git a/common/modules/blog/migrations/m180725_091725_add_blog_posts_type_field.php b/common/modules/blog/migrations/m180725_091725_add_blog_posts_type_field.php
index 1ff062b..5ee8d0b 100644
--- a/common/modules/blog/migrations/m180725_091725_add_blog_posts_type_field.php
+++ b/common/modules/blog/migrations/m180725_091725_add_blog_posts_type_field.php
@@ -29,6 +29,5 @@ class m180725_091725_add_blog_posts_type_field extends Migration
$this->dropColumn('{{%blog_posts}}', 'type');
$this->dropColumn('{{%blog_posts}}', 'revision_at');
$this->dropColumn('{{%blog_posts}}', 'revision_id');
- return false;
}
}
diff --git a/common/modules/blog/migrations/m180725_113503_remove_blog_posts_slug_unique_index.php b/common/modules/blog/migrations/m180725_113503_remove_blog_posts_slug_unique_index.php
index 9c0b82f..0ffde39 100644
--- a/common/modules/blog/migrations/m180725_113503_remove_blog_posts_slug_unique_index.php
+++ b/common/modules/blog/migrations/m180725_113503_remove_blog_posts_slug_unique_index.php
@@ -21,7 +21,6 @@ class m180725_113503_remove_blog_posts_slug_unique_index extends Migration
*/
public function safeDown()
{
- return false;
$this->dropIndex('{{%idx-blog_posts-slug}}', '{{%blog_posts}}');
$this->createIndex('{{%idx-blog_posts-slug}}', '{{%blog_posts}}', 'slug');
}
diff --git a/common/modules/pages/controllers/PageController.php b/common/modules/pages/controllers/PageController.php
index 94fb026..3913662 100644
--- a/common/modules/pages/controllers/PageController.php
+++ b/common/modules/pages/controllers/PageController.php
@@ -31,6 +31,11 @@ class PageController extends FrontendController
'allow' => true,
'roles' => ['Pages'],
],
+ [
+ 'actions' => ['preview'],
+ 'allow' => true,
+ 'roles' => ['PagesManagement'],
+ ],
[ // all the action are accessible to admin
'allow' => true,
'roles' => ['admin'],
@@ -56,4 +61,15 @@ class PageController extends FrontendController
'page' => $page,
]);
}
+
+ public function actionPreview($id)
+ {
+ if (!$page = $this->pages->findPreview($id)) {
+ throw new NotFoundHttpException('The requested page does not exist.');
+ }
+
+ return $this->render('view', [
+ 'page' => $page,
+ ]);
+ }
}
diff --git a/common/modules/pages/controllers/manage/PageController.php b/common/modules/pages/controllers/manage/PageController.php
index 22f79e0..91201a8 100644
--- a/common/modules/pages/controllers/manage/PageController.php
+++ b/common/modules/pages/controllers/manage/PageController.php
@@ -6,6 +6,7 @@ use common\modules\pages\forms\PageForm;
use common\modules\pages\services\PageManageService;
use common\modules\pages\entities\Page;
use common\modules\pages\forms\PageSearch;
+use yii\helpers\Url;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
@@ -30,7 +31,6 @@ class PageController extends Controller
'class' => AccessControl::class,
'rules' => [
[
- 'actions' => ['create', 'view', 'index', 'update', 'delete', 'move-up', 'move-down'],
'allow' => true,
'roles' => ['PagesManagement'],
],
@@ -44,6 +44,8 @@ class PageController extends Controller
'class' => VerbFilter::class,
'actions' => [
'delete' => ['POST'],
+ 'restore-history' => ['POST'],
+ 'clear-history' => ['POST'],
],
],
];
@@ -71,11 +73,38 @@ class PageController extends Controller
*/
public function actionView($id)
{
+ $history = Page::find()
+ ->andWhere(['OR', ['revision_id' => $id], ['id' => $id]])
+ ->orderBy(['revision_at' => SORT_DESC])
+ ->limit(20)
+ ->all();
+
return $this->render('view', [
'page' => $this->findModel($id),
+ 'history' => $history,
]);
}
+ public function actionCreatePreview()
+ {
+ $this->service->removePreviews();
+
+ $form = new PageForm();
+ $form->type = Page::TYPE_PREVIEW;
+ if ($form->load(Yii::$app->request->post()) && $form->validate()) {
+ try {
+ $page = $this->service->create($form, Page::TYPE_PREVIEW);
+ return $this->redirect(Url::to(Yii::$app->get('frontendUrlManager')->createAbsoluteUrl(['/pages/page/preview', 'id' => $page->id])));
+ } catch (\DomainException $e) {
+ Yii::$app->errorHandler->logException($e);
+ Yii::$app->session->setFlash('error', $e->getMessage());
+ }
+ }
+ return $this->render('create', [
+ 'model' => $form,
+ ]);
+ }
+
/**
* @return mixed
*/
@@ -162,7 +191,7 @@ class PageController extends Controller
\Yii::$app->response->format = Response::FORMAT_JSON;
$out = ['results' => ['id' => '', 'text' => '']];
if (!is_null($q)) {
- $data = Page::find()->select('id, title as text')->andWhere(['like', 'title', $q])->limit(20)->asArray()->all();
+ $data = Page::find()->select('id, title as text')->andWhere(['tree' => 1])->andWhere(['like', 'title', $q])->limit(20)->asArray()->all();
$out['results'] = array_values($data);
}
elseif ($id > 0) {
@@ -170,12 +199,29 @@ class PageController extends Controller
$out['results'] = ['id' => $tag_name, 'text' => $tag_name];
}
else {
- $data = Page::find()->select('id, title as text')->orderBy(['id' => SORT_DESC])->limit(20)->asArray()->all();
+ $data = Page::find()->select('id, title as text')->andWhere(['tree' => 1])->orderBy(['id' => SORT_DESC])->limit(20)->asArray()->all();
$out['results'] = array_values($data);
}
return $out;
}
+ public function actionRestoreHistory($id)
+ {
+ $page = $this->findModel($id);
+ if ($page_id = $page->revision_id) {
+ $this->service->restoreHistory($id, $page->revision_id);
+ return $this->redirect(['/pages/manage/page/view', 'id' => $page_id]);
+ }
+ return $this->redirect(['/pages/manage/page/index']);
+ }
+
+ public function actionClearHistory($id)
+ {
+ $page = $this->findModel($id);
+ $this->service->clearHistory($page);
+ return $this->redirect(['/pages/manage/page/view', 'id' => $page->id]);
+ }
+
/**
* @param integer $id
* @return Page the loaded model
diff --git a/common/modules/pages/entities/Page.php b/common/modules/pages/entities/Page.php
index 9d69749..3a363bc 100644
--- a/common/modules/pages/entities/Page.php
+++ b/common/modules/pages/entities/Page.php
@@ -2,21 +2,29 @@
namespace common\modules\pages\entities;
+use common\modules\pages\entities\queries\PageQuery;
use paulzi\nestedsets\NestedSetsBehavior;
use core\behaviors\MetaBehavior;
+use yii\behaviors\TimestampBehavior;
use yii\db\ActiveRecord;
use core\entities\Meta;
use Yii;
/**
- * @property integer $id
+ * @property int $id
* @property string $title
* @property string $slug
* @property string $content
+ * @property int $created_at
+ * @property int $updated_at
* @property string meta_json
- * @property integer $lft
- * @property integer $rgt
- * @property integer $depth
+ * @property int $tree
+ * @property int $lft
+ * @property int $rgt
+ * @property int $depth
+ * @property int $type
+ * @property int $revision_at
+ * @property int $revision_id
* @property Meta $meta
*
* @property Page $parent
@@ -28,24 +36,30 @@ use Yii;
*/
class Page extends ActiveRecord
{
+ const TYPE_PUBLIC = 0;
+ const TYPE_REVISION = 1;
+ const TYPE_PREVIEW = 2;
+
public $meta;
- public static function create($title, $slug, $content, Meta $meta): self
+ public static function create($title, $slug, $content, $type = Page::TYPE_PUBLIC, Meta $meta): self
{
$page = new static();
$page->title = $title;
$page->slug = $slug;
$page->content = $content;
$page->meta = $meta;
+ $page->type = $type;
return $page;
}
- public function edit($title, $slug, $content, Meta $meta): void
+ public function edit($title, $slug, $content, $type = Page::TYPE_PUBLIC, Meta $meta): void
{
$this->title = $title;
$this->slug = $slug;
$this->content = $content;
$this->meta = $meta;
+ $this->type = $type;
}
public function getSeoTitle(): string
@@ -62,7 +76,11 @@ class Page extends ActiveRecord
{
return [
MetaBehavior::class,
- NestedSetsBehavior::class,
+ [
+ 'class' => NestedSetsBehavior::class,
+ 'treeAttribute' => 'tree',
+ ],
+ TimestampBehavior::class,
];
}
@@ -81,4 +99,9 @@ class Page extends ActiveRecord
'content' => Yii::t('page', 'Content'),
];
}
+
+ public static function find(): PageQuery
+ {
+ return new PageQuery(static::class);
+ }
}
\ No newline at end of file
diff --git a/common/modules/pages/entities/queries/PageQuery.php b/common/modules/pages/entities/queries/PageQuery.php
new file mode 100644
index 0000000..13f6200
--- /dev/null
+++ b/common/modules/pages/entities/queries/PageQuery.php
@@ -0,0 +1,21 @@
+andWhere([
+ ($alias ? $alias . '.' : '') . 'type' => Page::TYPE_PUBLIC,
+ ]);
+ }
+}
\ No newline at end of file
diff --git a/common/modules/pages/forms/PageForm.php b/common/modules/pages/forms/PageForm.php
index 60f7e36..03114a5 100644
--- a/common/modules/pages/forms/PageForm.php
+++ b/common/modules/pages/forms/PageForm.php
@@ -6,6 +6,7 @@ use core\forms\CompositeForm;
use core\forms\MetaForm;
use common\modules\pages\entities\Page;
use core\validators\SlugValidator;
+use yii\db\ActiveQuery;
use yii\helpers\ArrayHelper;
use Yii;
@@ -14,12 +15,14 @@ use Yii;
*/
class PageForm extends CompositeForm
{
+ public $type;
+
public $title;
public $slug;
public $content;
public $parentId;
- private $_page;
+ public $_page;
public function __construct(Page $page = null, $config = [])
{
@@ -44,7 +47,18 @@ class PageForm extends CompositeForm
[['title', 'slug'], 'string', 'max' => 255],
[['content'], 'string'],
['slug', SlugValidator::class],
- [['slug'], 'unique', 'targetClass' => Page::class, 'filter' => $this->_page ? ['<>', 'id', $this->_page->id] : null]
+ //[['slug'], 'unique', 'targetClass' => Page::class, 'filter' => $this->_page ? ['<>', 'id', $this->_page->id] : null]
+ [['slug'], 'unique', 'targetClass' => Page::class, 'filter' => function (ActiveQuery $query) {
+ if ($this->type != Page::TYPE_PUBLIC) {
+ $query->andWhere($this->type . '=' . Page::TYPE_PUBLIC);
+ }
+
+ $query->andWhere(['type' => Page::TYPE_PUBLIC]);
+ if ($this->_page) {
+ $query->andWhere(['<>', 'id', $this->_page->id]);
+ }
+ return $query;
+ }],
];
}
@@ -60,7 +74,7 @@ class PageForm extends CompositeForm
public function parentsList(): array
{
- return ArrayHelper::map(Page::find()->orderBy('lft')->asArray()->all(), 'id', function (array $page) {
+ return ArrayHelper::map(Page::find()->andWhere(['tree' => 1])->orderBy('lft')->asArray()->all(), 'id', function (array $page) {
return ($page['depth'] > 1 ? str_repeat('-- ', $page['depth'] - 1) . ' ' : '') . $page['title'];
});
}
diff --git a/common/modules/pages/forms/PageSearch.php b/common/modules/pages/forms/PageSearch.php
index db1578b..fd5846b 100644
--- a/common/modules/pages/forms/PageSearch.php
+++ b/common/modules/pages/forms/PageSearch.php
@@ -27,7 +27,7 @@ class PageSearch extends Model
*/
public function search(array $params): ActiveDataProvider
{
- $query = Page::find()->andWhere(['>', 'depth', 0]);
+ $query = Page::find()->typePublic()->andWhere(['>', 'depth', 0]);
$dataProvider = new ActiveDataProvider([
'query' => $query,
diff --git a/common/modules/pages/helpers/PageHelper.php b/common/modules/pages/helpers/PageHelper.php
new file mode 100644
index 0000000..2464369
--- /dev/null
+++ b/common/modules/pages/helpers/PageHelper.php
@@ -0,0 +1,40 @@
+revision_id) {
+
+ $model->revision_at = time();
+
+ $page = Page::create(
+ $model->title,
+ $model->slug,
+ $model->content,
+ new Meta(
+ $model->meta->title,
+ $model->meta->description,
+ $model->meta->keywords
+ )
+ );
+
+ $page->revision_at = $model->updated_at;
+ $page->revision_id = $model->id;
+ $page->type = Page::TYPE_REVISION;
+ //$page->tree = 2;
+
+ $parent = Page::find()->andWhere(['slug' => 'temp'])->andWhere(['depth' => 0])->one();
+ $page->appendTo($parent);
+ $page->save();
+ }
+ }
+}
\ No newline at end of file
diff --git a/common/modules/pages/messages/ru/page.php b/common/modules/pages/messages/ru/page.php
index 091c640..b0f1475 100644
--- a/common/modules/pages/messages/ru/page.php
+++ b/common/modules/pages/messages/ru/page.php
@@ -11,4 +11,14 @@ return [
'Parent Page' => 'Родительская страница',
'Update Page: {name}' => 'Редактирование страницы: {name}',
'Select page...' => 'Укажите страницу',
+ 'History' => 'История изменений',
+ 'Clear History' => 'Очистить историю',
+ 'History is empty' => 'Нет изменений',
+ 'Current Edition' => 'Текущая редакция',
+ 'Restore' => 'Восстановить',
+ 'Are you sure you want to restore this history item?' => 'Вы уверены, что хотите восстановить эту запись?',
+ 'Are you sure you want to remove this history?' => 'Вы уверены, что хотите удалить всю историю?',
+ 'View' => 'Просмотр',
+ 'Publish' => 'Публикация',
+ 'Preview on site' => 'Просмотр на сайте',
];
\ No newline at end of file
diff --git a/common/modules/pages/migrations/m180720_051253_create_pages_table.php b/common/modules/pages/migrations/m180720_051253_create_pages_table.php
deleted file mode 100644
index 30d04bc..0000000
--- a/common/modules/pages/migrations/m180720_051253_create_pages_table.php
+++ /dev/null
@@ -1,43 +0,0 @@
-createTable('{{%pages}}', [
- 'id' => $this->primaryKey(),
- 'title' => $this->string()->notNull(),
- 'slug' => $this->string()->notNull(),
- 'content' => 'MEDIUMTEXT',
- 'meta_json' => $this->text()->notNull(),
- 'lft' => $this->integer()->notNull(),
- 'rgt' => $this->integer()->notNull(),
- 'depth' => $this->integer()->notNull(),
- ], $tableOptions);
-
- $this->createIndex('{{%idx-pages-slug}}', '{{%pages}}', 'slug', true);
-
- $this->insert('{{%pages}}', [
- 'id' => 1,
- 'title' => '',
- 'slug' => 'root',
- 'content' => null,
- 'meta_json' => '{}',
- 'lft' => 1,
- 'rgt' => 2,
- 'depth' => 0,
- ]);
- }
-
- public function down()
- {
- $this->dropTable('{{%pages}}');
- }
-}
diff --git a/common/modules/pages/migrations/m180727_110132_create_pages_table.php b/common/modules/pages/migrations/m180727_110132_create_pages_table.php
new file mode 100644
index 0000000..8b9a837
--- /dev/null
+++ b/common/modules/pages/migrations/m180727_110132_create_pages_table.php
@@ -0,0 +1,61 @@
+createTable('{{%pages}}', [
+ 'id' => $this->primaryKey(),
+ 'title' => $this->string()->notNull(),
+ 'slug' => $this->string()->notNull(),
+ 'content' => 'MEDIUMTEXT',
+ 'created_at' => $this->integer()->unsigned(),
+ 'updated_at' => $this->integer()->unsigned(),
+ 'meta_json' => $this->text()->notNull(),
+ 'tree' => $this->integer(),
+ 'lft' => $this->integer()->notNull(),
+ 'rgt' => $this->integer()->notNull(),
+ 'depth' => $this->integer()->notNull(),
+ ], $tableOptions);
+
+ $this->createIndex('{{%idx-pages-slug}}', '{{%pages}}', 'slug', true);
+ $this->createIndex('lft', '{{%pages}}', ['tree', 'lft', 'rgt']);
+ $this->createIndex('rgt', '{{%pages}}', ['tree', 'rgt']);
+
+ $this->insert('{{%pages}}', [
+ 'id' => 1,
+ 'title' => '',
+ 'slug' => 'root',
+ 'content' => null,
+ 'meta_json' => '{}',
+ 'tree' => 1,
+ 'lft' => 1,
+ 'rgt' => 2,
+ 'depth' => 0,
+ ]);
+
+ $this->insert('{{%pages}}', [
+ 'id' => 2,
+ 'title' => '',
+ 'slug' => 'temp',
+ 'content' => null,
+ 'meta_json' => '{}',
+ 'tree' => 2,
+ 'lft' => 1,
+ 'rgt' => 2,
+ 'depth' => 0,
+ ]);
+ }
+
+ public function down()
+ {
+ $this->dropTable('{{%pages}}');
+ }
+}
diff --git a/common/modules/pages/migrations/m180727_110133_add_pages_revision_fields.php b/common/modules/pages/migrations/m180727_110133_add_pages_revision_fields.php
new file mode 100644
index 0000000..06504ca
--- /dev/null
+++ b/common/modules/pages/migrations/m180727_110133_add_pages_revision_fields.php
@@ -0,0 +1,35 @@
+addColumn('{{%pages}}', 'type', $this->integer(2)->defaultValue(0)); // 0 - public, 1 - revision, 2 - preview
+ $this->addColumn('{{%pages}}', 'revision_at', $this->integer()->unsigned());
+ $this->addColumn('{{%pages}}', 'revision_id', $this->integer());
+
+ $this->dropIndex('{{%idx-pages-slug}}', '{{%pages}}');
+ $this->createIndex('{{%idx-pages-slug}}', '{{%pages}}', 'slug');
+
+ $this->createIndex('idx_pages_revision_id', '{{%pages}}', 'revision_id');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function safeDown()
+ {
+ $this->dropIndex('idx_pages_revision_id', '{{%pages}}');
+ $this->dropColumn('{{%pages}}', 'type');
+ $this->dropColumn('{{%pages}}', 'revision_at');
+ $this->dropColumn('{{%pages}}', 'revision_id');
+ }
+}
diff --git a/common/modules/pages/repositories/read/PageReadRepository.php b/common/modules/pages/repositories/read/PageReadRepository.php
index b084c47..d6615ab 100644
--- a/common/modules/pages/repositories/read/PageReadRepository.php
+++ b/common/modules/pages/repositories/read/PageReadRepository.php
@@ -8,7 +8,7 @@ class PageReadRepository
{
public function getAll(): array
{
- return Page::find()->andWhere(['>', 'depth', 0])->all();
+ return Page::find()->typePublic()->andWhere(['>', 'depth', 0])->all();
}
public function find($id): ?Page
@@ -18,6 +18,11 @@ class PageReadRepository
public function findBySlug($slug): ?Page
{
- return Page::find()->andWhere(['slug' => $slug])->andWhere(['>', 'depth', 0])->one();
+ return Page::find()->typePublic()->andWhere(['slug' => $slug])->andWhere(['>', 'depth', 0])->one();
}
+
+ public function findPreview($id): ?Page
+ {
+ return Page::find()->andWhere(['id' => $id])->one();
+ }
}
\ No newline at end of file
diff --git a/common/modules/pages/services/PageManageService.php b/common/modules/pages/services/PageManageService.php
index de2d663..2c59e50 100644
--- a/common/modules/pages/services/PageManageService.php
+++ b/common/modules/pages/services/PageManageService.php
@@ -2,6 +2,7 @@
namespace common\modules\pages\services;
+use common\modules\pages\helpers\PageHelper;
use core\entities\Meta;
use common\modules\pages\entities\Page;
use common\modules\pages\forms\PageForm;
@@ -16,20 +17,27 @@ class PageManageService
$this->pages = $pages;
}
- public function create(PageForm $form): Page
+ public function create(PageForm $form, $type = Page::TYPE_PUBLIC): Page
{
$parent = $this->pages->get($form->parentId);
$page = Page::create(
$form->title,
$form->slug,
$form->content,
+ $type,
new Meta(
$form->meta->title,
$form->meta->description,
$form->meta->keywords
)
);
- $page->appendTo($parent);
+ if ($type == Page::TYPE_PUBLIC) {
+ $page->appendTo( $parent );
+ }
+ else {
+ $parent = Page::find()->andWhere(['tree' => 2])->andWhere(['depth' => 0])->one();
+ $page->appendTo( $parent );
+ }
$this->pages->save($page);
return $page;
}
@@ -37,11 +45,15 @@ class PageManageService
public function edit($id, PageForm $form): void
{
$page = $this->pages->get($id);
+
+ PageHelper::saveRevision($page);
+
$this->assertIsNotRoot($page);
$page->edit(
$form->title,
$form->slug,
$form->content,
+ $form->type,
new Meta(
$form->meta->title,
$form->meta->description,
@@ -88,4 +100,36 @@ class PageManageService
throw new \DomainException('Unable to manage the root page.');
}
}
+
+ public function removePreviews(): void
+ {
+ $pages = Page::find()->andWhere(['type' => Page::TYPE_PREVIEW])->all();
+ foreach ($pages as $page) {
+ $page->delete();
+ }
+ }
+
+ public function clearHistory(Page $page): void
+ {
+ Page::deleteAll(['revision_id' => $page->id]);
+ }
+
+ public function restoreHistory($from_id, $id): void
+ {
+ $page = $this->pages->get($id);
+ $from = $this->pages->get($from_id);
+
+ $page->title = $from->title;
+ $page->slug = $from->slug;
+ $page->content = $from->content;
+ $page->created_at = $from->created_at;
+ $page->updated_at = $from->updated_at;
+ $page->revision_at = $from->revision_at;
+
+ $this->pages->save($page);
+
+ // remove current revision
+ $this->pages->remove($from);
+ Page::deleteAll(['AND', ['revision_id' => $page->id], ['>', 'revision_at', $page->revision_at]]);
+ }
}
\ No newline at end of file
diff --git a/common/modules/pages/views/manage/page/_form.php b/common/modules/pages/views/manage/page/_form.php
index a9d217f..3b325b0 100644
--- a/common/modules/pages/views/manage/page/_form.php
+++ b/common/modules/pages/views/manage/page/_form.php
@@ -13,29 +13,51 @@ use yii\widgets\ActiveForm;
-
-
-
- = $form->field($model, 'parentId')->dropDownList($model->parentsList()) ?>
- = $form->field($model, 'title')->textInput(['maxlength' => true]) ?>
- = $form->field($model, 'slug')->textInput(['maxlength' => true]) ?>
- = $form->field($model, 'content')->widget(CKEditor::class) ?>
-
-
-
-
-
-
-
- = $form->field($model->meta, 'title')->textInput() ?>
- = $form->field($model->meta, 'description')->textarea(['rows' => 2]) ?>
- = $form->field($model->meta, 'keywords')->textInput() ?>
-
-
-
-
- = Html::submitButton(Yii::t('buttons', 'Save'), ['class' => 'btn btn-success']) ?>
-
+
+
+
+
+
+
+ = $form->field($model, 'parentId')->dropDownList($model->parentsList()) ?>
+ = $form->field($model, 'title')->textInput(['maxlength' => true]) ?>
+ = $form->field($model, 'slug')->textInput(['maxlength' => true]) ?>
+ = $form->field($model, 'content')->widget(CKEditor::class) ?>
+
+
+
+
+
+
+
+ = $form->field($model->meta, 'title')->textInput() ?>
+ = $form->field($model->meta, 'description')->textarea(['rows' => 2]) ?>
+ = $form->field($model->meta, 'keywords')->textInput() ?>
+
+
+
+
+ = Html::submitButton(Yii::t('buttons', 'Save'), ['class' => 'btn btn-success']) ?>
+
+
+
+
+
+
+
+
+ = Html::submitButton(Yii::t('page', 'Preview on site'), [
+ 'class' => 'btn btn-info',
+ 'value'=>'preview',
+ 'name'=>'submit_preview',
+ 'formaction' => \yii\helpers\Url::to(['/pages/manage/page/create-preview']),
+ 'formtarget' => '_blank',
+ ]) ?>
+
+
+
+
+
diff --git a/common/modules/pages/views/manage/page/view.php b/common/modules/pages/views/manage/page/view.php
index 5b5a9ed..2f69c25 100644
--- a/common/modules/pages/views/manage/page/view.php
+++ b/common/modules/pages/views/manage/page/view.php
@@ -5,6 +5,7 @@ use yii\widgets\DetailView;
/* @var $this yii\web\View */
/* @var $page \common\modules\pages\entities\Page */
+/* @var $history \common\modules\pages\entities\Page[] */
$this->title = $page->title;
$this->params['breadcrumbs'][] = ['label' => Yii::t('page', 'Pages'), 'url' => ['index']];
@@ -24,53 +25,111 @@ $this->params['breadcrumbs'][] = $this->title;
]) ?>
-
-
-
- = DetailView::widget([
- 'model' => $page,
- 'attributes' => [
- 'id',
- 'title',
- 'slug',
- ],
- ]) ?>
-
-
-
-
-
-
- = Yii::$app->formatter->asHtml($page->content, [
- 'Attr.AllowedRel' => array('nofollow'),
- 'HTML.SafeObject' => true,
- 'Output.FlashCompat' => true,
- 'HTML.SafeIframe' => true,
- 'URI.SafeIframeRegexp'=>'%^(https?:)?//(www\.youtube(?:-nocookie)?\.com/embed/|player\.vimeo\.com/video/)%',
- ]) ?>
-
-
-
-
-
-
- = DetailView::widget([
- 'model' => $page,
- 'attributes' => [
- [
- 'attribute' => 'meta.title',
- 'label' => Yii::t('main', 'Title'),
- ],
- [
- 'attribute' => 'meta.description',
- 'label' => Yii::t('main', 'Description'),
- ],
- [
- 'attribute' => 'meta.keywords',
- 'label' => Yii::t('main', 'Keywords'),
- ],
- ],
- ]) ?>
-
-
+
+
+
+
+
+
+ = DetailView::widget([
+ 'model' => $page,
+ 'attributes' => [
+ 'id',
+ 'title',
+ 'slug',
+ ],
+ ]) ?>
+
+
+
+
+
+
+ = Yii::$app->formatter->asHtml($page->content, [
+ 'Attr.AllowedRel' => array('nofollow'),
+ 'HTML.SafeObject' => true,
+ 'Output.FlashCompat' => true,
+ 'HTML.SafeIframe' => true,
+ 'URI.SafeIframeRegexp'=>'%^(https?:)?//(www\.youtube(?:-nocookie)?\.com/embed/|player\.vimeo\.com/video/)%',
+ ]) ?>
+
+
+
+
+
+
+ = DetailView::widget([
+ 'model' => $page,
+ 'attributes' => [
+ [
+ 'attribute' => 'meta.title',
+ 'label' => Yii::t('main', 'Title'),
+ ],
+ [
+ 'attribute' => 'meta.description',
+ 'label' => Yii::t('main', 'Description'),
+ ],
+ [
+ 'attribute' => 'meta.keywords',
+ 'label' => Yii::t('main', 'Keywords'),
+ ],
+ ],
+ ]) ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+ revision_id): ?>
+ = date('d.m.Y H:i', $item->revision_at) ?>
+ →
+
+ = Html::a(Yii::t('blog', 'View'), \yii\helpers\Url::to(Yii::$app->get('frontendUrlManager')->createAbsoluteUrl(['/pages/page/preview', 'id' => $item->id])), [
+ 'style' => 'font-size:11px;',
+ 'target' => '_blank',
+ ]) ?>
+
+ |
+
+ = Html::a(Yii::t('page', 'Restore'), ['/pages/manage/page/restore-history', 'id' => $item->id], [
+ 'style' => 'font-size:11px; color: red',
+ 'data' => [
+ 'confirm' => Yii::t('page', 'Are you sure you want to restore this history item?'),
+ 'method' => 'post',
+ ],
+ ]) ?>
+
+
+ = Yii::t('page', 'Current Edition') ?>
+
+
+
+
+
+ = Html::a(Yii::t('page', 'Clear History'), ['/pages/manage/page/clear-history', 'id' => $page->id], [
+ 'class' => 'btn btn-danger btn-sm pull-right',
+ 'data' => [
+ 'confirm' => Yii::t('page', 'Are you sure you want to remove this history?'),
+ 'method' => 'post',
+ ],
+ ]) ?>
+
+
= Yii::t('page', 'History is empty') ?>
+
+
+
+
+
+
+
+