Browse Source

Pages revisions, on fly preview

master
Egorka 6 years ago
parent
commit
20d3b47856
  1. 7
      common/modules/blog/controllers/PostController.php
  2. 4
      common/modules/blog/entities/BlogPost.php
  3. 1
      common/modules/blog/forms/BlogPostForm.php
  4. 1
      common/modules/blog/migrations/m180725_091725_add_blog_posts_type_field.php
  5. 1
      common/modules/blog/migrations/m180725_113503_remove_blog_posts_slug_unique_index.php
  6. 16
      common/modules/pages/controllers/PageController.php
  7. 52
      common/modules/pages/controllers/manage/PageController.php
  8. 37
      common/modules/pages/entities/Page.php
  9. 21
      common/modules/pages/entities/queries/PageQuery.php
  10. 20
      common/modules/pages/forms/PageForm.php
  11. 2
      common/modules/pages/forms/PageSearch.php
  12. 40
      common/modules/pages/helpers/PageHelper.php
  13. 10
      common/modules/pages/messages/ru/page.php
  14. 20
      common/modules/pages/migrations/m180727_110132_create_pages_table.php
  15. 35
      common/modules/pages/migrations/m180727_110133_add_pages_revision_fields.php
  16. 9
      common/modules/pages/repositories/read/PageReadRepository.php
  17. 48
      common/modules/pages/services/PageManageService.php
  18. 68
      common/modules/pages/views/manage/page/_form.php
  19. 157
      common/modules/pages/views/manage/page/view.php

7
common/modules/blog/controllers/PostController.php

@ -2,21 +2,14 @@
namespace common\modules\blog\controllers; namespace common\modules\blog\controllers;
use common\modules\blog\entities\BlogPost;
use common\modules\blog\forms\BlogCommentForm; 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\BlogCategoryReadRepository;
use common\modules\blog\repositories\read\BlogPostReadRepository; use common\modules\blog\repositories\read\BlogPostReadRepository;
use common\modules\blog\repositories\read\BlogTagReadRepository; use common\modules\blog\repositories\read\BlogTagReadRepository;
use common\modules\blog\services\BlogCommentService; use common\modules\blog\services\BlogCommentService;
use core\entities\Meta;
use frontend\components\FrontendController; use frontend\components\FrontendController;
use Yii; use Yii;
use yii\base\Security;
use yii\data\ActiveDataProvider; use yii\data\ActiveDataProvider;
use yii\helpers\FileHelper;
use yii\helpers\Json;
use yii\web\NotFoundHttpException; use yii\web\NotFoundHttpException;
use yii\filters\AccessControl; use yii\filters\AccessControl;

4
common/modules/blog/entities/BlogPost.php

@ -57,7 +57,7 @@ class BlogPost extends ActiveRecord
public $meta; 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 = new static();
$post->category_id = $categoryId; $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->category_id = $categoryId;
$this->title = $title; $this->title = $title;

1
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 ? ['<>', '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' => $this->_post ? ['AND', ['<>', 'id', $this->_post->id], ['type' => BlogPost::TYPE_PUBLIC]] : ['type' => BlogPost::TYPE_PUBLIC]],
[['slug'], 'unique', 'targetClass' => BlogPost::class, 'filter' => function (ActiveQuery $query) { [['slug'], 'unique', 'targetClass' => BlogPost::class, 'filter' => function (ActiveQuery $query) {
if ($this->type != BlogPost::TYPE_PUBLIC) { if ($this->type != BlogPost::TYPE_PUBLIC) {
$query->andWhere($this->type . '=' . BlogPost::TYPE_PUBLIC); $query->andWhere($this->type . '=' . BlogPost::TYPE_PUBLIC);
} }

1
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}}', 'type');
$this->dropColumn('{{%blog_posts}}', 'revision_at'); $this->dropColumn('{{%blog_posts}}', 'revision_at');
$this->dropColumn('{{%blog_posts}}', 'revision_id'); $this->dropColumn('{{%blog_posts}}', 'revision_id');
return false;
} }
} }

