Browse Source

Blog preview and revisions

master
Egorka 6 years ago
parent
commit
b71921f359
  1. 57
      common/modules/blog/controllers/PostController.php
  2. 70
      common/modules/blog/controllers/manage/PostController.php
  3. 18
      common/modules/blog/entities/BlogPost.php
  4. 11
      common/modules/blog/entities/queries/BlogPostQuery.php
  5. 19
      common/modules/blog/forms/BlogPostForm.php
  6. 2
      common/modules/blog/forms/search/BlogPostSearch.php
  7. 17
      common/modules/blog/helpers/BlogPostHelper.php
  8. 10
      common/modules/blog/messages/ru/blog.php
  9. 34
      common/modules/blog/migrations/m180725_091725_add_blog_posts_type_field.php
  10. 28
      common/modules/blog/migrations/m180725_113503_remove_blog_posts_slug_unique_index.php
  11. 21
      common/modules/blog/repositories/read/BlogPostReadRepository.php
  12. 51
      common/modules/blog/services/BlogPostManageService.php
  13. 2
      common/modules/blog/views/manage/post/_form.php
  14. 59
      common/modules/blog/views/manage/post/view.php
  15. BIN
      static/cache/posts/368_287_13.jpg
  16. BIN
      static/cache/posts/370_325_13.jpg
  17. BIN
      static/cache/posts/683_407_13.jpg
  18. BIN
      static/cache/posts/94_94_13.jpg
  19. BIN
      static/cache/posts/admin_13.jpg
  20. BIN
      static/cache/posts/home_slider_13.jpg
  21. BIN
      static/cache/posts/list_13.jpg
  22. BIN
      static/cache/posts/origin_13.jpg
  23. BIN
      static/cache/posts/thumb_13.jpg
  24. BIN
      static/cache/posts/thumb_gallery_view_13.jpg
  25. BIN
      static/origin/posts/13.jpg
  26. 24
      vagrant/nginx/log/static-error.log

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

@ -53,11 +53,16 @@ class PostController extends FrontendController
'class' => AccessControl::class, 'class' => AccessControl::class,
'rules' => [ 'rules' => [
[ [
'actions' => ['index', 'category', 'tag', 'post', 'preview'], 'actions' => ['index', 'category', 'tag', 'post'],
'allow' => true, 'allow' => true,
//'roles' => ['Blog'], //'roles' => ['Blog'],
], ],
[ [
'actions' => ['preview'],
'allow' => true,
'roles' => ['BlogManagement'],
],
[
'actions' => ['comment'], 'actions' => ['comment'],
'allow' => true, 'allow' => true,
'roles' => ['Comments'], 'roles' => ['Comments'],
@ -178,13 +183,17 @@ class PostController extends FrontendController
return parent::beforeAction($action); return parent::beforeAction($action);
} }
public function actionPreview() /*public function actionPreview($id = null)
{ {
Yii::$app->controller->enableCsrfValidation = false; Yii::$app->controller->enableCsrfValidation = false;
$form = new BlogPostForm(); $form = new BlogPostForm();
if ($form->load(Yii::$app->request->post()) && $form->validate()) { $parent = $id ? BlogPost::findOne($id) : null;
if ($form->load(Yii::$app->request->post())) {
$form->slug = md5(time());
if ($form->validate()) {
$post = new BlogPost(); $post = new BlogPost();
$post->id = -1; $post->id = - 1;
$post->title = $form->title; $post->title = $form->title;
$post->description = $form->description; $post->description = $form->description;
$post->content = $form->content; $post->content = $form->content;
@ -193,38 +202,52 @@ class PostController extends FrontendController
$post->updated_at = time(); $post->updated_at = time();
$post->published_at = time(); $post->published_at = time();
$meta = new Meta($form->meta->title, $form->meta->description, $form->meta->keywords); $meta = new Meta( $form->meta->title, $form->meta->description, $form->meta->keywords );
$post->meta = $meta; $post->meta = $meta;
$post->meta_json = Json::encode([ $post->meta_json = Json::encode( [
'title' => $form->meta->title, 'title' => $form->meta->title,
'description' => $form->meta->description, 'description' => $form->meta->description,
'keywords' => $form->meta->keywords, 'keywords' => $form->meta->keywords,
]); ] );
$post->video = $form->video; $post->video = $form->video;
$post->slug = $form->slug; $post->slug = $form->slug;
if ($form->image) { if ( $form->image ) {
$post->setImage($form->image); $post->setImage( $form->image );
} } else if ( $form->video ) {
else if ($form->video) { $src = 'https://i.ytimg.com/vi/' . BlogPostHelper::parseYoutubeUrl( $post->video ) . '/maxresdefault.jpg';
$src = 'https://i.ytimg.com/vi/' . BlogPostHelper::parseYoutubeUrl($post->video) . '/maxresdefault.jpg'; $filename = ( new Security() )->generateRandomString( 15 ) . '.jpg';
$filename = (new Security())->generateRandomString(15) . '.jpg'; copy( $src, \Yii::getAlias( BlogPost::FILE_ORIGINAL_PATH . '/' . $post->id . '.jpg' ) );
copy($src, \Yii::getAlias(BlogPost::FILE_ORIGINAL_PATH . '/' . $post->id . '.jpg'));
//copy($src, \Yii::getAlias(BlogPost::FILE_ORIGINAL_PATH . '/' . $filename)); //copy($src, \Yii::getAlias(BlogPost::FILE_ORIGINAL_PATH . '/' . $filename));
$post->image = $filename; $post->image = $filename;
} }
if ($post->image && !is_string($post->image)) { if ( $post->image ) {
$path = $post->getUploadedFilePath( 'image' ); $path = $post->getUploadedFilePath( 'image' );
FileHelper::createDirectory( pathinfo( $path, PATHINFO_DIRNAME ), 0775, true ); FileHelper::createDirectory( pathinfo( $path, PATHINFO_DIRNAME ), 0775, true );
$post->image->saveAs( $path ); $post->image->saveAs( $path );
$post->image = $post->getImageFileUrl( 'image' ); $post->image = $post->getImageFileUrl( 'image' );
} else {
$post->image = $parent->image;
//$post->image = $post->getImageFileUrl( 'image' );
} }
return $this->render('post', [ return $this->render( 'post', [
'post' => $post, 'post' => $post,
]); ] );
} }
} else {print_r($form->errors);}
return ''; return '';
}*/
public function actionPreview($id)
{
if (!$post = $this->posts->findPreview($id)) {
throw new NotFoundHttpException('The requested page does not exist.');
}
return $this->render('post', [
'post' => $post,
]);
} }
} }

