1
0
mirror of https://github.com/flextype/flextype.git synced 2025-08-12 16:14:16 +02:00

NEW BRAND NAME - FLEXTYPE

This commit is contained in:
Awilum
2018-03-21 01:38:54 +03:00
parent 0c1e5ad250
commit 4c8741f263
12 changed files with 1435 additions and 0 deletions

227
flextype/Cache.php Executable file
View File

@@ -0,0 +1,227 @@
<?php namespace Flextype;
/**
* @package Flextype
*
* @author Sergey Romanenko <awilum@yandex.ru>
* @link http://flextype.org
*
* 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') : 'fansoro') . '-' . md5(ROOT_DIR . 'Fansoro::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
!Flextype::$filesystem->exists($cache_directory = CACHE_PATH . '/doctrine/') and Flextype::$filesystem->mkdir($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()
{
Flextype::$filesystem->remove(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 Fansoro Cache
*
* <code>
* Cache::init();
* </code>
*
* @access public
* @return object
*/
public static function init()
{
return !isset(self::$instance) and self::$instance = new Cache();
}
}

112
flextype/Config.php Executable file
View File

@@ -0,0 +1,112 @@
<?php namespace Flextype;
use Arr;
use Symfony\Component\Yaml\Yaml;
/**
* @package Flextype
*
* @author Sergey Romanenko <awilum@yandex.ru>
* @link http://flextype.org
*
* 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()
{
if (Flextype::$filesystem->exists($site_config = CONFIG_PATH . '/' . 'site.yml')) {
static::$config['site'] = Yaml::parse(file_get_contents($site_config));
} else {
throw new RuntimeException("Flextype site config file does not exist.");
}
}
/**
* Set new or update existing config variable
*
* @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
*
* @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 Flextype Config
*
* <code>
* Config::init();
* </code>
*
* @access public
*/
public static function init()
{
return !isset(self::$instance) and self::$instance = new Config();
}
}

101
flextype/Events.php Normal file
View File

@@ -0,0 +1,101 @@
<?php namespace Flextype;
use Arr;
/**
* @package Flextype
*
* @author Sergey Romanenko <awilum@yandex.ru>
* @link http://flextype.org
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Events
{
/**
* Events
*
* @var array
* @access protected
*/
protected static $events = [];
/**
* Protected constructor since this is a static class.
*
* @access protected
*/
protected function __construct()
{
// Nothing here
}
/**
* Hooks a function on to a specific event.
*
* @access public
* @param string $event_name Event name
* @param mixed $added_function Added function
* @param integer $priority Priority. Default is 10
* @param array $args Arguments
*/
public static function addListener(string $event_name, $added_function, int $priority = 10, array $args = null)
{
// Hooks a function on to a specific event.
static::$events[] = array(
'event_name' => $event_name,
'function' => $added_function,
'priority' => $priority,
'args' => $args
);
}
/**
* Run functions hooked on a specific event.
*
* @access public
* @param string $event_name Event name
* @param array $args Arguments
* @param boolean $return Return data or not. Default is false
* @return mixed
*/
public static function dispatch(string $event_name, array $args = [], bool $return = false)
{
// Redefine arguments
$event_name = $event_name;
$return = $return;
// Run event
if (count(static::$events) > 0) {
// Sort actions by priority
$events = Arr::subvalSort(static::$events, 'priority');
// Loop through $events array
foreach ($events as $action) {
// Execute specific action
if ($action['event_name'] == $event_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']);
}
}
}
}
}
}
}

125
flextype/Filters.php Executable file
View File

