1
0
mirror of https://github.com/monstra-cms/monstra.git synced 2025-08-16 18:14:07 +02:00

#431 initial commit for MONSTRA 4

This commit is contained in:
Awilum
2018-02-27 23:31:11 +03:00
parent 9a19078870
commit acfa870de9
46 changed files with 1760 additions and 0 deletions

113
monstra/Action.php Executable file
View File

@@ -0,0 +1,113 @@
<?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']);
}
}
}
}
}
}
}

102
monstra/Blocks.php Executable file
View File

@@ -0,0 +1,102 @@
<?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(STORAGE_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 = STORAGE_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();
}
}

248
monstra/Cache.php Executable file
View File

@@ -0,0 +1,248 @@
<?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 Cache
{
/**
* An instance of the Cache class
*
* @var object
*/
protected static $instance = null;
/**
* Unique cache key
*
* @var string Cache key.
*/
protected static $key;
/**
* Lifetime
*
* @var int Lifetime.
*/
protected static $lifetime;
/**
* Current time
*
* @var int Current time.
*/
protected static $now;
/**
* Cache Driver
*
* @var DoctrineCache
*/
protected static $driver;
/**
* Protected clone method to enforce singleton behavior.
*
* @access protected
*/
protected function __clone()
{
// Nothing here.
}
/**
* Constructor.
*
* @access protected
*/
protected function __construct()
{
// Set current time
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);
// Get Cache Driver
static::$driver = static::getCacheDriver();
// Set the cache namespace to our unique key
static::$driver->setNamespace(static::$key);
}
/**
* Get Cache Driver
*
* @access public
* @return object
*/
public static function getCacheDriver()
{
$driver_name = Config::get('site.cache.driver');
if (!$driver_name || $driver_name == 'auto') {
if (extension_loaded('apc')) {
$driver_name = 'apc';
} elseif (extension_loaded('wincache')) {
$driver_name = 'wincache';
} elseif (extension_loaded('xcache')) {
$driver_name = 'xcache';
}
} else {
$driver_name = 'file';
}
switch ($driver_name) {
case 'apc':
$driver = new \Doctrine\Common\Cache\ApcCache();
break;
case 'wincache':
$driver = new \Doctrine\Common\Cache\WinCacheCache();
break;
case 'xcache':
$driver = new \Doctrine\Common\Cache\XcacheCache();
break;
case 'memcache':
$memcache = new \Memcache();
$memcache->connect(Config::get('site.cache.memcache.server', 'localhost'),
Config::get('site.cache.memcache.port', 11211));
$driver = new \Doctrine\Common\Cache\MemcacheCache();
$driver->setMemcache($memcache);
break;
case 'redis':
$redis = new \Redis();
$redis->connect(Config::get('site.cache.redis.server', 'localhost'),
Config::get('site.cache.redis.port', 6379));
$driver = new \Doctrine\Common\Cache\RedisCache();
$driver->setRedis($redis);
break;
default:
// Create doctrine cache directory if its not exists
!Dir::exists($cache_directory = CACHE_PATH . '/doctrine/') and Dir::create($cache_directory);
$driver = new \Doctrine\Common\Cache\FilesystemCache($cache_directory);
break;
}
return $driver;
}
/**
* Returns driver variable
*
* @access public
* @return object
*/
public static function driver()
{
return static::$driver;
}
/**
* Get cache key.
*
* @access public
* @return string
*/
public static function getKey()
{
return static::$key;
}
/**
* Fetches an entry from the cache.
*
* @access public
* @param string $id The id of the cache entry to fetch.
* @return mixed The cached data or FALSE, if no cache entry exists for the given id.
*/
public function fetch($id)
{
if (Config::get('site.cache.enabled')) {
return static::$driver->fetch($id);
} else {
return false;
}
}
/**
* Puts data into the cache.
*
* @access public
* @param string $id The cache id.
* @param mixed $data The cache entry/data.
* @param int $lifeTime The lifetime in number of seconds for this cache entry.
* If zero (the default), the entry never expires (although it may be deleted from the cache
* to make place for other entries).
*/
public function save($id, $data, $lifetime = null)
{
if (Config::get('site.cache.enabled')) {
if ($lifetime === null) {
$lifetime = static::getLifetime();
}
static::$driver->save($id, $data, $lifetime);
}
}
/**
* Clear Cache
*/
public static function clear()
{
Dir::delete(CACHE_PATH . '/doctrine/');
}
/**
* Set the cache lifetime.
*
* @access public
* @param int $future timestamp
*/
public static function setLifetime($future)
{
if (!$future) {
return;
}
$interval = $future - $this->now;
if ($interval > 0 && $interval < static::getLifetime()) {
static::$lifetime = $interval;
}
}
/**
* Retrieve the cache lifetime (in seconds)
*
* @access public
* @return mixed
*/
public static function getLifetime()
{
if (static::$lifetime === null) {
static::$lifetime = Config::get('site.cache.lifetime') ?: 604800;
}
return static::$lifetime;
}
/**
* Initialize Monstra Cache
*
* <code>
* Cache::init();
* </code>
*
* @access public
* @return object
*/
public static function init()
{
return !isset(self::$instance) and self::$instance = new Cache();
}
}

