aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/application.php10
-rw-r--r--core/functions.php109
-rw-r--r--core/include/feed/main.php59
-rw-r--r--core/include/home.php31
-rw-r--r--core/include/page/list.php35
-rw-r--r--core/include/page/main.php113
-rw-r--r--core/include/post/list.php35
-rw-r--r--core/include/post/main.php113
-rw-r--r--core/include/search/main.php36
-rw-r--r--core/include/user/list.php30
-rw-r--r--core/include/user/main.php116
-rw-r--r--core/namespace/Application.php24
-rw-r--r--core/namespace/Attribute.php84
-rw-r--r--core/namespace/Entity.php47
-rw-r--r--core/namespace/EntityInterface.php8
-rw-r--r--core/namespace/Item.php98
-rw-r--r--core/namespace/ItemFactory.php23
-rw-r--r--core/namespace/ItemInterface.php4
-rw-r--r--core/namespace/Page/Attribute.php22
-rw-r--r--core/namespace/Page/Entity.php13
-rw-r--r--core/namespace/Page/Exception.php4
-rw-r--r--core/namespace/Page/Factory.php4
-rw-r--r--core/namespace/Page/Item.php20
-rw-r--r--core/namespace/Page/Repository.php17
-rw-r--r--core/namespace/Post/Attribute.php22
-rw-r--r--core/namespace/Post/Entity.php13
-rw-r--r--core/namespace/Post/Exception.php4
-rw-r--r--core/namespace/Post/Factory.php4
-rw-r--r--core/namespace/Post/Item.php27
-rw-r--r--core/namespace/Post/Repository.php17
-rw-r--r--core/namespace/Repository.php323
-rw-r--r--core/namespace/User/Attribute.php24
-rw-r--r--core/namespace/User/Entity.php15
-rw-r--r--core/namespace/User/Exception.php4
-rw-r--r--core/namespace/User/Factory.php8
-rw-r--r--core/namespace/User/Item.php6
-rw-r--r--core/namespace/User/Repository.php7
37 files changed, 822 insertions, 707 deletions
diff --git a/core/application.php b/core/application.php
index a84669f..e4c481f 100644
--- a/core/application.php
+++ b/core/application.php
@@ -164,9 +164,13 @@ if(Application::get('CORE.SEND_304') === TRUE AND !defined('ADMINISTRATION')) {
#===========================================================================
$execute = '(SELECT time_update FROM %s ORDER BY time_update DESC LIMIT 1) AS %s';
- $pageSQL = sprintf($execute, Page\Attribute::TABLE, Page\Attribute::TABLE);
- $postSQL = sprintf($execute, Post\Attribute::TABLE, Post\Attribute::TABLE);
- $userSQL = sprintf($execute, User\Attribute::TABLE, User\Attribute::TABLE);
+ $pageTable = Page\Repository::getTableName();
+ $postTable = Post\Repository::getTableName();
+ $userTable = User\Repository::getTableName();
+
+ $pageSQL = sprintf($execute, $pageTable, $pageTable);
+ $postSQL = sprintf($execute, $postTable, $postTable);
+ $userSQL = sprintf($execute, $postTable, $postTable);
$Statement = $Database->query("SELECT {$pageSQL}, {$postSQL}, {$userSQL}");
diff --git a/core/functions.php b/core/functions.php
index 31a295b..55744f1 100644
--- a/core/functions.php
+++ b/core/functions.php
@@ -1,16 +1,20 @@
<?php
+use Page\Entity as Page;
+use Post\Entity as Post;
+use User\Entity as User;
+use Template\Template as Template;
+use Template\Factory as TemplateFactory;
+
#===============================================================================
# Helper function to reduce duplicate code
#===============================================================================
-function generateNaviTemplate(int $current, $location, $namespace): Template\Template {
- $Database = Application::getDatabase();
- $Attribute = "{$namespace}\\Attribute";
-
- $Statement = $Database->query(sprintf('SELECT COUNT(id) FROM %s', $Attribute::TABLE));
+function generateNaviTemplate(int $current, $location, $namespace): Template {
+ $Repository = Application::getRepository($namespace);
- $lastSite = ceil($Statement->fetchColumn() / Application::get(strtoupper($namespace).'.LIST_SIZE'));
+ $listSize = Application::get(strtoupper($namespace).'.LIST_SIZE');
+ $lastSite = ceil($Repository->getCount() / $listSize);
- $PaginationTemplate = Template\Factory::build('pagination');
+ $PaginationTemplate = TemplateFactory::build('pagination');
$PaginationTemplate->set('THIS', $current);
$PaginationTemplate->set('LAST', $lastSite);
$PaginationTemplate->set('HREF', "{$location}?site=%d");
@@ -21,29 +25,29 @@ function generateNaviTemplate(int $current, $location, $namespace): Template\Tem
#===============================================================================
# Helper function to reduce duplicate code
#===============================================================================
-function generatePageNaviTemplate($current): Template\Template {
+function generatePageNaviTemplate($current): Template {
return generateNaviTemplate($current, Application::getPageURL(), 'Page');
}
#===============================================================================
# Helper function to reduce duplicate code
#===============================================================================
-function generatePostNaviTemplate($current): Template\Template {
+function generatePostNaviTemplate($current): Template {
return generateNaviTemplate($current, Application::getPostURL(), 'Post');
}
#===============================================================================
# Helper function to reduce duplicate code
#===============================================================================
-function generateUserNaviTemplate($current): Template\Template {
+function generateUserNaviTemplate($current): Template {
return generateNaviTemplate($current, Application::getUserURL(), 'User');
}
#===============================================================================
# Helper function to reduce duplicate code
#===============================================================================
-function generatePageItemTemplate(Page\Item $Page, User\Item $User): Template\Template {
- $Template = Template\Factory::build('page/item');
+function generatePageItemTemplate(Page $Page, User $User): Template {
+ $Template = TemplateFactory::build('page/item');
$Template->set('PAGE', generateItemTemplateData($Page));
$Template->set('USER', generateItemTemplateData($User));
@@ -53,8 +57,8 @@ function generatePageItemTemplate(Page\Item $Page, User\Item $User): Template\Te
#===============================================================================
# Helper function to reduce duplicate code
#===============================================================================
-function generatePostItemTemplate(Post\Item $Post, User\Item $User): Template\Template {
- $Template = Template\Factory::build('post/item');
+function generatePostItemTemplate(Post $Post, User $User): Template {
+ $Template = TemplateFactory::build('post/item');
$Template->set('POST', generateItemTemplateData($Post));
$Template->set('USER', generateItemTemplateData($User));
@@ -64,8 +68,8 @@ function generatePostItemTemplate(Post\Item $Post, User\Item $User): Template\Te
#===============================================================================
# Helper function to reduce duplicate code
#===============================================================================
-function generateUserItemTemplate(User\Item $User): Template\Template {
- $Template = Template\Factory::build('user/item');
+function generateUserItemTemplate(User $User): Template {
+ $Template = TemplateFactory::build('user/item');
$Template->set('USER', generateItemTemplateData($User));
return $Template;
@@ -74,16 +78,16 @@ function generateUserItemTemplate(User\Item $User): Template\Template {
#===============================================================================
# Helper function to reduce duplicate code
#===============================================================================
-function generateItemTemplateData(Item $Item): array {
- $ATTR = $Item->getAttribute()->getAll(['password']);
+function generateItemTemplateData(EntityInterface $Entity): array {
+ $ATTR = $Entity->getAll(['password']);
$ATTR = array_change_key_case($ATTR, CASE_UPPER);
- $preparsed = parseContentTags($Item->get('body'));
+ $preparsed = parseContentTags($Entity->get('body'));
return [
- 'URL' => Application::getEntityURL($Item),
- 'GUID' => generatePseudoGUID($Item),
- 'ARGV' => parseArguments($Item->get('argv')),
+ 'URL' => Application::getEntityURL($Entity),
+ 'GUID' => generatePseudoGUID($Entity),
+ 'ARGV' => parseArguments($Entity->get('argv')),
'ATTR' => $ATTR,
@@ -95,11 +99,11 @@ function generateItemTemplateData(Item $Item): array {
],
'BODY' => [
- 'TEXT' => function() use($Item) {
+ 'TEXT' => function() use($Entity) {
return $preparsed;
},
- 'HTML' => function() use($Item) {
- return parseEntityContent($Item);
+ 'HTML' => function() use($Entity) {
+ return parseEntityContent($Entity);
}
]
];
@@ -108,12 +112,12 @@ function generateItemTemplateData(Item $Item): array {
#===============================================================================
# Generate pseudo GUID for entity
#===============================================================================
-function generatePseudoGUID(Item $Entity) {
+function generatePseudoGUID(EntityInterface $Entity) {
switch(get_class($Entity)) {
- case "Page\Item":
+ case "Page\Entity":
$attr = Application::get('PAGE.FEED_GUID');
break;
- case "Post\Item":
+ case "Post\Entity":
$attr = Application::get('POST.FEED_GUID');
break;
default:
@@ -134,12 +138,14 @@ function parseContentTags(string $text): string {
$entity_tags = '#\{(POST|PAGE|USER)\[([0-9]+)\]\}#';
$text = preg_replace_callback($entity_tags, function($matches) {
- $namespace = ucfirst(strtolower($matches[1])).'\\Factory';
+ $namespace = ucfirst(strtolower($matches[1]));
+ $Repository = Application::getRepository($namespace);
- try {
- $Entity = $namespace::build($matches[2]);
+ if($Entity = $Repository->find($matches[2])) {
return Application::getEntityURL($Entity);
- } catch(Exception $Exception) {
+ }
+
+ else {
return '{undefined}';
}
}, $text);
@@ -156,15 +162,15 @@ function parseContentTags(string $text): string {
#===============================================================================
# Parse entity content
#===============================================================================
-function parseEntityContent(Item $Item): string {
- switch($class = get_class($Item)) {
- case 'Page\Item':
+function parseEntityContent(EntityInterface $Entity): string {
+ switch($class = get_class($Entity)) {
+ case 'Page\Entity':
$prefix = 'PAGE';
break;
- case 'Post\Item':
+ case 'Post\Entity':
$prefix = 'POST';
break;
- case 'User\Item':
+ case 'User\Entity':
$prefix = 'USER';
break;
default:
@@ -175,7 +181,7 @@ function parseEntityContent(Item $Item): string {
$Parsedown = new Parsedown();
$Parsedown->setUrlsLinked(FALSE);
- $text = parseContentTags($Item->get('body'));
+ $text = parseContentTags($Entity->get('body'));
if(Application::get("$prefix.EMOTICONS")) {
$text = parseUnicodeEmoticons($text);
@@ -409,34 +415,37 @@ function generateSlug($string, $separator = '-') {
# Function to get data from specific page in templates
#===============================================================================
function PAGE(int $id): array {
- try {
- $Page = Page\Factory::build($id);
+ $Repository = Application::getRepository('Page');
+
+ if($Page = $Repository->find($id)) {
return generateItemTemplateData($Page);
- } catch(Page\Exception $Exception) {
- return [];
}
+
+ return [];
}
#===============================================================================
# Function to get data from specific post in templates
#===============================================================================
function POST(int $id): array {
- try {
- $Post = Post\Factory::build($id);
+ $Repository = Application::getRepository('Post');
+
+ if($Post = $Repository->find($id)) {
return generateItemTemplateData($Post);
- } catch(Post\Exception $Exception) {
- return [];
}
+
+ return [];
}
#===============================================================================
# Function to get data from specific user in templates
#===============================================================================
function USER(int $id): array {
- try {
- $User = User\Factory::build($id);
+ $Repository = Application::getRepository('User');
+
+ if($User = $Repository->find($id)) {
return generateItemTemplateData($User);
- } catch(User\Exception $Exception) {
- return [];
}
+
+ return [];
}
diff --git a/core/include/feed/main.php b/core/include/feed/main.php
index 4dc7c81..637c54b 100644
--- a/core/include/feed/main.php
+++ b/core/include/feed/main.php
@@ -1,9 +1,8 @@
<?php
#===============================================================================
-# Get instances
+# Get repositories
#===============================================================================
-$Database = Application::getDatabase();
-$Language = Application::getLanguage();
+$UserRepository = Application::getRepository('User');
#===============================================================================
# HEADER: Content-Type for XML document
@@ -14,26 +13,21 @@ HTTP::responseHeader(HTTP::HEADER_CONTENT_TYPE, HTTP::CONTENT_TYPE_XML);
# Post feed
#===============================================================================
if(!isset($param) OR $param !== 'page') {
- $POST['FEED_SORT'] = Application::get('POST.FEED_SORT');
- $POST['FEED_SIZE'] = Application::get('POST.FEED_SIZE');
+ $PostRepository = Application::getRepository('Post');
- $execSQL = "SELECT id FROM %s ORDER BY {$POST['FEED_SORT']} LIMIT {$POST['FEED_SIZE']}";
- $postIDs = $Database->query(sprintf($execSQL, Post\Attribute::TABLE))->fetchAll($Database::FETCH_COLUMN);
+ $posts = $PostRepository->getPaginated(
+ Application::get('POST.FEED_SORT'),
+ Application::get('POST.FEED_SIZE')
+ );
- foreach($postIDs as $postID) {
- try {
- $Post = Post\Factory::build($postID);
- $User = User\Factory::build($Post->get('user'));
+ foreach($posts as $Post) {
+ $User = $UserRepository->find($Post->get('user'));
- $ItemTemplate = Template\Factory::build('feed/item_post');
- $ItemTemplate->set('POST', generateItemTemplateData($Post));
- $ItemTemplate->set('USER', generateItemTemplateData($User));
+ $ItemTemplate = Template\Factory::build('feed/item_post');
+ $ItemTemplate->set('POST', generateItemTemplateData($Post));
+ $ItemTemplate->set('USER', generateItemTemplateData($User));
- $post_templates[] = $ItemTemplate;
- }
-
- catch(Post\Exception $Exception){}
- catch(User\Exception $Exception){}
+ $post_templates[] = $ItemTemplate;
}
}
@@ -41,26 +35,21 @@ if(!isset($param) OR $param !== 'page') {
# Page feed
#===============================================================================
if(!isset($param) OR $param !== 'post') {
- $PAGE['FEED_SORT'] = Application::get('PAGE.FEED_SORT');
- $PAGE['FEED_SIZE'] = Application::get('PAGE.FEED_SIZE');
-
- $execSQL = "SELECT id FROM %s ORDER BY {$PAGE['FEED_SORT']} LIMIT {$PAGE['FEED_SIZE']}";
- $pageIDs = $Database->query(sprintf($execSQL, Page\Attribute::TABLE))->fetchAll($Database::FETCH_COLUMN);
+ $PageRepository = Application::getRepository('Page');
- foreach($pageIDs as $pageID) {
- try {
- $Page = Page\Factory::build($pageID);
- $User = User\Factory::build($Page->get('user'));
+ $pages = $PageRepository->getPaginated(
+ Application::get('PAGE.FEED_SORT'),
+ Application::get('PAGE.FEED_SIZE')
+ );
- $ItemTemplate = Template\Factory::build('feed/item_page');
- $ItemTemplate->set('PAGE', generateItemTemplateData($Page));
- $ItemTemplate->set('USER', generateItemTemplateData($User));
+ foreach($pages as $Page) {
+ $User = $UserRepository->find($Page->get('user'));
- $page_templates[] = $ItemTemplate;
- }
+ $ItemTemplate = Template\Factory::build('feed/item_page');
+ $ItemTemplate->set('PAGE', generateItemTemplateData($Page));
+ $ItemTemplate->set('USER', generateItemTemplateData($User));
- catch(Page\Exception $Exception){}
- catch(User\Exception $Exception){}
+ $page_templates[] = $ItemTemplate;
}
}
diff --git a/core/include/home.php b/core/include/home.php
index 76c9287..bc73bef 100644
--- a/core/include/home.php
+++ b/core/include/home.php
@@ -1,23 +1,21 @@
<?php
#===============================================================================
-# Get instances
+# Get repositories
#===============================================================================
-$Database = Application::getDatabase();
-$Language = Application::getLanguage();
+$PostRepository = Application::getRepository('Post');
+$UserRepository = Application::getRepository('User');
-$execSQL = 'SELECT id FROM %s ORDER BY '.Application::get('POST.LIST_SORT').' LIMIT '.Application::get('POST.LIST_SIZE');
-$Statement = $Database->query(sprintf($execSQL, Post\Attribute::TABLE));
-
-$postIDs = $Statement->fetchAll($Database::FETCH_COLUMN);
+#===============================================================================
+# Get paginated post list
+#===============================================================================
+$posts = $PostRepository->getPaginated(
+ Application::get('POST.LIST_SORT'),
+ Application::get('POST.LIST_SIZE')
+);
-foreach($postIDs as $postID) {
- try {
- $Post = Post\Factory::build($postID);
- $User = User\Factory::build($Post->get('user'));
- $templates[] = generatePostItemTemplate($Post, $User);
- }
- catch(Post\Exception $Exception){}
- catch(User\Exception $Exception){}
+foreach($posts as $Post) {
+ $User = $UserRepository->find($Post->get('user'));
+ $templates[] = generatePostItemTemplate($Post, $User);
}
#===============================================================================
@@ -35,7 +33,8 @@ $MainTemplate = Template\Factory::build('main');
$MainTemplate->set('HTML', $HomeTemplate);
$MainTemplate->set('HEAD', [
'NAME' => Application::get('BLOGMETA.HOME'),
- 'DESC' => Application::get('BLOGMETA.NAME').' – '.Application::get('BLOGMETA.DESC'),
+ 'DESC' => Application::get('BLOGMETA.NAME').' – '
+ .Application::get('BLOGMETA.DESC'),
'PERM' => Application::getURL()
]);
diff --git a/core/include/page/list.php b/core/include/page/list.php
index 7618009..f7541fa 100644
--- a/core/include/page/list.php
+++ b/core/include/page/list.php
@@ -2,16 +2,21 @@
#===============================================================================
# Get instances
#===============================================================================
-$Database = Application::getDatabase();
$Language = Application::getLanguage();
#===============================================================================
+# Get repositories
+#===============================================================================
+$PageRepository = Application::getRepository('Page');
+$UserRepository = Application::getRepository('User');
+
+#===============================================================================
# Pagination
#===============================================================================
$site_size = Application::get('PAGE.LIST_SIZE');
$site_sort = Application::get('PAGE.LIST_SORT');
-$count = $Database->query(sprintf('SELECT COUNT(id) FROM %s', Page\Attribute::TABLE))->fetchColumn();
+$count = $PageRepository->getCount();
$lastSite = ceil($count / $site_size);
$currentSite = HTTP::GET('site') ?? 1;
@@ -24,23 +29,23 @@ if($currentSite < 1 OR ($currentSite > $lastSite AND $lastSite > 0)) {
#===============================================================================
# Single redirect
#===============================================================================
-if(Application::get('PAGE.SINGLE_REDIRECT') === TRUE AND $count === '1') {
- $Statement = $Database->query(sprintf('SELECT id FROM %s LIMIT 1', Page\Attribute::TABLE));
- $Page = Page\Factory::build($Statement->fetchColumn());
+if(Application::get('PAGE.SINGLE_REDIRECT') === TRUE AND $count === 1) {
+ $Page = $PageRepository->getLast();
HTTP::redirect(Application::getEntityURL($Page));
}
-$execSQL = "SELECT id FROM %s ORDER BY {$site_sort} LIMIT ".(($currentSite-1) * $site_size).", {$site_size}";
-$pageIDs = $Database->query(sprintf($execSQL, Page\Attribute::TABLE))->fetchAll($Database::FETCH_COLUMN);
+#===============================================================================
+# Get paginated page list
+#===============================================================================
+$pages = $PageRepository->getPaginated(
+ $site_sort,
+ $site_size,
+ ($currentSite-1) * $site_size
+);
-foreach($pageIDs as $pageID) {
- try {
- $Page = Page\Factory::build($pageID);
- $User = User\Factory::build($Page->get('user'));
- $templates[] = generatePageItemTemplate($Page, $User);
- }
- catch(Page\Exception $Exception){}
- catch(User\Exception $Exception){}
+foreach($pages as $Page) {
+ $User = $UserRepository->find($Page->get('user'));
+ $templates[] = generatePageItemTemplate($Page, $User);
}
#===============================================================================
diff --git a/core/include/page/main.php b/core/include/page/main.php
index 01ef40d..39e1d3c 100644
--- a/core/include/page/main.php
+++ b/core/include/page/main.php
@@ -1,79 +1,72 @@
<?php
#===============================================================================
-# Get instances
+# Get repositories
#===============================================================================
-$Database = Application::getDatabase();
-$Language = Application::getLanguage();
+$PageRepository = Application::getRepository('Page');
+$UserRepository = Application::getRepository('User');
#===============================================================================
-# TRY: Page\Exception
+# Try to find page by slug URL or unique ID
#===============================================================================
-try {
- if(Application::get('PAGE.SLUG_URLS')) {
- $Page = Page\Factory::buildBySlug($param);
+if(Application::get('PAGE.SLUG_URLS')) {
+ if(!$Page = $PageRepository->findBy('slug', $param)) {
+ if($Page = $PageRepository->find($param)) {
+ HTTP::redirect(Application::getEntityURL($Page));
+ }
}
+}
- else {
- $Page = Page\Factory::build($param);
+else {
+ if(!$Page = $PageRepository->find($param)) {
+ if($Page = $PageRepository->findBy('slug', $param)) {
+ HTTP::redirect(Application::getEntityURL($Page));
+ }
}
+}
- $User = User\Factory::build($Page->get('user'));
-
- $page_data = generateItemTemplateData($Page);
- $user_data = generateItemTemplateData($User);
-
- #===============================================================================
- # Add page data for previous and next page
- #===============================================================================
- try {
- $PrevPage = Page\Factory::build($Page->getPrevID());
- $page_data['PREV'] = generateItemTemplateData($PrevPage);
- } catch(Page\Exception $Exception){}
-
- try {
- $NextPage = Page\Factory::build($Page->getNextID());
- $page_data['NEXT'] = generateItemTemplateData($NextPage);
- } catch(Page\Exception $Exception){}
-
- #===============================================================================
- # Build document
- #===============================================================================
- $PageTemplate = Template\Factory::build('page/main');
- $PageTemplate->set('PAGE', $page_data);
- $PageTemplate->set('USER', $user_data);
+#===============================================================================
+# Throw 404 error if page could not be found
+#===============================================================================
+if(!isset($Page)) {
+ Application::error404();
+}
- $MainTemplate = Template\Factory::build('main');
- $MainTemplate->set('HTML', $PageTemplate);
- $MainTemplate->set('HEAD', [
- 'NAME' => $page_data['ATTR']['NAME'],
- 'DESC' => description($page_data['BODY']['HTML'](), Application::get('PAGE.DESCRIPTION_SIZE')),
- 'PERM' => $page_data['URL'],
- 'OG_IMAGES' => $page_data['FILE']['LIST']
- ]);
+#===============================================================================
+# Generate template data
+#===============================================================================
+$User = $UserRepository->find($Page->get('user'));
+$page_data = generateItemTemplateData($Page);
+$user_data = generateItemTemplateData($User);
- # Get access to the current item data from main template
- $MainTemplate->set('TYPE', 'PAGE');
- $MainTemplate->set('PAGE', $page_data);
- $MainTemplate->set('USER', $user_data);
+#===============================================================================
+# Add template data for previous and next page
+#===============================================================================
+if($PrevPage = $PageRepository->findPrev($Page)) {
+ $page_data['PREV'] = generateItemTemplateData($PrevPage);
+}
- echo $MainTemplate;
+if($NextPage = $PageRepository->findNext($Page)) {
+ $page_data['NEXT'] = generateItemTemplateData($NextPage);
}
#===============================================================================
-# CATCH: Page\Exception
+# Build document
#===============================================================================
-catch(Page\Exception $Exception) {
- try {
- if(Application::get('PAGE.SLUG_URLS') === FALSE) {
- $Page = Page\Factory::buildBySlug($param);
- } else {
- $Page = Page\Factory::build($param);
- }
+$PageTemplate = Template\Factory::build('page/main');
+$PageTemplate->set('PAGE', $page_data);
+$PageTemplate->set('USER', $user_data);
- HTTP::redirect(Application::getEntityURL($Page));
- }
+$MainTemplate = Template\Factory::build('main');
+$MainTemplate->set('TYPE', 'PAGE');
+$MainTemplate->set('PAGE', $page_data);
+$MainTemplate->set('USER', $user_data);
+$MainTemplate->set('HTML', $PageTemplate);
+$MainTemplate->set('HEAD', [
+ 'NAME' => $page_data['ATTR']['NAME'],
+ 'DESC' => description($page_data['BODY']['HTML'](),
+ Application::get('PAGE.DESCRIPTION_SIZE')),
+ 'PERM' => $page_data['URL'],
+ 'OG_IMAGES' => $page_data['FILE']['LIST']
+]);
- catch(Page\Exception $Exception) {
- Application::error404();
- }
-}
+echo $MainTemplate;
diff --git a/core/include/post/list.php b/core/include/post/list.php
index 84de108..4599883 100644
--- a/core/include/post/list.php
+++ b/core/include/post/list.php
@@ -2,16 +2,21 @@
#===============================================================================
# Get instances
#===============================================================================
-$Database = Application::getDatabase();
$Language = Application::getLanguage();
#===============================================================================
+# Get repositories
+#===============================================================================
+$PostRepository = Application::getRepository('Post');
+$UserRepository = Application::getRepository('User');
+
+#===============================================================================
# Pagination
#===============================================================================
$site_size = Application::get('POST.LIST_SIZE');
$site_sort = Application::get('POST.LIST_SORT');
-$count = $Database->query(sprintf('SELECT COUNT(id) FROM %s', Post\Attribute::TABLE))->fetchColumn();
+$count = $PostRepository->getCount();
$lastSite = ceil($count / $site_size);
$currentSite = HTTP::GET('site') ?? 1;
@@ -24,23 +29,23 @@ if($currentSite < 1 OR ($currentSite > $lastSite AND $lastSite > 0)) {
#===============================================================================
# Single redirect
#===============================================================================
-if(Application::get('POST.SINGLE_REDIRECT') === TRUE AND $count === '1') {
- $Statement = $Database->query(sprintf('SELECT id FROM %s LIMIT 1', Post\Attribute::TABLE));
- $Post = Post\Factory::build($Statement->fetchColumn());
+if(Application::get('POST.SINGLE_REDIRECT') === TRUE AND $count === 1) {
+ $Post = $PostRepository->getLast();
HTTP::redirect(Application::getEntityURL($Post));
}
-$execSQL = "SELECT id FROM %s ORDER BY {$site_sort} LIMIT ".(($currentSite-1) * $site_size).", {$site_size}";
-$postIDs = $Database->query(sprintf($execSQL, Post\Attribute::TABLE))->fetchAll($Database::FETCH_COLUMN);
+#===============================================================================
+# Get paginated post list
+#===============================================================================
+$posts = $PostRepository->getPaginated(
+ $site_sort,
+ $site_size,
+ ($currentSite-1) * $site_size
+);
-foreach($postIDs as $postID) {
- try {
- $Post = Post\Factory::build($postID);
- $User = User\Factory::build($Post->get('user'));
- $templates[] = generatePostItemTemplate($Post, $User);
- }
- catch(Post\Exception $Exception){}
- catch(User\Exception $Exception){}
+foreach($posts as $Post) {
+ $User = $UserRepository->find($Post->get('user'));
+ $templates[] = generatePostItemTemplate($Post, $User);
}
#===============================================================================
diff --git a/core/include/post/main.php b/core/include/post/main.php
index 57cc402..86008f6 100644
--- a/core/include/post/main.php
+++ b/core/include/post/main.php
@@ -1,79 +1,72 @@
<?php
#===============================================================================
-# Get instances
+# Get repositories
#===============================================================================
-$Database = Application::getDatabase();
-$Language = Application::getLanguage();
+$PostRepository = Application::getRepository('Post');
+$UserRepository = Application::getRepository('User');
#===============================================================================
-# TRY: Post\Exception
+# Try to find post by slug URL or unique ID
#===============================================================================
-try {
- if(Application::get('POST.SLUG_URLS')) {
- $Post = Post\Factory::buildBySlug($param);
+if(Application::get('POST.SLUG_URLS')) {
+ if(!$Post = $PostRepository->findBy('slug', $param)) {
+ if($Post = $PostRepository->find($param)) {
+ HTTP::redirect(Application::getEntityURL($Post));
+ }
}
+}
- else {
- $Post = Post\Factory::build($param);
+else {
+ if(!$Post = $PostRepository->find($param)) {
+ if($Post = $PostRepository->findBy('slug', $param)) {
+ HTTP::redirect(Application::getEntityURL($Post));
+ }
}
+}
- $User = User\Factory::build($Post->get('user'));
-
- $post_data = generateItemTemplateData($Post);
- $user_data = generateItemTemplateData($User);
-
- #===============================================================================
- # Add post data for previous and next post
- #===============================================================================
- try {
- $PrevPost = Post\Factory::build($Post->getPrevID());
- $post_data['PREV'] = generateItemTemplateData($PrevPost);
- } catch(Post\Exception $Exception){}
-
- try {
- $NextPost = Post\Factory::build($Post->getNextID());
- $post_data['NEXT'] = generateItemTemplateData($NextPost);
- } catch(Post\Exception $Exception){}
-
- #===============================================================================
- # Build document
- #===============================================================================
- $PostTemplate = Template\Factory::build('post/main');
- $PostTemplate->set('POST', $post_data);
- $PostTemplate->set('USER', $user_data);
+#===============================================================================
+# Throw 404 error if post could not be found
+#===============================================================================
+if(!isset($Post)) {
+ Application::error404();
+}
- $MainTemplate = Template\Factory::build('main');
- $MainTemplate->set('HTML', $PostTemplate);
- $MainTemplate->set('HEAD', [
- 'NAME' => $post_data['ATTR']['NAME'],
- 'DESC' => description($post_data['BODY']['HTML'](), Application::get('POST.DESCRIPTION_SIZE')),
- 'PERM' => $post_data['URL'],
- 'OG_IMAGES' => $post_data['FILE']['LIST']
- ]);
+#===============================================================================
+# Generate template data
+#===============================================================================
+$User = $UserRepository->find($Post->get('user'));
+$post_data = generateItemTemplateData($Post);
+$user_data = generateItemTemplateData($User);
- # Get access to the current item data from main template
- $MainTemplate->set('TYPE', 'POST');
- $MainTemplate->set('POST', $post_data);
- $MainTemplate->set('USER', $user_data);
+#===============================================================================
+# Add template data for previous and next post
+#===============================================================================
+if($PrevPost = $PostRepository->findPrev($Post)) {
+ $post_data['PREV'] = generateItemTemplateData($PrevPost);
+}
- echo $MainTemplate;
+if($NextPost = $PostRepository->findNext($Post)) {
+ $post_data['NEXT'] = generateItemTemplateData($NextPost);
}
#===============================================================================
-# CATCH: Post\Exception
+# Build document
#===============================================================================
-catch(Post\Exception $Exception) {
- try {
- if(Application::get('POST.SLUG_URLS') === FALSE) {
- $Post = Post\Factory::buildBySlug($param);
- } else {
- $Post = Post\Factory::build($param);
- }
+$PostTemplate = Template\Factory::build('post/main');
+$PostTemplate->set('POST', $post_data);
+$PostTemplate->set('USER', $user_data);
- HTTP::redirect(Application::getEntityURL($Post));
- }
+$MainTemplate = Template\Factory::build('main');
+$MainTemplate->set('TYPE', 'POST');
+$MainTemplate->set('POST', $post_data);
+$MainTemplate->set('USER', $user_data);
+$MainTemplate->set('HTML', $PostTemplate);
+$MainTemplate->set('HEAD', [
+ 'NAME' => $post_data['ATTR']['NAME'],
+ 'DESC' => description($post_data['BODY']['HTML'](),
+ Application::get('POST.DESCRIPTION_SIZE')),
+ 'PERM' => $post_data['URL'],
+ 'OG_IMAGES' => $post_data['FILE']['LIST']
+]);
- catch(Post\Exception $Exception) {
- Application::error404();
- }
-}
+echo $MainTemplate;
diff --git a/core/include/search/main.php b/core/include/search/main.php
index 6bc6bdc..564f0dd 100644
--- a/core/include/search/main.php
+++ b/core/include/search/main.php
@@ -2,15 +2,22 @@
#===============================================================================
# Get instances
#===============================================================================
-$Database = Application::getDatabase();
$Language = Application::getLanguage();
-$D_LIST = $Database->query(sprintf('SELECT DISTINCT DAY(time_insert) AS temp FROM %s ORDER BY temp', Post\Attribute::TABLE));
-$M_LIST = $Database->query(sprintf('SELECT DISTINCT MONTH(time_insert) AS temp FROM %s ORDER BY temp', Post\Attribute::TABLE));
-$Y_LIST = $Database->query(sprintf('SELECT DISTINCT YEAR(time_insert) AS temp FROM %s ORDER BY temp', Post\Attribute::TABLE));
+#===============================================================================
+# Get repositories
+#===============================================================================
+$PostRepository = Application::getRepository('Post');
+$UserRepository = Application::getRepository('User');
if($search = HTTP::GET('q')) {
- if(!$postIDs = Post\Item::getSearchResultIDs($search, [HTTP::GET('d'), HTTP::GET('m'), HTTP::GET('y')], $Database)) {
+ $filter = [
+ 'day' => HTTP::GET('d'),
+ 'month' => HTTP::GET('m'),
+ 'year' => HTTP::GET('y')
+ ];
+
+ if(!$posts = $PostRepository->search($search, $filter)) {
$message = $Language->text('search_no_results', escapeHTML($search));
}
}
@@ -22,9 +29,9 @@ $form_data = [
'Y' => HTTP::GET('y'),
],
'OPTIONS' => [
- 'D' => $D_LIST->fetchAll($Database::FETCH_COLUMN),
- 'M' => $M_LIST->fetchAll($Database::FETCH_COLUMN),
- 'Y' => $Y_LIST->fetchAll($Database::FETCH_COLUMN),
+ 'D' => $PostRepository->getDistinctDays(),
+ 'M' => $PostRepository->getDistinctMonths(),
+ 'Y' => $PostRepository->getDistinctYears(),
]
];
@@ -36,15 +43,10 @@ $search_data = [
#===============================================================================
# Build document
#===============================================================================
-if(isset($postIDs) AND !empty($postIDs)) {
- foreach($postIDs as $postID) {
- try {
- $Post = Post\Factory::build($postID);
- $User = User\Factory::build($Post->get('user'));
- $templates[] = generatePostItemTemplate($Post, $User);
- }
- catch(Post\Exception $Exception){}
- catch(User\Exception $Exception){}
+if(!empty($posts)) {
+ foreach($posts as $Post) {
+ $User = $UserRepository->find($Post->get('user'));
+ $templates[] = generatePostItemTemplate($Post, $User);
}
$ResultTemplate = Template\Factory::build('search/result');
diff --git a/core/include/user/list.php b/core/include/user/list.php
index b64eee5..f6f794a 100644
--- a/core/include/user/list.php
+++ b/core/include/user/list.php
@@ -2,16 +2,20 @@
#===============================================================================
# Get instances
#===============================================================================
-$Database = Application::getDatabase();
$Language = Application::getLanguage();
#===============================================================================
+# Get repositories
+#===============================================================================
+$UserRepository = Application::getRepository('User');
+
+#===============================================================================
# Pagination
#===============================================================================
$site_size = Application::get('USER.LIST_SIZE');
$site_sort = Application::get('USER.LIST_SORT');
-$count = $Database->query(sprintf('SELECT COUNT(id) FROM %s', User\Attribute::TABLE))->fetchColumn();
+$count = $UserRepository->getCount();
$lastSite = ceil($count / $site_size);
$currentSite = HTTP::GET('site') ?? 1;
@@ -24,20 +28,22 @@ if($currentSite < 1 OR ($currentSite > $lastSite AND $lastSite > 0)) {
#===============================================================================
# Single redirect
#===============================================================================
-if(Application::get('USER.SINGLE_REDIRECT') === TRUE AND $count === '1') {
- $Statement = $Database->query(sprintf('SELECT id FROM %s LIMIT 1', User\Attribute::TABLE));
- $User = User\Factory::build($Statement->fetchColumn());
+if(Application::get('USER.SINGLE_REDIRECT') === TRUE AND $count === 1) {
+ $User = $UserRepository->getLast();
HTTP::redirect(Application::getEntityURL($User));
}
-$execSQL = "SELECT id FROM %s ORDER BY {$site_sort} LIMIT ".(($currentSite-1) * $site_size).", {$site_size}";
-$userIDs = $Database->query(sprintf($execSQL, User\Attribute::TABLE))->fetchAll($Database::FETCH_COLUMN);
+#===============================================================================
+# Get paginated user list
+#===============================================================================
+$users = $UserRepository->getPaginated(
+ $site_sort,
+ $site_size,
+ ($currentSite-1) * $site_size
+);
-foreach($userIDs as $userID) {
- try {
- $User = User\Factory::build($userID);
- $templates[] = generateUserItemTemplate($User);
- } catch(User\Exception $Exception){}
+foreach($users as $User) {
+ $templates[] = generateUserItemTemplate($User);
}
#===============================================================================
diff --git a/core/include/user/main.php b/core/include/user/main.php
index 34ec883..c0cb20d 100644
--- a/core/include/user/main.php
+++ b/core/include/user/main.php
@@ -1,81 +1,73 @@
<?php
#===============================================================================
-# Get instances
+# Get repositories
#===============================================================================
-$Database = Application::getDatabase();
-$Language = Application::getLanguage();
+$PageRepository = Application::getRepository('Page');
+$PostRepository = Application::getRepository('Post');
+$UserRepository = Application::getRepository('User');
#===============================================================================
-# TRY: User\Exception
+# Try to find user by slug URL or unique ID
#===============================================================================
-try {
- if(Application::get('USER.SLUG_URLS')) {
- $User = User\Factory::buildBySlug($param);
+if(Application::get('USER.SLUG_URLS')) {
+ if(!$User = $UserRepository->findBy('slug', $param)) {
+ if($User = $UserRepository->find($param)) {
+ HTTP::redirect(Application::getEntityURL($User));
+ }
}
+}
- else {
- $User = User\Factory::build($param);
+else {
+ if(!$User = $UserRepository->find($param)) {
+ if($User = $UserRepository->findBy('slug', $param)) {
+ HTTP::redirect(Application::getEntityURL($User));
+ }
}
+}
- $user_data = generateItemTemplateData($User);
-
- #===============================================================================
- # Add user data for previous and next user
- #===============================================================================
- try {
- $PrevUser = User\Factory::build($User->getPrevID());
- $user_data['PREV'] = generateItemTemplateData($PrevUser);
- } catch(User\Exception $Exception){}
-
- try {
- $NextUser = User\Factory::build($User->getNextID());
- $user_data['NEXT'] = generateItemTemplateData($NextUser);
- } catch(User\Exception $Exception){}
-
- $PostCountStatement = $Database->query(sprintf('SELECT COUNT(*) FROM %s WHERE user = %d', Post\Attribute::TABLE, $User->getID()));
- $PageCountStatement = $Database->query(sprintf('SELECT COUNT(*) FROM %s WHERE user = %d', Page\Attribute::TABLE, $User->getID()));
-
- #===============================================================================
- # Build document
- #===============================================================================
- $UserTemplate = Template\Factory::build('user/main');
- $UserTemplate->set('USER', $user_data);
- $UserTemplate->set('COUNT', [
- 'POST' => $PostCountStatement->fetchColumn(),
- 'PAGE' => $PageCountStatement->fetchColumn()
- ]);
+#===============================================================================
+# Throw 404 error if user could not be found
+#===============================================================================
+if(!isset($User)) {
+ Application::error404();
+}
- $MainTemplate = Template\Factory::build('main');
- $MainTemplate->set('HTML', $UserTemplate);
- $MainTemplate->set('HEAD', [
- 'NAME' => $user_data['ATTR']['FULLNAME'],
- 'DESC' => description($user_data['BODY']['HTML'](), Application::get('USER.DESCRIPTION_SIZE')),
- 'PERM' => $user_data['URL'],
- 'OG_IMAGES' => $user_data['FILE']['LIST']
- ]);
+#===============================================================================
+# Generate template data
+#===============================================================================
+$user_data = generateItemTemplateData($User);
- # Get access to the current item data from main template
- $MainTemplate->set('TYPE', 'USER');
- $MainTemplate->set('USER', $user_data);
+#===============================================================================
+# Add template data for previous and next user
+#===============================================================================
+if($PrevUser = $UserRepository->findPrev($User)) {
+ $user_data['PREV'] = generateItemTemplateData($PrevUser);
+}
- echo $MainTemplate;
+if($NextUser = $UserRepository->findNext($User)) {
+ $user_data['NEXT'] = generateItemTemplateData($NextUser);
}
#===============================================================================
-# CATCH: User\Exception
+# Build document
#===============================================================================
-catch(User\Exception $Exception) {
- try {
- if(Application::get('USER.SLUG_URLS') === FALSE) {
- $User = User\Factory::buildBySlug($param);
- } else {
- $User = User\Factory::build($param);
- }
+$UserTemplate = Template\Factory::build('user/main');
+$UserTemplate->set('USER', $user_data);
+$UserTemplate->set('COUNT', [
+ 'POST' => $PostRepository->getCountByUser($User),
+ 'PAGE' => $PageRepository->getCountByUser($User)
+]);
- HTTP::redirect(Application::getEntityURL($User));
- }
+$MainTemplate = Template\Factory::build('main');
+$MainTemplate->set('TYPE', 'USER');
+$MainTemplate->set('USER', $user_data);
+$MainTemplate->set('HTML', $UserTemplate);
+$MainTemplate->set('HEAD', [
+ 'NAME' => $user_data['ATTR']['FULLNAME'],
+ 'DESC' => description($user_data['BODY']['HTML'](),
+ Application::get('USER.DESCRIPTION_SIZE')),
+ 'PERM' => $user_data['URL'],
+ 'OG_IMAGES' => $user_data['FILE']['LIST']
+]);
- catch(User\Exception $Exception) {
- Application::error404();
- }
-}
+echo $MainTemplate;
diff --git a/core/namespace/Application.php b/core/namespace/Application.php
index f9a8196..7473e1f 100644
--- a/core/namespace/Application.php
+++ b/core/namespace/Application.php
@@ -6,6 +6,7 @@ class Application {
#===============================================================================
private static $Database;
private static $Language;
+ private static $repositories = [];
#===============================================================================
# Configuration array
@@ -68,6 +69,21 @@ class Application {
}
#===============================================================================
+ # Return singleton repository instance
+ #===============================================================================
+ public function getRepository(string $namespace): Repository {
+ $identifier = strtolower($namespace);
+ $repository = "$namespace\Repository";
+
+ if(!isset(self::$repositories[$identifier])) {
+ $Repository = new $repository(self::getDatabase());
+ self::$repositories[$identifier] = $Repository;
+ }
+
+ return self::$repositories[$identifier];
+ }
+
+ #===============================================================================
# Return unique CSRF token for the current session
#===============================================================================
public static function getSecurityToken(): string {
@@ -142,15 +158,15 @@ class Application {
#===============================================================================
# Return absolute URL of a specifc entity
#===============================================================================
- public function getEntityURL(Item $Entity) {
+ public function getEntityURL(EntityInterface $Entity) {
switch($class = get_class($Entity)) {
- case 'Page\Item':
+ case 'Page\Entity':
$attr = self::get('PAGE.SLUG_URLS') ? 'slug' : 'id';
return self::getPageURL($Entity->get($attr).'/');
- case 'Post\Item':
+ case 'Post\Entity':
$attr = self::get('POST.SLUG_URLS') ? 'slug' : 'id';
return self::getPostURL($Entity->get($attr).'/');
- case 'User\Item':
+ case 'User\Entity':
$attr = self::get('USER.SLUG_URLS') ? 'slug' : 'id';
return self::getUserURL($Entity->get($attr).'/');
default:
diff --git a/core/namespace/Attribute.php b/core/namespace/Attribute.php
deleted file mode 100644
index c874a57..0000000
--- a/core/namespace/Attribute.php
+++ /dev/null
@@ -1,84 +0,0 @@
-<?php
-abstract class Attribute {
-
- #===============================================================================
- # Set attribute
- #===============================================================================
- public function set($attribute, $value) {
- return $this->{$attribute} = $value;
- }
-
- #===============================================================================
- # Get attribute
- #===============================================================================
- public function get($attribute) {
- return $this->{$attribute} ?? NULL;
- }
-
- #===============================================================================
- # Get all attributes
- #===============================================================================
- public function getAll($exclude = []): array {
- $attributes = get_object_vars($this);
-
- return array_filter($attributes, function($attribute) use($exclude) {
- return !in_array($attribute, $exclude);
- }, ARRAY_FILTER_USE_KEY);
- }
-
- #===============================================================================
- # Get array with not FALSE attributes
- #===============================================================================
- protected function getFilteredAttributes(): array {
- return array_filter(get_object_vars($this), function($value) {
- return $value !== FALSE;
- });
- }
-
- #===============================================================================
- # Insert database item
- #===============================================================================
- public function insert(\Database $Database): bool {
- $part[0] = '';
- $part[1] = '';
-
- $attributes = $this->getFilteredAttributes();
-
- foreach($attributes as $column => $value) {
- $part[0] .= "{$column},";
- $part[1] .= '?,';
- }
-
- $part[0] = rtrim($part[0], ',');
- $part[1] = rtrim($part[1], ',');
-
- $Statement = $Database->prepare('INSERT INTO '.static::TABLE." ({$part[0]}) VALUES ({$part[1]})");
- return $Statement->execute(array_values($attributes));
- }
-
- #===============================================================================
- # Update database item
- #===============================================================================
- public function update(\Database $Database): bool {
- $part = '';
-
- $attributes = $this->getFilteredAttributes();
-
- foreach($attributes as $column => $value) {
- $part .= "{$column} = ?,";
- }
-
- $part = rtrim($part, ',');
-
- $Statement = $Database->prepare('UPDATE '.static::TABLE.' SET '.$part.' WHERE id = '.(int) $this->get('id'));
- return $Statement->execute(array_values($attributes));
- }
-
- #===============================================================================
- # Delete database item
- #===============================================================================
- public function delete(\Database $Database): bool {
- $Statement = $Database->prepare('DELETE FROM '.static::TABLE.' WHERE id = ?');
- return $Statement->execute([$this->get('id')]);
- }
-}
diff --git a/core/namespace/Entity.php b/core/namespace/Entity.php
new file mode 100644
index 0000000..4bedd37
--- /dev/null
+++ b/core/namespace/Entity.php
@@ -0,0 +1,47 @@
+<?php
+abstract class Entity implements EntityInterface {
+ protected $id;
+ protected $time_insert;
+ protected $time_update;
+
+ #===============================================================================
+ # Get attribute
+ #===============================================================================
+ public function get(string $attribute) {
+ return $this->{$attribute} ?? NULL;
+ }
+
+ #===============================================================================
+ # Set attribute
+ #===============================================================================
+ public function set(string $attribute, $value) {
+ return $this->{$attribute} = $value;
+ }
+
+ #===============================================================================
+ # Return ID
+ #===============================================================================
+ final public function getID(): int {
+ return $this->id;
+ }
+
+ #===============================================================================
+ # Get all attributes
+ #===============================================================================
+ public function getAll(array $exclude = []): array {
+ $attributes = get_object_vars($this);
+
+ return array_filter($attributes, function($attribute) use($exclude) {
+ return !in_array($attribute, $exclude);
+ }, ARRAY_FILTER_USE_KEY);
+ }
+
+ #===============================================================================
+ # Get array with all non-false attributes
+ #===============================================================================
+ public function getFilteredAttributes(): array {
+ return array_filter(get_object_vars($this), function($value) {
+ return $value !== FALSE;
+ });
+ }
+}
diff --git a/core/namespace/EntityInterface.php b/core/namespace/EntityInterface.php
new file mode 100644
index 0000000..8eaa089
--- /dev/null
+++ b/core/namespace/EntityInterface.php
@@ -0,0 +1,8 @@
+<?php
+interface EntityInterface {
+ public function get(string $attribute);
+ public function set(string $attribute, $value);
+
+ public function getID(): int;
+ public function getAll(array $exclude = []): array;
+}
diff --git a/core/namespace/Item.php b/core/namespace/Item.php
deleted file mode 100644
index 453a3e6..0000000
--- a/core/namespace/Item.php
+++ /dev/null
@@ -1,98 +0,0 @@
-<?php
-abstract class Item implements ItemInterface {
- protected $Database = NULL;
- protected $Attribute = NULL;
- protected $Reflection = NULL;
-
- #===============================================================================
- # Abstract item constructor
- #===============================================================================
- public final function __construct($itemID, \Database $Database) {
- $this->Database = $Database;
-
- $this->Reflection = new ReflectionObject($this);
-
- $attribute = "{$this->Reflection->getNamespaceName()}\\Attribute";
- $exception = "{$this->Reflection->getNamespaceName()}\\Exception";
-
- #===============================================================================
- # Checking if item in database exists
- #===============================================================================
- $Statement = $Database->prepare(sprintf('SELECT * FROM %s WHERE id = ?', $attribute::TABLE));
- $Statement->execute([$itemID]);
-
- #===============================================================================
- # Checking if retrieving data failed
- #===============================================================================
- if(!$this->Attribute = $Statement->fetchObject($attribute)) {
- throw new $exception(sprintf('%s\\Item with ID %s does not exist', $this->Reflection->getNamespaceName(), (int) $itemID));
- }
- }
-
- #===============================================================================
- # Return attribute by name (short hand wrapper)
- #===============================================================================
- public function get($attribute) {
- return $this->Attribute->get($attribute);
- }
-
- #===============================================================================
- # Return Attribute object
- #===============================================================================
- public final function getAttribute(): Attribute {
- return $this->Attribute;
- }
-
- #===============================================================================
- # Return unique ID
- #===============================================================================
- public final function getID(): int {
- return $this->Attribute->get('id');
- }
-
- #===============================================================================
- # Return previous item ID
- #===============================================================================
- public function getPrevID(): int {
- $execute = 'SELECT id FROM %s WHERE time_insert < ? ORDER BY time_insert DESC LIMIT 1';
-
- $attribute = "{$this->Reflection->getNamespaceName()}\\Attribute";
- $Statement = $this->Database->prepare(sprintf($execute, $attribute::TABLE));
-
- if($Statement->execute([$this->Attribute->get('time_insert')])) {
- return $Statement->fetchColumn();
- }
-
- return 0;
- }
-
- #===============================================================================
- # Return next item ID
- #===============================================================================
- public function getNextID(): int {
- $execute = 'SELECT id FROM %s WHERE time_insert > ? ORDER BY time_insert ASC LIMIT 1';
-
- $attribute = "{$this->Reflection->getNamespaceName()}\\Attribute";
- $Statement = $this->Database->prepare(sprintf($execute, $attribute::TABLE));
-
- if($Statement->execute([$this->Attribute->get('time_insert')])) {
- return $Statement->fetchColumn();
- }
-
- return 0;
- }
-
- #===============================================================================
- # Return unique ID based on specific field comparison with value
- #===============================================================================
- public static function getIDByField($field, $value, \Database $Database): int {
- $attribute = (new ReflectionClass(get_called_class()))->getNamespaceName().'\\Attribute';
- $Statement = $Database->prepare('SELECT id FROM '.$attribute::TABLE." WHERE {$field} = ?");
-
- if($Statement->execute([$value])) {
- return $Statement->fetchColumn();
- }
-
- return 0;
- }
-}
diff --git a/core/namespace/ItemFactory.php b/core/namespace/ItemFactory.php
deleted file mode 100644
index d81ff9f..0000000
--- a/core/namespace/ItemFactory.php
+++ /dev/null
@@ -1,23 +0,0 @@
-<?php
-abstract class ItemFactory extends Factory {
-
- #===========================================================================
- # Build instance by ID
- #===========================================================================
- public static function build($itemID): Item {
- if(!$Instance = parent::fetchInstance($itemID)) {
- $Item = (new ReflectionClass(get_called_class()))->getNamespaceName().'\\Item';
- $Instance = parent::storeInstance($itemID, new $Item($itemID, \Application::getDatabase()));
- }
-
- return $Instance;
- }
-
- #===========================================================================
- # Build instance by slug
- #===========================================================================
- public static function buildBySlug($slug): Item {
- $Item = (new ReflectionClass(get_called_class()))->getNamespaceName().'\\Item';
- return self::build($Item::getIDByField('slug', $slug, \Application::getDatabase()));
- }
-}
diff --git a/core/namespace/ItemInterface.php b/core/namespace/ItemInterface.php
deleted file mode 100644
index efee734..0000000
--- a/core/namespace/ItemInterface.php
+++ /dev/null
@@ -1,4 +0,0 @@
-<?php
-interface ItemInterface {
- public function __construct($itemID, \Database $Database);
-}
diff --git a/core/namespace/Page/Attribute.php b/core/namespace/Page/Attribute.php
deleted file mode 100644
index 05eaa33..0000000
--- a/core/namespace/Page/Attribute.php
+++ /dev/null
@@ -1,22 +0,0 @@
-<?php
-namespace Page;
-
-class Attribute extends \Attribute {
-
- #===============================================================================
- # Pre-Define database table columns
- #===============================================================================
- protected $id = FALSE;
- protected $user = FALSE;
- protected $slug = FALSE;
- protected $name = FALSE;
- protected $body = FALSE;
- protected $argv = FALSE;
- protected $time_insert = FALSE;
- protected $time_update = FALSE;
-
- #===============================================================================
- # Define database table name
- #===============================================================================
- const TABLE = 'page';
-}
diff --git a/core/namespace/Page/Entity.php b/core/namespace/Page/Entity.php
new file mode 100644
index 0000000..6ca5979
--- /dev/null
+++ b/core/namespace/Page/Entity.php
@@ -0,0 +1,13 @@
+<?php
+namespace Page;
+
+class Entity extends \Entity {
+ protected $id = FALSE;
+ protected $user = FALSE;
+ protected $slug = FALSE;
+ protected $name = FALSE;
+ protected $body = FALSE;
+ protected $argv = FALSE;
+ protected $time_insert = FALSE;
+ protected $time_update = FALSE;
+}
diff --git a/core/namespace/Page/Exception.php b/core/namespace/Page/Exception.php
deleted file mode 100644
index c41bddc..0000000
--- a/core/namespace/Page/Exception.php
+++ /dev/null
@@ -1,4 +0,0 @@
-<?php
-namespace Page;
-
-class Exception extends \Exception {}
diff --git a/core/namespace/Page/Factory.php b/core/namespace/Page/Factory.php
deleted file mode 100644
index 2fcc361..0000000
--- a/core/namespace/Page/Factory.php
+++ /dev/null
@@ -1,4 +0,0 @@
-<?php
-namespace Page;
-
-class Factory extends \ItemFactory {}
diff --git a/core/namespace/Page/Item.php b/core/namespace/Page/Item.php
deleted file mode 100644
index cbc99e6..0000000
--- a/core/namespace/Page/Item.php
+++ /dev/null
@@ -1,20 +0,0 @@
-<?php
-namespace Page;
-
-class Item extends \Item {
- const CONFIGURATION = 'PAGE';
-
- #===============================================================================
- # Return unique page IDs for search results
- #===============================================================================
- public static function getSearchResultIDs($search, \Database $Database): array {
- $Statement = $Database->prepare(sprintf("SELECT id FROM %s WHERE
- MATCH(name, body) AGAINST(? IN BOOLEAN MODE) LIMIT 20", Attribute::TABLE));
-
- if($Statement->execute([$search])) {
- return $Statement->fetchAll($Database::FETCH_COLUMN);
- }
-
- return [];
- }
-}
diff --git a/core/namespace/Page/Repository.php b/core/namespace/Page/Repository.php
new file mode 100644
index 0000000..b76ef85
--- /dev/null
+++ b/core/namespace/Page/Repository.php
@@ -0,0 +1,17 @@
+<?php
+namespace Page;
+
+class Repository extends \Repository {
+ public static function getTableName(): string { return 'page'; }
+ public static function getClassName(): string { return 'Page\Entity'; }
+
+ public function getCountByUser(\User\Entity $User): int {
+ $query = 'SELECT COUNT(id) FROM %s WHERE user = ?';
+ $query = sprintf($query, static::getTableName());
+
+ $Statement = $this->Database->prepare($query);
+ $Statement->execute([$User->getID()]);
+
+ return $Statement->fetchColumn();
+ }
+}
diff --git a/core/namespace/Post/Attribute.php b/core/namespace/Post/Attribute.php
deleted file mode 100644
index 20aafae..0000000
--- a/core/namespace/Post/Attribute.php
+++ /dev/null
@@ -1,22 +0,0 @@
-<?php
-namespace Post;
-
-class Attribute extends \Attribute {
-
- #===============================================================================
- # Pre-Define database table columns
- #===============================================================================
- protected $id = FALSE;
- protected $user = FALSE;
- protected $slug = FALSE;
- protected $name = FALSE;
- protected $body = FALSE;
- protected $argv = FALSE;
- protected $time_insert = FALSE;
- protected $time_update = FALSE;
-
- #===============================================================================
- # Define database table name
- #===============================================================================
- const TABLE = 'post';
-}
diff --git a/core/namespace/Post/Entity.php b/core/namespace/Post/Entity.php
new file mode 100644
index 0000000..399f5bb
--- /dev/null
+++ b/core/namespace/Post/Entity.php
@@ -0,0 +1,13 @@
+<?php
+namespace Post;
+
+class Entity extends \Entity {
+ protected $id = FALSE;
+ protected $user = FALSE;
+ protected $slug = FALSE;
+ protected $name = FALSE;
+ protected $body = FALSE;
+ protected $argv = FALSE;
+ protected $time_insert = FALSE;
+ protected $time_update = FALSE;
+}
diff --git a/core/namespace/Post/Exception.php b/core/namespace/Post/Exception.php
deleted file mode 100644
index 29b9345..0000000
--- a/core/namespace/Post/Exception.php
+++ /dev/null
@@ -1,4 +0,0 @@
-<?php
-namespace Post;
-
-class Exception extends \Exception {}
diff --git a/core/namespace/Post/Factory.php b/core/namespace/Post/Factory.php
deleted file mode 100644
index 20b29cc..0000000
--- a/core/namespace/Post/Factory.php
+++ /dev/null
@@ -1,4 +0,0 @@
-<?php
-namespace Post;
-
-class Factory extends \ItemFactory {}
diff --git a/core/namespace/Post/Item.php b/core/namespace/Post/Item.php
deleted file mode 100644
index e8b4615..0000000
--- a/core/namespace/Post/Item.php
+++ /dev/null
@@ -1,27 +0,0 @@
-<?php
-namespace Post;
-
-class Item extends \Item {
- const CONFIGURATION = 'POST';
-
- #===============================================================================
- # Return unique post IDs for search results
- #===============================================================================
- public static function getSearchResultIDs($search, array $date, \Database $Database): array {
- $D = ($D = intval($date[0])) !== 0 ? $D : 'NULL';
- $M = ($M = intval($date[1])) !== 0 ? $M : 'NULL';
- $Y = ($Y = intval($date[2])) !== 0 ? $Y : 'NULL';
-
- $Statement = $Database->prepare(sprintf("SELECT id FROM %s WHERE
- ({$Y} IS NULL OR YEAR(time_insert) = {$Y}) AND
- ({$M} IS NULL OR MONTH(time_insert) = {$M}) AND
- ({$D} IS NULL OR DAY(time_insert) = {$D}) AND
- MATCH(name, body) AGAINST(? IN BOOLEAN MODE) LIMIT 20", Attribute::TABLE));
-
- if($Statement->execute([$search])) {
- return $Statement->fetchAll($Database::FETCH_COLUMN);
- }
-
- return [];
- }
-}
diff --git a/core/namespace/Post/Repository.php b/core/namespace/Post/Repository.php
new file mode 100644
index 0000000..5a3d834
--- /dev/null
+++ b/core/namespace/Post/Repository.php
@@ -0,0 +1,17 @@
+<?php
+namespace Post;
+
+class Repository extends \Repository {
+ public static function getTableName(): string { return 'post'; }
+ public static function getClassName(): string { return 'Post\Entity'; }
+
+ public function getCountByUser(\User\Entity $User): int {
+ $query = 'SELECT COUNT(id) FROM %s WHERE user = ?';
+ $query = sprintf($query, static::getTableName());
+
+ $Statement = $this->Database->prepare($query);
+ $Statement->execute([$User->getID()]);
+
+ return $Statement->fetchColumn();
+ }
+}
diff --git a/core/namespace/Repository.php b/core/namespace/Repository.php
new file mode 100644
index 0000000..2c238b8
--- /dev/null
+++ b/core/namespace/Repository.php
@@ -0,0 +1,323 @@
+<?php
+abstract class Repository {
+ protected $Database;
+ protected $entities = [];
+
+ abstract public static function getTableName(): string;
+ abstract public static function getClassName(): string;
+
+ public function __construct(Database $Database) {
+ $this->Database = $Database;
+ }
+
+ #===============================================================================
+ # Adds an entity to the runtime cache
+ #===============================================================================
+ protected function storeInstance(int $identifier, EntityInterface $Entity) {
+ return $this->entities[$identifier] = $Entity;
+ }
+
+ #===============================================================================
+ # Adds an array of entities to the runtime cache
+ #===============================================================================
+ protected function storeMultipleInstances(array $entities) {
+ foreach($entities as $Entity) {
+ $this->storeInstance($Entity->getID(), $Entity);
+ }
+
+ return $entities;
+ }
+
+ #===============================================================================
+ # Gets an entity from the runtime cache
+ #===============================================================================
+ protected function fetchInstance(int $identifier) {
+ return $this->entities[$identifier] ?? FALSE;
+ }
+
+ #===============================================================================
+ # Removes an entity from the runtime cache
+ #===============================================================================
+ protected function removeInstance(int $identifier) {
+ if(isset($this->cache[$identifier])) {
+ unset($this->cache[$identifier]);
+ }
+ }
+
+ #===========================================================================
+ # Insert entity
+ #===========================================================================
+ public function insert(EntityInterface $Entity): bool {
+ $attributes = $Entity->getFilteredAttributes();
+
+ foreach($attributes as $field => $value) {
+ $fields[] = $field;
+ $values[] = '?';
+ }
+
+ $fields = implode(', ', $fields ?? []);
+ $values = implode(', ', $values ?? []);
+
+ $query = 'INSERT INTO %s (%s) VALUES(%s)';
+ $query = sprintf($query, static::getTableName(), $fields, $values);
+
+ $Statement = $this->Database->prepare($query);
+ return $Statement->execute(array_values($attributes));
+ }
+
+ #===========================================================================
+ # Update entity
+ #===========================================================================
+ public function update(EntityInterface $Entity): bool {
+ $attributes = $Entity->getFilteredAttributes();
+
+ foreach($attributes as $field => $value) {
+ $params[] = "$field = ?";
+ }
+
+ $params = implode(', ', $params ?? []);
+
+ $query = 'UPDATE %s SET %s WHERE id = '.intval($Entity->getID());
+ $query = sprintf($query, static::getTableName(), $params);
+
+ $Statement = $this->Database->prepare($query);
+ return $Statement->execute(array_values($attributes));
+ }
+
+ #===========================================================================
+ # Delete entity
+ #===========================================================================
+ public function delete(EntityInterface $Entity): bool {
+ $query = 'DELETE FROM %s WHERE id = ?';
+ $query = sprintf($query, static::getTableName());
+
+ $Statement = $this->Database->prepare($query);
+ return $Statement->execute([$Entity->getID()]);
+ }
+
+ #===========================================================================
+ # Find entity based on primary key
+ #===========================================================================
+ public function find(int $id): ?EntityInterface {
+ if($Entity = $this->fetchInstance($id)) {
+ return $Entity;
+ }
+
+ return $this->findBy('id', $id);
+ }
+
+ #===============================================================================
+ # Find entity based on specific field comparison
+ #===============================================================================
+ public function findBy(string $field, $value): ?EntityInterface {
+ $query = 'SELECT * FROM %s WHERE %s = ?';
+ $query = sprintf($query, static::getTableName(), $field);
+
+ $Statement = $this->Database->prepare($query);
+ $Statement->execute([$value]);
+
+ if($Entity = $Statement->fetchObject(static::getClassName())) {
+ $this->storeInstance($Entity->getID(), $Entity);
+ return $Entity;
+ }
+
+ return NULL;
+ }
+
+ #===============================================================================
+ # Find previous entitiy
+ #===============================================================================
+ public function findPrev(EntityInterface $Entity): ?EntityInterface {
+ $query = 'SELECT * FROM %s WHERE time_insert < ? ORDER BY time_insert DESC LIMIT 1';
+ $query = sprintf($query, static::getTableName());
+
+ $Statement = $this->Database->prepare($query);
+ $Statement->execute([$Entity->get('time_insert')]);
+
+ if($Entity = $Statement->fetchObject(static::getClassName())) {
+ $this->storeInstance($Entity->getID(), $Entity);
+ return $Entity;
+ }
+
+ return NULL;
+ }
+
+ #===============================================================================
+ # Find next entity
+ #===============================================================================
+ public function findNext(EntityInterface $Entity): ?EntityInterface {
+ $query = 'SELECT * FROM %s WHERE time_insert > ? ORDER BY time_insert ASC LIMIT 1';
+ $query = sprintf($query, static::getTableName());
+
+ $Statement = $this->Database->prepare($query);
+ $Statement->execute([$Entity->get('time_insert')]);
+
+ if($Entity = $Statement->fetchObject(static::getClassName())) {
+ $this->storeInstance($Entity->getID(), $Entity);
+ return $Entity;
+ }
+
+ return NULL;
+ }
+
+ #===========================================================================
+ # Find last (which means the newest) entity
+ #===========================================================================
+ public function getLast(): ?EntityInterface {
+ $query = 'SELECT * FROM %s ORDER BY time_insert DESC LIMIT 1';
+ $query = sprintf($query, static::getTableName());
+
+ $Statement = $this->Database->query($query);
+
+ if($Entity = $Statement->fetchObject(static::getClassName())) {
+ $this->storeInstance($Entity->getID(), $Entity);
+ return $Entity;
+ }
+
+ return NULL;
+ }
+
+ #===========================================================================
+ # Get entity count
+ #===========================================================================
+ public function getCount(): int {
+ $query = 'SELECT COUNT(id) FROM %s';
+ $query = sprintf($query, static::getTableName());
+
+ return $this->Database->query($query)->fetchColumn();
+ }
+
+ #===========================================================================
+ # Get paginated entity list
+ #===========================================================================
+ public function getPaginated(string $order, int $limit, int $offset = 0): array {
+ return $this->getAll([], $order, "$offset,$limit");
+ }
+
+ #===========================================================================
+ # Get all entities
+ #===========================================================================
+ public function getAll(array $filter = [], string $order = null, string $limit = null): array {
+ $select = 'SELECT * FROM '.static::getTableName();
+ $wheres = [];
+ $params = [];
+
+ if(!empty($filter)) {
+ foreach($filter as $column => $value) {
+ $wheres[] = "$column = ?";
+ $params[] = $value;
+ }
+
+ $where = 'WHERE '.implode(' AND ', $wheres);
+ }
+
+ if($order) {
+ $order = "ORDER BY $order";
+ }
+
+ if($limit) {
+ $limit = "LIMIT $limit";
+ }
+
+ $query = "$select %s %s %s";
+ $query = sprintf($query, $where ?? '', $order ?? '', $limit ?? '');
+
+ $Statement = $this->Database->prepare($query);
+ $Statement->execute($params);
+
+ if($entities = $Statement->fetchAll($this->Database::FETCH_CLASS, static::getClassName())) {
+ $this->storeMultipleInstances($entities);
+ return $entities;
+ }
+
+ return [];
+ }
+
+ #===============================================================================
+ # Get entities based on search query
+ #===============================================================================
+ public function search(string $search, array $filter = []): array {
+ if($search === '*') {
+ return $this->getAll([], NULL, 20);
+ }
+
+ if(strlen($filter['year'] ?? '') !== 0) {
+ $extend[] = 'YEAR(time_insert) = ? AND';
+ $params[] = $filter['year'];
+ }
+
+ if(strlen($filter['month'] ?? '') !== 0) {
+ $extend[] = 'MONTH(time_insert) = ? AND';
+ $params[] = $filter['month'];
+ }
+
+ if(strlen($filter['day'] ?? '') !== 0) {
+ $extend[] = 'DAY(time_insert) = ? AND';
+ $params[] = $filter['day'];
+ }
+
+ $dateparts = implode(' ', $extend ?? []);
+
+ $query = 'SELECT * FROM %s WHERE %s MATCH(name, body)
+ AGAINST(? IN BOOLEAN MODE) LIMIT 20';
+ $query = sprintf($query, static::getTableName(), $dateparts);
+
+ $Statement = $this->Database->prepare($query);
+ $Statement->execute(array_merge($params ?? [], [$search]));
+
+ if($entities = $Statement->fetchAll($this->Database::FETCH_CLASS, static::getClassName())) {
+ $this->storeMultipleInstances($entities);
+ return $entities;
+ }
+
+ return [];
+ }
+
+ #===============================================================================
+ # Get a list of distinct days
+ #===============================================================================
+ public function getDistinctDays(): array {
+ $query = 'SELECT DISTINCT DAY(time_insert) AS d FROM %s ORDER BY d';
+ $query = sprintf($query, static::getTableName());
+
+ $Statement = $this->Database->query($query);
+
+ if($result = $Statement->fetchAll($this->Database::FETCH_COLUMN)) {
+ return $result;
+ }
+
+ return [];
+ }
+
+ #===============================================================================
+ # Get a list of distinct months
+ #===============================================================================
+ public function getDistinctMonths(): array {
+ $query = 'SELECT DISTINCT MONTH(time_insert) AS m FROM %s ORDER BY m';
+ $query = sprintf($query, static::getTableName());
+
+ $Statement = $this->Database->query($query);
+
+ if($result = $Statement->fetchAll($this->Database::FETCH_COLUMN)) {
+ return $result;
+ }
+
+ return [];
+ }
+
+ #===============================================================================
+ # Get a list of distinct years
+ #===============================================================================
+ public function getDistinctYears(): array {
+ $query = 'SELECT DISTINCT YEAR(time_insert) AS y FROM %s ORDER BY y';
+ $query = sprintf($query, static::getTableName());
+
+ $Statement = $this->Database->query($query);
+
+ if($result = $Statement->fetchAll($this->Database::FETCH_COLUMN)) {
+ return $result;
+ }
+
+ return [];
+ }
+}
diff --git a/core/namespace/User/Attribute.php b/core/namespace/User/Attribute.php
deleted file mode 100644
index ccd31b5..0000000
--- a/core/namespace/User/Attribute.php
+++ /dev/null
@@ -1,24 +0,0 @@
-<?php
-namespace User;
-
-class Attribute extends \Attribute {
-
- #===============================================================================
- # Pre-Define database table columns
- #===============================================================================
- protected $id = FALSE;
- protected $slug = FALSE;
- protected $username = FALSE;
- protected $password = FALSE;
- protected $fullname = FALSE;
- protected $mailaddr = FALSE;
- protected $body = FALSE;
- protected $argv = FALSE;
- protected $time_insert = FALSE;
- protected $time_update = FALSE;
-
- #===============================================================================
- # Define database table name
- #===============================================================================
- const TABLE = 'user';
-}
diff --git a/core/namespace/User/Entity.php b/core/namespace/User/Entity.php
new file mode 100644
index 0000000..fdfaf9e
--- /dev/null
+++ b/core/namespace/User/Entity.php
@@ -0,0 +1,15 @@
+<?php
+namespace User;
+
+class Entity extends \Entity {
+ protected $id = FALSE;
+ protected $slug = FALSE;
+ protected $username = FALSE;
+ protected $password = FALSE;
+ protected $fullname = FALSE;
+ protected $mailaddr = FALSE;
+ protected $body = FALSE;
+ protected $argv = FALSE;
+ protected $time_insert = FALSE;
+ protected $time_update = FALSE;
+}
diff --git a/core/namespace/User/Exception.php b/core/namespace/User/Exception.php
deleted file mode 100644
index fdbe733..0000000
--- a/core/namespace/User/Exception.php
+++ /dev/null
@@ -1,4 +0,0 @@
-<?php
-namespace User;
-
-class Exception extends \Exception {}
diff --git a/core/namespace/User/Factory.php b/core/namespace/User/Factory.php
deleted file mode 100644
index 81930e6..0000000
--- a/core/namespace/User/Factory.php
+++ /dev/null
@@ -1,8 +0,0 @@
-<?php
-namespace User;
-
-class Factory extends \ItemFactory {
- public static function buildByUsername($username): \Item {
- return self::build(Item::getIDByField('username', $username, \Application::getDatabase()));
- }
-}
diff --git a/core/namespace/User/Item.php b/core/namespace/User/Item.php
deleted file mode 100644
index 5039287..0000000
--- a/core/namespace/User/Item.php
+++ /dev/null
@@ -1,6 +0,0 @@
-<?php
-namespace User;
-
-class Item extends \Item {
- const CONFIGURATION = 'USER';
-}
diff --git a/core/namespace/User/Repository.php b/core/namespace/User/Repository.php
new file mode 100644
index 0000000..59205b3
--- /dev/null
+++ b/core/namespace/User/Repository.php
@@ -0,0 +1,7 @@
+<?php
+namespace User;
+
+class Repository extends \Repository {
+ public static function getTableName(): string { return 'user'; }
+ public static function getClassName(): string { return 'User\Entity'; }
+}