70
common/modules/blog/controllers/manage/PostController.php

@ -8,6 +8,7 @@ use common\modules\blog\forms\BlogPostForm;
use common\modules\blog\forms\search\BlogPostSearch; use common\modules\blog\forms\search\BlogPostSearch;
use common\modules\blog\services\BlogPostManageService; use common\modules\blog\services\BlogPostManageService;
use Yii; use Yii;
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;
@ -49,6 +50,8 @@ class PostController extends Controller
'delete-photo' => ['POST'], 'delete-photo' => ['POST'],
'move-photo-up' => ['POST'], 'move-photo-up' => ['POST'],
'move-photo-down' => ['POST'], 'move-photo-down' => ['POST'],
'restore-history' => ['POST'],
'clear-history' => ['POST'],
], ],
], ],
]; ];
@ -76,28 +79,63 @@ class PostController extends Controller
public function actionView($id) public function actionView($id)
{ {
$post = $this->findModel($id); $post = $this->findModel($id);
$history = BlogPost::find()
->andWhere(['OR', ['revision_id' => $id], ['id' => $id]])
->orderBy(['revision_at' => SORT_DESC])
->limit(20)
->all();
return $this->render('view', [ return $this->render('view', [
'post' => $post, 'post' => $post,
'history' => $history,
]); ]);
} }
/** public function actionCreatePreview($id = null)
* @return string|Response
*/
public function actionCreate()
{ {
$this->service->removePreviews();
$form = new BlogPostForm(); $form = new BlogPostForm();
$form->action = 'create'; $form->type = BlogPost::TYPE_PREVIEW;
if ($form->load(Yii::$app->request->post()) && $form->validate()) {
try {
$post = $this->service->create( $form, BlogPost::TYPE_PREVIEW );
if ($id && !$post->image) {
$real_post = BlogPost::findOne($id);
if ($real_post->image) {
$post->image = $real_post->image;
$post->save();
$path = Yii::getAlias('@staticRoot/origin/posts');
$parts = pathinfo($real_post->image);
copy($path . '/' . $real_post->id . '.' . $parts['extension'], $path . '/' . $post->id . '.' . $parts['extension']);
}
}
return $this->redirect(Url::to(Yii::$app->get('frontendUrlManager')->createAbsoluteUrl(['/blog/post/preview', 'id' => $post->id])));
} catch (\DomainException $e) {
Yii::$app->errorHandler->logException($e);
Yii::$app->session->setFlash('error', $e->getMessage());
}
}
$form->published_at = date('d.m.Y H:i:s'); $form->published_at = date('d.m.Y H:i:s');
return $this->render('create', [
'model' => $form,
]);
}
public function actionCreate()
{
$form = new BlogPostForm();
if ($form->load(Yii::$app->request->post()) && $form->validate()) { if ($form->load(Yii::$app->request->post()) && $form->validate()) {
try { try {
$post = $this->service->create($form); $post = $this->service->create( $form );
return $this->redirect(['view', 'id' => $post->id]); return $this->redirect( [ 'view', 'id' => $post->id ] );
} catch (\DomainException $e) { } catch (\DomainException $e) {
Yii::$app->errorHandler->logException($e); Yii::$app->errorHandler->logException($e);
Yii::$app->session->setFlash('error', $e->getMessage()); Yii::$app->session->setFlash('error', $e->getMessage());
} }
} }
$form->published_at = date('d.m.Y H:i:s');
return $this->render('create', [ return $this->render('create', [
'model' => $form, 'model' => $form,
]); ]);
@ -113,7 +151,6 @@ class PostController extends Controller
{ {
$post = $this->findModel($id); $post = $this->findModel($id);
$form = new BlogPostForm($post); $form = new BlogPostForm($post);
$form->action = 'update';
$form->published_at = date('d.m.Y H:i:s', $form->published_at); $form->published_at = date('d.m.Y H:i:s', $form->published_at);
if ($form->load(Yii::$app->request->post()) && $form->validate()) { if ($form->load(Yii::$app->request->post()) && $form->validate()) {
try { try {
@ -207,6 +244,23 @@ class PostController extends Controller
return $out; return $out;
} }
public function actionRestoreHistory($id)
{
$post = $this->findModel($id);
if ($post_id = $post->revision_id) {
$this->service->restoreHistory($id, $post->revision_id);
return $this->redirect(['/blog/manage/post/view', 'id' => $post_id]);
}
return $this->redirect(['/blog/manage/post/index']);
}
public function actionClearHistory($id)
{
$post = $this->findModel($id);
$this->service->clearHistory($post);
return $this->redirect(['/blog/manage/post/view', 'id' => $post->id]);
}
/** /**
* @param $id * @param $id
* *

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

@ -4,6 +4,7 @@ namespace common\modules\blog\entities;
use common\modules\blog\entities\queries\BlogPostQuery; use common\modules\blog\entities\queries\BlogPostQuery;
use core\behaviors\MetaBehavior; use core\behaviors\MetaBehavior;
use core\behaviors\RevisionBehavior;
use core\entities\Meta; use core\entities\Meta;
use lhs\Yii2SaveRelationsBehavior\SaveRelationsBehavior; use lhs\Yii2SaveRelationsBehavior\SaveRelationsBehavior;
use yii\behaviors\TimestampBehavior; use yii\behaviors\TimestampBehavior;
@ -32,6 +33,9 @@ use Yii;
* @property int $comments_count * @property int $comments_count
* @property int $views * @property int $views
* @property string $slug * @property string $slug
* @property int $type
* @property int $revision_at
* @property int $revision_id
* *
* @property BlogComment[] $blogComments * @property BlogComment[] $blogComments
* @property BlogTagAssignment[] $blogTagAssignments * @property BlogTagAssignment[] $blogTagAssignments
@ -45,11 +49,15 @@ class BlogPost extends ActiveRecord
const STATUS_DRAFT = 0; const STATUS_DRAFT = 0;
const STATUS_ACTIVE = 1; const STATUS_ACTIVE = 1;
const TYPE_PUBLIC = 0;
const TYPE_REVISION = 1;
const TYPE_PREVIEW = 2;
const FILE_ORIGINAL_PATH = '@staticRoot/origin/posts'; const FILE_ORIGINAL_PATH = '@staticRoot/origin/posts';
public $meta; public $meta;
public static function create($categoryId, $title, $slug, $description, $content, $published_at, $video, Meta $meta): self public static function create($categoryId, $title, $slug, $description, $content, $published_at, $video, $type = 0, Meta $meta): self
{ {
$post = new static(); $post = new static();
$post->category_id = $categoryId; $post->category_id = $categoryId;
@ -63,6 +71,8 @@ class BlogPost extends ActiveRecord
$post->comments_count = 0; $post->comments_count = 0;
$post->published_at = $published_at; $post->published_at = $published_at;
$post->video = $video; $post->video = $video;
$post->type = $type;
$post->revision_at = time();
return $post; return $post;
} }
@ -72,7 +82,7 @@ class BlogPost extends ActiveRecord
} }
public function edit($categoryId, $title, $slug, $description, $content, $published_at, $video, Meta $meta): void public function edit($categoryId, $title, $slug, $description, $content, $published_at, $video, $type = 0, Meta $meta): void
{ {
$this->category_id = $categoryId; $this->category_id = $categoryId;
$this->title = $title; $this->title = $title;
@ -82,6 +92,8 @@ class BlogPost extends ActiveRecord
$this->meta = $meta; $this->meta = $meta;
$this->published_at = $published_at; $this->published_at = $published_at;
$this->video = $video; $this->video = $video;
$this->type = $type;
$this->revision_at = time();
} }
/** /**
@ -108,6 +120,8 @@ class BlogPost extends ActiveRecord
'content' => Yii::t('blog', 'Content'), 'content' => Yii::t('blog', 'Content'),
'image' => Yii::t('blog', 'Image'), 'image' => Yii::t('blog', 'Image'),
'video' => Yii::t('blog', 'Video'), 'video' => Yii::t('blog', 'Video'),
'type' => Yii::t('blog', 'Type'),
'revision_at' => Yii::t('blog', 'Revision At'),
'status' => Yii::t('blog', 'Status'), 'status' => Yii::t('blog', 'Status'),
'meta_json' => Yii::t('blog', 'Meta Json'), 'meta_json' => Yii::t('blog', 'Meta Json'),
'comments_count' => Yii::t('blog', 'Comments Count'), 'comments_count' => Yii::t('blog', 'Comments Count'),

11
common/modules/blog/entities/queries/BlogPostQuery.php

@ -23,11 +23,18 @@ class BlogPostQuery extends ActiveQuery
return $this->andWhere(['<', 'published_at', time()]); return $this->andWhere(['<', 'published_at', time()]);
} }
public function byType($type) public function typePublic($alias = null)
{ {
return $this->andWhere(['type_id' => $type]); return $this->andWhere([
($alias ? $alias . '.' : '') . 'type' => BlogPost::TYPE_PUBLIC,
]);
} }
/*public function byType($type)
{
return $this->andWhere(['type_id' => $type]);
}*/
public function last() public function last()
{ {
return $this->orderBy(['published_at' => SORT_DESC]); return $this->orderBy(['published_at' => SORT_DESC]);

19
common/modules/blog/forms/BlogPostForm.php

@ -7,6 +7,7 @@ use common\modules\blog\entities\BlogPost;
use core\forms\CompositeForm; use core\forms\CompositeForm;
use core\forms\MetaForm; use core\forms\MetaForm;
use core\validators\SlugValidator; use core\validators\SlugValidator;
use yii\db\ActiveQuery;
use yii\helpers\ArrayHelper; use yii\helpers\ArrayHelper;
use yii\web\UploadedFile; use yii\web\UploadedFile;
use Yii; use Yii;
@ -17,7 +18,7 @@ use Yii;
*/ */
class BlogPostForm extends CompositeForm class BlogPostForm extends CompositeForm
{ {
public $action; public $type;
public $category_id; public $category_id;
public $title; public $title;
@ -65,7 +66,21 @@ class BlogPostForm extends CompositeForm
['reset_image', 'boolean'], ['reset_image', 'boolean'],
['published_at', 'safe'], ['published_at', 'safe'],
['slug', SlugValidator::class], ['slug', SlugValidator::class],
[['slug'], 'unique', 'targetClass' => BlogPost::class, 'filter' => $this->_post ? ['<>', 'id', $this->_post->id] : null], //[['slug'], 'unique', 'targetClass' => BlogPost::class, 'filter' => $this->_post ? ['<>', 'id', $this->_post->id] : null],
//[['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);
}
$query->andWhere(['type' => BlogPost::TYPE_PUBLIC]);
if ($this->_post) {
$query->andWhere(['<>', 'id', $this->_post->id]);
}
return $query;
}],
]; ];
} }

2
common/modules/blog/forms/search/BlogPostSearch.php

@ -30,7 +30,7 @@ class BlogPostSearch extends Model
*/ */
public function search(array $params): ActiveDataProvider public function search(array $params): ActiveDataProvider
{ {
$query = BlogPost::find(); $query = BlogPost::find()->typePublic();
$dataProvider = new ActiveDataProvider([ $dataProvider = new ActiveDataProvider([
'query' => $query, 'query' => $query,

17
common/modules/blog/helpers/BlogPostHelper.php

@ -2,6 +2,7 @@
namespace common\modules\blog\helpers; namespace common\modules\blog\helpers;
use common\modules\blog\entities\BlogPost;
use core\entities\post\Post; use core\entities\post\Post;
use yii\helpers\ArrayHelper; use yii\helpers\ArrayHelper;
use yii\helpers\Html; use yii\helpers\Html;
@ -67,4 +68,20 @@ class BlogPostHelper
} }
return $id; return $id;
} }
public static function saveRevision(BlogPost $model) {
if (!$model->revision_id) {
$revision = clone $model;
$revision->id = null;
$revision->isNewRecord = true;
$revision->revision_at = $revision->updated_at;
$revision->revision_id = $model->id;
$revision->type = BlogPost::TYPE_REVISION;
$revision->save( $revision );
$path = Yii::getAlias('@staticRoot/origin/posts');
$parts = pathinfo($model->image);
copy($path . '/' . $model->id . '.' . $parts['extension'], $path . '/' . $revision->id . '.' . $parts['extension']);
}
}
} }

10
common/modules/blog/messages/ru/blog.php

@ -67,4 +67,14 @@ return [
'Blog Post' => 'Статья', 'Blog Post' => 'Статья',
'Blog Home' => 'Блог', 'Blog Home' => 'Блог',
'Select post...' => 'Укажите статью...', 'Select post...' => 'Укажите статью...',
'Type' => 'Тип',
'Revision At' => 'Версия',
'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' => 'Просмотр',
]; ];

34
common/modules/blog/migrations/m180725_091725_add_blog_posts_type_field.php

@ -0,0 +1,34 @@
<?php
use yii\db\Migration;
/**
* Class m180725_091725_add_blog_posts_type_field
*/
class m180725_091725_add_blog_posts_type_field extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->addColumn('{{%blog_posts}}', 'type', $this->integer(2)->defaultValue(0)); // 0 - public, 1 - revision, 2 - preview
$this->addColumn('{{%blog_posts}}', 'revision_at', $this->integer()->unsigned());
$this->addColumn('{{%blog_posts}}', 'revision_id', $this->integer());
$this->createIndex('idx_blog_posts_revision_id', '{{%blog_posts}}', 'revision_id');
}
/**
* {@inheritdoc}
*/
public function safeDown()
{
$this->dropIndex('idx_blog_posts_revision_id', '{{%blog_posts}}');
$this->dropColumn('{{%blog_posts}}', 'type');
$this->dropColumn('{{%blog_posts}}', 'revision_at');
$this->dropColumn('{{%blog_posts}}', 'revision_id');
return false;
}
}

