diff --git a/application/Espo/Core/Application.php b/application/Espo/Core/Application.php index 702b5e91d9..6135a1955e 100644 --- a/application/Espo/Core/Application.php +++ b/application/Espo/Core/Application.php @@ -44,6 +44,7 @@ use Espo\Core\{ Loaders\FileManager as FileManagerLoader, Loaders\DataManager as DataManagerLoader, Loaders\Metadata as MetadataLoader, + Loaders\DataCache as DataCacheLoader, }; use ReflectionClass; @@ -60,6 +61,7 @@ class Application 'log' => LogLoader::class, 'fileManager' => FileManagerLoader::class, 'dataManager' => DataManagerLoader::class, + 'dataCache' => DataCacheLoader::class, 'metadata' => MetadataLoader::class, ]; diff --git a/application/Espo/Core/Loaders/Metadata.php b/application/Espo/Core/Loaders/Metadata.php index 2176867183..9290a0fb03 100644 --- a/application/Espo/Core/Loaders/Metadata.php +++ b/application/Espo/Core/Loaders/Metadata.php @@ -32,27 +32,28 @@ namespace Espo\Core\Loaders; use Espo\Core\{ Utils\Metadata as MetadataService, InjectableFactory, + Utils\File\Manager as FileManager, + Utils\DataCache, Utils\Config, }; class Metadata implements Loader { - protected $injectableFactory; + protected $fileManager; + protected $dataCache; protected $config; - public function __construct(InjectableFactory $injectableFactory, Config $config) + public function __construct(FileManager $fileManager, DataCache $dataCache, Config $config) { - $this->injectableFactory = $injectableFactory; + $this->fileManager = $fileManager; + $this->dataCache = $dataCache; $this->config = $config; } public function load() : MetadataService { - return $this->injectableFactory->createWith( - MetadataService::class, - [ - 'useCache' => $this->config->get('useCache'), - ] - ); + $useCache = $this->config->get('useCache'); + + return new MetadataService($this->fileManager, $this->dataCache, $useCache); } } diff --git a/application/Espo/Core/Utils/Metadata.php b/application/Espo/Core/Utils/Metadata.php index 4ecb728725..0fd79b796d 100644 --- a/application/Espo/Core/Utils/Metadata.php +++ b/application/Espo/Core/Utils/Metadata.php @@ -35,6 +35,7 @@ use Espo\Core\{ Utils\File\Unifier, Utils\Module, Utils\Metadata\Helper, + Utils\DataCache, }; class Metadata @@ -49,17 +50,15 @@ class Metadata private $objUnifier; - private $fileManager; - private $module; private $metadataHelper; protected $pathToModules = 'application/Espo/Modules'; - protected $cacheFile = 'data/cache/application/metadata.php'; + protected $cacheKey = 'metadata'; - protected $objCacheFile = 'data/cache/application/objMetadata.php'; + protected $objCacheKey = 'objMetadata'; protected $paths = [ 'corePath' => 'application/Espo/Resources/metadata', @@ -75,10 +74,15 @@ class Metadata private $changedData = []; - public function __construct(FileManager $fileManager, bool $useCache = false) + private $fileManager; + private $dataCache; + + public function __construct(FileManager $fileManager, DataCache $dataCache, bool $useCache = false) { - $this->useCache = $useCache; $this->fileManager = $fileManager; + $this->dataCache = $dataCache; + + $this->useCache = $useCache; } protected function getObjUnifier() @@ -93,7 +97,7 @@ class Metadata protected function getModule() { if (!isset($this->module)) { - $this->module = new Module($this->fileManager, $this->useCache); + $this->module = new Module($this->fileManager, $this->dataCache, $this->useCache); } return $this->module; @@ -108,19 +112,6 @@ class Metadata return $this->metadataHelper; } - public function isCached() - { - if (!$this->useCache) { - return false; - } - - if (file_exists($this->cacheFile)) { - return true; - } - - return false; - } - /** * Init metadata. */ @@ -130,8 +121,8 @@ class Metadata $reload = true; } - if (file_exists($this->cacheFile) && !$reload) { - $this->data = $this->fileManager->getPhpContents($this->cacheFile); + if ($this->dataCache->has($this->cacheKey) && !$reload) { + $this->data = $this->dataCache->get($this->cacheKey); return; } @@ -143,11 +134,7 @@ class Metadata $this->data = Util::objectToArray($objData); if ($this->useCache) { - $isSaved = $this->fileManager->putPhpContents($this->cacheFile, $this->data); - - if ($isSaved === false) { - $GLOBALS['log']->emergency('Metadata:init() - metadata has not been saved to a cache file'); - } + $this->dataCache->store($this->cacheKey, $this->data); } } @@ -207,8 +194,8 @@ class Metadata $reload = true; } - if (file_exists($this->objCacheFile) && !$reload) { - $this->objData = $this->fileManager->getPhpContents($this->objCacheFile); + if ($this->dataCache->has($this->objCacheKey) && !$reload) { + $this->objData = $this->dataCache->get($this->objCacheKey); return; } @@ -217,11 +204,7 @@ class Metadata $this->objData = $this->addAdditionalFieldsObj($this->objData); if ($this->useCache) { - $isSaved = $this->fileManager->putPhpContents($this->objCacheFile, $this->objData, true); - - if ($isSaved === false) { - $GLOBALS['log']->emergency('Metadata:objInit() - metadata has not been saved to a cache file'); - } + $this->dataCache->store($this->objCacheKey, $this->objData); } } diff --git a/application/Espo/Core/Utils/Module.php b/application/Espo/Core/Utils/Module.php index 78d82493bb..8ffdb19661 100644 --- a/application/Espo/Core/Utils/Module.php +++ b/application/Espo/Core/Utils/Module.php @@ -33,6 +33,7 @@ use Espo\Core\{ Exceptions\Error, Utils\File\Manager as FileManager, Utils\File\FileUnifier, + Utils\DataCache, }; /** @@ -40,15 +41,13 @@ use Espo\Core\{ */ class Module { - private $fileManager; - private $useCache; private $unifier; protected $data = null; - protected $cacheFile = 'data/cache/application/modules.php'; + protected $cacheKey = 'modules'; protected $paths = [ 'corePath' => 'application/Espo/Resources/module.json', @@ -56,9 +55,13 @@ class Module 'customPath' => 'custom/Espo/Custom/Resources/module.json', ]; - public function __construct(FileManager $fileManager, bool $useCache = false) + private $fileManager; + private $dataCache; + + public function __construct(FileManager $fileManager, DataCache $dataCache, bool $useCache = false) { $this->fileManager = $fileManager; + $this->dataCache = $dataCache; $this->unifier = new FileUnifier($this->fileManager); @@ -91,8 +94,8 @@ class Module protected function init() { - if (file_exists($this->cacheFile) && $this->useCache) { - $this->data = $this->fileManager->getPhpContents($this->cacheFile); + if ($this->dataCache->has($this->cacheKey) && $this->useCache) { + $this->data = $this->dataCache->get($this->cacheKey); return; } @@ -100,11 +103,7 @@ class Module $this->data = $this->unifier->unify($this->paths, true); if ($this->useCache) { - $result = $this->fileManager->putPhpContents($this->cacheFile, $this->data, false, true); - - if ($result === false) { - throw new Error('Module: Could not save unified module data.'); - } + $this->dataCache->store($this->cacheKey, $this->data); } } } diff --git a/tests/unit/Espo/Core/Utils/MetadataTest.php b/tests/unit/Espo/Core/Utils/MetadataTest.php index 5ccc1bedbc..89b42c00c3 100644 --- a/tests/unit/Espo/Core/Utils/MetadataTest.php +++ b/tests/unit/Espo/Core/Utils/MetadataTest.php @@ -31,6 +31,11 @@ namespace tests\unit\Espo\Core\Utils; use tests\unit\ReflectionHelper; +use Espo\Core\Utils\Metadata; +use Espo\Core\Utils\File\Manager as FileManager; +use Espo\Core\Utils\Log; +use Espo\Core\Utils\DataCache; + class MetadataTest extends \PHPUnit\Framework\TestCase { protected $object; @@ -39,33 +44,19 @@ class MetadataTest extends \PHPUnit\Framework\TestCase protected $reflection; - protected $defaultCacheFile = 'tests/unit/testData/Utils/Metadata/metadata.php'; - protected $defaultObjCacheFile = 'tests/unit/testData/Utils/Metadata/metadata.php'; - - protected $cacheFile = 'tests/unit/testData/cache/metadata.php'; - protected $objCacheFile = 'tests/unit/testData/cache/objMetadata.php'; - protected function setUp() : void { - /*copy defaultCacheFile file to cache*/ - if (!file_exists($this->cacheFile)) { - copy($this->defaultCacheFile, $this->cacheFile); - } + $this->fileManager = new FileManager(); - if (!file_exists($this->objCacheFile)) { - copy($this->defaultObjCacheFile, $this->objCacheFile); - } + $this->dataCache = $this->getMockBuilder(DataCache::class)->disableOriginalConstructor()->getMock(); - $this->objects['fileManager'] = new \Espo\Core\Utils\File\Manager(); + $this->log = $this->getMockBuilder(Log::class)->disableOriginalConstructor()->getMock(); - $this->objects['log'] = $this->getMockBuilder('\\Espo\\Core\\Utils\\Log')->disableOriginalConstructor()->getMock(); - $GLOBALS['log'] = $this->objects['log']; + $GLOBALS['log'] = $this->log; - $this->object = new \Espo\Core\Utils\Metadata($this->objects['fileManager'], true); + $this->object = new Metadata($this->fileManager, $this->dataCache, true); $this->reflection = new ReflectionHelper($this->object); - $this->reflection->setProperty('cacheFile', $this->cacheFile); - $this->reflection->setProperty('objCacheFile', $this->objCacheFile); } protected function tearDown() : void @@ -96,7 +87,9 @@ class MetadataTest extends \PHPUnit\Framework\TestCase ), ), ); + $this->object->set('entityDefs', 'Attachment', $data); + $this->assertEquals('Views.Test.Custom', $this->object->get('entityDefs.Attachment.fields.name.view')); $this->assertEquals(150, $this->object->get('entityDefs.Attachment.fields.name.maxLength')); @@ -116,6 +109,7 @@ class MetadataTest extends \PHPUnit\Framework\TestCase ), ), ); + $this->object->set('entityDefs', 'Attachment', $data); $this->assertEquals(200, $this->object->get('entityDefs.Attachment.fields.name.maxLength')); $this->assertEquals('Views.Test.Custom', $this->object->get('entityDefs.Attachment.fields.name.view')); @@ -158,6 +152,7 @@ class MetadataTest extends \PHPUnit\Framework\TestCase ), ), ); + $this->assertEquals($result, $this->reflection->getProperty('deletedData')); $data = array ( @@ -182,15 +177,16 @@ class MetadataTest extends \PHPUnit\Framework\TestCase $this->assertNotNull($this->object->get('entityDefs.Attachment.fields.name.required')); $this->object->clearChanges(); - $this->assertEquals(array(), $this->reflection->getProperty('deletedData')); + $this->assertEquals([], $this->reflection->getProperty('deletedData')); } public function testUndelete() { - $data = array ( + $data = [ 'fields.name.type', 'fields.name.required', - ); + ]; + $this->object->delete('entityDefs', 'Attachment', $data); $this->assertNull($this->object->get('entityDefs.Attachment.fields.name.type')); @@ -242,11 +238,13 @@ class MetadataTest extends \PHPUnit\Framework\TestCase $paths = $this->reflection->getProperty('paths'); $paths['customPath'] = $customPath; + $this->reflection->setProperty('paths', $paths); $this->assertNull($this->object->getCustom('entityDefs', 'Lead')); $customData = $this->object->getCustom('entityDefs', 'Lead', (object) []); + $this->assertTrue(is_object($customData)); $data = (object) [ @@ -257,6 +255,7 @@ class MetadataTest extends \PHPUnit\Framework\TestCase ], ], ]; + $this->object->saveCustom('entityDefs', 'Lead', $data); $this->assertEquals($data, $this->object->getCustom('entityDefs', 'Lead')); @@ -286,7 +285,8 @@ class MetadataTest extends \PHPUnit\Framework\TestCase $this->object->saveCustom('entityDefs', 'Lead', $data); $savedFile = $customPath . '/entityDefs/Lead.json'; - $fileContent = $this->objects['fileManager']->getContents($savedFile); + $fileContent = $this->fileManager->getContents($savedFile); + $savedData = \Espo\Core\Utils\Json::decode($fileContent); $this->assertEquals($data, $savedData); @@ -324,7 +324,7 @@ class MetadataTest extends \PHPUnit\Framework\TestCase $this->object->saveCustom('entityDefs', 'Lead', $customData); $savedFile = $customPath . '/entityDefs/Lead.json'; - $fileContent = $this->objects['fileManager']->getContents($savedFile); + $fileContent = $this->fileManager->getContents($savedFile); $savedData = \Espo\Core\Utils\Json::decode($fileContent); $expectedData = (object) [