Files
core/app/Models/Content.php
T

296 lines
8.1 KiB
PHP

<?php
namespace App\Models;
use App\Enumerations\ContentStatuses;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
/**
* Class Content
*/
class Content extends Model
{
public $timestamps = true;
protected $fillable = [
'user_id',
'parent_id',
'module_handler',
'published_from',
'published_to',
'title_photo',
'template',
'is_homepage',
'title',
'url',
'meta_keywords',
'meta_description',
'content',
'module_settings',
'status'
];
protected $guarded = [];
protected $subpages = [];
protected $subpagesInit = false;
const STATUS_DELETED = 'deleted';
const STATUS_DRAFT = 'draft';
const STATUS_PROTECTED = 'protected';
const STATUS_PUBLIC = 'public';
/**
* Getter for query with setup filter for non-deleted and non-draft pages
*/
protected function getPageQuery()
{
return Content::where('status', '!=', Content::STATUS_DELETED)
->where('status', '!=', Content::STATUS_DRAFT);
}
/**
* Getter for homepage content page
* @return Content
*/
public function getHomepage()
{
return $this->getPageQuery()
->where('is_homepage', 1)
->first();
}
/**
* Getter for any page specified by its url.
*
* @param $url
*
* @return Content
*/
public function getByURL($url)
{
return $this->getPageQuery()
->where('url', $url)
->first();
}
/**
* Get list of all subpages
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function subpages()
{
if (!$this->subpagesInit) {
$this->subpages = $this->getPageQuery()
->where('parent_id', $this->id)
->get();
// convert JSON settings into stdClass
foreach ($this->subpages as $subpage) {
$subpage->module_settings = json_decode($subpage->module_settings);
}
$this->subpagesInit = true;
}
return $this->subpages;
}
/**
* Is current content draft?
*
* @return bool
*/
public function isDraft()
{
return $this->status == self::STATUS_DRAFT;
}
/**
* Is current content visible for all visitors?
*
* @return bool
*/
public function isPublic()
{
return $this->status == self::STATUS_PUBLIC;
}
/**
* Is current content visible only for logged users?
*
* @return bool
*/
public function isProtected()
{
return $this->status == self::STATUS_PROTECTED;
}
/**
* Is current content visible for logged user OR for everyone?
*
* @return bool
*/
public function isVisible()
{
return $this->isPublic() || $this->isProtected();
}
/**
* 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();
}
/**
* Getter for overview of all content pages.
* These content pages may be filtered by using some handler
*
* @param bool $handler
* @param bool $status
* @param bool $joinAuthor
*
* @return
*/
public function getOverview($handler = false, $status = false, $joinAuthor = false, $joinParent = false)
{
$query = DB::table('contents')
->select('contents.*', 'modules.name AS module_name')
->where('contents.status', '<>', self::STATUS_DELETED)
->join('modules', 'modules.handler', '=', 'contents.module_handler')
->orderBy('created_at', 'DESC');
// filter results using handler
if ($handler) {
$query = $query->where('module_handler', $handler);
}
// join user email and user name to results when needed
if ($joinAuthor) {
$query = $query->join('users', 'users.id', '=', 'contents.user_id')
->addSelect('users.name AS author_name')
->addSelect('users.email AS author_email');
}
if ($joinParent) {
$query = $query->leftJoin('contents as parent', 'parent.id', '=', 'contents.parent_id')
->addSelect('parent.title AS parent_title')
->addSelect('parent.url AS parent_url');
}
// add filtering by status
if (in_array($status, ContentStatuses::getSimple())) {
$query = $query->where('contents.status', $status);
}
return $query;
}
/**
* Updates current model with information about changed columns
*
* @param array $fields
* @param array $request
* @param string $revisionId
*
* @return int 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]) {
// 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);
// 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];
}
/**
* Mark relationship with its historical records
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function history()
{
return $this->hasMany('App\Models\ContentHistory');
}
/**
* Mark relationship with users table
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function author()
{
return $this->belongsTo('App\Models\User', 'user_id');
}
}