28
common/modules/blog/migrations/m180725_113503_remove_blog_posts_slug_unique_index.php

@ -0,0 +1,28 @@
<?php
use yii\db\Migration;
/**
* Class m180725_113503_remove_blog_posts_slug_unique_index
*/
class m180725_113503_remove_blog_posts_slug_unique_index extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->dropIndex('{{%idx-blog_posts-slug}}', '{{%blog_posts}}');
$this->createIndex('{{%idx-blog_posts-slug}}', '{{%blog_posts}}', 'slug');
}
/**
* {@inheritdoc}
*/
public function safeDown()
{
return false;
$this->dropIndex('{{%idx-blog_posts-slug}}', '{{%blog_posts}}');
$this->createIndex('{{%idx-blog_posts-slug}}', '{{%blog_posts}}', 'slug');
}
}

21
common/modules/blog/repositories/read/BlogPostReadRepository.php

@ -13,40 +13,40 @@ class BlogPostReadRepository
{ {
public function count(): int public function count(): int
{ {
return BlogPost::find()->active()->pubDate()->count(); return BlogPost::find()->active()->pubDate()->typePublic()->count();
} }
public function getAllByRange($offset, $limit): array public function getAllByRange($offset, $limit): array
{ {
return BlogPost::find()->active()->pubDate()->orderBy(['id' => SORT_ASC])->limit($limit)->offset($offset)->all(); return BlogPost::find()->active()->pubDate()->typePublic()->orderBy(['id' => SORT_ASC])->limit($limit)->offset($offset)->all();
} }
public function getAll(): DataProviderInterface public function getAll(): DataProviderInterface
{ {
$query = BlogPost::find()->active()->pubDate()->with('category'); $query = BlogPost::find()->active()->pubDate()->typePublic()->with('category');
return $this->getProvider($query); return $this->getProvider($query);
} }
public function getAllByCategory(BlogCategory $category): DataProviderInterface public function getAllByCategory(BlogCategory $category): DataProviderInterface
{ {
$query = BlogPost::find()->active()->pubDate()->andWhere(['category_id' => $category->id])->with('category'); $query = BlogPost::find()->active()->pubDate()->typePublic()->andWhere(['category_id' => $category->id])->with('category');
return $this->getProvider($query); return $this->getProvider($query);
} }
public function findNext(int $id): ?BlogPost public function findNext(int $id): ?BlogPost
{ {
return BlogPost::find()->active()->pubDate()->andWhere(['>', 'id', $id])->one(); return BlogPost::find()->active()->pubDate()->typePublic()->andWhere(['>', 'id', $id])->one();
} }
public function findPrev(int $id): ?BlogPost public function findPrev(int $id): ?BlogPost
{ {
return BlogPost::find()->active()->pubDate()->andWhere(['<', 'id', $id])->orderBy(['id' => SORT_DESC])->one(); return BlogPost::find()->active()->pubDate()->typePublic()->andWhere(['<', 'id', $id])->orderBy(['id' => SORT_DESC])->one();
} }
public function getAllByTag(BlogTag $tag): DataProviderInterface public function getAllByTag(BlogTag $tag): DataProviderInterface
{ {
$query = BlogPost::find()->alias('p')->active('p')->with('category'); $query = BlogPost::find()->alias('p')->active('p')->typePublic('p')->with('category');
$query->joinWith(['blogTagAssignments ta'], false); $query->joinWith(['blogTagAssignments ta'], false);
$query->andWhere(['ta.tag_id' => $tag->id]); $query->andWhere(['ta.tag_id' => $tag->id]);
$query->groupBy('p.id'); $query->groupBy('p.id');
@ -55,7 +55,7 @@ class BlogPostReadRepository
public function getByTagsId(BlogPost $post, array $tag_ids, int $limit = 15): DataProviderInterface public function getByTagsId(BlogPost $post, array $tag_ids, int $limit = 15): DataProviderInterface
{ {
$query = BlogPost::find()->alias('p')->active('p')->with('category'); $query = BlogPost::find()->alias('p')->active('p')->typePublic('p')->with('category');
$query->joinWith(['blogTagAssignments ta'], false); $query->joinWith(['blogTagAssignments ta'], false);
$query->andWhere(['ta.tag_id' => $tag_ids]); $query->andWhere(['ta.tag_id' => $tag_ids]);
$query->andWhere(['!=', 'p.id', $post->id]); $query->andWhere(['!=', 'p.id', $post->id]);
@ -91,4 +91,9 @@ class BlogPostReadRepository
{ {
return BlogPost::find()->andWhere(['slug' => $slug])->one(); return BlogPost::find()->andWhere(['slug' => $slug])->one();
} }
public function findPreview($id): ?BlogPost
{
return BlogPost::find()->andWhere(['id' => $id])->one();
}
} }

51
common/modules/blog/services/BlogPostManageService.php

@ -35,7 +35,7 @@ class BlogPostManageService
$this->transaction = $transaction; $this->transaction = $transaction;
} }
public function create(BlogPostForm $form): BlogPost public function create(BlogPostForm $form, $type = BlogPost::TYPE_PUBLIC): BlogPost
{ {
$category = $this->categories->get($form->category_id); $category = $this->categories->get($form->category_id);
@ -47,6 +47,7 @@ class BlogPostManageService
$form->content, $form->content,
$form->published_at, $form->published_at,
$form->video, $form->video,
$type,
new Meta( new Meta(
$form->meta->title, $form->meta->title,
$form->meta->description, $form->meta->description,
@ -91,6 +92,8 @@ class BlogPostManageService
public function edit($id, BlogPostForm $form): void public function edit($id, BlogPostForm $form): void
{ {
$post = $this->posts->get($id); $post = $this->posts->get($id);
BlogPostHelper::saveRevision($post);
$category = $this->categories->get($form->category_id); $category = $this->categories->get($form->category_id);
$post->edit( $post->edit(
@ -101,6 +104,7 @@ class BlogPostManageService
$form->content, $form->content,
$form->published_at, $form->published_at,
$form->video, $form->video,
$post->type,
new Meta( new Meta(
$form->meta->title, $form->meta->title,
$form->meta->description, $form->meta->description,
@ -129,9 +133,10 @@ class BlogPostManageService
$this->transaction->wrap(function () use ($post, $form) { $this->transaction->wrap(function () use ($post, $form) {
$post->revokeTags(); $post->revokeTags();
//$post->doRevision();
$this->posts->save($post); $this->posts->save($post);
//$post->stopRevision();
$tag_updated = false;
if (is_array($form->tags->new_tags) && !empty($form->tags->new_tags)) { if (is_array($form->tags->new_tags) && !empty($form->tags->new_tags)) {
foreach ( $form->tags->new_tags as $tag_id => $tag_name ) { foreach ( $form->tags->new_tags as $tag_id => $tag_name ) {
if ( ! $tag = $this->tags->findByName( $tag_name ) ) { if ( ! $tag = $this->tags->findByName( $tag_name ) ) {
@ -139,13 +144,9 @@ class BlogPostManageService
$this->tags->save( $tag ); $this->tags->save( $tag );
} }
$post->assignTag( $tag->id ); $post->assignTag( $tag->id );
$tag_updated = true;
} }
} }
if ($tag_updated) {
$this->posts->save( $post ); $this->posts->save( $post );
}
}); });
} }
@ -168,4 +169,42 @@ class BlogPostManageService
$post = $this->posts->get($id); $post = $this->posts->get($id);
$this->posts->remove($post); $this->posts->remove($post);
} }
public function removePreviews(): void
{
$posts = BlogPost::find()->andWhere(['type' => BlogPost::TYPE_PREVIEW])->all();
foreach ($posts as $post) {
$post->delete();
}
}
public function clearHistory(BlogPost $post): void
{
BlogPost::deleteAll(['revision_id' => $post->id]);
}
public function restoreHistory($from_id, $id): void
{
$post = $this->posts->get($id);
$from = $this->posts->get($from_id);
// remove current revision
$this->posts->remove($post);
// copy image
$path = \Yii::getAlias('@staticRoot/origin/posts');
$parts = pathinfo($from->image);
copy($path . '/' . $from->id . '.' . $parts['extension'], $path . '/' . $id . '.' . $parts['extension']);
$from->createThumbs();
$from->id = $id;
$from->type = BlogPost::TYPE_PUBLIC;
$from->revision_id = null;
// restore revision to current
$this->posts->save($from);
// delete never revisions
BlogPost::deleteAll(['AND', ['revision_id' => $from->id], ['>', 'revision_at', $from->revision_at]]);
}
} }

2
common/modules/blog/views/manage/post/_form.php

@ -168,7 +168,7 @@ $this->registerJs($js2);
'class' => 'btn btn-info', 'class' => 'btn btn-info',
'value'=>'preview', 'value'=>'preview',
'name'=>'submit_preview', 'name'=>'submit_preview',
'formaction' => Url::to(Yii::$app->params['frontendHostInfo'] . '/blog/post/preview'), 'formaction' => Url::to(['/blog/manage/post/create-preview', 'id' => $model->_post ? $model->_post->id : null]),
'formtarget' => '_blank', 'formtarget' => '_blank',
]) ?> ]) ?>
<hr> <hr>

59
common/modules/blog/views/manage/post/view.php

@ -8,6 +8,7 @@ use yii\widgets\DetailView;
/* @var $this yii\web\View */ /* @var $this yii\web\View */
/* @var $post \common\modules\blog\entities\BlogPost */ /* @var $post \common\modules\blog\entities\BlogPost */
/* @var $modificationsProvider yii\data\ActiveDataProvider */ /* @var $modificationsProvider yii\data\ActiveDataProvider */
/* @var $history \common\modules\blog\entities\BlogPost[] */
$title = $post->title; $title = $post->title;
$this->title = $title; $this->title = $title;
@ -33,6 +34,10 @@ $this->params['breadcrumbs'][] = $title;
]) ?> ]) ?>
</p> </p>
<div class="row">
<div class="col-md-9">
<div class="box"> <div class="box">
<div class="box-header with-border"><?= Yii::t('blog', 'Common') ?></div> <div class="box-header with-border"><?= Yii::t('blog', 'Common') ?></div>
<div class="box-body"> <div class="box-body">
@ -143,4 +148,58 @@ $this->params['breadcrumbs'][] = $title;
</div> </div>
</div> </div>
</div>
<div class="col-md-3">
<div class="box">
<div class="box-header with-border"><?= Yii::t('blog', '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(['/blog/post/preview', 'id' => $item->id])), [
'style' => 'font-size:11px;',
'target' => '_blank',
]) ?>
|
<?= Html::a(Yii::t('blog', 'Restore'), ['/blog/manage/post/restore-history', 'id' => $item->id], [
'style' => 'font-size:11px; color: red',
'data' => [
'confirm' => Yii::t('blog', 'Are you sure you want to restore this history item?'),
'method' => 'post',
],
]) ?>
<?php else: ?>
<strong><?= Yii::t('blog', 'Current Edition') ?></strong>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
<?= Html::a(Yii::t('blog', 'Clear History'), ['/blog/manage/post/clear-history', 'id' => $post->id], [
'class' => 'btn btn-danger btn-sm pull-right',
'data' => [
'confirm' => Yii::t('blog', 'Are you sure you want to remove this history?'),
'method' => 'post',
],
]) ?>
<?php else: ?>
<div style="padding: 20px 0; text-align: center"><?= Yii::t('blog', 'History is empty') ?></div>
<?php endif; ?>
</div>
</div>
</div>
</div>
</div> </div>

