draft knowledgebase incl. l11n with demo

This commit is contained in:
Dennis Eichhorn 2020-11-04 20:43:15 +01:00
parent cf8b79f287
commit 6091928f22
11 changed files with 539 additions and 74 deletions

View File

@ -27,16 +27,6 @@
"primary": true, "primary": true,
"autoincrement": true "autoincrement": true
}, },
"wiki_category_name": {
"name": "wiki_category_name",
"type": "VARCHAR(255)",
"null": false
},
"wiki_category_path": {
"name": "wiki_category_path",
"type": "VARCHAR(255)",
"null": false
},
"wiki_category_parent": { "wiki_category_parent": {
"name": "wiki_category_parent", "name": "wiki_category_parent",
"type": "INT", "type": "INT",
@ -55,6 +45,38 @@
} }
} }
}, },
"wiki_category_l11n": {
"name": "wiki_category_l11n",
"fields": {
"wiki_category_l11n_id": {
"name": "wiki_category_l11n_id",
"type": "INT",
"null": false,
"primary": true,
"autoincrement": true
},
"wiki_category_l11n_name": {
"name": "wiki_category_l11n_name",
"type": "VARCHAR(255)",
"null": false
},
"wiki_category_l11n_category": {
"name": "wiki_category_l11n_category",
"type": "INT",
"null": false,
"foreignTable": "wiki_category",
"foreignKey": "wiki_category_id"
},
"wiki_category_l11n_language": {
"name": "wiki_category_l11n_language",
"type": "VARCHAR(2)",
"default": null,
"null": true,
"foreignTable": "language",
"foreignKey": "language_639_1"
}
}
},
"wiki_article": { "wiki_article": {
"name": "wiki_article", "name": "wiki_article",
"fields": { "fields": {
@ -85,6 +107,11 @@
"type": "TEXT", "type": "TEXT",
"null": false "null": false
}, },
"wiki_article_docraw": {
"name": "wiki_article_docraw",
"type": "TEXT",
"null": false
},
"wiki_article_category": { "wiki_article_category": {
"name": "wiki_article_category", "name": "wiki_article_category",
"type": "INT", "type": "INT",

View File

@ -50,7 +50,6 @@ final class Installer extends InstallerAbstract
$category = new WikiCategory(); $category = new WikiCategory();
$category->setApp(new NullWikiApp($id)); $category->setApp(new NullWikiApp($id));
$category->setName('Default'); $category->setName('Default');
$category->setPath('/');
WikiCategoryMapper::create($category); WikiCategoryMapper::create($category);
@ -65,7 +64,6 @@ final class Installer extends InstallerAbstract
$category = new WikiCategory(); $category = new WikiCategory();
$category->setApp(new NullWikiApp($id)); $category->setApp(new NullWikiApp($id));
$category->setName('Default'); $category->setName('Default');
$category->setPath('/');
} }
} }
} }

View File

