mirror of
https://github.com/godotengine/godot-website.git
synced 2026-01-04 06:09:55 +03:00
288 lines
9.2 KiB
PHP
288 lines
9.2 KiB
PHP
<?php namespace RainLab\Blog\Models;
|
|
|
|
use Str;
|
|
use Model;
|
|
use URL;
|
|
use RainLab\Blog\Models\Post;
|
|
use October\Rain\Router\Helper as RouterHelper;
|
|
use Cms\Classes\Page as CmsPage;
|
|
use Cms\Classes\Theme;
|
|
|
|
class Category extends Model
|
|
{
|
|
use \October\Rain\Database\Traits\Validation;
|
|
use \October\Rain\Database\Traits\NestedTree;
|
|
|
|
public $table = 'rainlab_blog_categories';
|
|
public $implement = ['@RainLab.Translate.Behaviors.TranslatableModel'];
|
|
|
|
/*
|
|
* Validation
|
|
*/
|
|
public $rules = [
|
|
'name' => 'required',
|
|
'slug' => 'required|between:3,64|unique:rainlab_blog_categories',
|
|
'code' => 'unique:rainlab_blog_categories',
|
|
];
|
|
|
|
/**
|
|
* @var array Attributes that support translation, if available.
|
|
*/
|
|
public $translatable = [
|
|
'name',
|
|
'description',
|
|
['slug', 'index' => true]
|
|
];
|
|
|
|
protected $guarded = [];
|
|
|
|
public $belongsToMany = [
|
|
'posts' => ['RainLab\Blog\Models\Post',
|
|
'table' => 'rainlab_blog_posts_categories',
|
|
'order' => 'published_at desc',
|
|
'scope' => 'isPublished'
|
|
]
|
|
];
|
|
|
|
public function beforeValidate()
|
|
{
|
|
// Generate a URL slug for this model
|
|
if (!$this->exists && !$this->slug) {
|
|
$this->slug = Str::slug($this->name);
|
|
}
|
|
}
|
|
|
|
public function afterDelete()
|
|
{
|
|
$this->posts()->detach();
|
|
}
|
|
|
|
public function getPostCountAttribute()
|
|
{
|
|
return $this->posts()->count();
|
|
}
|
|
|
|
/**
|
|
* Sets the "url" attribute with a URL to this object
|
|
* @param string $pageName
|
|
* @param Cms\Classes\Controller $controller
|
|
*/
|
|
public function setUrl($pageName, $controller)
|
|
{
|
|
$params = [
|
|
'id' => $this->id,
|
|
'slug' => $this->slug,
|
|
];
|
|
|
|
return $this->url = $controller->pageUrl($pageName, $params);
|
|
}
|
|
|
|
/**
|
|
* Handler for the pages.menuitem.getTypeInfo event.
|
|
* Returns a menu item type information. The type information is returned as array
|
|
* with the following elements:
|
|
* - references - a list of the item type reference options. The options are returned in the
|
|
* ["key"] => "title" format for options that don't have sub-options, and in the format
|
|
* ["key"] => ["title"=>"Option title", "items"=>[...]] for options that have sub-options. Optional,
|
|
* required only if the menu item type requires references.
|
|
* - nesting - Boolean value indicating whether the item type supports nested items. Optional,
|
|
* false if omitted.
|
|
* - dynamicItems - Boolean value indicating whether the item type could generate new menu items.
|
|
* Optional, false if omitted.
|
|
* - cmsPages - a list of CMS pages (objects of the Cms\Classes\Page class), if the item type requires a CMS page reference to
|
|
* resolve the item URL.
|
|
* @param string $type Specifies the menu item type
|
|
* @return array Returns an array
|
|
*/
|
|
public static function getMenuTypeInfo($type)
|
|
{
|
|
$result = [];
|
|
|
|
if ($type == 'blog-category') {
|
|
$result = [
|
|
'references' => self::listSubCategoryOptions(),
|
|
'nesting' => true,
|
|
'dynamicItems' => true
|
|
];
|
|
}
|
|
|
|
if ($type == 'all-blog-categories') {
|
|
$result = [
|
|
'dynamicItems' => true
|
|
];
|
|
}
|
|
|
|
if ($result) {
|
|
$theme = Theme::getActiveTheme();
|
|
|
|
$pages = CmsPage::listInTheme($theme, true);
|
|
$cmsPages = [];
|
|
foreach ($pages as $page) {
|
|
if (!$page->hasComponent('blogPosts')) {
|
|
continue;
|
|
}
|
|
|
|
/*
|
|
* Component must use a category filter with a routing parameter
|
|
* eg: categoryFilter = "{{ :somevalue }}"
|
|
*/
|
|
$properties = $page->getComponentProperties('blogPosts');
|
|
if (!isset($properties['categoryFilter']) || !preg_match('/{{\s*:/', $properties['categoryFilter'])) {
|
|
continue;
|
|
}
|
|
|
|
$cmsPages[] = $page;
|
|
}
|
|
|
|
$result['cmsPages'] = $cmsPages;
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
protected static function listSubCategoryOptions()
|
|
{
|
|
$category = self::getNested();
|
|
|
|
$iterator = function($categories) use (&$iterator) {
|
|
$result = [];
|
|
|
|
foreach ($categories as $category) {
|
|
if (!$category->children) {
|
|
$result[$category->id] = $category->name;
|
|
}
|
|
else {
|
|
$result[$category->id] = [
|
|
'title' => $category->name,
|
|
'items' => $iterator($category->children)
|
|
];
|
|
}
|
|
}
|
|
|
|
return $result;
|
|
};
|
|
|
|
return $iterator($category);
|
|
}
|
|
|
|
/**
|
|
* Handler for the pages.menuitem.resolveItem event.
|
|
* Returns information about a menu item. The result is an array
|
|
* with the following keys:
|
|
* - url - the menu item URL. Not required for menu item types that return all available records.
|
|
* The URL should be returned relative to the website root and include the subdirectory, if any.
|
|
* Use the URL::to() helper to generate the URLs.
|
|
* - isActive - determines whether the menu item is active. Not required for menu item types that
|
|
* return all available records.
|
|
* - items - an array of arrays with the same keys (url, isActive, items) + the title key.
|
|
* The items array should be added only if the $item's $nesting property value is TRUE.
|
|
* @param \RainLab\Pages\Classes\MenuItem $item Specifies the menu item.
|
|
* @param \Cms\Classes\Theme $theme Specifies the current theme.
|
|
* @param string $url Specifies the current page URL, normalized, in lower case
|
|
* The URL is specified relative to the website root, it includes the subdirectory name, if any.
|
|
* @return mixed Returns an array. Returns null if the item cannot be resolved.
|
|
*/
|
|
public static function resolveMenuItem($item, $url, $theme)
|
|
{
|
|
$result = null;
|
|
|
|
if ($item->type == 'blog-category') {
|
|
if (!$item->reference || !$item->cmsPage) {
|
|
return;
|
|
}
|
|
|
|
$category = self::find($item->reference);
|
|
if (!$category) {
|
|
return;
|
|
}
|
|
|
|
$pageUrl = self::getCategoryPageUrl($item->cmsPage, $category, $theme);
|
|
if (!$pageUrl) {
|
|
return;
|
|
}
|
|
|
|
$pageUrl = URL::to($pageUrl);
|
|
|
|
$result = [];
|
|
$result['url'] = $pageUrl;
|
|
$result['isActive'] = $pageUrl == $url;
|
|
$result['mtime'] = $category->updated_at;
|
|
|
|
if ($item->nesting) {
|
|
$categories = $category->getNested();
|
|
$iterator = function($categories) use (&$iterator, &$item, &$theme, $url) {
|
|
$branch = [];
|
|
|
|
foreach ($categories as $category) {
|
|
|
|
$branchItem = [];
|
|
$branchItem['url'] = self::getCategoryPageUrl($item->cmsPage, $category, $theme);
|
|
$branchItem['isActive'] = $branchItem['url'] == $url;
|
|
$branchItem['title'] = $category->name;
|
|
$branchItem['mtime'] = $category->updated_at;
|
|
|
|
if ($category->children) {
|
|
$branchItem['items'] = $iterator($category->children);
|
|
}
|
|
|
|
$branch[] = $branchItem;
|
|
}
|
|
|
|
return $branch;
|
|
};
|
|
|
|
$result['items'] = $iterator($categories);
|
|
}
|
|
}
|
|
elseif ($item->type == 'all-blog-categories') {
|
|
$result = [
|
|
'items' => []
|
|
];
|
|
|
|
$categories = self::orderBy('name')->get();
|
|
foreach ($categories as $category) {
|
|
$categoryItem = [
|
|
'title' => $category->name,
|
|
'url' => self::getCategoryPageUrl($item->cmsPage, $category, $theme),
|
|
'mtime' => $category->updated_at,
|
|
];
|
|
|
|
$categoryItem['isActive'] = $categoryItem['url'] == $url;
|
|
|
|
$result['items'][] = $categoryItem;
|
|
}
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Returns URL of a category page.
|
|
*/
|
|
protected static function getCategoryPageUrl($pageCode, $category, $theme)
|
|
{
|
|
$page = CmsPage::loadCached($theme, $pageCode);
|
|
if (!$page) {
|
|
return;
|
|
}
|
|
|
|
$properties = $page->getComponentProperties('blogPosts');
|
|
if (!isset($properties['categoryFilter'])) {
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* Extract the routing parameter name from the category filter
|
|
* eg: {{ :someRouteParam }}
|
|
*/
|
|
if (!preg_match('/^\{\{([^\}]+)\}\}$/', $properties['categoryFilter'], $matches)) {
|
|
return;
|
|
}
|
|
|
|
$paramName = substr(trim($matches[1]), 1);
|
|
$url = CmsPage::url($page->getBaseFileName(), [$paramName => $category->slug]);
|
|
|
|
return $url;
|
|
}
|
|
}
|