BIN
static/cache/posts/368_287_13.jpg vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

BIN
static/cache/posts/370_325_13.jpg vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

BIN
static/cache/posts/683_407_13.jpg vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 213 KiB

BIN
static/cache/posts/94_94_13.jpg vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

BIN
static/cache/posts/admin_13.jpg vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

BIN
static/cache/posts/home_slider_13.jpg vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

BIN
static/cache/posts/list_13.jpg vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

BIN
static/cache/posts/origin_13.jpg vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 192 KiB

BIN
static/cache/posts/thumb_13.jpg vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

BIN
static/cache/posts/thumb_gallery_view_13.jpg vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

BIN
static/origin/posts/13.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

24
vagrant/nginx/log/static-error.log

@ -19,3 +19,27 @@
2018/07/06 10:17:57 [error] 1920#1920: *1225 open() "/app/static/cache/posts/blog_post_-1.jpg" failed (2: No such file or directory), client: 192.168.83.1, server: static.morework.local, request: "GET /cache/posts/blog_post_-1.jpg HTTP/1.1", host: "static.morework.local" 2018/07/06 10:17:57 [error] 1920#1920: *1225 open() "/app/static/cache/posts/blog_post_-1.jpg" failed (2: No such file or directory), client: 192.168.83.1, server: static.morework.local, request: "GET /cache/posts/blog_post_-1.jpg HTTP/1.1", host: "static.morework.local"
2018/07/06 10:18:44 [error] 1920#1920: *1228 open() "/app/static/cache/posts/blog_post_-1.jpg" failed (2: No such file or directory), client: 192.168.83.1, server: static.morework.local, request: "GET /cache/posts/blog_post_-1.jpg HTTP/1.1", host: "static.morework.local", referrer: "http://morework.local/blog/post/preview" 2018/07/06 10:18:44 [error] 1920#1920: *1228 open() "/app/static/cache/posts/blog_post_-1.jpg" failed (2: No such file or directory), client: 192.168.83.1, server: static.morework.local, request: "GET /cache/posts/blog_post_-1.jpg HTTP/1.1", host: "static.morework.local", referrer: "http://morework.local/blog/post/preview"
2018/07/06 10:20:25 [error] 1920#1920: *1232 open() "/app/static/cache/posts/blog_post_-1.jpg" failed (2: No such file or directory), client: 192.168.83.1, server: static.morework.local, request: "GET /cache/posts/blog_post_-1.jpg HTTP/1.1", host: "static.morework.local", referrer: "http://morework.local/blog/post/preview" 2018/07/06 10:20:25 [error] 1920#1920: *1232 open() "/app/static/cache/posts/blog_post_-1.jpg" failed (2: No such file or directory), client: 192.168.83.1, server: static.morework.local, request: "GET /cache/posts/blog_post_-1.jpg HTTP/1.1", host: "static.morework.local", referrer: "http://morework.local/blog/post/preview"
2018/07/25 14:48:26 [error] 1933#1933: *552 open() "/app/static/cache/posts/blog_post_13.jpg" failed (2: No such file or directory), client: 192.168.83.1, server: static.morework.local, request: "GET /cache/posts/blog_post_13.jpg HTTP/1.1", host: "static.morework.local", referrer: "http://morework.local/blog/post/preview?id=22"
2018/07/25 14:49:11 [error] 1933#1933: *558 open() "/app/static/cache/posts/blog_post_23.jpg" failed (2: No such file or directory), client: 192.168.83.1, server: static.morework.local, request: "GET /cache/posts/blog_post_23.jpg HTTP/1.1", host: "static.morework.local", referrer: "http://morework.local/blog/post/preview?id=23"
2018/07/25 14:49:57 [error] 1933#1933: *558 open() "/app/static/cache/posts/blog_post_24.png" failed (2: No such file or directory), client: 192.168.83.1, server: static.morework.local, request: "GET /cache/posts/blog_post_24.png HTTP/1.1", host: "static.morework.local", referrer: "http://morework.local/blog/post/preview?id=24"
2018/07/25 14:50:22 [error] 1933#1933: *558 open() "/app/static/cache/posts/blog_post_25.png" failed (2: No such file or directory), client: 192.168.83.1, server: static.morework.local, request: "GET /cache/posts/blog_post_25.png HTTP/1.1", host: "static.morework.local", referrer: "http://morework.local/blog/post/preview?id=25"
2018/07/25 14:55:07 [error] 1933#1933: *583 open() "/app/static/cache/posts/blog_post_26.png" failed (2: No such file or directory), client: 192.168.83.1, server: static.morework.local, request: "GET /cache/posts/blog_post_26.png HTTP/1.1", host: "static.morework.local", referrer: "http://morework.local/blog/post/preview?id=26"
2018/07/25 14:55:25 [error] 1933#1933: *583 open() "/app/static/cache/posts/blog_post_26.png" failed (2: No such file or directory), client: 192.168.83.1, server: static.morework.local, request: "GET /cache/posts/blog_post_26.png HTTP/1.1", host: "static.morework.local"
2018/07/25 14:55:32 [error] 1933#1933: *583 open() "/app/static/cache/posts/blog_post_26.png" failed (2: No such file or directory), client: 192.168.83.1, server: static.morework.local, request: "GET /cache/posts/blog_post_26.png HTTP/1.1", host: "static.morework.local"
2018/07/25 15:14:57 [error] 1933#1933: *638 open() "/app/static/cache/posts/blog_post_28.png" failed (2: No such file or directory), client: 192.168.83.1, server: static.morework.local, request: "GET /cache/posts/blog_post_28.png HTTP/1.1", host: "static.morework.local", referrer: "http://morework.local/blog/post/preview?id=28"
2018/07/25 15:19:30 [error] 1933#1933: *663 open() "/app/static/cache/posts/blog_post_30.png" failed (2: No such file or directory), client: 192.168.83.1, server: static.morework.local, request: "GET /cache/posts/blog_post_30.png HTTP/1.1", host: "static.morework.local", referrer: "http://morework.local/blog/post/preview?id=30"
2018/07/25 15:33:18 [error] 1933#1933: *669 open() "/app/static/cache/posts/blog_post_31.png" failed (2: No such file or directory), client: 192.168.83.1, server: static.morework.local, request: "GET /cache/posts/blog_post_31.png HTTP/1.1", host: "static.morework.local", referrer: "http://morework.local/blog/post/preview?id=31"
2018/07/25 15:35:13 [error] 1933#1933: *676 open() "/app/static/cache/posts/blog_post_32.png" failed (2: No such file or directory), client: 192.168.83.1, server: static.morework.local, request: "GET /cache/posts/blog_post_32.png HTTP/1.1", host: "static.morework.local", referrer: "http://morework.local/blog/post/preview?id=32"
2018/07/25 20:06:07 [error] 1933#1933: *946 open() "/app/static/cache/posts/blog_post_53.jpg" failed (2: No such file or directory), client: 192.168.83.1, server: static.morework.local, request: "GET /cache/posts/blog_post_53.jpg HTTP/1.1", host: "static.morework.local", referrer: "http://morework.local/blog/post/preview?id=53"
2018/07/25 23:05:07 [error] 1933#1933: *1256 open() "/app/static/cache/posts/thumb_gallery_view_68.jpg" failed (2: No such file or directory), client: 192.168.83.1, server: static.morework.local, request: "GET /cache/posts/thumb_gallery_view_68.jpg HTTP/1.1", host: "static.morework.local", referrer: "http://admin.morework.local/blog/manage/post/view/68"
2018/07/25 23:36:51 [error] 1933#1933: *1389 open() "/app/static/cache/posts/thumb_gallery_view_27.png" failed (2: No such file or directory), client: 192.168.83.1, server: static.morework.local, request: "GET /cache/posts/thumb_gallery_view_27.png HTTP/1.1", host: "static.morework.local", referrer: "http://admin.morework.local/blog/manage/post/view/27"
2018/07/25 23:47:55 [error] 1933#1933: *1465 open() "/app/static/cache/posts/thumb_gallery_view_83.png" failed (2: No such file or directory), client: 192.168.83.1, server: static.morework.local, request: "GET /cache/posts/thumb_gallery_view_83.png HTTP/1.1", host: "static.morework.local", referrer: "http://admin.morework.local/blog/manage/post/view/83"
2018/07/25 23:48:13 [error] 1933#1933: *1465 open() "/app/static/cache/posts/thumb_gallery_view_83.png" failed (2: No such file or directory), client: 192.168.83.1, server: static.morework.local, request: "GET /cache/posts/thumb_gallery_view_83.png HTTP/1.1", host: "static.morework.local", referrer: "http://admin.morework.local/blog/manage/post/update?id=83"
2018/07/25 23:48:13 [error] 1933#1933: *1465 open() "/app/static/cache/posts/thumb_gallery_view_83.png" failed (2: No such file or directory), client: 192.168.83.1, server: static.morework.local, request: "GET /cache/posts/thumb_gallery_view_83.png HTTP/1.1", host: "static.morework.local", referrer: "http://admin.morework.local/blog/manage/post/update?id=83"
2018/07/25 23:50:33 [error] 1933#1933: *1497 open() "/app/static/cache/posts/thumb_gallery_view_83.png" failed (2: No such file or directory), client: 192.168.83.1, server: static.morework.local, request: "GET /cache/posts/thumb_gallery_view_83.png HTTP/1.1", host: "static.morework.local", referrer: "http://admin.morework.local/blog/manage/post/view/83"
2018/07/25 23:50:39 [error] 1933#1933: *1497 open() "/app/static/cache/posts/thumb_gallery_view_83.png" failed (2: No such file or directory), client: 192.168.83.1, server: static.morework.local, request: "GET /cache/posts/thumb_gallery_view_83.png HTTP/1.1", host: "static.morework.local", referrer: "http://admin.morework.local/blog/manage/post/update?id=83"
2018/07/25 23:50:39 [error] 1933#1933: *1497 open() "/app/static/cache/posts/thumb_gallery_view_83.png" failed (2: No such file or directory), client: 192.168.83.1, server: static.morework.local, request: "GET /cache/posts/thumb_gallery_view_83.png HTTP/1.1", host: "static.morework.local", referrer: "http://admin.morework.local/blog/manage/post/update?id=83"
2018/07/25 23:51:08 [error] 1933#1933: *1497 open() "/app/static/cache/posts/thumb_gallery_view_83.png" failed (2: No such file or directory), client: 192.168.83.1, server: static.morework.local, request: "GET /cache/posts/thumb_gallery_view_83.png HTTP/1.1", host: "static.morework.local", referrer: "http://admin.morework.local/blog/manage/post/view/83"
2018/07/25 23:51:14 [error] 1933#1933: *1497 open() "/app/static/cache/posts/thumb_gallery_view_83.png" failed (2: No such file or directory), client: 192.168.83.1, server: static.morework.local, request: "GET /cache/posts/thumb_gallery_view_83.png HTTP/1.1", host: "static.morework.local", referrer: "http://admin.morework.local/blog/manage/post/update?id=83"
2018/07/25 23:51:14 [error] 1933#1933: *1497 open() "/app/static/cache/posts/thumb_gallery_view_83.png" failed (2: No such file or directory), client: 192.168.83.1, server: static.morework.local, request: "GET /cache/posts/thumb_gallery_view_83.png HTTP/1.1", host: "static.morework.local", referrer: "http://admin.morework.local/blog/manage/post/update?id=83"
2018/07/26 15:10:09 [error] 1933#1933: *1523 open() "/app/static/cache/posts/thumb_gallery_view_83.png" failed (2: No such file or directory), client: 192.168.83.1, server: static.morework.local, request: "GET /cache/posts/thumb_gallery_view_83.png HTTP/1.1", host: "static.morework.local", referrer: "http://admin.morework.local/blog/manage/post/view/83"

Loading…
Cancel
Save