1
0
mirror of https://github.com/flextype/flextype.git synced 2025-08-20 03:41:27 +02:00

Flextype Core: Entries #175 #165

- Collections implementation / new code for fetchAll() method
This commit is contained in:
Awilum
2019-06-28 00:07:53 +03:00
parent dfe09fee3a
commit 08ef023fa7

View File

@@ -14,6 +14,9 @@ namespace Flextype;
use Flextype\Component\Arr\Arr;
use Flextype\Component\Filesystem\Filesystem;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\Common\Collections\Expr\Comparison;
class Entries
{
@@ -51,46 +54,68 @@ class Entries
}
/**
* Fetch entry
* Fetch single entry
*
* @access public
* @param string $id Entry id
* @param string $id Entry ID
* @return array|false The entry contents or false on failure.
*/
public function fetch(string $id)
{
// Get entry file location
$entry_file = $this->_file_location($id);
// If requested entry founded then process it
if (Filesystem::has($entry_file)) {
// Create unique entry cache_id
$cache_id = md5('entry' . $entry_file . ((Filesystem::getTimestamp($entry_file) === false) ? '' : Filesystem::getTimestamp($entry_file)));
// Entry Cache ID = entry + entry file + entry file time stamp
$entry_cache_id = md5('entry' . $entry_file . 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)) {
return $entry_decoded;
// 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;
} else {
return false;
}
// else Try to get requested entry from the filesystem
} else {
// Try to get requested entry body content
if ($entry_body = Filesystem::read($entry_file)) {
// Try to decode requested entry body content
if ($entry_decoded = JsonParser::decode($entry_body)) {
// Create default entry items
//
// Add predefined entry items
//
// Entry Date
$entry_decoded['date'] = $entry_decoded['date'] ?? date($this->flextype['registry']->get('settings.date_format'), Filesystem::getTimestamp($entry_file));
// Entry Slug
$entry_decoded['slug'] = $entry_decoded['slug'] ?? ltrim(rtrim($id, '/'), '/');
// Save decoded entry content into the cache
$this->flextype['cache']->save($cache_id, $entry_decoded);
$this->flextype['cache']->save($entry_cache_id, $entry_decoded);
// Set entry
// Set entry to the Entry class property $entry
$this->entry = $entry_decoded;
// Run event onEntryAfterInitialized
$this->flextype['emitter']->emit('onEntryAfterInitialized');
// Return entry
// Return entry from the Entry class property $entry
return $this->entry;
} else {
return false;
@@ -105,43 +130,110 @@ class Entries
}
/**
* Fetch all entries
* Fetch entries collection
*
* @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
* @param bool $recursive Whether to list recursively.
* @param array $args Query arguments
* @return array The entries
*/
public function fetchAll(string $id, string $order_by = 'date', string $order_type = 'DESC', int $offset = null, int $length = null, bool $recursive = false) : array
public function fetchAll(array $args) : array
{
// Set empty entries array where founded entries will stored
$entries = [];
// Bind: entry id
$bind_id = ($args['id']) ?? '';
// Set empty cache id for the entries
$cache_id = '';
// Bind: recursive
$bind_recursive = ($args['recursive']) ? true : false;
// Bind: set first result
$bind_set_first_result = ($args['set_first_result']) ?? false;
// Bind: set max result
$bind_set_max_result = ($args['set_max_result']) ?? false;
// Bind: where
if ($args['where'] && is_array($args['where'])) {
$bind_where['where'] = [];
$bind_where['where']['key'] = $args['where']['key'];
$bind_where['where']['expr'] = $args['where']['expr'];
$bind_where['where']['value'] = $args['where']['value'];
} else {
$bind_where = false;
}
// Bind: and where
if ($args['and_where'] && is_array($args['and_where'])) {
$bind_and_where['and_where'] = [];
$bind_and_where['and_where']['key'] = $args['and_where']['key'];
$bind_and_where['and_where']['expr'] = $args['and_where']['expr'];
$bind_and_where['and_where']['value'] = $args['and_where']['value'];
} else {
$bind_and_where = false;
}
// Bind: or where
if ($args['or_where'] && is_array($args['or_where'])) {
$bind_or_where['or_where'] = [];
$bind_or_where['or_where']['key'] = $args['or_where']['key'];
$bind_or_where['or_where']['expr'] = $args['or_where']['expr'];
$bind_or_where['or_where']['value'] = $args['or_where']['value'];
} else {
$bind_or_where = false;
}
// Bind: order by
if ($args['order_by'] && is_array($args['order_by'])) {
$bind_order_by['order_by'] = [];
$bind_order_by['order_by']['field'] = $args['order_by']['field'];
$bind_order_by['order_by']['direction'] = $args['order_by']['direction'];
} else {
$bind_order_by = false;
}
// Get entries path
$entries_path = $this->_dir_location($id);
$entries_path = $this->_dir_location($bind_id);
// Get entries list
$entries_list = Filesystem::listContents($entries_path, $recursive);
$entries_list = Filesystem::listContents($entries_path, $bind_recursive);
// Create unique entries cache_id
// Create unique entries $_entries_ids
// 1. Go through all entries
// 2. set all entries IDs and their timestamps into the $_entries_ids
$_entries_ids = '';
foreach ($entries_list as $current_entry) {
if (strpos($current_entry['path'], $id . '/entry.json') !== false) {
if (strpos($current_entry['path'], $bind_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'));
$_entries_ids .= 'entry:' . ltrim(rtrim(str_replace(PATH['entries'], '', $current_entry['path']), '/'), '/') . ' timestamp:' . Filesystem::getTimestamp($current_entry['path'] . '/entry.json') . ' ';
}
}
}
// If the entries exist at a specific cache_id,
// Create unique entries $cache_id
$cache_id = md5($_entries_ids .
$bind_id .
($bind_recursive) ? 'true' : 'false' .
($bind_set_max_result) ? $bind_set_max_result : 'false' .
($bind_set_first_result) ? $bind_set_first_result : 'false' .
($bind_set_max_result) ? $bind_set_max_result : 'false' .
($bind_where['where']) ? 'true' : 'false' .
($bind_where['where']['key']) ? $bind_where['where']['key'] : 'false' .
($bind_where['where']['expr']) ? $bind_where['where']['expr'] : 'false' .
($bind_where['where']['value']) ? $bind_where['where']['value'] : 'false' .
($bind_and_where['and_where']) ? 'true' : 'false' .
($bind_and_where['and_where']['key']) ? $bind_and_where['and_where']['key'] : 'false' .
($bind_and_where['and_where']['expr']) ? $bind_and_where['and_where']['expr'] : 'false' .
($bind_and_where['and_where']['value']) ? $bind_and_where['and_where']['value'] : 'false' .
($bind_or_where['or_where']) ? 'true' : 'false' .
($bind_or_where['or_where']['key']) ? $bind_or_where['or_where']['key'] : 'false' .
($bind_or_where['or_where']['expr']) ? $bind_or_where['or_where']['expr'] : 'false' .
($bind_or_where['or_where']['value']) ? $bind_or_where['or_where']['value'] : 'false' .
($bind_or_where['order_by']) ? 'true' : 'false' .
($bind_or_where['order_by']['field']) ? $bind_or_where['order_by']['field'] : 'false' .
($bind_or_where['order_by']['direction']) ? $bind_or_where['order_by']['direction'] : 'false'
);
// 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);
@@ -149,7 +241,7 @@ class Entries
// 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) {
if (strpos($current_entry['path'], $bind_id . '/entry.json') !== false) {
// ignore ...
} else {
// We are checking...
@@ -162,28 +254,61 @@ class Entries
$uid = ltrim(rtrim(str_replace(PATH['entries'], '', $current_entry['path']), '/'), '/');
// For each founded entry we should create $entries array.
$entries[$uid] = $this->fetch($uid);
$entry = $this->fetch($uid);
// Add entry into the entries
$entries[$uid] = $entry;
}
}
}
// Create Array Collection from entries array
$collection = new ArrayCollection($entries);
// Create Criteria for filtering Selectable collections.
$criteria = new Criteria();
// Exec: where
if ($bind_where) {
$expr = new Comparison($bind_where['where']['key'], $bind_where['where']['expr'], $bind_where['where']['value']);
$criteria->where($expr);
}
// Exec: and where
if ($bind_and_where) {
$expr = new Comparison($bind_and_where['and_where']['key'], $bind_and_where['and_where']['expr'], $bind_and_where['and_where']['value']);
$criteria->where($expr);
}
// Exec: or where
if ($bind_or_where) {
$expr = new Comparison($bind_or_where['or_where']['key'], $bind_or_where['or_where']['expr'], $bind_or_where['or_where']['value']);
$criteria->where($expr);
}
// Exec: order by
if ($bind_order_by) {
$criteria->orderBy($bind_order_by['field'], $bind_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);
// Save entries into the cache
$this->flextype['cache']->save($cache_id, $entries);
}
// If count of the entries more then 0 then sort and slice them.
if (count($entries) > 0) {
// Sort entries
$entries = Arr::sort($entries, $order_by, $order_type);
// Slice entries
if ($offset !== null && $length !== null) {
$entries = array_slice($entries, $offset, $length);
}
}
// Set entries
// Set entries into the property entries
$this->entries = $entries;
// Run event onEntriesAfterInitialized