1
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() public function safeDown()
{ {
return false;
$this->dropIndex('{{%idx-blog_posts-slug}}', '{{%blog_posts}}'); $this->dropIndex('{{%idx-blog_posts-slug}}', '{{%blog_posts}}');
$this->createIndex('{{%idx-blog_posts-slug}}', '{{%blog_posts}}', 'slug'); $this->createIndex('{{%idx-blog_posts-slug}}', '{{%blog_posts}}', 'slug');
} }

16
common/modules/pages/controllers/PageController.php

@ -31,6 +31,11 @@ class PageController extends FrontendController
'allow' => true, 'allow' => true,
'roles' => ['Pages'], 'roles' => ['Pages'],
], ],
[
'actions' => ['preview'],
'allow' => true,
'roles' => ['PagesManagement'],
],
[ // all the action are accessible to admin [ // all the action are accessible to admin
'allow' => true, 'allow' => true,
'roles' => ['admin'], 'roles' => ['admin'],
@ -56,4 +61,15 @@ class PageController extends FrontendController
'page' => $page, '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,
]);
}
} }

52
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\services\PageManageService;
use common\modules\pages\entities\Page; use common\modules\pages\entities\Page;
use common\modules\pages\forms\PageSearch; use common\modules\pages\forms\PageSearch;
use yii\helpers\Url;
use yii\web\Controller; use yii\web\Controller;
use yii\web\NotFoundHttpException; use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter; use yii\filters\VerbFilter;
@ -30,7 +31,6 @@ class PageController extends Controller
'class' => AccessControl::class, 'class' => AccessControl::class,
'rules' => [ 'rules' => [
[ [
'actions' => ['create', 'view', 'index', 'update', 'delete', 'move-up', 'move-down'],
'allow' => true, 'allow' => true,
'roles' => ['PagesManagement'], 'roles' => ['PagesManagement'],
], ],
@ -44,6 +44,8 @@ class PageController extends Controller
'class' => VerbFilter::class, 'class' => VerbFilter::class,
'actions' => [ 'actions' => [
'delete' => ['POST'], 'delete' => ['POST'],
'restore-history' => ['POST'],
'clear-history' => ['POST'],
], ],
], ],
]; ];
@ -71,11 +73,38 @@ class PageController extends Controller
*/ */
public function actionView($id) 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', [ return $this->render('view', [
'page' => $this->findModel($id), '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 * @return mixed
*/ */
@ -162,7 +191,7 @@ class PageController extends Controller
\Yii::$app->response->format = Response::FORMAT_JSON; \Yii::$app->response->format = Response::FORMAT_JSON;
$out = ['results' => ['id' => '', 'text' => '']]; $out = ['results' => ['id' => '', 'text' => '']];
if (!is_null($q)) { 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); $out['results'] = array_values($data);
} }
elseif ($id > 0) { elseif ($id > 0) {
@ -170,12 +199,29 @@ class PageController extends Controller
$out['results'] = ['id' => $tag_name, 'text' => $tag_name]; $out['results'] = ['id' => $tag_name, 'text' => $tag_name];
} }
else { 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); $out['results'] = array_values($data);
} }
return $out; 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 * @param integer $id
* @return Page the loaded model * @return Page the loaded model

37
common/modules/pages/entities/Page.php