@ -30,6 +30,10 @@ use phpOMS\Message\RequestAbstract;
use phpOMS\Message\ResponseAbstract; use phpOMS\Message\ResponseAbstract;
use phpOMS\Model\Message\FormValidation; use phpOMS\Model\Message\FormValidation;
use phpOMS\Utils\Parser\Markdown\Markdown; use phpOMS\Utils\Parser\Markdown\Markdown;
use Modules\Knowledgebase\Models\WikiCategoryL11n;
use phpOMS\Message\Http\HttpRequest;
use Modules\Knowledgebase\Models\WikiCategoryL11nMapper;
use Modules\Knowledgebase\Models\NullWikiApp;
/** /**
* Knowledgebase class. * Knowledgebase class.
@ -92,6 +96,7 @@ final class ApiController extends Controller
$doc->setCategory(new NullWikiCategory((int) ($request->getData('category') ?? 1))); $doc->setCategory(new NullWikiCategory((int) ($request->getData('category') ?? 1)));
$doc->setLanguage((string) ($request->getData('language') ?? $request->getHeader()->getL11n()->getLanguage())); $doc->setLanguage((string) ($request->getData('language') ?? $request->getHeader()->getL11n()->getLanguage()));
$doc->setStatus((int) ($request->getData('status') ?? WikiStatus::INACTIVE)); $doc->setStatus((int) ($request->getData('status') ?? WikiStatus::INACTIVE));
$doc->setApp(new NullWikiApp((int) ($request->getData('app') ?? 1)));
if (!empty($tags = $request->getDataJson('tags'))) { if (!empty($tags = $request->getDataJson('tags'))) {
foreach ($tags as $tag) { foreach ($tags as $tag) {
@ -137,6 +142,76 @@ final class ApiController extends Controller
return []; return [];
} }
/**
* Validate tag l11n create request
*
* @param RequestAbstract $request Request
*
* @return array<string, bool>
*
* @since 1.0.0
*/
private function validateWikiCategoryL11nCreate(RequestAbstract $request) : array
{
$val = [];
if (($val['name'] = empty($request->getData('name')))
|| ($val['tag'] = empty($request->getData('tag')))
) {
return $val;
}
return [];
}
/**
* Api method to create tag localization
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param mixed $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiWikiCategoryL11nCreate(RequestAbstract $request, ResponseAbstract $response, $data = null) : void
{
if (!empty($val = $this->validateWikiCategoryL11nCreate($request))) {
$response->set('wiki_category_l11n_create', new FormValidation($val));
$response->getHeader()->setStatusCode(RequestStatusCode::R_400);
return;
}
$l11nWikiCategory = $this->createWikiCategoryL11nFromRequest($request);
$this->createModel($request->getHeader()->getAccount(), $l11nWikiCategory, WikiCategoryL11nMapper::class, 'wiki_category_l11n', $request->getOrigin());
$this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Localization', 'Category localization successfully created', $l11nWikiCategory);
}
/**
* Method to create tag localization from request.
*
* @param RequestAbstract $request Request
*
* @return WikiCategoryL11n
*
* @since 1.0.0
*/
private function createWikiCategoryL11nFromRequest(RequestAbstract $request) : WikiCategoryL11n
{
$l11nWikiCategory = new WikiCategoryL11n();
$l11nWikiCategory->setCategory((int) ($request->getData('category') ?? 0));
$l11nWikiCategory->setLanguage((string) (
$request->getData('language') ?? $request->getHeader()->getL11n()->getLanguage()
));
$l11nWikiCategory->setName((string) ($request->getData('name') ?? ''));
return $l11nWikiCategory;
}
/** /**
* Api method to get a doc * Api method to get a doc
* *
@ -238,6 +313,17 @@ final class ApiController extends Controller
$category = $this->createWikiCategoryFromRequest($request); $category = $this->createWikiCategoryFromRequest($request);
$this->createModel($request->getHeader()->getAccount(), $category, WikiCategoryMapper::class, 'category', $request->getOrigin()); $this->createModel($request->getHeader()->getAccount(), $category, WikiCategoryMapper::class, 'category', $request->getOrigin());
$l11nRequest = new HttpRequest($request->getUri());
$l11nRequest->setData('category', $category->getId());
$l11nRequest->setData('name', $request->getData('name'));
$l11nRequest->setData('language', $request->getData('language'));
$l11nWikiCategory = $this->createWikiCategoryL11nFromRequest($l11nRequest);
$this->createModel($request->getHeader()->getAccount(), $l11nWikiCategory, WikiCategoryL11nMapper::class, 'tag_l11n', $request->getOrigin());
$category->setName($l11nWikiCategory);
$this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Category', 'Category successfully created.', $category); $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Category', 'Category successfully created.', $category);
} }
@ -253,11 +339,7 @@ final class ApiController extends Controller
public function createWikiCategoryFromRequest(RequestAbstract $request) : WikiCategory public function createWikiCategoryFromRequest(RequestAbstract $request) : WikiCategory
{ {
$category = new WikiCategory(); $category = new WikiCategory();
$category->setName((string) $request->getData('title')); $category->setApp(new NullWikiApp((int) ($request->getData('app') ?? 1)));
if ($request->getData('path') !== null) {
$category->setPath((string) $request->getData('path'));
}
if ($request->getData('parent') !== null) { if ($request->getData('parent') !== null) {
$category->setParent(new NullWikiCategory((int) $request->getData('parent'))); $category->setParent(new NullWikiCategory((int) $request->getData('parent')));
@ -278,7 +360,7 @@ final class ApiController extends Controller
private function validateWikiCategoryCreate(RequestAbstract $request) : array private function validateWikiCategoryCreate(RequestAbstract $request) : array
{ {
$val = []; $val = [];
if (($val['title'] = empty($request->getData('title')))) { if (($val['name'] = empty($request->getData('name')))) {
return $val; return $val;
} }
@ -337,7 +419,6 @@ final class ApiController extends Controller
private function updateCategoryFromRequest(RequestAbstract $request) : WikiCategory private function updateCategoryFromRequest(RequestAbstract $request) : WikiCategory
{ {
$category = WikiCategoryMapper::get((int) $request->getData('id')); $category = WikiCategoryMapper::get((int) $request->getData('id'));
$category->setName((string) ($request->getData('title') ?? $category->getName()));
return $category; return $category;
} }

View File

@ -77,15 +77,20 @@ final class BackendController extends Controller
{ {
$view = new View($this->app->l11nManager, $request, $response); $view = new View($this->app->l11nManager, $request, $response);
$app = (int) ($request->getData('app') ?? $this->app->orgId);
$view->setTemplate('/Modules/Knowledgebase/Theme/Backend/wiki-dashboard'); $view->setTemplate('/Modules/Knowledgebase/Theme/Backend/wiki-dashboard');
$view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1005901001, $request, $response)); $view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1005901001, $request, $response));
$categories = WikiCategoryMapper::getAll(); $categories = WikiCategoryMapper::withConditional('language', $response->getHeader()->getL11n()->getLanguage())::getByParentAndApp($request->hasData('category') ? (int) $request->getData('category') : null, $app, 2);
$view->setData('categories', $categories); $view->setData('categories', $categories);
$documents = WikiDocMapper::withConditional('language', $response->getHeader()->getL11n()->getLanguage())::getNewest(50); $documents = WikiDocMapper::withConditional('language', $response->getHeader()->getL11n()->getLanguage())::getNewestByApp($app, 10);
$view->setData('docs', $documents); $view->setData('docs', $documents);
$apps = WikiAppMapper::getAll();
$view->setData('apps', $apps);
return $view; return $view;
} }
@ -178,10 +183,12 @@ final class BackendController extends Controller
{ {
$view = new View($this->app->l11nManager, $request, $response); $view = new View($this->app->l11nManager, $request, $response);
$app = (int) ($request->getData('app') ?? $this->app->orgId);
$view->setTemplate('/Modules/Knowledgebase/Theme/Backend/wiki-category-list'); $view->setTemplate('/Modules/Knowledgebase/Theme/Backend/wiki-category-list');
$view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1005901001, $request, $response)); $view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1005901001, $request, $response));
$list = WikiCategoryMapper::getAll(); $list = WikiCategoryMapper::getByApp($app, 2);
$view->setData('categories', $list); $view->setData('categories', $list);
return $view; return $view;
@ -276,11 +283,14 @@ final class BackendController extends Controller
{ {
$view = new View($this->app->l11nManager, $request, $response); $view = new View($this->app->l11nManager, $request, $response);
$category = WikiDocMapper::get((int) $request->getData('id')); $app = (int) ($request->getData('app') ?? $this->app->orgId);
$lang = $response->getHeader()->getL11n()->getLanguage();
$document = WikiDocMapper::withConditional('language', $lang)::get((int) $request->getData('id'));
$accountId = $request->getHeader()->getAccount(); $accountId = $request->getHeader()->getAccount();
if (!$this->app->accountManager->get($accountId)->hasPermission( if (!$this->app->accountManager->get($accountId)->hasPermission(
PermissionType::READ, $this->app->orgId, $this->app->appName, self::MODULE_NAME, PermissionState::WIKI, $category->getId()) PermissionType::READ, $this->app->orgId, $this->app->appName, self::MODULE_NAME, PermissionState::WIKI, $document->getId())
) { ) {
$view->setTemplate('/Web/Backend/Error/403_inline'); $view->setTemplate('/Web/Backend/Error/403_inline');
$response->getHeader()->setStatusCode(RequestStatusCode::R_403); $response->getHeader()->setStatusCode(RequestStatusCode::R_403);
@ -290,10 +300,8 @@ final class BackendController extends Controller
$view->setTemplate('/Modules/Knowledgebase/Theme/Backend/wiki-doc-single'); $view->setTemplate('/Modules/Knowledgebase/Theme/Backend/wiki-doc-single');
$view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1005901001, $request, $response)); $view->addData('nav', $this->app->moduleManager->get('Navigation')->createNavigationMid(1005901001, $request, $response));
$categories = WikiCategoryMapper::getAll(); $categories = WikiCategoryMapper::withConditional('language', $lang)::getByParentAndApp($request->hasData('category') ? (int) $request->getData('category') : null, $app, 2);
$view->setData('categories', $categories); $view->setData('categories', $categories);
$document = WikiDocMapper::get((int) $request->getData('id'));
$view->setData('document', $document); $view->setData('document', $document);
return $view; return $view;

View File

@ -14,6 +14,8 @@ declare(strict_types=1);
namespace Modules\Knowledgebase\Models; namespace Modules\Knowledgebase\Models;
use phpOMS\Localization\ISO639x1Enum;
/** /**
* Wiki category class. * Wiki category class.
* *
@ -45,18 +47,10 @@ class WikiCategory implements \JsonSerializable
/** /**
* Name. * Name.
* *
* @var string * @var string|WikiCategoryL11n
* @since 1.0.0 * @since 1.0.0
*/ */
private string $name = ''; private $name = '';
/**
* Path.
*
* @var string
* @since 1.0.0
*/
private string $path = '/';
/** /**
* Parent category. * Parent category.
@ -123,47 +117,29 @@ class WikiCategory implements \JsonSerializable
*/ */
public function getName() : string public function getName() : string
{ {
return $this->name; return $this->name instanceof WikiCategoryL11n ? $this->name->getName() : $this->name;
} }
/** /**
* Set name * Set name
* *
* @param string $name Name * @param string|TagL11n $name Tag article name
* *
* @return void * @return void
* *
* @since 1.0.0 * @since 1.0.0
*/ */
public function setName(string $name) : void public function setName($name, string $lang = ISO639x1Enum::_EN) : void
{ {
$this->name = $name; if ($name instanceof WikiCategoryL11n) {
} $this->name = $name;
} elseif ($this->name instanceof WikiCategoryL11n && \is_string($name)) {
/** $this->name->setName($name);
* Get path } elseif (\is_string($name)) {
* $this->name = new WikiCategoryL11n();
* @return string $this->name->setName($name);
* $this->name->setLanguage($lang);
* @since 1.0.0 }
*/
public function getPath() : string
{
return $this->path;
}
/**
* Set path
*
* @param string $path Path
*
* @return void
*
* @since 1.0.0
*/
public function setPath(string $path) : void
{
$this->path = $path;
} }
/** /**
@ -201,7 +177,6 @@ class WikiCategory implements \JsonSerializable
'id' => $this->id, 'id' => $this->id,
'app' => $this->app, 'app' => $this->app,
'name' => $this->name, 'name' => $this->name,
'path' => $this->path,
]; ];
} }

185
Models/WikiCategoryL11n.php Normal file
View File

@ -0,0 +1,185 @@
<?php
/**
* Orange Management
*
* PHP Version 7.4
*
* @package Modules\Knowledgebase\Models
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace Modules\Knowledgebase\Models;
use phpOMS\Contract\ArrayableInterface;
use phpOMS\Localization\ISO639x1Enum;
/**
* Category class.
*
* @package Modules\Knowledgebase\Models
* @license OMS License 1.0
* @link https://orange-management.org
* @since 1.0.0
*/
class WikiCategoryL11n implements \JsonSerializable, ArrayableInterface
{
/**
* Article ID.
*
* @var int
* @since 1.0.0
*/
protected int $id = 0;
/**
* Category ID.
*
* @var int
* @since 1.0.0
*/
protected int $category = 0;
/**
* Language.
*
* @var string
* @since 1.0.0
*/
protected string $language = ISO639x1Enum::_EN;
/**
* Name.
*
* @var string
* @since 1.0.0
*/
private string $name = '';
/**
* Constructor.
*
* @param string $name Name
*
* @since 1.0.0
*/
public function __construct(string $name = '', string $language = ISO639x1Enum::_EN)
{
$this->name = $name;
$this->language = $language;
}
/**
* Get id
*
* @return int
*
* @since 1.0.0
*/
public function getId() : int
{
return $this->id;
}
/**
* Set category.
*
* @param int $category Category id
*
* @return void
*
* @since 1.0.0
*/
public function setCategory(int $category) : void
{
$this->category = $category;
}
/**
* Get category
*
* @return int
*
* @since 1.0.0
*/
public function getCategory() : int
{
return $this->category;
}
/**
* Get language
*
* @return string
*
* @since 1.0.0
*/
public function getLanguage() : string
{
return $this->language;
}
/**
* Set language
*
* @param string $language Language
*
* @return void
*
* @since 1.0.0
*/
public function setLanguage(string $language) : void
{
$this->language = $language;
}
/**
* Get category name.
*
* @return string
*
* @since 1.0.0
*/
public function getName() : string
{
return $this->name;
}
/**
* Set name
*
* @param string $name Name
*
* @return void
*
* @since 1.0.0
*/
public function setName(string $name) : void
{
$this->name = $name;
}
/**
* {@inheritdoc}
*/
public function toArray() : array
{
return [
'id' => $this->id,
'name' => $this->name,
'category' => $this->category,
'language' => $this->language,
];
}
/**
* {@inheritdoc}
*/
public function jsonSerialize()
{
return $this->toArray();
}
}

View File

@ -0,0 +1,76 @@
<?php
/**
* Orange Management
*
* PHP Version 7.4
*
* @package Modules\Knowledgebase\Models
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace Modules\Knowledgebase\Models;
use phpOMS\DataStorage\Database\DataMapperAbstract;
use phpOMS\Localization\Defaults\LanguageMapper;
/**
* Category mapper class.
*
* @package Modules\Knowledgebase\Models
* @license OMS License 1.0
* @link https://orange-management.org
* @since 1.0.0
*
* @todo Do I really want to create a relation to the language mapper? It's not really needed right?
*/
final class WikiCategoryL11nMapper extends DataMapperAbstract
{
/**
* Columns.
*
* @var array<string, array{name:string, type:string, internal:string, autocomplete?:bool, readonly?:bool, writeonly?:bool, annotations?:array}>
* @since 1.0.0
*/
protected static array $columns = [
'wiki_category_l11n_id' => ['name' => 'wiki_category_l11n_id', 'type' => 'int', 'internal' => 'id'],
'wiki_category_l11n_name' => ['name' => 'wiki_category_l11n_name', 'type' => 'string', 'internal' => 'name', 'autocomplete' => true],
'wiki_category_l11n_category' => ['name' => 'wiki_category_l11n_category', 'type' => 'int', 'internal' => 'category'],
'wiki_category_l11n_language' => ['name' => 'wiki_category_l11n_language', 'type' => 'string', 'internal' => 'language'],
];
/**
* Has one relation.
*
* @var array<string, array{mapper:string, external:string, by?:string, column?:string, conditional?:bool}>
* @since 1.0.0
*/
protected static array $ownsOne = [
'language' => [
'mapper' => LanguageMapper::class,
'external' => 'wiki_category_l11n_language',
'by' => 'code2',
'column' => 'code2',
'conditional' => true,
],
];
/**
* Primary table.
*
* @var string
* @since 1.0.0
*/
protected static string $table = 'wiki_category_l11n';
/**
* Primary field name.
*
* @var string
* @since 1.0.0
*/
protected static string $primaryField = 'wiki_category_l11n_id';
}

View File

@ -15,6 +15,7 @@ declare(strict_types=1);
namespace Modules\Knowledgebase\Models; namespace Modules\Knowledgebase\Models;
use phpOMS\DataStorage\Database\DataMapperAbstract; use phpOMS\DataStorage\Database\DataMapperAbstract;
use phpOMS\DataStorage\Database\RelationType;
/** /**
* Mapper class. * Mapper class.
@ -35,11 +36,26 @@ final class WikiCategoryMapper extends DataMapperAbstract
protected static array $columns = [ protected static array $columns = [
'wiki_category_id' => ['name' => 'wiki_category_id', 'type' => 'int', 'internal' => 'id'], 'wiki_category_id' => ['name' => 'wiki_category_id', 'type' => 'int', 'internal' => 'id'],
'wiki_category_app' => ['name' => 'wiki_category_app', 'type' => 'int', 'internal' => 'app'], 'wiki_category_app' => ['name' => 'wiki_category_app', 'type' => 'int', 'internal' => 'app'],
'wiki_category_name' => ['name' => 'wiki_category_name', 'type' => 'string', 'internal' => 'name'],
'wiki_category_path' => ['name' => 'wiki_category_path', 'type' => 'string', 'internal' => 'path'],
'wiki_category_parent' => ['name' => 'wiki_category_parent', 'type' => 'int', 'internal' => 'parent'], 'wiki_category_parent' => ['name' => 'wiki_category_parent', 'type' => 'int', 'internal' => 'parent'],
]; ];
/**
* Has many relation.
*
* @var array<string, array{mapper:string, table:string, self?:?string, external?:?string, column?:string}>
* @since 1.0.0
*/
protected static array $hasMany = [
'name' => [
'mapper' => WikiCategoryL11nMapper::class,
'table' => 'wiki_category_l11n',
'self' => 'wiki_category_l11n_category',
'column' => 'name',
'conditional' => true,
'external' => null,
],
];
/** /**
* Has owns one relation. * Has owns one relation.
* *
@ -72,4 +88,50 @@ final class WikiCategoryMapper extends DataMapperAbstract
* @since 1.0.0 * @since 1.0.0
*/ */
protected static string $primaryField = 'wiki_category_id'; protected static string $primaryField = 'wiki_category_id';
/**
* Parent field name.
*
* @var string
* @since 1.0.0
*/
protected static string $parent = 'wiki_category_parent';
/**
* Get by parent.
*
* @param mixed $value Parent value id
* @param int $app App
* @param int $depth Relation depth
*
* @return array
*
* @since 1.0.0
*/
public static function getByParentAndApp($value, int $app = 1, int $depth = 3) : array
{
$query = self::getQuery();
$query->where(static::$table . '_' . $depth . '.' . static::$parent, '=', $value)
->andWhere(static::$table . '_' . $depth . '.wiki_category_app', '=', $app);
return self::getAllByQuery($query, RelationType::ALL, $depth);
}
/**
* Get by app.
*
* @param int $app App
* @param int $depth Relation depth
*
* @return array
*
* @since 1.0.0
*/
public static function getByApp(int $app, int $depth = 3) : array
{
$query = self::getQuery();
$query->where(static::$table . '_' . $depth . '.wiki_category_app', '=', $app);
return self::getAllByQuery($query, RelationType::ALL, $depth);
}
} }

