REFACTORING #1880 @4h30m: another ugly refactoring commit
This commit is contained in:
+103
-14
@@ -2,10 +2,14 @@
|
||||
|
||||
namespace App\Models\Content;
|
||||
|
||||
use App\CMS\Contracts\Repositories\Content as ContentContract;
|
||||
use App\CMS\Helpers\Traits\Nullable;
|
||||
use App\CMS\Observers\Content as ContentObserver;
|
||||
use App\Models\FileManager\File;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Support\Str;
|
||||
use Modules\Categories\Entities\Category;
|
||||
|
||||
/**
|
||||
@@ -13,27 +17,41 @@ use Modules\Categories\Entities\Category;
|
||||
*/
|
||||
class Content extends Model
|
||||
{
|
||||
use SoftDeletes, ModelTraits\Content;
|
||||
use SoftDeletes, ModelTraits\Content, Nullable;
|
||||
public $timestamps = true;
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
'parent_id',
|
||||
'category_id',
|
||||
'userId',
|
||||
'parentId',
|
||||
'categoryId',
|
||||
'language',
|
||||
'module_handler',
|
||||
'published_from',
|
||||
'published_to',
|
||||
'title_photo',
|
||||
'moduleHandler',
|
||||
'publishedFrom',
|
||||
'publishedTo',
|
||||
'titlePhoto',
|
||||
'template',
|
||||
'is_homepage',
|
||||
'isHomepage',
|
||||
'title',
|
||||
'url',
|
||||
'meta_keywords',
|
||||
'meta_description',
|
||||
'content',
|
||||
'module_settings',
|
||||
'metaKeywords',
|
||||
'metaDescription',
|
||||
'pageContent',
|
||||
'moduleSettings',
|
||||
'status'
|
||||
];
|
||||
protected $casts = [
|
||||
'isHomepage' => 'boolean',
|
||||
'moduleSettings' => 'array'
|
||||
];
|
||||
|
||||
/**
|
||||
* Assign observer for this model for logging
|
||||
*/
|
||||
protected static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
self::observe(ContentObserver::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark relationship with its historical records
|
||||
@@ -52,7 +70,7 @@ class Content extends Model
|
||||
*/
|
||||
public function author()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
return $this->belongsTo(User::class, 'userId');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,4 +92,75 @@ class Content extends Model
|
||||
{
|
||||
return $this->belongsTo(Category::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subpages assigned to page
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function subpages()
|
||||
{
|
||||
return $this->hasMany(Content::class, 'parentId');
|
||||
}
|
||||
|
||||
/**
|
||||
* Parent page
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function parentPage()
|
||||
{
|
||||
return $this->belongsTo(Content::class, 'parentId');
|
||||
}
|
||||
|
||||
/**
|
||||
* Is current content draft?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isDraft()
|
||||
{
|
||||
return $this->status == ContentContract::STATUS_DRAFT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is current content visible for all visitors?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isPublic()
|
||||
{
|
||||
return $this->status == ContentContract::STATUS_PUBLIC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is current content visible only for logged users?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isProtected()
|
||||
{
|
||||
return $this->status == ContentContract::STATUS_PROTECTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is current content visible for logged user OR for everyone?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isVisible()
|
||||
{
|
||||
return $this->isPublic() || $this->isProtected();
|
||||
}
|
||||
|
||||
public function save(array $options = [])
|
||||
{
|
||||
$this->parentId = $this->nullable($this->parentId);
|
||||
$this->categoryId = $this->nullable($this->categoryId);
|
||||
$this->publishedFrom = $this->nullableDate($this->publishedFrom);
|
||||
$this->publishedTo = $this->nullableDate($this->publishedTo);
|
||||
$this->url = Str::slug($this->url);
|
||||
|
||||
return parent::save($options);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,15 +2,25 @@
|
||||
|
||||
namespace App\Models\Content;
|
||||
|
||||
use App\Models\FileManager\File;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ContentHasFile extends Model
|
||||
{
|
||||
public $timestamps = false;
|
||||
public $table = 'contents_has_files';
|
||||
|
||||
protected $fillable = [
|
||||
'content_id',
|
||||
'file_id'
|
||||
];
|
||||
|
||||
public function content()
|
||||
{
|
||||
return $this->hasOne(Content::class);
|
||||
}
|
||||
|
||||
public function file()
|
||||
{
|
||||
return $this->hasOne(File::class);
|
||||
}
|
||||
}
|
||||
@@ -1,215 +1,29 @@
|
||||
<?php
|
||||
namespace App\Models\Content\ModelTraits;
|
||||
|
||||
use App\CMS\Contracts\Repositories\Content as IContent;
|
||||
use App\Http\Requests\Request;
|
||||
use App\Models\Content\ContentHasFile;
|
||||
use App\Models\Content\ContentHistory;
|
||||
use App\Models\FileManager\Directory;
|
||||
use App\Models\FileManager\File;
|
||||
use Illuminate\Support\Facades\App;
|
||||
|
||||
trait Content
|
||||
{
|
||||
/**
|
||||
* @var File
|
||||
*/
|
||||
private $file;
|
||||
protected $foundSubpages = [];
|
||||
protected $subpagesInit = false;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->file = App::make(File::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is current content draft?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isDraft()
|
||||
{
|
||||
return $this->status == IContent::STATUS_DRAFT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is current content visible for all visitors?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isPublic()
|
||||
{
|
||||
return $this->status == IContent::STATUS_PUBLIC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is current content visible only for logged users?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isProtected()
|
||||
{
|
||||
return $this->status == IContent::STATUS_PROTECTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is current content visible for logged user OR for everyone?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isVisible()
|
||||
{
|
||||
return $this->isPublic() || $this->isProtected();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of all subpages
|
||||
*
|
||||
* @param bool $orderBy
|
||||
* @param bool $orderDirection
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function subpages($orderBy = false, $orderDirection = false)
|
||||
{
|
||||
if (!$this->subpagesInit) {
|
||||
$subpages = $this->getPageQuery()
|
||||
->where('contents.parent_id', $this->id);
|
||||
|
||||
if ($orderBy) {
|
||||
$subpages->orderBy($orderBy, $orderDirection ? $orderDirection : 'ASC');
|
||||
}
|
||||
|
||||
$subpages = $subpages->get();
|
||||
|
||||
// convert JSON settings into stdClass
|
||||
foreach ($subpages as $i => $subpage) {
|
||||
$subpages[$i]->module_settings = json_decode($subpage->module_settings);
|
||||
}
|
||||
|
||||
$this->subpagesInit = true;
|
||||
$this->foundSubpages = $subpages;
|
||||
}
|
||||
|
||||
return $this->foundSubpages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of all root pages - those pages, which parent_id is null
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function rootPages()
|
||||
{
|
||||
$rootPages = $this->getPageQuery()
|
||||
->where('parent_id', null);
|
||||
|
||||
if ($this->id) {
|
||||
$rootPages = $rootPages->where('id', '!=', $this->id);
|
||||
}
|
||||
|
||||
return $rootPages->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates current model with information about changed columns
|
||||
*
|
||||
* @param array $fields
|
||||
* @param array $request
|
||||
* @param string $revisionId
|
||||
*
|
||||
* @return array revisionID and number of changed columns
|
||||
*/
|
||||
public function updateWithHistory(array $fields, array $request, $revisionId = null)
|
||||
{
|
||||
if (!$revisionId) {
|
||||
$revisionId = uniqid();
|
||||
}
|
||||
|
||||
$changed = 0;
|
||||
|
||||
foreach ($fields as $fieldDB => $fieldRequest) {
|
||||
// ignore non-existing fields
|
||||
if (!isset($request[$fieldRequest]) && !is_null($request[$fieldRequest])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// if module settings is still JSON, decode it to normal stdClass
|
||||
if (is_string($this->module_settings)) {
|
||||
$this->module_settings = json_decode($this->module_settings);
|
||||
}
|
||||
|
||||
// are we editing common settings, or module-specific settings?
|
||||
if (!in_array($fieldDB, $this->fillable)) {
|
||||
// this field is not part of "core" content - probably it will be module settings
|
||||
$commonField = false;
|
||||
$fieldValue = isset($this->module_settings->$fieldDB) ? $this->module_settings->$fieldDB : null;
|
||||
} else {
|
||||
$commonField = true;
|
||||
$fieldValue = $this->$fieldDB;
|
||||
}
|
||||
|
||||
// remove any whitespaces around real content
|
||||
if (!is_null($request[$fieldRequest])) {
|
||||
$request[$fieldRequest] = trim($request[$fieldRequest]);
|
||||
}
|
||||
|
||||
if (trim($fieldValue) != $request[$fieldRequest]) {
|
||||
|
||||
$this->saveHistory($revisionId, $fieldRequest, $fieldValue, $request);
|
||||
|
||||
// save change into database
|
||||
if ($commonField) {
|
||||
$this->$fieldDB = $request[$fieldRequest];
|
||||
} else {
|
||||
$this->module_settings->$fieldDB = $request[$fieldRequest];
|
||||
}
|
||||
|
||||
$changed++;
|
||||
}
|
||||
}
|
||||
|
||||
// make JSON from stdClass
|
||||
if (!is_string($this->module_settings)) {
|
||||
$this->module_settings = json_encode($this->module_settings);
|
||||
}
|
||||
|
||||
$this->save();
|
||||
|
||||
return [$revisionId, $changed];
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload and set some image as title photo
|
||||
*
|
||||
* @param Request $request
|
||||
*/
|
||||
public function uploadTitlePhoto(Request $request)
|
||||
{
|
||||
if ($request->hasFile('titlePhoto')) {
|
||||
return $this->file->upload($request->file('titlePhoto'), $request);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload and assign files to newly created content page
|
||||
*
|
||||
* @param Request $request
|
||||
* @param null $revisionId
|
||||
* @param $files
|
||||
* @param $assignedFiles
|
||||
* @param null $revisionId
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function uploadRelatedFiles(Request $request, $revisionId = null)
|
||||
public function uploadRelatedFiles($files, $assignedFiles = [], $revisionId = null)
|
||||
{
|
||||
$files = $request->all()['files'];
|
||||
$changed = 0;
|
||||
|
||||
// check if any file was removed
|
||||
if ($revisionId) {
|
||||
$changed += $this->removeRelatedFiles($revisionId, $request);
|
||||
$changed += $this->removeRelatedFiles($revisionId, $assignedFiles);
|
||||
}
|
||||
|
||||
// allow uploading only on created pages
|
||||
@@ -222,13 +36,16 @@ trait Content
|
||||
'name' => '.content_files',
|
||||
'hidden' => true
|
||||
]);
|
||||
$request->directoryId = $directory->id;
|
||||
$data = new \stdClass();
|
||||
$data->directoryId = $directory->id;
|
||||
|
||||
$fileModel = App::make(File::class);
|
||||
|
||||
foreach ($files as $file) {
|
||||
if (!$file) {
|
||||
continue;
|
||||
}
|
||||
$uploaded = $this->file->upload($file, $request);
|
||||
$uploaded = $fileModel->upload($file, $data);
|
||||
|
||||
// add assignement
|
||||
ContentHasFile::create([
|
||||
@@ -250,16 +67,13 @@ trait Content
|
||||
* Delete files from association
|
||||
*
|
||||
* @param $revisionId
|
||||
* @param $request
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function removeRelatedFiles($revisionId, $request)
|
||||
private function removeRelatedFiles($revisionId, $assignedFiles)
|
||||
{
|
||||
$files = array_keys((array)$request->keepAssigned);
|
||||
|
||||
$allFiles = $this->files()
|
||||
->whereNotIn('id', $files)
|
||||
->whereNotIn('id', $assignedFiles)
|
||||
->get();
|
||||
|
||||
foreach ($allFiles as $file) {
|
||||
@@ -273,29 +87,6 @@ trait Content
|
||||
return count($allFiles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save history entry into database
|
||||
*
|
||||
* @param $revisionId
|
||||
* @param $fieldRequest
|
||||
* @param $fieldValue
|
||||
* @param $request
|
||||
*/
|
||||
private function saveHistory($revisionId, $fieldRequest, $fieldValue, $request)
|
||||
{ // setup history object
|
||||
$history = [
|
||||
'user_id' => \Auth::user()->id,
|
||||
'content_id' => $this->id,
|
||||
'edit_batch' => $revisionId,
|
||||
'column' => $fieldRequest,
|
||||
'old_value' => $fieldValue,
|
||||
'new_value' => $request[$fieldRequest]
|
||||
];
|
||||
|
||||
// save history
|
||||
ContentHistory::create($history);
|
||||
}
|
||||
|
||||
public function view()
|
||||
{
|
||||
$this->viewed++;
|
||||
|
||||
@@ -18,7 +18,7 @@ trait ContentHistory
|
||||
public function getStructuredHistoryOf(Content $content)
|
||||
{
|
||||
$data = $content->history()
|
||||
->select('content_history.*', 'contents.module_handler', 'users.email AS user_email', 'users.name AS user_name')
|
||||
->select('content_history.*', 'contents.moduleHandler', 'users.email AS user_email', 'users.name AS user_name')
|
||||
->join('users', 'users.id', '=', 'content_history.user_id')
|
||||
->join('contents', 'contents.id', '=', 'content_history.content_id')
|
||||
->orderBy('changed_at', 'DESC')
|
||||
@@ -61,7 +61,7 @@ trait ContentHistory
|
||||
*/
|
||||
|
||||
// get handler of given content page
|
||||
$handler = $change->module_handler;
|
||||
$handler = $change->moduleHandler;
|
||||
|
||||
return $handler::getHistoryHandler();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user