@@ -0,0 +1,125 @@
<?php namespace Flextype;
/**
* @package Flextype
*
* @author Sergey Romanenko <awilum@yandex.ru>
* @link http://flextype.org
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Filters
{
/**
* @var Flextype
*/
protected $flextype;
/**
* Filters
*
* @var array
* @access protected
*/
protected static $filters = [];
/**
* Protected constructor since this is a static class.
*
* @access protected
*/
protected function __construct()
{
// Nothing here
}
/**
* Dispatch filters
*
* <code>
* Filter::dispatch('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 dispatch(string $filter_name, $value)
{
$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 addListener($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;
}
}

136
flextype/Flextype.php Executable file
View File

@@ -0,0 +1,136 @@
<?php namespace Flextype;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Finder\Finder;
use Url;
use Session;
/**
* @package Flextype
*
* @author Romanenko Sergey / Awilum <awilum@yandex.ru>
* @link http://flextype.org
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Flextype
{
/**
* An instance of the Flextype class
*
* @var object
* @access protected
*/
protected static $instance = null;
/**
* Filesystem
*
* @var object
* @access public
*/
public static $filesystem = null;
/**
* Finder
*
* @var object
* @access public
*/
public static $finder = null;
/**
* Protected clone method to enforce singleton behavior.
*
* @access protected
*/
protected function __clone()
{
// Nothing here.
}
/**
* The version of Flextype
*
* @var string
*/
const VERSION = '0.0.0';
/**
* Constructor.
*
* @access protected
*/
protected function __construct()
{
static::$finder = new Finder();
static::$filesystem = new Filesystem();
// Init Config
Config::init();
// Turn on output buffering
ob_start();
// Display Errors
if (Config::get('site.errors.display')) {
define('DEVELOPMENT', true);
error_reporting(-1);
} else {
define('DEVELOPMENT', false);
error_reporting(0);
}
// 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 Error handler
set_error_handler('ErrorHandler::error');
register_shutdown_function('ErrorHandler::fatal');
set_exception_handler('ErrorHandler::exception');
// Set default timezone
date_default_timezone_set(Config::get('site.timezone'));
// Start the session
Session::start();
// Init Cache
Cache::init();
// Init I18n
I18n::init();
// Init Themes
Themes::init();
// Init Plugins
Plugins::init();
// Render current page
Pages::init();
// Flush (send) the output buffer and turn off output buffering
ob_end_flush();
}
/**
* Initialize Flextype Application
*
* <code>
* Rawium::init();
* </code>
*
* @access public
* @return object
*/
public static function init()
{
return !isset(self::$instance) and self::$instance = new Flextype();
}
}

145
flextype/I18n.php Normal file
View File

@@ -0,0 +1,145 @@
<?php namespace Flextype;
use Symfony\Component\Yaml\Yaml;
/**
* @package Flextype
*
* @author Sergey Romanenko <awilum@yandex.ru>
* @link http://flextype.org
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class I18n
{
/**
* An instance of the Cache class
*
* @var object
*/
protected static $instance = null;
/**
* Locales array
*
* @var array
*/
public static $locales = [
'ar' => 'العربية',
'bg' => 'Български',
'ca' => 'Català',
'cs' => 'Česky',
'da' => 'Dansk',
'de' => 'Deutsch',
'el' => 'Ελληνικά',
'en' => 'English',
'es' => 'Español',
'fa' => 'Farsi',
'fi' => 'Suomi',
'fr' => 'Français',
'gl' => 'Galego',
'ka-ge' => 'Georgian',
'hu' => 'Magyar',
'it' => 'Italiano',
'id' => 'Bahasa Indonesia',
'ja' => '日本語',
'lt' => 'Lietuvių',
'nl' => 'Nederlands',
'no' => 'Norsk',
'pl' => 'Polski',
'pt' => 'Português',
'pt-br' => 'Português do Brasil',
'ru' => 'Русский',
'sk' => 'Slovenčina',
'sl' => 'Slovenščina',
'sv' => 'Svenska',
'sr' => 'Srpski',
'tr' => 'Türkçe',
'uk' => 'Українська',
'zh-cn' => '简体中文',
];
/**
* Dictionary
*
* @var array
*/
public static $dictionary = [];
/**
* Protected clone method to enforce singleton behavior.
*
* @access protected
*/
protected function __clone()
{
// Nothing here.
}
/**
* Construct
*/
protected function __construct()
{
// Get Plugins and Site Locales list
(array) $plugins_list = Config::get('site.plugins');
(array) $locales = Config::get('site.locales');
(array) $dictionary = [];
// Create dictionary
if (is_array($plugins_list) && count($plugins_list) > 0) {
foreach ($locales as $locale) {
foreach ($plugins_list as $plugin) {
$language_file = PLUGINS_PATH . '/' . $plugin . '/languages/' . $locale . '.yml';
if (file_exists($language_file)) {
$dictionary[$plugin][$locale] = Yaml::parse(file_get_contents($language_file));
}
}
}
}
// Save dictionary
static::$dictionary = $dictionary;
}
/**
* Returns translation of a string. If no translation exists, the original
* string will be returned. No parameters are replaced.
*
* @param string $string Text to translate
* @param string $namespace Namespace
* @param string $locale Locale
* @return string
*/
public static function find(string $string, string $namespace, string $locale, array $values = []) : string
{
// Search current string to translate in the Dictionary
if (isset(static::$dictionary[$namespace][$locale][$string])) {
$string = static::$dictionary[$namespace][$locale][$string];
$string = empty($values) ? $string : strtr($string, $values);
} else {
$string = $string;
}
// Return translation of a string
return $string;
}
/**
* Initialize Flextype I18n
*
* <code>
* I18n::init();
* </code>
*
* @access public
* @return object
*/
public static function init()
{
return !isset(self::$instance) and self::$instance = new I18n();
}
}