View File

@ -16,6 +16,8 @@ namespace Modules\Knowledgebase\Models;
use Modules\Tag\Models\TagMapper; use Modules\Tag\Models\TagMapper;
use phpOMS\DataStorage\Database\DataMapperAbstract; use phpOMS\DataStorage\Database\DataMapperAbstract;
use phpOMS\DataStorage\Database\RelationType;
use phpOMS\DataStorage\Database\Query\Builder;
/** /**
* Mapper class. * Mapper class.
@ -39,6 +41,7 @@ final class WikiDocMapper extends DataMapperAbstract
'wiki_article_title' => ['name' => 'wiki_article_title', 'type' => 'string', 'internal' => 'name'], 'wiki_article_title' => ['name' => 'wiki_article_title', 'type' => 'string', 'internal' => 'name'],
'wiki_article_language' => ['name' => 'wiki_article_language', 'type' => 'string', 'internal' => 'language'], 'wiki_article_language' => ['name' => 'wiki_article_language', 'type' => 'string', 'internal' => 'language'],
'wiki_article_doc' => ['name' => 'wiki_article_doc', 'type' => 'string', 'internal' => 'doc'], 'wiki_article_doc' => ['name' => 'wiki_article_doc', 'type' => 'string', 'internal' => 'doc'],
'wiki_article_docraw' => ['name' => 'wiki_article_docraw', 'type' => 'string', 'internal' => 'docRaw'],
'wiki_article_status' => ['name' => 'wiki_article_status', 'type' => 'int', 'internal' => 'status'], 'wiki_article_status' => ['name' => 'wiki_article_status', 'type' => 'int', 'internal' => 'status'],
'wiki_article_category' => ['name' => 'wiki_article_category', 'type' => 'int', 'internal' => 'category'], 'wiki_article_category' => ['name' => 'wiki_article_category', 'type' => 'int', 'internal' => 'category'],
]; ];
@ -90,4 +93,35 @@ final class WikiDocMapper extends DataMapperAbstract
* @since 1.0.0 * @since 1.0.0
*/ */
protected static string $primaryField = 'wiki_article_id'; protected static string $primaryField = 'wiki_article_id';
/**
* Get newest.
*
* This will fall back to the insert id if no datetime column is present.
*
* @param int $app App
* @param int $limit Newest limit
* @param Builder $query Pre-defined query
* @param int $relations Load relations
* @param int $depth Relation depth
*
* @return array
*
* @since 1.0.0
*/
public static function getNewestByApp(int $app, int $limit = 1, Builder $query = null, int $relations = RelationType::ALL, int $depth = 3) : array
{
$query ??= self::getQuery(null, [], $relations, $depth);
$query->where(static::$table . '_' . $depth . '.' . 'wiki_article_app', '=', $app)
->limit($limit);
if (!empty(static::$createdAt)) {
$query->orderBy(static::$table . '_' . $depth . '.' . static::$columns[static::$createdAt]['name'], 'DESC');
} else {
$query->orderBy(static::$table . '_' . $depth . '.' . static::$columns[static::$primaryField]['name'], 'DESC');
}
return self::getAllByQuery($query, $relations, $depth);
}
} }

