1
0
mirror of https://github.com/monstra-cms/monstra.git synced 2025-07-31 18:30:20 +02:00

#431 general structure changes

This commit is contained in:
Awilum
2018-03-05 00:22:55 +03:00
parent a616757ee0
commit 0b94ad6d1e
19 changed files with 390 additions and 833 deletions

View File

@@ -16,16 +16,21 @@
"issues": "https://github.com/monstra-cms/monstra/issues"
},
"require": {
"php": ">=5.5.9",
"erusev/parsedown-extra": "0.7.*",
"mustangostang/spyc" : "0.5.*",
"doctrine/cache": "1.6.*",
"doctrine/collections": "1.3",
"php": ">=7.1.3",
"erusev/parsedown": "1.7.0",
"erusev/parsedown-extra": "0.7.1",
"doctrine/cache": "1.7.1",
"symfony/yaml": "4.0.4",
"symfony/console": "4.0.4",
"symfony/filesystem": "4.0.4",
"symfony/finder": "4.0.4",
"symfony/event-dispatcher": "4.0.5",
"pimple/pimple": "3.2.3",
"force/session" : "*",
"force/filesystem" : "*",
"force/shortcode" : "*",
"force/arr" : "*",
"force/http" : "*",
"force/shortcode" : "*",
"force/filesystem" : "*",
"force/token" : "*",
"force/url" : "*"
},
@@ -34,10 +39,7 @@
"Monstra"
],
"files": [
"Monstra/boot/defines.php",
"Monstra/boot/shortcodes.php",
"Monstra/boot/filters.php",
"Monstra/boot/actions.php"
"monstra/boot/defines.php"
]
}
}

View File

@@ -1,10 +1,14 @@
<?php
// Monstra requires PHP 5.5.9 or greater
version_compare(PHP_VERSION, "5.5.9", "<") and exit("Monstra requires PHP 5.5.9 or greater.");
namespace Monstra;
// Register the auto-loader.
require_once __DIR__ . '/vendor/autoload.php';
$loader = require __DIR__ . '/vendor/autoload.php';
// Initialize Monstra Application
Monstra::init();
// Check PHP Version
version_compare($ver = PHP_VERSION, $req = '7.1.3', '<') and exit(sprintf('You are running PHP %s, but Monstra needs at least <strong>PHP %s</strong> to run.', $ver, $req));
// Get Monstra Instance
$app = Monstra::instance();
// Run Monstra Application
$app->run();

View File

@@ -1,113 +0,0 @@
<?php
/**
* This file is part of the Monstra.
*
* (c) Romanenko Sergey / Awilum <awilum@msn.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Action
{
/**
* Actions
*
* @var array
* @access protected
*/
protected static $actions = [];
/**
* Protected constructor since this is a static class.
*
* @access protected
*/
protected function __construct()
{
// Nothing here
}
/**
* Hooks a function on to a specific action.
*
* <code>
* // Hooks a function "newLink" on to a "footer" action.
* Action::add('footer', 'newLink', 10);
*
* function newLink() {
* echo '<a href="#">My link</a>';
* }
* </code>
*
* @access public
* @param string $action_name Action name
* @param mixed $added_function Added function
* @param integer $priority Priority. Default is 10
* @param array $args Arguments
*/
public static function add($action_name, $added_function, $priority = 10, array $args = null)
{
// Hooks a function on to a specific action.
static::$actions[] = array(
'action_name' => (string) $action_name,
'function' => $added_function,
'priority' => (int) $priority,
'args' => $args
);
}
/**
* Run functions hooked on a specific action hook.
*
* <code>
* // Run functions hooked on a "footer" action hook.
* Action::run('footer');
* </code>
*
* @access public
* @param string $action_name Action name
* @param array $args Arguments
* @param boolean $return Return data or not. Default is false
* @return mixed
*/
public static function run($action_name, $args = [], $return = false)
{
// Redefine arguments
$action_name = (string) $action_name;
$return = (bool) $return;
// Run action
if (count(static::$actions) > 0) {
// Sort actions by priority
$actions = Arr::subvalSort(static::$actions, 'priority');
// Loop through $actions array
foreach ($actions as $action) {
// Execute specific action
if ($action['action_name'] == $action_name) {
// isset arguments ?
if (isset($args)) {
// Return or Render specific action results ?
if ($return) {
return call_user_func_array($action['function'], $args);
} else {
call_user_func_array($action['function'], $args);
}
} else {
if ($return) {
return call_user_func_array($action['function'], $action['args']);
} else {
call_user_func_array($action['function'], $action['args']);
}
}
}
}
}
}
}