113
monstra/Config.php Executable file
View File

@@ -0,0 +1,113 @@
<?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 Config
{
/**
* An instance of the Config class
*
* @var object
* @access protected
*/
protected static $instance = null;
/**
* Config
*
* @var array
* @access protected
*/
protected static $config = [];
/**
* Protected clone method to enforce singleton behavior.
*
* @access protected
*/
protected function __clone()
{
// Nothing here.
}
/**
* Constructor.
*
* @access protected
*/
protected function __construct()
{
static::$config['site'] = Yaml::parseFile(CONFIG_PATH . '/' . 'site.yml');
}
/**
* 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)
{
Arr::set(static::$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)
{
return Arr::get(static::$config, $key, $default);
}
/**
* Get config array
*
* <code>
* $config = Config::getConfig();
* </code>
*
* @access public
* @return array
*/
public static 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();
}
}

120
monstra/Filter.php Executable file
View File

@@ -0,0 +1,120 @@
<?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 Filter
{
/**
* Filters
*
* @var array
* @access protected
*/
protected static $filters = [];
/**
* Protected constructor since this is a static class.
*
* @access protected
*/
protected function __construct()
{
// Nothing here
}
/**
* Apply filters
*
* <code>
* Filter::apply('content', $content);
* </code>
*
* @access public
* @param string $filter_name The name of the filter hook.
* @param mixed $value The value on which the filters hooked.
* @return mixed
*/
public static function apply($filter_name, $value)
{
// Redefine arguments
$filter_name = (string) $filter_name;
$args = array_slice(func_get_args(), 2);
if (! isset(static::$filters[$filter_name])) {
return $value;
}
foreach (static::$filters[$filter_name] as $priority => $functions) {
if (! is_null($functions)) {
foreach ($functions as $function) {
$all_args = array_merge(array($value), $args);
$function_name = $function['function'];
$accepted_args = $function['accepted_args'];
if ($accepted_args == 1) {
$the_args = array($value);
} elseif ($accepted_args > 1) {
$the_args = array_slice($all_args, 0, $accepted_args);
} elseif ($accepted_args == 0) {
$the_args = null;
} else {
$the_args = $all_args;
}
$value = call_user_func_array($function_name, $the_args);
}
}
}
return $value;
}
/**
* Add filter
*
* <code>
* Filter::add('content', 'replacer');
*
* function replacer($content) {
* return preg_replace(array('/\[b\](.*?)\[\/b\]/ms'), array('<strong>\1</strong>'), $content);
* }
* </code>
*
* @access public
* @param string $filter_name The name of the filter to hook the $function_to_add to.
* @param string $function_to_add The name of the function to be called when the filter is applied.
* @param integer $priority Function to add priority - default is 10.
* @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)
{
// Redefine arguments
$filter_name = (string) $filter_name;
$function_to_add = $function_to_add;
$priority = (int) $priority;
$accepted_args = (int) $accepted_args;
// 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) {
if ($filter['function'] == $function_to_add) {
return true;
}
}
}
static::$filters[$filter_name]["$priority"][] = array('function' => $function_to_add, 'accepted_args' => $accepted_args);
// Sort
ksort(static::$filters[$filter_name]["$priority"]);
return true;
}
}

39
monstra/Markdown.php Executable file
View File

@@ -0,0 +1,39 @@
<?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);
}
}

98
monstra/Monstra.php Executable file
View File

@@ -0,0 +1,98 @@
<?php
/**
* Monstra
*
* @package Monstra
* @author Romanenko Sergey / Awilum <awilum@msn.com>
* @link http://monstra.org
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Monstra
{
/**
* An instance of the Monstra class
*
* @var object
* @access protected
*/
protected static $instance = null;
/**
* The version of Monstra
*
* @var string
*/
const VERSION = '4.0.0 alpha';
/**
* Protected clone method to enforce singleton behavior.
*
* @access protected
*/
protected function __clone()
{
// Nothing here.
}
/**
* Constructor.
*
* @access protected
*/
protected function __construct()
{
// Init Config
Config::init();
// Turn on output buffering
ob_start();
// Display Errors
Config::get('site.errors.display') and error_reporting(-1);
// 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'));
// Set default timezone
date_default_timezone_set(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();
// Flush (send) the output buffer and turn off output buffering
ob_end_flush();
}
/**
* Initialize Monstra Application
*
* <code>
* Monstra::init();
* </code>
*
* @access public
* @return object
*/
public static function init()
{
return !isset(self::$instance) and self::$instance = new Monstra();
}
}

309
monstra/Pages.php Executable file
View File

@@ -0,0 +1,309 @@
<?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 Pages
{
/**
* An instance of the Pages class
*
* @var object
* @access protected
*/
protected static $instance = null;
/**
* Current page.
*
* @var array
* @access protected
*/
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()
{
// Nothing here.
}
/**
* Constructor.
*
* @access protected
*/
protected function __construct()
{
// Get Current Page
static::$current_page = static::getPage(Url::getUriString());
// 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');
}
/**
* 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(STORAGE_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(STORAGE_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);
if ($limit != null) {
$_pages = array_slice($_pages, null, $limit);
}
Cache::driver()->save($pages_cache_id, $_pages);
return $_pages;
}
}
/**
* 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 that its a homepage
if ($url) {
$file = STORAGE_PATH . '/pages/' . $url;
} else {
$file = STORAGE_PATH . '/pages/' . 'index';
}
// Select the file
if (is_dir($file)) {
$file = STORAGE_PATH . '/pages/' . $url .'/index.md';
} else {
$file .= '.md';
}
// Get 404 page if file not exists
if (!file_exists($file)) {
$file = STORAGE_PATH . '/pages/' . '404.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(STORAGE_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();
}
}

116
monstra/Plugins.php Executable file
View File

@@ -0,0 +1,116 @@
<?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 Plugins
{
/**
* An instance of the Plugins 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()
{
$plugins_cache_id = '';
$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 {
// 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_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);
}
}
// 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')) {
include_once PLUGINS_PATH .'/'. $plugin_name .'/'. $plugin_name . '.php';
}
}
}
// Run Actions on plugins_loaded
Action::run('plugins_loaded');
}
/**
* Initialize Monstra Plugins
*
* <code>
* Plugins::init();
* </code>
*
* @access public
*/
public static function init()
{
if (! isset(self::$instance)) {
self::$instance = new Plugins();
}
return self::$instance;
}
}

9
monstra/Theme.php Executable file
View File

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

59
monstra/Yaml.php Executable file
View File

@@ -0,0 +1,59 @@
<?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);
}
}