42
flextype/Markdown.php Normal file
View File

@@ -0,0 +1,42 @@
<?php namespace Flextype;
use ParsedownExtra;
/**
* @package Flextype
*
* @author Sergey Romanenko <awilum@yandex.ru>
* @link http://flextype.org
*
* 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(string $content) : string
{
!static::$markdown and static::$markdown = new ParsedownExtra();
return static::$markdown->text($content);
}
}

207
flextype/Pages.php Executable file
View File

@@ -0,0 +1,207 @@
<?php namespace Flextype;
use Arr;
use Url;
use Response;
use Shortcode;
use Symfony\Component\Yaml\Yaml;
/**
* @package Flextype
*
* @author Sergey Romanenko <awilum@yandex.ru>
* @link http://flextype.org
*
* 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 Cache class
*
* @var object
*/
protected static $instance = null;
/**
* Page
*
* @var Page
*/
public static $page;
/**
* Constructor
*
* @param Flextype $flextype
*/
protected function __construct()
{
// The page is not processed and not sent to the display.
Events::dispatch('onPageBeforeRender');
// Get current page
static::$page = static::getPage(Url::getUriString());
// Display page for current requested url
static::renderPage(static::$page);
// The page has been fully processed and sent to the display.
Events::dispatch('onPageAfterRender');
}
/**
* Page finder
*/
public static function finder($url = '', $url_abs = false)
{
// If url is empty that its a homepage
if ($url_abs) {
if ($url) {
$file = $url;
} else {
$file = PAGES_PATH . '/' . Config::get('site.pages.main') . '/' . 'index.md';
}
} else {
if ($url) {
$file = PAGES_PATH . '/' . $url . '/index.md';
} else {
$file = PAGES_PATH . '/' . Config::get('site.pages.main') . '/' . 'index.md';
}
}
// Get 404 page if file not exists
if (Flextype::$filesystem->exists($file)) {
$file = $file;
} else {
$file = PAGES_PATH . '/404/index.md';
Response::status(404);
}
return $file;
}
/**
* Render page
*/
public static function renderPage($page)
{
$template_ext = '.php';
$template_name = empty($page['template']) ? 'index' : $page['template'];
$site_theme = Config::get('site.theme');
$template_path = THEMES_PATH . '/' . $site_theme . '/' . $template_name . $template_ext;
if (Flextype::$filesystem->exists($template_path)) {
include $template_path;
} else {
throw new RuntimeException("Template {$template_name} does not exist.");
}
}
/**
* Page parser
*/
public static function parse($file)
{
$page = trim(file_get_contents($file));
$page = explode('---', $page, 3);
$frontmatter = Shortcodes::parse($page[1]);
$result_page = Yaml::parse($frontmatter);
// Get page url
$url = str_replace(PAGES_PATH, Url::getBase(), $file);
$url = str_replace('index.md', '', $url);
$url = str_replace('.md', '', $url);
$url = str_replace('\\', '/', $url);
$url = rtrim($url, '/');
$result_page['url'] = $url;
// Get page slug
$url = str_replace(Url::getBase(), '', $url);
$url = ltrim($url, '/');
$url = rtrim($url, '/');
$result_page['slug'] = str_replace(Url::getBase(), '', $url);
$result_page['content'] = $page[2];
return $result_page;
}
/**
* Get page
*/
public static function getPage(string $url = '', bool $raw = false, bool $url_abs = false)
{
$file = static::finder($url, $url_abs);
if ($raw) {
$page = trim(file_get_contents($file));
static::$page = $page;
Events::dispatch('onPageContentRawAfter');
} else {
$page = static::parse($file);
static::$page = $page;
static::$page['content'] = Filters::dispatch('content', static::parseContent(static::$page['content']));
Events::dispatch('onPageContentAfter');
}
return static::$page;
}
public static function parseContent(string $content) : string
{
$content = Shortcodes::parse($content);
$content = Markdown::parse($content);
return $content;
}
/**
* getPage
*/
public static function getPages($url = '', $raw = false, $order_by = 'title', $order_type = 'DESC', $limit = null)
{
// Get pages list for current $url
$pages_list = Flextype::$finder->files()->name('*.md')->in(PAGES_PATH . '/' . $url);
// Go trough pages list
foreach ($pages_list as $key => $page) {
if (strpos($page->getPathname(), $url.'/index.md') !== false) {
} else {
$pages[$key] = static::getPage($page->getPathname(), $raw, true);
}
}
// 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);
}
}
return $pages;
}
/**
* Initialize Flextype Pages
*
* <code>
* Pages::init();
* </code>
*
* @access public
* @return object
*/
public static function init()
{
return !isset(self::$instance) and self::$instance = new Pages();
}
}