View File

@@ -1,102 +0,0 @@
<?php
/**
* This file is part of the Monstra.
*
* (c) Romanenko Sergey / Awilum <awilum@msn.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Blocks
{
/**
* An instance of the Blocks class
*
* @var object
* @access protected
*/
protected static $instance = null;
/**
* Protected clone method to enforce singleton behavior.
*
* @access protected
*/
protected function __clone()
{
// Nothing here.
}
/**
* Constructor.
*
* @access protected
*/
protected function __construct()
{
$blocks_cache_id = '';
$blocks = File::scan(CONTENT_PATH . '/blocks', 'md');
if ($blocks) {
foreach ($blocks as $block) {
$blocks_cache_id .= filemtime($block);
}
// Create Unique Cache ID for Block
$blocks_cache_id = md5('blocks' . ROOT_DIR . $blocks_cache_id);
}
if (Cache::driver()->contains($blocks_cache_id)) {
Cache::driver()->fetch($blocks_cache_id);
} else {
Config::set('site.pages.flush_cache', true);
Cache::driver()->save($blocks_cache_id, $blocks_cache_id);
}
}
/**
* Get Page Block
*
* <code>
* $block = Blocks::get('my-block');
* </code>
*
* @access public
* @param string $name Block name
* @return string Formatted Block content
*/
public static function get($name)
{
if (File::exists($block_path = CONTENT_PATH .'/blocks/' . $name . '.md')) {
// Create Unique Cache ID for Block
$block_cache_id = md5('block' . ROOT_DIR . $block_path . filemtime($block_path));
if (Cache::driver()->contains($block_cache_id)) {
return Cache::driver()->fetch($block_cache_id);
} else {
Cache::driver()->save($block_cache_id, $block = Filter::apply('content', file_get_contents($block_path)));
return $block;
}
} else {
return 'Block '.$name.' is not found!';
}
}
/**
* Initialize Monstra Blocks
*
* <code>
* Blocks::init();
* </code>
*
* @access public
*/
public static function init()
{
return !isset(self::$instance) and self::$instance = new Blocks();
}
}

View File

@@ -67,7 +67,7 @@ class Cache
static::$now = time();
// Cache key allows us to invalidate all cache on configuration changes.
static::$key = (Config::get('site.cache.prefix') ? Config::get('site.cache.prefix') : 'Monstra') . '-' . md5(ROOT_DIR . Monstra::VERSION);
static::$key = (Config::get('site.cache.prefix') ? Config::get('site.cache.prefix') : 'monstra') . '-' . md5(ROOT_DIR . Monstra::VERSION);
// Get Cache Driver
static::$driver = static::getCacheDriver();
@@ -196,6 +196,7 @@ class Cache
public static function clear()
{
Dir::delete(CACHE_PATH . '/doctrine/');
Dir::delete(CACHE_PATH . '/fenom/');
}
/**

View File

@@ -1,4 +1,8 @@
<?php
namespace Monstra;
use Arr;
use Symfony\Component\Yaml\Yaml;
/**
* This file is part of the Monstra.
@@ -12,12 +16,9 @@
class Config
{
/**
* An instance of the Config class
*
* @var object
* @access protected
* @var Monstra
*/
protected static $instance = null;
protected $monstra;
/**
* Config
@@ -27,87 +28,55 @@ class Config
*/
protected static $config = [];
/**
* Protected clone method to enforce singleton behavior.
*
* @access protected
*/
protected function __clone()
{
// Nothing here.
}
/**
* Constructor.
*
* @access protected
*/
protected function __construct()
public function __construct(Monstra $c)
{
static::$config['site'] = Yaml::parseFile(CONFIG_PATH . '/' . 'site.yml');
$this->monstra = $c;
if ($this->monstra['filesystem']->exists($site_config = CONFIG_PATH . '/' . 'site.yml')) {
self::$config['site'] = Yaml::parse(file_get_contents($site_config));
} else {
throw new RuntimeException("Monstra site config file does not exist.");
}
}
/**
* Set new or update existing config variable
*
* <code>
* Config::set('site.title', 'value');
* </code>
*
* @access public
* @param string $key Key
* @param mixed $value Value
*/
public static function set($key, $value)
public function set($key, $value)
{
Arr::set(static::$config, $key, $value);
Arr::set(self::$config, $key, $value);
}
/**
* Get config variable
*
* <code>
* Config::get('site');
* Config::get('site.title');
* Config::get('site.title', 'Default title');
* </code>
*
* @access public
* @param string $key Key
* @param mixed $default Default value
* @return mixed
*/
public static function get($key, $default = null)
public function get($key, $default = null)
{
return Arr::get(static::$config, $key, $default);
return Arr::get(self::$config, $key, $default);
}
/**
* Get config array
*
* <code>
* $config = Config::getConfig();
* </code>
*
* @access public
* @return array
*/
public static function getConfig()
public function getConfig()
{
return static::$config;
}
/**
* Initialize Monstra Config
*
* <code>
* Config::init();
* </code>
*
* @access public
*/
public static function init()
{
return !isset(self::$instance) and self::$instance = new Config();
return self::$config;
}
}

