mirror of
https://github.com/flextype/flextype.git
synced 2025-08-18 02:41:27 +02:00
Merge branch 'dev'
This commit is contained in:
12
.github/FUNDING.yml
vendored
Normal file
12
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: awilum
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: awilum
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: https://qiwi.com/p/79805359141
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,5 +1,6 @@
|
||||
# Composer
|
||||
.composer
|
||||
composer.lock
|
||||
vendor/*
|
||||
!*/vendor/*
|
||||
|
||||
|
@@ -1,8 +1,8 @@
|
||||
##
|
||||
# @package Flextype
|
||||
#
|
||||
# @author Sergey Romanenko <awilum@yandex.ru>
|
||||
# @link http://flextype.org
|
||||
# @author Sergey Romanenko <hello@romanenko.digital>
|
||||
# @link http://romanenko.digital
|
||||
#
|
||||
# For the full copyright and license information, please view the LICENSE
|
||||
# file that was distributed with this source code.
|
||||
|
51
CHANGELOG.md
51
CHANGELOG.md
@@ -1,3 +1,54 @@
|
||||
## [0.9.0] - 2019-06-14
|
||||
### Added
|
||||
- Flextype Core: Slim Framework Integration!
|
||||
- Flextype Core: Twig Template Engine Integration!
|
||||
- Flextype Core: Whoops Error Handler Integration!
|
||||
- Flextype Core: Monolog library Integration!
|
||||
- Flextype Core: Slugify library Integration!
|
||||
- Flextype Core: Complete Glide/Intervention Image Implemented for Image manipulation on fly!
|
||||
- Flextype Core: New Event handler from The League of Extraordinary Packages for better event handling.
|
||||
- Flextype Core: New Entries API
|
||||
- Flextype Core: New Fieldsets API
|
||||
- Flextype Core: New Snippets API
|
||||
- Flextype Core: New Plugins API
|
||||
- Flextype Core: New JSON Parser instead of old YAML Parser.
|
||||
- Flextype Core: Using new languages files format and JSON extension instead of YAML.
|
||||
- Flextype Core: Using JSON extension instead of YAML for all kind of data to store.
|
||||
- Flextype Core: New CSRF service for better cross-site request forgery protection.
|
||||
- Flextype Core: composer.json ext-json and ext-mbstring added into require section.
|
||||
- Flextype Core: composer.json suggest section added.
|
||||
- Flextype Core: composer.json: apcu-autoloader added for APCu cache as a fallback for the class map.
|
||||
- Flextype Site: New plugin Site added.
|
||||
- Flextype Core: Respect Validation - The most awesome validation engine ever created for PHP - added.
|
||||
- Flextype Admin Panel: New admin panel plugin based on Slim Framework.
|
||||
- Flextype Admin Panel: Fieldset Sections(groups) added.
|
||||
- Flextype Admin Panel: New Field types - select, editor (instead of html)
|
||||
|
||||
### Changed
|
||||
- Flextype Core: Thunderer Shortcodes don't parse fields by default, need to use filter.
|
||||
- Flextype Core: Thunderer Shortcodes updated to 0.7.2.
|
||||
- Flextype Core: Flextype Components Arr updated to 1.2.5
|
||||
- Flextype Core: Flextype Components Number updated to 1.1.0
|
||||
- Admin Panel: Bootstrap updated to 4.3.1
|
||||
- Admin Panel: Codemirror updated to 5.43.0
|
||||
- Admin Panel: Trumbowyg updated to 2.18.0
|
||||
- Admin Panel: Settings Manager - locales list - improvements!
|
||||
|
||||
### Fixed
|
||||
- Admin Panel: Translates fixes.
|
||||
- Admin Panel: Issue with js error for codemirror - fixed.
|
||||
- Flextype Core: Plugins API - issue with plugins list fixed.
|
||||
|
||||
### Removed
|
||||
- Flextype Admin Panel: Menus Manager removed.
|
||||
- Flextype Core: YAML Parser removed.
|
||||
- Flextype Core: Symfony YAML Component removed.
|
||||
- Flextype Core: Flextype Token Component removed.
|
||||
- Flextype Core: Flextype Notification Component removed.
|
||||
- Flextype Core: Flextype Error Handler Component removed.
|
||||
- Flextype Core: Flextype Event Component removed.
|
||||
|
||||
|
||||
## [0.8.3] - 2019-01-16
|
||||
### Added
|
||||
- Admin Panel: New Gorgeous Light Theme for Admin panel!
|
||||
|
@@ -7,3 +7,4 @@ Flextype is an open source project and community contributions are essential to
|
||||
* Find and [report issues.](https://github.com/flextype/flextype/issues)
|
||||
* Link back to [Flextype](http://flextype.org).
|
||||
* [Donate to keep Flextype free.](http://flextype.org/about/sponsors)
|
||||
* [Join Flextype International Translator Team](https://crowdin.com/project/flextype/invite)
|
||||
|
44
README.md
44
README.md
@@ -1,10 +1,13 @@
|
||||
# Flextype
|
||||
[](https://discordapp.com/invite/CCKPKVG)
|
||||

|
||||

|
||||
|
||||

|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/flextype/flextype/releases"><img alt="Version" src="https://img.shields.io/github/release/flextype/flextype.svg?label=version"></a> <a href="https://github.com/flextype/flextype"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License"></a> <a href="https://github.com/flextype/flextype"><img src="https://img.shields.io/github/downloads/flextype/flextype/total.svg?colorB=blue" alt="Total downloads"></a> <a href="https://crowdin.com/project/flextype"><img src="https://d322cqt584bo4o.cloudfront.net/flextype/localized.svg" alt="Crowdin"></a> <a href="https://scrutinizer-ci.com/g/flextype/flextype?branch=master"><img src="https://img.shields.io/scrutinizer/g/flextype/flextype.svg?branch=master" alt="Quality Score"></a> <a href="https://discordapp.com/invite/CCKPKVG"><img src="https://img.shields.io/discord/423097982498635778.svg?logo=discord&colorB=728ADA&label=Discord%20Chat" alt="Discord"></a>
|
||||
|
||||
</p>
|
||||
|
||||
# Flextype
|
||||
|
||||
Flextype is Open Source, fast and flexible file-based Content Management System.
|
||||
That's Easy to install, upgrade and use. Flextype provides amazing API's for plugins, themes and core developers!
|
||||
|
||||
@@ -41,8 +44,11 @@ Make sure your server meets the following requirements.
|
||||
#### PHP extensions
|
||||
Flextype needs the following PHP extensions to be enabled:
|
||||
|
||||
- Multibyte String
|
||||
- SPL
|
||||
- PHP [mbstring](http://php.net/manual/en/book.mbstring.php) module for full UTF-8 support.
|
||||
- PHP [gd](http://php.net/manual/en/book.image.php) module for image processing.
|
||||
- PHP [json](https://php.net/manual/en/book.json.php) module for JSON manipulation.
|
||||
- PHP [Fileinfo](https://www.php.net/manual/en/book.fileinfo.php)
|
||||
- PHP [SPL](https://www.php.net/manual/en/book.spl.php)
|
||||
|
||||
Although it is optional, we strongly recommend enabling the following PHP extensions:
|
||||
APC, APCu, XCache, Memcached, or Redis for better performance.
|
||||
@@ -64,7 +70,7 @@ Mobile
|
||||
|
||||
#### Using (S)FTP
|
||||
|
||||
[Download the latest version.](http://flextype.org/download)
|
||||
[Download the latest version.](http://flextype.org/en/downloads)
|
||||
|
||||
Unzip the contents to a new folder on your local computer, and upload to your webhost using the (S)FTP client of your choice. After you’ve done this, be sure to chmod the following directories (with containing files) to 755(or 777), so they are readable and writable by Flextype:
|
||||
* `site/`
|
||||
@@ -77,16 +83,20 @@ You can easily install Flextype with Composer.
|
||||
composer create-project flextype/flextype
|
||||
```
|
||||
|
||||
Install vendor libs for Flextype
|
||||
```
|
||||
composer install
|
||||
```
|
||||
|
||||
Install vendor libs for Default Theme
|
||||
|
||||
```
|
||||
composer install
|
||||
cd site/themes/default
|
||||
npm install
|
||||
gulp
|
||||
```
|
||||
|
||||
Install vendor libs for Admin Panel
|
||||
Install vendor libs for Admin Panel plugin
|
||||
|
||||
```
|
||||
cd site/plugins/admin
|
||||
@@ -95,6 +105,15 @@ npm install
|
||||
gulp
|
||||
```
|
||||
|
||||
Install vendor libs for Site plugin
|
||||
|
||||
```
|
||||
cd site/plugins/site
|
||||
composer install
|
||||
npm install
|
||||
gulp
|
||||
```
|
||||
|
||||
## COMMUNITY
|
||||
Flextype is open source, community driven project, and maintained by community!
|
||||
|
||||
@@ -120,17 +139,18 @@ With Flextype you can create any project you want.
|
||||
## CONTRIBUTE
|
||||
Flextype is an open source project and community contributions are essential to its growing and success. Contributing to the Flextype is easy and you can give as little or as much time as you want.
|
||||
|
||||
* Help on the [Communities.](http://flextype.org/documentation/basics/getting-help)
|
||||
* Help on the [Communities.](http://flextype.org/en/documentation/guide/basics/getting-help)
|
||||
* Develop a new plugin.
|
||||
* Create a new theme.
|
||||
* Find and [report issues.](https://github.com/flextype/flextype/issues)
|
||||
* Link back to [Flextype](http://flextype.org).
|
||||
* [Donate to keep Flextype free.](http://flextype.org/about/sponsors)
|
||||
* [Donate to keep Flextype free.](http://flextype.org/en/about/sponsors)
|
||||
* [Join Flextype International Translator Team](https://crowdin.com/project/flextype/invite)
|
||||
|
||||
|
||||
## LINKS
|
||||
- [Site](http://flextype.org)
|
||||
- [Documentation](http://flextype.org/documentation)
|
||||
- [Documentation](http://flextype.org/en/documentation)
|
||||
|
||||
|
||||
## LICENSE
|
||||
|
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "flextype/flextype",
|
||||
"type": "project",
|
||||
"description": "Modern Open Source Flat-File Content Management System",
|
||||
"description": "Build fast, flexible, easier to manage websites with Flextype.",
|
||||
"keywords": ["flextype", "php", "cms", "flat-file cms", "flat cms", "flatfile cms", "html"],
|
||||
"homepage": "http://flextype.org",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Sergey Romanenko",
|
||||
"email": "awilum@yandex.ru",
|
||||
"homepage": "https://github.com/Awilum"
|
||||
"email": "hello@romanenko.digital",
|
||||
"homepage": "http://romanenko.digital"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
@@ -17,29 +17,51 @@
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1.3",
|
||||
"doctrine/cache": "1.8.0",
|
||||
"symfony/yaml": "4.2.2",
|
||||
"thunderer/shortcode": "0.7.0",
|
||||
"flextype-components/arr" : "1.2.4",
|
||||
"flextype-components/assets" : "1.0.1",
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
|
||||
"doctrine/cache": "^1.8.0",
|
||||
"thunderer/shortcode": "^0.7.2",
|
||||
|
||||
"flextype-components/arr" : "1.2.5",
|
||||
"flextype-components/assets" : "1.0.3",
|
||||
"flextype-components/cookie" : "1.2.0",
|
||||
"flextype-components/date" : "1.0.0",
|
||||
"flextype-components/debug" : "1.0.0",
|
||||
"flextype-components/event" : "1.0.4",
|
||||
"flextype-components/errorhandler" : "1.0.5",
|
||||
"flextype-components/filesystem" : "1.1.5",
|
||||
"flextype-components/form" : "1.0.2",
|
||||
"flextype-components/filesystem" : "2.0.3",
|
||||
"flextype-components/i18n" : "1.2.0",
|
||||
"flextype-components/http" : "1.1.1",
|
||||
"flextype-components/html" : "1.0.0",
|
||||
"flextype-components/number" : "1.0.0",
|
||||
"flextype-components/notification" : "1.0.1",
|
||||
"flextype-components/registry" : "1.1.0",
|
||||
"flextype-components/number" : "1.1.0",
|
||||
"flextype-components/registry" : "2.0.0",
|
||||
"flextype-components/session" : "1.1.1",
|
||||
"flextype-components/token" : "1.2.0",
|
||||
"flextype-components/view" : "1.1.1",
|
||||
"flextype-components/text" : "1.1.2",
|
||||
"league/glide": "^1.4"
|
||||
"flextype-components/form" : "1.0.2",
|
||||
|
||||
"slim/slim": "^3.0",
|
||||
"slim/twig-view": "^2.5",
|
||||
"slim/flash": "^0.4.0",
|
||||
"slim/csrf": "^0.8.3",
|
||||
"zeuxisoo/slim-whoops": "^0.6.0",
|
||||
|
||||
"league/glide-slim": "^1.0",
|
||||
"league/event": "^2.2",
|
||||
"league/glide": "^1.5",
|
||||
|
||||
"respect/validation": "^1.0",
|
||||
"monolog/monolog": "^1.24",
|
||||
"cocur/slugify": "^3.2",
|
||||
"oscarotero/psr7-middlewares": "^3.21"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-zend-opcache": "Recommended for better performance",
|
||||
"ext-memcache": "Needed to support Memcache servers",
|
||||
"ext-memcached": "Needed to support Memcached servers",
|
||||
"ext-redis": "Needed to support Redis servers"
|
||||
},
|
||||
"config": {
|
||||
"apcu-autoloader": true,
|
||||
"platform": {
|
||||
"php": "7.1.3"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
|
3
crowdin.yml
Normal file
3
crowdin.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
files:
|
||||
- source: /site/plugins/admin/lang/en_US.json
|
||||
translation: /site/plugins/admin/lang/%locale_with_underscore%.json
|
@@ -1,365 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
use Flextype\Component\Registry\Registry;
|
||||
use \Doctrine\Common\Cache as DoctrineCache;
|
||||
|
||||
class Cache
|
||||
{
|
||||
/**
|
||||
* An instance of the Cache class
|
||||
*
|
||||
* @var object
|
||||
* @access private
|
||||
*/
|
||||
private 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;
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
Cache::init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Init Cache
|
||||
*
|
||||
* @access protected
|
||||
* @return void
|
||||
*/
|
||||
protected static function init() : void
|
||||
{
|
||||
// Create Cache Directory
|
||||
!Filesystem::dirExists(PATH['cache']) and Filesystem::createDir(PATH['cache']);
|
||||
|
||||
// Set current time
|
||||
Cache::$now = time();
|
||||
|
||||
// Create cache key to allow invalidate all cache on configuration changes.
|
||||
Cache::$key = (Registry::get('settings.cache.prefix') ?? 'flextype') . '-' . md5(PATH['site'] . Flextype::VERSION);
|
||||
|
||||
// Get Cache Driver
|
||||
Cache::$driver = Cache::getCacheDriver();
|
||||
|
||||
// Set the cache namespace to our unique key
|
||||
Cache::$driver->setNamespace(Cache::$key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Cache Driver
|
||||
*
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public static function getCacheDriver()
|
||||
{
|
||||
$driver_name = Registry::get('settings.cache.driver');
|
||||
|
||||
$cache_directory = PATH['cache'] . '/doctrine/';
|
||||
|
||||
if (!$driver_name || $driver_name == 'auto') {
|
||||
if (extension_loaded('apcu')) {
|
||||
$driver_name = 'apcu';
|
||||
} elseif (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) {
|
||||
// The ApcCache driver uses the apc_fetch, apc_exists, etc. functions
|
||||
// that come with PHP so no additional setup is required in order to use it.
|
||||
case 'apc':
|
||||
$driver = new DoctrineCache\ApcCache();
|
||||
break;
|
||||
// The ApcuCache driver uses the apcu_fetch, apcu_exists, etc. functions
|
||||
// that come with PHP so no additional setup is required in order to use it.
|
||||
case 'apcu':
|
||||
$driver = new DoctrineCache\ApcuCache();
|
||||
break;
|
||||
// The ArrayCache driver stores the cache data in PHPs memory and is not persisted anywhere.
|
||||
// This can be useful for caching things in memory for a single process when you don't need the cache to be persistent across processes.
|
||||
case 'array':
|
||||
$driver = new DoctrineCache\ArrayCache();
|
||||
break;
|
||||
// The WinCacheCache driver uses the wincache_ucache_get, wincache_ucache_exists, etc. functions
|
||||
// that come with the wincache extension
|
||||
// http://php.net/manual/en/book.wincache.php
|
||||
case 'wincache':
|
||||
$driver = new DoctrineCache\WinCacheCache();
|
||||
break;
|
||||
// The XcacheCache driver uses functions that come with the xcache extension
|
||||
// https://xcache.lighttpd.net
|
||||
case 'xcache':
|
||||
$driver = new DoctrineCache\XcacheCache();
|
||||
break;
|
||||
// The MemcacheCache drivers stores the cache data in Memcache.
|
||||
case 'memcache':
|
||||
$memcache = new \Memcache();
|
||||
$memcache->connect(
|
||||
Registry::get('settings.cache.memcache.server', 'localhost'),
|
||||
Registry::get('settings.cache.memcache.port', 11211)
|
||||
);
|
||||
$driver = new DoctrineCache\MemcacheCache();
|
||||
$driver->setMemcache($memcache);
|
||||
break;
|
||||
// The MemcachedCache drivers stores the cache data in Memcached.
|
||||
case 'memcached':
|
||||
$memcached = new \Memcached();
|
||||
$memcached->addServer(
|
||||
Registry::get('settings.cache.memcached.server', 'localhost'),
|
||||
Registry::get('settings.cache.memcache.port', 11211)
|
||||
);
|
||||
$driver = new DoctrineCache\MemcachedCache();
|
||||
$driver->setMemcached($memcached);
|
||||
break;
|
||||
// The SQLite3Cache driver stores the cache data in a SQLite database and depends on the sqlite3 extension
|
||||
// http://php.net/manual/en/book.sqlite3.php
|
||||
case 'sqlite3':
|
||||
// Create doctrine cache directory if its not exists
|
||||
!Filesystem::fileExists($cache_directory) and Filesystem::createDir($cache_directory);
|
||||
|
||||
$db = new \SQLite3($cache_directory . Registry::get('settings.cache.sqlite3.database', 'flextype') . '.db');
|
||||
$driver = new DoctrineCache\SQLite3Cache($db, Registry::get('settings.cache.sqlite3.table', 'flextype'));
|
||||
break;
|
||||
// The ZendDataCache driver uses the Zend Data Cache API available in the Zend Platform.
|
||||
case 'zend':
|
||||
$driver = new DoctrineCache\ZendDataCache();
|
||||
break;
|
||||
// The RedisCache driver stores the cache data in Redis and depends on the phpredis extension
|
||||
// https://github.com/phpredis/phpredis
|
||||
case 'redis':
|
||||
$redis = new \Redis();
|
||||
$socket = Registry::get('settings.cache.redis.socket', false);
|
||||
$password = Registry::get('settings.cache.redis.password', false);
|
||||
|
||||
if ($socket) {
|
||||
$redis->connect($socket);
|
||||
} else {
|
||||
$redis->connect(
|
||||
Registry::get('settings.cache.redis.server', 'localhost'),
|
||||
Registry::get('settings.cache.redis.port', 6379)
|
||||
);
|
||||
}
|
||||
|
||||
// Authenticate with password if set
|
||||
if ($password && !$redis->auth($password)) {
|
||||
throw new \RedisException('Redis authentication failed');
|
||||
}
|
||||
|
||||
$driver = new DoctrineCache\RedisCache();
|
||||
$driver->setRedis($redis);
|
||||
break;
|
||||
default:
|
||||
// Create doctrine cache directory if its not exists
|
||||
!Filesystem::fileExists($cache_directory) and Filesystem::createDir($cache_directory);
|
||||
$driver = new DoctrineCache\FilesystemCache($cache_directory);
|
||||
break;
|
||||
}
|
||||
return $driver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns driver variable
|
||||
*
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public static function driver()
|
||||
{
|
||||
return Cache::$driver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cache key.
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public static function getKey() : string
|
||||
{
|
||||
return Cache::$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 static function fetch(string $id)
|
||||
{
|
||||
if (Registry::get('settings.cache.enabled')) {
|
||||
return Cache::$driver->fetch($id);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a boolean state of whether or not the item exists in the cache based on id key
|
||||
*
|
||||
* @param string $id the id of the cached data entry
|
||||
* @return bool true if the cached items exists
|
||||
*/
|
||||
public static function contains($id)
|
||||
{
|
||||
if (Registry::get('settings.cache.enabled')) {
|
||||
return Cache::$driver->contains(($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 static function save(string $id, $data, $lifetime = null)
|
||||
{
|
||||
if (Registry::get('settings.cache.enabled')) {
|
||||
if ($lifetime === null) {
|
||||
$lifetime = Cache::getLifetime();
|
||||
}
|
||||
Cache::$driver->save($id, $data, $lifetime);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear Cache
|
||||
*/
|
||||
public static function clear() : void
|
||||
{
|
||||
// Clear stat cache
|
||||
@clearstatcache();
|
||||
|
||||
// Clear opcache
|
||||
function_exists('opcache_reset') and @opcache_reset();
|
||||
|
||||
// Remove cache dirs
|
||||
Filesystem::deleteDir(PATH['cache'] . '/doctrine/');
|
||||
Filesystem::deleteDir(PATH['cache'] . '/glide/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the cache lifetime.
|
||||
*
|
||||
* @access public
|
||||
* @param int $future timestamp
|
||||
*/
|
||||
public static function setLifetime(int $future)
|
||||
{
|
||||
if (!$future) {
|
||||
return;
|
||||
}
|
||||
|
||||
$interval = $future - Cache::$now;
|
||||
|
||||
if ($interval > 0 && $interval < Cache::getLifetime()) {
|
||||
Cache::$lifetime = $interval;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the cache lifetime (in seconds)
|
||||
*
|
||||
* @access public
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getLifetime()
|
||||
{
|
||||
if (Cache::$lifetime === null) {
|
||||
Cache::$lifetime = Registry::get('settings.cache.lifetime') ?: 604800;
|
||||
}
|
||||
|
||||
return Cache::$lifetime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Cache instance.
|
||||
*
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
if (is_null(Cache::$instance)) {
|
||||
Cache::$instance = new self;
|
||||
}
|
||||
|
||||
return Cache::$instance;
|
||||
}
|
||||
}
|
@@ -1,500 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
|
||||
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 Entries
|
||||
{
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
Entries::init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Init Entry
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
private static function init() : void
|
||||
{
|
||||
Entries::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
|
||||
Entries::initParsers();
|
||||
|
||||
// Event: The entry has been not loaded.
|
||||
Event::dispatch('onCurrentEntryBeforeLoaded');
|
||||
|
||||
// Set current requested entry data to global $entry array
|
||||
Entries::$entry = Entries::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
|
||||
Entries::displayCurrentEntry();
|
||||
|
||||
// Event: The entry has been fully processed and sent to the display.
|
||||
Event::dispatch('onCurrentEntryAfterProcessed');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current entry
|
||||
*
|
||||
* $entry = Entries::getCurrentPage();
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public static function getCurrentEntry() : array
|
||||
{
|
||||
return Entries::$entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update current entry
|
||||
*
|
||||
* Entries::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(Entries::$entry, $path, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get entry
|
||||
*
|
||||
* $entry = Entries::getEntry('projects');
|
||||
*
|
||||
* @access public
|
||||
* @param string $url Page url.
|
||||
* @param bool $raw Parse content or raw content without parsing.
|
||||
* @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 = Entries::processEntry($file_path, true);
|
||||
} else {
|
||||
$entry = Entries::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 = Entries::getError404Entry();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Cache::save($entry_cache_id, $entry);
|
||||
return $entry;
|
||||
}
|
||||
} else {
|
||||
return Entries::getError404Entry();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get entries
|
||||
*
|
||||
* // Get list of subentries for entry 'projects'
|
||||
* $entries = Entries::getEntries('projects');
|
||||
*
|
||||
* // Get list of subentries for entry 'projects' and order by date and order type DESC
|
||||
* $entries = Entries::getEntries('projects', false, 'date', 'DESC');
|
||||
*
|
||||
* @access public
|
||||
* @param string $url Page url.
|
||||
* @param string $order_by Order by specific entry field.
|
||||
* @param string $order_type Order type: DESC or ASC
|
||||
* @param int $offset Offset
|
||||
* @param int $length Length
|
||||
* @param bool $multilevel Get nested entries or not.
|
||||
* @param bool $raw Parse content or raw content without parsing.
|
||||
* @return array
|
||||
*/
|
||||
public static function getEntries(string $url = '', string $order_by = 'date', string $order_type = 'DESC', int $offset = null, int $length = null, bool $multilevel = false, bool $raw = false) : 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] = Entries::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] = Entries::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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Error404 entry
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns $shortcode object
|
||||
*
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public static function shortcode() : ShortcodeFacade
|
||||
{
|
||||
return Entries::$shortcode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Front matter parser
|
||||
*
|
||||
* $content = Entries::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 = Entries::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 = Entries::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(Entries::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 base url
|
||||
$_entry['base_url'] = Http::getBaseUrl() . '/site/entries/';
|
||||
|
||||
// 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'] = Entries::processContent($entry_content);
|
||||
}
|
||||
|
||||
// Return entry
|
||||
return $_entry;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process shortcodes
|
||||
*
|
||||
* $content = Entries::processShortcodes($content);
|
||||
*
|
||||
* @access public
|
||||
* @param string $content Content to parse
|
||||
* @return string
|
||||
*/
|
||||
public static function processShortcodes(string $content) : string
|
||||
{
|
||||
return Entries::shortcode()->process($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process content with markdown and shortcodes processors
|
||||
*
|
||||
* $content = Entries::processContent($content);
|
||||
*
|
||||
* @access public
|
||||
* @param string $content Content to parse
|
||||
* @return string
|
||||
*/
|
||||
public static function processContent(string $content) : string
|
||||
{
|
||||
return Entries::processShortcodes($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Init Parsers
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
private static function initParsers() : void
|
||||
{
|
||||
// Init Shortcodes
|
||||
Entries::initShortcodes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Init Shortcodes
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
private static function initShortcodes() : void
|
||||
{
|
||||
// Create Shortcode Parser object
|
||||
Entries::$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(Entries::$entry['template']) ? 'templates/default' : 'templates/' . Entries::$entry['template'])
|
||||
->assign('entry', Entries::$entry, true)
|
||||
->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Content instance.
|
||||
*
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
if (is_null(Entries::$instance)) {
|
||||
Entries::$instance = new self;
|
||||
}
|
||||
|
||||
return Entries::$instance;
|
||||
}
|
||||
}
|
@@ -1,185 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Http\Http;
|
||||
use Flextype\Component\Session\Session;
|
||||
use Flextype\Component\ErrorHandler\ErrorHandler;
|
||||
use Flextype\Component\Registry\Registry;
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
|
||||
class Flextype
|
||||
{
|
||||
/**
|
||||
* The version of Flextype
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const VERSION = '0.8.3';
|
||||
|
||||
/**
|
||||
* An instance of the Flextype class
|
||||
*
|
||||
* @var object
|
||||
* @access private
|
||||
*/
|
||||
private static $instance = null;
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
Flextype::init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Init Flextype Application
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private static function init() : void
|
||||
{
|
||||
// Turn on output buffering
|
||||
ob_start();
|
||||
|
||||
// Set Flextype config
|
||||
Flextype::setConfig();
|
||||
|
||||
// Set internal encoding
|
||||
function_exists('mb_language') and mb_language('uni');
|
||||
function_exists('mb_regex_encoding') and mb_regex_encoding(Registry::get('settings.charset'));
|
||||
function_exists('mb_internal_encoding') and mb_internal_encoding(Registry::get('settings.charset'));
|
||||
|
||||
// Set error handler
|
||||
Flextype::setErrorHandler();
|
||||
|
||||
// Set default timezone
|
||||
date_default_timezone_set(Registry::get('settings.timezone'));
|
||||
|
||||
// Start the session
|
||||
Session::start();
|
||||
|
||||
// Get Cache Instance
|
||||
Cache::getInstance();
|
||||
|
||||
// Get Images Instance
|
||||
Images::getInstance();
|
||||
|
||||
// Get Snippets Instance
|
||||
Snippets::getInstance();
|
||||
|
||||
// Get Themes Instance
|
||||
Themes::getInstance();
|
||||
|
||||
// Get Plugins Instance
|
||||
Plugins::getInstance();
|
||||
|
||||
// Get Entries Instance
|
||||
Entries::getInstance();
|
||||
|
||||
// Flush (send) the output buffer and turn off output buffering
|
||||
ob_end_flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set error handler
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private static function setErrorHandler() : void
|
||||
{
|
||||
// Display Errors
|
||||
if (Registry::get('settings.errors.display')) {
|
||||
define('DEVELOPMENT', true);
|
||||
error_reporting(-1);
|
||||
} else {
|
||||
define('DEVELOPMENT', false);
|
||||
error_reporting(0);
|
||||
}
|
||||
|
||||
// Create directory for logs
|
||||
!Filesystem::fileExists(LOGS_PATH) and Filesystem::createDir(LOGS_PATH);
|
||||
|
||||
// Set Error handler
|
||||
set_error_handler('Flextype\Component\ErrorHandler\ErrorHandler::error');
|
||||
register_shutdown_function('Flextype\Component\ErrorHandler\ErrorHandler::fatal');
|
||||
set_exception_handler('Flextype\Component\ErrorHandler\ErrorHandler::exception');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set config
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private static function setConfig() : void
|
||||
{
|
||||
// Set empty site settings array
|
||||
Registry::set('settings', []);
|
||||
|
||||
// Set settings files path
|
||||
$default_settings_file_path = PATH['config']['default'] . '/settings.yaml';
|
||||
$site_settings_file_path = PATH['config']['site'] . '/settings.yaml';
|
||||
|
||||
// Set settings if Flextype settings and Site settings config files exist
|
||||
if (Filesystem::fileExists($default_settings_file_path) && Filesystem::fileExists($site_settings_file_path)) {
|
||||
|
||||
// Get Flextype settings and Site settings
|
||||
$default_settings = YamlParser::decode(Filesystem::getFileContent($default_settings_file_path));
|
||||
$site_settings = YamlParser::decode(Filesystem::getFileContent($site_settings_file_path));
|
||||
|
||||
// Merge settings
|
||||
$settings = array_replace_recursive($default_settings, $site_settings);
|
||||
|
||||
// Set settings
|
||||
Registry::set('settings', $settings);
|
||||
} else {
|
||||
throw new \RuntimeException("Flextype settings and Site settings config files does not exist.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Flextype instance.
|
||||
*
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
if (is_null(Flextype::$instance)) {
|
||||
Flextype::$instance = new self;
|
||||
}
|
||||
|
||||
return Flextype::$instance;
|
||||
}
|
||||
}
|
@@ -1,274 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Http\Http;
|
||||
use Flextype\Component\Event\Event;
|
||||
use Flextype\Component\Html\Html;
|
||||
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
|
||||
|
||||
// Event: onShortcodesInitialized
|
||||
Event::addListener('onShortcodesInitialized', function () {
|
||||
|
||||
// Shortcode: [image path="home/image.jpg"]
|
||||
// Result: Display image
|
||||
Entries::shortcode()->addHandler('image', function(ShortcodeInterface $s) {
|
||||
$params = [];
|
||||
$attributes = [];
|
||||
|
||||
// API
|
||||
// http://glide.thephpleague.com/1.0/api/quick-reference/
|
||||
($s->getParameter('or')) and $params['or'] = $s->getParameter('or');
|
||||
($s->getParameter('flip')) and $params['flip'] = $s->getParameter('flip');
|
||||
($s->getParameter('crop')) and $params['crop'] = $s->getParameter('crop');
|
||||
($s->getParameter('w')) and $params['w'] = $s->getParameter('w');
|
||||
($s->getParameter('h')) and $params['h'] = $s->getParameter('h');
|
||||
($s->getParameter('fit')) and $params['fit'] = $s->getParameter('fit');
|
||||
($s->getParameter('dpr')) and $params['dpr'] = $s->getParameter('dpr');
|
||||
($s->getParameter('bri')) and $params['bri'] = $s->getParameter('bri');
|
||||
($s->getParameter('con')) and $params['con'] = $s->getParameter('con');
|
||||
($s->getParameter('gam')) and $params['gam'] = $s->getParameter('gam');
|
||||
($s->getParameter('sharp')) and $params['sharp'] = $s->getParameter('sharp');
|
||||
($s->getParameter('blur')) and $params['blur'] = $s->getParameter('blur');
|
||||
($s->getParameter('pixel')) and $params['pixel'] = $s->getParameter('pixel');
|
||||
($s->getParameter('filt')) and $params['filt'] = $s->getParameter('filt');
|
||||
($s->getParameter('mark')) and $params['mark'] = $s->getParameter('mark');
|
||||
($s->getParameter('markw')) and $params['markw'] = $s->getParameter('markw');
|
||||
($s->getParameter('markh')) and $params['markh'] = $s->getParameter('markh');
|
||||
($s->getParameter('markx')) and $params['markx'] = $s->getParameter('markx');
|
||||
($s->getParameter('marky')) and $params['marky'] = $s->getParameter('marky');
|
||||
($s->getParameter('markpad')) and $params['markpad'] = $s->getParameter('markpad');
|
||||
($s->getParameter('markpos')) and $params['markpos'] = $s->getParameter('markpos');
|
||||
($s->getParameter('markalpha')) and $params['markalpha'] = $s->getParameter('markalpha');
|
||||
($s->getParameter('bg')) and $params['bg'] = $s->getParameter('bg');
|
||||
($s->getParameter('border')) and $params['border'] = $s->getParameter('border');
|
||||
($s->getParameter('q')) and $params['q'] = $s->getParameter('q');
|
||||
($s->getParameter('fm')) and $params['fm'] = $s->getParameter('fm');
|
||||
|
||||
($s->getParameter('width')) and $attributes['width'] = $s->getParameter('width');
|
||||
($s->getParameter('height')) and $attributes['height'] = $s->getParameter('height');
|
||||
($s->getParameter('class')) and $attributes['class'] = $s->getParameter('class');
|
||||
($s->getParameter('id')) and $attributes['id'] = $s->getParameter('id');
|
||||
($s->getParameter('alt')) and $attributes['alt'] = $s->getParameter('alt');
|
||||
|
||||
return Images::getImage($s->getParameter('path'), $params, $attributes);
|
||||
});
|
||||
|
||||
// Shortcode: [image_url path="home/image.jpg"]
|
||||
// Result: Display image url
|
||||
Entries::shortcode()->addHandler('image_url', function(ShortcodeInterface $s) {
|
||||
$params = [];
|
||||
|
||||
// API
|
||||
// http://glide.thephpleague.com/1.0/api/quick-reference/
|
||||
($s->getParameter('or')) and $params['or'] = $s->getParameter('or');
|
||||
($s->getParameter('flip')) and $params['flip'] = $s->getParameter('flip');
|
||||
($s->getParameter('crop')) and $params['crop'] = $s->getParameter('crop');
|
||||
($s->getParameter('w')) and $params['w'] = $s->getParameter('w');
|
||||
($s->getParameter('h')) and $params['h'] = $s->getParameter('h');
|
||||
($s->getParameter('fit')) and $params['fit'] = $s->getParameter('fit');
|
||||
($s->getParameter('dpr')) and $params['dpr'] = $s->getParameter('dpr');
|
||||
($s->getParameter('bri')) and $params['bri'] = $s->getParameter('bri');
|
||||
($s->getParameter('con')) and $params['con'] = $s->getParameter('con');
|
||||
($s->getParameter('gam')) and $params['gam'] = $s->getParameter('gam');
|
||||
($s->getParameter('sharp')) and $params['sharp'] = $s->getParameter('sharp');
|
||||
($s->getParameter('blur')) and $params['blur'] = $s->getParameter('blur');
|
||||
($s->getParameter('pixel')) and $params['pixel'] = $s->getParameter('pixel');
|
||||
($s->getParameter('filt')) and $params['filt'] = $s->getParameter('filt');
|
||||
($s->getParameter('mark')) and $params['mark'] = $s->getParameter('mark');
|
||||
($s->getParameter('markw')) and $params['markw'] = $s->getParameter('markw');
|
||||
($s->getParameter('markh')) and $params['markh'] = $s->getParameter('markh');
|
||||
($s->getParameter('markx')) and $params['markx'] = $s->getParameter('markx');
|
||||
($s->getParameter('marky')) and $params['marky'] = $s->getParameter('marky');
|
||||
($s->getParameter('markpad')) and $params['markpad'] = $s->getParameter('markpad');
|
||||
($s->getParameter('markpos')) and $params['markpos'] = $s->getParameter('markpos');
|
||||
($s->getParameter('markalpha')) and $params['markalpha'] = $s->getParameter('markalpha');
|
||||
($s->getParameter('bg')) and $params['bg'] = $s->getParameter('bg');
|
||||
($s->getParameter('border')) and $params['border'] = $s->getParameter('border');
|
||||
($s->getParameter('q')) and $params['q'] = $s->getParameter('q');
|
||||
($s->getParameter('fm')) and $params['fm'] = $s->getParameter('fm');
|
||||
|
||||
return Images::getImageUrl($s->getParameter('path'), $params);
|
||||
});
|
||||
});
|
||||
|
||||
class Images
|
||||
{
|
||||
/**
|
||||
* An instance of the Themes class
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
private static $instance = null;
|
||||
|
||||
/**
|
||||
* Images Server
|
||||
*
|
||||
* @var
|
||||
*/
|
||||
protected static $server;
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
Images::init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Init Images
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
private static function init() : void
|
||||
{
|
||||
// Set source filesystem
|
||||
$source = new \League\Flysystem\Filesystem(
|
||||
new \League\Flysystem\Adapter\Local(PATH['entries'])
|
||||
);
|
||||
|
||||
// Set cache filesystem
|
||||
$cache = new \League\Flysystem\Filesystem(
|
||||
new \League\Flysystem\Adapter\Local(PATH['cache'] . '/glide')
|
||||
);
|
||||
|
||||
// Set watermarks filesystem
|
||||
$watermarks = new \League\Flysystem\Filesystem(
|
||||
new \League\Flysystem\Adapter\Local(PATH['site'] . '/watermarks')
|
||||
);
|
||||
|
||||
// Set image manager
|
||||
$imageManager = new \Intervention\Image\ImageManager([
|
||||
'driver' => 'gd',
|
||||
]);
|
||||
|
||||
// Set manipulators
|
||||
$manipulators = [
|
||||
new \League\Glide\Manipulators\Orientation(),
|
||||
new \League\Glide\Manipulators\Crop(),
|
||||
new \League\Glide\Manipulators\Size(2000*2000),
|
||||
new \League\Glide\Manipulators\Brightness(),
|
||||
new \League\Glide\Manipulators\Contrast(),
|
||||
new \League\Glide\Manipulators\Gamma(),
|
||||
new \League\Glide\Manipulators\Sharpen(),
|
||||
new \League\Glide\Manipulators\Filter(),
|
||||
new \League\Glide\Manipulators\Blur(),
|
||||
new \League\Glide\Manipulators\Pixelate(),
|
||||
new \League\Glide\Manipulators\Watermark($watermarks),
|
||||
new \League\Glide\Manipulators\Background(),
|
||||
new \League\Glide\Manipulators\Border(),
|
||||
new \League\Glide\Manipulators\Encode(),
|
||||
];
|
||||
|
||||
// Set API
|
||||
$api = new \League\Glide\Api\Api($imageManager, $manipulators);
|
||||
|
||||
// Setup Glide server
|
||||
$server = new \League\Glide\Server(
|
||||
$source,
|
||||
$cache,
|
||||
$api
|
||||
);
|
||||
|
||||
Images::$server = $server;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get image url
|
||||
*
|
||||
* Images::getImageUrl('page-name/image.jpg', [w => '200']);
|
||||
* http://glide.thephpleague.com/1.0/api/quick-reference/
|
||||
*
|
||||
* @access public
|
||||
* @param string $path Image path
|
||||
* @param array $params Image params
|
||||
* @return string
|
||||
*/
|
||||
public static function getImageUrl($path, array $params)
|
||||
{
|
||||
if (file_exists(PATH['entries'] . '/' . $path)) {
|
||||
return Http::getBaseUrl() . '/site/cache/glide/' . Images::$server->makeImage($path, $params);
|
||||
} else {
|
||||
return "File {$path} does not exist.";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get image
|
||||
*
|
||||
* Images::getImage('page-name/image.jpg', [w => '200']);
|
||||
* http://glide.thephpleague.com/1.0/api/quick-reference/
|
||||
*
|
||||
* @access public
|
||||
* @param string $path Image path
|
||||
* @param array $params Image params
|
||||
* @param array $attributes Image html attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function getImage($path, array $params, array $attributes = [])
|
||||
{
|
||||
if (file_exists(PATH['entries'] . '/' . $path)) {
|
||||
return '<img '.Html::attributes($attributes).' src="'. Images::getImageUrl($path, $params) .'">';
|
||||
} else {
|
||||
return "File {$path} does not exist.";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns server variable
|
||||
*
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public static function server()
|
||||
{
|
||||
return Images::$server;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Image instance.
|
||||
*
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
if (is_null(Images::$instance)) {
|
||||
Images::$instance = new self;
|
||||
}
|
||||
|
||||
return Images::$instance;
|
||||
}
|
||||
}
|
@@ -1,38 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
|
||||
class Menus
|
||||
{
|
||||
/**
|
||||
* Get menu
|
||||
*
|
||||
* Menu::get('menu-name');
|
||||
*
|
||||
* @access public
|
||||
* @param string $menu_name Menu name
|
||||
* @return array
|
||||
*/
|
||||
public static function get(string $menu_name)
|
||||
{
|
||||
$menu_path = PATH['menus'] . '/' . $menu_name . '.yaml';
|
||||
|
||||
if (Filesystem::fileExists($menu_path)) {
|
||||
return YamlParser::decode(Filesystem::getFileContent($menu_path));
|
||||
} else {
|
||||
throw new \RuntimeException("Menu {$menu_name} does not exist.");
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,357 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
use Flextype\Component\Event\Event;
|
||||
use Flextype\Component\I18n\I18n;
|
||||
use Flextype\Component\Registry\Registry;
|
||||
|
||||
class Plugins
|
||||
{
|
||||
/**
|
||||
* An instance of the Cache class
|
||||
*
|
||||
* @var object
|
||||
* @access private
|
||||
*/
|
||||
private static $instance = null;
|
||||
|
||||
/**
|
||||
* Locales array
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $locales = [
|
||||
'om' => 'Afaan Oromoo',
|
||||
'aa' => 'Afaraf',
|
||||
'af' => 'Afrikaans',
|
||||
'ak' => 'Akan',
|
||||
'an' => 'aragonés',
|
||||
'ig' => 'Asụsụ Igbo',
|
||||
'gn' => 'Avañe\'ẽ',
|
||||
'ae' => 'avesta',
|
||||
'ay' => 'aymar aru',
|
||||
'az' => 'azərbaycan dili',
|
||||
'id' => 'Bahasa Indonesia',
|
||||
'ms' => 'bahasa Melayu',
|
||||
'bm' => 'bamanankan',
|
||||
'jv' => 'basa Jawa',
|
||||
'su' => 'Basa Sunda',
|
||||
'bi' => 'Bislama',
|
||||
'bs' => 'bosanski jezik',
|
||||
'br' => 'brezhoneg',
|
||||
'ca' => 'català',
|
||||
'ch' => 'Chamoru',
|
||||
'ny' => 'chiCheŵa',
|
||||
'sn' => 'chiShona',
|
||||
'co' => 'corsu',
|
||||
'cy' => 'Cymraeg',
|
||||
'da' => 'dansk',
|
||||
'se' => 'Davvisámegiella',
|
||||
'de' => 'Deutsch',
|
||||
'nv' => 'Diné bizaad',
|
||||
'et' => 'eesti',
|
||||
'na' => 'Ekakairũ Naoero',
|
||||
'en' => 'English',
|
||||
'es' => 'español',
|
||||
'eo' => 'Esperanto',
|
||||
'eu' => 'euskara',
|
||||
'ee' => 'Eʋegbe',
|
||||
'to' => 'faka Tonga',
|
||||
'mg' => 'fiteny malagasy',
|
||||
'fr' => 'français',
|
||||
'fy' => 'Frysk',
|
||||
'ff' => 'Fulfulde',
|
||||
'fo' => 'føroyskt',
|
||||
'ga' => 'Gaeilge',
|
||||
'gv' => 'Gaelg',
|
||||
'sm' => 'gagana fa\'a Samoa',
|
||||
'gl' => 'galego',
|
||||
'sq' => 'gjuha shqipe',
|
||||
'gd' => 'Gàidhlig',
|
||||
'ki' => 'Gĩkũyũ',
|
||||
'ha' => 'Hausa',
|
||||
'ho' => 'Hiri Motu',
|
||||
'hr' => 'hrvatski jezik',
|
||||
'io' => 'Ido',
|
||||
'rw' => 'Ikinyarwanda',
|
||||
'rn' => 'Ikirundi',
|
||||
'ia' => 'Interlingua',
|
||||
'nd' => 'isiNdebele',
|
||||
'nr' => 'isiNdebele',
|
||||
'xh' => 'isiXhosa',
|
||||
'zu' => 'isiZulu',
|
||||
'it' => 'italiano',
|
||||
'ik' => 'Iñupiaq',
|
||||
'pl' => 'język polski',
|
||||
'mh' => 'Kajin M̧ajeļ',
|
||||
'kl' => 'kalaallisut',
|
||||
'kr' => 'Kanuri',
|
||||
'kw' => 'Kernewek',
|
||||
'kg' => 'KiKongo',
|
||||
'sw' => 'Kiswahili',
|
||||
'ht' => 'Kreyòl ayisyen',
|
||||
'kj' => 'Kuanyama',
|
||||
'ku' => 'Kurdî',
|
||||
'la' => 'latine',
|
||||
'lv' => 'latviešu valoda',
|
||||
'lt' => 'lietuvių kalba',
|
||||
'ro' => 'limba română',
|
||||
'li' => 'Limburgs',
|
||||
'ln' => 'Lingála',
|
||||
'lg' => 'Luganda',
|
||||
'lb' => 'Lëtzebuergesch',
|
||||
'hu' => 'magyar',
|
||||
'mt' => 'Malti',
|
||||
'nl' => 'Nederlands',
|
||||
'no' => 'Norsk',
|
||||
'nb' => 'Norsk bokmål',
|
||||
'nn' => 'Norsk nynorsk',
|
||||
'uz' => 'O\'zbek',
|
||||
'oc' => 'occitan',
|
||||
'ie' => 'Interlingue',
|
||||
'hz' => 'Otjiherero',
|
||||
'ng' => 'Owambo',
|
||||
'pt' => 'português',
|
||||
'ty' => 'Reo Tahiti',
|
||||
'rm' => 'rumantsch grischun',
|
||||
'qu' => 'Runa Simi',
|
||||
'sc' => 'sardu',
|
||||
'za' => 'Saɯ cueŋƅ',
|
||||
'st' => 'Sesotho',
|
||||
'tn' => 'Setswana',
|
||||
'ss' => 'SiSwati',
|
||||
'sl' => 'slovenski jezik',
|
||||
'sk' => 'slovenčina',
|
||||
'so' => 'Soomaaliga',
|
||||
'fi' => 'suomi',
|
||||
'sv' => 'Svenska',
|
||||
'mi' => 'te reo Māori',
|
||||
'vi' => 'Tiếng Việt',
|
||||
'lu' => 'Tshiluba',
|
||||
've' => 'Tshivenḓa',
|
||||
'tw' => 'Twi',
|
||||
'tk' => 'Türkmen',
|
||||
'tr' => 'Türkçe',
|
||||
'ug' => 'Uyƣurqə',
|
||||
'vo' => 'Volapük',
|
||||
'fj' => 'vosa Vakaviti',
|
||||
'wa' => 'walon',
|
||||
'tl' => 'Wikang Tagalog',
|
||||
'wo' => 'Wollof',
|
||||
'ts' => 'Xitsonga',
|
||||
'yo' => 'Yorùbá',
|
||||
'sg' => 'yângâ tî sängö',
|
||||
'is' => 'Íslenska',
|
||||
'cs' => 'čeština',
|
||||
'el' => 'ελληνικά',
|
||||
'av' => 'авар мацӀ',
|
||||
'ab' => 'аҧсуа бызшәа',
|
||||
'ba' => 'башҡорт теле',
|
||||
'be' => 'беларуская мова',
|
||||
'bg' => 'български език',
|
||||
'os' => 'ирон æвзаг',
|
||||
'kv' => 'коми кыв',
|
||||
'ky' => 'Кыргызча',
|
||||
'mk' => 'македонски јазик',
|
||||
'mn' => 'монгол',
|
||||
'ce' => 'нохчийн мотт',
|
||||
'ru' => 'Русский язык',
|
||||
'sr' => 'српски језик',
|
||||
'tt' => 'татар теле',
|
||||
'tg' => 'тоҷикӣ',
|
||||
'uk' => 'Українська',
|
||||
'cv' => 'чӑваш чӗлхи',
|
||||
'cu' => 'ѩзыкъ словѣньскъ',
|
||||
'kk' => 'қазақ тілі',
|
||||
'hy' => 'Հայերեն',
|
||||
'yi' => 'ייִדיש',
|
||||
'he' => 'עברית',
|
||||
'ur' => 'اردو',
|
||||
'ar' => 'العربية',
|
||||
'fa' => 'فارسی',
|
||||
'ps' => 'پښتو',
|
||||
'ks' => 'कश्मीरी',
|
||||
'ne' => 'नेपाली',
|
||||
'pi' => 'पाऴि',
|
||||
'bh' => 'भोजपुरी',
|
||||
'mr' => 'मराठी',
|
||||
'sa' => 'संस्कृतम्',
|
||||
'sd' => 'सिन्धी',
|
||||
'hi' => 'हिन्दी',
|
||||
'as' => 'অসমীয়া',
|
||||
'bn' => 'বাংলা',
|
||||
'pa' => 'ਪੰਜਾਬੀ',
|
||||
'gu' => 'ગુજરાતી',
|
||||
'or' => 'ଓଡ଼ିଆ',
|
||||
'ta' => 'தமிழ்',
|
||||
'te' => 'తెలుగు',
|
||||
'kn' => 'ಕನ್ನಡ',
|
||||
'ml' => 'മലയാളം',
|
||||
'si' => 'සිංහල',
|
||||
'th' => 'ไทย',
|
||||
'lo' => 'ພາສາລາວ',
|
||||
'bo' => 'བོད་ཡིག',
|
||||
'dz' => 'རྫོང་ཁ',
|
||||
'my' => 'ဗမာစာ',
|
||||
'ka' => 'ქართული',
|
||||
'ti' => 'ትግርኛ',
|
||||
'am' => 'አማርኛ',
|
||||
'iu' => 'ᐃᓄᒃᑎᑐᑦ',
|
||||
'oj' => 'ᐊᓂᔑᓈᐯᒧᐎᓐ',
|
||||
'cr' => 'ᓀᐦᐃᔭᐍᐏᐣ',
|
||||
'km' => 'ខ្មែរ',
|
||||
'zh' => '中文 (Zhōngwén)',
|
||||
'ja' => '日本語 (にほんご)',
|
||||
'ii' => 'ꆈꌠ꒿ Nuosuhxop',
|
||||
'ko' => '한국어 (韓國語)'
|
||||
];
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
Plugins::init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Init Plugins
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
private static function init() : void
|
||||
{
|
||||
// Plugin cache id
|
||||
$plugins_cache_id = '';
|
||||
$_plugins_cache_id = '';
|
||||
|
||||
// Set empty plugins item
|
||||
Registry::set('plugins', []);
|
||||
|
||||
// Get Plugins List
|
||||
$plugins_list = Filesystem::getDirList(PATH['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 (Filesystem::fileExists($_plugin_settings = PATH['plugins'] . '/' . $plugin . '/settings.yaml') and
|
||||
Filesystem::fileExists($_plugin_config = PATH['plugins'] . '/' . $plugin . '/'. $plugin .'.yaml')) {
|
||||
$_plugins_cache_id .= filemtime($_plugin_settings) . filemtime($_plugin_config);
|
||||
}
|
||||
}
|
||||
|
||||
// Create Unique Cache ID for Plugins
|
||||
$plugins_cache_id = md5('plugins' . PATH['plugins'] . '/' . $_plugins_cache_id);
|
||||
|
||||
// Get plugins list from cache or scan plugins folder and create new plugins cache item
|
||||
if (Cache::contains($plugins_cache_id)) {
|
||||
Registry::set('plugins', Cache::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 (Filesystem::fileExists($_plugin_settings = PATH['plugins'] . '/' . $plugin . '/settings.yaml')) {
|
||||
$plugin_settings = YamlParser::decode(Filesystem::getFileContent($_plugin_settings));
|
||||
}
|
||||
|
||||
if (Filesystem::fileExists($_plugin_config = PATH['plugins'] . '/' . $plugin . '/'. $plugin. '.yaml')) {
|
||||
$plugin_config = YamlParser::decode(Filesystem::getFileContent($_plugin_config));
|
||||
}
|
||||
|
||||
$_plugins_config[basename($_plugin_config, '.yaml')] = array_merge($plugin_settings, $plugin_config);
|
||||
}
|
||||
|
||||
Registry::set('plugins', $_plugins_config);
|
||||
Cache::save($plugins_cache_id, $_plugins_config);
|
||||
}
|
||||
}
|
||||
|
||||
// Create Dictionary
|
||||
if (is_array($plugins_list) && count($plugins_list) > 0) {
|
||||
foreach (Plugins::$locales as $locale => $locale_title) {
|
||||
foreach ($plugins_list as $plugin) {
|
||||
$language_file = PATH['plugins'] . '/' . $plugin . '/languages/' . $locale . '.yaml';
|
||||
if (Filesystem::fileExists($language_file)) {
|
||||
I18n::add(YamlParser::decode(Filesystem::getFileContent($language_file)), $locale);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Include enabled plugins
|
||||
if (is_array(Registry::get('plugins')) && count(Registry::get('plugins')) > 0) {
|
||||
foreach (Registry::get('plugins') as $plugin_name => $plugin) {
|
||||
if (Registry::get('plugins.'.$plugin_name.'.enabled')) {
|
||||
include_once PATH['plugins'] . '/' . $plugin_name .'/'. $plugin_name . '.php';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Event::dispatch('onPluginsInitialized');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get locales.
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public static function getLocales() : array
|
||||
{
|
||||
return Plugins::$locales;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Plugins instance.
|
||||
*
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
if (is_null(Plugins::$instance)) {
|
||||
Plugins::$instance = new self;
|
||||
}
|
||||
|
||||
return Plugins::$instance;
|
||||
}
|
||||
}
|
@@ -1,126 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
use Flextype\Component\Event\Event;
|
||||
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
|
||||
|
||||
// Event: onShortcodesInitialized
|
||||
Event::addListener('onShortcodesInitialized', function () {
|
||||
|
||||
// Shortcode: [snippet name=snippet-name]
|
||||
Entries::shortcode()->addHandler('snippet', function(ShortcodeInterface $s) {
|
||||
return Snippets::get($s->getParameter('name'));
|
||||
});
|
||||
});
|
||||
|
||||
class Snippets
|
||||
{
|
||||
/**
|
||||
* An instance of the Snippets class
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
private static $instance = null;
|
||||
|
||||
/**
|
||||
* Images Server
|
||||
*
|
||||
* @var
|
||||
*/
|
||||
protected static $server;
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
Snippets::init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Init Snippets
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
private static function init() : void
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get snippet
|
||||
*
|
||||
* Snippets::get('snippet-name');
|
||||
*
|
||||
* @access public
|
||||
* @param string $snippet_name Snippet name
|
||||
* @return string|bool Returns the contents of the output buffer and end output buffering.
|
||||
* If output buffering isn't active then FALSE is returned.
|
||||
*/
|
||||
public static function get(string $snippet_name)
|
||||
{
|
||||
$snippet_path = PATH['snippets'] . '/' . $snippet_name . '.php';
|
||||
|
||||
if (Filesystem::fileExists($snippet_path)) {
|
||||
|
||||
// Turn on output buffering
|
||||
ob_start();
|
||||
|
||||
// Include view file
|
||||
include $snippet_path;
|
||||
|
||||
// Output...
|
||||
return ob_get_clean();
|
||||
} else {
|
||||
throw new \RuntimeException("Snippet {$snippet_name} does not exist.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Snippets instance.
|
||||
*
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
if (is_null(Snippets::$instance)) {
|
||||
Snippets::$instance = new self;
|
||||
}
|
||||
|
||||
return Snippets::$instance;
|
||||
}
|
||||
}
|
@@ -1,231 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
use Flextype\Component\View\View;
|
||||
use Flextype\Component\Registry\Registry;
|
||||
|
||||
class Themes
|
||||
{
|
||||
/**
|
||||
* An instance of the Themes class
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
private static $instance = null;
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
Themes::init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Init Themes
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
private static function init() : void
|
||||
{
|
||||
// Theme Manifest
|
||||
$theme_manifest = [];
|
||||
|
||||
// Theme cache id
|
||||
$theme_cache_id = '';
|
||||
|
||||
// Get current theme
|
||||
$theme = Registry::get('settings.theme');
|
||||
|
||||
// Set empty themes items
|
||||
Registry::set('themes', []);
|
||||
|
||||
// Create Unique Cache ID for Theme
|
||||
$theme_cache_id = md5('theme' . filemtime(PATH['themes'] .'/'. $theme . '/' . 'settings.yaml') .
|
||||
filemtime(PATH['themes'] .'/'. $theme . '/' . $theme . '.yaml'));
|
||||
|
||||
// Get Theme mafifest file and write to settings.themes array
|
||||
if (Cache::contains($theme_cache_id)) {
|
||||
Registry::set('themes.'.Registry::get('settings.theme'), Cache::fetch($theme_cache_id));
|
||||
} else {
|
||||
if (Filesystem::fileExists($theme_settings = PATH['themes'] . '/' . $theme . '/' . 'settings.yaml') and
|
||||
Filesystem::fileExists($theme_config = PATH['themes'] . '/' . $theme . '/' . $theme . '.yaml')) {
|
||||
$theme_settings = YamlParser::decode(Filesystem::getFileContent($theme_settings));
|
||||
$theme_config = YamlParser::decode(Filesystem::getFileContent($theme_config));
|
||||
$_theme = array_merge($theme_settings, $theme_config);
|
||||
Registry::set('themes.'.Registry::get('settings.theme'), $_theme);
|
||||
Cache::save($theme_cache_id, $_theme);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get themes view
|
||||
*
|
||||
* @param string $template Template file
|
||||
* @param string $variables Variables
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public static function view(string $template, array $variables = [])
|
||||
{
|
||||
// Set view file
|
||||
// From current theme folder or from plugin folder
|
||||
if (Filesystem::fileExists(PATH['themes'] . '/' . Registry::get('settings.theme') . '/views/' . $template . View::$view_ext)) {
|
||||
$template = PATH['themes'] . '/' . Registry::get('settings.theme') . '/views/' . $template;
|
||||
} else {
|
||||
$template = PATH['plugins'] . '/' . $template;
|
||||
}
|
||||
|
||||
// Return template
|
||||
return new View($template, $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get partials for current theme
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public static function getPartials() : array
|
||||
{
|
||||
$partials = [];
|
||||
|
||||
// Get templates files
|
||||
$_partials = Filesystem::getFilesList(PATH['themes'] . '/' . Registry::get('settings.theme') . '/views/partials/', 'php');
|
||||
|
||||
// If there is any template file then go...
|
||||
if (count($_partials) > 0) {
|
||||
foreach ($_partials as $partial) {
|
||||
if (!is_bool(Themes::_strrevpos($partial, '/partials/'))) {
|
||||
$partial_name = str_replace('.php', '', substr($partial, Themes::_strrevpos($partial, '/partials/')+strlen('/partials/')));
|
||||
$partials[$partial_name] = $partial_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return partials
|
||||
return $partials;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get templates for current theme
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public static function getTemplates() : array
|
||||
{
|
||||
$templates = [];
|
||||
|
||||
// Get templates files
|
||||
$_templates = Filesystem::getFilesList(PATH['themes'] . '/' . Registry::get('settings.theme') . '/views/templates/', 'php');
|
||||
|
||||
// If there is any template file then go...
|
||||
if (count($_templates) > 0) {
|
||||
foreach ($_templates as $template) {
|
||||
if (!is_bool(Themes::_strrevpos($template, '/templates/'))) {
|
||||
$template_name = str_replace('.php', '', substr($template, Themes::_strrevpos($template, '/templates/')+strlen('/templates/')));
|
||||
$templates[$template_name] = $template_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return templates
|
||||
return $templates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Fieldsets for current theme
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public static function getFieldsets() : array
|
||||
{
|
||||
$fieldsets = [];
|
||||
|
||||
// Get fieldsets files
|
||||
$_fieldsets = Filesystem::getFilesList(PATH['themes'] . '/' . Registry::get('settings.theme') . '/fieldsets/', 'yaml');
|
||||
|
||||
// If there is any template file then go...
|
||||
if (count($_fieldsets) > 0) {
|
||||
foreach ($_fieldsets as $fieldset) {
|
||||
if (!is_bool(Themes::_strrevpos($fieldset, '/fieldsets/'))) {
|
||||
$fieldset_name = str_replace('.yaml', '', substr($fieldset, Themes::_strrevpos($fieldset, '/fieldsets/')+strlen('/fieldsets/')));
|
||||
$fieldset = YamlParser::decode(Filesystem::getFileContent($fieldset));
|
||||
$fieldsets[$fieldset_name] = $fieldset['title'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return fieldsets
|
||||
return $fieldsets;
|
||||
}
|
||||
|
||||
/**
|
||||
* _strrevpos
|
||||
*
|
||||
* @param string $instr instr
|
||||
* @param string $needle needle
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function _strrevpos($instr, $needle)
|
||||
{
|
||||
$rev_pos = strpos(strrev($instr), strrev($needle));
|
||||
if ($rev_pos === false) {
|
||||
return false;
|
||||
} else {
|
||||
return strlen($instr) - $rev_pos - strlen($needle);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Themes instance.
|
||||
*
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
if (is_null(Themes::$instance)) {
|
||||
Themes::$instance = new self;
|
||||
}
|
||||
|
||||
return Themes::$instance;
|
||||
}
|
||||
}
|
149
flextype/bootstrap.php
Executable file
149
flextype/bootstrap.php
Executable file
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Flextype
|
||||
*
|
||||
* @author Romanenko Sergey <hello@romanenko.digital>
|
||||
* @link http://romanenko.digital
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Session\Session;
|
||||
use Flextype\Component\Registry\Registry;
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
|
||||
/**
|
||||
* The version of Flextype
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
define('FLEXTYPE_VERSION', '0.9.0');
|
||||
|
||||
// Start the session
|
||||
Session::start();
|
||||
|
||||
// Configure application
|
||||
$config = [
|
||||
'settings' => [
|
||||
'debug' => false,
|
||||
'whoops.editor' => 'atom',
|
||||
'whoops.page_title' => 'Error!',
|
||||
'displayErrorDetails' => false,
|
||||
'addContentLengthHeader' => true,
|
||||
'addContentLengthHeader' => false,
|
||||
'routerCacheFile' => false,
|
||||
'determineRouteBeforeAppMiddleware' => false,
|
||||
'outputBuffering' => 'append',
|
||||
'responseChunkSize' => 4096,
|
||||
'httpVersion' => '1.1',
|
||||
'twig' => [
|
||||
'cache' => PATH['cache'] . '/twig',
|
||||
'auto_reload' => true
|
||||
],
|
||||
'images' => [
|
||||
'driver' => 'gd',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* Create new application
|
||||
*/
|
||||
$app = new \Slim\App($config);
|
||||
|
||||
/**
|
||||
* Set Flextype Dependency Injection Container
|
||||
*/
|
||||
$flextype = $app->getContainer();
|
||||
|
||||
/**
|
||||
* Include Dependencies
|
||||
*/
|
||||
include_once 'dependencies.php';
|
||||
|
||||
/**
|
||||
* Include Middlewares
|
||||
*/
|
||||
include_once 'middlewares.php';
|
||||
|
||||
/**
|
||||
* Include Routes (web)
|
||||
*/
|
||||
include_once 'routes/web.php';
|
||||
|
||||
// Set empty settings array
|
||||
$flextype['registry']->set('settings', []);
|
||||
|
||||
// Set settings files path
|
||||
$default_settings_file_path = PATH['config']['default'] . '/settings.json';
|
||||
$site_settings_file_path = PATH['config']['site'] . '/settings.json';
|
||||
|
||||
// Set settings if Flextype settings and Site settings config files exist
|
||||
if (Filesystem::has($default_settings_file_path) && Filesystem::has($site_settings_file_path)) {
|
||||
if (($content = Filesystem::read($default_settings_file_path)) === false) {
|
||||
throw new \RuntimeException('Load file: ' . $default_settings_file_path . ' - failed!');
|
||||
} else {
|
||||
$default_settings = JsonParser::decode($content);
|
||||
}
|
||||
|
||||
if (($content = Filesystem::read($site_settings_file_path)) === false) {
|
||||
throw new \RuntimeException('Load file: ' . $site_settings_file_path . ' - failed!');
|
||||
} else {
|
||||
$site_settings = JsonParser::decode($content);
|
||||
}
|
||||
|
||||
// Merge settings
|
||||
$settings = array_replace_recursive($default_settings, $site_settings);
|
||||
|
||||
// Set settings
|
||||
$flextype['registry']->set('settings', $settings);
|
||||
} else {
|
||||
throw new \RuntimeException("Flextype settings and Site settings config files does not exist.");
|
||||
}
|
||||
|
||||
// Set internal encoding
|
||||
function_exists('mb_language') and mb_language('uni');
|
||||
function_exists('mb_regex_encoding') and mb_regex_encoding($flextype['registry']->get('settings.charset'));
|
||||
function_exists('mb_internal_encoding') and mb_internal_encoding($flextype['registry']->get('settings.charset'));
|
||||
|
||||
// Display Errors
|
||||
if ($flextype['registry']->get('settings.errors.display')) {
|
||||
|
||||
/**
|
||||
* Add WhoopsMiddleware
|
||||
*/
|
||||
$app->add(new \Zeuxisoo\Whoops\Provider\Slim\WhoopsMiddleware($app));
|
||||
|
||||
} else {
|
||||
error_reporting(0);
|
||||
}
|
||||
|
||||
// Set default timezone
|
||||
date_default_timezone_set($flextype['registry']->get('settings.timezone'));
|
||||
|
||||
// Get Default Shortocdes List
|
||||
$shortcodes_list = Filesystem::listContents(ROOT_DIR . '/flextype/shortcodes');
|
||||
|
||||
// Include default shortcodes
|
||||
foreach ($shortcodes_list as $shortcode) {
|
||||
include_once $shortcode['path'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Init themes
|
||||
*/
|
||||
$flextype['themes']->init($flextype, $app);
|
||||
|
||||
/**
|
||||
* Init plugins
|
||||
*/
|
||||
$flextype['plugins']->init($flextype, $app);
|
||||
|
||||
/**
|
||||
* Run application
|
||||
*/
|
||||
$app->run();
|
636
flextype/config/locales.json
Normal file
636
flextype/config/locales.json
Normal file
@@ -0,0 +1,636 @@
|
||||
{
|
||||
"af": {
|
||||
"name": "Afrikaans",
|
||||
"nativeName": "Afrikaans"
|
||||
},
|
||||
"af_ZA": {
|
||||
"name": "Afrikaans",
|
||||
"nativeName": "Afrikaans"
|
||||
},
|
||||
"ak": {
|
||||
"name": "Akan",
|
||||
"nativeName": "Akan"
|
||||
},
|
||||
"ast": {
|
||||
"name": "Asturian",
|
||||
"nativeName": "Asturianu"
|
||||
},
|
||||
"ar": {
|
||||
"name": "Arabic",
|
||||
"nativeName": "عربي",
|
||||
"orientation": "rtl"
|
||||
},
|
||||
"ar_SA": {
|
||||
"name": "Arabic",
|
||||
"nativeName": "عربي",
|
||||
"orientation": "rtl"
|
||||
},
|
||||
"as": {
|
||||
"name": "Assamese",
|
||||
"nativeName": "অসমীয়া"
|
||||
},
|
||||
"be": {
|
||||
"name": "Belarusian",
|
||||
"nativeName": "Беларуская"
|
||||
},
|
||||
"bg": {
|
||||
"name": "Bulgarian",
|
||||
"nativeName": "Български"
|
||||
},
|
||||
"bn": {
|
||||
"name": "Bengali",
|
||||
"nativeName": "বাংলা"
|
||||
},
|
||||
"bn_BD": {
|
||||
"name": "Bengali (Bangladesh)",
|
||||
"nativeName": "বাংলা (বাংলাদেশ)"
|
||||
},
|
||||
"bn_IN": {
|
||||
"name": "Bengali (India)",
|
||||
"nativeName": "বাংলা (ভারত)"
|
||||
},
|
||||
"br": {
|
||||
"name": "Breton",
|
||||
"nativeName": "Brezhoneg"
|
||||
},
|
||||
"bs": {
|
||||
"name": "Bosnian",
|
||||
"nativeName": "Bosanski"
|
||||
},
|
||||
"ca": {
|
||||
"name": "Catalan",
|
||||
"nativeName": "Català"
|
||||
},
|
||||
"ca_ES": {
|
||||
"name": "Catalan",
|
||||
"nativeName": "Català"
|
||||
},
|
||||
"ca_valencia": {
|
||||
"name": "Catalan (Valencian)",
|
||||
"nativeName": "Català (valencià)"
|
||||
},
|
||||
"cs": {
|
||||
"name": "Czech",
|
||||
"nativeName": "Čeština"
|
||||
},
|
||||
"cs_CZ": {
|
||||
"name": "Czech",
|
||||
"nativeName": "Čeština"
|
||||
},
|
||||
"cy": {
|
||||
"name": "Welsh",
|
||||
"nativeName": "Cymraeg"
|
||||
},
|
||||
"da": {
|
||||
"name": "Danish",
|
||||
"nativeName": "Dansk"
|
||||
},
|
||||
"da_DK": {
|
||||
"name": "Danish",
|
||||
"nativeName": "Dansk"
|
||||
},
|
||||
"de": {
|
||||
"name": "German",
|
||||
"nativeName": "Deutsch"
|
||||
},
|
||||
"de_AT": {
|
||||
"name": "German (Austria)",
|
||||
"nativeName": "Deutsch (Österreich)"
|
||||
},
|
||||
"de_CH": {
|
||||
"name": "German (Switzerland)",
|
||||
"nativeName": "Deutsch (Schweiz)"
|
||||
},
|
||||
"de_DE": {
|
||||
"name": "German (Germany)",
|
||||
"nativeName": "Deutsch (Deutschland)"
|
||||
},
|
||||
"dsb": {
|
||||
"name": "Lower Sorbian",
|
||||
"nativeName": "Dolnoserbšćina"
|
||||
},
|
||||
"el": {
|
||||
"name": "Greek",
|
||||
"nativeName": "Ελληνικά"
|
||||
},
|
||||
"el_GR": {
|
||||
"name": "Greek",
|
||||
"nativeName": "Ελληνικά"
|
||||
},
|
||||
"en": {
|
||||
"name": "English",
|
||||
"nativeName": "English"
|
||||
},
|
||||
"en_AU": {
|
||||
"name": "English (Australian)",
|
||||
"nativeName": "English (Australian)"
|
||||
},
|
||||
"en_CA": {
|
||||
"name": "English (Canadian)",
|
||||
"nativeName": "English (Canadian)"
|
||||
},
|
||||
"en_GB": {
|
||||
"name": "English (British)",
|
||||
"nativeName": "English (British)"
|
||||
},
|
||||
"en_NZ": {
|
||||
"name": "English (New Zealand)",
|
||||
"nativeName": "English (New Zealand)"
|
||||
},
|
||||
"en_US": {
|
||||
"name": "English (US)",
|
||||
"nativeName": "English (US)"
|
||||
},
|
||||
"en_ZA": {
|
||||
"name": "English (South African)",
|
||||
"nativeName": "English (South African)"
|
||||
},
|
||||
"eo": {
|
||||
"name": "Esperanto",
|
||||
"nativeName": "Esperanto"
|
||||
},
|
||||
"es": {
|
||||
"name": "Spanish",
|
||||
"nativeName": "Español"
|
||||
},
|
||||
"es_AR": {
|
||||
"name": "Spanish (Argentina)",
|
||||
"nativeName": "Español (de Argentina)"
|
||||
},
|
||||
"es_CL": {
|
||||
"name": "Spanish (Chile)",
|
||||
"nativeName": "Español (de Chile)"
|
||||
},
|
||||
"es_ES": {
|
||||
"name": "Spanish (Spain)",
|
||||
"nativeName": "Español (de España)"
|
||||
},
|
||||
"es_MX": {
|
||||
"name": "Spanish (Mexico)",
|
||||
"nativeName": "Español (de México)"
|
||||
},
|
||||
"et": {
|
||||
"name": "Estonian",
|
||||
"nativeName": "Eesti keel"
|
||||
},
|
||||
"eu": {
|
||||
"name": "Basque",
|
||||
"nativeName": "Euskara"
|
||||
},
|
||||
"fa": {
|
||||
"name": "Persian",
|
||||
"nativeName": "فارسی",
|
||||
"orientation": "rtl"
|
||||
},
|
||||
"fi": {
|
||||
"name": "Finnish",
|
||||
"nativeName": "Suomi"
|
||||
},
|
||||
"fi_FI": {
|
||||
"name": "Finnish",
|
||||
"nativeName": "Suomi"
|
||||
},
|
||||
"fj_FJ": {
|
||||
"name": "Fijian",
|
||||
"nativeName": "Vosa vaka_Viti"
|
||||
},
|
||||
"fr": {
|
||||
"name": "French",
|
||||
"nativeName": "Français"
|
||||
},
|
||||
"fr_CA": {
|
||||
"name": "French (Canada)",
|
||||
"nativeName": "Français (Canada)"
|
||||
},
|
||||
"fr_FR": {
|
||||
"name": "French (France)",
|
||||
"nativeName": "Français (France)"
|
||||
},
|
||||
"fur": {
|
||||
"name": "Friulian",
|
||||
"nativeName": "Furlan"
|
||||
},
|
||||
"fur_IT": {
|
||||
"name": "Friulian",
|
||||
"nativeName": "Furlan"
|
||||
},
|
||||
"fy": {
|
||||
"name": "Frisian",
|
||||
"nativeName": "Frysk"
|
||||
},
|
||||
"fy_NL": {
|
||||
"name": "Frisian",
|
||||
"nativeName": "Frysk"
|
||||
},
|
||||
"ga": {
|
||||
"name": "Irish",
|
||||
"nativeName": "Gaeilge"
|
||||
},
|
||||
"ga_IE": {
|
||||
"name": "Irish (Ireland)",
|
||||
"nativeName": "Gaeilge (Éire)"
|
||||
},
|
||||
"gd": {
|
||||
"name": "Gaelic (Scotland)",
|
||||
"nativeName": "Gàidhlig"
|
||||
},
|
||||
"gl": {
|
||||
"name": "Galician",
|
||||
"nativeName": "Galego"
|
||||
},
|
||||
"gu": {
|
||||
"name": "Gujarati",
|
||||
"nativeName": "ગુજરાતી"
|
||||
},
|
||||
"gu_IN": {
|
||||
"name": "Gujarati",
|
||||
"nativeName": "ગુજરાતી"
|
||||
},
|
||||
"he": {
|
||||
"name": "Hebrew",
|
||||
"nativeName": "עברית",
|
||||
"orientation": "rtl"
|
||||
},
|
||||
"he_IL": {
|
||||
"name": "Hebrew",
|
||||
"nativeName": "עברית",
|
||||
"orientation": "rtl"
|
||||
},
|
||||
"hi": {
|
||||
"name": "Hindi",
|
||||
"nativeName": "हिन्दी"
|
||||
},
|
||||
"hi_IN": {
|
||||
"name": "Hindi (India)",
|
||||
"nativeName": "हिन्दी (भारत)"
|
||||
},
|
||||
"hr": {
|
||||
"name": "Croatian",
|
||||
"nativeName": "Hrvatski"
|
||||
},
|
||||
"hr_HR": {
|
||||
"name": "Croatian",
|
||||
"nativeName": "Hrvatski"
|
||||
},
|
||||
"hsb": {
|
||||
"name": "Upper Sorbian",
|
||||
"nativeName": "Hornjoserbsce"
|
||||
},
|
||||
"hu": {
|
||||
"name": "Hungarian",
|
||||
"nativeName": "Magyar"
|
||||
},
|
||||
"hu_HU": {
|
||||
"name": "Hungarian",
|
||||
"nativeName": "Magyar"
|
||||
},
|
||||
"hy": {
|
||||
"name": "Armenian",
|
||||
"nativeName": "Հայերեն"
|
||||
},
|
||||
"hy_AM": {
|
||||
"name": "Armenian",
|
||||
"nativeName": "Հայերեն"
|
||||
},
|
||||
"id": {
|
||||
"name": "Indonesian",
|
||||
"nativeName": "Bahasa Indonesia"
|
||||
},
|
||||
"is": {
|
||||
"name": "Icelandic",
|
||||
"nativeName": "íslenska"
|
||||
},
|
||||
"it": {
|
||||
"name": "Italian",
|
||||
"nativeName": "Italiano"
|
||||
},
|
||||
"it_IT": {
|
||||
"name": "Italian",
|
||||
"nativeName": "Italiano"
|
||||
},
|
||||
"ja": {
|
||||
"name": "Japanese",
|
||||
"nativeName": "日本語"
|
||||
},
|
||||
"ja_JP": {
|
||||
"name": "Japanese",
|
||||
"nativeName": "日本語"
|
||||
},
|
||||
"ka": {
|
||||
"name": "Georgian",
|
||||
"nativeName": "ქართული"
|
||||
},
|
||||
"kk": {
|
||||
"name": "Kazakh",
|
||||
"nativeName": "Қазақ"
|
||||
},
|
||||
"kn": {
|
||||
"name": "Kannada",
|
||||
"nativeName": "ಕನ್ನಡ"
|
||||
},
|
||||
"ko": {
|
||||
"name": "Korean",
|
||||
"nativeName": "한국어"
|
||||
},
|
||||
"ko_KR": {
|
||||
"name": "Korean",
|
||||
"nativeName": "한국어"
|
||||
},
|
||||
"ku": {
|
||||
"name": "Kurdish",
|
||||
"nativeName": "Kurdî"
|
||||
},
|
||||
"la": {
|
||||
"name": "Latin",
|
||||
"nativeName": "Latina"
|
||||
},
|
||||
"lb": {
|
||||
"name": "Luxembourgish",
|
||||
"nativeName": "Lëtzebuergesch"
|
||||
},
|
||||
"lg": {
|
||||
"name": "Luganda",
|
||||
"nativeName": "Luganda"
|
||||
},
|
||||
"lt": {
|
||||
"name": "Lithuanian",
|
||||
"nativeName": "Lietuvių kalba"
|
||||
},
|
||||
"lv": {
|
||||
"name": "Latvian",
|
||||
"nativeName": "Latviešu"
|
||||
},
|
||||
"mai": {
|
||||
"name": "Maithili",
|
||||
"nativeName": "मैथिली মৈথিলী"
|
||||
},
|
||||
"mg": {
|
||||
"name": "Malagasy",
|
||||
"nativeName": "Malagasy"
|
||||
},
|
||||
"mi": {
|
||||
"name": "Maori (Aotearoa)",
|
||||
"nativeName": "Māori (Aotearoa)"
|
||||
},
|
||||
"mk": {
|
||||
"name": "Macedonian",
|
||||
"nativeName": "Македонски"
|
||||
},
|
||||
"ml": {
|
||||
"name": "Malayalam",
|
||||
"nativeName": "മലയാളം"
|
||||
},
|
||||
"mn": {
|
||||
"name": "Mongolian",
|
||||
"nativeName": "Монгол"
|
||||
},
|
||||
"mr": {
|
||||
"name": "Marathi",
|
||||
"nativeName": "मराठी"
|
||||
},
|
||||
"no": {
|
||||
"name": "Norwegian",
|
||||
"nativeName": "Norsk"
|
||||
},
|
||||
"no_NO": {
|
||||
"name": "Norwegian",
|
||||
"nativeName": "Norsk"
|
||||
},
|
||||
"nb": {
|
||||
"name": "Norwegian",
|
||||
"nativeName": "Norsk"
|
||||
},
|
||||
"nb_NO": {
|
||||
"name": "Norwegian (Bokmål)",
|
||||
"nativeName": "Norsk bokmål"
|
||||
},
|
||||
"ne_NP": {
|
||||
"name": "Nepali",
|
||||
"nativeName": "नेपाली"
|
||||
},
|
||||
"nn_NO": {
|
||||
"name": "Norwegian (Nynorsk)",
|
||||
"nativeName": "Norsk nynorsk"
|
||||
},
|
||||
"nl": {
|
||||
"name": "Dutch",
|
||||
"nativeName": "Nederlands"
|
||||
},
|
||||
"nl_NL": {
|
||||
"name": "Dutch",
|
||||
"nativeName": "Nederlands"
|
||||
},
|
||||
"nr": {
|
||||
"name": "Ndebele, South",
|
||||
"nativeName": "IsiNdebele"
|
||||
},
|
||||
"nso": {
|
||||
"name": "Northern Sotho",
|
||||
"nativeName": "Sepedi"
|
||||
},
|
||||
"oc": {
|
||||
"name": "Occitan (Lengadocian)",
|
||||
"nativeName": "Occitan (lengadocian)"
|
||||
},
|
||||
"or": {
|
||||
"name": "Oriya",
|
||||
"nativeName": "ଓଡ଼ିଆ"
|
||||
},
|
||||
"pa": {
|
||||
"name": "Punjabi",
|
||||
"nativeName": "ਪੰਜਾਬੀ"
|
||||
},
|
||||
"pa_IN": {
|
||||
"name": "Punjabi",
|
||||
"nativeName": "ਪੰਜਾਬੀ"
|
||||
},
|
||||
"pl": {
|
||||
"name": "Polish",
|
||||
"nativeName": "Polski"
|
||||
},
|
||||
"pl_PL": {
|
||||
"name": "Polish",
|
||||
"nativeName": "Polski"
|
||||
},
|
||||
"pt": {
|
||||
"name": "Portuguese",
|
||||
"nativeName": "Português"
|
||||
},
|
||||
"pt_BR": {
|
||||
"name": "Portuguese (Brazilian)",
|
||||
"nativeName": "Português (do Brasil)"
|
||||
},
|
||||
"pt_PT": {
|
||||
"name": "Portuguese (Portugal)",
|
||||
"nativeName": "Português (Europeu)"
|
||||
},
|
||||
"ro": {
|
||||
"name": "Romanian",
|
||||
"nativeName": "Română"
|
||||
},
|
||||
"ro_RO": {
|
||||
"name": "Romanian",
|
||||
"nativeName": "Română"
|
||||
},
|
||||
"rm": {
|
||||
"name": "Romansh",
|
||||
"nativeName": "Rumantsch"
|
||||
},
|
||||
"ru": {
|
||||
"name": "Russian",
|
||||
"nativeName": "Русский"
|
||||
},
|
||||
"ru_RU": {
|
||||
"name": "Russian",
|
||||
"nativeName": "Русский"
|
||||
},
|
||||
"rw": {
|
||||
"name": "Kinyarwanda",
|
||||
"nativeName": "Ikinyarwanda"
|
||||
},
|
||||
"si": {
|
||||
"name": "Sinhala",
|
||||
"nativeName": "සිංහල"
|
||||
},
|
||||
"sk": {
|
||||
"name": "Slovak",
|
||||
"nativeName": "Slovenčina"
|
||||
},
|
||||
"sl": {
|
||||
"name": "Slovenian",
|
||||
"nativeName": "Slovensko"
|
||||
},
|
||||
"son": {
|
||||
"name": "Songhai",
|
||||
"nativeName": "Soŋay"
|
||||
},
|
||||
"sq": {
|
||||
"name": "Albanian",
|
||||
"nativeName": "Shqip"
|
||||
},
|
||||
"sr": {
|
||||
"name": "Serbian",
|
||||
"nativeName": "Српски"
|
||||
},
|
||||
"sr_SP": {
|
||||
"name": "Serbian",
|
||||
"nativeName": "Српски"
|
||||
},
|
||||
"sr_Latn": {
|
||||
"name": "Serbian",
|
||||
"nativeName": "Srpski"
|
||||
},
|
||||
"ss": {
|
||||
"name": "Siswati",
|
||||
"nativeName": "siSwati"
|
||||
},
|
||||
"st": {
|
||||
"name": "Southern Sotho",
|
||||
"nativeName": "Sesotho"
|
||||
},
|
||||
"sv": {
|
||||
"name": "Swedish",
|
||||
"nativeName": "Svenska"
|
||||
},
|
||||
"sv_SE": {
|
||||
"name": "Swedish",
|
||||
"nativeName": "Svenska"
|
||||
},
|
||||
"ta": {
|
||||
"name": "Tamil",
|
||||
"nativeName": "தமிழ்"
|
||||
},
|
||||
"ta_IN": {
|
||||
"name": "Tamil (India)",
|
||||
"nativeName": "தமிழ் (இந்தியா)"
|
||||
},
|
||||
"ta_LK": {
|
||||
"name": "Tamil (Sri Lanka)",
|
||||
"nativeName": "தமிழ் (இலங்கை)"
|
||||
},
|
||||
"te": {
|
||||
"name": "Telugu",
|
||||
"nativeName": "తెలుగు"
|
||||
},
|
||||
"th": {
|
||||
"name": "Thai",
|
||||
"nativeName": "ไทย"
|
||||
},
|
||||
"tlh": {
|
||||
"name": "Klingon",
|
||||
"nativeName": "Klingon"
|
||||
},
|
||||
"tn": {
|
||||
"name": "Tswana",
|
||||
"nativeName": "Setswana"
|
||||
},
|
||||
"tr": {
|
||||
"name": "Turkish",
|
||||
"nativeName": "Türkçe"
|
||||
},
|
||||
"tr_TR": {
|
||||
"name": "Turkish",
|
||||
"nativeName": "Türkçe"
|
||||
},
|
||||
"ts": {
|
||||
"name": "Tsonga",
|
||||
"nativeName": "Xitsonga"
|
||||
},
|
||||
"tt": {
|
||||
"name": "Tatar",
|
||||
"nativeName": "Tatarça"
|
||||
},
|
||||
"tt_RU": {
|
||||
"name": "Tatar",
|
||||
"nativeName": "Tatarça"
|
||||
},
|
||||
"uk": {
|
||||
"name": "Ukrainian",
|
||||
"nativeName": "Українська"
|
||||
},
|
||||
"uk_UA": {
|
||||
"name": "Ukrainian",
|
||||
"nativeName": "Українська"
|
||||
},
|
||||
"ur": {
|
||||
"name": "Urdu",
|
||||
"nativeName": "اُردو",
|
||||
"orientation": "rtl"
|
||||
},
|
||||
"ve": {
|
||||
"name": "Venda",
|
||||
"nativeName": "Tshivenḓa"
|
||||
},
|
||||
"vi": {
|
||||
"name": "Vietnamese",
|
||||
"nativeName": "Tiếng Việt"
|
||||
},
|
||||
"vi_VN": {
|
||||
"name": "Vietnamese",
|
||||
"nativeName": "Tiếng Việt"
|
||||
},
|
||||
"wo": {
|
||||
"name": "Wolof",
|
||||
"nativeName": "Wolof"
|
||||
},
|
||||
"xh": {
|
||||
"name": "Xhosa",
|
||||
"nativeName": "isiXhosa"
|
||||
},
|
||||
"zh": {
|
||||
"name": "Chinese (Simplified)",
|
||||
"nativeName": "中文 (简体)"
|
||||
},
|
||||
"zh_CN": {
|
||||
"name": "Chinese (Simplified)",
|
||||
"nativeName": "中文 (简体)"
|
||||
},
|
||||
"zh_TW": {
|
||||
"name": "Chinese (Traditional)",
|
||||
"nativeName": "正體中文 (繁體)"
|
||||
},
|
||||
"zu": {
|
||||
"name": "Zulu",
|
||||
"nativeName": "isiZulu"
|
||||
}
|
||||
}
|
60
flextype/config/settings.json
Normal file
60
flextype/config/settings.json
Normal file
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"title":"Flextype",
|
||||
"description":"Build fast, flexible, easier to manage websites with Flextype.",
|
||||
"keywords":"flextype, php, cms, flat-file cms, flat cms, flatfile cms, html",
|
||||
"robots":"index, follow",
|
||||
"author":{
|
||||
"email":"",
|
||||
"name":""
|
||||
},
|
||||
"timezone":"UTC",
|
||||
"charset":"UTF-8",
|
||||
"date_format":"F d Y H:i:s",
|
||||
"theme":"default",
|
||||
"locale":"en_US",
|
||||
"entries":{
|
||||
"main":"home",
|
||||
"media":{
|
||||
"upload_images_quality":70,
|
||||
"upload_images_width":1600,
|
||||
"upload_images_height":0,
|
||||
"accept_file_types":"gif, jpg, jpeg, png, ico, zip, tgz, txt, md, doc, docx, pdf, epub, xls, xlsx, ppt, pptx, mp3, ogg, wav, m4a, mp4, m4v, ogv, wmv, avi, webm, svg"
|
||||
},
|
||||
"error404":{
|
||||
"title":"Error 404",
|
||||
"description":"We're sorry but the page you are looking for doesn't appear to exist!",
|
||||
"content":"We're sorry but the page you are looking for doesn't appear to exist!",
|
||||
"template":"default"
|
||||
}
|
||||
},
|
||||
"errors":{
|
||||
"display":false
|
||||
},
|
||||
"cache":{
|
||||
"enabled":true,
|
||||
"prefix":"flextype",
|
||||
"driver":"auto",
|
||||
"lifetime":604800,
|
||||
"memcache":{
|
||||
"server":"localhost",
|
||||
"port":11211
|
||||
},
|
||||
"memcached":{
|
||||
"server":"localhost",
|
||||
"port":11211
|
||||
},
|
||||
"redis":{
|
||||
"socket":false,
|
||||
"password":false,
|
||||
"server":"localhost",
|
||||
"port":6379
|
||||
},
|
||||
"sqlite3":{
|
||||
"database":"flextype",
|
||||
"table":"flextype"
|
||||
}
|
||||
},
|
||||
"admin_panel":{
|
||||
"theme":"light"
|
||||
}
|
||||
}
|
@@ -1,121 +0,0 @@
|
||||
# The title of the website
|
||||
title: "Flextype"
|
||||
|
||||
# The description of the website
|
||||
description: "Modern Open Source Flat-File Content Management System"
|
||||
|
||||
# The keywords of the website
|
||||
keywords: "flextype, php, cms, flat-file cms, flat cms, flatfile cms, html"
|
||||
|
||||
# The robots of the website
|
||||
robots: "index, follow"
|
||||
|
||||
# The name and email address of the website author
|
||||
author:
|
||||
email: ""
|
||||
name: ""
|
||||
|
||||
# Set the timezone to be used on the website.
|
||||
# For a list of valid timezone settings, see:
|
||||
# http://php.net/manual/en/timezones.php
|
||||
timezone: UTC
|
||||
|
||||
# Charset
|
||||
#
|
||||
# Set internal character encoding.
|
||||
#
|
||||
# Currently the following names are supported:
|
||||
# http://php.net/manual/ru/function.mb-regex-encoding.php#121645
|
||||
charset: UTF-8
|
||||
|
||||
# Valid date format
|
||||
# see: http://php.net/manual/ru/function.date.php
|
||||
date_format: "F d Y H:i:s"
|
||||
|
||||
# The theme to use.
|
||||
#
|
||||
# Don't edit the provided theme templates directly, because they get updated
|
||||
# in next releases. If you wish to modify a default theme, copy its folder, and
|
||||
# change the name here accordingly.
|
||||
theme: default
|
||||
|
||||
# The locale that'll be used by the Flextype.
|
||||
locale: "en"
|
||||
|
||||
# The entries settings
|
||||
# Define the file types (extensions to be exact) that are acceptable for upload.
|
||||
entries:
|
||||
main: home
|
||||
media:
|
||||
upload_images_quality: 70
|
||||
upload_images_width: 1600
|
||||
upload_images_height: 0
|
||||
accept_file_types: "gif, jpg, jpeg, png, ico, zip, tgz, txt, md, doc, docx, pdf, epub, xls, xlsx, ppt, pptx, mp3, ogg, wav, m4a, mp4, m4v, ogv, wmv, avi, webm, svg"
|
||||
error404:
|
||||
title: "Error 404"
|
||||
description: "We're sorry but the page you are looking for doesn't appear to exist!"
|
||||
content: "We're sorry but the page you are looking for doesn't appear to exist!"
|
||||
template: "default"
|
||||
|
||||
# Display errors
|
||||
#
|
||||
# - display: Display errors or not.
|
||||
errors:
|
||||
display: false
|
||||
|
||||
# Cache
|
||||
#
|
||||
# - enabled: Set to true to enable caching
|
||||
#
|
||||
# - prefix: Cache prefix string (prevents cache conflicts)
|
||||
#
|
||||
# - driver: Available drivers: auto (will get one from installed cache drivers), apcu,
|
||||
# apc, array, wincache, xcache, memcache, memcached, redis, file.
|
||||
#
|
||||
# - lifetime: Lifetime of cached data in seconds
|
||||
#
|
||||
# - redis.socket: Path to redis unix socket (e.g. /var/run/redis/redis.sock),
|
||||
# false = use server and port to connect
|
||||
#
|
||||
# - redis.password Redis password
|
||||
#
|
||||
# - redis.server Redis server
|
||||
#
|
||||
# - redis.port Redis port
|
||||
#
|
||||
# - memcache.server Memcache server
|
||||
#
|
||||
# - memcache.port Memcache port
|
||||
#
|
||||
# - memcached.server Memcached server
|
||||
#
|
||||
# - memcached.port Memcached port
|
||||
#
|
||||
# - sqlite3.database SQLite3 Database
|
||||
#
|
||||
# - sqlite3.table SQLite3 Table
|
||||
cache:
|
||||
enabled: true
|
||||
prefix: flextype
|
||||
driver: auto
|
||||
lifetime: 604800
|
||||
memcache:
|
||||
server: 'localhost'
|
||||
port: 11211
|
||||
memcached:
|
||||
server: 'localhost'
|
||||
port: 11211
|
||||
redis:
|
||||
socket: false
|
||||
password: false
|
||||
server: 'localhost'
|
||||
port: 6379
|
||||
sqlite3:
|
||||
database: flextype
|
||||
table: flextype
|
||||
|
||||
# Admin Panel
|
||||
#
|
||||
# - themes: Theme (dark, light)
|
||||
admin_panel:
|
||||
theme: light
|
407
flextype/core/Cache.php
Executable file
407
flextype/core/Cache.php
Executable file
@@ -0,0 +1,407 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Flextype
|
||||
*
|
||||
* @author Sergey Romanenko <hello@romanenko.digital>
|
||||
* @link http://romanenko.digital
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
use \Doctrine\Common\Cache as DoctrineCache;
|
||||
|
||||
class Cache
|
||||
{
|
||||
/**
|
||||
* Flextype Dependency Container
|
||||
*/
|
||||
private $flextype;
|
||||
|
||||
/**
|
||||
* Unique cache key
|
||||
*
|
||||
* @var string Cache key.
|
||||
*/
|
||||
private $key;
|
||||
|
||||
/**
|
||||
* Lifetime
|
||||
*
|
||||
* @var int Lifetime.
|
||||
*/
|
||||
private $lifetime;
|
||||
|
||||
/**
|
||||
* Current time
|
||||
*
|
||||
* @var int Current time.
|
||||
*/
|
||||
private $now;
|
||||
|
||||
/**
|
||||
* Cache Driver
|
||||
*
|
||||
* @var DoctrineCache
|
||||
*/
|
||||
private $driver;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function __construct($flextype)
|
||||
{
|
||||
$this->flextype = $flextype;
|
||||
|
||||
// Create Cache Directory
|
||||
!Filesystem::has(PATH['cache']) and Filesystem::createDir(PATH['cache']);
|
||||
|
||||
// Set current time
|
||||
$this->now = time();
|
||||
|
||||
// Create cache key to allow invalidate all cache on configuration changes.
|
||||
$this->key = ($this->flextype['registry']->get('settings.cache.prefix') ?? 'flextype') . '-' . md5(PATH['site'] . 'Flextype::VERSION');
|
||||
|
||||
// Get Cache Driver
|
||||
$this->driver = $this->getCacheDriver();
|
||||
|
||||
// Set the cache namespace to our unique key
|
||||
$this->driver->setNamespace($this->key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Cache Driver
|
||||
*
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function getCacheDriver()
|
||||
{
|
||||
// Try to set default cache driver name
|
||||
$driver_name = $this->setDefaultCacheDriverName($this->flextype['registry']->get('settings.cache.driver'));
|
||||
|
||||
// Set cache driver
|
||||
return $this->setCacheDriver($driver_name);
|
||||
}
|
||||
|
||||
protected function setCacheDriver(string $driver_name)
|
||||
{
|
||||
switch ($driver_name) {
|
||||
case 'apcu':
|
||||
$driver = $this->setApcuCacheDriver();
|
||||
break;
|
||||
case 'array':
|
||||
$driver = $this->setArrayCacheDriver();
|
||||
break;
|
||||
case 'wincache':
|
||||
$driver = $this->setWinCacheDriver();
|
||||
break;
|
||||
case 'memcached':
|
||||
$driver = $this->setMemcachedCacheDriver();
|
||||
break;
|
||||
case 'sqlite3':
|
||||
$driver = $this->setSQLite3CacheDriver();
|
||||
break;
|
||||
case 'zend':
|
||||
$driver = $this->setZendDataCacheDriver();
|
||||
break;
|
||||
case 'redis':
|
||||
$driver = $this->setRedisCacheDriver();
|
||||
break;
|
||||
default:
|
||||
$driver = $this->setFilesystemCacheDriver();
|
||||
break;
|
||||
}
|
||||
|
||||
return $driver;
|
||||
}
|
||||
|
||||
/**
|
||||
* The ZendDataCache driver uses the Zend Data Cache API available in the Zend Platform.
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function setZendDataCacheDriver()
|
||||
{
|
||||
$driver = new DoctrineCache\ZendDataCache();
|
||||
|
||||
return $driver;
|
||||
}
|
||||
|
||||
/**
|
||||
* The SQLite3Cache driver stores the cache data in a SQLite database and depends on the sqlite3 extension
|
||||
* http://php.net/manual/en/book.sqlite3.php
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function setSQLite3CacheDriver()
|
||||
{
|
||||
// Cache directory
|
||||
$cache_directory = PATH['cache'] . '/doctrine/';
|
||||
|
||||
// Create doctrine cache directory if its not exists
|
||||
!Filesystem::has($cache_directory) and Filesystem::createDir($cache_directory);
|
||||
|
||||
$db = new \SQLite3($cache_directory . $this->flextype['registry']->get('settings.cache.sqlite3.database', 'flextype') . '.db');
|
||||
$driver = new DoctrineCache\SQLite3Cache($db, $this->flextype['registry']->get('settings.cache.sqlite3.table', 'flextype'));
|
||||
|
||||
return $driver;
|
||||
}
|
||||
|
||||
/**
|
||||
* The MemcachedCache drivers stores the cache data in Memcached.
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function setMemcachedCacheDriver()
|
||||
{
|
||||
$memcached = new \Memcached();
|
||||
$memcached->addServer(
|
||||
$this->flextype['registry']->get('settings.cache.memcached.server', 'localhost'),
|
||||
$this->flextype['registry']->get('settings.cache.memcache.port', 11211)
|
||||
);
|
||||
$driver = new DoctrineCache\MemcachedCache();
|
||||
$driver->setMemcached($memcached);
|
||||
|
||||
return $driver;
|
||||
}
|
||||
|
||||
/**
|
||||
* The WinCacheCache driver uses the wincache_ucache_get, wincache_ucache_exists, etc. functions
|
||||
* that come with the wincache extension
|
||||
* http://php.net/manual/en/book.wincache.php
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function setWinCacheDriver()
|
||||
{
|
||||
$driver = new DoctrineCache\WinCacheCache();
|
||||
|
||||
return $driver;
|
||||
}
|
||||
|
||||
/**
|
||||
* The ArrayCache driver stores the cache data in PHPs memory and is not persisted anywhere.
|
||||
* This can be useful for caching things in memory for a single process when you don't need the cache to be persistent across processes.
|
||||
* @access protected
|
||||
*/
|
||||
protected function setArrayCacheDriver()
|
||||
{
|
||||
$driver = new DoctrineCache\ArrayCache();
|
||||
|
||||
return $driver;
|
||||
}
|
||||
|
||||
/**
|
||||
* The ApcuCache driver uses the apcu_fetch, apcu_exists, etc. functions
|
||||
* that come with PHP so no additional setup is required in order to use it.
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function setApcuCacheDriver()
|
||||
{
|
||||
$driver = new DoctrineCache\ApcuCache();
|
||||
|
||||
return $driver;
|
||||
}
|
||||
|
||||
/**
|
||||
* The RedisCache driver stores the cache data in Redis and depends on the phpredis extension
|
||||
* https://github.com/phpredis/phpredis
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function setRedisCacheDriver()
|
||||
{
|
||||
$redis = new \Redis();
|
||||
$socket = $this->flextype['registry']->get('settings.cache.redis.socket', false);
|
||||
$password = $this->flextype['registry']->get('settings.cache.redis.password', false);
|
||||
|
||||
if ($socket) {
|
||||
$redis->connect($socket);
|
||||
} else {
|
||||
$redis->connect(
|
||||
$this->flextype['registry']->get('settings.cache.redis.server', 'localhost'),
|
||||
$this->flextype['registry']->get('settings.cache.redis.port', 6379)
|
||||
);
|
||||
}
|
||||
|
||||
// Authenticate with password if set
|
||||
if ($password && !$redis->auth($password)) {
|
||||
throw new \RedisException('Redis authentication failed');
|
||||
}
|
||||
|
||||
$driver = new DoctrineCache\RedisCache();
|
||||
$driver->setRedis($redis);
|
||||
|
||||
return $driver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filesystem cache Driver
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function setFilesystemCacheDriver()
|
||||
{
|
||||
// Cache directory
|
||||
$cache_directory = PATH['cache'] . '/doctrine/';
|
||||
|
||||
// Create doctrine cache directory if its not exists
|
||||
!Filesystem::has($cache_directory) and Filesystem::createDir($cache_directory);
|
||||
$driver = new DoctrineCache\FilesystemCache($cache_directory);
|
||||
|
||||
return $driver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Default Cache Driver Name
|
||||
*
|
||||
* @access protected
|
||||
* @param string $driver_name Driver name.
|
||||
* @return string
|
||||
*/
|
||||
protected function setDefaultCacheDriverName(string $driver_name)
|
||||
{
|
||||
if (!$driver_name || $driver_name == 'auto') {
|
||||
if (extension_loaded('apcu')) {
|
||||
$driver_name = 'apcu';
|
||||
} elseif (extension_loaded('wincache')) {
|
||||
$driver_name = 'wincache';
|
||||
} else {
|
||||
$driver_name = 'file';
|
||||
}
|
||||
}
|
||||
|
||||
return $driver_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns driver variable
|
||||
*
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public function driver()
|
||||
{
|
||||
return $this->driver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cache key.
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getKey() : string
|
||||
{
|
||||
return $this->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(string $id)
|
||||
{
|
||||
if ($this->flextype['registry']->get('settings.cache.enabled')) {
|
||||
return $this->driver->fetch($id);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a boolean state of whether or not the item exists in the cache based on id key
|
||||
*
|
||||
* @param string $id the id of the cached data entry
|
||||
* @return bool true if the cached items exists
|
||||
*/
|
||||
public function contains($id)
|
||||
{
|
||||
if ($this->flextype['registry']->get('settings.cache.enabled')) {
|
||||
return $this->driver->contains($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(string $id, $data, $lifetime = null)
|
||||
{
|
||||
if ($this->flextype['registry']->get('settings.cache.enabled')) {
|
||||
if ($lifetime === null) {
|
||||
$lifetime = $this->getLifetime();
|
||||
}
|
||||
$this->driver->save($id, $data, $lifetime);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear Cache
|
||||
*/
|
||||
public function clear() : void
|
||||
{
|
||||
// Clear stat cache
|
||||
@clearstatcache();
|
||||
|
||||
// Clear opcache
|
||||
function_exists('opcache_reset') and @opcache_reset();
|
||||
|
||||
// Remove cache dirs
|
||||
Filesystem::deleteDir(PATH['cache'] . '/doctrine/');
|
||||
Filesystem::deleteDir(PATH['cache'] . '/glide/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the cache lifetime.
|
||||
*
|
||||
* @access public
|
||||
* @param int $future timestamp
|
||||
*/
|
||||
public function setLifetime(int $future)
|
||||
{
|
||||
if (!$future) {
|
||||
return;
|
||||
}
|
||||
|
||||
$interval = $future-$this->now;
|
||||
|
||||
if ($interval > 0 && $interval < $this->getLifetime()) {
|
||||
$this->lifetime = $interval;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the cache lifetime (in seconds)
|
||||
*
|
||||
* @access public
|
||||
* @return mixed
|
||||
*/
|
||||
public function getLifetime()
|
||||
{
|
||||
if ($this->lifetime === null) {
|
||||
$this->lifetime = $this->flextype['registry']->get('settings.cache.lifetime') ?: 604800;
|
||||
}
|
||||
|
||||
return $this->lifetime;
|
||||
}
|
||||
}
|
30
flextype/core/Controller.php
Normal file
30
flextype/core/Controller.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Flextype
|
||||
*
|
||||
* @author Sergey Romanenko <hello@romanenko.digital>
|
||||
* @link http://romanenko.digital
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
class Controller
|
||||
{
|
||||
protected $container;
|
||||
|
||||
public function __construct($container)
|
||||
{
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
public function __get($property)
|
||||
{
|
||||
if ($this->container->{$property}) {
|
||||
return $this->container->{$property};
|
||||
}
|
||||
}
|
||||
}
|
283
flextype/core/Entries.php
Executable file
283
flextype/core/Entries.php
Executable file
@@ -0,0 +1,283 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Flextype
|
||||
*
|
||||
* @author Sergey Romanenko <hello@romanenko.digital>
|
||||
* @link http://romanenko.digital
|
||||
*
|
||||
* 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\Filesystem\Filesystem;
|
||||
|
||||
class Entries
|
||||
{
|
||||
/**
|
||||
* Flextype Dependency Container
|
||||
*/
|
||||
private $flextype;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function __construct($flextype)
|
||||
{
|
||||
$this->flextype = $flextype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch entry
|
||||
*
|
||||
* @access public
|
||||
* @param string $id Entry id
|
||||
* @return array|false The entry contents or false on failure.
|
||||
*/
|
||||
public function fetch(string $id)
|
||||
{
|
||||
$entry_file = $this->_file_location($id);
|
||||
|
||||
if (Filesystem::has($entry_file)) {
|
||||
$cache_id = md5('entry' . $entry_file . ((Filesystem::getTimestamp($entry_file) === false) ? '' : Filesystem::getTimestamp($entry_file)));
|
||||
|
||||
// Try to get the entry from cache
|
||||
if ($this->flextype['cache']->contains($cache_id)) {
|
||||
if ($entry_decoded = $this->flextype['cache']->fetch($cache_id)) {
|
||||
|
||||
// Apply Shortcodes for each entry fields
|
||||
foreach ($entry_decoded as $key => $_entry_decoded) {
|
||||
$entry_decoded[$key] = $_entry_decoded;//$this->flextype['shortcodes']->process($_entry_decoded);
|
||||
}
|
||||
|
||||
return $entry_decoded;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if ($entry_body = Filesystem::read($entry_file)) {
|
||||
if ($entry_decoded = JsonParser::decode($entry_body)) {
|
||||
|
||||
// Create default entry items
|
||||
$entry_decoded['date'] = $entry_decoded['date'] ?? date($this->flextype['registry']->get('settings.date_format'), Filesystem::getTimestamp($entry_file));
|
||||
$entry_decoded['slug'] = $entry_decoded['slug'] ?? ltrim(rtrim($id, '/'), '/');
|
||||
|
||||
// Save to cache
|
||||
$this->flextype['cache']->save($cache_id, $entry_decoded);
|
||||
|
||||
// Apply Shortcodes for each entry fields
|
||||
foreach ($entry_decoded as $key => $_entry_decoded) {
|
||||
$entry_decoded[$key] = $_entry_decoded;//$this->flextype['shortcodes']->process($_entry_decoded);
|
||||
}
|
||||
|
||||
return $entry_decoded;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch all entries
|
||||
*
|
||||
* @access public
|
||||
* @param string $id Entry id
|
||||
* @param string $order_by Order by specific entry field.
|
||||
* @param string $order_type Order type: DESC or ASC
|
||||
* @param int $offset Offset
|
||||
* @param int $length Length
|
||||
* @return array The entries
|
||||
*/
|
||||
public function fetchAll(string $id, string $order_by = 'date', string $order_type = 'DESC', int $offset = null, int $length = null) : array
|
||||
{
|
||||
// Entries array where founded entries will stored
|
||||
$entries = [];
|
||||
|
||||
// Сache id
|
||||
$cache_id = '';
|
||||
|
||||
// Entries path
|
||||
$entries_path = $this->_dir_location($id);
|
||||
|
||||
// Get entries list
|
||||
$entries_list = Filesystem::listContents($entries_path);
|
||||
|
||||
// Create entries cached id
|
||||
foreach ($entries_list as $current_entry) {
|
||||
if (strpos($current_entry['path'], $id . '/entry.json') !== false) {
|
||||
// ignore ...
|
||||
} else {
|
||||
if ($current_entry['type'] == 'dir' && Filesystem::has($current_entry['path'] . '/entry.json')) {
|
||||
$cache_id .= md5('entries' . $current_entry['path'] . Filesystem::getTimestamp($current_entry['path'] . '/entry.json'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->flextype['cache']->contains($cache_id)) {
|
||||
$entries = $this->flextype['cache']->fetch($cache_id);
|
||||
} else {
|
||||
|
||||
// Create entries array from entries list and ignore current requested entry
|
||||
foreach ($entries_list as $current_entry) {
|
||||
if (strpos($current_entry['path'], $id . '/entry.json') !== false) {
|
||||
// ignore ...
|
||||
} else {
|
||||
if ($current_entry['type'] == 'dir' && Filesystem::has($current_entry['path'] . '/entry.json')) {
|
||||
$entries[$current_entry['dirname']] = $this->fetch($id . '/' . $current_entry['dirname']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->flextype['cache']->save($cache_id, $entries);
|
||||
}
|
||||
|
||||
// Sort and Slice entries if $raw === false
|
||||
if (count($entries) > 0) {
|
||||
$entries = Arr::sort($entries, $order_by, $order_type);
|
||||
|
||||
if ($offset !== null && $length !== null) {
|
||||
$entries = array_slice($entries, $offset, $length);
|
||||
}
|
||||
}
|
||||
|
||||
return $entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename entry.
|
||||
*
|
||||
* @access public
|
||||
* @param string $id Entry id
|
||||
* @param string $new_id New entry id
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function rename(string $id, string $new_id) : bool
|
||||
{
|
||||
return rename($this->_dir_location($id), $this->_dir_location($new_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update entry
|
||||
*
|
||||
* @access public
|
||||
* @param string $id Entry
|
||||
* @param array $data Data
|
||||
* @return bool
|
||||
*/
|
||||
public function update(string $id, array $data) : bool
|
||||
{
|
||||
$entry_file = $this->_file_location($id);
|
||||
|
||||
if (Filesystem::has($entry_file)) {
|
||||
return Filesystem::write($entry_file, JsonParser::encode($data));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create entry
|
||||
*
|
||||
* @access public
|
||||
* @param string $id Entry id
|
||||
* @param array $data Data
|
||||
* @return bool
|
||||
*/
|
||||
public function create(string $id, array $data) : bool
|
||||
{
|
||||
$entry_dir = $this->_dir_location($id);
|
||||
|
||||
// Check if new entry directory exists
|
||||
if (!Filesystem::has($entry_dir)) {
|
||||
|
||||
// Try to create directory for new entry
|
||||
if (Filesystem::createDir($entry_dir)) {
|
||||
$entry_file = $entry_dir . '/entry.json';
|
||||
|
||||
// Check if new entry file exists
|
||||
if (!Filesystem::has($entry_file)) {
|
||||
return Filesystem::write($entry_file, JsonParser::encode($data));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete entry.
|
||||
*
|
||||
* @access public
|
||||
* @param string $id Entry id
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function delete(string $id) : bool
|
||||
{
|
||||
return Filesystem::deleteDir($this->_dir_location($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy entry(s)
|
||||
*
|
||||
* @access public
|
||||
* @param string $id Entry id
|
||||
* @param string $new_id New entry id
|
||||
* @param bool $recursive Recursive copy entries.
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function copy(string $id, string $new_id, bool $recursive = false)
|
||||
{
|
||||
return Filesystem::copy($this->_dir_location($id), $this->_dir_location($new_id), $recursive);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether entry exists.
|
||||
*
|
||||
* @access public
|
||||
* @param string $id Entry
|
||||
* @return bool
|
||||
*/
|
||||
public function has(string $id) : bool
|
||||
{
|
||||
return Filesystem::has($this->_file_location($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method _file_location
|
||||
*
|
||||
* @access private
|
||||
* @param string $id Entry id
|
||||
* @return string
|
||||
*/
|
||||
private function _file_location(string $id) : string
|
||||
{
|
||||
return PATH['entries'] . '/' . $id . '/entry.json';
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method _dir_location
|
||||
*
|
||||
* @access private
|
||||
* @param string $id Entry id
|
||||
* @return string
|
||||
*/
|
||||
private function _dir_location(string $id) : string
|
||||
{
|
||||
return PATH['entries'] . '/' . $id;
|
||||
}
|
||||
}
|
198
flextype/core/Fieldsets.php
Normal file
198
flextype/core/Fieldsets.php
Normal file
@@ -0,0 +1,198 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Flextype
|
||||
*
|
||||
* @author Sergey Romanenko <hello@romanenko.digital>
|
||||
* @link http://romanenko.digital
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
|
||||
class Fieldsets
|
||||
{
|
||||
/**
|
||||
* Flextype Dependency Container
|
||||
*/
|
||||
private $flextype;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function __construct($flextype)
|
||||
{
|
||||
$this->flextype = $flextype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch fieldset
|
||||
*
|
||||
* @access public
|
||||
* @param string $id Fieldset id
|
||||
* @return array|false The entry contents or false on failure.
|
||||
*/
|
||||
public function fetch(string $id)
|
||||
{
|
||||
$fieldset_file = $this->_file_location($id);
|
||||
|
||||
if (Filesystem::has($fieldset_file)) {
|
||||
if ($fieldset_body = Filesystem::read($fieldset_file)) {
|
||||
if ($fieldset_decoded = JsonParser::decode($fieldset_body)) {
|
||||
return $fieldset_decoded;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch all fieldsets
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function fetchAll() : array
|
||||
{
|
||||
// Init Fieldsets array
|
||||
$fieldsets = [];
|
||||
|
||||
// Get fieldsets files
|
||||
$_fieldsets = Filesystem::listContents($this->_dir_location());
|
||||
|
||||
// If there is any fieldsets file then go...
|
||||
if (count($_fieldsets) > 0) {
|
||||
foreach ($_fieldsets as $fieldset) {
|
||||
if ($fieldset['type'] == 'file' && $fieldset['extension'] == 'json') {
|
||||
$fieldset_content = JsonParser::decode(Filesystem::read($fieldset['path']));
|
||||
$fieldsets[$fieldset['basename']] = $fieldset_content['title'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return fieldsets array
|
||||
return $fieldsets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename fieldset
|
||||
*
|
||||
* @access public
|
||||
* @param string $id Fieldset id
|
||||
* @param string $new_id New fieldset id
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function rename(string $id, string $new_id) : bool
|
||||
{
|
||||
return rename($this->_file_location($id), $this->_file_location($new_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update fieldset
|
||||
*
|
||||
* @access public
|
||||
* @param string $id Fieldset id
|
||||
* @param array $data Fieldset data to save
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function update(string $id, array $data) : bool
|
||||
{
|
||||
$fieldset_file = $this->_file_location($id);
|
||||
|
||||
if (Filesystem::has($fieldset_file)) {
|
||||
return Filesystem::write($fieldset_file, JsonParser::encode($data));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create fieldset
|
||||
*
|
||||
* @access public
|
||||
* @param string $id Fieldset id
|
||||
* @param array $data Fieldset data to save
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function create(string $id, array $data) : bool
|
||||
{
|
||||
$fieldset_file = $this->_file_location($id);
|
||||
|
||||
if (!Filesystem::has($fieldset_file)) {
|
||||
return Filesystem::write($fieldset_file, JsonParser::encode($data));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete fieldset
|
||||
*
|
||||
* @access public
|
||||
* @param string $id Fieldset id
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function delete(string $id) : bool
|
||||
{
|
||||
return Filesystem::delete($this->_file_location($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy fieldset
|
||||
*
|
||||
* @access public
|
||||
* @param string $id Fieldset id
|
||||
* @param string $new_id New fieldset id
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function copy(string $id, string $new_id) : bool
|
||||
{
|
||||
return Filesystem::copy($this->_file_location($id), $this->_file_location($new_id), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether fieldset exists.
|
||||
*
|
||||
* @access public
|
||||
* @param string $id Fieldset id
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function has(string $id) : bool
|
||||
{
|
||||
return Filesystem::has($this->_file_location($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method _dir_location
|
||||
*
|
||||
* @access private
|
||||
* @return string
|
||||
*/
|
||||
private function _dir_location() : string
|
||||
{
|
||||
return PATH['site'] . '/fieldsets/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method _file_location
|
||||
*
|
||||
* @access private
|
||||
* @param string $id Fieldsets id
|
||||
* @return string
|
||||
*/
|
||||
private function _file_location(string $id) : string
|
||||
{
|
||||
return PATH['site'] . '/fieldsets/' . $id . '.json';
|
||||
}
|
||||
}
|
30
flextype/core/Middleware.php
Normal file
30
flextype/core/Middleware.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Flextype
|
||||
*
|
||||
* @author Sergey Romanenko <hello@romanenko.digital>
|
||||
* @link http://romanenko.digital
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
class Middleware
|
||||
{
|
||||
protected $container;
|
||||
|
||||
public function __construct($container)
|
||||
{
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
public function __get($property)
|
||||
{
|
||||
if ($this->container->{$property}) {
|
||||
return $this->container->{$property};
|
||||
}
|
||||
}
|
||||
}
|
201
flextype/core/Plugins.php
Executable file
201
flextype/core/Plugins.php
Executable file
@@ -0,0 +1,201 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Flextype
|
||||
*
|
||||
* @author Sergey Romanenko <hello@romanenko.digital>
|
||||
* @link http://romanenko.digital
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
use Flextype\Component\I18n\I18n;
|
||||
use Flextype\Component\Arr\Arr;
|
||||
|
||||
class Plugins
|
||||
{
|
||||
/**
|
||||
* Flextype Dependency Container
|
||||
*/
|
||||
private $flextype;
|
||||
|
||||
/**
|
||||
* Locales array
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $locales = [];
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function __construct($flextype, $app)
|
||||
{
|
||||
$this->flextype = $flextype;
|
||||
$this->locales = JsonParser::decode(Filesystem::read(ROOT_DIR . '/flextype/config/locales.json'));
|
||||
}
|
||||
|
||||
public function getLocales()
|
||||
{
|
||||
return $this->locales;
|
||||
}
|
||||
|
||||
/**
|
||||
* Init Plugins
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
public function init($flextype, $app) : void
|
||||
{
|
||||
// Set empty plugins item
|
||||
$this->flextype['registry']->set('plugins', []);
|
||||
|
||||
// Get Plugins List
|
||||
$_plugins_list = Filesystem::listContents(PATH['plugins']);
|
||||
$plugins_list = [];
|
||||
|
||||
foreach($_plugins_list as $plugin) {
|
||||
if ($plugin['type'] == 'dir') {
|
||||
$plugins_list[] = $plugin;
|
||||
}
|
||||
}
|
||||
|
||||
// Get plugins cache ID
|
||||
$plugins_cache_id = $this->getPluginsCacheID($plugins_list);
|
||||
|
||||
// If Plugins List isnt empty then create plugin cache ID
|
||||
if (is_array($plugins_list) && count($plugins_list) > 0) {
|
||||
|
||||
// Get plugins list from cache or scan plugins folder and create new plugins cache item
|
||||
if ($this->flextype['cache']->contains($plugins_cache_id)) {
|
||||
$this->flextype['registry']->set('plugins', $this->flextype['cache']->fetch($plugins_cache_id));
|
||||
} else {
|
||||
|
||||
// If Plugins List isnt empty
|
||||
if (is_array($plugins_list) && count($plugins_list) > 0) {
|
||||
|
||||
// Init plugin configs
|
||||
$_plugins_config = [];
|
||||
$plugin_settings = [];
|
||||
$plugin_config = [];
|
||||
|
||||
// Go through...
|
||||
foreach ($plugins_list as $plugin) {
|
||||
if (Filesystem::has($_plugin_settings = PATH['plugins'] . '/' . $plugin['dirname'] . '/settings.json')) {
|
||||
if (($content = Filesystem::read($_plugin_settings)) === false) {
|
||||
throw new \RuntimeException('Load file: ' . $_plugin_settings . ' - failed!');
|
||||
} else {
|
||||
$plugin_settings = JsonParser::decode($content);
|
||||
}
|
||||
}
|
||||
|
||||
if (Filesystem::has($_plugin_config = PATH['plugins'] . '/' . $plugin['dirname'] . '/plugin.json')) {
|
||||
if (($content = Filesystem::read($_plugin_config)) === false) {
|
||||
throw new \RuntimeException('Load file: ' . $_plugin_config . ' - failed!');
|
||||
} else {
|
||||
$plugin_config = JsonParser::decode($content);
|
||||
}
|
||||
}
|
||||
|
||||
$_plugins_config[$plugin['dirname']] = array_merge($plugin_settings, $plugin_config);
|
||||
|
||||
// Set default plugin priority 0
|
||||
if (!isset($_plugins_config[$plugin['dirname']]['priority'])) {
|
||||
$_plugins_config[$plugin['dirname']]['priority'] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Sort plugins list by priority.
|
||||
$_plugins_config = Arr::sort($_plugins_config, 'priority', 'DESC');
|
||||
|
||||
$this->flextype['registry']->set('plugins', $_plugins_config);
|
||||
$this->flextype['cache']->save($plugins_cache_id, $_plugins_config);
|
||||
}
|
||||
}
|
||||
|
||||
$this->createPluginsDictionary($plugins_list);
|
||||
|
||||
$this->includeEnabledPlugins($flextype, $app);
|
||||
|
||||
$this->flextype['emitter']->emit('onPluginsInitialized');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create plugins dictionary
|
||||
*
|
||||
* @param array $plugins_list Plugins list
|
||||
* @access protected
|
||||
* @return void
|
||||
*/
|
||||
private function createPluginsDictionary(array $plugins_list) : void
|
||||
{
|
||||
if (is_array($plugins_list) && count($plugins_list) > 0) {
|
||||
foreach ($this->locales as $locale => $locale_title) {
|
||||
foreach ($plugins_list as $plugin) {
|
||||
$language_file = PATH['plugins'] . '/' . $plugin['dirname'] . '/lang/' . $locale . '.json';
|
||||
if (Filesystem::has($language_file)) {
|
||||
if (($content = Filesystem::read($language_file)) === false) {
|
||||
throw new \RuntimeException('Load file: ' . $language_file . ' - failed!');
|
||||
} else {
|
||||
I18n::add(JsonParser::decode($content), $locale);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get plugins cache ID
|
||||
*
|
||||
* @param array $plugins_list Plugins list
|
||||
* @access protected
|
||||
* @return string
|
||||
*/
|
||||
private function getPluginsCacheID(array $plugins_list) : string
|
||||
{
|
||||
// Plugin cache id
|
||||
$_plugins_cache_id = '';
|
||||
|
||||
// Go through...
|
||||
if (is_array($plugins_list) && count($plugins_list) > 0) {
|
||||
foreach ($plugins_list as $plugin) {
|
||||
if (Filesystem::has($_plugin_settings = PATH['plugins'] . '/' . $plugin['dirname'] . '/settings.json') and
|
||||
Filesystem::has($_plugin_config = PATH['plugins'] . '/' . $plugin['dirname'] . '/plugin.json')) {
|
||||
$_plugins_cache_id .= filemtime($_plugin_settings) . filemtime($_plugin_config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create Unique Cache ID for Plugins
|
||||
$plugins_cache_id = md5('plugins' . PATH['plugins'] . '/' . $_plugins_cache_id);
|
||||
|
||||
// Return plugin cache id
|
||||
return $plugins_cache_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Include enabled plugins
|
||||
*
|
||||
* @access protected
|
||||
* @return void
|
||||
*/
|
||||
private function includeEnabledPlugins($flextype, $app) : void
|
||||
{
|
||||
if (is_array($this->flextype['registry']->get('plugins')) && count($this->flextype['registry']->get('plugins')) > 0) {
|
||||
foreach ($this->flextype['registry']->get('plugins') as $plugin_name => $plugin) {
|
||||
if ($this->flextype['registry']->get('plugins.' . $plugin_name . '.enabled')) {
|
||||
include_once PATH['plugins'] . '/' . $plugin_name . '/bootstrap.php';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
241
flextype/core/Snippets.php
Normal file
241
flextype/core/Snippets.php
Normal file
@@ -0,0 +1,241 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Flextype
|
||||
*
|
||||
* @author Sergey Romanenko <hello@romanenko.digital>
|
||||
* @link http://romanenko.digital
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
|
||||
class Snippets
|
||||
{
|
||||
/**
|
||||
* Flextype Dependency Container
|
||||
*/
|
||||
private $flextype;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function __construct($flextype)
|
||||
{
|
||||
$this->flextype = $flextype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get snippet
|
||||
*
|
||||
* @access public
|
||||
* @param string $id Snippet id
|
||||
* @return string|bool Returns the contents of the output buffer and end output buffering.
|
||||
* If output buffering isn't active then FALSE is returned.
|
||||
*/
|
||||
public function display(string $id)
|
||||
{
|
||||
return $this->_display_snippet(['fetch' => $id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch snippet
|
||||
*
|
||||
* @access public
|
||||
* @param string $id Snippet id
|
||||
* @return array|false The entry contents or false on failure.
|
||||
*/
|
||||
public function fetch(string $id)
|
||||
{
|
||||
$snippet_file = $this->_file_location($id);
|
||||
|
||||
if (Filesystem::has($snippet_file)) {
|
||||
if ($snippet_body = Filesystem::read($snippet_file)) {
|
||||
return $snippet_body;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch Snippets
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function fetchAll() : array
|
||||
{
|
||||
$snippets = [];
|
||||
|
||||
// Get snippets files
|
||||
$_snippets = Filesystem::listContents($this->_dir_location());
|
||||
|
||||
// If there is any snippets file then go...
|
||||
if (count($_snippets) > 0) {
|
||||
foreach ($_snippets as $snippet) {
|
||||
if ($snippet['type'] == 'file' && $snippet['extension'] == 'php') {
|
||||
$snippets[$snippet['basename']] = $snippet['basename'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return snippets
|
||||
return $snippets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename snippet.
|
||||
*
|
||||
* @access public
|
||||
* @param string $id Snippet id
|
||||
* @param string $new_id New snippet id
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function rename(string $id, string $new_id) : bool
|
||||
{
|
||||
return rename($this->_file_location($id), $this->_file_location($new_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update Snippet
|
||||
*
|
||||
* @access public
|
||||
* @param string $id Snippet id
|
||||
* @param string $data Data
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function update(string $id, string $data) : bool
|
||||
{
|
||||
$snippet_file = $this->_file_location($id);
|
||||
|
||||
if (Filesystem::has($snippet_file)) {
|
||||
return Filesystem::write($snippet_file, $data);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create snippet
|
||||
*
|
||||
* @access public
|
||||
* @param string $id Snippet id
|
||||
* @param string $data Data
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function create(string $id, string $data = '') : bool
|
||||
{
|
||||
$snippet_file = $this->_file_location($id);
|
||||
|
||||
// Check if new entry file exists
|
||||
if (!Filesystem::has($snippet_file)) {
|
||||
return Filesystem::write($snippet_file, $data);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete snippet.
|
||||
*
|
||||
* @access public
|
||||
* @param string $id Snippet id
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function delete(string $id) : bool
|
||||
{
|
||||
return Filesystem::delete($this->_file_location($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy snippet
|
||||
*
|
||||
* @access public
|
||||
* @param string $id Snippet id
|
||||
* @param string $new_id New snippet id
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function copy(string $id, string $new_id) : bool
|
||||
{
|
||||
return Filesystem::copy($this->_file_location($id), $this->_file_location($new_id), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether snippet exists.
|
||||
*
|
||||
* @access public
|
||||
* @param string $id Snippet id
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function has(string $id) : bool
|
||||
{
|
||||
return Filesystem::has($this->_file_location($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper private method _display_snippet
|
||||
*
|
||||
* @access private
|
||||
* @param array $vars Vars
|
||||
* @return string|bool Returns the contents of the output buffer and end output buffering.
|
||||
* If output buffering isn't active then FALSE is returned.
|
||||
*/
|
||||
private function _display_snippet(array $vars)
|
||||
{
|
||||
// Extracst attributes
|
||||
extract($vars);
|
||||
|
||||
// Get snippet name
|
||||
$name = (isset($fetch)) ? (string) $fetch : '';
|
||||
|
||||
// Define snippet path
|
||||
$snippet_file = $this->_file_location($name);
|
||||
|
||||
// Process snippet
|
||||
if (Filesystem::has($snippet_file)) {
|
||||
|
||||
// Turn on output buffering
|
||||
ob_start();
|
||||
|
||||
// Include view file
|
||||
include $snippet_file;
|
||||
|
||||
// Output...
|
||||
return ob_get_clean();
|
||||
} else {
|
||||
throw new \RuntimeException("Snippet {$name} does not exist.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method _file_location
|
||||
*
|
||||
* @access private
|
||||
* @param string $id Snippet id
|
||||
* @return string
|
||||
*/
|
||||
private function _file_location(string $id) : string
|
||||
{
|
||||
return PATH['snippets'] . '/' . $id . '.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method _dir_location
|
||||
*
|
||||
* @access private
|
||||
* @return string
|
||||
*/
|
||||
private function _dir_location() : string
|
||||
{
|
||||
return PATH['snippets'] . '/';
|
||||
}
|
||||
}
|
114
flextype/core/Themes.php
Normal file
114
flextype/core/Themes.php
Normal file
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Flextype
|
||||
*
|
||||
* @author Sergey Romanenko <hello@romanenko.digital>
|
||||
* @link http://romanenko.digital
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
|
||||
class Themes
|
||||
{
|
||||
/**
|
||||
* Flextype Dependency Container
|
||||
*/
|
||||
private $flextype;
|
||||
|
||||
/**
|
||||
* Private construct method to enforce singleton behavior.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
public function __construct($flextype)
|
||||
{
|
||||
$this->flextype = $flextype;
|
||||
}
|
||||
|
||||
public function init($flextype, $app)
|
||||
{
|
||||
|
||||
// Get current theme
|
||||
$theme = $this->flextype['registry']->get('settings.theme');
|
||||
|
||||
// Set empty themes items
|
||||
$this->flextype['registry']->set('themes', []);
|
||||
|
||||
// Create Unique Cache ID for Theme
|
||||
$theme_cache_id = md5('theme' . filemtime(PATH['themes'] . '/' . $theme . '/' . 'settings.json') .
|
||||
filemtime(PATH['themes'] . '/' . $theme . '/' . 'theme.json'));
|
||||
|
||||
// Get Theme mafifest file and write to settings.themes array
|
||||
if ($this->flextype['cache']->contains($theme_cache_id)) {
|
||||
$this->flextype['registry']->set('themes.' . $this->flextype['registry']->get('settings.theme'), $this->flextype['cache']->fetch($theme_cache_id));
|
||||
} else {
|
||||
if (Filesystem::has($theme_settings = PATH['themes'] . '/' . $theme . '/' . 'settings.json') and
|
||||
Filesystem::has($theme_config = PATH['themes'] . '/' . $theme . '/' . 'theme.json')) {
|
||||
$theme_settings = JsonParser::decode(Filesystem::read($theme_settings));
|
||||
$theme_config = JsonParser::decode(Filesystem::read($theme_config));
|
||||
$_theme = array_merge($theme_settings, $theme_config);
|
||||
$this->flextype['registry']->set('themes.' . $this->flextype['registry']->get('settings.theme'), $_theme);
|
||||
$this->flextype['cache']->save($theme_cache_id, $_theme);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get partials for current theme
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getPartials() : array
|
||||
{
|
||||
$partials = [];
|
||||
|
||||
// Get partials files
|
||||
$_partials = Filesystem::listContents(PATH['themes'] . '/' . $this->flextype['registry']->get('settings.theme') . '/templates/partials/');
|
||||
|
||||
// If there is any partials file then go...
|
||||
if (count($_partials) > 0) {
|
||||
foreach ($_partials as $partial) {
|
||||
if ($partial['type'] == 'file' && $partial['extension'] == 'html') {
|
||||
$partials[$partial['basename']] = $partial['basename'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return partials
|
||||
return $partials;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get templates for current theme
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getTemplates() : array
|
||||
{
|
||||
$templates = [];
|
||||
|
||||
// Get templates files
|
||||
$_templates = Filesystem::listContents(PATH['themes'] . '/' . $this->flextype['registry']->get('settings.theme') . '/templates/');
|
||||
|
||||
// If there is any template file then go...
|
||||
if (count($_templates) > 0) {
|
||||
foreach ($_templates as $template) {
|
||||
if ($template['type'] == 'file' && $template['extension'] == 'html') {
|
||||
$templates[$template['basename']] = $template['basename'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return templates
|
||||
return $templates;
|
||||
}
|
||||
}
|
231
flextype/dependencies.php
Normal file
231
flextype/dependencies.php
Normal file
@@ -0,0 +1,231 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Flextype
|
||||
*
|
||||
* @author Romanenko Sergey <hello@romanenko.digital>
|
||||
* @link http://romanenko.digital
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Registry\Registry;
|
||||
use Thunder\Shortcode\ShortcodeFacade;
|
||||
use Slim\Flash\Messages;
|
||||
use Cocur\Slugify\Slugify;
|
||||
use League\Glide\ServerFactory;
|
||||
use League\Glide\Responses\SlimResponseFactory;
|
||||
use League\Event\Emitter;
|
||||
|
||||
/**
|
||||
* Add CSRF (cross-site request forgery) protection service to Flextype container
|
||||
*/
|
||||
$flextype['csrf'] = function ($container) {
|
||||
return new \Slim\Csrf\Guard;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add logger
|
||||
*/
|
||||
$flextype['logger'] = function($container) {
|
||||
$logger = new \Monolog\Logger('flextype');
|
||||
$file_handler = new \Monolog\Handler\StreamHandler(PATH['site'] . '/logs/' . date('Y-m-d') . '.log');
|
||||
$logger->pushHandler($file_handler);
|
||||
return $logger;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add emitter service to Flextype container
|
||||
*/
|
||||
$flextype['emitter'] = function ($container) {
|
||||
return new Emitter();
|
||||
};
|
||||
|
||||
/**
|
||||
* Add slugify service to Flextype container
|
||||
*/
|
||||
$flextype['slugify'] = function ($container) {
|
||||
return new Slugify(['separator' => '-', 'lowercase' => true, 'trim' => true]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add flash service to Flextype container
|
||||
*/
|
||||
$flextype['flash'] = function ($container) {
|
||||
return new Messages();
|
||||
};
|
||||
|
||||
/**
|
||||
* Add registry service to Flextype container
|
||||
*/
|
||||
$flextype['registry'] = function ($container) {
|
||||
return new Registry();
|
||||
};
|
||||
|
||||
/**
|
||||
* Add cache service to Flextype container
|
||||
*/
|
||||
$flextype['cache'] = function ($container) use ($flextype) {
|
||||
return new Cache($flextype);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add images service to Flextype container
|
||||
*/
|
||||
$flextype['images'] = function ($container) {
|
||||
|
||||
// Get images settings
|
||||
$imagesSettings = $container->get('settings')['images'];
|
||||
|
||||
// Set source filesystem
|
||||
$source = new \League\Flysystem\Filesystem(
|
||||
new \League\Flysystem\Adapter\Local(PATH['entries'])
|
||||
);
|
||||
|
||||
// Set cache filesystem
|
||||
$cache = new \League\Flysystem\Filesystem(
|
||||
new \League\Flysystem\Adapter\Local(PATH['cache'] . '/glide')
|
||||
);
|
||||
|
||||
// Set watermarks filesystem
|
||||
$watermarks = new \League\Flysystem\Filesystem(
|
||||
new \League\Flysystem\Adapter\Local(PATH['site'] . '/watermarks')
|
||||
);
|
||||
|
||||
// Set image manager
|
||||
$imageManager = new \Intervention\Image\ImageManager($imagesSettings);
|
||||
|
||||
// Set manipulators
|
||||
$manipulators = [
|
||||
new \League\Glide\Manipulators\Orientation(),
|
||||
new \League\Glide\Manipulators\Crop(),
|
||||
new \League\Glide\Manipulators\Size(2000*2000),
|
||||
new \League\Glide\Manipulators\Brightness(),
|
||||
new \League\Glide\Manipulators\Contrast(),
|
||||
new \League\Glide\Manipulators\Gamma(),
|
||||
new \League\Glide\Manipulators\Sharpen(),
|
||||
new \League\Glide\Manipulators\Filter(),
|
||||
new \League\Glide\Manipulators\Blur(),
|
||||
new \League\Glide\Manipulators\Pixelate(),
|
||||
new \League\Glide\Manipulators\Watermark($watermarks),
|
||||
new \League\Glide\Manipulators\Background(),
|
||||
new \League\Glide\Manipulators\Border(),
|
||||
new \League\Glide\Manipulators\Encode(),
|
||||
];
|
||||
|
||||
// Set API
|
||||
$api = new \League\Glide\Api\Api($imageManager, $manipulators);
|
||||
|
||||
// Setup Glide server
|
||||
$server = \League\Glide\ServerFactory::create([
|
||||
'source' => $source,
|
||||
'cache' => $cache,
|
||||
'api' => $api,
|
||||
'response' => new SlimResponseFactory(),
|
||||
]);
|
||||
|
||||
return $server;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add fieldsets service to Flextype container
|
||||
*/
|
||||
$flextype['fieldsets'] = function ($container) use ($flextype) {
|
||||
return new Fieldsets($flextype);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add snippets service to Flextype container
|
||||
*/
|
||||
$flextype['snippets'] = function ($container) use ($flextype) {
|
||||
return new Snippets($flextype);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add shortcodes service to Flextype container
|
||||
*/
|
||||
$flextype['shortcodes'] = function ($container) {
|
||||
return new ShortcodeFacade();
|
||||
};
|
||||
|
||||
/**
|
||||
* Add entries service to Flextype container
|
||||
*/
|
||||
$flextype['entries'] = function ($container) {
|
||||
return new Entries($container);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add view service to Flextype container
|
||||
*/
|
||||
$flextype['view'] = function ($container) {
|
||||
|
||||
// Get twig settings
|
||||
$twigSettings = $container->get('settings')['twig'];
|
||||
|
||||
// Create Twig View
|
||||
$view = new \Slim\Views\Twig(PATH['site'], $twigSettings);
|
||||
|
||||
// Instantiate
|
||||
$router = $container->get('router');
|
||||
$uri = \Slim\Http\Uri::createFromEnvironment(new \Slim\Http\Environment($_SERVER));
|
||||
|
||||
// Add Twig Extension
|
||||
$view->addExtension(new \Slim\Views\TwigExtension($router, $uri));
|
||||
|
||||
// Add Twig Debug Extension
|
||||
$view->addExtension(new \Twig\Extension\DebugExtension());
|
||||
|
||||
// Add Entries Twig Extension
|
||||
$view->addExtension(new EntriesTwigExtension($container));
|
||||
|
||||
// Add Emitter Twig Extension
|
||||
$view->addExtension(new EmitterTwigExtension($container));
|
||||
|
||||
// Add Flash Twig Extension
|
||||
$view->addExtension(new FlashTwigExtension($container));
|
||||
|
||||
// Add I18n Twig Extension
|
||||
$view->addExtension(new I18nTwigExtension());
|
||||
|
||||
// Add JsonParser Extension
|
||||
$view->addExtension(new JsonParserTwigExtension());
|
||||
|
||||
// Add Filesystem Extension
|
||||
$view->addExtension(new FilesystemTwigExtension());
|
||||
|
||||
// Add Assets Twig Extension
|
||||
$view->addExtension(new AssetsTwigExtension());
|
||||
|
||||
// Add Csrf Twig Extension
|
||||
$view->addExtension(new CsrfTwigExtension($container->get('csrf')));
|
||||
|
||||
// Add Global Vars Twig Extension
|
||||
$view->addExtension(new GlobalVarsTwigExtension($container));
|
||||
|
||||
// Add Global Shortcodes Twig Extension
|
||||
$view->addExtension(new ShortcodesTwigExtension($container));
|
||||
|
||||
// Add Global Snippets Twig Extension
|
||||
$view->addExtension(new SnippetsTwigExtension($container));
|
||||
|
||||
// Return view
|
||||
return $view;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add themes service to Flextype container
|
||||
*/
|
||||
$flextype['themes'] = function ($container) use ($flextype, $app) {
|
||||
return new Themes($flextype, $app);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add plugins service to Flextype container
|
||||
*/
|
||||
$flextype['plugins'] = function ($container) use ($flextype, $app) {
|
||||
return new Plugins($flextype, $app);
|
||||
};
|
26
flextype/middlewares.php
Normal file
26
flextype/middlewares.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Flextype
|
||||
*
|
||||
* @author Romanenko Sergey <hello@romanenko.digital>
|
||||
* @link http://romanenko.digital
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Psr7Middlewares\Middleware;
|
||||
use Psr7Middlewares\Middleware\TrailingSlash;
|
||||
|
||||
/**
|
||||
* Add middleware CSRF (cross-site request forgery) protection for all routes
|
||||
*/
|
||||
$app->add($flextype->get('csrf'));
|
||||
|
||||
/**
|
||||
* Add middleware TrailingSlash for all routes
|
||||
*/
|
||||
$app->add((new TrailingSlash(false))->redirect(301));
|
119
flextype/parsers/JsonParser.php
Normal file
119
flextype/parsers/JsonParser.php
Normal file
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Flextype
|
||||
*
|
||||
* @author Sergey Romanenko <hello@romanenko.digital>
|
||||
* @link http://romanenko.digital
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
class JsonParser
|
||||
{
|
||||
|
||||
/**
|
||||
* Encode options
|
||||
*
|
||||
* Bitmask consisting of encode options
|
||||
* https://www.php.net/manual/en/function.json-encode.php
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public static $encode_options = JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT;
|
||||
|
||||
/**
|
||||
* Encode Depth
|
||||
*
|
||||
* Set the maximum depth.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public static $encode_depth = 512;
|
||||
|
||||
/**
|
||||
* Decode assoc
|
||||
*
|
||||
* Set the maximum depth.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public static $decode_assoc = true;
|
||||
|
||||
/**
|
||||
* Decode Depth
|
||||
*
|
||||
* Set the maximum depth.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public static $decode_depth = 512;
|
||||
|
||||
/**
|
||||
* Decode options
|
||||
*
|
||||
* Bitmask consisting of decode options
|
||||
* https://www.php.net/manual/en/function.json-decode.php
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public static $decode_options = 0;
|
||||
|
||||
/**
|
||||
* Returns the JSON representation of a value
|
||||
*
|
||||
* $result = JsonParser::encode($json_content);
|
||||
*
|
||||
* @param mixed $input A string containing JSON
|
||||
* @param int $encode_depth User specified recursion depth.
|
||||
* @param int $encode_options Bitmask consisting of encode options.
|
||||
* @return mixed The JSON converted to a PHP value
|
||||
*
|
||||
*/
|
||||
public static function encode($input, int $encode_options = 0, int $encode_depth = 512) : string
|
||||
{
|
||||
$encoded = @json_encode(
|
||||
$input,
|
||||
$encode_options ? $encode_options : JsonParser::$encode_options,
|
||||
$encode_depth ? $encode_depth : JsonParser::$encode_depth
|
||||
);
|
||||
|
||||
if ($encoded === false) {
|
||||
throw new \RuntimeException('Encoding JSON failed');
|
||||
}
|
||||
|
||||
return $encoded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a JSON encoded string and converts it into a PHP variable.
|
||||
*
|
||||
* $array = JsonParser::decode($json_file_content);
|
||||
*
|
||||
* @param string $input A string containing JSON
|
||||
* @param bool $decode_assoc When TRUE, returned objects will be converted into associative arrays.
|
||||
* @param int $decode_depth User specified recursion depth.
|
||||
* @param int $decode_options Bitmask consisting of decode options.
|
||||
* @return mixed The JSON converted to a PHP value
|
||||
*
|
||||
* @throws ParseException If the JSON is not valid
|
||||
*/
|
||||
public static function decode(string $input, bool $decode_assoc = true, int $decode_depth = 512, int $decode_options = 0)
|
||||
{
|
||||
$decoded = @json_decode(
|
||||
$input,
|
||||
$decode_assoc ? $decode_assoc : JsonParser::$decode_assoc,
|
||||
$decode_depth ? $decode_depth : JsonParser::$decode_depth,
|
||||
$decode_options ? $decode_options : JsonParser::$decode_options
|
||||
);
|
||||
|
||||
if ($decoded === false) {
|
||||
throw new \RuntimeException('Decoding JSON failed');
|
||||
}
|
||||
|
||||
return $decoded;
|
||||
}
|
||||
}
|
@@ -1,118 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
use Symfony\Component\Yaml\Exception\DumpException;
|
||||
use Symfony\Component\Yaml\Exception\ParseException;
|
||||
|
||||
class YamlParser {
|
||||
|
||||
/**
|
||||
* Inline
|
||||
*
|
||||
* The level where you switch to inline YAML
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public static $inline = 5;
|
||||
|
||||
/**
|
||||
* Ident
|
||||
*
|
||||
* The amount of spaces to use for indentation of nested nodes
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public static $indent = 2;
|
||||
|
||||
/**
|
||||
* Native
|
||||
*
|
||||
* Use native parser or symfony
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public static $native = true;
|
||||
|
||||
/**
|
||||
* Flag
|
||||
*
|
||||
* A bit field of PARSE_* constants to customize the YAML parser behavior
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public static $flag = 16;
|
||||
|
||||
/**
|
||||
* Dumps a PHP value to a YAML string.
|
||||
*
|
||||
* The dump method, when supplied with an array, will do its best
|
||||
* to convert the array into friendly YAML.
|
||||
*
|
||||
* @param mixed $input The PHP value
|
||||
* @param int $inline The level where you switch to inline YAML
|
||||
* @param int $indent The amount of spaces to use for indentation of nested nodes
|
||||
* @param int $flags A bit field of DUMP_* constants to customize the dumped YAML string
|
||||
*
|
||||
* @return string A YAML string representing the original PHP value
|
||||
*/
|
||||
public static function encode($input, int $inline = 5, int $indent = 2, int $flags = 16) : string
|
||||
{
|
||||
try {
|
||||
return Yaml::dump(
|
||||
$input,
|
||||
$inline ? $inline : YamlParser::$inline,
|
||||
$indent ? $indent : YamlParser::$indent,
|
||||
$flags ? $flags : YamlParser::$flag
|
||||
);
|
||||
} catch (DumpException $e) {
|
||||
throw new \RuntimeException('Encoding YAML failed: ' . $e->getMessage(), 0, $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses YAML into a PHP value.
|
||||
*
|
||||
* $array = YamlParser::decode($yaml_file_content);
|
||||
*
|
||||
* @param string $input A string containing YAML
|
||||
* @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior
|
||||
*
|
||||
* @return mixed The YAML converted to a PHP value
|
||||
*
|
||||
* @throws ParseException If the YAML is not valid
|
||||
*/
|
||||
public static function decode(string $input, int $flags = 0)
|
||||
{
|
||||
// Try native PECL YAML PHP extension first if available.
|
||||
if (YamlParser::$native && function_exists('yaml_parse')) {
|
||||
|
||||
// Safely decode YAML.
|
||||
$saved = @ini_get('yaml.decode_php');
|
||||
@ini_set('yaml.decode_php', 0);
|
||||
$decoded = @yaml_parse($input);
|
||||
@ini_set('yaml.decode_php', $saved);
|
||||
|
||||
if ($decoded !== false) {
|
||||
return (array) $decoded;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return (array) Yaml::parse($input);
|
||||
} catch (ParseException $e) {
|
||||
throw new \RuntimeException('Decoding YAML failed: ' . $e->getMessage(), 0, $e);
|
||||
}
|
||||
}
|
||||
}
|
13
flextype/routes/web.php
Normal file
13
flextype/routes/web.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
/**
|
||||
* Generates and returns the image response
|
||||
*/
|
||||
$app->get('/image/{path:.+}', function (Request $request, Response $response, array $args) use ($flextype) {
|
||||
return $flextype['images']->getImageResponse($args['path'], $_GET);
|
||||
});
|
21
flextype/shortcodes/SiteUrlShortcode.php
Normal file
21
flextype/shortcodes/SiteUrlShortcode.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Flextype
|
||||
*
|
||||
* @author Sergey Romanenko <hello@romanenko.digital>
|
||||
* @link http://romanenko.digital
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Thunder\Shortcode\ShortcodeFacade;
|
||||
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
|
||||
|
||||
// Shortcode: [site_url]
|
||||
$flextype['shortcodes']->addHandler('site_url', function () {
|
||||
return \Slim\Http\Uri::createFromEnvironment(new \Slim\Http\Environment($_SERVER))->getBaseUrl();
|
||||
});
|
21
flextype/shortcodes/SnippetsShortcode.php
Normal file
21
flextype/shortcodes/SnippetsShortcode.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Flextype
|
||||
*
|
||||
* @author Sergey Romanenko <hello@romanenko.digital>
|
||||
* @link http://romanenko.digital
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Thunder\Shortcode\ShortcodeFacade;
|
||||
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
|
||||
|
||||
// Shortcode: [snippets fetch=snippet-name]
|
||||
$flextype['shortcodes']->addHandler('snippets', function (ShortcodeInterface $s) use ($flextype) {
|
||||
return $flextype['snippets']->display($s->getParameter('fetch'));
|
||||
});
|
41
flextype/twig/AssetsTwigExtension.php
Normal file
41
flextype/twig/AssetsTwigExtension.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Flextype
|
||||
*
|
||||
* @author Sergey Romanenko <hello@romanenko.digital>
|
||||
* @link http://romanenko.digital
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Assets\Assets;
|
||||
|
||||
class AssetsTwigExtension extends \Twig_Extension
|
||||
{
|
||||
/**
|
||||
* Callback for twig.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFunctions()
|
||||
{
|
||||
return [
|
||||
new \Twig_SimpleFunction('assets_add', [$this, 'add']),
|
||||
new \Twig_SimpleFunction('assets_get', [$this, 'get']),
|
||||
];
|
||||
}
|
||||
|
||||
public function add(string $asset_type, string $asset, string $namespace, int $priority = 1) : void
|
||||
{
|
||||
Assets::add($asset_type, $asset, $namespace, $priority);
|
||||
}
|
||||
|
||||
public function get(string $asset_type, string $namespace) : array
|
||||
{
|
||||
return Assets::get($asset_type, $namespace);
|
||||
}
|
||||
}
|
75
flextype/twig/CsrfTwigExtension.php
Normal file
75
flextype/twig/CsrfTwigExtension.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Flextype
|
||||
*
|
||||
* @author Sergey Romanenko <hello@romanenko.digital>
|
||||
* @link http://romanenko.digital
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
class CsrfTwigExtension extends \Twig_Extension implements \Twig_Extension_GlobalsInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @var \Slim\Csrf\Guard
|
||||
*/
|
||||
protected $csrf;
|
||||
|
||||
public function __construct(\Slim\Csrf\Guard $csrf)
|
||||
{
|
||||
$this->csrf = $csrf;
|
||||
}
|
||||
|
||||
public function getGlobals()
|
||||
{
|
||||
// CSRF token name and value
|
||||
$csrfNameKey = $this->csrf->getTokenNameKey();
|
||||
$csrfValueKey = $this->csrf->getTokenValueKey();
|
||||
$csrfName = $this->csrf->getTokenName();
|
||||
$csrfValue = $this->csrf->getTokenValue();
|
||||
|
||||
return [
|
||||
'csrf' => [
|
||||
'keys' => [
|
||||
'name' => $csrfNameKey,
|
||||
'value' => $csrfValueKey
|
||||
],
|
||||
'name' => $csrfName,
|
||||
'value' => $csrfValue
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'slim/csrf';
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for twig.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFunctions()
|
||||
{
|
||||
return [
|
||||
new \Twig_SimpleFunction('csrf', [$this, 'csrf'], ['is_safe' => ['html']]),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* CSRF
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function csrf()
|
||||
{
|
||||
return '<input type="hidden" name="'.$this->csrf->getTokenNameKey().'" value="'.$this->csrf->getTokenName().'">'.
|
||||
'<input type="hidden" name="'.$this->csrf->getTokenValueKey().'" value="'.$this->csrf->getTokenValue().'">';
|
||||
}
|
||||
}
|
46
flextype/twig/EmitterTwigExtension.php
Normal file
46
flextype/twig/EmitterTwigExtension.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Flextype
|
||||
*
|
||||
* @author Sergey Romanenko <hello@romanenko.digital>
|
||||
* @link http://romanenko.digital
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
class EmitterTwigExtension extends \Twig_Extension
|
||||
{
|
||||
/**
|
||||
* Flextype Dependency Container
|
||||
*/
|
||||
private $flextype;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct($flextype)
|
||||
{
|
||||
$this->flextype = $flextype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for twig.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFunctions()
|
||||
{
|
||||
return [
|
||||
new \Twig_SimpleFunction('emmiter_emmit', [$this, 'emit']),
|
||||
];
|
||||
}
|
||||
|
||||
public function emit(string $event)
|
||||
{
|
||||
$this->flextype['emitter']->emit($event);
|
||||
}
|
||||
}
|
52
flextype/twig/EntriesTwigExtension.php
Normal file
52
flextype/twig/EntriesTwigExtension.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Flextype
|
||||
*
|
||||
* @author Sergey Romanenko <hello@romanenko.digital>
|
||||
* @link http://romanenko.digital
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
class EntriesTwigExtension extends \Twig_Extension
|
||||
{
|
||||
/**
|
||||
* Flextype Dependency Container
|
||||
*/
|
||||
private $flextype;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct($flextype)
|
||||
{
|
||||
$this->flextype = $flextype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for twig.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFunctions()
|
||||
{
|
||||
return [
|
||||
new \Twig_SimpleFunction('entries_fetch', [$this, 'fetch']),
|
||||
new \Twig_SimpleFunction('entries_fetch_all', [$this, 'fetchAll']),
|
||||
];
|
||||
}
|
||||
|
||||
public function fetch(string $entry)
|
||||
{
|
||||
return $this->flextype['entries']->fetch($entry);
|
||||
}
|
||||
|
||||
public function fetchAll(string $entry, string $order_by = 'date', string $order_type = 'DESC', int $offset = null, int $length = null) : array
|
||||
{
|
||||
return $this->flextype['entries']->fetchAll($entry, $order_by, $order_type, $offset, $length);
|
||||
}
|
||||
}
|
53
flextype/twig/FilesystemTwigExtension.php
Normal file
53
flextype/twig/FilesystemTwigExtension.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Flextype
|
||||
*
|
||||
* @author Sergey Romanenko <hello@romanenko.digital>
|
||||
* @link http://romanenko.digital
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
|
||||
class FilesystemTwigExtension extends \Twig_Extension
|
||||
{
|
||||
/**
|
||||
* Callback for twig.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFunctions()
|
||||
{
|
||||
return [
|
||||
new \Twig_SimpleFunction('filesystem_has', [$this, 'has']),
|
||||
new \Twig_SimpleFunction('filesystem_read', [$this, 'read']),
|
||||
new \Twig_SimpleFunction('filesystem_ext', [$this, 'ext']),
|
||||
new \Twig_SimpleFunction('filesystem_basename', [$this, 'basename']),
|
||||
];
|
||||
}
|
||||
|
||||
public function has($path)
|
||||
{
|
||||
return Filesystem::has($path);
|
||||
}
|
||||
|
||||
public function read($path)
|
||||
{
|
||||
return Filesystem::read($path);
|
||||
}
|
||||
|
||||
public function ext($file)
|
||||
{
|
||||
return substr(strrchr($file, '.'), 1);
|
||||
}
|
||||
|
||||
public function basename($value, $suffix = '')
|
||||
{
|
||||
return basename($value, $suffix);
|
||||
}
|
||||
}
|
59
flextype/twig/FlashTwigExtension.php
Normal file
59
flextype/twig/FlashTwigExtension.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Flextype
|
||||
*
|
||||
* @author Sergey Romanenko <hello@romanenko.digital>
|
||||
* @link http://romanenko.digital
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Slim\Flash\Messages;
|
||||
|
||||
class FlashTwigExtension extends \Twig_Extension
|
||||
{
|
||||
/**
|
||||
* Flextype Dependency Container
|
||||
*/
|
||||
private $flextype;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct($flextype)
|
||||
{
|
||||
$this->flextype = $flextype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for twig.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFunctions() : array
|
||||
{
|
||||
return [
|
||||
new \Twig_SimpleFunction('flash', [$this, 'getMessages']),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Flash messages; If key is provided then returns messages
|
||||
* for that key.
|
||||
*
|
||||
* @param string $key
|
||||
* @return array
|
||||
*/
|
||||
public function getMessages($key = null) : array
|
||||
{
|
||||
if (null !== $key) {
|
||||
return $this->flextype['flash']->getMessage($key);
|
||||
}
|
||||
|
||||
return $this->flextype['flash']->getMessages();
|
||||
}
|
||||
}
|
47
flextype/twig/GlobalVarsTwigExtension.php
Normal file
47
flextype/twig/GlobalVarsTwigExtension.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Flextype
|
||||
*
|
||||
* @author Sergey Romanenko <hello@romanenko.digital>
|
||||
* @link http://romanenko.digital
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Session\Session;
|
||||
|
||||
class GlobalVarsTwigExtension extends \Twig_Extension implements \Twig_Extension_GlobalsInterface
|
||||
{
|
||||
/**
|
||||
* Flextype Dependency Container
|
||||
*/
|
||||
private $flextype;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct($flextype)
|
||||
{
|
||||
$this->flextype = $flextype;
|
||||
}
|
||||
|
||||
public function getGlobals()
|
||||
{
|
||||
return [
|
||||
'PATH_SITE' => PATH['site'],
|
||||
'PATH_PLUGINS' => PATH['plugins'],
|
||||
'PATH_THEMES' => PATH['themes'],
|
||||
'PATH_ENTRIES' => PATH['entries'],
|
||||
'PATH_SNIPPETS' => PATH['snippets'],
|
||||
'PATH_CONFIG_DEFAULT' => PATH['config']['default'],
|
||||
'PATH_CONFIG_SITE' => PATH['config']['site'],
|
||||
'PATH_CACHE' => PATH['cache'],
|
||||
'flextype_version' => FLEXTYPE_VERSION,
|
||||
'registry' => $this->flextype['registry']->dump()
|
||||
];
|
||||
}
|
||||
}
|
35
flextype/twig/I18nTwigExtension.php
Normal file
35
flextype/twig/I18nTwigExtension.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Flextype
|
||||
*
|
||||
* @author Sergey Romanenko <hello@romanenko.digital>
|
||||
* @link http://romanenko.digital
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\I18n\I18n;
|
||||
|
||||
class I18nTwigExtension extends \Twig_Extension
|
||||
{
|
||||
/**
|
||||
* Callback for twig.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFunctions()
|
||||
{
|
||||
return [
|
||||
new \Twig_SimpleFunction('tr', [$this, 'tr']),
|
||||
];
|
||||
}
|
||||
|
||||
public function tr(string $translate, string $locale = null, array $values = []) : string
|
||||
{
|
||||
return I18n::find($translate, $locale, $values);
|
||||
}
|
||||
}
|
39
flextype/twig/JsonParserTwigExtension.php
Normal file
39
flextype/twig/JsonParserTwigExtension.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Flextype
|
||||
*
|
||||
* @author Sergey Romanenko <hello@romanenko.digital>
|
||||
* @link http://romanenko.digital
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
class JsonParserTwigExtension extends \Twig_Extension
|
||||
{
|
||||
/**
|
||||
* Callback for twig.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFunctions()
|
||||
{
|
||||
return [
|
||||
new \Twig_SimpleFunction('json_parser_decode', [$this, 'decode']),
|
||||
new \Twig_SimpleFunction('json_parser_encode', [$this, 'encode'])
|
||||
];
|
||||
}
|
||||
|
||||
public function encode($input, int $encode_options = 0, int $encode_depth = 512) : string
|
||||
{
|
||||
return JsonParser::encode($input, $encode_options, $encode_depth);
|
||||
}
|
||||
|
||||
public function decode(string $input, bool $decode_assoc = true, int $decode_depth = 512, int $decode_options = 0)
|
||||
{
|
||||
return JsonParser::decode($input, $decode_assoc, $decode_depth, $decode_options);
|
||||
}
|
||||
}
|
47
flextype/twig/ShortcodesTwigExtension.php
Normal file
47
flextype/twig/ShortcodesTwigExtension.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Flextype
|
||||
*
|
||||
* @author Sergey Romanenko <hello@romanenko.digital>
|
||||
* @link http://romanenko.digital
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
class ShortcodesTwigExtension extends \Twig_Extension
|
||||
{
|
||||
|
||||
/**
|
||||
* Flextype Dependency Container
|
||||
*/
|
||||
private $flextype;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct($flextype)
|
||||
{
|
||||
$this->flextype = $flextype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for twig.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFilters()
|
||||
{
|
||||
return [
|
||||
new \Twig_SimpleFilter('shortcode', [$this, 'shortcode']),
|
||||
];
|
||||
}
|
||||
|
||||
public function shortcode(string $value) : string
|
||||
{
|
||||
return $this->flextype->shortcodes->process($value);
|
||||
}
|
||||
}
|
46
flextype/twig/SnippetsTwigExtension.php
Normal file
46
flextype/twig/SnippetsTwigExtension.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Flextype
|
||||
*
|
||||
* @author Sergey Romanenko <hello@romanenko.digital>
|
||||
* @link http://romanenko.digital
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
class SnippetsTwigExtension extends \Twig_Extension
|
||||
{
|
||||
/**
|
||||
* Flextype Dependency Container
|
||||
*/
|
||||
private $flextype;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct($flextype)
|
||||
{
|
||||
$this->flextype = $flextype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for twig.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFunctions()
|
||||
{
|
||||
return [
|
||||
new \Twig_SimpleFunction('snippet', [$this, 'snippet'])
|
||||
];
|
||||
}
|
||||
|
||||
public function snippet(string $id)
|
||||
{
|
||||
return $this->flextype['snippets']->display($id);
|
||||
}
|
||||
}
|
65
index.php
65
index.php
@@ -3,8 +3,8 @@
|
||||
/**
|
||||
* @package Flextype
|
||||
*
|
||||
* @author Sergey Romanenko <awilum@yandex.ru>
|
||||
* @link http://flextype.org
|
||||
* @author Sergey Romanenko <hello@romanenko.digital>
|
||||
* @link http://romanenko.digital
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
@@ -12,36 +12,57 @@
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
// Define the application minimum supported PHP version.
|
||||
/**
|
||||
* Define the application minimum supported PHP version.
|
||||
*/
|
||||
define('FLEXTYPE_MINIMUM_PHP', '7.1.3');
|
||||
|
||||
// Define the path to the root directory (without trailing slash).
|
||||
/**
|
||||
* Define the PATH to the root directory (without trailing slash).
|
||||
*/
|
||||
define('ROOT_DIR', str_replace(DIRECTORY_SEPARATOR, '/', getcwd()));
|
||||
|
||||
// Define the PATH (without trailing slash).
|
||||
define('PATH', ['site' => ROOT_DIR . '/site',
|
||||
'plugins' => ROOT_DIR . '/site/plugins',
|
||||
'themes' => ROOT_DIR . '/site/themes',
|
||||
'entries' => ROOT_DIR . '/site/entries',
|
||||
'snippets' => ROOT_DIR . '/site/snippets',
|
||||
'menus' => ROOT_DIR . '/site/menus',
|
||||
'config' => [
|
||||
/**
|
||||
* Define the PATH (without trailing slash).
|
||||
*/
|
||||
define('PATH', ['site' => ROOT_DIR . '/site',
|
||||
'plugins' => ROOT_DIR . '/site/plugins',
|
||||
'themes' => ROOT_DIR . '/site/themes',
|
||||
'entries' => ROOT_DIR . '/site/entries',
|
||||
'snippets' => ROOT_DIR . '/site/snippets',
|
||||
'fieldsets' => ROOT_DIR . '/site/fieldsets',
|
||||
'config' => [
|
||||
'default' => ROOT_DIR . '/flextype/config',
|
||||
'site' => ROOT_DIR . '/site/config'
|
||||
],
|
||||
'cache' => ROOT_DIR . '/site/cache']);
|
||||
],
|
||||
'cache' => ROOT_DIR . '/site/cache']);
|
||||
|
||||
// Define the path to the logs directory (without trailing slash).
|
||||
define('LOGS_PATH', PATH['site'] . '/logs');
|
||||
|
||||
// Check PHP Version
|
||||
/**
|
||||
* Check PHP Version
|
||||
*/
|
||||
version_compare($ver = PHP_VERSION, $req = FLEXTYPE_MINIMUM_PHP, '<') and exit(sprintf('You are running PHP %s, but Flextype needs at least <strong>PHP %s</strong> to run.', $ver, $req));
|
||||
|
||||
// Ensure vendor libraries exist
|
||||
/**
|
||||
* Ensure vendor libraries exist
|
||||
*/
|
||||
!is_file($autoload = __DIR__ . '/vendor/autoload.php') and exit("Please run: <i>composer install</i>");
|
||||
|
||||
// Register The Auto Loader
|
||||
/**
|
||||
* Register The Auto Loader
|
||||
*
|
||||
* Composer provides a convenient, automatically generated class loader for
|
||||
* our application. We just need to utilize it! We'll simply require it
|
||||
* into the script here so that we don't have to worry about manual
|
||||
* loading any of our classes later on. It feels nice to relax.
|
||||
* Register The Auto Loader
|
||||
*/
|
||||
$loader = require_once $autoload;
|
||||
|
||||
// Get Flextype Instance
|
||||
$flextype = Flextype::getInstance();
|
||||
/**
|
||||
* Bootstraps the Flextype
|
||||
*
|
||||
* This bootstraps the Flextype and gets it ready for use, then it
|
||||
* will load up this application so that we can run it and send
|
||||
* the responses back to the browser and delight our users.
|
||||
*/
|
||||
include 'flextype/bootstrap.php';
|
||||
|
0
site/cache/.gitkeep
vendored
0
site/cache/.gitkeep
vendored
1
site/config/settings.json
Normal file
1
site/config/settings.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
@@ -1,10 +0,0 @@
|
||||
---
|
||||
title: About
|
||||
image: lilia.jpg
|
||||
template: about
|
||||
fieldset: about
|
||||
date: 'December 26 2018 10:26:04'
|
||||
|
||||
---
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
|
13
site/entries/about/entry.json
Normal file
13
site/entries/about/entry.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"title": "About",
|
||||
"image": "lilia.jpg",
|
||||
"template": "about",
|
||||
"fieldset": "about",
|
||||
"content": "<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>\r\n<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>\r\n",
|
||||
"date": "June 07 2019 10:08:11",
|
||||
"description": "",
|
||||
"menu_item_title": "About",
|
||||
"menu_item_url": "about",
|
||||
"menu_item_target": "self",
|
||||
"menu_item_order": "3"
|
||||
}
|
@@ -1,24 +0,0 @@
|
||||
---
|
||||
title: 'Allamco laboris nisi ut aliquip nisi ut aliquip'
|
||||
summary: '<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>'
|
||||
template: blog-post
|
||||
fieldset: blog-post
|
||||
date: 'December 25 2018 23:16:47'
|
||||
|
||||
---
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
|
||||
<br>
|
||||
<p>
|
||||
<img src="https://pp.userapi.com/c846416/v846416486/1188f2/Ob4Xk_yQclo.jpg" alt="">
|
||||
<br>
|
||||
</p>
|
||||
<br>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
|
||||
<br>
|
||||
<p>
|
||||
<img src="https://pp.userapi.com/c852232/v852232861/2d7e5/qD2cprowsVg.jpg" alt="">
|
||||
<br>
|
||||
</p>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
|
||||
<br>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
|
File diff suppressed because one or more lines are too long
@@ -1,9 +0,0 @@
|
||||
---
|
||||
title: 'Cillum dolore eu fugiat nulla pariatur'
|
||||
summary: '<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>'
|
||||
template: blog-post
|
||||
fieldset: blog-post
|
||||
date: 'December 25 2018 23:13:53'
|
||||
|
||||
---
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
|
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Cillum dolore eu fugiat nulla pariatur",
|
||||
"summary": "<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>",
|
||||
"template": "blog-post",
|
||||
"fieldset": "blog-post",
|
||||
"content": "<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>\n",
|
||||
"date": "June 06 2019 22:08:11"
|
||||
}
|
@@ -1,6 +0,0 @@
|
||||
---
|
||||
title: Blog
|
||||
template: blog
|
||||
fieldset: blog
|
||||
date: 'December 25 2018 22:27:15'
|
||||
---
|
11
site/entries/blog/entry.json
Normal file
11
site/entries/blog/entry.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"title": "Blog",
|
||||
"template": "blog",
|
||||
"fieldset": "blog",
|
||||
"date": "June 07 2019 10:08:11",
|
||||
"description": "",
|
||||
"menu_item_title": "Blog",
|
||||
"menu_item_url": "blog",
|
||||
"menu_item_target": "self",
|
||||
"menu_item_order": "2"
|
||||
}
|
@@ -1,9 +0,0 @@
|
||||
---
|
||||
title: 'Excepteur sint occaecat cupidatat non proident'
|
||||
summary: '<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>'
|
||||
template: blog-post
|
||||
fieldset: blog-post
|
||||
date: 'December 25 2018 22:57:55'
|
||||
|
||||
---
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
|
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Excepteur sint occaecat cupidatat non proident",
|
||||
"summary": "<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>",
|
||||
"template": "blog-post",
|
||||
"fieldset": "blog-post",
|
||||
"content": "<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>\n",
|
||||
"date": "June 06 2019 22:08:11"
|
||||
}
|
@@ -1,9 +0,0 @@
|
||||
---
|
||||
title: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit'
|
||||
summary: '<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>'
|
||||
template: blog-post
|
||||
fieldset: blog-post
|
||||
date: 'December 25 2018 22:50:01'
|
||||
|
||||
---
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
|
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Lorem ipsum dolor sit amet, consectetur adipisicing elit",
|
||||
"summary": "<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>",
|
||||
"template": "blog-post",
|
||||
"fieldset": "blog-post",
|
||||
"content": "<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>\n",
|
||||
"date": "June 06 2019 22:08:11"
|
||||
}
|
@@ -1,9 +0,0 @@
|
||||
---
|
||||
title: 'Ullamco laboris nisi ut aliquip'
|
||||
summary: '<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>'
|
||||
template: blog-post
|
||||
fieldset: blog-post
|
||||
date: 'December 25 2018 23:14:49'
|
||||
|
||||
---
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
|
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"title": "Ullamco laboris nisi ut aliquip",
|
||||
"summary": "<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>",
|
||||
"template": "blog-post",
|
||||
"fieldset": "blog-post",
|
||||
"content": "<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>\n",
|
||||
"date": "June 06 2019 22:08:11"
|
||||
}
|
@@ -1,17 +0,0 @@
|
||||
---
|
||||
title: Home
|
||||
template: home
|
||||
visibility: visible
|
||||
date: 'December 25 2018 23:46:58'
|
||||
fieldset: default
|
||||
---
|
||||
<h1 style="text-align: center;">
|
||||
Welcome!
|
||||
</h1>
|
||||
<p style="text-align: center;" class="lead">
|
||||
Welcome to your new Flextype powered website.
|
||||
<br>
|
||||
Flextype is succesfully installed, you can start editing the content and customising your site in <a href="./admin">Admin panel</a>.
|
||||
</p>
|
||||
<br>
|
||||
<p style="text-align: center;">Latest blog posts:</p>
|
13
site/entries/home/entry.json
Normal file
13
site/entries/home/entry.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"title": "Home",
|
||||
"content": "<h1 style=\"text-align: center;\">\r\n Welcome!\r\n</h1>\r\n<p style=\"text-align: center;\" class=\"lead\">\r\n Welcome to your new Flextype powered website.\r\n <br>\r\n Flextype is succesfully installed, you can start editing the content and customising your site in <a href=\"./admin\">Admin panel</a>.\r\n</p>\r\n<br>\r\n<p style=\"text-align: center;\">Latest blog posts:</p>\r\n",
|
||||
"template": "home",
|
||||
"fieldset": "default",
|
||||
"visibility": "visible",
|
||||
"date": "February 20 2019 11:06:46",
|
||||
"description": "",
|
||||
"menu_item_title": "Home",
|
||||
"menu_item_url": "home",
|
||||
"menu_item_target": "self",
|
||||
"menu_item_order": "1"
|
||||
}
|
67
site/fieldsets/about.json
Normal file
67
site/fieldsets/about.json
Normal file
@@ -0,0 +1,67 @@
|
||||
{
|
||||
"title": "About",
|
||||
"default_field": "title",
|
||||
"sections": {
|
||||
"main": {
|
||||
"title": "Main",
|
||||
"fields": {
|
||||
"title": {
|
||||
"title": "admin_title",
|
||||
"type": "text",
|
||||
"size": "col-12"
|
||||
},
|
||||
"content": {
|
||||
"title": "admin_content",
|
||||
"type": "editor",
|
||||
"size": "col-12"
|
||||
},
|
||||
"image": {
|
||||
"title": "admin_media",
|
||||
"type": "media_select",
|
||||
"size": "col-3"
|
||||
}
|
||||
}
|
||||
},
|
||||
"seo": {
|
||||
"title": "Seo",
|
||||
"fields": {
|
||||
"description": {
|
||||
"title": "admin_description",
|
||||
"type": "textarea",
|
||||
"size": "col-12"
|
||||
}
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"title": "Menu",
|
||||
"fields": {
|
||||
"menu_item_title": {
|
||||
"title": "admin_menu_item_title",
|
||||
"type": "text",
|
||||
"size": "col-4"
|
||||
},
|
||||
"menu_item_url": {
|
||||
"title": "admin_menu_item_url",
|
||||
"type": "text",
|
||||
"size": "col-4"
|
||||
},
|
||||
"menu_item_target": {
|
||||
"title": "admin_menu_item_target",
|
||||
"type": "select",
|
||||
"options": {
|
||||
"self": "_self",
|
||||
"blank": "_blank",
|
||||
"parent": "_parent",
|
||||
"top": "_top"
|
||||
},
|
||||
"size": "col-4"
|
||||
},
|
||||
"menu_item_order": {
|
||||
"title": "admin_menu_item_order",
|
||||
"type": "text",
|
||||
"size": "col-4"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
36
site/fieldsets/blog-post.json
Normal file
36
site/fieldsets/blog-post.json
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"title": "Blog Post",
|
||||
"default_field": "title",
|
||||
"sections": {
|
||||
"main": {
|
||||
"title": "Main",
|
||||
"fields": {
|
||||
"title": {
|
||||
"title": "admin_title",
|
||||
"type": "text",
|
||||
"size": "col-12"
|
||||
},
|
||||
"summary": {
|
||||
"title": "admin_summary",
|
||||
"type": "editor",
|
||||
"size": "col-12"
|
||||
},
|
||||
"content": {
|
||||
"title": "admin_content",
|
||||
"type": "editor",
|
||||
"size": "col-12"
|
||||
}
|
||||
}
|
||||
},
|
||||
"seo": {
|
||||
"title": "Seo",
|
||||
"fields": {
|
||||
"description": {
|
||||
"title": "admin_description",
|
||||
"type": "textarea",
|
||||
"size": "col-12"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
57
site/fieldsets/blog.json
Normal file
57
site/fieldsets/blog.json
Normal file
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"title": "Blog",
|
||||
"default_field": "title",
|
||||
"sections": {
|
||||
"main": {
|
||||
"title": "Main",
|
||||
"fields": {
|
||||
"title": {
|
||||
"title": "admin_title",
|
||||
"type": "text",
|
||||
"size": "col-12"
|
||||
}
|
||||
}
|
||||
},
|
||||
"seo": {
|
||||
"title": "Seo",
|
||||
"fields": {
|
||||
"description": {
|
||||
"title": "admin_description",
|
||||
"type": "textarea",
|
||||
"size": "col-12"
|
||||
}
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"title": "Menu",
|
||||
"fields": {
|
||||
"menu_item_title": {
|
||||
"title": "admin_menu_item_title",
|
||||
"type": "text",
|
||||
"size": "col-4"
|
||||
},
|
||||
"menu_item_url": {
|
||||
"title": "admin_menu_item_url",
|
||||
"type": "text",
|
||||
"size": "col-4"
|
||||
},
|
||||
"menu_item_target": {
|
||||
"title": "admin_menu_item_target",
|
||||
"type": "select",
|
||||
"options": {
|
||||
"self": "_self",
|
||||
"blank": "_blank",
|
||||
"parent": "_parent",
|
||||
"top": "_top"
|
||||
},
|
||||
"size": "col-4"
|
||||
},
|
||||
"menu_item_order": {
|
||||
"title": "admin_menu_item_order",
|
||||
"type": "text",
|
||||
"size": "col-4"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
77
site/fieldsets/default.json
Normal file
77
site/fieldsets/default.json
Normal file
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"title": "Default",
|
||||
"default_field": "title",
|
||||
"sections": {
|
||||
"main": {
|
||||
"title": "Main",
|
||||
"fields": {
|
||||
"title": {
|
||||
"title": "admin_title",
|
||||
"type": "text",
|
||||
"size": "col-12"
|
||||
},
|
||||
"content": {
|
||||
"title": "admin_content",
|
||||
"type": "editor",
|
||||
"size": "col-12"
|
||||
},
|
||||
"template": {
|
||||
"title": "admin_template",
|
||||
"type": "template_select",
|
||||
"size": "col-4"
|
||||
},
|
||||
"visibility": {
|
||||
"title": "admin_visibility",
|
||||
"type": "visibility_select",
|
||||
"size": "col-4"
|
||||
},
|
||||
"date": {
|
||||
"title": "admin_date",
|
||||
"type": "text",
|
||||
"size": "col-4"
|
||||
}
|
||||
}
|
||||
},
|
||||
"seo": {
|
||||
"title": "Seo",
|
||||
"fields": {
|
||||
"description": {
|
||||
"title": "admin_description",
|
||||
"type": "textarea",
|
||||
"size": "col-12"
|
||||
}
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"title": "Menu",
|
||||
"fields": {
|
||||
"menu_item_title": {
|
||||
"title": "admin_menu_item_title",
|
||||
"type": "text",
|
||||
"size": "col-4"
|
||||
},
|
||||
"menu_item_url": {
|
||||
"title": "admin_menu_item_url",
|
||||
"type": "text",
|
||||
"size": "col-4"
|
||||
},
|
||||
"menu_item_target": {
|
||||
"title": "admin_menu_item_target",
|
||||
"type": "select",
|
||||
"options": {
|
||||
"self": "_self",
|
||||
"blank": "_blank",
|
||||
"parent": "_parent",
|
||||
"top": "_top"
|
||||
},
|
||||
"size": "col-4"
|
||||
},
|
||||
"menu_item_order": {
|
||||
"title": "admin_menu_item_order",
|
||||
"type": "text",
|
||||
"size": "col-4"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,14 +0,0 @@
|
||||
title: Default
|
||||
items:
|
||||
home:
|
||||
title: 'Home'
|
||||
url: 'home'
|
||||
order: 1
|
||||
blog:
|
||||
title: 'Blog'
|
||||
url: 'blog'
|
||||
order: 2
|
||||
about:
|
||||
title: 'About'
|
||||
url: 'about'
|
||||
order: 3
|
@@ -1,188 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
/**
|
||||
*
|
||||
* Flextype Admin Plugin
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
|
||||
use Flextype\Component\Arr\Arr;
|
||||
use Flextype\Component\Number\Number;
|
||||
use Flextype\Component\I18n\I18n;
|
||||
use Flextype\Component\Http\Http;
|
||||
use Flextype\Component\Event\Event;
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
use Flextype\Component\Session\Session;
|
||||
use Flextype\Component\Registry\Registry;
|
||||
use Flextype\Component\Token\Token;
|
||||
use Flextype\Component\Text\Text;
|
||||
use Flextype\Component\Notification\Notification;
|
||||
use Flextype\Component\Form\Form;
|
||||
use function Flextype\Component\I18n\__;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
use Gajus\Dindent\Indenter;
|
||||
|
||||
//
|
||||
// If isAdminArea
|
||||
//
|
||||
if (Admin::isAdminArea()) {
|
||||
|
||||
// Ensure vendor libraries exist
|
||||
!is_file($autoload = __DIR__ . '/vendor/autoload.php') and exit("Please run: <i>composer install</i>");
|
||||
|
||||
// Register The Auto Loader
|
||||
$loader = require_once $autoload;
|
||||
|
||||
//
|
||||
// Add listner for onCurrentPageBeforeLoaded event
|
||||
//
|
||||
Event::addListener('onCurrentEntryBeforeLoaded', function () {
|
||||
|
||||
// Add navigation links
|
||||
NavigationManager::addItem('content', 'entries', '<i class="far fa-newspaper"></i>' . __('admin_menu_content_entries', Registry::get('settings.locale')), Http::getBaseUrl() . '/admin/entries', ['class' => 'nav-link']);
|
||||
NavigationManager::addItem('extends', 'menus', '<i class="fab fa-elementor"></i>' . __('admin_menu_content_menus', Registry::get('settings.locale')), Http::getBaseUrl() . '/admin/menus', ['class' => 'nav-link']);
|
||||
NavigationManager::addItem('extends', 'fieldsets', '<i class="fas fa-list"></i>' . __('admin_menu_extends_fieldsets', Registry::get('settings.locale')), Http::getBaseUrl() . '/admin/fieldsets', ['class' => 'nav-link']);
|
||||
NavigationManager::addItem('extends', 'templates', '<i class="fas fa-layer-group"></i>' . __('admin_menu_extends_templates', Registry::get('settings.locale')), Http::getBaseUrl() . '/admin/templates', ['class' => 'nav-link']);
|
||||
NavigationManager::addItem('extends', 'snippets', '<i class="far fa-file-code"></i>' . __('admin_menu_extends_snippets', Registry::get('settings.locale')), Http::getBaseUrl() . '/admin/snippets', ['class' => 'nav-link']);
|
||||
NavigationManager::addItem('extends', 'plugins', '<i class="fas fa-plug"></i>' . __('admin_menu_extends_plugins', Registry::get('settings.locale')), Http::getBaseUrl() . '/admin/plugins', ['class' => 'nav-link']);
|
||||
NavigationManager::addItem('settings', 'settings', '<i class="fas fa-cog"></i>' . __('admin_menu_system_settings', Registry::get('settings.locale')), Http::getBaseUrl() . '/admin/settings', ['class' => 'nav-link']);
|
||||
NavigationManager::addItem('settings', 'infomation', '<i class="fas fa-info"></i>' . __('admin_menu_system_information', Registry::get('settings.locale')), Http::getBaseUrl() . '/admin/information', ['class' => 'nav-link']);
|
||||
|
||||
if (Registry::get('settings.locale') == 'ru') {
|
||||
NavigationManager::addItem('help', 'documentation', '<i class="far fa-question-circle"></i>' . __('admin_menu_help_documentation', Registry::get('settings.locale')), 'http://flextype.ru/documentation/basics/getting-help', ['class' => 'nav-link', 'target' => '_blank']);
|
||||
} else {
|
||||
NavigationManager::addItem('help', 'documentation', '<i class="far fa-question-circle"></i>' . __('admin_menu_help_documentation', Registry::get('settings.locale')), 'http://flextype.org/documentation/basics/getting-help', ['class' => 'nav-link', 'target' => '_blank']);
|
||||
}
|
||||
|
||||
// Initializes the Notification service.
|
||||
Notification::init();
|
||||
|
||||
// Get Admin Instance
|
||||
Admin::getInstance();
|
||||
});
|
||||
}
|
||||
|
||||
class Admin
|
||||
{
|
||||
/**
|
||||
* An instance of the Admin class
|
||||
*
|
||||
* @var object
|
||||
* @access private
|
||||
*/
|
||||
private static $instance = null;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
protected function __construct()
|
||||
{
|
||||
Admin::init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Init Flextype Admin
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private static function init() : void
|
||||
{
|
||||
// Set Default Admin locale
|
||||
I18n::$locale = Registry::get('settings.locale');
|
||||
|
||||
if (UsersManager::isLoggedIn()) {
|
||||
Admin::getAdminArea();
|
||||
} else {
|
||||
if (UsersManager::isUsersExists()) {
|
||||
UsersManager::getAuthPage();
|
||||
} else {
|
||||
UsersManager::getRegistrationPage();
|
||||
}
|
||||
}
|
||||
|
||||
// Event: onBeforeRequestShutdown
|
||||
Event::dispatch('onBeforeRequestShutdown');
|
||||
|
||||
// Shutdown request
|
||||
Http::requestShutdown();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Flextype Admin Area
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private static function getAdminArea() : void
|
||||
{
|
||||
|
||||
// Event: onAdminArea
|
||||
Event::dispatch('onAdminArea');
|
||||
|
||||
// Route the Uri
|
||||
Http::getUriSegment(1) == '' and DashboardManager::getDashboardManager();
|
||||
Http::getUriSegment(1) == 'entries' and EntriesManager::getEntriesManager();
|
||||
Http::getUriSegment(1) == 'menus' and MenusManager::getMenusManager();
|
||||
Http::getUriSegment(1) == 'fieldsets' and FieldsetsManager::getFieldsetsManager();
|
||||
Http::getUriSegment(1) == 'templates' and TemplatesManager::getTemplatesManager();
|
||||
Http::getUriSegment(1) == 'snippets' and SnippetsManager::getSnippetsManager();
|
||||
Http::getUriSegment(1) == 'plugins' and PluginsManager::getPluginsManager();
|
||||
Http::getUriSegment(1) == 'information' and InformationManager::getInformationManager();
|
||||
Http::getUriSegment(1) == 'settings' and SettingsManager::getSettingsManager();
|
||||
Http::getUriSegment(1) == 'profile' and UsersManager::getProfileManager();
|
||||
Http::getUriSegment(1) == 'logout' and UsersManager::logout();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check is Admin Area
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public static function isAdminArea()
|
||||
{
|
||||
return (Http::getUriSegment(0) == 'admin') ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Admin instance.
|
||||
*
|
||||
* @access public
|
||||
* @return object
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
if (is_null(Admin::$instance)) {
|
||||
Admin::$instance = new self;
|
||||
}
|
||||
|
||||
return Admin::$instance;
|
||||
}
|
||||
}
|
@@ -1,10 +0,0 @@
|
||||
name: Admin
|
||||
version: 0.0.0
|
||||
description: "Admin plugin for Flextype"
|
||||
author:
|
||||
name: Sergey Romanenko
|
||||
email: awilum@yandex.ru
|
||||
url: http://flextype.org
|
||||
homepage: https://github.com/flextype-plugins/admin
|
||||
bugs: https://github.com/flextype-plugins/admin/issues
|
||||
license: MIT
|
25
site/plugins/admin/app/Controllers/DashboardController.php
Normal file
25
site/plugins/admin/app/Controllers/DashboardController.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
/**
|
||||
* @property Router $router
|
||||
*/
|
||||
class DashboardController extends Controller
|
||||
{
|
||||
/**
|
||||
* Index page
|
||||
*
|
||||
* @param Request $request PSR7 request
|
||||
* @param Response $response PSR7 response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function index(/** @scrutinizer ignore-unused */ Request $request, Response $response) : Response
|
||||
{
|
||||
return $response->withRedirect($this->router->pathFor('admin.entries.index'));
|
||||
}
|
||||
}
|
1088
site/plugins/admin/app/Controllers/EntriesController.php
Normal file
1088
site/plugins/admin/app/Controllers/EntriesController.php
Normal file
File diff suppressed because it is too large
Load Diff
192
site/plugins/admin/app/Controllers/FieldsetsController.php
Normal file
192
site/plugins/admin/app/Controllers/FieldsetsController.php
Normal file
@@ -0,0 +1,192 @@
|
||||
<?php
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Arr\Arr;
|
||||
use Flextype\Component\Text\Text;
|
||||
use function Flextype\Component\I18n\__;
|
||||
use Respect\Validation\Validator as v;
|
||||
|
||||
/**
|
||||
* @property View $view
|
||||
* @property Fieldsets $fieldsets
|
||||
* @property Router $router
|
||||
* @property Slugify $slugify
|
||||
*/
|
||||
class FieldsetsController extends Controller
|
||||
{
|
||||
public function index($request, $response)
|
||||
{
|
||||
return $this->view->render(
|
||||
$response,
|
||||
'plugins/admin/views/templates/extends/fieldsets/index.html',
|
||||
[
|
||||
'menu_item' => 'fieldsets',
|
||||
'fieldsets_list' => $this->fieldsets->fetchAll(),
|
||||
'links' => [
|
||||
'fieldsets' => [
|
||||
'link' => $this->router->pathFor('admin.fieldsets.index'),
|
||||
'title' => __('admin_fieldsets'),
|
||||
'attributes' => ['class' => 'navbar-item active']
|
||||
],
|
||||
],
|
||||
'buttons' => [
|
||||
'fieldsets_add' => [
|
||||
'link' => $this->router->pathFor('admin.fieldsets.add'),
|
||||
'title' => __('admin_create_new_fieldset'),
|
||||
'attributes' => ['class' => 'float-right btn']
|
||||
]
|
||||
]
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function add($request, $response)
|
||||
{
|
||||
return $this->view->render(
|
||||
$response,
|
||||
'plugins/admin/views/templates/extends/fieldsets/add.html',
|
||||
[
|
||||
'menu_item' => 'fieldsets',
|
||||
'fieldsets_list' => $this->fieldsets->fetchAll(),
|
||||
'links' => [
|
||||
'fieldsets' => [
|
||||
'link' => $this->router->pathFor('admin.fieldsets.index'),
|
||||
'title' => __('admin_fieldsets'),
|
||||
'attributes' => ['class' => 'navbar-item active']
|
||||
],
|
||||
],
|
||||
'buttons' => [
|
||||
'fieldsets_add' => [
|
||||
'link' => $this->router->pathFor('admin.fieldsets.add'),
|
||||
'title' => __('admin_create_new_fieldset'),
|
||||
'attributes' => ['class' => 'float-right btn']
|
||||
]
|
||||
]
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function addProcess($request, $response)
|
||||
{
|
||||
$data = $request->getParsedBody();
|
||||
|
||||
Arr::delete($data, 'csrf_name');
|
||||
Arr::delete($data, 'csrf_value');
|
||||
|
||||
$id = $this->slugify->slugify($data['id']);
|
||||
$data = ['title' => $data['title']];
|
||||
|
||||
if ($this->fieldsets->create($id, $data)) {
|
||||
$this->flash->addMessage('success', __('admin_message_fieldset_created'));
|
||||
} else {
|
||||
$this->flash->addMessage('error', __('admin_message_fieldset_was_not_created'));
|
||||
}
|
||||
|
||||
return $response->withRedirect($this->router->pathFor('admin.fieldsets.index'));
|
||||
}
|
||||
|
||||
public function edit($request, $response)
|
||||
{
|
||||
return $this->view->render(
|
||||
$response,
|
||||
'plugins/admin/views/templates/extends/fieldsets/edit.html',
|
||||
[
|
||||
'menu_item' => 'fieldsets',
|
||||
'id' => $request->getQueryParams()['id'],
|
||||
'data' => JsonParser::encode($this->fieldsets->fetch($request->getQueryParams()['id'])),
|
||||
'links' => [
|
||||
'fieldsets' => [
|
||||
'link' => $this->router->pathFor('admin.fieldsets.edit') . '?id=' . $request->getQueryParams()['id'],
|
||||
'title' => __('admin_fieldsets'),
|
||||
'attributes' => ['class' => 'navbar-item active']
|
||||
],
|
||||
],
|
||||
'buttons' => [
|
||||
'save_entry' => [
|
||||
'link' => 'javascript:;',
|
||||
'title' => __('admin_save'),
|
||||
'attributes' => ['class' => 'js-save-form-submit float-right btn']
|
||||
],
|
||||
]
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function editProcess($request, $response)
|
||||
{
|
||||
$data = $request->getParsedBody()['data'];
|
||||
|
||||
if (v::json()->validate($data)) {
|
||||
|
||||
if ($this->fieldsets->update($request->getParsedBody()['id'], JsonParser::decode($data))) {
|
||||
$this->flash->addMessage('success', __('admin_message_fieldset_saved'));
|
||||
} else {
|
||||
$this->flash->addMessage('error', __('admin_message_fieldset_was_not_saved'));
|
||||
}
|
||||
|
||||
return $response->withRedirect($this->router->pathFor('admin.fieldsets.index'));
|
||||
|
||||
} else {
|
||||
$this->flash->addMessage('error', __('admin_message_json_invalid'));
|
||||
return $response->withRedirect($this->router->pathFor('admin.fieldsets.index'));
|
||||
}
|
||||
}
|
||||
|
||||
public function rename($request, $response)
|
||||
{
|
||||
return $this->view->render(
|
||||
$response,
|
||||
'plugins/admin/views/templates/extends/fieldsets/rename.html',
|
||||
[
|
||||
'menu_item' => 'fieldsets',
|
||||
'id' => $request->getQueryParams()['id'],
|
||||
'links' => [
|
||||
'fieldsets' => [
|
||||
'link' => $this->router->pathFor('admin.fieldsets.index'),
|
||||
'title' => __('admin_fieldsets'),
|
||||
'attributes' => ['class' => 'navbar-item active']
|
||||
],
|
||||
'fieldsets_rename' => [
|
||||
'link' => $this->router->pathFor('admin.fieldsets.rename') . '?id=' . $request->getQueryParams()['id'],
|
||||
'title' => __('admin_rename'),
|
||||
'attributes' => ['class' => 'navbar-item active']
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function renameProcess($request, $response)
|
||||
{
|
||||
if ($this->fieldsets->rename($request->getParsedBody()['fieldset-id-current'], $request->getParsedBody()['id'])) {
|
||||
$this->flash->addMessage('success', __('admin_message_fieldset_renamed'));
|
||||
} else {
|
||||
$this->flash->addMessage('error', __('admin_message_fieldset_was_not_renamed'));
|
||||
}
|
||||
|
||||
return $response->withRedirect($this->router->pathFor('admin.fieldsets.index'));
|
||||
}
|
||||
|
||||
public function deleteProcess($request, $response)
|
||||
{
|
||||
if ($this->fieldsets->delete($request->getParsedBody()['fieldset-id'])) {
|
||||
$this->flash->addMessage('success', __('admin_message_fieldset_deleted'));
|
||||
} else {
|
||||
$this->flash->addMessage('error', __('admin_message_fieldset_was_not_deleted'));
|
||||
}
|
||||
|
||||
return $response->withRedirect($this->router->pathFor('admin.fieldsets.index'));
|
||||
}
|
||||
|
||||
public function duplicateProcess($request, $response)
|
||||
{
|
||||
if ($this->fieldsets->copy($request->getParsedBody()['fieldset-id'], $request->getParsedBody()['fieldset-id'] . '-duplicate-' . date("Ymd_His"))) {
|
||||
$this->flash->addMessage('success', __('admin_message_fieldset_duplicated'));
|
||||
} else {
|
||||
$this->flash->addMessage('error', __('admin_message_fieldset_was_not_duplicated'));
|
||||
}
|
||||
|
||||
return $response->withRedirect($this->router->pathFor('admin.fieldsets.index'));
|
||||
}
|
||||
}
|
54
site/plugins/admin/app/Controllers/InformationController.php
Normal file
54
site/plugins/admin/app/Controllers/InformationController.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use function Flextype\Component\I18n\__;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
/**
|
||||
* @property View $view
|
||||
* @property Router $router
|
||||
*/
|
||||
class InformationController extends Controller
|
||||
{
|
||||
/**
|
||||
* Index page
|
||||
*
|
||||
* @param Request $request PSR7 request
|
||||
* @param Response $response PSR7 response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function index(/** @scrutinizer ignore-unused */ Request $request, Response $response) : Response
|
||||
{
|
||||
if (function_exists('apache_get_modules')) {
|
||||
if (!in_array('mod_rewrite', apache_get_modules())) {
|
||||
$apache_mod_rewrite_installed = false;
|
||||
} else {
|
||||
$apache_mod_rewrite_installed = true;
|
||||
}
|
||||
} else {
|
||||
$apache_mod_rewrite_installed = true;
|
||||
}
|
||||
|
||||
return $this->view->render(
|
||||
$response,
|
||||
'plugins/admin/views/templates/system/information/index.html',
|
||||
[
|
||||
'menu_item' => 'infomation',
|
||||
'php_uname' => php_uname(),
|
||||
'webserver' => isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : @getenv('SERVER_SOFTWARE'),
|
||||
'php_sapi_name' => php_sapi_name(),
|
||||
'apache_mod_rewrite_installed' => $apache_mod_rewrite_installed,
|
||||
'links' => [
|
||||
'information' => [
|
||||
'link' => $this->router->pathFor('admin.information.index'),
|
||||
'title' => __('admin_information'),
|
||||
'attributes' => ['class' => 'navbar-item active']
|
||||
],
|
||||
]
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
73
site/plugins/admin/app/Controllers/PluginsController.php
Normal file
73
site/plugins/admin/app/Controllers/PluginsController.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
use Flextype\Component\Date\Date;
|
||||
use Flextype\Component\Arr\Arr;
|
||||
use function Flextype\Component\I18n\__;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
/**
|
||||
* @property View $view
|
||||
* @property Router $router
|
||||
* @property Cache $cache
|
||||
* @property Registry $registry
|
||||
*/
|
||||
class PluginsController extends Controller
|
||||
{
|
||||
/**
|
||||
* Index page
|
||||
*
|
||||
* @param Request $request PSR7 request
|
||||
* @param Response $response PSR7 response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function index(/** @scrutinizer ignore-unused */ Request $request, Response $response) : Response
|
||||
{
|
||||
return $this->view->render(
|
||||
$response,
|
||||
'plugins/admin/views/templates/extends/plugins/index.html',
|
||||
[
|
||||
'plugins_list' => $this->registry->get('plugins'),
|
||||
'menu_item' => 'plugins',
|
||||
'links' => [
|
||||
'plugins' => [
|
||||
'link' => $this->router->pathFor('admin.plugins.index'),
|
||||
'title' => __('admin_plugins'),
|
||||
'attributes' => ['class' => 'navbar-item active']
|
||||
],
|
||||
],
|
||||
'buttons' => [
|
||||
'plugins_get_more' => [
|
||||
'link' => 'https://github.com/flextype/plugins',
|
||||
'title' => __('admin_get_more_plugins'),
|
||||
'attributes' => ['class' => 'float-right btn', 'target' => '_blank']
|
||||
],
|
||||
]
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Сhange plugin status process
|
||||
*
|
||||
* @param Request $request PSR7 request
|
||||
* @param Response $response PSR7 response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function pluginStatusProcess(Request $request, Response $response) : Response
|
||||
{
|
||||
$data = $request->getParsedBody();
|
||||
|
||||
$plugin_settings = JsonParser::decode(Filesystem::read(PATH['plugins'] . '/' . $data['plugin-key'] . '/' . 'settings.json'));
|
||||
Arr::set($plugin_settings, 'enabled', ($data['plugin-status'] == 'true' ? true : false));
|
||||
Filesystem::write(PATH['plugins'] . '/' . $data['plugin-key'] . '/' . 'settings.json', JsonParser::encode($plugin_settings));
|
||||
$this->cache->clear();
|
||||
|
||||
return $response->withRedirect($this->router->pathFor('admin.plugins.index'));
|
||||
}
|
||||
}
|
144
site/plugins/admin/app/Controllers/SettingsController.php
Normal file
144
site/plugins/admin/app/Controllers/SettingsController.php
Normal file
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
use Flextype\Component\Date\Date;
|
||||
use Flextype\Component\Arr\Arr;
|
||||
use function Flextype\Component\I18n\__;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
/**
|
||||
* @property View $view
|
||||
* @property Router $router
|
||||
* @property Cache $cache
|
||||
*/
|
||||
class SettingsController extends Controller
|
||||
{
|
||||
/**
|
||||
* Index page
|
||||
*
|
||||
* @param Request $request PSR7 request
|
||||
* @param Response $response PSR7 response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function index(/** @scrutinizer ignore-unused */ Request $request, Response $response) : Response
|
||||
{
|
||||
$entries = [];
|
||||
foreach ($this->entries->fetchAll('', 'date', 'DESC') as $entry) {
|
||||
$entries[$entry['slug']] = $entry['title'];
|
||||
}
|
||||
|
||||
$themes = [];
|
||||
foreach (Filesystem::listContents(PATH['themes']) as $theme) {
|
||||
if ($theme['type'] == 'dir' && Filesystem::has($theme['path'] . '/' . 'theme.json')) {
|
||||
$themes[$theme['dirname']] = $theme['dirname'];
|
||||
}
|
||||
}
|
||||
|
||||
$available_locales = Filesystem::listContents(PATH['plugins'] . '/admin/lang/');
|
||||
$system_locales = $this->plugins->getLocales();
|
||||
$locales = [];
|
||||
foreach ($available_locales as $locale) {
|
||||
if ($locale['type'] == 'file' && $locale['extension'] == 'json') {
|
||||
$locales[$locale['basename']] = $system_locales[$locale['basename']]['nativeName'];
|
||||
}
|
||||
}
|
||||
|
||||
$cache_driver = ['auto' => 'Auto Detect',
|
||||
'file' => 'File',
|
||||
'apcu' => 'APCu',
|
||||
'wincache' => 'WinCache',
|
||||
'memcached' => 'Memcached',
|
||||
'redis' => 'Redis',
|
||||
'sqlite3' => 'SQLite3',
|
||||
'zend' => 'Zend',
|
||||
'array' => 'Array'];
|
||||
|
||||
return $this->view->render(
|
||||
$response,
|
||||
'plugins/admin/views/templates/system/settings/index.html',
|
||||
[
|
||||
'timezones' => Date::timezones(),
|
||||
'settings' => $this->registry->get('settings'),
|
||||
'cache_driver' => $cache_driver,
|
||||
'locales' => $locales,
|
||||
'entries' => $entries,
|
||||
'themes' => $themes,
|
||||
'menu_item' => 'settings',
|
||||
'links' => [
|
||||
'settings' => [
|
||||
'link' => $this->router->pathFor('admin.settings.index'),
|
||||
'title' => __('admin_settings'),
|
||||
'attributes' => ['class' => 'navbar-item active']
|
||||
]
|
||||
],
|
||||
'buttons' => [
|
||||
'save' => [
|
||||
'link' => 'javascript:;',
|
||||
'title' => __('admin_save'),
|
||||
'attributes' => ['class' => 'js-save-form-submit float-right btn']
|
||||
],
|
||||
'settings_clear_cache' => [
|
||||
'type' => 'action',
|
||||
'id' => 'clear-cache',
|
||||
'link' => $this->router->pathFor('admin.settings.clear-cache'),
|
||||
'title' => __('admin_clear_cache'),
|
||||
'attributes' => ['class' => 'float-right btn']
|
||||
]
|
||||
]
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update settings process
|
||||
*
|
||||
* @param Request $request PSR7 request
|
||||
* @param Response $response PSR7 response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function updateSettingsProcess(Request $request, Response $response) : Response
|
||||
{
|
||||
$data = $request->getParsedBody();
|
||||
|
||||
Arr::delete($data, 'csrf_name');
|
||||
Arr::delete($data, 'csrf_value');
|
||||
Arr::delete($data, 'action');
|
||||
|
||||
Arr::set($data, 'errors.display', ($data['errors']['display'] == '1' ? true : false));
|
||||
Arr::set($data, 'cache.enabled', ($data['cache']['enabled'] == '1' ? true : false));
|
||||
Arr::set($data, 'cache.lifetime', (int) $data['cache']['lifetime']);
|
||||
Arr::set($data, 'entries.media.upload_images_quality', (int) $data['entries']['media']['upload_images_quality']);
|
||||
Arr::set($data, 'entries.media.upload_images_width', (int) $data['entries']['media']['upload_images_width']);
|
||||
Arr::set($data, 'entries.media.upload_images_height', (int) $data['entries']['media']['upload_images_height']);
|
||||
|
||||
if (Filesystem::write(PATH['config']['site'] . '/settings.json', JsonParser::encode(array_merge($this->registry->get('settings'), $data)))) {
|
||||
$this->flash->addMessage('success', __('admin_message_settings_saved'));
|
||||
} else {
|
||||
$this->flash->addMessage('error', __('admin_message_settings_was_not_saved'));
|
||||
}
|
||||
|
||||
return $response->withRedirect($this->router->pathFor('admin.settings.index'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear cache process
|
||||
*
|
||||
* @param Request $request PSR7 request
|
||||
* @param Response $response PSR7 response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function clearCacheProcess(/** @scrutinizer ignore-unused */ Request $request, Response $response) : Response
|
||||
{
|
||||
$this->cache->clear();
|
||||
Filesystem::has(PATH['cache'] . '/twig') and Filesystem::deleteDir(PATH['cache'] . '/twig');
|
||||
|
||||
$this->flash->addMessage('success', __('admin_message_cache_files_deleted'));
|
||||
return $response->withRedirect($this->router->pathFor('admin.settings.index'));
|
||||
}
|
||||
}
|
254
site/plugins/admin/app/Controllers/SnippetsController.php
Normal file
254
site/plugins/admin/app/Controllers/SnippetsController.php
Normal file
@@ -0,0 +1,254 @@
|
||||
<?php
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
use Flextype\Component\Text\Text;
|
||||
use function Flextype\Component\I18n\__;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
/**
|
||||
* @property View $view
|
||||
* @property Router $router
|
||||
* @property Snippets $snippets
|
||||
* @property Slugify $slugify
|
||||
*/
|
||||
class SnippetsController extends Controller
|
||||
{
|
||||
/**
|
||||
* Index page
|
||||
*
|
||||
* @param Request $request PSR7 request
|
||||
* @param Response $response PSR7 response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function index(/** @scrutinizer ignore-unused */ Request $request, Response $response) : Response
|
||||
{
|
||||
return $this->view->render(
|
||||
$response,
|
||||
'plugins/admin/views/templates/extends/snippets/index.html',
|
||||
[
|
||||
'menu_item' => 'snippets',
|
||||
'snippets_list' => $this->snippets->fetchAll(),
|
||||
'links' => [
|
||||
'snippets' => [
|
||||
'link' => $this->router->pathFor('admin.snippets.index'),
|
||||
'title' => __('admin_snippets'),
|
||||
'attributes' => ['class' => 'navbar-item active']
|
||||
],
|
||||
],
|
||||
'buttons' => [
|
||||
'snippets_create' => [
|
||||
'link' => $this->router->pathFor('admin.snippets.add'),
|
||||
'title' => __('admin_create_new_snippet'),
|
||||
'attributes' => ['class' => 'float-right btn']
|
||||
],
|
||||
]
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add snippet
|
||||
*
|
||||
* @param Request $request PSR7 request
|
||||
* @param Response $response PSR7 response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function add(/** @scrutinizer ignore-unused */ Request $request, Response $response) : Response
|
||||
{
|
||||
return $this->view->render(
|
||||
$response,
|
||||
'plugins/admin/views/templates/extends/snippets/add.html',
|
||||
[
|
||||
'menu_item' => 'snippets',
|
||||
'links' => [
|
||||
'snippets' => [
|
||||
'link' => $this->router->pathFor('admin.snippets.index'),
|
||||
'title' => __('admin_snippets'),
|
||||
'attributes' => ['class' => 'navbar-item active']
|
||||
],
|
||||
]
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add snippet process
|
||||
*
|
||||
* @param Request $request PSR7 request
|
||||
* @param Response $response PSR7 response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function addProcess(Request $request, Response $response) : Response
|
||||
{
|
||||
$id = $this->slugify->slugify($request->getParsedBody()['id']);
|
||||
|
||||
if ($this->snippets->create($id, "")) {
|
||||
$this->flash->addMessage('success', __('admin_message_snippet_created'));
|
||||
} else {
|
||||
$this->flash->addMessage('error', __('admin_message_snippet_was_not_created'));
|
||||
}
|
||||
|
||||
return $response->withRedirect($this->router->pathFor('admin.snippets.index'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit snippet
|
||||
*
|
||||
* @param Request $request PSR7 request
|
||||
* @param Response $response PSR7 response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function edit(Request $request, Response $response) : Response
|
||||
{
|
||||
$id = $request->getQueryParams()['id'];
|
||||
|
||||
return $this->view->render(
|
||||
$response,
|
||||
'plugins/admin/views/templates/extends/snippets/edit.html',
|
||||
[
|
||||
'menu_item' => 'snippets',
|
||||
'id' => $id,
|
||||
'data' => $this->snippets->fetch($id),
|
||||
'links' => [
|
||||
'snippets' => [
|
||||
'link' => $this->router->pathFor('admin.snippets.index'),
|
||||
'title' => __('admin_snippets'),
|
||||
'attributes' => ['class' => 'navbar-item active']
|
||||
],
|
||||
],
|
||||
'buttons' => [
|
||||
'save_snippet' => [
|
||||
'link' => 'javascript:;',
|
||||
'title' => __('admin_save'),
|
||||
'attributes' => ['class' => 'js-save-form-submit float-right btn']
|
||||
]
|
||||
]
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit snippet process
|
||||
*
|
||||
* @param Request $request PSR7 request
|
||||
* @param Response $response PSR7 response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function editProcess(Request $request, Response $response) : Response
|
||||
{
|
||||
$id = $request->getParsedBody()['id'];
|
||||
$data = $request->getParsedBody()['data'];
|
||||
|
||||
if ($this->snippets->update($id, $data)) {
|
||||
$this->flash->addMessage('success', __('admin_message_snippet_saved'));
|
||||
} else {
|
||||
$this->flash->addMessage('error', __('admin_message_snippet_was_not_saved'));
|
||||
}
|
||||
|
||||
return $response->withRedirect($this->router->pathFor('admin.snippets.index'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename snippet
|
||||
*
|
||||
* @param Request $request PSR7 request
|
||||
* @param Response $response PSR7 response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function rename(Request $request, Response $response) : Response
|
||||
{
|
||||
|
||||
return $this->view->render(
|
||||
$response,
|
||||
'plugins/admin/views/templates/extends/snippets/rename.html',
|
||||
[
|
||||
'menu_item' => 'snippets',
|
||||
'id_current' => $request->getQueryParams()['id'],
|
||||
'links' => [
|
||||
'templates' => [
|
||||
'link' => $this->router->pathFor('admin.snippets.index'),
|
||||
'title' => __('admin_templates'),
|
||||
'attributes' => ['class' => 'navbar-item active']
|
||||
],
|
||||
]
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename snippet process
|
||||
*
|
||||
* @param Request $request PSR7 request
|
||||
* @param Response $response PSR7 response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function renameProcess(Request $request, Response $response) : Response
|
||||
{
|
||||
$id = $this->slugify->slugify($request->getParsedBody()['id']);
|
||||
$id_current = $request->getParsedBody()['id_current'];
|
||||
|
||||
if ($this->snippets->rename(
|
||||
$id_current,
|
||||
$id
|
||||
)
|
||||
) {
|
||||
$this->flash->addMessage('success', __('admin_message_snippet_renamed'));
|
||||
} else {
|
||||
$this->flash->addMessage('error', __('admin_message_snippet_was_not_renamed'));
|
||||
}
|
||||
|
||||
return $response->withRedirect($this->router->pathFor('admin.snippets.index'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete snippet process
|
||||
*
|
||||
* @param Request $request PSR7 request
|
||||
* @param Response $response PSR7 response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function deleteProcess(Request $request, Response $response) : Response
|
||||
{
|
||||
$id = $request->getParsedBody()['snippet-id'];
|
||||
|
||||
if ($this->snippets->delete($id)) {
|
||||
$this->flash->addMessage('success', __('admin_message_snippet_deleted'));
|
||||
} else {
|
||||
$this->flash->addMessage('error', __('admin_message_snippet_was_not_deleted'));
|
||||
}
|
||||
|
||||
return $response->withRedirect($this->router->pathFor('admin.snippets.index'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate snippet process
|
||||
*
|
||||
* @param Request $request PSR7 request
|
||||
* @param Response $response PSR7 response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function duplicateProcess(Request $request, Response $response) : Response
|
||||
{
|
||||
$id = $request->getParsedBody()['snippet-id'];
|
||||
|
||||
if ($this->snippets->copy($id, $id . '-duplicate-' . date("Ymd_His"))) {
|
||||
$this->flash->addMessage('success', __('admin_message_snippet_duplicated'));
|
||||
} else {
|
||||
$this->flash->addMessage('error', __('admin_message_snippet_was_not_duplicated'));
|
||||
}
|
||||
|
||||
return $response->withRedirect($this->router->pathFor('admin.snippets.index'));
|
||||
}
|
||||
}
|
287
site/plugins/admin/app/Controllers/TemplatesController.php
Normal file
287
site/plugins/admin/app/Controllers/TemplatesController.php
Normal file
@@ -0,0 +1,287 @@
|
||||
<?php
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
use Flextype\Component\Text\Text;
|
||||
use function Flextype\Component\I18n\__;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
/**
|
||||
* @property View $view
|
||||
* @property Router $router
|
||||
* @property Cache $cache
|
||||
* @property Themes $themes
|
||||
* @property Slugify $slugify
|
||||
*/
|
||||
class TemplatesController extends Controller
|
||||
{
|
||||
/**
|
||||
* Index page
|
||||
*
|
||||
* @param Request $request PSR7 request
|
||||
* @param Response $response PSR7 response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function index(/** @scrutinizer ignore-unused */ Request $request, Response $response) : Response
|
||||
{
|
||||
return $this->view->render(
|
||||
$response,
|
||||
'plugins/admin/views/templates/extends/templates/index.html',
|
||||
[
|
||||
'menu_item' => 'templates',
|
||||
'templates_list' => $this->themes->getTemplates(),
|
||||
'partials_list' => $this->themes->getPartials(),
|
||||
'links' => [
|
||||
'templates' => [
|
||||
'link' => $this->router->pathFor('admin.templates.index'),
|
||||
'title' => __('admin_templates'),
|
||||
'attributes' => ['class' => 'navbar-item active']
|
||||
],
|
||||
],
|
||||
'buttons' => [
|
||||
'templates_create' => [
|
||||
'link' => $this->router->pathFor('admin.templates.add'),
|
||||
'title' => __('admin_create_new_template'),
|
||||
'attributes' => ['class' => 'float-right btn']
|
||||
],
|
||||
]
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add template
|
||||
*
|
||||
* @param Request $request PSR7 request
|
||||
* @param Response $response PSR7 response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function add(/** @scrutinizer ignore-unused */ Request $request, Response $response) : Response
|
||||
{
|
||||
return $this->view->render(
|
||||
$response,
|
||||
'plugins/admin/views/templates/extends/templates/add.html',
|
||||
[
|
||||
'menu_item' => 'templates',
|
||||
'links' => [
|
||||
'templates' => [
|
||||
'link' => $this->router->pathFor('admin.templates.index'),
|
||||
'title' => __('admin_templates'),
|
||||
'attributes' => ['class' => 'navbar-item active']
|
||||
],
|
||||
]
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add template process
|
||||
*
|
||||
* @param Request $request PSR7 request
|
||||
* @param Response $response PSR7 response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function addProcess(Request $request, Response $response) : Response
|
||||
{
|
||||
$type = $request->getParsedBody()['type'];
|
||||
|
||||
$id = $this->slugify->slugify($request->getParsedBody()['id']) . '.html';
|
||||
|
||||
$file = PATH['themes'] . '/' . $this->registry->get('settings.theme') . '/' . $this->_type_location($type) . $id;
|
||||
|
||||
if (!Filesystem::has($file)) {
|
||||
if (Filesystem::write(
|
||||
$file,
|
||||
""
|
||||
)) {
|
||||
$this->flash->addMessage('success', __('admin_message_'.$type.'_created'));
|
||||
} else {
|
||||
$this->flash->addMessage('error', __('admin_message_'.$type.'_was_not_created'));
|
||||
}
|
||||
} else {
|
||||
$this->flash->addMessage('error', __('admin_message_'.$type.'_was_not_created'));
|
||||
}
|
||||
|
||||
return $response->withRedirect($this->router->pathFor('admin.templates.index'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit template
|
||||
*
|
||||
* @param Request $request PSR7 request
|
||||
* @param Response $response PSR7 response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function edit(Request $request, Response $response) : Response
|
||||
{
|
||||
$type = $request->getQueryParams()['type'];
|
||||
|
||||
return $this->view->render(
|
||||
$response,
|
||||
'plugins/admin/views/templates/extends/templates/edit.html',
|
||||
[
|
||||
'menu_item' => 'templates',
|
||||
'id' => $request->getQueryParams()['id'],
|
||||
'data' => Filesystem::read(PATH['themes'] . '/' . $this->registry->get('settings.theme') . '/' . $this->_type_location($type) . $request->getQueryParams()['id'] . '.html'),
|
||||
'type' => (($request->getQueryParams()['type'] && $request->getQueryParams()['type'] == 'partial') ? 'partial' : 'template'),
|
||||
'links' => [
|
||||
'templates' => [
|
||||
'link' => $this->router->pathFor('admin.templates.index'),
|
||||
'title' => __('admin_templates'),
|
||||
'attributes' => ['class' => 'navbar-item active']
|
||||
],
|
||||
],
|
||||
'buttons' => [
|
||||
'save_template' => [
|
||||
'link' => 'javascript:;',
|
||||
'title' => __('admin_save'),
|
||||
'attributes' => ['class' => 'js-save-form-submit float-right btn']
|
||||
]
|
||||
]
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit template process
|
||||
*
|
||||
* @param Request $request PSR7 request
|
||||
* @param Response $response PSR7 response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function editProcess(Request $request, Response $response) : Response
|
||||
{
|
||||
$type = $request->getParsedBody()['type'];
|
||||
|
||||
if (Filesystem::write(PATH['themes'] . '/' . $this->registry->get('settings.theme') . '/' . $this->_type_location($type) . $request->getParsedBody()['id'] . '.html', $request->getParsedBody()['data'])) {
|
||||
$this->flash->addMessage('success', __('admin_message_' . $type . '_saved'));
|
||||
} else {
|
||||
$this->flash->addMessage('error', __('admin_message_' . $type . '_was_not_saved'));
|
||||
}
|
||||
|
||||
return $response->withRedirect($this->router->pathFor('admin.templates.index'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename template
|
||||
*
|
||||
* @param Request $request PSR7 request
|
||||
* @param Response $response PSR7 response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function rename(Request $request, Response $response) : Response
|
||||
{
|
||||
return $this->view->render(
|
||||
$response,
|
||||
'plugins/admin/views/templates/extends/templates/rename.html',
|
||||
[
|
||||
'menu_item' => 'templates',
|
||||
'types' => ['partial' => __('admin_partial'), 'template' => __('admin_template')],
|
||||
'id_current' => $request->getQueryParams()['id'],
|
||||
'type_current' => (($request->getQueryParams()['type'] && $request->getQueryParams()['type'] == 'partial') ? 'partial' : 'template'),
|
||||
'links' => [
|
||||
'templates' => [
|
||||
'link' => $this->router->pathFor('admin.templates.index'),
|
||||
'title' => __('admin_templates'),
|
||||
'attributes' => ['class' => 'navbar-item active']
|
||||
],
|
||||
]
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename template process
|
||||
*
|
||||
* @param Request $request PSR7 request
|
||||
* @param Response $response PSR7 response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function renameProcess(Request $request, Response $response) : Response
|
||||
{
|
||||
$type = $request->getParsedBody()['type_current'];
|
||||
|
||||
if (!Filesystem::has(PATH['themes'] . '/' . $this->registry->get('settings.theme') . '/' . $this->_type_location($type) . $request->getParsedBody()['id'] . '.html')) {
|
||||
if (Filesystem::rename(
|
||||
PATH['themes'] . '/' . $this->registry->get('settings.theme') . '/' . $this->_type_location($type) . $request->getParsedBody()['id_current'] . '.html',
|
||||
PATH['themes'] . '/' . $this->registry->get('settings.theme') . '/' . $this->_type_location($type) . $request->getParsedBody()['id'] . '.html'
|
||||
)
|
||||
) {
|
||||
$this->flash->addMessage('success', __('admin_message_'.$type.'_renamed'));
|
||||
} else {
|
||||
$this->flash->addMessage('error', __('admin_message_'.$type.'_was_not_renamed'));
|
||||
}
|
||||
} else {
|
||||
$this->flash->addMessage('error', __('admin_message_'.$type.'_was_not_renamed'));
|
||||
}
|
||||
|
||||
return $response->withRedirect($this->router->pathFor('admin.templates.index'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete template process
|
||||
*
|
||||
* @param Request $request PSR7 request
|
||||
* @param Response $response PSR7 response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function deleteProcess(Request $request, Response $response) : Response
|
||||
{
|
||||
$type = $request->getParsedBody()['type'];
|
||||
|
||||
$file_path = PATH['themes'] . '/' . $this->registry->get('settings.theme') . '/' . $this->_type_location($type) . $request->getParsedBody()[$type . '-id'] . '.html';
|
||||
|
||||
if (Filesystem::delete($file_path)) {
|
||||
$this->flash->addMessage('success', __('admin_message_' . $type . '_deleted'));
|
||||
} else {
|
||||
$this->flash->addMessage('error', __('admin_message_' . $type . '_was_not_deleted'));
|
||||
}
|
||||
|
||||
return $response->withRedirect($this->router->pathFor('admin.templates.index'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate template process
|
||||
*
|
||||
* @param Request $request PSR7 request
|
||||
* @param Response $response PSR7 response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function duplicateProcess(Request $request, Response $response) : Response
|
||||
{
|
||||
$type = $request->getParsedBody()['type'];
|
||||
|
||||
$file_path = PATH['themes'] . '/' . $this->registry->get('settings.theme') . '/' . $this->_type_location($type) . $request->getParsedBody()[$type . '-id'] . '.html';
|
||||
$file_path_new = PATH['themes'] . '/' . $this->registry->get('settings.theme') . '/' . $this->_type_location($type) . $request->getParsedBody()[$type . '-id'] . '-duplicate-' . date("Ymd_His") . '.html';
|
||||
|
||||
if (Filesystem::copy($file_path, $file_path_new)) {
|
||||
$this->flash->addMessage('success', __('admin_message_' . $type . '_duplicated'));
|
||||
} else {
|
||||
$this->flash->addMessage('error', __('admin_message_' . $type . '_was_not_duplicated'));
|
||||
}
|
||||
|
||||
return $response->withRedirect($this->router->pathFor('admin.templates.index'));
|
||||
}
|
||||
|
||||
private function _type_location($type)
|
||||
{
|
||||
if ($type == 'partial') {
|
||||
$_type = '/templates/partials/';
|
||||
} else {
|
||||
$_type = '/templates/';
|
||||
}
|
||||
|
||||
return $_type;
|
||||
}
|
||||
}
|
128
site/plugins/admin/app/Controllers/UsersController.php
Normal file
128
site/plugins/admin/app/Controllers/UsersController.php
Normal file
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
use Flextype\Component\Session\Session;
|
||||
use Flextype\Component\Text\Text;
|
||||
use function Flextype\Component\I18n\__;
|
||||
|
||||
/**
|
||||
* @property View $view
|
||||
* @property Router $router
|
||||
* @property Slugify $slugify
|
||||
*/
|
||||
class UsersController extends Controller
|
||||
{
|
||||
public function profile($request, $response)
|
||||
{
|
||||
return $this->container->get('view')->render(
|
||||
$response,
|
||||
'plugins/admin/views/templates/users/profile.html'
|
||||
);
|
||||
}
|
||||
|
||||
public function login($request, $response)
|
||||
{
|
||||
$users = $this->getUsers();
|
||||
|
||||
if ((Session::exists('role') && Session::get('role') == 'admin')) {
|
||||
return $response->withRedirect($this->router->pathFor('admin.entries.index'));
|
||||
} else {
|
||||
if ($users && count($users) > 0) {
|
||||
return $this->container->get('view')->render(
|
||||
$response,
|
||||
'plugins/admin/views/templates/users/login.html'
|
||||
);
|
||||
} else {
|
||||
return $response->withRedirect($this->router->pathFor('admin.users.registration'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function loginProcess($request, $response)
|
||||
{
|
||||
$data = $request->getParsedBody();
|
||||
|
||||
if (Filesystem::has($_user_file = PATH['site'] . '/accounts/' . $data['username'] . '.json')) {
|
||||
$user_file = JsonParser::decode(Filesystem::read($_user_file));
|
||||
if (password_verify(trim($data['password']), $user_file['hashed_password'])) {
|
||||
Session::set('username', $user_file['username']);
|
||||
Session::set('role', $user_file['role']);
|
||||
return $response->withRedirect($this->router->pathFor('admin.entries.index'));
|
||||
} else {
|
||||
$this->flash->addMessage('error', __('admin_message_wrong_username_password'));
|
||||
return $response->withRedirect($this->router->pathFor('admin.users.login'));
|
||||
}
|
||||
} else {
|
||||
$this->flash->addMessage('error', __('admin_message_wrong_username_password'));
|
||||
return $response->withRedirect($this->router->pathFor('admin.users.login'));
|
||||
}
|
||||
}
|
||||
|
||||
public function registration($request, $response)
|
||||
{
|
||||
if ((Session::exists('role') && Session::get('role') == 'admin')) {
|
||||
return $response->withRedirect($this->router->pathFor('admin.entries.index'));
|
||||
} else {
|
||||
return $this->view->render(
|
||||
$response,
|
||||
'plugins/admin/views/templates/users/registration.html'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* registrationProcess
|
||||
*/
|
||||
public function registrationProcess($request, $response)
|
||||
{
|
||||
// Get POST data
|
||||
$data = $request->getParsedBody();
|
||||
|
||||
if (!Filesystem::has($_user_file = PATH['site'] . '/accounts/' . $this->slugify->slugify($data['username']) . '.json')) {
|
||||
Filesystem::createDir(PATH['site'] . '/accounts/');
|
||||
if (Filesystem::write(
|
||||
PATH['site'] . '/accounts/' . $data['username'] . '.json',
|
||||
JsonParser::encode(['username' => $this->slugify->slugify($data['username']),
|
||||
'hashed_password' => password_hash($data['password'], PASSWORD_BCRYPT),
|
||||
'email' => $data['email'],
|
||||
'role' => 'admin',
|
||||
'state' => 'enabled'])
|
||||
)) {
|
||||
return $response->withRedirect($this->router->pathFor('admin.users.login'));
|
||||
} else {
|
||||
return $response->withRedirect($this->router->pathFor('admin.users.registration'));
|
||||
}
|
||||
} else {
|
||||
return $response->withRedirect($this->router->pathFor('admin.users.registration'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* logoutProcess
|
||||
*/
|
||||
public function logoutProcess($request, $response)
|
||||
{
|
||||
Session::destroy();
|
||||
return $response->withRedirect($this->router->pathFor('admin.users.login'));
|
||||
}
|
||||
|
||||
public function getUsers()
|
||||
{
|
||||
// Get Users Profiles
|
||||
$users = Filesystem::listContents(PATH['site'] . '/accounts/');
|
||||
|
||||
// Get Plugins List
|
||||
$_users_list = Filesystem::listContents(PATH['plugins']);
|
||||
$users_list = [];
|
||||
|
||||
foreach($_users_list as $user) {
|
||||
if ($user['type'] == 'dir') {
|
||||
$users_list[] = $user;
|
||||
}
|
||||
}
|
||||
|
||||
return $users;
|
||||
}
|
||||
}
|
19
site/plugins/admin/app/Middleware/AuthMiddleware.php
Normal file
19
site/plugins/admin/app/Middleware/AuthMiddleware.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Session\Session;
|
||||
|
||||
class AuthMiddleware extends Middleware
|
||||
{
|
||||
public function __invoke($request, $response, $next)
|
||||
{
|
||||
if (Session::exists('role') && Session::get('role') == 'admin') {
|
||||
$response = $next($request, $response);
|
||||
} else {
|
||||
$response = $response->withRedirect($this->router->pathFor('admin.users.login'));
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
// Admin Theme main SCSS
|
||||
// (c) Sergey Romanenko <https://github.com/Awilum>
|
||||
// (c) Sergey Romanenko <http://romanenko.digital>
|
||||
|
||||
// Generic
|
||||
// Low-specificity, far-reaching rulesets
|
||||
|
@@ -181,3 +181,19 @@
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-pills {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.nav-pills .nav-link {
|
||||
border-radius: 0;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.nav-pills .nav-link.active,
|
||||
.nav-pills .show > .nav-link {
|
||||
background: none;
|
||||
border-bottom: 1px solid #ccc;
|
||||
color: black;
|
||||
}
|
||||
|
@@ -38,6 +38,10 @@
|
||||
border: 1px solid #000;
|
||||
}
|
||||
|
||||
.input-group-append > .btn {
|
||||
padding: 6.5px 16px;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
color: $btn-text-color;
|
||||
|
||||
|
85
site/plugins/admin/bootstrap.php
Executable file
85
site/plugins/admin/bootstrap.php
Executable file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
/**
|
||||
*
|
||||
* Flextype Admin Plugin
|
||||
*
|
||||
* @author Romanenko Sergey / Awilum <hello@romanenko.digital>
|
||||
* @link http://romanenko.digital
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Flextype\Component\Arr\Arr;
|
||||
use Flextype\Component\I18n\I18n;
|
||||
use function Flextype\Component\I18n\__;
|
||||
|
||||
// Get URI
|
||||
$uri = explode('/', \Slim\Http\Uri::createFromEnvironment(new \Slim\Http\Environment($_SERVER))->getPath());
|
||||
|
||||
// Set base admin route
|
||||
$admin_route = 'admin';
|
||||
|
||||
// Ensure vendor libraries exist
|
||||
!is_file($autoload = __DIR__ . '/vendor/autoload.php') and exit("Please run: <i>composer install</i>");
|
||||
|
||||
// Register The Auto Loader
|
||||
$loader = require_once $autoload;
|
||||
|
||||
// Include routes
|
||||
include_once 'routes/web.php';
|
||||
|
||||
// Set Default Admin locale
|
||||
I18n::$locale = $flextype->registry->get('settings.locale');
|
||||
|
||||
// Add Admin Navigation
|
||||
$flextype->registry->set('admin_navigation.content.entries', ['title' => '<i class="far fa-newspaper"></i>' . __('admin_entries'), 'link' => $flextype->router->pathFor('admin.entries.index'), 'attributes' => ['class' => 'nav-link']]);
|
||||
$flextype->registry->set('admin_navigation.extends.fieldsets', ['title' => '<i class="fas fa-list"></i>' . __('admin_fieldsets'), 'link' => $flextype->router->pathFor('admin.fieldsets.index'), 'attributes' => ['class' => 'nav-link']]);
|
||||
$flextype->registry->set('admin_navigation.extends.templates', ['title' => '<i class="fas fa-layer-group"></i>' . __('admin_templates'), 'link' => $flextype->router->pathFor('admin.templates.index'), 'attributes' => ['class' => 'nav-link']]);
|
||||
$flextype->registry->set('admin_navigation.extends.snippets', ['title' => '<i class="far fa-file-code"></i>' . __('admin_snippets'), 'link' => $flextype->router->pathFor('admin.snippets.index'), 'attributes' => ['class' => 'nav-link']]);
|
||||
$flextype->registry->set('admin_navigation.extends.plugins', ['title' => '<i class="fas fa-plug"></i>' . __('admin_plugins'), 'link' => $flextype->router->pathFor('admin.plugins.index'), 'attributes' => ['class' => 'nav-link']]);
|
||||
$flextype->registry->set('admin_navigation.settings.settings', ['title' => '<i class="fas fa-cog"></i>' . __('admin_settings'), 'link' => $flextype->router->pathFor('admin.settings.index'), 'attributes' => ['class' => 'nav-link']]);
|
||||
$flextype->registry->set('admin_navigation.settings.infomation', ['title' => '<i class="fas fa-info"></i>' . __('admin_information'), 'link' => $flextype->router->pathFor('admin.information.index'), 'attributes' => ['class' => 'nav-link']]);
|
||||
$flextype->registry->set('admin_navigation.help.docs', ['title' => '<i class="far fa-question-circle"></i>' . __('admin_documentation'), 'link' => 'http://flextype.org/en/documentation', 'attributes' => ['class' => 'nav-link', 'target' => '_blank']]);
|
||||
|
||||
// Add Global Vars Admin Twig Extension
|
||||
$flextype->view->addExtension(new GlobalVarsAdminTwigExtension($flextype));
|
||||
|
||||
$flextype['DashboardController'] = function ($container) {
|
||||
return new DashboardController($container);
|
||||
};
|
||||
|
||||
$flextype['SettingsController'] = function ($container) {
|
||||
return new SettingsController($container);
|
||||
};
|
||||
|
||||
$flextype['InformationController'] = function ($container) {
|
||||
return new InformationController($container);
|
||||
};
|
||||
|
||||
$flextype['PluginsController'] = function ($container) {
|
||||
return new PluginsController($container);
|
||||
};
|
||||
|
||||
$flextype['EntriesController'] = function ($container) {
|
||||
return new EntriesController($container);
|
||||
};
|
||||
|
||||
$flextype['FieldsetsController'] = function ($container) {
|
||||
return new FieldsetsController($container);
|
||||
};
|
||||
|
||||
$flextype['SnippetsController'] = function ($container) {
|
||||
return new SnippetsController($container);
|
||||
};
|
||||
|
||||
$flextype['TemplatesController'] = function ($container) {
|
||||
return new TemplatesController($container);
|
||||
};
|
||||
|
||||
$flextype['UsersController'] = function ($container) {
|
||||
return new UsersController($container);
|
||||
};
|
@@ -1,13 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Http\Http;
|
||||
|
||||
class DashboardManager
|
||||
{
|
||||
public static function getDashboardManager()
|
||||
{
|
||||
Http::redirect(Http::getBaseUrl().'/admin/entries');
|
||||
}
|
||||
}
|
@@ -1,659 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Arr\Arr;
|
||||
use Flextype\Component\Number\Number;
|
||||
use Flextype\Component\I18n\I18n;
|
||||
use Flextype\Component\Http\Http;
|
||||
use Flextype\Component\Event\Event;
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
use Flextype\Component\Session\Session;
|
||||
use Flextype\Component\Registry\Registry;
|
||||
use Flextype\Component\Token\Token;
|
||||
use Flextype\Component\Text\Text;
|
||||
use Flextype\Component\Form\Form;
|
||||
use Flextype\Component\Notification\Notification;
|
||||
use function Flextype\Component\I18n\__;
|
||||
use Gajus\Dindent\Indenter;
|
||||
use Intervention\Image\ImageManagerStatic as Image;
|
||||
|
||||
class EntriesManager
|
||||
{
|
||||
|
||||
public static function getEntriesManager()
|
||||
{
|
||||
Registry::set('sidebar_menu_item', 'entries');
|
||||
|
||||
if (Http::get('entry') && Http::get('entry') != '') {
|
||||
$query = Http::get('entry');
|
||||
} else {
|
||||
$query = '';
|
||||
}
|
||||
|
||||
switch (Http::getUriSegment(2)) {
|
||||
case 'add':
|
||||
$create_entry = Http::post('create_entry');
|
||||
|
||||
if (isset($create_entry)) {
|
||||
if (Token::check((Http::post('token')))) {
|
||||
$file = PATH['entries'] . '/' . Http::post('parent_entry') . '/' . Text::safeString(Http::post('slug'), '-', true) . '/entry.html';
|
||||
|
||||
if (!Filesystem::fileExists($file)) {
|
||||
|
||||
// Get fieldset
|
||||
$fieldset = YamlParser::decode(Filesystem::getFileContent(PATH['themes'] . '/' . Registry::get('settings.theme') . '/fieldsets/' . Http::post('fieldset') . '.yaml'));
|
||||
|
||||
// We need to check if template for current fieldset is exists
|
||||
// if template is not exist then default template will be used!
|
||||
$template_path = PATH['themes'] . '/' . Registry::get('settings.theme') . '/views/templates/' . Http::post('fieldset') . '.php';
|
||||
if (Filesystem::fileExists($template_path)) {
|
||||
$template = Http::post('fieldset');
|
||||
} else {
|
||||
$template = 'default';
|
||||
}
|
||||
|
||||
// Init frontmatter
|
||||
$frontmatter = [];
|
||||
$_frontmatter = [];
|
||||
|
||||
// Define frontmatter values based on POST data
|
||||
$_frontmatter['title'] = Http::post('title');
|
||||
$_frontmatter['template'] = $template;
|
||||
$_frontmatter['fieldset'] = Http::post('fieldset');
|
||||
$_frontmatter['date'] = date(Registry::get('settings.date_format'), time());
|
||||
|
||||
// Define frontmatter values based on fieldset
|
||||
foreach ($fieldset['fields'] as $key => $field) {
|
||||
|
||||
if (isset($_frontmatter[$key])) {
|
||||
$_value = $_frontmatter[$key];
|
||||
} elseif(isset($field['value'])) {
|
||||
$_value = $field['value'];
|
||||
} else {
|
||||
$_value = '';
|
||||
}
|
||||
|
||||
$frontmatter[$key] = $_value;
|
||||
}
|
||||
|
||||
// Delete content field from frontmatter
|
||||
Arr::delete($frontmatter, 'content');
|
||||
|
||||
// Create a entry!
|
||||
if (Filesystem::setFileContent(
|
||||
$file,
|
||||
'---'."\n".
|
||||
YamlParser::encode(array_replace_recursive($frontmatter, $_frontmatter)).
|
||||
'---'."\n"
|
||||
)) {
|
||||
Notification::set('success', __('admin_message_entry_created'));
|
||||
Http::redirect(Http::getBaseUrl().'/admin/entries/?entry='.Http::post('parent_entry'));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
|
||||
Themes::view('admin/views/templates/content/entries/add')
|
||||
->assign('fieldsets', Themes::getFieldsets())
|
||||
->assign('entries_list', Entries::getEntries('', 'slug'))
|
||||
->display();
|
||||
break;
|
||||
case 'delete':
|
||||
if (Http::get('entry') != '') {
|
||||
if (Token::check((Http::get('token')))) {
|
||||
Filesystem::deleteDir(PATH['entries'] . '/' . Http::get('entry'));
|
||||
Notification::set('success', __('admin_message_entry_deleted'));
|
||||
Http::redirect(Http::getBaseUrl() . '/admin/entries/?entry=' . Http::get('entry_current'));
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'duplicate':
|
||||
if (Http::get('entry') != '') {
|
||||
if (Token::check((Http::get('token')))) {
|
||||
Filesystem::recursiveCopy(PATH['entries'] . '/' . Http::get('entry'),
|
||||
PATH['entries'] . '/' . Http::get('entry') . '-duplicate-' . date("Ymd_His"));
|
||||
Notification::set('success', __('admin_message_entry_duplicated'));
|
||||
Http::redirect(Http::getBaseUrl().'/admin/entries/?entry='.implode('/', array_slice(explode("/", Http::get('entry')), 0, -1)));
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'rename':
|
||||
$entry = Entries::processEntry(PATH['entries'] . '/' . Http::get('entry') . '/entry.html', false, true);
|
||||
|
||||
$rename_entry = Http::post('rename_entry');
|
||||
|
||||
if (isset($rename_entry)) {
|
||||
if (Token::check((Http::post('token')))) {
|
||||
if (!Filesystem::dirExists(PATH['entries'] . '/' . Http::post('name'))) {
|
||||
if (rename(
|
||||
PATH['entries'] . '/' . Http::post('entry_path_current'),
|
||||
PATH['entries'] . '/' . Http::post('entry_parent') . '/' . Text::safeString(Http::post('name'), '-', true)
|
||||
)) {
|
||||
Notification::set('success', __('admin_message_entry_renamed'));
|
||||
Http::redirect(Http::getBaseUrl().'/admin/entries/?entry='.Http::post('entry_parent'));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
|
||||
Themes::view('admin/views/templates/content/entries/rename')
|
||||
->assign('name_current', Arr::last(explode("/", Http::get('entry'))))
|
||||
->assign('entry_path_current', Http::get('entry'))
|
||||
->assign('entry_parent', implode('/', array_slice(explode("/", Http::get('entry')), 0, -1)))
|
||||
->assign('entry', $entry)
|
||||
->display();
|
||||
break;
|
||||
case 'type':
|
||||
|
||||
$type_entry = Http::post('type_entry');
|
||||
|
||||
if (isset($type_entry)) {
|
||||
if (Token::check((Http::post('token')))) {
|
||||
|
||||
$entry = Entries::processEntry(PATH['entries'] . '/' . Http::get('entry') . '/entry.html', false, true);
|
||||
|
||||
$content = $entry['content'];
|
||||
Arr::delete($entry, 'content');
|
||||
Arr::delete($entry, 'url');
|
||||
Arr::delete($entry, 'slug');
|
||||
Arr::delete($entry, 'base_url');
|
||||
|
||||
$frontmatter = $_POST;
|
||||
Arr::delete($frontmatter, 'token');
|
||||
Arr::delete($frontmatter, 'type_entry');
|
||||
Arr::delete($frontmatter, 'entry');
|
||||
$frontmatter = YamlParser::encode(array_merge($entry, $frontmatter));
|
||||
|
||||
if (Filesystem::setFileContent(
|
||||
PATH['entries'] . '/' . Http::post('entry') . '/entry.html',
|
||||
'---'."\n".
|
||||
$frontmatter."\n".
|
||||
'---'."\n".
|
||||
$content
|
||||
)) {
|
||||
Notification::set('success', __('admin_message_entry_changes_saved'));
|
||||
Http::redirect(Http::getBaseUrl() . '/admin/entries?entry='.implode('/', array_slice(explode("/", Http::get('entry')), 0, -1)));
|
||||
}
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
|
||||
$entry = Entries::processEntry(PATH['entries'] . '/' . Http::get('entry') . '/entry.html', false, true);
|
||||
|
||||
Themes::view('admin/views/templates/content/entries/type')
|
||||
->assign('fieldset', $entry['fieldset'])
|
||||
->assign('fieldsets', Themes::getFieldsets())
|
||||
->display();
|
||||
break;
|
||||
case 'move':
|
||||
$entry = Entries::processEntry(PATH['entries'] . '/' . Http::get('entry') . '/entry.html', false, true);
|
||||
|
||||
$move_entry = Http::post('move_entry');
|
||||
|
||||
if (isset($move_entry)) {
|
||||
if (Token::check((Http::post('token')))) {
|
||||
if (!Filesystem::dirExists(realpath(PATH['entries'] . '/' . Http::post('parent_entry') . '/' . Http::post('name_current')))) {
|
||||
if (rename(
|
||||
PATH['entries'] . '/' . Http::post('entry_path_current'),
|
||||
PATH['entries'] . '/' . Http::post('parent_entry') . '/' . Text::safeString(Http::post('name_current'), '-', true)
|
||||
)) {
|
||||
Notification::set('success', __('admin_message_entry_moved'));
|
||||
Http::redirect(Http::getBaseUrl().'/admin/entries/?entry='.Http::post('parent_entry'));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
|
||||
$_entries_list = Entries::getEntries('', 'slug');
|
||||
$entries_list['/'] = '/';
|
||||
foreach ($_entries_list as $_entry) {
|
||||
if ($_entry['slug'] != '') {
|
||||
$entries_list[$_entry['slug']] = $_entry['slug'];
|
||||
} else {
|
||||
$entries_list[Registry::get('settings.entries.main')] = Registry::get('settings.entries.main');
|
||||
}
|
||||
}
|
||||
|
||||
Themes::view('admin/views/templates/content/entries/move')
|
||||
->assign('entry_path_current', Http::get('entry'))
|
||||
->assign('entries_list', $entries_list)
|
||||
->assign('name_current', Arr::last(explode("/", Http::get('entry'))))
|
||||
->assign('entry_parent', implode('/', array_slice(explode("/", Http::get('entry')), 0, -1)))
|
||||
->assign('entry', $entry)
|
||||
->display();
|
||||
break;
|
||||
case 'edit':
|
||||
$entry = Entries::processEntry(PATH['entries'] . '/' . Http::get('entry') . '/entry.html', false, true);
|
||||
|
||||
if (Http::get('media') && Http::get('media') == 'true') {
|
||||
EntriesManager::processFilesManager();
|
||||
|
||||
Themes::view('admin/views/templates/content/entries/media')
|
||||
->assign('entry_name', Http::get('entry'))
|
||||
->assign('files', EntriesManager::getMediaList(Http::get('entry')), true)
|
||||
->assign('entry', $entry)
|
||||
->display();
|
||||
} else {
|
||||
if (Http::get('source') && Http::get('source') == 'true') {
|
||||
$action = Http::post('action');
|
||||
|
||||
if (isset($action) && $action == 'save-form') {
|
||||
if (Token::check((Http::post('token')))) {
|
||||
Filesystem::setFileContent(
|
||||
PATH['entries'] . '/' . Http::post('entry_name') . '/entry.html',
|
||||
Http::post('entry_content')
|
||||
);
|
||||
Notification::set('success', __('admin_message_entry_changes_saved'));
|
||||
Http::redirect(Http::getBaseUrl().'/admin/entries/edit?entry='.Http::post('entry_name').'&source=true');
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
|
||||
$entry_content = Filesystem::getFileContent(PATH['entries'] . '/' . Http::get('entry') . '/entry.html');
|
||||
|
||||
Themes::view('admin/views/templates/content/entries/source')
|
||||
->assign('entry_name', Http::get('entry'))
|
||||
->assign('entry_content', $entry_content)
|
||||
->assign('entry', $entry)
|
||||
->assign('files', EntriesManager::getMediaList(Http::get('entry')), true)
|
||||
->display();
|
||||
} else {
|
||||
$action = Http::post('action');
|
||||
$indenter = new Indenter();
|
||||
|
||||
if (isset($action) && $action == 'save-form') {
|
||||
if (Token::check((Http::post('token')))) {
|
||||
$entry = Entries::processEntry(PATH['entries'] . '/' . Http::get('entry') . '/entry.html', false, true);
|
||||
Arr::delete($entry, 'content');
|
||||
Arr::delete($entry, 'url');
|
||||
Arr::delete($entry, 'slug');
|
||||
Arr::delete($entry, 'base_url');
|
||||
|
||||
$frontmatter = $_POST;
|
||||
Arr::delete($frontmatter, 'token');
|
||||
Arr::delete($frontmatter, 'action');
|
||||
Arr::delete($frontmatter, 'content');
|
||||
$frontmatter = YamlParser::encode(array_merge($entry, $frontmatter));
|
||||
|
||||
$content = Http::post('content');
|
||||
$content = (isset($content)) ? $indenter->indent($content) : '';
|
||||
|
||||
Filesystem::setFileContent(
|
||||
PATH['entries'] . '/' . Http::get('entry') . '/entry.html',
|
||||
'---'."\n".
|
||||
$frontmatter."\n".
|
||||
'---'."\n".
|
||||
$content
|
||||
);
|
||||
Notification::set('success', __('admin_message_entry_changes_saved'));
|
||||
Http::redirect(Http::getBaseUrl().'/admin/entries/edit?entry='.Http::get('entry'));
|
||||
}
|
||||
}
|
||||
|
||||
// Fieldset for current entry template
|
||||
$fieldset_path = PATH['themes'] . '/' . Registry::get('settings.theme') . '/fieldsets/' . (isset($entry['fieldset']) ? $entry['fieldset'] : 'default') . '.yaml';
|
||||
$fieldset = YamlParser::decode(Filesystem::getFileContent($fieldset_path));
|
||||
is_null($fieldset) and $fieldset = [];
|
||||
|
||||
Themes::view('admin/views/templates/content/entries/content')
|
||||
->assign('entry_name', Http::get('entry'))
|
||||
->assign('entry', $entry)
|
||||
->assign('fieldset', $fieldset)
|
||||
->assign('templates', Themes::getTemplates())
|
||||
->assign('files', EntriesManager::getMediaList(Http::get('entry')), true)
|
||||
->display();
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (!Http::get('add')) {
|
||||
Themes::view('admin/views/templates/content/entries/list')
|
||||
->assign('entries_list', Entries::getEntries($query, 'date', 'DESC'))
|
||||
->display();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static function getMediaList($entry, $path = false)
|
||||
{
|
||||
$files = [];
|
||||
foreach (array_diff(scandir(PATH['entries'] . '/' . $entry), ['..', '.']) as $file) {
|
||||
if (strpos(Registry::get('settings.entries.media.accept_file_types'), $file_ext = substr(strrchr($file, '.'), 1)) !== false) {
|
||||
if (strpos($file, strtolower($file_ext), 1)) {
|
||||
if ($path) {
|
||||
$files[Http::getBaseUrl().'/'.$entry.'/'.$file] = Http::getBaseUrl().'/'.$entry.'/'.$file;
|
||||
} else {
|
||||
$files[$file] = $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $files;
|
||||
}
|
||||
|
||||
public static function displayEntryForm(array $form, array $values = [], string $content)
|
||||
{
|
||||
echo Form::open(null, ['id' => 'form', 'class' => 'row']);
|
||||
echo Form::hidden('token', Token::generate());
|
||||
echo Form::hidden('action', 'save-form');
|
||||
|
||||
if (isset($form) > 0) {
|
||||
foreach ($form as $element => $property) {
|
||||
|
||||
// Create attributes
|
||||
$property['attributes'] = Arr::keyExists($property, 'attributes') ? $property['attributes'] : [] ;
|
||||
|
||||
// Create attribute class
|
||||
$property['attributes']['class'] = Arr::keyExists($property, 'attributes.class') ? 'form-control ' . $property['attributes']['class'] : 'form-control' ;
|
||||
|
||||
// Create attribute size
|
||||
$property['size'] = Arr::keyExists($property, 'size') ? $property['size'] : 'col-12' ;
|
||||
|
||||
// Create attribute value
|
||||
$property['value'] = Arr::keyExists($property, 'value') ? $property['value'] : '' ;
|
||||
|
||||
$pos = strpos($element, '.');
|
||||
|
||||
if ($pos === false) {
|
||||
$form_element_name = $element;
|
||||
} else {
|
||||
$form_element_name = str_replace(".", "][", "$element").']';
|
||||
}
|
||||
|
||||
$pos = strpos($form_element_name, ']');
|
||||
|
||||
if ($pos !== false) {
|
||||
$form_element_name = substr_replace($form_element_name, '', $pos, strlen(']'));
|
||||
}
|
||||
|
||||
// Form value
|
||||
$form_value = Arr::keyExists($values, $element) ? Arr::get($values, $element) : $property['value'];
|
||||
|
||||
// Form label
|
||||
$form_label = Form::label($element, __($property['title']));
|
||||
|
||||
// Form elements
|
||||
switch ($property['type']) {
|
||||
|
||||
// Simple text-input, for multi-line fields.
|
||||
case 'textarea':
|
||||
$form_element = Form::textarea($element, $form_value, $property['attributes']);
|
||||
break;
|
||||
|
||||
// The hidden field is like the text field, except it's hidden from the content editor.
|
||||
case 'hidden':
|
||||
$form_element = Form::hidden($element, $form_value);
|
||||
break;
|
||||
|
||||
// A WYSIWYG HTML field.
|
||||
case 'html':
|
||||
$property['attributes']['class'] .= ' js-html-editor';
|
||||
$form_element = Form::textarea($element, $form_value, $property['attributes']);
|
||||
break;
|
||||
|
||||
// A specific WYSIWYG HTML field for entry content editing
|
||||
case 'content':
|
||||
$form_element = Form::textarea($element, $content, $property['attributes']);
|
||||
break;
|
||||
|
||||
// Template select field for selecting entry template
|
||||
case 'template_select':
|
||||
$form_element = Form::select($form_element_name, Themes::getTemplates(), $form_value, $property['attributes']);
|
||||
break;
|
||||
|
||||
// Visibility select field for selecting entry visibility state
|
||||
case 'visibility_select':
|
||||
$form_element = Form::select($form_element_name, ['draft' => __('admin_entries_draft'), 'visible' => __('admin_entries_visible'), 'hidden' => __('admin_entries_hidden')], (!empty($form_value) ? $form_value : 'visible'), $property['attributes']);
|
||||
break;
|
||||
|
||||
// Media select field
|
||||
case 'media_select':
|
||||
$form_element = Form::select($form_element_name, EntriesManager::getMediaList(Http::get('entry'), false), $form_value, $property['attributes']);
|
||||
break;
|
||||
|
||||
// Simple text-input, for single-line fields.
|
||||
default:
|
||||
$form_element = Form::input($form_element_name, $form_value, $property['attributes']);
|
||||
break;
|
||||
}
|
||||
|
||||
// Render form elments with labels
|
||||
if ($property['type'] == 'hidden') {
|
||||
echo $form_element;
|
||||
} else {
|
||||
echo '<div class="form-group '.$property['size'].'">';
|
||||
echo $form_label . $form_element;
|
||||
echo '</div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo Form::close();
|
||||
}
|
||||
|
||||
protected static function processFilesManager()
|
||||
{
|
||||
$files_directory = PATH['entries'] . '/' . Http::get('entry') . '/';
|
||||
|
||||
if (Http::get('delete_file') != '') {
|
||||
if (Token::check((Http::get('token')))) {
|
||||
Filesystem::deleteFile($files_directory . Http::get('delete_file'));
|
||||
Notification::set('success', __('admin_message_entry_file_deleted'));
|
||||
Http::redirect(Http::getBaseUrl().'/admin/entries/edit?entry='.Http::get('entry').'&media=true');
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
|
||||
if (Http::post('upload_file')) {
|
||||
if (Token::check(Http::post('token'))) {
|
||||
//echo Registry::get('settings.entries.media.accept_file_types');
|
||||
|
||||
$file = EntriesManager::uploadFile($_FILES['file'], $files_directory, Registry::get('settings.entries.media.accept_file_types'), 27000000);
|
||||
|
||||
if($file !== false) {
|
||||
|
||||
if (in_array(pathinfo($file)['extension'], ['jpg', 'jpeg', 'png', 'gif'])) {
|
||||
|
||||
// open an image file
|
||||
$img = Image::make($file);
|
||||
|
||||
// now you are able to resize the instance
|
||||
if (Registry::get('settings.entries.media.upload_images_width') > 0 && Registry::get('settings.entries.media.upload_images_height') > 0) {
|
||||
$img->resize(Registry::get('settings.entries.media.upload_images_width'), Registry::get('settings.entries.media.upload_images_height'), function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
});
|
||||
} elseif (Registry::get('settings.entries.media.upload_images_width') > 0) {
|
||||
$img->resize(Registry::get('settings.entries.media.upload_images_width'), null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
});
|
||||
} elseif (Registry::get('settings.entries.media.upload_images_height') > 0) {
|
||||
$img->resize(null, Registry::get('settings.entries.media.upload_images_height'), function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
});
|
||||
}
|
||||
|
||||
// finally we save the image as a new file
|
||||
$img->save($file, Registry::get('settings.entries.media.upload_images_quality'));
|
||||
|
||||
// destroy
|
||||
$img->destroy();
|
||||
}
|
||||
|
||||
Notification::set('success', __('admin_message_entry_file_uploaded'));
|
||||
Http::redirect(Http::getBaseUrl().'/admin/entries/edit?entry='.Http::get('entry').'&media=true');
|
||||
} else {
|
||||
Notification::set('error', __('admin_message_entry_file_not_uploaded'));
|
||||
Http::redirect(Http::getBaseUrl().'/admin/entries/edit?entry='.Http::get('entry').'&media=true');
|
||||
}
|
||||
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload files on the Server with several type of Validations!
|
||||
*
|
||||
* Entries::uploadFile($_FILES['file'], $files_directory);
|
||||
*
|
||||
* @param array $file Uploaded file data
|
||||
* @param string $upload_directory Upload directory
|
||||
* @param string $allowed Allowed file extensions
|
||||
* @param int $max_size Max file size in bytes
|
||||
* @param string $filename New filename
|
||||
* @param bool $remove_spaces Remove spaces from the filename
|
||||
* @param int $max_width Maximum width of image
|
||||
* @param int $max_height Maximum height of image
|
||||
* @param bool $exact Match width and height exactly?
|
||||
* @param int $chmod Chmod mask
|
||||
* @return string on success, full path to new file
|
||||
* @return false on failure
|
||||
*/
|
||||
public static function uploadFile(
|
||||
array $file,
|
||||
string $upload_directory,
|
||||
string $allowed = 'jpeg, png, gif, jpg',
|
||||
int $max_size = 3000000,
|
||||
string $filename = null,
|
||||
bool $remove_spaces = true,
|
||||
int $max_width = null,
|
||||
int $max_height = null,
|
||||
bool $exact = false,
|
||||
int $chmod = 0644
|
||||
) {
|
||||
//
|
||||
// Tests if a successful upload has been made.
|
||||
//
|
||||
if (isset($file['error'])
|
||||
and isset($file['tmp_name'])
|
||||
and $file['error'] === UPLOAD_ERR_OK
|
||||
and is_uploaded_file($file['tmp_name'])) {
|
||||
|
||||
//
|
||||
// Tests if upload data is valid, even if no file was uploaded.
|
||||
//
|
||||
if (isset($file['error'])
|
||||
and isset($file['name'])
|
||||
and isset($file['type'])
|
||||
and isset($file['tmp_name'])
|
||||
and isset($file['size'])) {
|
||||
|
||||
//
|
||||
// Test if an uploaded file is an allowed file type, by extension.
|
||||
//
|
||||
if (strpos($allowed, strtolower(pathinfo($file['name'], PATHINFO_EXTENSION))) !== false) {
|
||||
|
||||
//
|
||||
// Validation rule to test if an uploaded file is allowed by file size.
|
||||
//
|
||||
if (($file['error'] != UPLOAD_ERR_INI_SIZE)
|
||||
and ($file['error'] == UPLOAD_ERR_OK)
|
||||
and ($file['size'] <= $max_size)) {
|
||||
|
||||
//
|
||||
// Validation rule to test if an upload is an image and, optionally, is the correct size.
|
||||
//
|
||||
if (in_array(mime_content_type($file['tmp_name']), ['image/jpeg', 'image/jpg', 'image/png','image/gif'])) {
|
||||
function validateImage($file, $max_width, $max_height, $exact)
|
||||
{
|
||||
try {
|
||||
// Get the width and height from the uploaded image
|
||||
list($width, $height) = getimagesize($file['tmp_name']);
|
||||
} catch (ErrorException $e) {
|
||||
// Ignore read errors
|
||||
}
|
||||
|
||||
if (empty($width) or empty($height)) {
|
||||
// Cannot get image size, cannot validate
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! $max_width) {
|
||||
// No limit, use the image width
|
||||
$max_width = $width;
|
||||
}
|
||||
|
||||
if (! $max_height) {
|
||||
// No limit, use the image height
|
||||
$max_height = $height;
|
||||
}
|
||||
|
||||
if ($exact) {
|
||||
// Check if dimensions match exactly
|
||||
return ($width === $max_width and $height === $max_height);
|
||||
} else {
|
||||
// Check if size is within maximum dimensions
|
||||
return ($width <= $max_width and $height <= $max_height);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (validateImage($file, $max_width, $max_height, $exact) === false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (! isset($file['tmp_name']) or ! is_uploaded_file($file['tmp_name'])) {
|
||||
|
||||
// Ignore corrupted uploads
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($filename === null) {
|
||||
|
||||
// Use the default filename
|
||||
$filename = $file['name'];
|
||||
}
|
||||
|
||||
if ($remove_spaces === true) {
|
||||
|
||||
// Remove spaces from the filename
|
||||
$filename = Text::safeString(pathinfo($filename)['filename'], '-', true) . '.' . pathinfo($filename)['extension'];
|
||||
}
|
||||
|
||||
if (! is_dir($upload_directory) or ! is_writable(realpath($upload_directory))) {
|
||||
throw new \RuntimeException("Directory {$upload_directory} must be writable");
|
||||
}
|
||||
|
||||
// Make the filename into a complete path
|
||||
$filename = realpath($upload_directory).DIRECTORY_SEPARATOR.$filename;
|
||||
|
||||
if (move_uploaded_file($file['tmp_name'], $filename)) {
|
||||
|
||||
if ($chmod !== false) {
|
||||
// Set permissions on filename
|
||||
chmod($filename, $chmod);
|
||||
}
|
||||
|
||||
// Return new file path
|
||||
return $filename;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@@ -1,133 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Registry\Registry;
|
||||
use Flextype\Component\Http\Http;
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
use Flextype\Component\Token\Token;
|
||||
use Flextype\Component\Text\Text;
|
||||
use Flextype\Component\Notification\Notification;
|
||||
use function Flextype\Component\I18n\__;
|
||||
|
||||
class FieldsetsManager
|
||||
{
|
||||
public static function getFieldsetsManager()
|
||||
{
|
||||
Registry::set('sidebar_menu_item', 'fieldsets');
|
||||
|
||||
switch (Http::getUriSegment(2)) {
|
||||
case 'add':
|
||||
$create_fieldset = Http::post('create_fieldset');
|
||||
|
||||
if (isset($create_fieldset)) {
|
||||
if (Token::check((Http::post('token')))) {
|
||||
|
||||
$file = PATH['themes'] . '/' . Registry::get('settings.theme') . '/fieldsets/' . Text::safeString(Http::post('name'), '-', true) . '.yaml';
|
||||
|
||||
if (!Filesystem::fileExists($file)) {
|
||||
// Create a fieldset!
|
||||
if (Filesystem::setFileContent(
|
||||
$file,
|
||||
YamlParser::encode([
|
||||
'title' => Http::post('title'),
|
||||
'fields' => [
|
||||
'title' => [
|
||||
'title' => 'admin_title',
|
||||
'type' => 'text',
|
||||
'size' => 'col-12'
|
||||
]
|
||||
]
|
||||
])
|
||||
)) {
|
||||
Notification::set('success', __('admin_message_fieldset_created'));
|
||||
Http::redirect(Http::getBaseUrl() . '/admin/fieldsets');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
|
||||
Themes::view('admin/views/templates/extends/fieldsets/add')
|
||||
->display();
|
||||
break;
|
||||
case 'delete':
|
||||
if (Http::get('fieldset') != '') {
|
||||
if (Token::check((Http::get('token')))) {
|
||||
Filesystem::deleteFile(PATH['themes'] . '/' . Registry::get('settings.theme') . '/fieldsets/' . Http::get('fieldset') . '.yaml');
|
||||
Notification::set('success', __('admin_message_fieldset_deleted'));
|
||||
Http::redirect(Http::getBaseUrl() . '/admin/fieldsets');
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'rename':
|
||||
$rename_fieldset = Http::post('rename_fieldset');
|
||||
|
||||
if (isset($rename_fieldset)) {
|
||||
if (Token::check((Http::post('token')))) {
|
||||
if (!Filesystem::fileExists(PATH['themes'] . '/' . Registry::get('settings.theme') . '/fieldsets/' . Http::post('name') . '.yaml')) {
|
||||
if (rename(
|
||||
PATH['themes'] . '/' . Registry::get('settings.theme') . '/fieldsets/' . Http::post('name_current') . '.yaml',
|
||||
PATH['themes'] . '/' . Registry::get('settings.theme') . '/fieldsets/' . Http::post('name') . '.yaml')
|
||||
) {
|
||||
Notification::set('success', __('admin_message_fieldset_renamed'));
|
||||
Http::redirect(Http::getBaseUrl() . '/admin/fieldsets');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
|
||||
Themes::view('admin/views/templates/extends/fieldsets/rename')
|
||||
->assign('name_current', Http::get('fieldset'))
|
||||
->display();
|
||||
break;
|
||||
case 'duplicate':
|
||||
if (Http::get('fieldset') != '') {
|
||||
if (Token::check((Http::get('token')))) {
|
||||
Filesystem::copy(PATH['themes'] . '/' . Registry::get('settings.theme') . '/fieldsets/' . Http::get('fieldset') . '.yaml',
|
||||
PATH['themes'] . '/' . Registry::get('settings.theme') . '/fieldsets/' . Http::get('fieldset') . '-duplicate-' . date("Ymd_His") . '.yaml');
|
||||
Notification::set('success', __('admin_message_fieldset_duplicated'));
|
||||
Http::redirect(Http::getBaseUrl().'/admin/fieldsets');
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'edit':
|
||||
$action = Http::post('action');
|
||||
|
||||
if (isset($action) && $action == 'save-form') {
|
||||
if (Token::check((Http::post('token')))) {
|
||||
|
||||
// Save a fieldset!
|
||||
if (Filesystem::setFileContent(
|
||||
PATH['themes'] . '/' . Registry::get('settings.theme') . '/fieldsets/' . Http::post('name') . '.yaml',
|
||||
Http::post('fieldset')
|
||||
)) {
|
||||
Notification::set('success', __('admin_message_fieldset_saved'));
|
||||
Http::redirect(Http::getBaseUrl() . '/admin/fieldsets/edit?fieldset='.Http::post('name'));
|
||||
}
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
|
||||
Themes::view('admin/views/templates/extends/fieldsets/edit')
|
||||
->assign('fieldset', Filesystem::getFileContent(PATH['themes'] . '/' . Registry::get('settings.theme') . '/fieldsets/' . Http::get('fieldset') . '.yaml'))
|
||||
->display();
|
||||
break;
|
||||
default:
|
||||
$fieldsets_list = Themes::getFieldsets();
|
||||
|
||||
Themes::view('admin/views/templates/extends/fieldsets/list')
|
||||
->assign('fieldsets_list', $fieldsets_list)
|
||||
->display();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,14 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Registry\Registry;
|
||||
|
||||
class InformationManager
|
||||
{
|
||||
public static function getInformationManager()
|
||||
{
|
||||
Registry::set('sidebar_menu_item', 'infomation');
|
||||
Themes::view('admin/views/templates/system/information/list')->display();
|
||||
}
|
||||
}
|
@@ -1,136 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Registry\Registry;
|
||||
use Flextype\Component\Http\Http;
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
use Flextype\Component\Token\Token;
|
||||
use Flextype\Component\Text\Text;
|
||||
use Flextype\Component\Notification\Notification;
|
||||
use function Flextype\Component\I18n\__;
|
||||
|
||||
class MenusManager
|
||||
{
|
||||
public static function getMenusManager()
|
||||
{
|
||||
Registry::set('sidebar_menu_item', 'menus');
|
||||
|
||||
// Create directory for menus
|
||||
!Filesystem::fileExists(PATH['menus']) and Filesystem::createDir(PATH['menus']);
|
||||
|
||||
switch (Http::getUriSegment(2)) {
|
||||
case 'add':
|
||||
$create_menu = Http::post('create_menu');
|
||||
|
||||
if (isset($create_menu)) {
|
||||
if (Token::check((Http::post('token')))) {
|
||||
|
||||
$file = PATH['menus'] . '/' . Text::safeString(Http::post('name'), '-', true) . '.yaml';
|
||||
|
||||
if (!Filesystem::fileExists($file)) {
|
||||
// Create a menu!
|
||||
if (Filesystem::setFileContent(
|
||||
$file,
|
||||
YamlParser::encode(['title' => Http::post('title')])
|
||||
)) {
|
||||
Notification::set('success', __('admin_message_menu_created'));
|
||||
Http::redirect(Http::getBaseUrl() . '/admin/menus');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
|
||||
Themes::view('admin/views/templates/extends/menus/add')
|
||||
->display();
|
||||
break;
|
||||
case 'delete':
|
||||
if (Http::get('menu') != '') {
|
||||
if (Token::check((Http::get('token')))) {
|
||||
Filesystem::deleteFile(PATH['menus'] . '/' . Http::get('menu') . '.yaml');
|
||||
Notification::set('success', __('admin_message_menu_deleted'));
|
||||
Http::redirect(Http::getBaseUrl() . '/admin/menus');
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'rename':
|
||||
$rename_menu = Http::post('rename_menu');
|
||||
|
||||
if (isset($rename_menu)) {
|
||||
if (Token::check((Http::post('token')))) {
|
||||
if (!Filesystem::fileExists(PATH['menus'] . '/' . Http::post('name') . '.yaml')) {
|
||||
if (rename(
|
||||
PATH['menus'] . '/' . Http::post('name_current') . '.yaml',
|
||||
PATH['menus'] . '/' . Http::post('name') . '.yaml')
|
||||
) {
|
||||
Notification::set('success', __('admin_message_menu_renamed'));
|
||||
Http::redirect(Http::getBaseUrl() . '/admin/menus');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
|
||||
Themes::view('admin/views/templates/extends/menus/rename')
|
||||
->assign('name_current', Http::get('menu'))
|
||||
->display();
|
||||
break;
|
||||
case 'duplicate':
|
||||
if (Http::get('menu') != '') {
|
||||
if (Token::check((Http::get('token')))) {
|
||||
Filesystem::copy(PATH['menus'] . '/' . Http::get('menu') . '.yaml',
|
||||
PATH['menus'] . '/' . Http::get('menu') . '-duplicate-' . date("Ymd_His") . '.yaml');
|
||||
Notification::set('success', __('admin_message_menu_duplicated'));
|
||||
Http::redirect(Http::getBaseUrl().'/admin/menus');
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'edit':
|
||||
$action = Http::post('action');
|
||||
|
||||
if (isset($action) && $action == 'save-form') {
|
||||
if (Token::check((Http::post('token')))) {
|
||||
|
||||
// Save a menu!
|
||||
if (Filesystem::setFileContent(
|
||||
PATH['menus'] . '/' . Http::post('name') . '.yaml',
|
||||
Http::post('menu')
|
||||
)) {
|
||||
Notification::set('success', __('admin_message_menu_saved'));
|
||||
Http::redirect(Http::getBaseUrl() . '/admin/menus/edit?menu=' . Http::post('name'));
|
||||
}
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
|
||||
Themes::view('admin/views/templates/extends/menus/edit')
|
||||
->assign('menu', Filesystem::getFileContent(PATH['menus'] . '/' . Http::get('menu') . '.yaml'))
|
||||
->display();
|
||||
break;
|
||||
default:
|
||||
$menus = [];
|
||||
$menus_list = [];
|
||||
|
||||
$menus = Filesystem::getFilesList(PATH['menus'], 'yaml');
|
||||
|
||||
if (count($menus) > 0) {
|
||||
foreach ($menus as $menu) {
|
||||
$menus_list[basename($menu, '.yaml')] = YamlParser::decode(Filesystem::getFileContent($menu));
|
||||
}
|
||||
}
|
||||
|
||||
Themes::view('admin/views/templates/extends/menus/list')
|
||||
->assign('menus_list', $menus_list)
|
||||
->display();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Registry\Registry;
|
||||
|
||||
class NavigationManager
|
||||
{
|
||||
public static function addItem(string $area, string $item, string $title, string $link, array $attributes = [])
|
||||
{
|
||||
Registry::set("admin_navigation.{$area}.{$item}.area", $area);
|
||||
Registry::set("admin_navigation.{$area}.{$item}.item", $item);
|
||||
Registry::set("admin_navigation.{$area}.{$item}.title", $title);
|
||||
Registry::set("admin_navigation.{$area}.{$item}.link", $link);
|
||||
Registry::set("admin_navigation.{$area}.{$item}.attributes", $attributes);
|
||||
}
|
||||
|
||||
public static function getItems(string $area)
|
||||
{
|
||||
return Registry::get("admin_navigation.{$area}");
|
||||
}
|
||||
}
|
@@ -1,45 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Arr\Arr;
|
||||
use Flextype\Component\Http\Http;
|
||||
use Flextype\Component\Event\Event;
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
use Flextype\Component\Registry\Registry;
|
||||
use Flextype\Component\Token\Token;
|
||||
|
||||
|
||||
class PluginsManager
|
||||
{
|
||||
|
||||
/**
|
||||
* _pluginsChangeStatusAjax
|
||||
*/
|
||||
public static function _pluginsChangeStatusAjax()
|
||||
{
|
||||
if (Http::post('plugin_change_status')) {
|
||||
if (Token::check((Http::post('token')))) {
|
||||
$plugin_settings = YamlParser::decode(Filesystem::getFileContent(PATH['plugins'] . '/' . Http::post('plugin') . '/' . 'settings.yaml'));
|
||||
Arr::set($plugin_settings, 'enabled', (Http::post('status') == 'true' ? true : false));
|
||||
Filesystem::setFileContent(PATH['plugins'] . '/' . Http::post('plugin') . '/' . 'settings.yaml', YamlParser::encode($plugin_settings));
|
||||
Cache::clear();
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function getPluginsManager()
|
||||
{
|
||||
Registry::set('sidebar_menu_item', 'plugins');
|
||||
|
||||
Event::addListener('onBeforeRequestShutdown', function () {
|
||||
PluginsManager::_pluginsChangeStatusAjax();
|
||||
});
|
||||
|
||||
Themes::view('admin/views/templates/extends/plugins/list')
|
||||
->assign('plugins_list', Registry::get('plugins'))
|
||||
->display();
|
||||
}
|
||||
}
|
@@ -1,104 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Arr\Arr;
|
||||
use Flextype\Component\Number\Number;
|
||||
use Flextype\Component\I18n\I18n;
|
||||
use Flextype\Component\Http\Http;
|
||||
use Flextype\Component\Event\Event;
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
use Flextype\Component\Session\Session;
|
||||
use Flextype\Component\Registry\Registry;
|
||||
use Flextype\Component\Token\Token;
|
||||
use Flextype\Component\Text\Text;
|
||||
use Flextype\Component\Form\Form;
|
||||
use Flextype\Component\Notification\Notification;
|
||||
use function Flextype\Component\I18n\__;
|
||||
use Gajus\Dindent\Indenter;
|
||||
|
||||
class SettingsManager
|
||||
{
|
||||
public static function getSettingsManager()
|
||||
{
|
||||
Registry::set('sidebar_menu_item', 'settings');
|
||||
|
||||
// Clear cache
|
||||
if (Http::get('clear_cache')) {
|
||||
if (Token::check((Http::get('token')))) {
|
||||
Cache::clear();
|
||||
Notification::set('success', __('admin_message_cache_files_deleted'));
|
||||
Http::redirect(Http::getBaseUrl().'/admin/settings');
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
|
||||
$action = Http::post('action');
|
||||
|
||||
if (isset($action) && $action == 'save-form') {
|
||||
if (Token::check((Http::post('token')))) {
|
||||
|
||||
$settings = $_POST;
|
||||
|
||||
Arr::delete($settings, 'token');
|
||||
Arr::delete($settings, 'action');
|
||||
Arr::set($settings, 'errors.display', (Http::post('errors.display') == '1' ? true : false));
|
||||
Arr::set($settings, 'cache.enabled', (Http::post('cache.enabled') == '1' ? true : false));
|
||||
Arr::set($settings, 'cache.lifetime', (int) Http::post('cache.lifetime'));
|
||||
Arr::set($settings, 'entries.media.upload_images_quality', (int) Http::post('entries.media.upload_images_quality'));
|
||||
Arr::set($settings, 'entries.media.upload_images_width', (int) Http::post('entries.media.upload_images_width'));
|
||||
Arr::set($settings, 'entries.media.upload_images_height', (int) Http::post('entries.media.upload_images_height'));
|
||||
|
||||
if (Filesystem::setFileContent(PATH['config']['site'] . '/settings.yaml', YamlParser::encode(array_merge(Registry::get('settings'), $settings)))) {
|
||||
Notification::set('success', __('admin_message_settings_saved'));
|
||||
Http::redirect(Http::getBaseUrl().'/admin/settings');
|
||||
}
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
|
||||
$available_locales = Filesystem::getFilesList(PATH['plugins'] . '/admin/languages/', 'yaml');
|
||||
$system_locales = Plugins::getLocales();
|
||||
|
||||
$locales = [];
|
||||
|
||||
foreach ($available_locales as $locale) {
|
||||
$locales[basename($locale, '.yaml')] = $system_locales[basename($locale, '.yaml')];
|
||||
}
|
||||
|
||||
$entries = [];
|
||||
|
||||
foreach (Entries::getEntries('', 'date', 'DESC') as $entry) {
|
||||
$entries[$entry['slug']] = $entry['title'];
|
||||
}
|
||||
|
||||
$themes = [];
|
||||
|
||||
foreach (Filesystem::getDirList(PATH['themes']) as $theme) {
|
||||
$themes[$theme] = $theme;
|
||||
}
|
||||
|
||||
$cache_driver = ['auto' => 'Auto Detect',
|
||||
'file' => 'File',
|
||||
'apc' => 'APC',
|
||||
'apcu' => 'APCu',
|
||||
'wincache' => 'WinCache',
|
||||
'xcache' => 'Xcache',
|
||||
'memcache' => 'Memcache',
|
||||
'memcached' => 'Memcached',
|
||||
'redis' => 'Redis',
|
||||
'sqlite3' => 'SQLite3',
|
||||
'zend' => 'Zend',
|
||||
'array' => 'Array'];
|
||||
|
||||
Themes::view('admin/views/templates/system/settings/list')
|
||||
->assign('settings', Registry::get('settings'))
|
||||
->assign('cache_driver', $cache_driver)
|
||||
->assign('locales', $locales)
|
||||
->assign('entries', $entries)
|
||||
->assign('themes', $themes)
|
||||
->display();
|
||||
}
|
||||
}
|
@@ -1,127 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Registry\Registry;
|
||||
use Flextype\Component\Http\Http;
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
use Flextype\Component\Token\Token;
|
||||
use Flextype\Component\Text\Text;
|
||||
use Flextype\Component\Notification\Notification;
|
||||
use function Flextype\Component\I18n\__;
|
||||
|
||||
class SnippetsManager
|
||||
{
|
||||
public static function getSnippetsManager()
|
||||
{
|
||||
Registry::set('sidebar_menu_item', 'snippets');
|
||||
|
||||
// Create directory for logs
|
||||
!Filesystem::fileExists(PATH['snippets']) and Filesystem::createDir(PATH['snippets']);
|
||||
|
||||
switch (Http::getUriSegment(2)) {
|
||||
case 'add':
|
||||
$create_snippet = Http::post('create_snippet');
|
||||
|
||||
if (isset($create_snippet)) {
|
||||
if (Token::check((Http::post('token')))) {
|
||||
|
||||
$file = PATH['snippets'] . '/' . Text::safeString(Http::post('name'), '-', true) . '.php';
|
||||
|
||||
if (!Filesystem::fileExists($file)) {
|
||||
// Create a snippet!
|
||||
if (Filesystem::setFileContent(
|
||||
$file,
|
||||
""
|
||||
)) {
|
||||
Notification::set('success', __('admin_message_snippet_created'));
|
||||
Http::redirect(Http::getBaseUrl() . '/admin/snippets');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
|
||||
Themes::view('admin/views/templates/extends/snippets/add')
|
||||
->display();
|
||||
break;
|
||||
case 'delete':
|
||||
if (Http::get('snippet') != '') {
|
||||
if (Token::check((Http::get('token')))) {
|
||||
Filesystem::deleteFile(PATH['snippets'] . '/' . Http::get('snippet') . '.php');
|
||||
Notification::set('success', __('admin_message_snippet_deleted'));
|
||||
Http::redirect(Http::getBaseUrl() . '/admin/snippets');
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'rename':
|
||||
$rename_snippet = Http::post('rename_snippet');
|
||||
|
||||
if (isset($rename_snippet)) {
|
||||
if (Token::check((Http::post('token')))) {
|
||||
if (!Filesystem::fileExists(PATH['snippets'] . '/' . Http::post('name') . '.php')) {
|
||||
if (rename(
|
||||
PATH['snippets'] . '/' . Http::post('name_current') . '.php',
|
||||
PATH['snippets'] . '/' . Http::post('name') . '.php')
|
||||
) {
|
||||
Notification::set('success', __('admin_message_snippet_renamed'));
|
||||
Http::redirect(Http::getBaseUrl() . '/admin/snippets');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
|
||||
Themes::view('admin/views/templates/extends/snippets/rename')
|
||||
->assign('name_current', Http::get('snippet'))
|
||||
->display();
|
||||
break;
|
||||
case 'duplicate':
|
||||
if (Http::get('snippet') != '') {
|
||||
if (Token::check((Http::get('token')))) {
|
||||
Filesystem::copy(PATH['snippets'] . '/' . Http::get('snippet') . '.php',
|
||||
PATH['snippets'] . '/' . Http::get('snippet') . '-duplicate-' . date("Ymd_His") . '.php');
|
||||
Notification::set('success', __('admin_message_snippet_duplicated'));
|
||||
Http::redirect(Http::getBaseUrl().'/admin/snippets');
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'edit':
|
||||
$action = Http::post('action');
|
||||
|
||||
if (isset($action) && $action == 'save-form') {
|
||||
if (Token::check((Http::post('token')))) {
|
||||
|
||||
// Save a snippet!
|
||||
if (Filesystem::setFileContent(
|
||||
PATH['snippets'] . '/' . Http::post('name') . '.php',
|
||||
Http::post('snippet')
|
||||
)) {
|
||||
Notification::set('success', __('admin_message_snippet_saved'));
|
||||
Http::redirect(Http::getBaseUrl() . '/admin/snippets/edit?snippet='.Http::post('name'));
|
||||
}
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
|
||||
Themes::view('admin/views/templates/extends/snippets/edit')
|
||||
->assign('snippet', Filesystem::getFileContent(PATH['snippets'] . '/' . Http::get('snippet') . '.php'))
|
||||
->display();
|
||||
break;
|
||||
default:
|
||||
$snippets_list = Filesystem::getFilesList(PATH['snippets'], 'php');
|
||||
|
||||
Themes::view('admin/views/templates/extends/snippets/list')
|
||||
->assign('snippets_list', $snippets_list)
|
||||
->display();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,136 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Registry\Registry;
|
||||
use Flextype\Component\Http\Http;
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
use Flextype\Component\Token\Token;
|
||||
use Flextype\Component\Text\Text;
|
||||
use Flextype\Component\Notification\Notification;
|
||||
use function Flextype\Component\I18n\__;
|
||||
|
||||
class TemplatesManager
|
||||
{
|
||||
public static function getTemplatesManager()
|
||||
{
|
||||
Registry::set('sidebar_menu_item', 'templates');
|
||||
|
||||
switch (Http::getUriSegment(2)) {
|
||||
case 'add':
|
||||
$create_template = Http::post('create_template');
|
||||
|
||||
if (isset($create_template)) {
|
||||
if (Token::check((Http::post('token')))) {
|
||||
|
||||
$type = (Http::post('type') && Http::post('type') == 'partial') ? 'partial' : 'template';
|
||||
|
||||
$file = PATH['themes'] . '/' . Registry::get('settings.theme') . '/views/' . $type . 's' . '/' . Text::safeString(Http::post('name'), '-', true) . '.php';
|
||||
|
||||
if (!Filesystem::fileExists($file)) {
|
||||
// Create a template!
|
||||
if (Filesystem::setFileContent(
|
||||
$file,
|
||||
""
|
||||
)) {
|
||||
Notification::set('success', __('admin_message_template_created'));
|
||||
Http::redirect(Http::getBaseUrl() . '/admin/templates');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
|
||||
Themes::view('admin/views/templates/extends/templates/add')
|
||||
->display();
|
||||
break;
|
||||
case 'delete':
|
||||
if (Http::get('template') != '') {
|
||||
if (Token::check((Http::get('token')))) {
|
||||
$type = (Http::get('type') && Http::get('type') == 'partial') ? 'partial' : 'template';
|
||||
Filesystem::deleteFile(PATH['themes'] . '/' . Registry::get('settings.theme') . '/views/' . $type . 's' . '/' . Http::get('template') . '.php');
|
||||
Notification::set('success', __('admin_message_template_deleted'));
|
||||
Http::redirect(Http::getBaseUrl() . '/admin/templates');
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'rename':
|
||||
$rename_template = Http::post('rename_template');
|
||||
|
||||
if (isset($rename_template)) {
|
||||
if (Token::check((Http::post('token')))) {
|
||||
$type = (Http::post('type') && Http::post('type') == 'partial') ? 'partial' : 'template';
|
||||
$type_current = (Http::post('type_current') && Http::post('type_current') == 'partial') ? 'partial' : 'template';
|
||||
if (!Filesystem::fileExists(PATH['themes'] . '/' . Registry::get('settings.theme') . '/views/' . $type . 's' . '/' . Http::post('name') . '.php')) {
|
||||
if (rename(
|
||||
PATH['themes'] . '/' . Registry::get('settings.theme') . '/views/' . $type_current . 's' . '/' . Http::post('name_current') . '.php',
|
||||
PATH['themes'] . '/' . Registry::get('settings.theme') . '/views/' . $type . 's' . '/' . Http::post('name') . '.php')
|
||||
) {
|
||||
Notification::set('success', __('admin_message_template_renamed'));
|
||||
Http::redirect(Http::getBaseUrl() . '/admin/templates');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
|
||||
Themes::view('admin/views/templates/extends/templates/rename')
|
||||
->assign('name_current', Http::get('template'))
|
||||
->assign('type', ((Http::get('type') && Http::get('type') == 'partial') ? 'partial' : 'template'))
|
||||
->display();
|
||||
break;
|
||||
case 'duplicate':
|
||||
if (Http::get('template') != '') {
|
||||
if (Token::check((Http::get('token')))) {
|
||||
$type = (Http::get('type') && Http::get('type') == 'partial') ? 'partial' : 'template';
|
||||
Filesystem::copy(PATH['themes'] . '/' . Registry::get('settings.theme') . '/views/' . $type . 's' . '/' . Http::get('template') . '.php',
|
||||
PATH['themes'] . '/' . Registry::get('settings.theme') . '/views/' . $type . 's' . '/' . Http::get('template') . '-duplicate-' . date("Ymd_His") . '.php');
|
||||
Notification::set('success', __('admin_message_template_duplicated'));
|
||||
Http::redirect(Http::getBaseUrl().'/admin/templates');
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'edit':
|
||||
$action = Http::post('action');
|
||||
|
||||
if (isset($action) && $action == 'save-form') {
|
||||
if (Token::check((Http::post('token')))) {
|
||||
|
||||
$type = (Http::post('type') && Http::post('type') == 'partial') ? 'partial' : 'template';
|
||||
|
||||
// Save a template!
|
||||
if (Filesystem::setFileContent(
|
||||
PATH['themes'] . '/' . Registry::get('settings.theme') . '/views/' . $type . 's' . '/' . Http::post('name') . '.php',
|
||||
Http::post('template')
|
||||
)) {
|
||||
Notification::set('success', __('admin_message_template_saved'));
|
||||
Http::redirect(Http::getBaseUrl() . '/admin/templates/edit?template=' . Http::post('name') . '&type=' . $type);
|
||||
}
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
|
||||
$type = (Http::get('type') && Http::get('type') == 'partial') ? 'partials' : 'templates';
|
||||
|
||||
Themes::view('admin/views/templates/extends/templates/edit')
|
||||
->assign('template', Filesystem::getFileContent(PATH['themes'] . '/' . Registry::get('settings.theme') . '/views/' . $type . '/' . Http::get('template') . '.php'))
|
||||
->assign('type', ((Http::get('type') && Http::get('type') == 'partial') ? 'partial' : 'template'))
|
||||
->display();
|
||||
break;
|
||||
default:
|
||||
|
||||
Themes::view('admin/views/templates/extends/templates/list')
|
||||
->assign('templates_list', Themes::getTemplates())
|
||||
->assign('partials_list', Themes::getPartials())
|
||||
->display();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,107 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Http\Http;
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
use Flextype\Component\Session\Session;
|
||||
use Flextype\Component\Token\Token;
|
||||
use Flextype\Component\Registry\Registry;
|
||||
use Flextype\Component\Text\Text;
|
||||
use Flextype\Component\Notification\Notification;
|
||||
use function Flextype\Component\I18n\__;
|
||||
|
||||
class UsersManager
|
||||
{
|
||||
|
||||
public static function getProfileManager()
|
||||
{
|
||||
Registry::set('sidebar_menu_item', 'profile');
|
||||
|
||||
Themes::view('admin/views/templates/users/profile')
|
||||
->display();
|
||||
}
|
||||
|
||||
public static function logout()
|
||||
{
|
||||
if (Token::check((Http::get('token')))) {
|
||||
Session::destroy();
|
||||
Http::redirect(Http::getBaseUrl().'/admin');
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
|
||||
public static function getRegistrationPage()
|
||||
{
|
||||
Registry::set('sidebar_menu_item', '');
|
||||
|
||||
$registration = Http::post('registration');
|
||||
|
||||
if (isset($registration)) {
|
||||
if (Token::check((Http::post('token')))) {
|
||||
if (Filesystem::fileExists($_user_file = PATH['site'] . '/accounts/' . Text::safeString(Http::post('username')) . '.yaml')) {
|
||||
} else {
|
||||
Filesystem::setFileContent(
|
||||
PATH['site'] . '/accounts/' . Http::post('username') . '.yaml',
|
||||
YamlParser::encode(['username' => Text::safeString(Http::post('username')),
|
||||
'hashed_password' => password_hash(trim(Http::post('password')), PASSWORD_BCRYPT),
|
||||
'email' => Http::post('email'),
|
||||
'role' => 'admin',
|
||||
'state' => 'enabled'])
|
||||
);
|
||||
|
||||
Http::redirect(Http::getBaseUrl().'/admin/entries');
|
||||
}
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
|
||||
Themes::view('admin/views/templates/auth/registration')
|
||||
->display();
|
||||
}
|
||||
|
||||
public static function isUsersExists()
|
||||
{
|
||||
// Get Users Profiles
|
||||
$users = Filesystem::getFilesList(PATH['site'] . '/accounts/', 'yaml');
|
||||
|
||||
// If any users exists then return true
|
||||
return ($users && count($users) > 0) ? true : false;
|
||||
}
|
||||
|
||||
public static function isLoggedIn()
|
||||
{
|
||||
return (Session::exists('role') && Session::get('role') == 'admin') ? true : false;
|
||||
}
|
||||
|
||||
public static function getAuthPage()
|
||||
{
|
||||
Registry::set('sidebar_menu_item', '');
|
||||
|
||||
$login = Http::post('login');
|
||||
|
||||
if (isset($login)) {
|
||||
if (Token::check((Http::post('token')))) {
|
||||
if (Filesystem::fileExists($_user_file = PATH['site'] . '/accounts/' . Http::post('username') . '.yaml')) {
|
||||
$user_file = YamlParser::decode(Filesystem::getFileContent($_user_file));
|
||||
if (password_verify(trim(Http::post('password')), $user_file['hashed_password'])) {
|
||||
Session::set('username', $user_file['username']);
|
||||
Session::set('role', $user_file['role']);
|
||||
Http::redirect(Http::getBaseUrl().'/admin/entries');
|
||||
} else {
|
||||
Notification::set('error', __('admin_message_wrong_username_password'));
|
||||
}
|
||||
} else {
|
||||
Notification::set('error', __('admin_message_wrong_username_password'));
|
||||
}
|
||||
} else {
|
||||
die('Request was denied because it contained an invalid security token. Please refresh the page and try again.');
|
||||
}
|
||||
}
|
||||
|
||||
Themes::view('admin/views/templates/auth/login')
|
||||
->display();
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user