104
flextype/Plugins.php Executable file
View File

@@ -0,0 +1,104 @@
<?php namespace Flextype;
use Symfony\Component\Yaml\Yaml;
/**
* @package Flextype
*
* @author Sergey Romanenko <awilum@yandex.ru>
* @link http://flextype.org
*
* 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 Cache class
*
* @var object
*/
protected static $instance = null;
/**
* Init Plugins
*
* @access public
* @return mixed
*/
protected function __construct()
{
// Plugin manifest
$plugin_manifest = [];
// Plugin cache id
$plugins_cache_id = '';
// 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 (Flextype::$filesystem->exists($_plugin = PLUGINS_PATH . '/' . $plugin . '/' . $plugin . '.yml')) {
$plugins_cache_id .= filemtime($_plugin);
}
}
// Create Unique Cache ID for Plugins
$plugins_cache_id = md5('plugins' . 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 (Flextype::$filesystem->exists($_plugin_manifest = PLUGINS_PATH . '/' . $plugin . '/' . $plugin . '.yml')) {
$plugin_manifest = Yaml::parseFile($_plugin_manifest);
}
$_plugins_config[basename($_plugin_manifest, '.yml')] = $plugin_manifest;
}
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';
}
}
}
Events::dispatch('onPluginsInitialized');
}
/**
* Initialize Flextype Plugins
*
* <code>
* Plugins::init();
* </code>
*
* @access public
* @return object
*/
public static function init()
{
return !isset(self::$instance) and self::$instance = new Plugins();
}
}

131
flextype/Shortcodes.php Normal file
View File