View File

@ -13,6 +13,7 @@
declare(strict_types=1); declare(strict_types=1);
use \phpOMS\Uri\UriFactory; use \phpOMS\Uri\UriFactory;
use phpOMS\Utils\Parser\Markdown\Markdown;
/** @var \phpOMS\Views\View $this */ /** @var \phpOMS\Views\View $this */
/** @var \Modules\Knowledgebase\Models\WikiCategory[] $categories */ /** @var \Modules\Knowledgebase\Models\WikiCategory[] $categories */
@ -21,6 +22,9 @@ $categories = $this->getData('categories') ?? [];
/** @var \Modules\Knowledgebase\Models\WikiDoc[] $documents */ /** @var \Modules\Knowledgebase\Models\WikiDoc[] $documents */
$documents = $this->getData('docs') ?? []; $documents = $this->getData('docs') ?? [];
/** @var \Modules\Knowledgebase\Models\WikiApp[] $apps */
$apps = $this->getData('apps') ?? [];
echo $this->getData('nav')->render(); ?> echo $this->getData('nav')->render(); ?>
<div class="row"> <div class="row">
<div class="col-xs-12 col-md-8 col-lg-9"> <div class="col-xs-12 col-md-8 col-lg-9">
@ -31,7 +35,7 @@ echo $this->getData('nav')->render(); ?>
<div class="portlet-head"><a href="<?= $url; ?>"><?= $this->printHtml($doc->getName()); ?></a></div> <div class="portlet-head"><a href="<?= $url; ?>"><?= $this->printHtml($doc->getName()); ?></a></div>
<div class="portlet-body"> <div class="portlet-body">
<article> <article>
<?= \substr($doc->getDoc(), 0, 300) . (\strlen($doc->getDoc()) > 300 ? '...' : ''); ?> <?= Markdown::parse(\substr($doc->getDocRaw(), 0, 500)); ?>
</article> </article>
</div> </div>
<div class="portlet-foot"> <div class="portlet-foot">
@ -49,8 +53,22 @@ echo $this->getData('nav')->render(); ?>
</div> </div>
<div class="col-xs-12 col-md-4 col-lg-3"> <div class="col-xs-12 col-md-4 col-lg-3">
<section class="box wf-100"> <section class="portlet">
<div class="inner"> <div class="portlet-head">App</div>
<div class="portlet-body">
<form>
<select>
<?php foreach ($apps as $app) : ?>
<option><?= $this->printHtml($app->getName()); ?>
<?php endforeach; ?>
</select>
</form>
</div>
</section>
<section class="portlet">
<div class="portlet-head">Categories</div>
<div class="portlet-body">
<ul> <ul>
<?php foreach ($categories as $category) : ?> <?php foreach ($categories as $category) : ?>
<li><a href="<?= UriFactory::build('{/prefix}wiki/doc/list?{?}&id=' . $category->getId()); ?>"><?= $this->printHtml($category->getName()); ?></a> <li><a href="<?= UriFactory::build('{/prefix}wiki/doc/list?{?}&id=' . $category->getId()); ?>"><?= $this->printHtml($category->getName()); ?></a>

View File

@ -62,7 +62,8 @@ echo $this->getData('nav')->render();
<div class="col-xs-12 col-md-4 col-lg-3"> <div class="col-xs-12 col-md-4 col-lg-3">
<section class="portlet"> <section class="portlet">
<div class="inner"> <div class="portlet-head">Categories</div>
<div class="portlet-body">
<ul> <ul>
<?php foreach ($categories as $category) : ?> <?php foreach ($categories as $category) : ?>
<li><a href="<?= UriFactory::build('{/prefix}wiki/doc/list?{?}&id=' . $category->getId()); ?>"><?= $this->printHtml($category->getName()); ?></a> <li><a href="<?= UriFactory::build('{/prefix}wiki/doc/list?{?}&id=' . $category->getId()); ?>"><?= $this->printHtml($category->getName()); ?></a>