15
monstra/boot/actions.php Executable file
View File

@@ -0,0 +1,15 @@
<?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" />');
});

34
monstra/boot/defines.php Executable file
View File

@@ -0,0 +1,34 @@
<?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.
*/
// Define the path to the root directory (without trailing slash).
define('ROOT_DIR', str_replace(DIRECTORY_SEPARATOR, '/', getcwd()));
// Define the path to the storage directory (without trailing slash).
define('SITE_PATH', ROOT_DIR . '/site');
// Define the path to the storage directory (without trailing slash).
define('STORAGE_PATH', SITE_PATH . '/storage');
// Define the path to the themes directory (without trailing slash).
define('THEMES_PATH', SITE_PATH . '/themes');
// Define the path to the plugins directory (without trailing slash).
define('PLUGINS_PATH', SITE_PATH . '/plugins');
// Define the path to the config directory (without trailing slash).
define('CONFIG_PATH', SITE_PATH . '/config');
// Define the path to the cache directory (without trailing slash).
define('CACHE_PATH', SITE_PATH . '/cache');
// Define the path to the cache directory (without trailing slash).
define('ACCOUNTS_PATH', SITE_PATH . '/cache');

16
monstra/boot/filters.php Executable file
View File

@@ -0,0 +1,16 @@
<?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 Shortcode parser filter
Filter::add('content', 'Shortcode::parse', 1);
// Add Parsedown parser filter
Filter::add('content', 'Markdown::parse', 2);

22
monstra/boot/shortcodes.php Executable file
View File

@@ -0,0 +1,22 @@
<?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();
});