@@ -0,0 +1,131 @@
<?php namespace Flextype;
/**
* @package Flextype
*
* @author Sergey Romanenko <awilum@yandex.ru>
* @link http://flextype.org
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Shortcodes
{
/**
* Shortcode tags array
*
* @var shortcode_tags
*/
protected static $shortcode_tags = [];
/**
* Protected constructor since this is a static class.
*
* @access protected
*/
protected function __construct()
{
// Nothing here
}
/**
* Add new shortcode
*
* @param string $shortcode Shortcode tag to be searched in content.
* @param string $callback_function The callback function to replace the shortcode with.
*/
public static function add(string $shortcode, $callback_function)
{
// Add new shortcode
if (is_callable($callback_function)) {
static::$shortcode_tags[$shortcode] = $callback_function;
}
}
/**
* Remove a specific registered shortcode.
*
* @param string $shortcode Shortcode tag.
*/
public static function delete(string $shortcode)
{
// Delete shortcode
if (static::exists($shortcode)) {
unset(static::$shortcode_tags[$shortcode]);
}
}
/**
* Remove all registered shortcodes.
*
* <code>
* Shortcode::clear();
* </code>
*
*/
public static function clear()
{
static::$shortcode_tags = array();
}
/**
* Check if a shortcode has been registered.
*
* @param string $shortcode Shortcode tag.
*/
public static function exists(string $shortcode)
{
// Check shortcode
return array_key_exists($shortcode, static::$shortcode_tags);
}
/**
* Parse a string, and replace any registered shortcodes within it with the result of the mapped callback.
*
* @param string $content Content
* @return string
*/
public static function parse(string $content)
{
if (! static::$shortcode_tags) {
return $content;
}
$shortcodes = implode('|', array_map('preg_quote', array_keys(static::$shortcode_tags)));
$pattern = "/(.?)\{([$shortcodes]+)(.*?)(\/)?\}(?(4)|(?:(.+?)\{\/\s*\\2\s*\}))?(.?)/s";
return preg_replace_callback($pattern, 'static::_handle', $content);
}
/**
* _handle()
*/
protected static function _handle($matches)
{
$prefix = $matches[1];
$suffix = $matches[6];
$shortcode = $matches[2];
// Allow for escaping shortcodes by enclosing them in {{shortcode}}
if ($prefix == '{' && $suffix == '}') {
return substr($matches[0], 1, -1);
}
$attributes = array(); // Parse attributes into into this array.
if (preg_match_all('/(\w+) *= *(?:([\'"])(.*?)\\2|([^ "\'>]+))/', $matches[3], $match, PREG_SET_ORDER)) {
foreach ($match as $attribute) {
if (! empty($attribute[4])) {
$attributes[strtolower($attribute[1])] = $attribute[4];
} elseif (! empty($attribute[3])) {
$attributes[strtolower($attribute[1])] = $attribute[3];
}
}
}
// Check if this shortcode realy exists then call user function else return empty string
return (isset(static::$shortcode_tags[$shortcode])) ? $prefix . call_user_func(static::$shortcode_tags[$shortcode], $attributes, $matches[5], $shortcode) . $suffix : '';
}
}

47
flextype/Templates.php Normal file
View File

@@ -0,0 +1,47 @@
<?php namespace Flextype;
/**
* @package Flextype
*
* @author Sergey Romanenko <awilum@yandex.ru>
* @link http://flextype.org
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Templates
{
/**
* Protected constructor since this is a static class.
*
* @access protected
*/
protected function __construct()
{
// Nothing here
}
/**
* Get Themes template
*
* @access public
* @param string $template_name Template name
* @return mixed
*/
public static function display(string $template_name)
{
$template_ext = '.php';
$page = Pages::$page;
$template_path = THEMES_PATH . '/' . Config::get('site.theme') . '/' . $template_name . $template_ext;
if (Flextype::$filesystem->exists($template_path)) {
include $template_path;
} else {
throw new RuntimeException("Template {$template_name} does not exist.");
}
}
}

58
flextype/Themes.php Normal file
View File

@@ -0,0 +1,58 @@
<?php namespace Flextype;
use Symfony\Component\Yaml\Yaml;
/**
* @package Flextype
*
* @author Sergey Romanenko <awilum@yandex.ru>
* @link http://flextype.org
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class Themes
{
/**
* An instance of the Themes class
*
* @var object
*/
protected static $instance = null;
/**
* Init Themes
*
* @access public
* @return mixed
*/
protected function __construct()
{
// Theme Manifest
$theme_manifest = [];
// Get current theme
$theme = Config::get('site.theme');
if (Flextype::$filesystem->exists($theme_manifest_file = THEMES_PATH . '/' . $theme . '/' . $theme . '.yml')) {
$theme_manifest = Yaml::parseFile($theme_manifest_file);
Config::set('themes.'.Config::get('site.theme'), $theme_manifest);
}
}
/**
* Initialize Flextype Themes
*
* <code>
* Themes::init();
* </code>
*
* @access public
* @return object
*/
public static function init()
{
return !isset(self::$instance) and self::$instance = new Themes();
}
}