From c39e544a3a7d4c0f9b55c676e8d268b2ab312df6 Mon Sep 17 00:00:00 2001 From: Awilum Date: Sat, 22 Dec 2018 13:48:41 +0300 Subject: [PATCH] Infrastructure changes: to improve engine flexibility was decided to use entity name Entries/Entry instead of entity name Pages/Page --- flextype/Content.php | 490 ---------------------------------- flextype/Entry.php | 490 ++++++++++++++++++++++++++++++++++ flextype/Flextype.php | 4 +- flextype/config/settings.yaml | 2 +- 4 files changed, 493 insertions(+), 493 deletions(-) delete mode 100755 flextype/Content.php create mode 100755 flextype/Entry.php diff --git a/flextype/Content.php b/flextype/Content.php deleted file mode 100755 index 99632bed..00000000 --- a/flextype/Content.php +++ /dev/null @@ -1,490 +0,0 @@ - - * @link http://flextype.org - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Flextype; - -use Flextype\Component\Arr\Arr; -use Flextype\Component\Http\Http; -use Flextype\Component\Filesystem\Filesystem; -use Flextype\Component\Event\Event; -use Flextype\Component\Registry\Registry; -use Thunder\Shortcode\ShortcodeFacade; -use Thunder\Shortcode\Shortcode\ShortcodeInterface; - -class Content -{ - /** - * An instance of the Content class - * - * @var object - * @access private - */ - private static $instance = null; - - /** - * Shortcode object - * - * @var object - * @access private - */ - private static $shortcode = null; - - /** - * Current page data array - * - * @var array - * @access private - */ - private static $page = []; - - /** - * Private clone method to enforce singleton behavior. - * - * @access private - */ - private function __clone() - { - } - - /** - * Private wakeup method to enforce singleton behavior. - * - * @access private - */ - private function __wakeup() - { - } - - /** - * Private construct method to enforce singleton behavior. - * - * @access private - */ - private function __construct() - { - Content::init(); - } - - /** - * Init Content - * - * @access private - * @return void - */ - private static function init() : void - { - Content::processCurrentPage(); - } - - /** - * Process Current Page - * - * @access private - * @return void - */ - private static function processCurrentPage() : void - { - // Event: The page is not processed and not sent to the display. - Event::dispatch('onCurrentPageBeforeProcessed'); - - // Init Parsers - Content::initParsers(); - - // Event: The page has been not loaded. - Event::dispatch('onCurrentPageBeforeLoaded'); - - // Set current requested page data to global $page array - Content::$page = Content::getPage(Http::getUriString()); - - // Event: The page has been fully processed and not sent to the display. - Event::dispatch('onCurrentPageBeforeDisplayed'); - - // Display page for current requested url - Content::displayCurrentPage(); - - // Event: The page has been fully processed and sent to the display. - Event::dispatch('onCurrentPageAfterProcessed'); - } - - /** - * Get current page - * - * $page = Content::getCurrentPage(); - * - * @access public - * @return array - */ - public static function getCurrentPage() : array - { - return Content::$page; - } - - /** - * Update current page - * - * Content::updateCurrentPage('title', 'New page title'); - * - * @access public - * @param string $path Array path - * @param mixed $value Value to set - * @return void - */ - public static function updateCurrentPage(string $path, $value) : void - { - Arr::set(Content::$page, $path, $value); - } - - /** - * Get page - * - * $page = Content::getPage('projects'); - * - * @access public - * @param string $url Page url - * @param bool $raw Raw or not raw content - * @param bool $hidden Get hidden pages - * @return array|string - */ - public static function getPage(string $url = '', bool $raw = false, bool $hidden = false) - { - // If $url is empty then set path for default main page - if ($url === '') { - $file_path = PATH['pages'] . '/' . Registry::get('settings.pages.main') . '/page.html'; - } else { - $file_path = PATH['pages'] . '/' . $url . '/page.html'; - } - - // If page exist - if (Filesystem::fileExists($file_path)) { - $page_cache_id = md5('page' . $file_path . filemtime($file_path) . (($raw === true) ? 'true' : 'false') . (($hidden === true) ? 'true' : 'false')); - - // Try to get the page from cache - if (Cache::contains($page_cache_id)) { - return Cache::fetch($page_cache_id); - } else { - - // Get raw page if $raw is true - if ($raw) { - $page = Content::processPage($file_path, true); - } else { - $page = Content::processPage($file_path); - - // Don't proccess 404 page if we want to get hidden page. - if ($hidden === false) { - - // Get 404 page if page is not published - if (isset($page['visibility']) && ($page['visibility'] === 'draft' || $page['visibility'] === 'hidden')) { - $page = Content::getError404Page(); - } - } - } - - Cache::save($page_cache_id, $page); - return $page; - } - } else { - return Content::getError404Page(); - } - } - - private static function getError404Page() : array - { - Http::setResponseStatus(404); - - $page['title'] = Registry::get('settings.pages.error404.title'); - $page['description'] = Registry::get('settings.pages.error404.description'); - $page['content'] = Registry::get('settings.pages.error404.content'); - $page['template'] = Registry::get('settings.pages.error404.template'); - - return $page; - } - - /** - * Get pages - * - * // Get list of subpages for page 'projects' - * $pages = Content::getPages('projects'); - * - * // Get list of subpages for page 'projects' and order by date and order type DESC - * $pages = Content::getPages('projects', false, 'date', 'DESC'); - * - * @access public - * @param string $url Page url - * @param bool $raw Raw or not raw content - * @param string $order_by Order type - * @param int $offset Offset - * @param int $length Length - * @return array - */ - public static function getPages(string $url = '', bool $raw = false, string $order_by = 'date', string $order_type = 'DESC', int $offset = null, int $length = null, bool $multilevel = true) : array - { - // if $url is empty then set path for defined main page - if ($url === '') { - $file_path = PATH['pages'] . '/'; - } else { - $file_path = PATH['pages'] . '/' . $url; - } - - // Pages array where founded pages will stored - $pages = []; - - // Pages cache id - $pages_cache_id = ''; - - // Get pages for $url - // If $url is empty then we want to have a list of pages for /pages dir. - if ($url === '') { - - // Get pages list - $pages_list = Filesystem::getFilesList($file_path, 'html', true, $multilevel); - - // Create pages cached id - foreach ($pages_list as $key => $page) { - $pages_cache_id .= md5('pages' . $page . filemtime($page) . (($raw === true) ? 'true' : 'false') . $order_by . $order_type . $offset . $length); - } - - if (Cache::contains($pages_cache_id)) { - $pages = Cache::fetch($pages_cache_id); - } else { - // Create pages array from pages list - foreach ($pages_list as $key => $page) { - $pages[$key] = Content::processPage($page, $raw); - } - - Cache::save($pages_cache_id, $pages); - } - } else { - - // Get pages list - $pages_list = Filesystem::getFilesList($file_path, 'html', true, $multilevel); - - // Create pages cached id - foreach ($pages_list as $key => $page) { - if (strpos($page, $url . '/page.html') !== false) { - // ignore ... - } else { - $pages_cache_id .= md5('pages' . $page . filemtime($page) . (($raw === true) ? 'true' : 'false') . $order_by . $order_type . $offset . $length); - } - } - - if (Cache::contains($pages_cache_id)) { - $pages = Cache::fetch($pages_cache_id); - } else { - // Create pages array from pages list and ignore current requested page - foreach ($pages_list as $key => $page) { - if (strpos($page, $url . '/page.html') !== false) { - // ignore ... - } else { - $pages[$key] = Content::processPage($page, $raw); - } - } - - Cache::save($pages_cache_id, $pages); - } - } - - // Sort and Slice pages if $raw === false - if (count($pages) > 0) { - if (!$raw) { - $pages = Arr::sort($pages, $order_by, $order_type); - - if ($offset !== null && $length !== null) { - $pages = array_slice($pages, $offset, $length); - } - } - } - - // Return pages array - return $pages; - } - - /** - * Returns $shortcode object - * - * @access public - * @return object - */ - public static function shortcode() : ShortcodeFacade - { - return Content::$shortcode; - } - - /** - * Front matter parser - * - * $content = Content::frontMatterParser($content); - * - * @param string $content Content to parse - * @access public - * @return array - */ - public static function frontMatterParser(string $content) : array - { - $parts = preg_split('/^[\s\r\n]?---[\s\r\n]?$/sm', PHP_EOL.ltrim($content)); - - if (count($parts) < 3) return ['matter' => [], 'body' => $content]; - - return ['matter' => trim($parts[1]), 'body' => implode(PHP_EOL.'---'.PHP_EOL, array_slice($parts, 2))]; - } - - /** - * Process page - * - * $page = Content::processPage(PATH['pages'] . '/home/page.html'); - * - * @access public - * @param string $file_path File path - * @param bool $raw Raw or not raw content - * @param bool $ignore_content Ignore content parsing - * @return array|string - */ - public static function processPage(string $file_path, bool $raw = false, bool $ignore_content = false) - { - // Get page from file - $page = trim(Filesystem::getFileContent($file_path)); - - // Return raw page if $raw is true - if ($raw) { - return $page; - } else { - - // Create $page_frontmatter and $page_content - $page = Content::frontMatterParser($page); - $page_frontmatter = $page['matter']; - $page_content = $page['body']; - - // Create empty $_page - $_page = []; - - // Process $page_frontmatter with YAML and Shortcodes parsers - $_page = YamlParser::decode(Content::processShortcodes($page_frontmatter)); - - // Create page url item - $url = str_replace(PATH['pages'], Http::getBaseUrl(), $file_path); - $url = str_replace('page.html', '', $url); - $url = str_replace('.html', '', $url); - $url = str_replace('\\', '/', $url); - $url = str_replace('///', '/', $url); - $url = str_replace('//', '/', $url); - $url = str_replace('http:/', 'http://', $url); - $url = str_replace('https:/', 'https://', $url); - $url = rtrim($url, '/'); - $_page['url'] = $url; - - // Create page slug item - $url = str_replace(Http::getBaseUrl(), '', $url); - $url = ltrim($url, '/'); - $url = rtrim($url, '/'); - $_page['slug'] = str_replace(Http::getBaseUrl(), '', $url); - - // Create page template item - $_page['template'] = $_page['template'] ?? 'default'; - - // Create page date item - $_page['date'] = $_page['date'] ?? date(Registry::get('settings.date_format'), filemtime($file_path)); - - // Create page content item with $page_content - if ($ignore_content) { - $_page['content'] = $page_content; - } else { - $_page['content'] = Content::processContent($page_content); - } - - // Return page - return $_page; - } - } - - /** - * Process shortcodes - * - * $content = Content::processShortcodes($content); - * - * @access public - * @param string $content Content to parse - * @return string - */ - public static function processShortcodes(string $content) : string - { - return Content::shortcode()->process($content); - } - - /** - * Process content with markdown and shortcodes processors - * - * $content = Content::processContent($content); - * - * @access public - * @param string $content Content to parse - * @return string - */ - public static function processContent(string $content) : string - { - return Content::processShortcodes($content); - } - - /** - * Init Parsers - * - * @access private - * @return void - */ - private static function initParsers() : void - { - // Init Shortcodes - Content::initShortcodes(); - } - - /** - * Init Shortcodes - * - * @access private - * @return void - */ - private static function initShortcodes() : void - { - // Create Shortcode Parser object - Content::$shortcode = new ShortcodeFacade(); - - // Event: Shortcodes initialized and now we can add our custom shortcodes - Event::dispatch('onShortcodesInitialized'); - } - - /** - * Display current page - * - * @access private - * @return void - */ - private static function displayCurrentPage() : void - { - Http::setRequestHeaders('Content-Type: text/html; charset='.Registry::get('settings.charset')); - Themes::view(empty(Content::$page['template']) ? 'templates/default' : 'templates/' . Content::$page['template']) - ->assign('page', Content::$page, true) - ->display(); - } - - /** - * Get the Content instance. - * - * @access public - * @return object - */ - public static function getInstance() - { - if (is_null(Content::$instance)) { - Content::$instance = new self; - } - - return Content::$instance; - } -} diff --git a/flextype/Entry.php b/flextype/Entry.php new file mode 100755 index 00000000..28db2fe2 --- /dev/null +++ b/flextype/Entry.php @@ -0,0 +1,490 @@ + + * @link http://flextype.org + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Flextype; + +use Flextype\Component\Arr\Arr; +use Flextype\Component\Http\Http; +use Flextype\Component\Filesystem\Filesystem; +use Flextype\Component\Event\Event; +use Flextype\Component\Registry\Registry; +use Thunder\Shortcode\ShortcodeFacade; +use Thunder\Shortcode\Shortcode\ShortcodeInterface; + +class Entry +{ + /** + * An instance of the Entry class + * + * @var object + * @access private + */ + private static $instance = null; + + /** + * Shortcode object + * + * @var object + * @access private + */ + private static $shortcode = null; + + /** + * Current entry data array + * + * @var array + * @access private + */ + private static $entry = []; + + /** + * Private clone method to enforce singleton behavior. + * + * @access private + */ + private function __clone() + { + } + + /** + * Private wakeup method to enforce singleton behavior. + * + * @access private + */ + private function __wakeup() + { + } + + /** + * Private construct method to enforce singleton behavior. + * + * @access private + */ + private function __construct() + { + Entry::init(); + } + + /** + * Init Entry + * + * @access private + * @return void + */ + private static function init() : void + { + Entry::processCurrentEntry(); + } + + /** + * Process Current Entry + * + * @access private + * @return void + */ + private static function processCurrentEntry() : void + { + // Event: The entry is not processed and not sent to the display. + Event::dispatch('onCurrentEntryBeforeProcessed'); + + // Init Parsers + Entry::initParsers(); + + // Event: The entry has been not loaded. + Event::dispatch('onCurrentEntryBeforeLoaded'); + + // Set current requested entry data to global $entry array + Entry::$entry = Entry::getEntry(Http::getUriString()); + + // Event: The entry has been fully processed and not sent to the display. + Event::dispatch('onCurrentEntryBeforeDisplayed'); + + // Display entry for current requested url + Entry::displayCurrentEntry(); + + // Event: The entry has been fully processed and sent to the display. + Event::dispatch('onCurrentEntryAfterProcessed'); + } + + /** + * Get current entry + * + * $entry = Entry::getCurrentPage(); + * + * @access public + * @return array + */ + public static function getCurrentEntry() : array + { + return Entry::$entry; + } + + /** + * Update current entry + * + * Entry::updateCurrentPage('title', 'New entry title'); + * + * @access public + * @param string $path Array path + * @param mixed $value Value to set + * @return void + */ + public static function updateCurrentEntry(string $path, $value) : void + { + Arr::set(Entry::$entry, $path, $value); + } + + /** + * Get entry + * + * $entry = Entry::getEntry('projects'); + * + * @access public + * @param string $url Page url + * @param bool $raw Raw or not raw content + * @param bool $hidden Get hidden entries + * @return array|string + */ + public static function getEntry(string $url = '', bool $raw = false, bool $hidden = false) + { + // If $url is empty then set path for default main entry + if ($url === '') { + $file_path = PATH['entries'] . '/' . Registry::get('settings.entries.main') . '/entry.html'; + } else { + $file_path = PATH['entries'] . '/' . $url . '/entry.html'; + } + + // If entry exist + if (Filesystem::fileExists($file_path)) { + $entry_cache_id = md5('entry' . $file_path . filemtime($file_path) . (($raw === true) ? 'true' : 'false') . (($hidden === true) ? 'true' : 'false')); + + // Try to get the entry from cache + if (Cache::contains($entry_cache_id)) { + return Cache::fetch($entry_cache_id); + } else { + + // Get raw entry if $raw is true + if ($raw) { + $entry = Entry::processEntry($file_path, true); + } else { + $entry = Entry::processEntry($file_path); + + // Don't proccess 404 entry if we want to get hidden entry. + if ($hidden === false) { + + // Get 404 entry if entry is not published + if (isset($entry['visibility']) && ($entry['visibility'] === 'draft' || $entry['visibility'] === 'hidden')) { + $entry = Entry::getError404Entry(); + } + } + } + + Cache::save($entry_cache_id, $entry); + return $entry; + } + } else { + return Entry::getError404Entry(); + } + } + + private static function getError404Entry() : array + { + Http::setResponseStatus(404); + + $entry['title'] = Registry::get('settings.entries.error404.title'); + $entry['description'] = Registry::get('settings.entries.error404.description'); + $entry['content'] = Registry::get('settings.entries.error404.content'); + $entry['template'] = Registry::get('settings.entries.error404.template'); + + return $entry; + } + + /** + * Get entries + * + * // Get list of subentries for entry 'projects' + * $entries = Entry::getEntries('projects'); + * + * // Get list of subentries for entry 'projects' and order by date and order type DESC + * $entries = Entry::getEntries('projects', false, 'date', 'DESC'); + * + * @access public + * @param string $url Page url + * @param bool $raw Raw or not raw content + * @param string $order_by Order type + * @param int $offset Offset + * @param int $length Length + * @return array + */ + public static function getEntries(string $url = '', bool $raw = false, string $order_by = 'date', string $order_type = 'DESC', int $offset = null, int $length = null, bool $multilevel = true) : array + { + // if $url is empty then set path for defined main entry + if ($url === '') { + $file_path = PATH['entries'] . '/'; + } else { + $file_path = PATH['entries'] . '/' . $url; + } + + // Pages array where founded entries will stored + $entries = []; + + // Pages cache id + $entry_cache_id = ''; + + // Get entries for $url + // If $url is empty then we want to have a list of entries for /entries dir. + if ($url === '') { + + // Get entries list + $entries_list = Filesystem::getFilesList($file_path, 'html', true, $multilevel); + + // Create entries cached id + foreach ($entries_list as $key => $entry) { + $entry_cache_id .= md5('entries' . $entry . filemtime($entry) . (($raw === true) ? 'true' : 'false') . $order_by . $order_type . $offset . $length); + } + + if (Cache::contains($entry_cache_id)) { + $entries = Cache::fetch($entry_cache_id); + } else { + // Create entries array from entries list + foreach ($entries_list as $key => $entry) { + $entries[$key] = Entry::processEntry($entry, $raw); + } + + Cache::save($entry_cache_id, $entries); + } + } else { + + // Get entries list + $entries_list = Filesystem::getFilesList($file_path, 'html', true, $multilevel); + + // Create entries cached id + foreach ($entries_list as $key => $entry) { + if (strpos($entry, $url . '/entry.html') !== false) { + // ignore ... + } else { + $entry_cache_id .= md5('entries' . $entry . filemtime($entry) . (($raw === true) ? 'true' : 'false') . $order_by . $order_type . $offset . $length); + } + } + + if (Cache::contains($entry_cache_id)) { + $entries = Cache::fetch($entry_cache_id); + } else { + // Create entries array from entries list and ignore current requested entry + foreach ($entries_list as $key => $entry) { + if (strpos($entry, $url . '/entry.html') !== false) { + // ignore ... + } else { + $entries[$key] = Entry::processEntry($entry, $raw); + } + } + + Cache::save($entry_cache_id, $entries); + } + } + + // Sort and Slice entries if $raw === false + if (count($entries) > 0) { + if (!$raw) { + $entries = Arr::sort($entries, $order_by, $order_type); + + if ($offset !== null && $length !== null) { + $entries = array_slice($entries, $offset, $length); + } + } + } + + // Return entries array + return $entries; + } + + /** + * Returns $shortcode object + * + * @access public + * @return object + */ + public static function shortcode() : ShortcodeFacade + { + return Entry::$shortcode; + } + + /** + * Front matter parser + * + * $content = Entry::frontMatterParser($content); + * + * @param string $content Content to parse + * @access public + * @return array + */ + public static function frontMatterParser(string $content) : array + { + $parts = preg_split('/^[\s\r\n]?---[\s\r\n]?$/sm', PHP_EOL.ltrim($content)); + + if (count($parts) < 3) return ['matter' => [], 'body' => $content]; + + return ['matter' => trim($parts[1]), 'body' => implode(PHP_EOL.'---'.PHP_EOL, array_slice($parts, 2))]; + } + + /** + * Process entry + * + * $entry = Entry::processEntry(PATH['entries'] . '/home/entry.html'); + * + * @access public + * @param string $file_path File path + * @param bool $raw Raw or not raw content + * @param bool $ignore_content Ignore content parsing + * @return array|string + */ + public static function processEntry(string $file_path, bool $raw = false, bool $ignore_content = false) + { + // Get entry from file + $entry = trim(Filesystem::getFileContent($file_path)); + + // Return raw entry if $raw is true + if ($raw) { + return $entry; + } else { + + // Create $entry_frontmatter and $entry_content + $entry = Entry::frontMatterParser($entry); + $entry_frontmatter = $entry['matter']; + $entry_content = $entry['body']; + + // Create empty $_entry + $_entry = []; + + // Process $entry_frontmatter with YAML and Shortcodes parsers + $_entry = YamlParser::decode(Entry::processShortcodes($entry_frontmatter)); + + // Create entry url item + $url = str_replace(PATH['entries'], Http::getBaseUrl(), $file_path); + $url = str_replace('entry.html', '', $url); + $url = str_replace('.html', '', $url); + $url = str_replace('\\', '/', $url); + $url = str_replace('///', '/', $url); + $url = str_replace('//', '/', $url); + $url = str_replace('http:/', 'http://', $url); + $url = str_replace('https:/', 'https://', $url); + $url = rtrim($url, '/'); + $_entry['url'] = $url; + + // Create entry slug item + $url = str_replace(Http::getBaseUrl(), '', $url); + $url = ltrim($url, '/'); + $url = rtrim($url, '/'); + $_entry['slug'] = str_replace(Http::getBaseUrl(), '', $url); + + // Create entry template item + $_entry['template'] = $_entry['template'] ?? 'default'; + + // Create entry date item + $_entry['date'] = $_entry['date'] ?? date(Registry::get('settings.date_format'), filemtime($file_path)); + + // Create entry content item with $entry_content + if ($ignore_content) { + $_entry['content'] = $entry_content; + } else { + $_entry['content'] = Entry::processContent($entry_content); + } + + // Return entry + return $_entry; + } + } + + /** + * Process shortcodes + * + * $content = Entry::processShortcodes($content); + * + * @access public + * @param string $content Content to parse + * @return string + */ + public static function processShortcodes(string $content) : string + { + return Entry::shortcode()->process($content); + } + + /** + * Process content with markdown and shortcodes processors + * + * $content = Entry::processContent($content); + * + * @access public + * @param string $content Content to parse + * @return string + */ + public static function processContent(string $content) : string + { + return Entry::processShortcodes($content); + } + + /** + * Init Parsers + * + * @access private + * @return void + */ + private static function initParsers() : void + { + // Init Shortcodes + Entry::initShortcodes(); + } + + /** + * Init Shortcodes + * + * @access private + * @return void + */ + private static function initShortcodes() : void + { + // Create Shortcode Parser object + Entry::$shortcode = new ShortcodeFacade(); + + // Event: Shortcodes initialized and now we can add our custom shortcodes + Event::dispatch('onShortcodesInitialized'); + } + + /** + * Display current entry + * + * @access private + * @return void + */ + private static function displayCurrentEntry() : void + { + Http::setRequestHeaders('Content-Type: text/html; charset='.Registry::get('settings.charset')); + Themes::view(empty(Entry::$entry['template']) ? 'templates/default' : 'templates/' . Entry::$entry['template']) + ->assign('entry', Entry::$entry, true) + ->display(); + } + + /** + * Get the Content instance. + * + * @access public + * @return object + */ + public static function getInstance() + { + if (is_null(Entry::$instance)) { + Entry::$instance = new self; + } + + return Entry::$instance; + } +} diff --git a/flextype/Flextype.php b/flextype/Flextype.php index f93e9274..92502801 100755 --- a/flextype/Flextype.php +++ b/flextype/Flextype.php @@ -98,8 +98,8 @@ class Flextype // Get Plugins Instance Plugins::getInstance(); - // Get Content Instance - Content::getInstance(); + // Get Entry Instance + Entry::getInstance(); // Flush (send) the output buffer and turn off output buffering ob_end_flush(); diff --git a/flextype/config/settings.yaml b/flextype/config/settings.yaml index aae96b59..39ecf767 100644 --- a/flextype/config/settings.yaml +++ b/flextype/config/settings.yaml @@ -37,7 +37,7 @@ theme: simple locale: "en" # The default page to use for the homepage. -pages: +entries: main: home error404: title: "Error 404"