luyadev/luya-module-news

View on GitHub
src/models/Article.php

Summary

Maintainability
A
0 mins
Test Coverage
D
64%
<?php

namespace luya\news\models;

use Yii;
use yii\helpers\Inflector;
use luya\helpers\Url;
use luya\news\admin\Module;
use luya\admin\ngrest\base\NgRestModel;
use luya\admin\traits\SoftDeleteTrait;
use luya\admin\traits\TaggableTrait;
use luya\admin\aws\TaggableActiveWindow;
use luya\admin\behaviors\BlameableBehavior;
use luya\admin\buttons\DuplicateActiveButton;
use luya\admin\models\User;
use luya\news\admin\aws\PreviewActiveWindow;
use luya\web\LinkInterface;
use yii\behaviors\TimestampBehavior;

/**
 * News Article
 *
 * @property integer $id
 * @property string $title
 * @property string $text
 * @property integer $cat_id
 * @property string $image_id
 * @property array $image_list
 * @property array $file_list
 * @property integer $create_user_id
 * @property integer $update_user_id
 * @property integer $timestamp_create
 * @property integer $timestamp_update
 * @property boolean $is_deleted
 * @property boolean $is_online
 * @property boolean $is_archived
 * @property string $teaser_text
 * @property string $detailUrl Return the link to the detail url of a news item.
 * @property string $author
 * @property LinkInterface $link
 * @property string $authorName
 * @property Cat $cat
 * @property User $createUser
 * @property User $updateUser
 * @property string $previewHash
 * 
 * @author Basil Suter <basil@nadar.io>
 * @since 1.0.0
 */
class Article extends NgRestModel
{
    use SoftDeleteTrait;
    use TaggableTrait;
    
