mirror of
https://github.com/flextype/flextype.git
synced 2025-08-12 08:04:05 +02:00
Merge branch 'element-queries-436' into dev
This commit is contained in:
@@ -1 +0,0 @@
|
||||
{"php":"7.2.20","version":"2.15.0","indent":" ","lineEnding":"\n","rules":{"blank_line_after_namespace":true,"braces":true,"class_definition":true,"elseif":true,"function_declaration":true,"indentation_type":true,"line_ending":true,"lowercase_constants":true,"lowercase_keywords":true,"method_argument_space":{"on_multiline":"ensure_fully_multiline"},"no_break_comment":true,"no_closing_tag":true,"no_spaces_after_function_name":true,"no_spaces_inside_parenthesis":true,"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"single_blank_line_at_eof":true,"single_class_element_per_statement":{"elements":["property"]},"single_import_per_statement":true,"single_line_after_imports":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"visibility_required":true,"encoding":true,"full_opening_tag":true},"hashes":{"vendor\/flextype-components\/arr\/Arr.php":3460238454}}
|
@@ -13,8 +13,9 @@ However, the amount of effort needed to maintain and develop new features for th
|
||||
|
||||
### Backers
|
||||
* Arseni Khramenkin
|
||||
* Roman
|
||||
* Viktoriya Kozyr
|
||||
|
||||
### One-time donations
|
||||
* Viktoriya Kozyr
|
||||
* Alexander Greca
|
||||
* Izabela Sokołowska
|
||||
|
@@ -73,7 +73,10 @@
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"src"
|
||||
"src/flextype"
|
||||
],
|
||||
"files": [
|
||||
"src/flextype/Support/helpers.php"
|
||||
]
|
||||
},
|
||||
"require-dev": {
|
||||
|
@@ -160,6 +160,7 @@ class Cache
|
||||
if ($lifetime === null) {
|
||||
$lifetime = $this->getLifetime();
|
||||
}
|
||||
|
||||
$this->driver->save($id, $data, $lifetime);
|
||||
}
|
||||
|
@@ -9,8 +9,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
use Flextype\Component\Arr\Arr;
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
|
||||
class Config
|
||||
{
|
||||
@@ -50,24 +50,22 @@ class Config
|
||||
/**
|
||||
* Create new config item
|
||||
*
|
||||
* @param string $config Config namespace.
|
||||
* @param string $key The key of the config item to get.
|
||||
* @param mixed $value Value
|
||||
*
|
||||
* @return bool
|
||||
* @param string $config Config namespace.
|
||||
* @param string $key The key of the config item to get.
|
||||
* @param mixed $value Value
|
||||
*/
|
||||
public function create(string $config, string $key, $value) : bool
|
||||
{
|
||||
$config_file = $this->getFileLocation($config);
|
||||
|
||||
if (Filesystem::has($config_file)) {
|
||||
|
||||
$config_file_data = $this->flextype->serializer->decode(Filesystem::read($config_file), 'yaml');
|
||||
|
||||
if (!Arr::keyExists($config_file_data, $key)) {
|
||||
Arr::set($config_file_data, $key, $value);
|
||||
return Filesystem::write($config_file, $this->flextype->serializer->encode($config_file_data, 'yaml'));
|
||||
}
|
||||
if (! Arr::keyExists($config_file_data, $key)) {
|
||||
Arr::set($config_file_data, $key, $value);
|
||||
|
||||
return Filesystem::write($config_file, $this->flextype->serializer->encode($config_file_data, 'yaml'));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -78,24 +76,22 @@ class Config
|
||||
/**
|
||||
* Update config item
|
||||
*
|
||||
* @param string $config Config namespace.
|
||||
* @param string $key The key of the config item to get.
|
||||
* @param mixed $value Value
|
||||
*
|
||||
* @return bool
|
||||
* @param string $config Config namespace.
|
||||
* @param string $key The key of the config item to get.
|
||||
* @param mixed $value Value
|
||||
*/
|
||||
public function update(string $config, string $key, $value) : bool
|
||||
{
|
||||
$config_file = $this->getFileLocation($config);
|
||||
|
||||
if (Filesystem::has($config_file)) {
|
||||
|
||||
$config_file_data = $this->flextype->serializer->decode(Filesystem::read($config_file), 'yaml');
|
||||
|
||||
if (Arr::keyExists($config_file_data, $key)) {
|
||||
Arr::set($config_file_data, $key, $value);
|
||||
return Filesystem::write($config_file, $this->flextype->serializer->encode($config_file_data, 'yaml'));
|
||||
}
|
||||
if (Arr::keyExists($config_file_data, $key)) {
|
||||
Arr::set($config_file_data, $key, $value);
|
||||
|
||||
return Filesystem::write($config_file, $this->flextype->serializer->encode($config_file_data, 'yaml'));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -106,23 +102,21 @@ class Config
|
||||
/**
|
||||
* Delete config item
|
||||
*
|
||||
* @param string $config Config namespace.
|
||||
* @param string $key The key of the config item to get.
|
||||
*
|
||||
* @return bool
|
||||
* @param string $config Config namespace.
|
||||
* @param string $key The key of the config item to get.
|
||||
*/
|
||||
public function delete(string $config, $key) : bool
|
||||
public function delete(string $config, string $key) : bool
|
||||
{
|
||||
$config_file = $this->getFileLocation($config);
|
||||
|
||||
if (Filesystem::has($config_file)) {
|
||||
|
||||
$config_file_data = $this->flextype->serializer->decode(Filesystem::read($config_file), 'yaml');
|
||||
|
||||
if (Arr::keyExists($config_file_data, $key)) {
|
||||
Arr::delete($config_file_data, $key);
|
||||
return Filesystem::write($config_file, $this->flextype->serializer->encode($config_file_data, 'yaml'));
|
||||
}
|
||||
if (Arr::keyExists($config_file_data, $key)) {
|
||||
Arr::delete($config_file_data, $key);
|
||||
|
||||
return Filesystem::write($config_file, $this->flextype->serializer->encode($config_file_data, 'yaml'));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -133,22 +127,19 @@ class Config
|
||||
/**
|
||||
* Checks if an config item with this key name is in the config.
|
||||
*
|
||||
* @param string $config Config namespace.
|
||||
* @param string $key The key of the config item to get.
|
||||
*
|
||||
* @return bool
|
||||
* @param string $config Config namespace.
|
||||
* @param string $key The key of the config item to get.
|
||||
*/
|
||||
public function has(string $config, $key) : bool
|
||||
public function has(string $config, string $key) : bool
|
||||
{
|
||||
$config_file = $this->getFileLocation($config);
|
||||
|
||||
if (Filesystem::has($config_file)) {
|
||||
|
||||
$config_file_data = $this->flextype->serializer->decode(Filesystem::read($config_file), 'yaml');
|
||||
|
||||
if (Arr::keyExists($config_file_data, $key)) {
|
||||
return true;
|
||||
}
|
||||
if (Arr::keyExists($config_file_data, $key)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -159,7 +150,7 @@ class Config
|
||||
/**
|
||||
* Get config file location
|
||||
*
|
||||
* @param string $config Config namespace.
|
||||
* @param string $config Config namespace.
|
||||
*
|
||||
* @return string config file location
|
||||
*
|
||||
@@ -173,7 +164,7 @@ class Config
|
||||
/**
|
||||
* Get config directory location
|
||||
*
|
||||
* @param string $config Config namespace.
|
||||
* @param string $config Config namespace.
|
||||
*
|
||||
* @return string config directory location
|
||||
*
|
70
src/flextype/Foundation/Cors/Cors.php
Normal file
70
src/flextype/Foundation/Cors/Cors.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Flextype (http://flextype.org)
|
||||
* Founded by Sergey Romanenko and maintained by Flextype Community.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use function count;
|
||||
use function implode;
|
||||
|
||||
class Cors
|
||||
{
|
||||
/**
|
||||
* Flextype Dependency Container
|
||||
*/
|
||||
private $flextype;
|
||||
|
||||
|
||||
/**
|
||||
* Flextype app
|
||||
*/
|
||||
private $app;
|
||||
|
||||
/**
|
||||
* __construct
|
||||
*/
|
||||
public function __construct($flextype, $app)
|
||||
{
|
||||
$this->flextype = $flextype;
|
||||
$this->app = $app;
|
||||
}
|
||||
|
||||
/**
|
||||
* Init CORS
|
||||
*/
|
||||
public function init() : void
|
||||
{
|
||||
$flextype = $this->flextype;
|
||||
|
||||
if (! $flextype['registry']->get('flextype.settings.cors.enabled')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->app->options('/{routes:.+}', function ($request, $response, $args) {
|
||||
return $response;
|
||||
});
|
||||
|
||||
$this->app->add(function ($req, $res, $next) use ($flextype) {
|
||||
$response = $next($req, $res);
|
||||
|
||||
// Set variables
|
||||
$origin = $flextype['registry']->get('flextype.settings.cors.origin');
|
||||
$headers = count($flextype['registry']->get('flextype.settings.cors.headers')) ? implode(', ', $flextype['registry']->get('flextype.settings.cors.headers')) : '';
|
||||
$methods = count($flextype['registry']->get('flextype.settings.cors.methods')) ? implode(', ', $flextype['registry']->get('flextype.settings.cors.methods')) : '';
|
||||
$expose = count($flextype['registry']->get('flextype.settings.cors.expose')) ? implode(', ', $flextype['registry']->get('flextype.settings.cors.expose')) : '';
|
||||
$credentials = $flextype['registry']->get('flextype.settings.cors.credentials') ? true : false;
|
||||
|
||||
return $response
|
||||
->withHeader('Access-Control-Allow-Origin', $origin)
|
||||
->withHeader('Access-Control-Allow-Headers', $headers)
|
||||
->withHeader('Access-Control-Allow-Methods', $methods)
|
||||
->withHeader('Access-Control-Allow-Expose', $expose)
|
||||
->withHeader('Access-Control-Allow-Credentials', $credentials);
|
||||
});
|
||||
}
|
||||
}
|
467
src/flextype/Foundation/Entries/Entries.php
Executable file
467
src/flextype/Foundation/Entries/Entries.php
Executable file
@@ -0,0 +1,467 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Flextype (http://flextype.org)
|
||||
* Founded by Sergey Romanenko and maintained by Flextype Community.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Arr\Arr;
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
use Flextype\Component\Session\Session;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use function array_merge;
|
||||
use function count;
|
||||
use function date;
|
||||
use function in_array;
|
||||
use function is_array;
|
||||
use function is_bool;
|
||||
use function ltrim;
|
||||
use function md5;
|
||||
use function rename;
|
||||
use function rtrim;
|
||||
use function str_replace;
|
||||
use function strpos;
|
||||
use function strtotime;
|
||||
use function time;
|
||||
|
||||
class Entries
|
||||
{
|
||||
/**
|
||||
* Current entry data array
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
public $entry = [];
|
||||
|
||||
/**
|
||||
* Current entries data array
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
public $entries = [];
|
||||
|
||||
/**
|
||||
* Entries Visibility
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
public $visibility = [
|
||||
'draft' => 'draft',
|
||||
'hidden' => 'hidden',
|
||||
'visible' => 'visible',
|
||||
];
|
||||
|
||||
/**
|
||||
* Entries system fields
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
public $system_fields = [
|
||||
'published_at' => 'published_at',
|
||||
'published_by' => 'published_by',
|
||||
'created_at' => 'created_at',
|
||||
'modified_at' => 'modified_at',
|
||||
'slug' => 'slug',
|
||||
'routable' => 'routable',
|
||||
'parsers' => 'parsers',
|
||||
'visibility' => 'visibility',
|
||||
];
|
||||
|
||||
/**
|
||||
* Flextype Dependency Container
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private $flextype;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function __construct($flextype)
|
||||
{
|
||||
$this->flextype = $flextype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch entry(entries)
|
||||
*
|
||||
* @param string $path Unique identifier of the entry(entries).
|
||||
* @param array|null $filter Select items in collection by given conditions.
|
||||
*
|
||||
* @return array The entry array data.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function fetch(string $path, ?array $filter = null) : array
|
||||
{
|
||||
// If filter is array then it is entries collection request
|
||||
if (is_array($filter)) {
|
||||
return $this->fetchCollection($path, $filter);
|
||||
}
|
||||
|
||||
return $this->fetchSingle($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch single entry
|
||||
*
|
||||
* @param string $path Unique identifier of the entry(entries).
|
||||
*
|
||||
* @return array The entry array data.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function fetchSingle(string $path) : array
|
||||
{
|
||||
// Get entry file location
|
||||
$entry_file = $this->getFileLocation($path);
|
||||
|
||||
// If requested entry file founded then process it
|
||||
if (Filesystem::has($entry_file)) {
|
||||
// Create unique entry cache_id
|
||||
// Entry Cache ID = entry + entry file + entry file time stamp
|
||||
if ($timestamp = Filesystem::getTimestamp($entry_file)) {
|
||||
$entry_cache_id = md5('entry' . $entry_file . $timestamp);
|
||||
} else {
|
||||
$entry_cache_id = md5('entry' . $entry_file);
|
||||
}
|
||||
|
||||
// Try to get the requested entry from cache
|
||||
if ($this->flextype['cache']->contains($entry_cache_id)) {
|
||||
// Try to fetch requested entry from the cache
|
||||
if ($entry = $this->flextype['cache']->fetch($entry_cache_id)) {
|
||||
// Run event onEntryAfterInitialized
|
||||
$this->flextype['emitter']->emit('onEntryAfterInitialized');
|
||||
|
||||
// Return entry
|
||||
return $entry;
|
||||
}
|
||||
|
||||
// Return empty array
|
||||
return [];
|
||||
|
||||
// else Try to get requested entry from the filesystem
|
||||
}
|
||||
|
||||
$entry_decoded = $this->flextype['serializer']->decode(Filesystem::read($entry_file), 'frontmatter');
|
||||
|
||||
// Add predefined entry items
|
||||
// Entry Published At
|
||||
$entry_decoded['published_at'] = isset($entry_decoded['published_at']) ? (int) strtotime($entry_decoded['published_at']) : (int) Filesystem::getTimestamp($entry_file);
|
||||
|
||||
// Entry Created At
|
||||
$entry_decoded['created_at'] = isset($entry_decoded['created_at']) ? (int) strtotime($entry_decoded['created_at']) : (int) Filesystem::getTimestamp($entry_file);
|
||||
|
||||
// Entry Modified
|
||||
$entry_decoded['modified_at'] = (int) Filesystem::getTimestamp($entry_file);
|
||||
|
||||
// Entry Slug
|
||||
$entry_decoded['slug'] = isset($entry_decoded['slug']) ? (string) $entry_decoded['slug'] : (string) ltrim(rtrim($path, '/'), '/');
|
||||
|
||||
// Entry Routable
|
||||
$entry_decoded['routable'] = isset($entry_decoded['routable']) ? (bool) $entry_decoded['routable'] : true;
|
||||
|
||||
// Entry Visibility
|
||||
if (isset($entry_decoded['visibility']) && in_array($entry_decoded['visibility'], $this->visibility)) {
|
||||
$entry_decoded['visibility'] = (string) $this->visibility[$entry_decoded['visibility']];
|
||||
} else {
|
||||
$entry_decoded['visibility'] = (string) $this->visibility['visible'];
|
||||
}
|
||||
|
||||
// Parsers
|
||||
if (isset($entry_decoded['parsers'])) {
|
||||
foreach ($entry_decoded['parsers'] as $parser_name => $parser_data) {
|
||||
if (! in_array($parser_name, ['markdown', 'shortcodes'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! isset($entry_decoded['parsers'][$parser_name]['enabled']) || $entry_decoded['parsers'][$parser_name]['enabled'] !== true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isset($entry_decoded['parsers'][$parser_name]['cache']) && $entry_decoded['parsers'][$parser_name]['cache'] === true) {
|
||||
$cache = true;
|
||||
} else {
|
||||
$cache = false;
|
||||
}
|
||||
|
||||
if (! isset($entry_decoded['parsers'][$parser_name]['fields'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! is_array($entry_decoded['parsers'][$parser_name]['fields'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($entry_decoded['parsers'][$parser_name]['fields'] as $field) {
|
||||
if (in_array($field, $this->system_fields)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($parser_name === 'markdown') {
|
||||
if (Arr::keyExists($entry_decoded, $field)) {
|
||||
Arr::set($entry_decoded, $field, $this->flextype['parser']->parse(Arr::get($entry_decoded, $field), 'markdown', $cache));
|
||||
}
|
||||
}
|
||||
|
||||
if ($parser_name !== 'shortcodes') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! Arr::keyExists($entry_decoded, $field)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Arr::set($entry_decoded, $field, $this->flextype['parser']->parse(Arr::get($entry_decoded, $field), 'shortcodes', $cache));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Save decoded entry content into the cache
|
||||
$this->flextype['cache']->save($entry_cache_id, $entry_decoded);
|
||||
|
||||
// Set entry to the Entry class property $entry
|
||||
$this->entry = $entry_decoded;
|
||||
|
||||
// Run event onEntryAfterInitialized
|
||||
$this->flextype['emitter']->emit('onEntryAfterInitialized');
|
||||
|
||||
// Return entry from the Entry class property $entry
|
||||
return $this->entry;
|
||||
}
|
||||
|
||||
// Return empty array
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch entries collection
|
||||
*
|
||||
* @param string $path Unique identifier of the entry(entries).
|
||||
* @param array $deep
|
||||
*
|
||||
* @return array The entries array data.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function fetchCollection(string $path, $recursive = false) : array
|
||||
{
|
||||
// Init Entries
|
||||
$entries = [];
|
||||
|
||||
// Init Entries
|
||||
$this->entries = $entries;
|
||||
|
||||
// Get entries path
|
||||
$entries_path = $this->getDirLocation($path);
|
||||
|
||||
// Get entries list
|
||||
$entries_list = Filesystem::listContents($entries_path, $recursive);
|
||||
|
||||
// If entries founded in entries folder
|
||||
if (count($entries_list) > 0) {
|
||||
// Create entries array from entries list and ignore current requested entry
|
||||
foreach ($entries_list as $current_entry) {
|
||||
if (strpos($current_entry['path'], $path . '/entry' . '.' . $this->flextype->registry->get('flextype.settings.entries.extension')) !== false) {
|
||||
// ignore ...
|
||||
} else {
|
||||
// We are checking...
|
||||
// Whether the requested entry is a director and whether the file entry is in this directory.
|
||||
if ($current_entry['type'] === 'dir' && Filesystem::has($current_entry['path'] . '/entry' . '.' . $this->flextype->registry->get('flextype.settings.entries.extension'))) {
|
||||
// Get entry uid
|
||||
// 1. Remove entries path
|
||||
// 2. Remove left and right slashes
|
||||
$uid = ltrim(rtrim(str_replace(PATH['project'] . '/entries/', '', $current_entry['path']), '/'), '/');
|
||||
|
||||
// For each founded entry we should create $entries array.
|
||||
$entry = $this->fetch($uid);
|
||||
|
||||
// Add entry into the entries
|
||||
$entries[$uid] = $entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set entries into the property entries
|
||||
$this->entries = $entries;
|
||||
|
||||
// Run event onEntriesAfterInitialized
|
||||
$this->flextype['emitter']->emit('onEntriesAfterInitialized');
|
||||
}
|
||||
|
||||
// Return entries
|
||||
return $this->entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename entry
|
||||
*
|
||||
* @param string $path Unique identifier of the entry(entries).
|
||||
* @param string $new_id New Unique identifier of the entry(entries).
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function rename(string $path, string $new_id) : bool
|
||||
{
|
||||
if (! Filesystem::has($this->getDirLocation($new_id))) {
|
||||
return rename($this->getDirLocation($path), $this->getDirLocation($new_id));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update entry
|
||||
*
|
||||
* @param string $path Unique identifier of the entry(entries).
|
||||
* @param array $data Data to update for the entry.
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function update(string $path, array $data) : bool
|
||||
{
|
||||
$entry_file = $this->getFileLocation($path);
|
||||
|
||||
if (Filesystem::has($entry_file)) {
|
||||
$body = Filesystem::read($entry_file);
|
||||
$entry = $this->flextype['serializer']->decode($body, 'frontmatter');
|
||||
|
||||
return Filesystem::write($entry_file, $this->flextype['serializer']->encode(array_merge($entry, $data), 'frontmatter'));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create entry
|
||||
*
|
||||
* @param string $path Unique identifier of the entry(entries).
|
||||
* @param array $data Data to create for the entry.
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function create(string $path, array $data) : bool
|
||||
{
|
||||
$entry_dir = $this->getDirLocation($path);
|
||||
|
||||
if (! Filesystem::has($entry_dir)) {
|
||||
// Try to create directory for new entry
|
||||
if (Filesystem::createDir($entry_dir)) {
|
||||
// Check if new entry file exists
|
||||
if (! Filesystem::has($entry_file = $entry_dir . '/entry' . '.' . $this->flextype->registry->get('flextype.settings.entries.extension'))) {
|
||||
$data['uuid'] = Uuid::uuid4()->toString();
|
||||
$data['published_at'] = date($this->flextype->registry->get('flextype.settings.date_format'), time());
|
||||
$data['created_at'] = date($this->flextype->registry->get('flextype.settings.date_format'), time());
|
||||
$data['published_by'] = (Session::exists('uuid') ? Session::get('uuid') : '');
|
||||
$data['created_by'] = (Session::exists('uuid') ? Session::get('uuid') : '');
|
||||
|
||||
if (isset($data['routable']) && is_bool($data['routable'])) {
|
||||
$data['routable'] = $data['routable'];
|
||||
} else {
|
||||
$data['routable'] = true;
|
||||
}
|
||||
|
||||
if (isset($data['visibility']) && in_array($data['visibility'], $this->visibility)) {
|
||||
$data['visibility'] = $data['visibility'];
|
||||
} else {
|
||||
$data['visibility'] = 'visible';
|
||||
}
|
||||
|
||||
return Filesystem::write($entry_file, $this->flextype['serializer']->encode($data, 'frontmatter'));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete entry
|
||||
*
|
||||
* @param string $path Unique identifier of the entry(entries).
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function delete(string $path) : bool
|
||||
{
|
||||
return Filesystem::deleteDir($this->getDirLocation($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy entry(s)
|
||||
*
|
||||
* @param string $path Unique identifier of the entry(entries).
|
||||
* @param string $new_id New Unique identifier of the entry(entries).
|
||||
* @param bool $recursive Recursive copy entries.
|
||||
*
|
||||
* @return bool|null True on success, false on failure.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function copy(string $path, string $new_id, bool $recursive = false) : ?bool
|
||||
{
|
||||
return Filesystem::copy($this->getDirLocation($path), $this->getDirLocation($new_id), $recursive);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether entry exists
|
||||
*
|
||||
* @param string $path Unique identifier of the entry(entries).
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function has(string $path) : bool
|
||||
{
|
||||
return Filesystem::has($this->getFileLocation($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get entry file location
|
||||
*
|
||||
* @param string $path Unique identifier of the entry(entries).
|
||||
*
|
||||
* @return string entry file location
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
public function getFileLocation(string $path) : string
|
||||
{
|
||||
return PATH['project'] . '/entries/' . $path . '/entry' . '.' . $this->flextype->registry->get('flextype.settings.entries.extension');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get entry directory location
|
||||
*
|
||||
* @param string $path Unique identifier of the entry(entries).
|
||||
*
|
||||
* @return string entry directory location
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
public function getDirLocation(string $path) : string
|
||||
{
|
||||
return PATH['project'] . '/entries/' . $path;
|
||||
}
|
||||
}
|
@@ -10,10 +10,19 @@ declare(strict_types=1);
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
use Flextype\Component\Arr\Arr;
|
||||
use Intervention\Image\ImageManagerStatic as Image;
|
||||
use Slim\Http\Environment;
|
||||
use Slim\Http\Uri;
|
||||
use function in_array;
|
||||
use function is_uploaded_file;
|
||||
use function mime_content_type;
|
||||
use function pathinfo;
|
||||
use function strpos;
|
||||
use function strtolower;
|
||||
use const PATHINFO_EXTENSION;
|
||||
use const UPLOAD_ERR_INI_SIZE;
|
||||
use const UPLOAD_ERR_OK;
|
||||
use function getimagesize;
|
||||
|
||||
class MediaFiles
|
||||
{
|
||||
@@ -44,7 +53,7 @@ class MediaFiles
|
||||
*/
|
||||
public function upload(array $file, string $folder)
|
||||
{
|
||||
$upload_folder = PATH['project'] . '/uploads/' . $folder . '/';
|
||||
$upload_folder = PATH['project'] . '/uploads/' . $folder . '/';
|
||||
$upload_metadata_folder = PATH['project'] . '/uploads/.meta/' . $folder . '/';
|
||||
|
||||
if (! Filesystem::has($upload_folder)) {
|
||||
@@ -56,93 +65,94 @@ class MediaFiles
|
||||
}
|
||||
|
||||
$accept_file_types = $this->flextype['registry']->get('flextype.settings.media.accept_file_types');
|
||||
$max_file_size = $this->flextype['registry']->get('flextype.settings.media.max_file_size');
|
||||
$safe_names = $this->flextype['registry']->get('flextype.settings.media.safe_names');
|
||||
$max_image_width = $this->flextype['registry']->get('flextype.settings.media.max_image_width');
|
||||
$max_image_height = $this->flextype['registry']->get('flextype.settings.media.max_image_height');
|
||||
$max_file_size = $this->flextype['registry']->get('flextype.settings.media.max_file_size');
|
||||
$safe_names = $this->flextype['registry']->get('flextype.settings.media.safe_names');
|
||||
$max_image_width = $this->flextype['registry']->get('flextype.settings.media.max_image_width');
|
||||
$max_image_height = $this->flextype['registry']->get('flextype.settings.media.max_image_height');
|
||||
|
||||
$exact = false;
|
||||
$chmod = 0644;
|
||||
$filename = null;
|
||||
$exact = false;
|
||||
$chmod = 0644;
|
||||
$filename = null;
|
||||
$exif_data = [];
|
||||
|
||||
//
|
||||
// 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($accept_file_types, 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)
|
||||
if (($file['error'] !== UPLOAD_ERR_INI_SIZE)
|
||||
and ($file['error'] === UPLOAD_ERR_OK)
|
||||
and ($file['size'] <= $max_file_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_image_width, $max_image_height, $exact)
|
||||
{
|
||||
try {
|
||||
// Get the width and height from the uploaded image
|
||||
list($width, $height) = getimagesize($file['tmp_name']);
|
||||
[$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_image_width) {
|
||||
|
||||
if (! $max_image_width) {
|
||||
// No limit, use the image width
|
||||
$max_image_width = $width;
|
||||
}
|
||||
if (!$max_image_height) {
|
||||
|
||||
if (! $max_image_height) {
|
||||
// No limit, use the image height
|
||||
$max_image_height = $height;
|
||||
}
|
||||
|
||||
if ($exact) {
|
||||
// Check if dimensions match exactly
|
||||
return ($width === $max_image_width and $height === $max_image_height);
|
||||
return $width === $max_image_width and $height === $max_image_height;
|
||||
} else {
|
||||
// Check if size is within maximum dimensions
|
||||
return ($width <= $max_image_width and $height <= $max_image_height);
|
||||
return $width <= $max_image_width and $height <= $max_image_height;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (validateImage($file, $max_image_width, $max_image_height, $exact) === false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!isset($file['tmp_name']) or !is_uploaded_file($file['tmp_name'])) {
|
||||
|
||||
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 ($safe_names === true) {
|
||||
// Remove spaces from the filename
|
||||
$filename = $this->flextype['slugify']->slugify(pathinfo($filename)['filename']) . '.' . pathinfo($filename)['extension'];
|
||||
}
|
||||
if (!is_dir($upload_folder) or !is_writable(realpath($upload_folder))) {
|
||||
|
||||
if (! is_dir($upload_folder) or ! is_writable(realpath($upload_folder))) {
|
||||
throw new \RuntimeException("Directory {$upload_folder} must be writable");
|
||||
}
|
||||
|
||||
// Make the filename into a complete path
|
||||
$filename = realpath($upload_folder) . DIRECTORY_SEPARATOR . $filename;
|
||||
if (move_uploaded_file($file['tmp_name'], $filename)) {
|
||||
@@ -155,17 +165,17 @@ class MediaFiles
|
||||
|
||||
// now you are able to resize the instance
|
||||
if ($this->flextype['registry']->get('plugins.admin.settings.entries.media.upload_images_width') > 0 && $this->flextype['registry']->get('plugins.admin.settings.entries.media.upload_images_height') > 0) {
|
||||
$img->resize($this->flextype['registry']->get('plugins.admin.settings.entries.media.upload_images_width'), $this->flextype['registry']->get('plugins.admin.settings.entries.media.upload_images_height'), function($constraint) {
|
||||
$img->resize($this->flextype['registry']->get('plugins.admin.settings.entries.media.upload_images_width'), $this->flextype['registry']->get('plugins.admin.settings.entries.media.upload_images_height'), static function ($constraint) : void {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
});
|
||||
} elseif ($this->flextype['registry']->get('plugins.admin.settings.entries.media.upload_images_width') > 0) {
|
||||
$img->resize($this->flextype['registry']->get('plugins.admin.settings.entries.media.upload_images_width'), null, function($constraint) {
|
||||
$img->resize($this->flextype['registry']->get('plugins.admin.settings.entries.media.upload_images_width'), null, static function ($constraint) : void {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
});
|
||||
} elseif ($this->flextype['registry']->get('plugins.admin.settings.entries.media.upload_images_height') > 0) {
|
||||
$img->resize(null, $this->flextype['registry']->get('plugins.admin.settings.entries.media.upload_images_height'), function($constraint) {
|
||||
$img->resize(null, $this->flextype['registry']->get('plugins.admin.settings.entries.media.upload_images_height'), static function ($constraint) : void {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
});
|
||||
@@ -186,16 +196,19 @@ class MediaFiles
|
||||
}
|
||||
}
|
||||
|
||||
$metadata = ['title' => substr(basename($filename), 0, strrpos(basename($filename), '.')),
|
||||
'description' => '',
|
||||
'type' => mime_content_type($filename),
|
||||
'filesize' => Filesystem::getSize($filename),
|
||||
'uploaded_on' => time(),
|
||||
'exif' => $exif_data];
|
||||
|
||||
Filesystem::write($upload_metadata_folder . basename($filename) . '.yaml',
|
||||
$this->flextype['serializer']->encode($metadata, 'yaml'));
|
||||
$metadata = [
|
||||
'title' => substr(basename($filename), 0, strrpos(basename($filename), '.')),
|
||||
'description' => '',
|
||||
'type' => mime_content_type($filename),
|
||||
'filesize' => Filesystem::getSize($filename),
|
||||
'uploaded_on' => time(),
|
||||
'exif' => $exif_data,
|
||||
];
|
||||
|
||||
Filesystem::write(
|
||||
$upload_metadata_folder . basename($filename) . '.yaml',
|
||||
$this->flextype['serializer']->encode($metadata, 'yaml')
|
||||
);
|
||||
|
||||
// Return new file path
|
||||
return $filename;
|
||||
@@ -241,14 +254,14 @@ class MediaFiles
|
||||
if (Filesystem::has($this->flextype['media_files_meta']->getFileMetaLocation($path))) {
|
||||
$result = $this->flextype['serializer']->decode(Filesystem::read($this->flextype['media_files_meta']->getFileMetaLocation($path)), 'yaml');
|
||||
|
||||
$result['filename'] = pathinfo(str_replace("/.meta", "", $this->flextype['media_files_meta']->getFileMetaLocation($path)))['filename'];
|
||||
$result['basename'] = explode(".", basename($this->flextype['media_files_meta']->getFileMetaLocation($path)))[0];
|
||||
$result['filename'] = pathinfo(str_replace('/.meta', '', $this->flextype['media_files_meta']->getFileMetaLocation($path)))['filename'];
|
||||
$result['basename'] = explode('.', basename($this->flextype['media_files_meta']->getFileMetaLocation($path)))[0];
|
||||
$result['extension'] = ltrim(strstr($path, '.'), '.');
|
||||
$result['dirname'] = pathinfo(str_replace("/.meta", "", $this->flextype['media_files_meta']->getFileMetaLocation($path)))['dirname'];
|
||||
$result['dirname'] = pathinfo(str_replace('/.meta', '', $this->flextype['media_files_meta']->getFileMetaLocation($path)))['dirname'];
|
||||
|
||||
$result['url'] = 'project/uploads/' . $path;
|
||||
|
||||
if ($this->flextype['registry']->has('flextype.settings.url') && $this->flextype['registry']->get('flextype.settings.url') != '') {
|
||||
if ($this->flextype['registry']->has('flextype.settings.url') && $this->flextype['registry']->get('flextype.settings.url') !== '') {
|
||||
$full_url = $this->flextype['registry']->get('flextype.settings.url');
|
||||
} else {
|
||||
$full_url = Uri::createFromEnvironment(new Environment($_SERVER))->getBaseUrl();
|
||||
@@ -274,14 +287,14 @@ class MediaFiles
|
||||
foreach (Filesystem::listContents($this->flextype['media_folders_meta']->getDirMetaLocation($path)) as $file) {
|
||||
$result[$file['basename']] = $this->flextype['serializer']->decode(Filesystem::read($file['path']), 'yaml');
|
||||
|
||||
$result[$file['basename']]['filename'] = pathinfo(str_replace("/.meta", "", $this->flextype['media_files_meta']->getFileMetaLocation($file['basename'])))['filename'];
|
||||
$result[$file['basename']]['basename'] = explode(".", basename($this->flextype['media_files_meta']->getFileMetaLocation($file['basename'])))[0];
|
||||
$result[$file['basename']]['filename'] = pathinfo(str_replace('/.meta', '', $this->flextype['media_files_meta']->getFileMetaLocation($file['basename'])))['filename'];
|
||||
$result[$file['basename']]['basename'] = explode('.', basename($this->flextype['media_files_meta']->getFileMetaLocation($file['basename'])))[0];
|
||||
$result[$file['basename']]['extension'] = ltrim(strstr($file['basename'], '.'), '.');
|
||||
$result[$file['basename']]['dirname'] = pathinfo(str_replace("/.meta", "", $file['path']))['dirname'];
|
||||
$result[$file['basename']]['dirname'] = pathinfo(str_replace('/.meta', '', $file['path']))['dirname'];
|
||||
|
||||
$result[$file['basename']]['url'] = 'project/uploads/' . $path . '/' . $file['basename'];
|
||||
|
||||
if ($this->flextype['registry']->has('flextype.settings.url') && $this->flextype['registry']->get('flextype.settings.url') != '') {
|
||||
if ($this->flextype['registry']->has('flextype.settings.url') && $this->flextype['registry']->get('flextype.settings.url') !== '') {
|
||||
$full_url = $this->flextype['registry']->get('flextype.settings.url');
|
||||
} else {
|
||||
$full_url = Uri::createFromEnvironment(new Environment($_SERVER))->getBaseUrl();
|
||||
@@ -305,15 +318,11 @@ class MediaFiles
|
||||
*/
|
||||
public function rename(string $id, string $new_id) : bool
|
||||
{
|
||||
if (!Filesystem::has($this->getFileLocation($new_id)) && !Filesystem::has($this->flextype['media_files_meta']->getFileMetaLocation($new_id))) {
|
||||
if (rename($this->getFileLocation($id), $this->getFileLocation($new_id)) && rename($this->flextype['media_files_meta']->getFileMetaLocation($id), $this->flextype['media_files_meta']->getFileMetaLocation($new_id))) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
if (! Filesystem::has($this->getFileLocation($new_id)) && ! Filesystem::has($this->flextype['media_files_meta']->getFileMetaLocation($new_id))) {
|
||||
return rename($this->getFileLocation($id), $this->getFileLocation($new_id)) && rename($this->flextype['media_files_meta']->getFileMetaLocation($id), $this->flextype['media_files_meta']->getFileMetaLocation($new_id));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -325,7 +334,7 @@ class MediaFiles
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function delete(string $id)
|
||||
public function delete(string $id) : bool
|
||||
{
|
||||
Filesystem::delete($this->getFileLocation($id));
|
||||
Filesystem::delete($this->flextype['media_files_meta']->getFileMetaLocation($id));
|
@@ -9,11 +9,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
use Flextype\Component\Arr\Arr;
|
||||
use Intervention\Image\ImageManagerStatic as Image;
|
||||
use Slim\Http\Environment;
|
||||
use Slim\Http\Uri;
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
|
||||
class MediaFilesMeta
|
||||
{
|
||||
@@ -51,6 +48,7 @@ class MediaFilesMeta
|
||||
|
||||
if (Arr::keyExists($file_data, $field)) {
|
||||
Arr::set($file_data, $field, $value);
|
||||
|
||||
return Filesystem::write($this->getFileMetaLocation($id), $this->flextype['serializer']->encode($file_data, 'yaml'));
|
||||
}
|
||||
|
||||
@@ -72,8 +70,9 @@ class MediaFilesMeta
|
||||
{
|
||||
$file_data = $this->flextype['serializer']->decode(Filesystem::read($this->getFileMetaLocation($id)), 'yaml');
|
||||
|
||||
if (!Arr::keyExists($file_data, $field)) {
|
||||
if (! Arr::keyExists($file_data, $field)) {
|
||||
Arr::set($file_data, $field, $value);
|
||||
|
||||
return Filesystem::write($this->getFileMetaLocation($id), $this->flextype['serializer']->encode($file_data, 'yaml'));
|
||||
}
|
||||
|
||||
@@ -96,6 +95,7 @@ class MediaFilesMeta
|
||||
|
||||
if (Arr::keyExists($file_data, $field)) {
|
||||
Arr::delete($file_data, $field);
|
||||
|
||||
return Filesystem::write($this->getFileMetaLocation($id), $this->flextype['serializer']->encode($file_data, 'yaml'));
|
||||
}
|
||||
|
@@ -10,10 +10,10 @@ declare(strict_types=1);
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
use Flextype\Component\Arr\Arr;
|
||||
use Intervention\Image\ImageManagerStatic as Image;
|
||||
use Slim\Http\Environment;
|
||||
use Slim\Http\Uri;
|
||||
use function rename;
|
||||
use function str_replace;
|
||||
|
||||
class MediaFolders
|
||||
{
|
||||
@@ -44,9 +44,9 @@ class MediaFolders
|
||||
*/
|
||||
public function fetch(string $path, string $mode = 'collection') : array
|
||||
{
|
||||
if ($mode == 'collection') {
|
||||
if ($mode === 'collection') {
|
||||
$result = $this->fetchCollection($path);
|
||||
} elseif ($mode == 'single') {
|
||||
} elseif ($mode === 'single') {
|
||||
$result = $this->fetchSingle($path);
|
||||
}
|
||||
|
||||
@@ -65,12 +65,11 @@ class MediaFolders
|
||||
$result = [];
|
||||
|
||||
if (Filesystem::has($this->flextype['media_folders_meta']->getDirMetaLocation($path))) {
|
||||
$result['path'] = $path;
|
||||
$result['full_path'] = str_replace('/.meta', '', $this->flextype['media_folders_meta']->getDirMetaLocation($path));
|
||||
$result['url'] = 'project/uploads/' . $path;
|
||||
|
||||
$result['path'] = $path;
|
||||
$result['full_path'] = str_replace("/.meta", "", $this->flextype['media_folders_meta']->getDirMetaLocation($path));
|
||||
$result['url'] = 'project/uploads/' . $path;
|
||||
|
||||
if ($this->flextype['registry']->has('flextype.settings.url') && $this->flextype['registry']->get('flextype.settings.url') != '') {
|
||||
if ($this->flextype['registry']->has('flextype.settings.url') && $this->flextype['registry']->get('flextype.settings.url') !== '') {
|
||||
$full_url = $this->flextype['registry']->get('flextype.settings.url');
|
||||
} else {
|
||||
$full_url = Uri::createFromEnvironment(new Environment($_SERVER))->getBaseUrl();
|
||||
@@ -94,25 +93,25 @@ class MediaFolders
|
||||
$result = [];
|
||||
|
||||
foreach (Filesystem::listContents($this->flextype['media_folders_meta']->getDirMetaLocation($path)) as $folder) {
|
||||
if ($folder['type'] == 'dir') {
|
||||
|
||||
$result[$folder['dirname']]['full_path'] = str_replace("/.meta", "", $this->flextype['media_folders_meta']->getDirMetaLocation($folder['dirname']));
|
||||
$result[$folder['dirname']]['url'] = 'project/uploads/' . $folder['dirname'];
|
||||
|
||||
if ($this->flextype['registry']->has('flextype.settings.url') && $this->flextype['registry']->get('flextype.settings.url') != '') {
|
||||
$full_url = $this->flextype['registry']->get('flextype.settings.url');
|
||||
} else {
|
||||
$full_url = Uri::createFromEnvironment(new Environment($_SERVER))->getBaseUrl();
|
||||
}
|
||||
|
||||
$result[$folder['dirname']]['full_url'] = $full_url . '/project/uploads/' . $folder['dirname'];
|
||||
if ($folder['type'] !== 'dir') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$result[$folder['dirname']]['full_path'] = str_replace('/.meta', '', $this->flextype['media_folders_meta']->getDirMetaLocation($folder['dirname']));
|
||||
$result[$folder['dirname']]['url'] = 'project/uploads/' . $folder['dirname'];
|
||||
|
||||
if ($this->flextype['registry']->has('flextype.settings.url') && $this->flextype['registry']->get('flextype.settings.url') !== '') {
|
||||
$full_url = $this->flextype['registry']->get('flextype.settings.url');
|
||||
} else {
|
||||
$full_url = Uri::createFromEnvironment(new Environment($_SERVER))->getBaseUrl();
|
||||
}
|
||||
|
||||
$result[$folder['dirname']]['full_url'] = $full_url . '/project/uploads/' . $folder['dirname'];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create folder
|
||||
*
|
||||
@@ -124,15 +123,11 @@ class MediaFolders
|
||||
*/
|
||||
public function create(string $id) : bool
|
||||
{
|
||||
if (!Filesystem::has($this->getDirLocation($id)) && !Filesystem::has($this->flextype['media_folders_meta']->getDirMetaLocation($id))) {
|
||||
if (Filesystem::createDir($this->getDirLocation($id)) && Filesystem::createDir($this->flextype['media_folders_meta']->getDirMetaLocation($id))) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
if (! Filesystem::has($this->getDirLocation($id)) && ! Filesystem::has($this->flextype['media_folders_meta']->getDirMetaLocation($id))) {
|
||||
return Filesystem::createDir($this->getDirLocation($id)) && Filesystem::createDir($this->flextype['media_folders_meta']->getDirMetaLocation($id));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -147,15 +142,11 @@ class MediaFolders
|
||||
*/
|
||||
public function rename(string $id, string $new_id) : bool
|
||||
{
|
||||
if (!Filesystem::has($this->getDirLocation($new_id)) && !Filesystem::has($this->flextype['media_folders_meta']->getDirMetaLocation($new_id))) {
|
||||
if (rename($this->getDirLocation($id), $this->getDirLocation($new_id)) && rename($this->flextype['media_folders_meta']->getDirMetaLocation($id), $this->flextype['media_folders_meta']->getDirMetaLocation($new_id))) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
if (! Filesystem::has($this->getDirLocation($new_id)) && ! Filesystem::has($this->flextype['media_folders_meta']->getDirMetaLocation($new_id))) {
|
||||
return rename($this->getDirLocation($id), $this->getDirLocation($new_id)) && rename($this->flextype['media_folders_meta']->getDirMetaLocation($id), $this->flextype['media_folders_meta']->getDirMetaLocation($new_id));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -167,7 +158,7 @@ class MediaFolders
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function delete(string $id)
|
||||
public function delete(string $id) : bool
|
||||
{
|
||||
Filesystem::deleteDir($this->getDirLocation($id));
|
||||
Filesystem::deleteDir($this->flextype['media_folders_meta']->getDirMetaLocation($id));
|
@@ -86,22 +86,22 @@ class Parser
|
||||
}
|
||||
|
||||
break;
|
||||
case 'shortcodes':
|
||||
if ($cache === true && $this->flextype['registry']->get('flextype.settings.cache.enabled') === true) {
|
||||
$key = md5($input);
|
||||
case 'shortcodes':
|
||||
if ($cache === true && $this->flextype['registry']->get('flextype.settings.cache.enabled') === true) {
|
||||
$key = md5($input);
|
||||
|
||||
if ($data_from_cache = $this->flextype['cache']->fetch($key)) {
|
||||
return $data_from_cache;
|
||||
}
|
||||
|
||||
$data = $this->flextype['shortcodes']->process($input);
|
||||
$this->flextype['cache']->save($key, $data);
|
||||
|
||||
return $data;
|
||||
} else {
|
||||
return $this->flextype['shortcodes']->process($input);
|
||||
if ($data_from_cache = $this->flextype['cache']->fetch($key)) {
|
||||
return $data_from_cache;
|
||||
}
|
||||
|
||||
$data = $this->flextype['shortcodes']->process($input);
|
||||
$this->flextype['cache']->save($key, $data);
|
||||
|
||||
return $data;
|
||||
} else {
|
||||
return $this->flextype['shortcodes']->process($input);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
// code...
|
@@ -14,9 +14,9 @@ use Slim\Http\Uri;
|
||||
|
||||
// Shortcode: [url]
|
||||
$flextype['shortcodes']->addHandler('url', static function () use ($flextype) {
|
||||
if ($flextype['registry']->has('flextype.settings.url') && $flextype['registry']->get('flextype.settings.url') != '') {
|
||||
if ($flextype['registry']->has('flextype.settings.url') && $flextype['registry']->get('flextype.settings.url') !== '') {
|
||||
return $flextype['registry']->get('flextype.settings.url');
|
||||
} else {
|
||||
return Uri::createFromEnvironment(new Environment($_SERVER))->getBaseUrl();
|
||||
}
|
||||
|
||||
return Uri::createFromEnvironment(new Environment($_SERVER))->getBaseUrl();
|
||||
});
|
@@ -9,12 +9,12 @@ declare(strict_types=1);
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Composer\Semver\Semver;
|
||||
use Flextype\Component\Arr\Arr;
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
use Flextype\Component\I18n\I18n;
|
||||
use Composer\Semver\Comparator;
|
||||
use Composer\Semver\Semver;
|
||||
use RuntimeException;
|
||||
use function array_diff_key;
|
||||
use function array_replace_recursive;
|
||||
use function count;
|
||||
use function filemtime;
|
||||
@@ -94,19 +94,17 @@ class Plugins
|
||||
$dictionary = $this->getPluginsDictionary($plugins_list, $locale);
|
||||
$this->flextype['cache']->save($locale, $dictionary[$locale]);
|
||||
}
|
||||
|
||||
} else {
|
||||
// Init plugin configs
|
||||
$plugins = [];
|
||||
$plugin_settings = [];
|
||||
$plugin_manifest = [];
|
||||
$default_plugin_settings = [];
|
||||
$project_plugin_settings = [];
|
||||
$project_plugin_settings = [];
|
||||
$default_plugin_manifest = [];
|
||||
|
||||
// Go through...
|
||||
foreach ($plugins_list as $plugin) {
|
||||
|
||||
// Set plugin settings directory
|
||||
$project_plugin_settings_dir = PATH['project'] . '/config/plugins/' . $plugin['dirname'];
|
||||
|
||||
@@ -156,7 +154,6 @@ class Plugins
|
||||
|
||||
// Check if is not set plugin priority
|
||||
if (! isset($plugins[$plugin['dirname']]['settings']['priority'])) {
|
||||
|
||||
// Set default plugin priority = 1
|
||||
$plugins[$plugin['dirname']]['settings']['priority'] = 100;
|
||||
}
|
||||
@@ -183,7 +180,6 @@ class Plugins
|
||||
// Save plugins dictionary
|
||||
$dictionary = $this->getPluginsDictionary($plugins_list, $locale);
|
||||
$this->flextype['cache']->save($locale, $dictionary[$locale]);
|
||||
|
||||
}
|
||||
|
||||
$this->includeEnabledPlugins($flextype, $app);
|
||||
@@ -260,9 +256,8 @@ class Plugins
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function getValidPluginsDependencies($plugins) : array
|
||||
public function getValidPluginsDependencies(array $plugins) : array
|
||||
{
|
||||
|
||||
// Set verified plugins array
|
||||
$verified_plugins = [];
|
||||
|
||||
@@ -271,55 +266,55 @@ class Plugins
|
||||
|
||||
// Go through plugins list and verify them.
|
||||
foreach ($plugins as $plugin_name => &$plugin_data) {
|
||||
|
||||
// Set verified true by default
|
||||
$verified = true;
|
||||
|
||||
// If there is any dependencies for this plugin
|
||||
if (isset($plugin_data['manifest']['dependencies'])) {
|
||||
|
||||
// Go through plugin dependencies
|
||||
foreach ($plugin_data['manifest']['dependencies'] as $dependency => $constraints) {
|
||||
|
||||
// Verify flextype version
|
||||
if ($dependency === 'flextype') {
|
||||
if (!Semver::satisfies($this->flextype['registry']->get('flextype.manifest.version'), $constraints)) {
|
||||
if (! Semver::satisfies($this->flextype['registry']->get('flextype.manifest.version'), $constraints)) {
|
||||
$verified = false;
|
||||
|
||||
// Remove plugin where it is require this dependency
|
||||
foreach ($plugins as $_plugin_name => $_plugin_data) {
|
||||
if ($_plugin_data['manifest']['dependencies'][$plugin_name]) {
|
||||
unset($plugins[$_plugin_name]);
|
||||
unset($verified_plugins[$_plugin_name]);
|
||||
if (! $_plugin_data['manifest']['dependencies'][$plugin_name]) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
unset($plugins[$_plugin_name]);
|
||||
unset($verified_plugins[$_plugin_name]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Verify plugin dependencies
|
||||
if (!isset($plugins[$dependency])) {
|
||||
if (! isset($plugins[$dependency])) {
|
||||
$verified = false;
|
||||
|
||||
// Remove plugin where it is require this dependency
|
||||
foreach ($plugins as $_plugin_name => $_plugin_data) {
|
||||
if ($_plugin_data['manifest']['dependencies'][$plugin_name]) {
|
||||
unset($plugins[$_plugin_name]);
|
||||
unset($verified_plugins[$_plugin_name]);
|
||||
if (! $_plugin_data['manifest']['dependencies'][$plugin_name]) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
unset($plugins[$_plugin_name]);
|
||||
unset($verified_plugins[$_plugin_name]);
|
||||
}
|
||||
} else {
|
||||
$version = $plugins[$dependency]['manifest']['version'];
|
||||
if (!Semver::satisfies($version, $constraints)) {
|
||||
|
||||
if (! Semver::satisfies($version, $constraints)) {
|
||||
$verified = false;
|
||||
|
||||
// Remove plugin where it is require this dependency
|
||||
foreach ($plugins as $_plugin_name => $_plugin_data) {
|
||||
if ($_plugin_data['manifest']['dependencies'][$plugin_name]) {
|
||||
unset($plugins[$_plugin_name]);
|
||||
unset($verified_plugins[$_plugin_name]);
|
||||
if (! $_plugin_data['manifest']['dependencies'][$plugin_name]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
unset($plugins[$_plugin_name]);
|
||||
unset($verified_plugins[$_plugin_name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -328,9 +323,11 @@ class Plugins
|
||||
}
|
||||
|
||||
// If plugin is verified than include it
|
||||
if ($verified) {
|
||||
$verified_plugins[$plugin_name] = $plugin_data;
|
||||
if (! $verified) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$verified_plugins[$plugin_name] = $plugin_data;
|
||||
}
|
||||
|
||||
// Show alert if dependencies are not installed properly
|
||||
@@ -338,11 +335,12 @@ class Plugins
|
||||
if (count($diff) > 0) {
|
||||
echo '<b>The following dependencies need to be installed properly:</b>';
|
||||
echo '<ul>';
|
||||
foreach($diff as $plugin_name => $plugin_data) {
|
||||
echo '<li>'.$plugin_name.'</li>';
|
||||
foreach ($diff as $plugin_name => $plugin_data) {
|
||||
echo '<li>' . $plugin_name . '</li>';
|
||||
}
|
||||
|
||||
echo '</ul>';
|
||||
die();
|
||||
die;
|
||||
}
|
||||
|
||||
// Return verified plugins list
|
@@ -10,13 +10,13 @@ declare(strict_types=1);
|
||||
namespace Flextype;
|
||||
|
||||
use Flextype\Component\Arr\Arr;
|
||||
use const PHP_EOL;
|
||||
use function array_slice;
|
||||
use function count;
|
||||
use function implode;
|
||||
use function ltrim;
|
||||
use function preg_split;
|
||||
use function trim;
|
||||
use const PHP_EOL;
|
||||
|
||||
class Frontmatter
|
||||
{
|
@@ -10,11 +10,11 @@ declare(strict_types=1);
|
||||
namespace Flextype;
|
||||
|
||||
use RuntimeException;
|
||||
use function json_decode;
|
||||
use function json_encode;
|
||||
use const JSON_PRETTY_PRINT;
|
||||
use const JSON_UNESCAPED_SLASHES;
|
||||
use const JSON_UNESCAPED_UNICODE;
|
||||
use function json_decode;
|
||||
use function json_encode;
|
||||
|
||||
class Json
|
||||
{
|
@@ -27,10 +27,12 @@ class Serializer
|
||||
'frontmatter' => [
|
||||
'name' => 'frontmatter',
|
||||
'ext' => 'md',
|
||||
], 'json' => [
|
||||
],
|
||||
'json' => [
|
||||
'name' => 'json',
|
||||
'ext' => 'json',
|
||||
], 'yaml' => [
|
||||
],
|
||||
'yaml' => [
|
||||
'name' => 'yaml',
|
||||
'ext' => 'yaml',
|
||||
],
|
407
src/flextype/Support/Collection.php
Normal file
407
src/flextype/Support/Collection.php
Normal file
@@ -0,0 +1,407 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Flextype (http://flextype.org)
|
||||
* Founded by Sergey Romanenko and maintained by Flextype Community.
|
||||
*/
|
||||
|
||||
namespace Flextype\Support;
|
||||
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use Doctrine\Common\Collections\Expr\Comparison;
|
||||
use Flextype\Component\Arr\Arr;
|
||||
use Awilum\ArrayDots\ArrayDots;
|
||||
use function array_merge;
|
||||
use function array_rand;
|
||||
use function count;
|
||||
use function error_reporting;
|
||||
use const E_NOTICE;
|
||||
|
||||
class Collection
|
||||
{
|
||||
/**
|
||||
* Order Direction
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
public $direction = [
|
||||
'ASC' => Criteria::ASC,
|
||||
'DESC' => Criteria::DESC,
|
||||
];
|
||||
|
||||
/**
|
||||
* Expression
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
public $expression = [
|
||||
'eq' => Comparison::EQ,
|
||||
'=' => Comparison::EQ,
|
||||
|
||||
'<>' => Comparison::NEQ,
|
||||
'!=' => Comparison::NEQ,
|
||||
'neq' => Comparison::NEQ,
|
||||
|
||||
'<' => Comparison::LT,
|
||||
'lt' => Comparison::LT,
|
||||
|
||||
'<=' => Comparison::LTE,
|
||||
'lte' => Comparison::LTE,
|
||||
|
||||
'>' => Comparison::GT,
|
||||
'gt' => Comparison::GT,
|
||||
|
||||
'>=' => Comparison::GTE,
|
||||
'gte' => Comparison::GTE,
|
||||
|
||||
'is' => Comparison::IS,
|
||||
'in' => Comparison::IN,
|
||||
'nin' => Comparison::NIN,
|
||||
'contains' => Comparison::CONTAINS,
|
||||
'like' => Comparison::CONTAINS,
|
||||
'member_of' => Comparison::MEMBER_OF,
|
||||
'start_with' => Comparison::STARTS_WITH,
|
||||
'ends_with' => Comparison::ENDS_WITH,
|
||||
];
|
||||
|
||||
/**
|
||||
* Collection
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private $collection;
|
||||
|
||||
/**
|
||||
* Criteria
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private $criteria;
|
||||
|
||||
/**
|
||||
* Error Reporting
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private $errorReporting;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function __construct($array)
|
||||
{
|
||||
// Save error_reporting state and turn it off
|
||||
// because PHP Doctrine Collections don't works with collections
|
||||
// if there is no requested fields to search inside item:
|
||||
// vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/ClosureExpressionVisitor.php
|
||||
// line 40: return $object[$field];
|
||||
//
|
||||
// @todo research this issue and find possible better solution to avoid this in the future
|
||||
$this->oldErrorReporting = error_reporting();
|
||||
error_reporting($this->oldErrorReporting & ~E_NOTICE);
|
||||
|
||||
// Flatten a multi-dimensional array with dots.
|
||||
if (Arr::isAssoc($array)) {
|
||||
$flat_array = [];
|
||||
|
||||
foreach ($array as $key => $value) {
|
||||
$flat_array[$key] = array_dot($value);
|
||||
}
|
||||
|
||||
$array = $flat_array;
|
||||
}
|
||||
|
||||
// Create Array Collection from entries array
|
||||
$this->collection = new ArrayCollection($array);
|
||||
|
||||
// Create Criteria for filtering Selectable collections.
|
||||
$this->criteria = new Criteria();
|
||||
|
||||
// Return
|
||||
return $this;
|
||||
}
|
||||
|
||||
public static function collect($array)
|
||||
{
|
||||
return new Collections($array);
|
||||
}
|
||||
|
||||
public function merge(...$arrays)
|
||||
{
|
||||
$this->collection = new ArrayCollection(
|
||||
array_merge($this->collection->toArray(), ...$arrays)
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the where expression to evaluate when this Criteria is searched for.
|
||||
*
|
||||
* @param string $field The field path using dot notation.
|
||||
* @param string $expr Expression @see $this->expression
|
||||
* @param mixed $value Value
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function where(string $field, string $expr, $value)
|
||||
{
|
||||
$this->criteria->where(new Comparison($field, $this->expression[$expr], $value));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the where expression to evaluate when this Criteria is searched
|
||||
* for using an AND with previous expression.
|
||||
*
|
||||
* @param string $field The field path using dot notation.
|
||||
* @param string $expr Expression @see $this->expression
|
||||
* @param mixed $value Value
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function andWhere(string $field, string $expr, $value)
|
||||
{
|
||||
$this->criteria->andWhere(new Comparison($field, $this->expression[$expr], $value));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the where expression to evaluate when this Criteria is searched
|
||||
* for using an OR with previous expression.
|
||||
*
|
||||
* @param string $field The field path using dot notation.
|
||||
* @param string $expr Expression @see $this->expression
|
||||
* @param mixed $value Value
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function orWhere(string $field, string $expr, $value)
|
||||
{
|
||||
$this->criteria->orWhere(new Comparison($field, $this->expression[$expr], $value));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ordering of the result of this Criteria.
|
||||
*
|
||||
* Keys are field and values are the order, being either ASC or DESC.
|
||||
*
|
||||
* @param string $field The field path using dot notation.
|
||||
* @param string $direction Sort direction: asc or desc
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function orderBy(string $field, string $direction)
|
||||
{
|
||||
$this->criteria->orderBy([$field => $this->direction[$direction]]);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number of first result that this Criteria should return.
|
||||
*
|
||||
* @param int|null $firstResult The value to set.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function setFirstResult(?int $firstResult)
|
||||
{
|
||||
$this->criteria->setFirstResult($firstResult);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the max results that this Criteria should return.
|
||||
*
|
||||
* @param int|null $limit The value to set.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function limit(?int $limit)
|
||||
{
|
||||
$this->criteria->setMaxResults($limit);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value indicating whether the collection contains any item of data.
|
||||
*
|
||||
* @return bool Return true or false.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function exists() : bool
|
||||
{
|
||||
return $this->count() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of items.
|
||||
*
|
||||
* @return int The number of items.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function count() : int
|
||||
{
|
||||
return count($this->all());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a last single item of result.
|
||||
*
|
||||
* @return array Item
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function last() : array
|
||||
{
|
||||
return array_undot($this->matchCollection()->last());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a single item of result.
|
||||
*
|
||||
* Moves the internal iterator position to the next element and returns this element.
|
||||
*
|
||||
* @return array Item
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function next() : array
|
||||
{
|
||||
return array_undot($this->matchCollection()->next());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a single item of result.
|
||||
*
|
||||
* Moves the internal iterator position to the next element and returns this element.
|
||||
*
|
||||
* @return array Item
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function shuffle() : array
|
||||
{
|
||||
$results = $this->matchCollection()->toArray();
|
||||
|
||||
return Arr::isAssoc($results) ?
|
||||
Arr::shuffle(array_undot(array_dot($results))) :
|
||||
$results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a single item of result.
|
||||
*
|
||||
* @return array Item
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function first() : array
|
||||
{
|
||||
$results = $this->matchCollection()->first();
|
||||
|
||||
return Arr::isAssoc($results) ?
|
||||
array_undot($results) :
|
||||
$results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns random item from result.
|
||||
*
|
||||
* @return array The array data.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function random() : array
|
||||
{
|
||||
$results = $this->matchCollection()->toArray();
|
||||
|
||||
return Arr::isAssoc($results) ?
|
||||
$results[array_rand(array_undot(array_dot($results)))] :
|
||||
$results[array_rand($results)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts a slice of $length elements starting at position $offset from the Collection.
|
||||
*
|
||||
* If $length is null it returns all elements from $offset to the end of the Collection.
|
||||
* Keys have to be preserved by this method. Calling this method will only return
|
||||
* the selected slice and NOT change the elements contained in the collection slice is called on.
|
||||
*
|
||||
* @param int $offset Slice begin index.
|
||||
* @param int|null $length Length of the slice.
|
||||
*
|
||||
* @return array The array data.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function slice(int $offset = 0, ?int $limit = null) : array
|
||||
{
|
||||
$results = $this->matchCollection()->slice($offset, $limit);
|
||||
|
||||
return Arr::isAssoc($results) ?
|
||||
array_undot(array_dot($results)) :
|
||||
$results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all results as an array.
|
||||
*
|
||||
* @return array The array data.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function all() : array
|
||||
{
|
||||
$results = $this->matchCollection()->toArray();
|
||||
|
||||
return Arr::isAssoc($results) ?
|
||||
array_undot(array_dot($results)) :
|
||||
$results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Match collection
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
public function matchCollection()
|
||||
{
|
||||
// Match collection
|
||||
$collection = $this->collection->matching($this->criteria);
|
||||
|
||||
// Restore error_reporting
|
||||
error_reporting($this->oldErrorReporting);
|
||||
|
||||
// Return collection
|
||||
return $collection;
|
||||
}
|
||||
}
|
22
src/flextype/Support/helpers.php
Normal file
22
src/flextype/Support/helpers.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Flextype (http://flextype.org)
|
||||
* Founded by Sergey Romanenko and maintained by Flextype Community.
|
||||
*/
|
||||
|
||||
use Flextype\Support\Collection;
|
||||
|
||||
if (! function_exists('collect')) {
|
||||
/**
|
||||
* Create a collection from the given value.
|
||||
*
|
||||
* @param array $value Items to collect
|
||||
*/
|
||||
function collect($array) : \Flextype\Support\Collection
|
||||
{
|
||||
return new Collection($array);
|
||||
}
|
||||
}
|
@@ -169,7 +169,7 @@ date_default_timezone_set($flextype['registry']->get('flextype.settings.timezone
|
||||
$shortcodes_extensions = $flextype['registry']->get('flextype.settings.shortcodes.extensions');
|
||||
|
||||
foreach ($shortcodes_extensions as $shortcodes_extension) {
|
||||
$shortcodes_extension_file_path = ROOT_DIR . '/src/flextype/core/Parsers/shortcodes/' . $shortcodes_extension . 'ShortcodeExtension.php';
|
||||
$shortcodes_extension_file_path = ROOT_DIR . '/src/flextype/Foundation/Parsers/shortcodes/' . $shortcodes_extension . 'ShortcodeExtension.php';
|
||||
if (file_exists($shortcodes_extension_file_path)) {
|
||||
include_once $shortcodes_extension_file_path;
|
||||
}
|
||||
|
@@ -1,66 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Flextype (http://flextype.org)
|
||||
* Founded by Sergey Romanenko and maintained by Flextype Community.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
class Cors
|
||||
{
|
||||
/**
|
||||
* Flextype Dependency Container
|
||||
*/
|
||||
private $flextype;
|
||||
|
||||
|
||||
/**
|
||||
* Flextype app
|
||||
*/
|
||||
private $app;
|
||||
|
||||
/**
|
||||
* __construct
|
||||
*/
|
||||
public function __construct($flextype, $app)
|
||||
{
|
||||
$this->flextype = $flextype;
|
||||
$this->app = $app;
|
||||
}
|
||||
|
||||
/**
|
||||
* Init CORS
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$flextype = $this->flextype;
|
||||
|
||||
if ($flextype['registry']->get('flextype.settings.cors.enabled')) {
|
||||
|
||||
$this->app->options('/{routes:.+}', function ($request, $response, $args) {
|
||||
return $response;
|
||||
});
|
||||
|
||||
$this->app->add(function ($req, $res, $next) use ($flextype) {
|
||||
$response = $next($req, $res);
|
||||
|
||||
// Set variables
|
||||
$origin = $flextype['registry']->get('flextype.settings.cors.origin');
|
||||
$headers = count($flextype['registry']->get('flextype.settings.cors.headers')) ? implode(', ', $flextype['registry']->get('flextype.settings.cors.headers')) : '';
|
||||
$methods = count($flextype['registry']->get('flextype.settings.cors.methods')) ? implode(', ', $flextype['registry']->get('flextype.settings.cors.methods')) : '';
|
||||
$expose = count($flextype['registry']->get('flextype.settings.cors.expose')) ? implode(', ', $flextype['registry']->get('flextype.settings.cors.expose')) : '';
|
||||
$credentials = ($flextype['registry']->get('flextype.settings.cors.credentials')) ? true : false;
|
||||
|
||||
return $response
|
||||
->withHeader('Access-Control-Allow-Origin', $origin)
|
||||
->withHeader('Access-Control-Allow-Headers', $headers)
|
||||
->withHeader('Access-Control-Allow-Methods', $methods)
|
||||
->withHeader('Access-Control-Allow-Expose', $expose)
|
||||
->withHeader('Access-Control-Allow-Credentials', $credentials);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,667 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Flextype (http://flextype.org)
|
||||
* Founded by Sergey Romanenko and maintained by Flextype Community.
|
||||
*/
|
||||
|
||||
namespace Flextype;
|
||||
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use Doctrine\Common\Collections\Expr\Comparison;
|
||||
use Flextype\Component\Filesystem\Filesystem;
|
||||
use Flextype\Component\Session\Session;
|
||||
use Flextype\Component\Arr\Arr;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use function array_merge;
|
||||
use function count;
|
||||
use function date;
|
||||
use function error_reporting;
|
||||
use function in_array;
|
||||
use function is_array;
|
||||
use function is_bool;
|
||||
use function json_encode;
|
||||
use function ltrim;
|
||||
use function md5;
|
||||
use function rename;
|
||||
use function rtrim;
|
||||
use function str_replace;
|
||||
use function strpos;
|
||||
use function strtotime;
|
||||
use function time;
|
||||
|
||||
class Entries
|
||||
{
|
||||
/**
|
||||
* Current entry data array
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
public $entry = [];
|
||||
|
||||
/**
|
||||
* Current entries data array
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
public $entries = [];
|
||||
|
||||
/**
|
||||
* Expression
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
public $expression = [
|
||||
'eq' => Comparison::EQ,
|
||||
'=' => Comparison::EQ,
|
||||
|
||||
'<>' => Comparison::NEQ,
|
||||
'!=' => Comparison::NEQ,
|
||||
'neq' => Comparison::NEQ,
|
||||
|
||||
'<' => Comparison::LT,
|
||||
'lt' => Comparison::LT,
|
||||
|
||||
'<=' => Comparison::LTE,
|
||||
'lte' => Comparison::LTE,
|
||||
|
||||
'>' => Comparison::GT,
|
||||
'gt' => Comparison::GT,
|
||||
|
||||
'>=' => Comparison::GTE,
|
||||
'gte' => Comparison::GTE,
|
||||
|
||||
'is' => Comparison::IS,
|
||||
'in' => Comparison::IN,
|
||||
'nin' => Comparison::NIN,
|
||||
'contains' => Comparison::CONTAINS,
|
||||
'like' => Comparison::CONTAINS,
|
||||
'member_of' => Comparison::MEMBER_OF,
|
||||
'start_with' => Comparison::STARTS_WITH,
|
||||
'ends_with' => Comparison::ENDS_WITH,
|
||||
];
|
||||
|
||||
/**
|
||||
* Entires Order Direction
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
public $direction = [
|
||||
'asc' => Criteria::ASC,
|
||||
'desc' => Criteria::DESC,
|
||||
];
|
||||
|
||||
/**
|
||||
* Entries Visibility
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
public $visibility = [
|
||||
'draft' => 'draft',
|
||||
'hidden' => 'hidden',
|
||||
'visible' => 'visible',
|
||||
];
|
||||
|
||||
/**
|
||||
* Entries system fields
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
public $system_fields = [
|
||||
'published_at' => 'published_at',
|
||||
'published_by' => 'published_by',
|
||||
'created_at' => 'created_at',
|
||||
'modified_at' => 'modified_at',
|
||||
'slug' => 'slug',
|
||||
'routable' => 'routable',
|
||||
'parsers' => 'parsers',
|
||||
'visibility' => 'visibility',
|
||||
];
|
||||
|
||||
/**
|
||||
* Flextype Dependency Container
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private $flextype;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function __construct($flextype)
|
||||
{
|
||||
$this->flextype = $flextype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch entry(entries)
|
||||
*
|
||||
* @param string $id Unique identifier of the entry(entries).
|
||||
* @param array|null $filter Select items in collection by given conditions.
|
||||
*
|
||||
* @return array The entry array data.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function fetch(string $id, ?array $filter = null) : array
|
||||
{
|
||||
// If filter is array then it is entries collection request
|
||||
if (is_array($filter)) {
|
||||
return $this->fetchCollection($id, $filter);
|
||||
}
|
||||
|
||||
return $this->fetchSingle($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch single entry
|
||||
*
|
||||
* @param string $id Unique identifier of the entry(entries).
|
||||
*
|
||||
* @return array The entry array data.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function fetchSingle(string $id) : array
|
||||
{
|
||||
// Get entry file location
|
||||
$entry_file = $this->getFileLocation($id);
|
||||
|
||||
// If requested entry file founded then process it
|
||||
if (Filesystem::has($entry_file)) {
|
||||
// Create unique entry cache_id
|
||||
// Entry Cache ID = entry + entry file + entry file time stamp
|
||||
if ($timestamp = Filesystem::getTimestamp($entry_file)) {
|
||||
$entry_cache_id = md5('entry' . $entry_file . $timestamp);
|
||||
} else {
|
||||
$entry_cache_id = md5('entry' . $entry_file);
|
||||
}
|
||||
|
||||
// Try to get the requested entry from cache
|
||||
if ($this->flextype['cache']->contains($entry_cache_id)) {
|
||||
// Try to fetch requested entry from the cache
|
||||
if ($entry = $this->flextype['cache']->fetch($entry_cache_id)) {
|
||||
// Run event onEntryAfterInitialized
|
||||
$this->flextype['emitter']->emit('onEntryAfterInitialized');
|
||||
|
||||
// Return entry
|
||||
return $entry;
|
||||
}
|
||||
|
||||
// Return empty array
|
||||
return [];
|
||||
|
||||
// else Try to get requested entry from the filesystem
|
||||
}
|
||||
|
||||
$entry_decoded = $this->flextype['serializer']->decode(Filesystem::read($entry_file), 'frontmatter');
|
||||
|
||||
// Add predefined entry items
|
||||
// Entry Published At
|
||||
$entry_decoded['published_at'] = isset($entry_decoded['published_at']) ? (int) strtotime($entry_decoded['published_at']) : (int) Filesystem::getTimestamp($entry_file);
|
||||
|
||||
// Entry Created At
|
||||
$entry_decoded['created_at'] = isset($entry_decoded['created_at']) ? (int) strtotime($entry_decoded['created_at']) : (int) Filesystem::getTimestamp($entry_file);
|
||||
|
||||
// Entry Modified
|
||||
$entry_decoded['modified_at'] = (int) Filesystem::getTimestamp($entry_file);
|
||||
|
||||
// Entry Slug
|
||||
$entry_decoded['slug'] = isset($entry_decoded['slug']) ? (string) $entry_decoded['slug'] : (string) ltrim(rtrim($id, '/'), '/');
|
||||
|
||||
// Entry Routable
|
||||
$entry_decoded['routable'] = isset($entry_decoded['routable']) ? (bool) $entry_decoded['routable'] : true;
|
||||
|
||||
// Entry Visibility
|
||||
if (isset($entry_decoded['visibility']) && in_array($entry_decoded['visibility'], $this->visibility)) {
|
||||
$entry_decoded['visibility'] = (string) $this->visibility[$entry_decoded['visibility']];
|
||||
} else {
|
||||
$entry_decoded['visibility'] = (string) $this->visibility['visible'];
|
||||
}
|
||||
|
||||
// Parsers
|
||||
if (isset($entry_decoded['parsers'])) {
|
||||
foreach ($entry_decoded['parsers'] as $parser_name => $parser_data) {
|
||||
if (in_array($parser_name, ['markdown', 'shortcodes'])) {
|
||||
if (isset($entry_decoded['parsers'][$parser_name]['enabled']) && $entry_decoded['parsers'][$parser_name]['enabled'] === true) {
|
||||
if (isset($entry_decoded['parsers'][$parser_name]['cache']) && $entry_decoded['parsers'][$parser_name]['cache'] === true) {
|
||||
$cache = true;
|
||||
} else {
|
||||
$cache = false;
|
||||
}
|
||||
if (isset($entry_decoded['parsers'][$parser_name]['fields'])) {
|
||||
if (is_array($entry_decoded['parsers'][$parser_name]['fields'])) {
|
||||
foreach ($entry_decoded['parsers'][$parser_name]['fields'] as $field) {
|
||||
if (! in_array($field, $this->system_fields)) {
|
||||
if ($parser_name == 'markdown') {
|
||||
if (Arr::keyExists($entry_decoded, $field)) {
|
||||
Arr::set($entry_decoded, $field, $this->flextype['parser']->parse(Arr::get($entry_decoded, $field), 'markdown', $cache));
|
||||
}
|
||||
}
|
||||
if ($parser_name == 'shortcodes') {
|
||||
if (Arr::keyExists($entry_decoded, $field)) {
|
||||
Arr::set($entry_decoded, $field, $this->flextype['parser']->parse(Arr::get($entry_decoded, $field), 'shortcodes', $cache));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Save decoded entry content into the cache
|
||||
$this->flextype['cache']->save($entry_cache_id, $entry_decoded);
|
||||
|
||||
// Set entry to the Entry class property $entry
|
||||
$this->entry = $entry_decoded;
|
||||
|
||||
// Run event onEntryAfterInitialized
|
||||
$this->flextype['emitter']->emit('onEntryAfterInitialized');
|
||||
|
||||
// Return entry from the Entry class property $entry
|
||||
return $this->entry;
|
||||
}
|
||||
|
||||
// Return empty array
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch entries collection
|
||||
*
|
||||
* @param string $id Unique identifier of the entry(entries).
|
||||
* @param array $filter Select items in collection by given conditions.
|
||||
*
|
||||
* @return array The entries array data.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function fetchCollection(string $id, array $filter = []) : array
|
||||
{
|
||||
// Init Entries
|
||||
$entries = [];
|
||||
|
||||
// Init Entries
|
||||
$this->entries = $entries;
|
||||
|
||||
// Set Expression
|
||||
$expression = $this->expression;
|
||||
|
||||
// Set Direction
|
||||
$direction = $this->direction;
|
||||
|
||||
// Bind: Entry ID
|
||||
$bind_id = $id;
|
||||
|
||||
// Bind: recursive
|
||||
$bind_recursive = $filter['recursive'] ?? false;
|
||||
|
||||
// Bind: set first result
|
||||
$bind_set_first_result = $filter['set_first_result'] ?? false;
|
||||
|
||||
// Bind: set max result
|
||||
$bind_set_max_result = $filter['set_max_result'] ?? false;
|
||||
|
||||
// Bind: where
|
||||
$bind_where = [];
|
||||
if (isset($filter['where']['key']) && isset($filter['where']['expr']) && isset($filter['where']['value'])) {
|
||||
$bind_where['where']['key'] = $filter['where']['key'];
|
||||
$bind_where['where']['expr'] = $expression[$filter['where']['expr']];
|
||||
$bind_where['where']['value'] = $filter['where']['value'];
|
||||
}
|
||||
|
||||
// Bind: and where
|
||||
$bind_and_where = [];
|
||||
if (isset($filter['and_where'])) {
|
||||
foreach ($filter['and_where'] as $key => $value) {
|
||||
if (! isset($value['key']) || ! isset($value['expr']) || ! isset($value['value'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$bind_and_where[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
// Bind: or where
|
||||
$bind_or_where = [];
|
||||
if (isset($filter['or_where'])) {
|
||||
foreach ($filter['or_where'] as $key => $value) {
|
||||
if (! isset($value['key']) || ! isset($value['expr']) || ! isset($value['value'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$bind_or_where[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
// Bind: order by
|
||||
$bind_order_by = [];
|
||||
if (isset($filter['order_by']['field']) && isset($filter['order_by']['direction'])) {
|
||||
$bind_order_by['order_by']['field'] = $filter['order_by']['field'];
|
||||
$bind_order_by['order_by']['direction'] = $filter['order_by']['direction'];
|
||||
}
|
||||
|
||||
// Get entries path
|
||||
$entries_path = $this->getDirLocation($bind_id);
|
||||
|
||||
// Get entries list
|
||||
$entries_list = Filesystem::listContents($entries_path, $bind_recursive);
|
||||
|
||||
// If entries founded in entries folder
|
||||
if (count($entries_list) > 0) {
|
||||
// Entries IDs
|
||||
$entries_ids = '';
|
||||
|
||||
// Entries IDs timestamps
|
||||
$entries_ids_timestamps = '';
|
||||
|
||||
// Create entries array from entries list and ignore current requested entry
|
||||
foreach ($entries_list as $current_entry) {
|
||||
if (strpos($current_entry['path'], $bind_id . '/entry' . '.' . $this->flextype->registry->get('flextype.settings.entries.extension')) !== false) {
|
||||
// ignore ...
|
||||
} else {
|
||||
// We are checking...
|
||||
// Whether the requested entry is a director and whether the file entry is in this directory.
|
||||
if ($current_entry['type'] === 'dir' && Filesystem::has($current_entry['path'] . '/entry' . '.' . $this->flextype->registry->get('flextype.settings.entries.extension'))) {
|
||||
// Get entry uid
|
||||
// 1. Remove entries path
|
||||
// 2. Remove left and right slashes
|
||||
$uid = ltrim(rtrim(str_replace(PATH['project'] . '/entries/', '', $current_entry['path']), '/'), '/');
|
||||
|
||||
// For each founded entry we should create $entries array.
|
||||
$entry = $this->fetch($uid);
|
||||
|
||||
// Flatten a multi-dimensional entries array with dots.
|
||||
$entry = Arr::dot($entry);
|
||||
|
||||
// Add entry into the entries
|
||||
$entries[$uid] = $entry;
|
||||
|
||||
// Create entries IDs list
|
||||
$entries_ids .= $uid;
|
||||
|
||||
// Create entries IDs timestamps
|
||||
$entries_ids_timestamps .= Filesystem::getTimestamp($current_entry['path'] . '/entry' . '.' . $this->flextype->registry->get('flextype.settings.entries.extension'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create unique entries $cache_id
|
||||
$cache_id = md5(
|
||||
$bind_id .
|
||||
$entries_ids .
|
||||
$entries_ids_timestamps .
|
||||
($bind_recursive ? 'true' : 'false') .
|
||||
($bind_set_max_result ? $bind_set_max_result : '') .
|
||||
($bind_set_first_result ? $bind_set_first_result : '') .
|
||||
json_encode($bind_where) .
|
||||
json_encode($bind_and_where) .
|
||||
json_encode($bind_or_where) .
|
||||
json_encode($bind_order_by)
|
||||
);
|
||||
|
||||
// If requested entries exist with a specific cache_id,
|
||||
// then we take them from the cache otherwise we look for them.
|
||||
if ($this->flextype['cache']->contains($cache_id)) {
|
||||
$entries = $this->flextype['cache']->fetch($cache_id);
|
||||
} else {
|
||||
// Save error_reporting state and turn it off
|
||||
// because PHP Doctrine Collections don't works with collections
|
||||
// if there is no requested fields to search:
|
||||
// vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/ClosureExpressionVisitor.php
|
||||
// line 40: return $object[$field];
|
||||
//
|
||||
// @todo research this issue and find possible better solution to avoid this in the future
|
||||
$oldErrorReporting = error_reporting();
|
||||
error_reporting(0);
|
||||
|
||||
// Create Array Collection from entries array
|
||||
$collection = new ArrayCollection($entries);
|
||||
|
||||
// Create Criteria for filtering Selectable collections.
|
||||
$criteria = new Criteria();
|
||||
|
||||
// Exec: where
|
||||
if (isset($bind_where['where']['key']) && isset($bind_where['where']['expr']) && isset($bind_where['where']['value'])) {
|
||||
$expr = new Comparison($bind_where['where']['key'], $bind_where['where']['expr'], $bind_where['where']['value']);
|
||||
$criteria->where($expr);
|
||||
}
|
||||
|
||||
// Exec: and where
|
||||
if (isset($bind_and_where)) {
|
||||
$_expr = [];
|
||||
foreach ($bind_and_where as $key => $value) {
|
||||
$_expr[$key] = new Comparison($value['key'], $expression[$value['expr']], $value['value']);
|
||||
$criteria->andWhere($_expr[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
// Exec: or where
|
||||
if (isset($bind_or_where)) {
|
||||
$_expr = [];
|
||||
foreach ($bind_or_where as $key => $value) {
|
||||
$_expr[$key] = new Comparison($value['key'], $expression[$value['expr']], $value['value']);
|
||||
$criteria->orWhere($_expr[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
// Exec: order by
|
||||
if (isset($bind_order_by['order_by']['field']) && isset($bind_order_by['order_by']['direction'])) {
|
||||
$criteria->orderBy([$bind_order_by['order_by']['field'] => $direction[$bind_order_by['order_by']['direction']]]);
|
||||
}
|
||||
|
||||
// Exec: set max result
|
||||
if ($bind_set_max_result) {
|
||||
$criteria->setMaxResults($bind_set_max_result);
|
||||
}
|
||||
|
||||
// Exec: set first result
|
||||
if ($bind_set_first_result) {
|
||||
$criteria->setFirstResult($bind_set_first_result);
|
||||
}
|
||||
|
||||
// Get entries for matching criterias
|
||||
$entries = $collection->matching($criteria);
|
||||
|
||||
// Gets a native PHP array representation of the collection.
|
||||
$entries = $entries->toArray();
|
||||
|
||||
// Magic is here... dot and undot for entries array
|
||||
// 1. Flatten a multi-dimensional entries array with dots.
|
||||
// 2. Restore entries array with dots into correct multi-dimensional entries array
|
||||
$entries = Arr::undot(Arr::dot($entries));
|
||||
|
||||
// Restore error_reporting
|
||||
error_reporting($oldErrorReporting);
|
||||
|
||||
// Save entries into the cache
|
||||
$this->flextype['cache']->save($cache_id, $entries);
|
||||
}
|
||||
|
||||
// Set entries into the property entries
|
||||
$this->entries = $entries;
|
||||
|
||||
// Run event onEntriesAfterInitialized
|
||||
$this->flextype['emitter']->emit('onEntriesAfterInitialized');
|
||||
}
|
||||
|
||||
// Return entries
|
||||
return $this->entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename entry
|
||||
*
|
||||
* @param string $id Unique identifier of the entry(entries).
|
||||
* @param string $new_id New Unique identifier of the entry(entries).
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function rename(string $id, string $new_id) : bool
|
||||
{
|
||||
if (!Filesystem::has($this->getDirLocation($new_id))) {
|
||||
return rename($this->getDirLocation($id), $this->getDirLocation($new_id));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update entry
|
||||
*
|
||||
* @param string $id Unique identifier of the entry(entries).
|
||||
* @param array $data Data to update for the entry.
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function update(string $id, array $data) : bool
|
||||
{
|
||||
$entry_file = $this->getFileLocation($id);
|
||||
|
||||
if (Filesystem::has($entry_file)) {
|
||||
$body = Filesystem::read($entry_file);
|
||||
$entry = $this->flextype['serializer']->decode($body, 'frontmatter');
|
||||
|
||||
return Filesystem::write($entry_file, $this->flextype['serializer']->encode(array_merge($entry, $data), 'frontmatter'));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create entry
|
||||
*
|
||||
* @param string $id Unique identifier of the entry(entries).
|
||||
* @param array $data Data to create for the entry.
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function create(string $id, array $data) : bool
|
||||
{
|
||||
$entry_dir = $this->getDirLocation($id);
|
||||
|
||||
if (! Filesystem::has($entry_dir)) {
|
||||
// Try to create directory for new entry
|
||||
if (Filesystem::createDir($entry_dir)) {
|
||||
// Check if new entry file exists
|
||||
if (! Filesystem::has($entry_file = $entry_dir . '/entry' . '.' . $this->flextype->registry->get('flextype.settings.entries.extension'))) {
|
||||
$data['uuid'] = Uuid::uuid4()->toString();
|
||||
$data['published_at'] = date($this->flextype->registry->get('flextype.settings.date_format'), time());
|
||||
$data['created_at'] = date($this->flextype->registry->get('flextype.settings.date_format'), time());
|
||||
$data['published_by'] = (Session::exists('uuid') ? Session::get('uuid') : '');
|
||||
$data['created_by'] = (Session::exists('uuid') ? Session::get('uuid') : '');
|
||||
|
||||
if (isset($data['routable']) && is_bool($data['routable'])) {
|
||||
$data['routable'] = $data['routable'];
|
||||
} else {
|
||||
$data['routable'] = true;
|
||||
}
|
||||
|
||||
if (isset($data['visibility']) && in_array($data['visibility'], $this->visibility)) {
|
||||
$data['visibility'] = $data['visibility'];
|
||||
} else {
|
||||
$data['visibility'] = 'visible';
|
||||
}
|
||||
|
||||
return Filesystem::write($entry_file, $this->flextype['serializer']->encode($data, 'frontmatter'));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete entry
|
||||
*
|
||||
* @param string $id Unique identifier of the entry(entries).
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function delete(string $id) : bool
|
||||
{
|
||||
return Filesystem::deleteDir($this->getDirLocation($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy entry(s)
|
||||
*
|
||||
* @param string $id Unique identifier of the entry(entries).
|
||||
* @param string $new_id New Unique identifier of the entry(entries).
|
||||
* @param bool $recursive Recursive copy entries.
|
||||
*
|
||||
* @return bool|null True on success, false on failure.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function copy(string $id, string $new_id, bool $recursive = false) : ?bool
|
||||
{
|
||||
return Filesystem::copy($this->getDirLocation($id), $this->getDirLocation($new_id), $recursive);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether entry exists
|
||||
*
|
||||
* @param string $id Unique identifier of the entry(entries).
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function has(string $id) : bool
|
||||
{
|
||||
return Filesystem::has($this->getFileLocation($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get entry file location
|
||||
*
|
||||
* @param string $id Unique identifier of the entry(entries).
|
||||
*
|
||||
* @return string entry file location
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
public function getFileLocation(string $id) : string
|
||||
{
|
||||
return PATH['project'] . '/entries/' . $id . '/entry' . '.' . $this->flextype->registry->get('flextype.settings.entries.extension');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get entry directory location
|
||||
*
|
||||
* @param string $id Unique identifier of the entry(entries).
|
||||
*
|
||||
* @return string entry directory location
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
public function getDirLocation(string $id) : string
|
||||
{
|
||||
return PATH['project'] . '/entries/' . $id;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user