View File

@@ -1,4 +1,5 @@
<?php
namespace Monstra;
/**
* This file is part of the Monstra.
@@ -9,8 +10,15 @@
* file that was distributed with this source code.
*/
class Filter
{
/**
* @var Monstra
*/
protected $monstra;
/**
* Filters
*
@@ -20,13 +28,11 @@ class Filter
protected static $filters = [];
/**
* Protected constructor since this is a static class.
*
* @access protected
* Construct
*/
protected function __construct()
public function __construct(Monstra $c)
{
// Nothing here
$this->monstra = $c;
}
/**
@@ -41,7 +47,7 @@ class Filter
* @param mixed $value The value on which the filters hooked.
* @return mixed
*/
public static function apply($filter_name, $value)
public function dispatch($filter_name, $value)
{
// Redefine arguments
$filter_name = (string) $filter_name;
@@ -93,7 +99,7 @@ class Filter
* @param integer $accepted_args The number of arguments the function accept default is 1.
* @return boolean
*/
public static function add($filter_name, $function_to_add, $priority = 10, $accepted_args = 1)
public function addListener($filter_name, $function_to_add, $priority = 10, $accepted_args = 1)
{
// Redefine arguments
$filter_name = (string) $filter_name;
@@ -101,6 +107,8 @@ class Filter
$priority = (int) $priority;
$accepted_args = (int) $accepted_args;
//die($function_to_add);
// Check that we don't already have the same filter at the same priority. Thanks to WP :)
if (isset(static::$filters[$filter_name]["$priority"])) {
foreach (static::$filters[$filter_name]["$priority"] as $filter) {

View File

@@ -1,39 +0,0 @@
<?php
/**
* This file is part of the Monstra.
*
* (c) Romanenko Sergey / Awilum <awilum@msn.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Markdown
{
/**
* Parsedown Extra Object
*
* @var object
* @access protected
*/
protected static $markdown;
/**
* Markdown parser
*
* <code>
* $content = Markdown::parse($content);
* </code>
*
* @access public
* @param string $content Content to parse
* @return string Formatted content
*/
public static function parse($content)
{
!static::$markdown and static::$markdown = new ParsedownExtra();
return static::$markdown->text($content);
}
}

View File

@@ -1,6 +1,14 @@
<?php
namespace Monstra;
/**
use Pimple\Container as Container;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Finder\Finder;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\Event;
use ParsedownExtra;
/**
* Monstra
*
* @package Monstra
@@ -11,7 +19,7 @@
* file that was distributed with this source code.
*/
class Monstra
class Monstra extends Container
{
/**
* An instance of the Monstra class
@@ -19,80 +27,101 @@ class Monstra
* @var object
* @access protected
*/
protected static $instance = null;
protected static $instance;
/**
* The version of Monstra
*
* @var string
*/
const VERSION = '4.0.0 alpha';
const VERSION = 'X.X.X alfa';
/**
* Protected clone method to enforce singleton behavior.
*
* @access protected
* Init Monstra Application
*/
protected function __clone()
protected static function init()
{
// Nothing here.
$container = new static();
$container['filesystem'] = function ($c) {
return new Filesystem();
};
$container['finder'] = function ($c) {
return new Finder();
};
$container['config'] = function ($c) {
return new Config($c);
};
$container['markdown'] = function ($c) {
return new ParsedownExtra();
};
$container['events'] = function ($c) {
return new EventDispatcher();
};
$container['filters'] = function ($c) {
return new Filter($c);
};
$container['plugins'] = function ($c) {
return new Plugins($c);
};
$container['plugins']->init();
$container['pages'] = function ($c) {
return new Pages($c);
};
$container['themes'] = function ($c) {
return new Themes($c);
};
return $container;
}
/**
* Constructor.
*
* @access protected
* Run Monstra Application
*/
protected function __construct()
public function run()
{
// Init Config
Config::init();
// Turn on output buffering
ob_start();
// Display Errors
Config::get('site.errors.display') and error_reporting(-1);
$this['config']->get('site.errors.display') and error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_USER_DEPRECATED);
// Set internal encoding
function_exists('mb_language') and mb_language('uni');
function_exists('mb_regex_encoding') and mb_regex_encoding(Config::get('site.charset'));
function_exists('mb_internal_encoding') and mb_internal_encoding(Config::get('site.charset'));
function_exists('mb_regex_encoding') and mb_regex_encoding($this['config']->get('site.charset'));
function_exists('mb_internal_encoding') and mb_internal_encoding($this['config']->get('site.charset'));
// Set default timezone
date_default_timezone_set(Config::get('site.timezone'));
date_default_timezone_set($this['config']->get('site.timezone'));
// Start the session
Session::start();
// Init Cache
Cache::init();
// Init Plugins
Plugins::init();
// Init Blocks
Blocks::init();
// Init Pages
Pages::init();
$this['themes']->renderTemplate($this['pages']->getPage(\Url::getUriString()));
// Flush (send) the output buffer and turn off output buffering
ob_end_flush();
}
/**
* Initialize Monstra Application
*
* <code>
* Monstra::init();
* </code>
* Get Monstra Application Instance
*
* @access public
* @return object
*/
public static function init()
public static function instance()
{
return !isset(self::$instance) and self::$instance = new Monstra();
if (!self::$instance) {
self::$instance = static::init();
MonstraTrait::setMonstra(self::$instance);
}
return self::$instance;
}
}

31
monstra/MonstraTrait.php Executable file
View File

@@ -0,0 +1,31 @@
<?php
namespace Monstra;
trait MonstraTrait
{
/**
* @var Monstra
*/
protected static $monstra;
/**
* @return Monstra
*/
public static function getMonstra()
{
if (!self::$monstra) {
self::$monstra = Monstra::instance();
}
return self::$monstra;
}
/**
* @param Monstra $monstra
*/
public static function setMonstra(Monstra $monstra)
{
self::$monstra = $monstra;
}
}

124
monstra/Page.php Executable file
View File

@@ -0,0 +1,124 @@
<?php
namespace Monstra;
use Url;
use Response;
use Symfony\Component\Yaml\Yaml;
/**
* This file is part of the Monstra.
*
* (c) Romanenko Sergey / Awilum <awilum@msn.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Page
{
/**
* @var Monstra
*/
protected $monstra;
/**
* __construct
*/
public function __construct(Monstra $c)
{
$this->monstra = $c;
}
/**
* Get page
*/
public function getPage($url = '', $raw = false, $url_abs = false)
{
$file = $this->finder($url, $url_abs);
if ($raw) {
$page = trim(file_get_contents($file));
} else {
$page = $this->parse($file);
$page_frontmatter = $page['frontmatter'];
$page_content = $page['content'];
$page = $page_frontmatter;
// Parse page for summary <!--more-->
if (($pos = strpos($page_content, "<!--more-->")) === false) {
$page_content = $this->monstra['filters']->dispatch('content', $page_content);
} else {
$page_content = explode("<!--more-->", $page_content);
$page['summary'] = $this->monstra['filters']->dispatch('content', $page_content[0]);
$page['content'] = $this->monstra['filters']->dispatch('content', $page_content[0].$page_content[1]);
}
if (is_array($page_content)) {
$page['summary'] = $page['summary'];
$page['content'] = $page['content'];
} else {
$page['content'] = $page_content;
}
}
return $page;
}
/**
* Page finder
*/
public function finder($url = '', $url_abs = false)
{
// If url is empty that its a homepage
if ($url_abs) {
if ($url) {
$file = $url;
} else {
$file = CONTENT_PATH . '/pages/' . $this->monstra['config']->get('site.pages.main') . '/' . 'index.md';
}
} else {
if ($url) {
$file = CONTENT_PATH . '/pages/' . $url . '/index.md';
} else {
$file = CONTENT_PATH . '/pages/' . $this->monstra['config']->get('site.pages.main') . '/' . 'index.md';
}
}
// Get 404 page if file not exists
if ($this->monstra['filesystem']->exists($file)) {
$file = $file;
} else {
$file = CONTENT_PATH . '/pages/404/index.md';
Response::status(404);
}
return $file;
}
/**
* Page parser
*/
public function parse($file)
{
$page = trim(file_get_contents($file));
$page = explode('---', $page, 3);
$frontmatter = Yaml::parse($page[1]);
$content = $page[2];
$url = str_replace(CONTENT_PATH . '/pages', Url::getBase(), $file);
$url = str_replace('index.md', '', $url);
$url = str_replace('.md', '', $url);
$url = str_replace('\\', '/', $url);
$url = rtrim($url, '/');
$frontmatter['url'] = $url;
$frontmatter['slug'] = basename($file, '.md');
return ['frontmatter' => $frontmatter, 'content' => $content];
}
}

View File

@@ -1,4 +1,7 @@
<?php
namespace Monstra;
use Arr;
/**
* This file is part of the Monstra.
@@ -9,301 +12,43 @@
* file that was distributed with this source code.
*/
class Pages
class Pages extends Page
{
/**
* An instance of the Pages class
*
* @var object
* @access protected
* @var Monstra
*/
protected static $instance = null;
protected $monstra;
/**
* Current page.
*
* @var array
* @access protected
* Construct
*/
protected static $current_page;
/**
* Current page template.
*
* @var object
* @access protected
*/
protected static $current_template;
/**
* Protected clone method to enforce singleton behavior.
*
* @access protected
*/
protected function __clone()
public function __construct(Monstra $c)
{
// Nothing here.
$this->monstra = $c;
}
/**
* Constructor.
*
* @access protected
* getPage
*/
protected function __construct()
public function getPages($url = '', $raw = false, $order_by = 'date', $order_type = 'DESC', $ignore = ['404', 'index'], $limit = null)
{
// Get Current Page
static::$current_page = static::getPage(Url::getUriString());
// Get pages list for current $url
$pages_list = $this->monstra['finder']->files()->name('*.md')->in(CONTENT_PATH . '/pages/' . $url);
// Get Theme Templates
static::$current_template = ((!empty(static::$current_page['template'])) ? static::$current_page['template'] : 'index');
// Send default header
header('Content-Type: text/html; charset='.Config::get('site.charset'));
// Run actions before page rendered
Action::run('before_page_rendered');
// Display page for current requested url
static::display(static::$current_page);
// Run actions after page rendered
Action::run('after_page_rendered');
// Go trough pages list
foreach ($pages_list as $key => $page) {
$pages[$key] = $this->getPage($page->getPathname(), $raw, true);
}
/**
* Get pages
*
* <code>
* $pages = Pages::getPages('blog');
* </code>
*
* @access public
* @param string $url Url
* @param string $order_by Order by
* @param string $order_type Order type
* @param array $ignore Pages to ignore
* @param int $limit Limit of pages
* @return array
*/
public static function getPages($url = '', $order_by = 'date', $order_type = 'DESC', $ignore = array('404'), $limit = null)
{
$pages = File::scan(CONTENT_PATH . '/pages/' . $url, 'md');
if ($pages) {
foreach ($pages as $page) {
$pages_cache_id .= filemtime($page);
}
// Create Unique Cache ID for Pages
$pages_cache_id = md5('pages' . ROOT_DIR . $url . $order_by . $order_type . implode(",", $ignore) . (($limit === null) ? 'null' : $limit) . $pages_cache_id);
}
if (Cache::driver()->contains($pages_cache_id)) {
return Cache::driver()->fetch($pages_cache_id);
} else {
foreach ($pages as $key => $page) {
if (!in_array(basename($page, '.md'), $ignore)) {
$content = file_get_contents($page);
$_page = explode('---', $content, 3);
$_pages[$key] = Yaml::parse($_page[1]);
$url = str_replace(CONTENT_PATH . '/pages', Url::getBase(), $page);
$url = str_replace('index.md', '', $url);
$url = str_replace('.md', '', $url);
$url = str_replace('\\', '/', $url);
$url = rtrim($url, '/');
$_pages[$key]['url'] = $url;
$_content = $_page[2];
// Parse page for summary <!--more-->
if (($pos = strpos($_content, "<!--more-->")) === false) {
$_content = Filter::apply('content', $_content);
} else {
$_content = explode("<!--more-->", $_content);
$_content['summary'] = Filter::apply('content', $_content[0]);
$_content['content'] = Filter::apply('content', $_content[0].$_content[1]);
}
if (is_array($_content)) {
$_pages[$key]['summary'] = $_content['summary'];
$_pages[$key]['content'] = $_content['content'];
} else {
$_pages[$key]['summary'] = $_content;
$_pages[$key]['content'] = $_content;
}
$_pages[$key]['slug'] = basename($page, '.md');
}
}
$_pages = Arr::subvalSort($_pages, $order_by, $order_type);
// Sort and Slice pages if !$raw
if (!$raw) {
$pages = Arr::subvalSort($pages, $order_by, $order_type);
if ($limit != null) {
$_pages = array_slice($_pages, null, $limit);
}
Cache::driver()->save($pages_cache_id, $_pages);
return $_pages;
$pages = array_slice($_pages, null, $limit);
}
}
/**
* Get page
*
* <code>
* $page = Pages::getPage('downloads');
* </code>
*
* @access public
* @param string $url Url
* @return array
*/
public static function getPage($url)
{
// If url is empty then its a homepage
if ($url) {
$file = CONTENT_PATH . '/pages/' . $url;
} else {
$file = CONTENT_PATH . '/pages/' . Config::get('site.pages.main') . '/' . 'index';
}
// Select the file
if (is_dir($file)) {
$file = CONTENT_PATH . '/pages/' . $url .'/index.md';
} else {
$file .= '.md';
}
// Get 404 page if file not exists
if (!file_exists($file)) {
$file = CONTENT_PATH . '/pages/404/' . 'index.md';
Response::status(404);
}
// Create Unique Cache ID for requested page
$page_cache_id = md5('page' . ROOT_DIR . $file . filemtime($file));
if (Cache::driver()->contains($page_cache_id) && Config::get('site.pages.flush_cache') == false) {
return Cache::driver()->fetch($page_cache_id);
} else {
$content = file_get_contents($file);
$_page = explode('---', $content, 3);
$page = Yaml::parse($_page[1]);
$url = str_replace(CONTENT_PATH . '/pages', Url::getBase(), $file);
$url = str_replace('index.md', '', $url);
$url = str_replace('.md', '', $url);
$url = str_replace('\\', '/', $url);
$url = rtrim($url, '/');
$page['url'] = $url;
$_content = $_page[2];
// Parse page for summary <!--more-->
if (($pos = strpos($_content, "<!--more-->")) === false) {
$_content = Filter::apply('content', $_content);
} else {
$_content = explode("<!--more-->", $_content);
$_content['summary'] = Filter::apply('content', $_content[0]);
$_content['content'] = Filter::apply('content', $_content[0].$_content[1]);
}
if (is_array($_content)) {
$page['summary'] = $_content['summary'];
$page['content'] = $_content['content'];
} else {
$page['content'] = $_content;
}
$page['slug'] = basename($file, '.md');
// Overload page title, keywords and description if needed
empty($page['title']) and $page['title'] = Config::get('site.title');
empty($page['keywords']) and $page['keywords'] = Config::get('site.keywords');
empty($page['description']) and $page['description'] = Config::get('site.description');
Cache::driver()->save($page_cache_id, $page);
return $page;
}
}
/**
* Get Current Page
*
* <code>
* $page = Pages::getCurrentPage();
* </code>
*
* @return array
*/
public static function getCurrentPage()
{
return static::$current_page;
}
/**
* Update Current Page
*
* <code>
* Pages::updateCurrentPage('title', 'My new Page Title');
* </code>
*
* @return array
*/
public static function updateCurrentPage($path, $value)
{
Arr::set(static::$current_page, $path, $value);
}
/**
* Display Page
*
* <code>
* Pages::display($page);
* </code>
*
* @access public
* @param array $page Page array
* @return string
*/
public static function display($page)
{
Theme::getTemplate(((!empty($page['template'])) ? $page['template'] : 'index'));
}
/**
* Get Current Template
*
* <code>
* $template = Pages::getCurrentTemplate();
* </code>
*
* @access public
* @return object
*/
public static function getCurrentTemplate()
{
return static::$current_template;
}
/**
* Initialize Monstra Pages
*
* <code>
* Pages::init();
* </code>
*
* @access public
*/
public static function init()
{
return !isset(self::$instance) and self::$instance = new Pages();
return $pages;
}
}

View File

@@ -1,4 +1,5 @@
<?php
namespace Monstra;
/**
* This file is part of the Monstra.
@@ -9,8 +10,19 @@
* file that was distributed with this source code.
*/
// Add Shortcode parser filter
Filter::add('content', 'Shortcode::parse', 1);
// Add Parsedown parser filter
Filter::add('content', 'Markdown::parse', 2);
class Plugin
{
/**
* @var Monstra
*/
protected $monstra;
/**
* __construct
*/
public function __construct(Monstra $c)
{
$this->monstra = $c;
}
}

View File

@@ -1,4 +1,7 @@
<?php
namespace Monstra;
use Symfony\Component\Yaml\Yaml;
/**
* This file is part of the Monstra.
@@ -8,109 +11,53 @@
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Plugins
{
/**
* An instance of the Plugins class
*
* @var object
* @access protected
* @var Monstra
*/
protected static $instance = null;
protected $monstra;
/**
* Protected clone method to enforce singleton behavior.
*
* @access protected
* __construct
*/
protected function __clone()
public function __construct(Monstra $c)
{
// Nothing here.
}
$this->monstra = $c;
/**
* Constructor.
*
* @access protected
*/
protected function __construct()
{
$plugins_cache_id = '';
$monstra = $this->monstra;
$plugin_manifest = [];
$plugin_settings = [];
// Get Plugins List
$plugins_list = Config::get('site.plugins');
// If Plugins List isnt empty then create plugin cache ID
if (is_array($plugins_list) && count($plugins_list) > 0) {
// Go through...
foreach ($plugins_list as $plugin) {
if (File::exists($_plugin = PLUGINS_PATH . '/' . $plugin . '/' . $plugin . '.yml')) {
$plugins_cache_id .= filemtime($_plugin);
}
}
// Create Unique Cache ID for Plugins
$plugins_cache_id = md5('plugins' . ROOT_DIR . PLUGINS_PATH . $plugins_cache_id);
}
// Get plugins list from cache or scan plugins folder and create new plugins cache item
if (Cache::driver()->contains($plugins_cache_id)) {
Config::set('plugins', Cache::driver()->fetch($plugins_cache_id));
} else {
$plugins_list = $this->monstra['config']->get('site.plugins');
// @TODO THIS with cache then
// If Plugins List isnt empty
if (is_array($plugins_list) && count($plugins_list) > 0) {
// Go through...
foreach ($plugins_list as $plugin) {
if (File::exists($_plugin_manifest = PLUGINS_PATH . '/' . $plugin . '/' . $plugin . '.yml')) {
$plugin_manifest = Yaml::parseFile($_plugin_manifest);
if (file_exists($_plugin_manifest = PLUGINS_PATH . '/' . $plugin . '/' . $plugin . '.yml')) {
$plugin_manifest = Yaml::parse(file_get_contents($_plugin_manifest));
}
if (File::exists($_plugin_settings = PLUGINS_PATH . '/' . $plugin . '/settings.yml')) {
$plugin_settings = Yaml::parseFile($_plugin_settings);
}
$_plugins_config[File::name($_plugin_manifest)] = array_merge($plugin_manifest, $plugin_settings);
}
Config::set('plugins', $_plugins_config);
Cache::driver()->save($plugins_cache_id, $_plugins_config);
$_plugins_config[basename($_plugin_manifest)] = array_merge($plugin_manifest, $plugin_settings);
}
}
// Include enabled plugins
if (is_array(Config::get('plugins')) && count(Config::get('plugins')) > 0) {
foreach (Config::get('plugins') as $plugin_name => $plugin) {
if (Config::get('plugins.'.$plugin_name.'.enabled')) {
if (is_array($this->monstra['config']->get('site.plugins')) && count($this->monstra['config']->get('site.plugins')) > 0) {
foreach ($this->monstra['config']->get('site.plugins') as $plugin_id => $plugin_name) {
//echo '@@@'.$plugins;
//if ($this->monstra['config']->get('plugins.'.$plugin_name.'.enabled')) {
//echo $plugin_name;
include_once PLUGINS_PATH .'/'. $plugin_name .'/'. $plugin_name . '.php';
}
}
}
// Run Actions on plugins_loaded
Action::run('plugins_loaded');
}
public function init() {
/**
* Initialize Monstra Plugins
*
* <code>
* Plugins::init();
* </code>
*
* @access public
*/
public static function init()
{
if (! isset(self::$instance)) {
self::$instance = new Plugins();
}
return self::$instance;
}
}

View File

@@ -1,9 +0,0 @@
<?php
class Theme
{
public static function getTemplate($template = null)
{
include THEMES_PATH . '/' . Config::get('site.theme') . '/' . $template . '.php';
}
}

44
monstra/Themes.php Normal file
View File

@@ -0,0 +1,44 @@
<?php
namespace Monstra;
use Url;
use Response;
/**
* This file is part of the Monstra.
*
* (c) Romanenko Sergey / Awilum <awilum@msn.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Themes
{
/**
* @var Monstra
*/
protected $monstra;
/**
* __construct
*/
public function __construct(Monstra $c)
{
$this->monstra = $c;
}
public function renderTemplate($page)
{
if (empty($page['template'])) {
$template_name = 'index';
} else {
$template_name = $page['template'];
}
$template_ext = '.php';
include THEMES_PATH . '/' . $this->monstra['config']->get('site.theme') . '/' . $template_name . $template_ext;
}
}

View File

@@ -1,59 +0,0 @@
<?php
/**
* This file is part of the Monstra.
*
* (c) Romanenko Sergey / Awilum <awilum@msn.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Yaml
{
/**
* Parses YAML to array.
*
* <code>
* $array = Yaml::parseFile('file.yml');
* </code>
*
* @access public
* @param string $file Path to YAML file.
* @return array
*/
public static function parseFile($file)
{
return Spyc::YAMLLoad($file);
}
/**
* Parses YAML to array.
*
* <code>
* $array = Yaml::parse('title: My title');
* </code>
*
* @param string $string YAML string.
* @return array
*/
public static function parse($string)
{
return Spyc::YAMLLoadString($string);
}
/**
* Dumps array to YAML.
*
* <code>
* $yaml = Yaml::dump($data);
* </code>
*
* @param array $data Array.
* @return string
*/
public static function dump($data)
{
return Spyc::YAMLDump($data, false, false, true);
}
}

View File

@@ -1,15 +0,0 @@
<?php
/**
* This file is part of the Monstra.
*
* (c) Romanenko Sergey / Awilum <awilum@msn.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
// Set Monstra Meta Generator
Action::add('theme_meta', function () {
echo('<meta name="generator" content="Powered by Monstra" />');
});

View File

@@ -1,22 +0,0 @@
<?php
/**
* This file is part of the Monstra.
*
* (c) Romanenko Sergey / Awilum <awilum@msn.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
// Add {block name=block-name} shortcode
Shortcode::add('block', function ($attributes) {
if (isset($attributes['name'])) {
return Blocks::get($attributes['name']);
}
});
// Add {site_url} shortcode
Shortcode::add('site_url', function () {
return Url::getBase();
});