    public $i18n = ['title', 'text', 'teaser_text', 'image_list', 'link'];

    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return 'news_article';
    }

    /**
     * {@inheritDoc}
     */
    public function behaviors()
    {
        return [
            [
                'class' => BlameableBehavior::class,
                'createdByAttribute' => 'create_user_id',
                'updatedByAttribute' => 'update_user_id',
            ],
            [
                'class' => TimestampBehavior::class,
                'createdAtAttribute' => false,
                'updatedAtAttribute' => 'timestamp_update'
            ]
        ];
    }

    public function init()
    {
        parent::init();

        $this->on(self::EVENT_BEFORE_INSERT, function() {
            if (empty($this->timestamp_create)) {
                $this->timestamp_create = time();
            }
        });
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['title', 'text'], 'required'],
            [['title', 'text', 'image_list', 'file_list', 'teaser_text', 'author'], 'string'],
            [['cat_id', 'create_user_id', 'update_user_id', 'timestamp_create', 'timestamp_update'], 'integer'],
            [['cat_id'], 'exist', 'targetClass' => Cat::class, 'targetAttribute' => 'id'],
            [['is_deleted', 'is_online', 'is_archived'], 'boolean'],
            [['image_id', 'link'], 'safe'],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'title' => Module::t('article_title'),
            'text' => Module::t('article_text'),
            'teaser_text' => Module::t('teaser_text'),
            'cat_id' => Module::t('article_cat_id'),
            'image_id' => Module::t('article_image_id'),
            'timestamp_create' => Module::t('article_timestamp_create'),
            'is_online' => Module::t('article_is_online'),
            'image_list' => Module::t('article_image_list'),
            'file_list' => Module::t('article_file_list'),
            'author' => Module::t('article_author'),
            'link' => Module::t('article_link'),
            'is_archived' => Module::t('article_is_archived'),
        ];
    }
    
    /**
     * @inheritdoc
     */
    public function ngRestAttributeTypes()
    {
        return [
            'title' => 'text',
            'teaser_text' => ['textarea', 'markdown' => true],
            'text' => ['textarea', 'markdown' => true],
            'image_id' => 'image',
            'is_online'  => ['toggleStatus', 'scheduling' => true],
            'is_archived' => ['toggleStatus', 'scheduling' => true],
            'timestamp_create' => 'datetime',
            'is_display_limit' => 'toggleStatus',
            'image_list' => 'imageArray',
            'file_list' => 'fileArray',
            'cat_id' => ['selectModel', 'modelClass' => Cat::class, 'valueField' => 'id', 'labelField' => 'title'],
            'author' => 'text',
            'link' => 'link',
        ];
    }

    /**
     *
     * @return string
     */
    public function getDetailUrl()
    {
        return Url::toRoute(['/news/default/detail', 'id' => $this->id, 'title' => Inflector::slug($this->title)]);
    }

    /**
     * Get image object.
     *
     * @return \luya\admin\image\Item|boolean
     */
    public function getImage()
    {
        return Yii::$app->storage->getImage($this->image_id);
    }
    
    /**
     * @inheritdoc
     */
    public static function ngRestApiEndpoint()
    {
        return 'api-news-article';
    }
    
    /**
     * @inheritdoc
     */
    public function ngRestAttributeGroups()
    {
        return [
            [['timestamp_create', 'is_online', 'is_archived'], 'Time', 'collapsed'],
            [['image_id', 'image_list', 'file_list'], 'Media'],
        ];
    }
    
    /**
     * @inheritdoc
     */
    public function ngRestScopes()
    {
        return [
            [['list'], ['cat_id', 'title', 'timestamp_create', 'is_online', 'image_id']],
            [['create', 'update'], ['cat_id', 'title', 'teaser_text', 'text', 'author', 'link', 'timestamp_create', 'is_online', 'is_archived', 'image_id', 'image_list', 'file_list']],
            [['delete'], true],
        ];
    }
    
    /**
     * @inheritdoc
     */
    public function ngRestActiveWindows()
    {
        $buttons = [
            [
                'class' => TaggableActiveWindow::class,
            ],
        ];

        if (Module::getInstance()->previewButton) {
            $buttons[] = [
                'class' => PreviewActiveWindow::class,
            ];
        }

        return $buttons;
    }

    /**
     * {@inheritDoc}
     */
    public function ngRestActiveButtons()
    {
        return [
            [
                'class' => DuplicateActiveButton::class,
            ],
        ];
    }

    /**
     * Returns only available News items.
     * 
     * @param false|int $limit
     * @return Article
     */
    public static function getAvailableNews($limit = false)
    {
        $q = self::find()
            ->andWhere(['is_online' => true, 'is_archived' => false])
            ->orderBy('timestamp_create DESC');
        
        if ($limit) {
            $q->limit($limit);
        }
        
        $articles = $q->all();

        return $articles;
    }

    /**
     * @return Cat
     */
    public function getCat()
    {
        return $this->hasOne(Cat::class, ['id' => 'cat_id']);
    }
    
    /**
     * Returns the Category name
     *
     * @return string
     * @deprecated Since version 2.0 will be removed in 3.0
     */
    public function getCategoryName()
    {
        return $this->cat->title;
    }

    /**
     * Created User Relation
     *
     * @return User
     * @since 3.0
     */
    public function getCreateUser()
    {
        return $this->hasOne(User::class, ['id' => 'create_user_id']);
    }

    /**
     * Updated user Relation
     *
     * @return User
     * @since 3.0
     */
    public function getUpdateUser()
    {
        return $this->hasOne(User::class, ['id' => 'update_user_id']);
    }

    /**
     * Returns the Author Name.
     * 
     * If an author name is defined, the author is returned, otherwise the first name and last name
     * of the person which has created the article will be returned.
     *
     * @return string
     * @since 3.0
     */
    public function getAuthorName()
    {
        return $this->author ? $this->author : $this->createUser->firstname . ' ' . $this->createUser->lastname;
    }

    /**
     * Generate A preview hash with most static values
     *
     * @return string
     * @since 3.1.0
     */
    public function getPreviewHash()
    {
        return md5($this->timestamp_create . $this->create_user_id . $this->id);
    }
}