Added FlexObject::refresh() method to make sure object is up to date

This commit is contained in:
Matias Griese
2020-11-24 14:48:12 +02:00
parent cf052b5bd4
commit 9bb1d99ae4
3 changed files with 91 additions and 40 deletions

View File

@@ -3,6 +3,7 @@
1. [](#new)
* Set minimum requirements to **PHP 7.3.6**
* Updated Clockwork to v5.0
* Added `FlexDirectoryInterface` interface
* Renamed `PageCollectionInterface::nonModular()` into `PageCollectionInterface::pages()` and deprecated the old method
* Renamed `PageCollectionInterface::modular()` into `PageCollectionInterface::modules()` and deprecated the old method'
@@ -10,7 +11,6 @@
* Added search option `same_as` to Flex Objects
* Added PHP 8 compatible `function_exists()`: `Utils::functionExists()`
* New sites have `compatibility` features turned off by default, upgrading from older versions will keep the settings on
* Updated Clockwork to v5.0
1. [](#improved)
* Updated bundled JQuery to latest version `3.5.1`
* Forward a `sid` to GPM when downloading a premium package via CLI
@@ -20,6 +20,7 @@
* Added XSS detection to all forms. See [documentation](http://learn.grav.local/17/forms/forms/form-options#xss-checks)
* Better handling of missing repository index [grav-plugin-admin#1916](https://github.com/getgrav/grav-plugin-admin/issues/1916)
* Added support for having all sites / environments under `user/env` folder [#3072](https://github.com/getgrav/grav/issues/3072)
* Added `FlexObject::refresh()` method to make sure object is up to date
1. [](#bugfix)
* *Menu Visibility Requires Access* Security option setting wrong frontmatter [login#265](https://github.com/getgrav/grav-plugin-login/issues/265)
* Accessing page with unsupported file extension (jpg, pdf, xsl) will use wrong mime type [#3031](https://github.com/getgrav/grav/issues/3031)

View File

@@ -35,6 +35,7 @@ use RocketTheme\Toolbox\File\YamlFile;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
use RuntimeException;
use function call_user_func_array;
use function count;
use function is_array;
use Grav\Common\Flex\Types\Generic\GenericObject;
use Grav\Common\Flex\Types\Generic\GenericCollection;
@@ -563,8 +564,6 @@ class FlexDirectory implements FlexDirectoryInterface, FlexAuthorizeInterface
/** @var Debugger $debugger */
$debugger = Grav::instance()['debugger'];
$cache = $this->getCache('object');
$keys = [];
$rows = [];
$fetch = [];
@@ -583,48 +582,14 @@ class FlexDirectory implements FlexDirectoryInterface, FlexAuthorizeInterface
}
}
$loading = \count($fetch);
// Attempt to fetch missing rows from the cache.
if ($fetch) {
try {
$debugger->startTimer('flex-objects', sprintf('Flex: Loading %d %s', $loading, $this->type));
$fetched = (array)$cache->getMultiple($fetch);
if ($fetched) {
$index = $this->loadIndex('storage_key');
// Make sure cached objects are up to date: compare against index checksum/timestamp.
/**
* @var string $key
* @var mixed $value
*/
foreach ($fetched as $key => $value) {
if ($value instanceof FlexObjectInterface) {
$objectMeta = $value->getMetaData();
} else {
$objectMeta = $value['__META'] ?? [];
}
$indexMeta = $index->getMetaData($key);
$indexChecksum = $indexMeta['checksum'] ?? $indexMeta['storage_timestamp'] ?? null;
$objectChecksum = $objectMeta['checksum'] ?? $objectMeta['storage_timestamp'] ?? null;
if ($indexChecksum !== $objectChecksum) {
unset($fetched[$key]);
}
}
}
// Update cached rows.
$rows = (array)array_replace($rows, $fetched);
} catch (InvalidArgumentException $e) {
$debugger->addException($e);
}
$rows = (array)array_replace($rows, $this->loadCachedObjects($fetch));
}
// Read missing rows from the storage.
$storage = $this->getStorage();
$updated = [];
$storage = $this->getStorage();
$rows = $storage->readRows($rows, $updated);
// Create objects from the rows.
@@ -669,6 +634,7 @@ class FlexDirectory implements FlexDirectoryInterface, FlexAuthorizeInterface
// Store updated rows to the cache.
if ($updated) {
$cache = $this->getCache('object');
if (!$cache instanceof MemoryCache) {
///** @var Debugger $debugger */
//$debugger = Grav::instance()['debugger'];
@@ -689,6 +655,56 @@ class FlexDirectory implements FlexDirectoryInterface, FlexAuthorizeInterface
return $list;
}
protected function loadCachedObjects(array $fetch): array
{
if (!$fetch) {
return [];
}
/** @var Debugger $debugger */
$debugger = Grav::instance()['debugger'];
$cache = $this->getCache('object');
// Attempt to fetch missing rows from the cache.
$fetched = [];
try {
$loading = count($fetch);
$debugger->startTimer('flex-objects', sprintf('Flex: Loading %d %s', $loading, $this->type));
$fetched = (array)$cache->getMultiple($fetch);
if ($fetched) {
$index = $this->loadIndex('storage_key');
// Make sure cached objects are up to date: compare against index checksum/timestamp.
/**
* @var string $key
* @var mixed $value
*/
foreach ($fetched as $key => $value) {
if ($value instanceof FlexObjectInterface) {
$objectMeta = $value->getMetaData();
} else {
$objectMeta = $value['__META'] ?? [];
}
$indexMeta = $index->getMetaData($key);
$indexChecksum = $indexMeta['checksum'] ?? $indexMeta['storage_timestamp'] ?? null;
$objectChecksum = $objectMeta['checksum'] ?? $objectMeta['storage_timestamp'] ?? null;
if ($indexChecksum !== $objectChecksum) {
unset($fetched[$key]);
}
}
}
} catch (InvalidArgumentException $e) {
$debugger->addException($e);
}
return $fetched;
}
/**
* @return void
*/
@@ -875,7 +891,7 @@ class FlexDirectory implements FlexDirectoryInterface, FlexAuthorizeInterface
$keys = $className::loadEntriesFromStorage($storage);
if (!$cache instanceof MemoryCache) {
$debugger->addMessage(
sprintf('Flex: Caching %s index of %d objects', $this->type, \count($keys)),
sprintf('Flex: Caching %s index of %d objects', $this->type, count($keys)),
'debug'
);
}

View File

@@ -191,6 +191,40 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
return $this->_flexDirectory;
}
public function refresh(): void
{
$key = $this->getStorageKey();
if ('' === $key) {
return;
}
$storage = $this->getFlexDirectory()->getStorage();
$meta = $storage->getMetaData([$key])[$key] ?? null;
$newChecksum = $meta['checksum'] ?? $meta['storage_timestamp'] ?? null;
$curChecksum = $this->_meta['checksum'] ?? $this->_meta['storage_timestamp'] ?? null;
// Check if object is up to date with the storage.
if (null === $newChecksum || $newChecksum === $curChecksum) {
return;
}
$elements = $storage->readRows([$key => null])[$key] ?? null;
if (null !== $elements || isset($elements['__ERROR'])) {
$meta = $elements['_META'] ?? $meta;
$this->filterElements($elements);
$newKey = $meta['key'] ?? $this->getKey();
if ($meta) {
$this->setMetaData($meta);
}
$this->objectConstruct($elements, $newKey);
}
/** @var Debugger $debugger */
$debugger = Grav::instance()['debugger'];
$debugger->addMessage("Refreshed {$this->getFlexType()} object {$this->getKey()}", 'debug');
}
/**
* {@inheritdoc}
* @see FlexObjectInterface::getTimestamp()