@ -2,21 +2,29 @@
namespace common\modules\pages\entities; namespace common\modules\pages\entities;
use common\modules\pages\entities\queries\PageQuery;
use paulzi\nestedsets\NestedSetsBehavior; use paulzi\nestedsets\NestedSetsBehavior;
use core\behaviors\MetaBehavior; use core\behaviors\MetaBehavior;
use yii\behaviors\TimestampBehavior;
use yii\db\ActiveRecord; use yii\db\ActiveRecord;
use core\entities\Meta; use core\entities\Meta;
use Yii; use Yii;
/** /**
* @property integer $id * @property int $id
* @property string $title * @property string $title
* @property string $slug * @property string $slug
* @property string $content * @property string $content
* @property int $created_at
* @property int $updated_at
* @property string meta_json * @property string meta_json
* @property integer $lft * @property int $tree
* @property integer $rgt * @property int $lft
* @property integer $depth * @property int $rgt
* @property int $depth
* @property int $type
* @property int $revision_at
* @property int $revision_id
* @property Meta $meta * @property Meta $meta
* *
* @property Page $parent * @property Page $parent
@ -28,24 +36,30 @@ use Yii;
*/ */
class Page extends ActiveRecord class Page extends ActiveRecord
{ {
const TYPE_PUBLIC = 0;
const TYPE_REVISION = 1;
const TYPE_PREVIEW = 2;
public $meta; 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 = new static();
$page->title = $title; $page->title = $title;
$page->slug = $slug; $page->slug = $slug;
$page->content = $content; $page->content = $content;
$page->meta = $meta; $page->meta = $meta;
$page->type = $type;
return $page; 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->title = $title;
$this->slug = $slug; $this->slug = $slug;
$this->content = $content; $this->content = $content;
$this->meta = $meta; $this->meta = $meta;
$this->type = $type;
} }
public function getSeoTitle(): string public function getSeoTitle(): string
@ -62,7 +76,11 @@ class Page extends ActiveRecord
{ {
return [ return [
MetaBehavior::class, MetaBehavior::class,
NestedSetsBehavior::class, [
'class' => NestedSetsBehavior::class,
'treeAttribute' => 'tree',
],
TimestampBehavior::class,
]; ];
} }
@ -81,4 +99,9 @@ class Page extends ActiveRecord
'content' => Yii::t('page', 'Content'), 'content' => Yii::t('page', 'Content'),
]; ];
} }
public static function find(): PageQuery
{
return new PageQuery(static::class);
}
} }

21
common/modules/pages/entities/queries/PageQuery.php

@ -0,0 +1,21 @@
<?php
/**
* Created by Error202
* Date: 27.07.2018
*/
namespace common\modules\pages\entities\queries;
use common\modules\pages\entities\Page;
use yii\db\ActiveQuery;
class PageQuery extends ActiveQuery
{
public function typePublic($alias = null)
{
return $this->andWhere([
($alias ? $alias . '.' : '') . 'type' => Page::TYPE_PUBLIC,
]);
}
}

20
common/modules/pages/forms/PageForm.php

@ -6,6 +6,7 @@ use core\forms\CompositeForm;
use core\forms\MetaForm; use core\forms\MetaForm;
use common\modules\pages\entities\Page; use common\modules\pages\entities\Page;
use core\validators\SlugValidator; use core\validators\SlugValidator;
use yii\db\ActiveQuery;
use yii\helpers\ArrayHelper; use yii\helpers\ArrayHelper;
use Yii; use Yii;
@ -14,12 +15,14 @@ use Yii;
*/ */
class PageForm extends CompositeForm class PageForm extends CompositeForm
{ {
public $type;
public $title; public $title;
public $slug; public $slug;
public $content; public $content;
public $parentId; public $parentId;
private $_page; public $_page;
public function __construct(Page $page = null, $config = []) public function __construct(Page $page = null, $config = [])
{ {
@ -44,7 +47,18 @@ class PageForm extends CompositeForm
[['title', 'slug'], 'string', 'max' => 255], [['title', 'slug'], 'string', 'max' => 255],
[['content'], 'string'], [['content'], 'string'],
['slug', SlugValidator::class], ['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 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']; return ($page['depth'] > 1 ? str_repeat('-- ', $page['depth'] - 1) . ' ' : '') . $page['title'];
}); });
} }

2
common/modules/pages/forms/PageSearch.php

@ -27,7 +27,7 @@ class PageSearch extends Model
*/ */
public function search(array $params): ActiveDataProvider public function search(array $params): ActiveDataProvider
{ {
$query = Page::find()->andWhere(['>', 'depth', 0]); $query = Page::find()->typePublic()->andWhere(['>', 'depth', 0]);
$dataProvider = new ActiveDataProvider([ $dataProvider = new ActiveDataProvider([
'query' => $query, 'query' => $query,

40
common/modules/pages/helpers/PageHelper.php

@ -0,0 +1,40 @@
<?php
/**
* Created by Error202
* Date: 27.07.2018
*/
namespace common\modules\pages\helpers;
use common\modules\pages\entities\Page;
use core\entities\Meta;
class PageHelper
{
public static function saveRevision(Page $model) {
if (!$model->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();
}
}
}

10
common/modules/pages/messages/ru/page.php

@ -11,4 +11,14 @@ return [
'Parent Page' => 'Родительская страница', 'Parent Page' => 'Родительская страница',
'Update Page: {name}' => 'Редактирование страницы: {name}', 'Update Page: {name}' => 'Редактирование страницы: {name}',
'Select page...' => 'Укажите страницу', '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' => 'Просмотр на сайте',
]; ];

20
common/modules/pages/migrations/m180720_051253_create_pages_table.php → common/modules/pages/migrations/m180727_110132_create_pages_table.php

@ -5,7 +5,7 @@ use yii\db\Migration;
/** /**
* Handles the creation of table `pages`. * Handles the creation of table `pages`.
*/ */
class m180720_051253_create_pages_table extends Migration class m180727_110132_create_pages_table extends Migration
{ {
public function up() public function up()
{ {
@ -16,13 +16,18 @@ class m180720_051253_create_pages_table extends Migration
'title' => $this->string()->notNull(), 'title' => $this->string()->notNull(),
'slug' => $this->string()->notNull(), 'slug' => $this->string()->notNull(),
'content' => 'MEDIUMTEXT', 'content' => 'MEDIUMTEXT',
'created_at' => $this->integer()->unsigned(),
'updated_at' => $this->integer()->unsigned(),
'meta_json' => $this->text()->notNull(), 'meta_json' => $this->text()->notNull(),
'tree' => $this->integer(),
'lft' => $this->integer()->notNull(), 'lft' => $this->integer()->notNull(),
'rgt' => $this->integer()->notNull(), 'rgt' => $this->integer()->notNull(),
'depth' => $this->integer()->notNull(), 'depth' => $this->integer()->notNull(),
], $tableOptions); ], $tableOptions);
$this->createIndex('{{%idx-pages-slug}}', '{{%pages}}', 'slug', true); $this->createIndex('{{%idx-pages-slug}}', '{{%pages}}', 'slug', true);
$this->createIndex('lft', '{{%pages}}', ['tree', 'lft', 'rgt']);
$this->createIndex('rgt', '{{%pages}}', ['tree', 'rgt']);
$this->insert('{{%pages}}', [ $this->insert('{{%pages}}', [
'id' => 1, 'id' => 1,
@ -30,6 +35,19 @@ class m180720_051253_create_pages_table extends Migration
'slug' => 'root', 'slug' => 'root',
'content' => null, 'content' => null,
'meta_json' => '{}', '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, 'lft' => 1,
'rgt' => 2, 'rgt' => 2,
'depth' => 0, 'depth' => 0,

35
common/modules/pages/migrations/m180727_110133_add_pages_revision_fields.php

@ -0,0 +1,35 @@
<?php
use yii\db\Migration;
/**
* Class m180727_110133_add_pages_revision_fields
*/
class m180727_110133_add_pages_revision_fields extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->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');
}
}

9
common/modules/pages/repositories/read/PageReadRepository.php

@ -8,7 +8,7 @@ class PageReadRepository
{ {
public function getAll(): array public function getAll(): array
{ {
return Page::find()->andWhere(['>', 'depth', 0])->all(); return Page::find()->typePublic()->andWhere(['>', 'depth', 0])->all();
} }
public function find($id): ?Page public function find($id): ?Page
@ -18,6 +18,11 @@ class PageReadRepository
public function findBySlug($slug): ?Page 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();
}
} }

48
common/modules/pages/services/PageManageService.php

@ -2,6 +2,7 @@
namespace common\modules\pages\services; namespace common\modules\pages\services;
use common\modules\pages\helpers\PageHelper;
use core\entities\Meta; use core\entities\Meta;
use common\modules\pages\entities\Page; use common\modules\pages\entities\Page;
use common\modules\pages\forms\PageForm; use common\modules\pages\forms\PageForm;
@ -16,20 +17,27 @@ class PageManageService
$this->pages = $pages; $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); $parent = $this->pages->get($form->parentId);
$page = Page::create( $page = Page::create(
$form->title, $form->title,
$form->slug, $form->slug,
$form->content, $form->content,
$type,
new Meta( new Meta(
$form->meta->title, $form->meta->title,
$form->meta->description, $form->meta->description,
$form->meta->keywords $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); $this->pages->save($page);
return $page; return $page;
} }
@ -37,11 +45,15 @@ class PageManageService
public function edit($id, PageForm $form): void public function edit($id, PageForm $form): void
{ {
$page = $this->pages->get($id); $page = $this->pages->get($id);
PageHelper::saveRevision($page);
$this->assertIsNotRoot($page); $this->assertIsNotRoot($page);
$page->edit( $page->edit(
$form->title, $form->title,
$form->slug, $form->slug,
$form->content, $form->content,
$form->type,
new Meta( new Meta(
$form->meta->title, $form->meta->title,
$form->meta->description, $form->meta->description,
@ -88,4 +100,36 @@ class PageManageService
throw new \DomainException('Unable to manage the root page.'); 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]]);
}
} }

68
common/modules/pages/views/manage/page/_form.php

@ -13,29 +13,51 @@ use yii\widgets\ActiveForm;
<?php $form = ActiveForm::begin(); ?> <?php $form = ActiveForm::begin(); ?>
<div class="box box-default"> <div class="row">
<div class="box-header with-border"><?= Yii::t('page', 'Common') ?></div> <div class="col-md-10">
<div class="box-body">
<?= $form->field($model, 'parentId')->dropDownList($model->parentsList()) ?> <div class="box box-default">
<?= $form->field($model, 'title')->textInput(['maxlength' => true]) ?> <div class="box-header with-border"><?= Yii::t('page', 'Common') ?></div>
<?= $form->field($model, 'slug')->textInput(['maxlength' => true]) ?> <div class="box-body">
<?= $form->field($model, 'content')->widget(CKEditor::class) ?> <?= $form->field($model, 'parentId')->dropDownList($model->parentsList()) ?>
<?= $form->field($model, 'title')->textInput(['maxlength' => true]) ?>
</div> <?= $form->field($model, 'slug')->textInput(['maxlength' => true]) ?>
</div> <?= $form->field($model, 'content')->widget(CKEditor::class) ?>
<div class="box box-default"> </div>
<div class="box-header with-border"><?= Yii::t('page', 'SEO') ?></div> </div>
<div class="box-body">
<?= $form->field($model->meta, 'title')->textInput() ?> <div class="box box-default">
<?= $form->field($model->meta, 'description')->textarea(['rows' => 2]) ?> <div class="box-header with-border"><?= Yii::t('page', 'SEO') ?></div>
<?= $form->field($model->meta, 'keywords')->textInput() ?> <div class="box-body">
</div> <?= $form->field($model->meta, 'title')->textInput() ?>
</div> <?= $form->field($model->meta, 'description')->textarea(['rows' => 2]) ?>
<?= $form->field($model->meta, 'keywords')->textInput() ?>
<div class="form-group"> </div>
<?= Html::submitButton(Yii::t('buttons', 'Save'), ['class' => 'btn btn-success']) ?> </div>
</div>
<div class="form-group">
<?= Html::submitButton(Yii::t('buttons', 'Save'), ['class' => 'btn btn-success']) ?>
</div>
</div>
<div class="col-md-2">
<div class="box box-default">
<div class="box-header with-border"><?= Yii::t('page', 'Publish') ?></div>
<div class="box-body">
<?= 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',
]) ?>
</div>
</div>
</div>
</div>
<?php ActiveForm::end(); ?> <?php ActiveForm::end(); ?>

157
common/modules/pages/views/manage/page/view.php

@ -5,6 +5,7 @@ use yii\widgets\DetailView;
/* @var $this yii\web\View */ /* @var $this yii\web\View */
/* @var $page \common\modules\pages\entities\Page */ /* @var $page \common\modules\pages\entities\Page */
/* @var $history \common\modules\pages\entities\Page[] */
$this->title = $page->title; $this->title = $page->title;
$this->params['breadcrumbs'][] = ['label' => Yii::t('page', 'Pages'), 'url' => ['index']]; $this->params['breadcrumbs'][] = ['label' => Yii::t('page', 'Pages'), 'url' => ['index']];
@ -24,53 +25,111 @@ $this->params['breadcrumbs'][] = $this->title;
]) ?> ]) ?>
</p> </p>
<div class="box"> <div class="row">
<div class="box-header with-border"><?= Yii::t('page', 'Common') ?></div> <div class="col-md-9">
<div class="box-body">
<?= DetailView::widget([ <div class="box">
'model' => $page, <div class="box-header with-border"><?= Yii::t('page', 'Common') ?></div>
'attributes' => [ <div class="box-body">
'id', <?= DetailView::widget([
'title', 'model' => $page,
'slug', 'attributes' => [
], 'id',
]) ?> 'title',
</div> 'slug',
</div> ],
]) ?>
<div class="box"> </div>
<div class="box-header with-border"><?= Yii::t('page', 'Content') ?></div> </div>
<div class="box-body">
<?= Yii::$app->formatter->asHtml($page->content, [ <div class="box">
'Attr.AllowedRel' => array('nofollow'), <div class="box-header with-border"><?= Yii::t('page', 'Content') ?></div>
'HTML.SafeObject' => true, <div class="box-body">
'Output.FlashCompat' => true, <?= Yii::$app->formatter->asHtml($page->content, [
'HTML.SafeIframe' => true, 'Attr.AllowedRel' => array('nofollow'),
'URI.SafeIframeRegexp'=>'%^(https?:)?//(www\.youtube(?:-nocookie)?\.com/embed/|player\.vimeo\.com/video/)%', 'HTML.SafeObject' => true,
]) ?> 'Output.FlashCompat' => true,
</div> 'HTML.SafeIframe' => true,
</div> 'URI.SafeIframeRegexp'=>'%^(https?:)?//(www\.youtube(?:-nocookie)?\.com/embed/|player\.vimeo\.com/video/)%',
]) ?>
<div class="box"> </div>
<div class="box-header with-border"><?= Yii::t('page', 'SEO') ?></div> </div>
<div class="box-body">
<?= DetailView::widget([ <div class="box">
'model' => $page, <div class="box-header with-border"><?= Yii::t('page', 'SEO') ?></div>
'attributes' => [ <div class="box-body">
[ <?= DetailView::widget([
'attribute' => 'meta.title', 'model' => $page,
'label' => Yii::t('main', 'Title'), 'attributes' => [
], [
[ 'attribute' => 'meta.title',
'attribute' => 'meta.description', 'label' => Yii::t('main', 'Title'),
'label' => Yii::t('main', 'Description'), ],
], [
[ 'attribute' => 'meta.description',
'attribute' => 'meta.keywords', 'label' => Yii::t('main', 'Description'),
'label' => Yii::t('main', 'Keywords'), ],
], [
], 'attribute' => 'meta.keywords',
]) ?> 'label' => Yii::t('main', 'Keywords'),
</div> ],
</div> ],
]) ?>
</div>
</div>
</div>
<div class="col-md-3">
<div class="box">
<div class="box-header with-border"><?= Yii::t('page', 'History') ?></div>
<div class="box-body">
<?php if ($history): ?>
<ul>
<?php foreach ($history as $item): ?>
<li>
<?php if ($item->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',
],
]) ?>
<?php else: ?>
<strong><?= Yii::t('page', 'Current Edition') ?></strong>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
<?= 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',
],
]) ?>
<?php else: ?>
<div style="padding: 20px 0; text-align: center"><?= Yii::t('page', 'History is empty') ?></div>
<?php endif; ?>
</div>
</div>
</div>
</div>
</div> </div>

Loading…
Cancel
Save