refactoring
This commit is contained in:
@@ -40,12 +40,6 @@ class ClassFinder
|
||||
{
|
||||
private $classMap;
|
||||
|
||||
private $pathsTemplate = [
|
||||
'corePath' => 'application/Espo/{category}',
|
||||
'modulePath' => 'application/Espo/Modules/{*}/{category}',
|
||||
'customPath' => 'custom/Espo/Custom/{category}',
|
||||
];
|
||||
|
||||
private $dataHashMap = [];
|
||||
|
||||
public function __construct(ClassMap $classMap)
|
||||
@@ -81,21 +75,9 @@ class ClassFinder
|
||||
|
||||
private function load(string $category, bool $subDirs = false): void
|
||||
{
|
||||
$paths = $this->buildPaths($category);
|
||||
$cacheFile = $this->buildCacheKey($category);
|
||||
|
||||
$this->dataHashMap[$category] = $this->classMap->getData($paths, $cacheFile, null, $subDirs);
|
||||
}
|
||||
|
||||
private function buildPaths(string $category): array
|
||||
{
|
||||
$paths = [];
|
||||
|
||||
foreach ($this->pathsTemplate as $key => $value) {
|
||||
$paths[$key] = str_replace('{category}', $category, $value);
|
||||
}
|
||||
|
||||
return $paths;
|
||||
$this->dataHashMap[$category] = $this->classMap->getData($category, $cacheFile, null, $subDirs);
|
||||
}
|
||||
|
||||
private function buildCacheKey(string $category): string
|
||||
|
||||
@@ -78,13 +78,7 @@ class Schema
|
||||
'custom/Espo/Custom/Core/Utils/Database/DBAL/FieldTypes',
|
||||
];
|
||||
|
||||
/**
|
||||
* Paths of rebuild action folders.
|
||||
*/
|
||||
protected $rebuildActionsPath = [
|
||||
'corePath' => 'application/Espo/Core/Utils/Database/Schema/rebuildActions',
|
||||
'customPath' => 'custom/Espo/Custom/Core/Utils/Database/Schema/rebuildActions',
|
||||
];
|
||||
private $rebuildActionsPath = 'Core/Utils/Database/Schema/rebuildActions';
|
||||
|
||||
/**
|
||||
* Array of rebuildActions classes in format:
|
||||
@@ -295,13 +289,16 @@ class Schema
|
||||
*/
|
||||
protected function initRebuildActions($currentSchema = null, $metadataSchema = null)
|
||||
{
|
||||
$methods = ['beforeRebuild', 'afterRebuild'];
|
||||
$methods = [
|
||||
'beforeRebuild',
|
||||
'afterRebuild',
|
||||
];
|
||||
|
||||
$rebuildActions = $this->classMap->getData($this->rebuildActionsPath, null, $methods);
|
||||
|
||||
$classes = [];
|
||||
|
||||
foreach ($rebuildActions as $actionName => $actionClass) {
|
||||
foreach ($rebuildActions as $actionClass) {
|
||||
$rebuildActionClass = new $actionClass(
|
||||
$this->metadata,
|
||||
$this->config,
|
||||
|
||||
@@ -33,9 +33,10 @@ use Espo\Core\{
|
||||
Utils\Util,
|
||||
Utils\File\Manager as FileManager,
|
||||
Utils\Config,
|
||||
Utils\Metadata,
|
||||
Utils\Module,
|
||||
Utils\DataCache,
|
||||
Utils\Log,
|
||||
Utils\Module\PathProvider,
|
||||
};
|
||||
|
||||
use ReflectionClass;
|
||||
@@ -46,40 +47,37 @@ class ClassMap
|
||||
|
||||
private $config;
|
||||
|
||||
private $metadata;
|
||||
private $module;
|
||||
|
||||
private $dataCache;
|
||||
|
||||
private $log;
|
||||
|
||||
private $pathProvider;
|
||||
|
||||
public function __construct(
|
||||
FileManager $fileManager,
|
||||
Config $config,
|
||||
Metadata $metadata,
|
||||
Module $module,
|
||||
DataCache $dataCache,
|
||||
Log $log
|
||||
){
|
||||
Log $log,
|
||||
PathProvider $pathProvider
|
||||
) {
|
||||
$this->fileManager = $fileManager;
|
||||
$this->config = $config;
|
||||
$this->metadata = $metadata;
|
||||
$this->module = $module;
|
||||
$this->dataCache = $dataCache;
|
||||
$this->log = $log;
|
||||
$this->pathProvider = $pathProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return paths to class files.
|
||||
*
|
||||
* @param string|array $paths in the format ```
|
||||
* [
|
||||
* 'corePath' => '',
|
||||
* 'modulePath' => '',
|
||||
* 'customPath' => '',
|
||||
* ]
|
||||
* ```
|
||||
* @param $allowedMethods If specified, classes w/o specified method will be ignored.
|
||||
*/
|
||||
public function getData(
|
||||
$paths,
|
||||
string $path,
|
||||
?string $cacheKey = null,
|
||||
?array $allowedMethods = null,
|
||||
bool $subDirs = false
|
||||
@@ -87,13 +85,11 @@ class ClassMap
|
||||
|
||||
$data = null;
|
||||
|
||||
if (is_string($paths)) {
|
||||
$paths = [
|
||||
'corePath' => $paths,
|
||||
];
|
||||
}
|
||||
|
||||
if ($cacheKey && $this->dataCache->has($cacheKey) && $this->config->get('useCache')) {
|
||||
if (
|
||||
$cacheKey &&
|
||||
$this->dataCache->has($cacheKey) &&
|
||||
$this->config->get('useCache')
|
||||
) {
|
||||
$data = $this->dataCache->get($cacheKey);
|
||||
|
||||
if (!is_array($data)) {
|
||||
@@ -101,27 +97,38 @@ class ClassMap
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_array($data)) {
|
||||
$data = $this->getClassNameHash($paths['corePath'], $allowedMethods, $subDirs);
|
||||
if (is_array($data)) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
if (isset($paths['modulePath'])) {
|
||||
foreach ($this->metadata->getModuleList() as $moduleName) {
|
||||
$path = str_replace('{*}', $moduleName, $paths['modulePath']);
|
||||
$data = $this->getClassNameHash(
|
||||
$this->pathProvider->getCore() . $path,
|
||||
$allowedMethods,
|
||||
$subDirs
|
||||
);
|
||||
|
||||
$data = array_merge($data, $this->getClassNameHash($path, $allowedMethods, $subDirs));
|
||||
}
|
||||
}
|
||||
foreach ($this->module->getOrderedList() as $moduleName) {
|
||||
$data = array_merge(
|
||||
$data,
|
||||
$this->getClassNameHash(
|
||||
$this->pathProvider->getModule($moduleName) . $path,
|
||||
$allowedMethods,
|
||||
$subDirs
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (isset($paths['customPath'])) {
|
||||
$data = array_merge(
|
||||
$data,
|
||||
$this->getClassNameHash($paths['customPath'], $allowedMethods, $subDirs)
|
||||
);
|
||||
}
|
||||
$data = array_merge(
|
||||
$data,
|
||||
$this->getClassNameHash(
|
||||
$this->pathProvider->getCustom() . $path,
|
||||
$allowedMethods,
|
||||
$subDirs
|
||||
)
|
||||
);
|
||||
|
||||
if ($cacheKey && $this->config->get('useCache')) {
|
||||
$this->dataCache->store($cacheKey, $data);
|
||||
}
|
||||
if ($cacheKey && $this->config->get('useCache')) {
|
||||
$this->dataCache->store($cacheKey, $data);
|
||||
}
|
||||
|
||||
return $data;
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Utils\Module;
|
||||
|
||||
class PathProvider
|
||||
{
|
||||
private $core = 'application/Espo/';
|
||||
|
||||
private $module = 'application/Espo/Modules/{*}/';
|
||||
|
||||
private $custom = 'custom/Espo/Custom/';
|
||||
|
||||
public function __construct() {}
|
||||
|
||||
public function getCore(): string
|
||||
{
|
||||
return $this->core;
|
||||
}
|
||||
|
||||
public function getCustom(): string
|
||||
{
|
||||
return $this->custom;
|
||||
}
|
||||
|
||||
public function getModule(?string $moduleName): string
|
||||
{
|
||||
if ($moduleName === null) {
|
||||
return $this->module;
|
||||
}
|
||||
|
||||
return str_replace('{*}', $moduleName, $this->module);
|
||||
}
|
||||
}
|
||||
@@ -29,32 +29,29 @@
|
||||
|
||||
namespace Espo\Core\Utils\Resource;
|
||||
|
||||
use Espo\Core\Utils\Module\PathProvider as ModulePathProvider;
|
||||
|
||||
class PathProvider
|
||||
{
|
||||
private $core = 'application/Espo/Resources/';
|
||||
private $provider;
|
||||
|
||||
private $module = 'application/Espo/Modules/{*}/Resources/';
|
||||
|
||||
private $custom = 'custom/Espo/Custom/Resources/';
|
||||
|
||||
public function __construct() {}
|
||||
public function __construct(ModulePathProvider $provider)
|
||||
{
|
||||
$this->provider = $provider;
|
||||
}
|
||||
|
||||
public function getCore(): string
|
||||
{
|
||||
return $this->core;
|
||||
return $this->provider->getCore() . 'Resources/';
|
||||
}
|
||||
|
||||
public function getCustom(): string
|
||||
{
|
||||
return $this->custom;
|
||||
return $this->provider->getCustom() . 'Resources/';
|
||||
}
|
||||
|
||||
public function getModule(?string $moduleName): string
|
||||
{
|
||||
if ($moduleName === null) {
|
||||
return $this->module;
|
||||
}
|
||||
|
||||
return str_replace('{*}', $moduleName, $this->module);
|
||||
return $this->provider->getModule($moduleName) . 'Resources/';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,60 +36,129 @@ use Espo\Core\Utils\DataCache;
|
||||
use Espo\Core\Utils\File\Manager as FileManager;
|
||||
use Espo\Core\Utils\Log;
|
||||
|
||||
use Espo\Core\Utils\Config;
|
||||
use Espo\Core\Utils\Module;
|
||||
|
||||
use Espo\Core\Utils\Module\PathProvider;
|
||||
|
||||
class ClassMapTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected $object;
|
||||
|
||||
protected $objects;
|
||||
/**
|
||||
* @var ClassMap
|
||||
*/
|
||||
protected $classMap;
|
||||
|
||||
protected $reflection;
|
||||
|
||||
protected function setUp() : void
|
||||
private $customPath = 'tests/unit/testData/EntryPoints/Espo/Custom/';
|
||||
|
||||
private $corePath = 'tests/unit/testData/EntryPoints/Espo/';
|
||||
|
||||
private $modulePath = 'tests/unit/testData/EntryPoints/Espo/Modules/{*}/';
|
||||
|
||||
/**
|
||||
* @var \PHPUnit\Framework\MockObject\MockObject
|
||||
*/
|
||||
private $module;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->fileManager = new FileManager();
|
||||
|
||||
$this->config = $this->getMockBuilder('Espo\Core\Utils\Config')->disableOriginalConstructor()->getMock();
|
||||
$this->metadata = $this->getMockBuilder('Espo\Core\Utils\Metadata')->disableOriginalConstructor()->getMock();
|
||||
$this->config = $this->createMock(Config::class);
|
||||
$this->module = $this->createMock(Module::class);
|
||||
|
||||
$this->dataCache = $this->getMockBuilder(DataCache::class)->disableOriginalConstructor()->getMock();
|
||||
$this->dataCache = $this->createMock(DataCache::class);
|
||||
|
||||
$this->log = $this->createMock(Log::class);
|
||||
|
||||
$this->object = new ClassMap(
|
||||
$pathProvider = $this->createMock(PathProvider::class);
|
||||
|
||||
$pathProvider
|
||||
->method('getCustom')
|
||||
->willReturn($this->customPath);
|
||||
|
||||
$pathProvider
|
||||
->method('getCore')
|
||||
->willReturn($this->corePath);
|
||||
|
||||
$pathProvider
|
||||
->method('getModule')
|
||||
->willReturnCallback(
|
||||
function (?string $moduleName): string {
|
||||
if ($moduleName === null) {
|
||||
return $this->modulePath;
|
||||
}
|
||||
|
||||
return str_replace('{*}', $moduleName, $this->modulePath);
|
||||
}
|
||||
);
|
||||
|
||||
$this->module
|
||||
->method('getOrderedList')
|
||||
->willReturn(['Crm']);
|
||||
|
||||
$this->classMap = new ClassMap(
|
||||
$this->fileManager,
|
||||
$this->config,
|
||||
$this->metadata,
|
||||
$this->module,
|
||||
$this->dataCache,
|
||||
$this->log
|
||||
$this->log,
|
||||
$pathProvider
|
||||
);
|
||||
|
||||
$this->reflection = new ReflectionHelper($this->object);
|
||||
$this->reflection = new ReflectionHelper($this->classMap);
|
||||
}
|
||||
|
||||
protected function tearDown() : void
|
||||
public function testGetDataWithNoCache1(): void
|
||||
{
|
||||
$this->object = NULL;
|
||||
}
|
||||
|
||||
function testGetClassNameHash()
|
||||
{
|
||||
$paths = [
|
||||
'tests/unit/testData/EntryPoints/Espo/EntryPoints',
|
||||
'tests/unit/testData/EntryPoints/Espo/Modules/Crm/EntryPoints',
|
||||
];
|
||||
|
||||
$result = [
|
||||
$expected = [
|
||||
'Download' => 'tests\unit\testData\EntryPoints\Espo\EntryPoints\Download',
|
||||
'Test' => 'tests\unit\testData\EntryPoints\Espo\EntryPoints\Test',
|
||||
'InModule' => 'tests\unit\testData\EntryPoints\Espo\Modules\Crm\EntryPoints\InModule'
|
||||
];
|
||||
$this->assertEquals($result, $this->reflection->invokeMethod('getClassNameHash', [$paths, ['run']]));
|
||||
|
||||
$this->assertEquals($expected, $this->classMap->getData('EntryPoints', null, ['run']));
|
||||
}
|
||||
|
||||
function testGetDataWithCache()
|
||||
public function testGetDataWithNoCache2(): void
|
||||
{
|
||||
$this->dataCache
|
||||
->expects($this->once())
|
||||
->method('has')
|
||||
->with('entryPoints')
|
||||
->willReturn(true);
|
||||
|
||||
$this->config
|
||||
->expects($this->exactly(2))
|
||||
->method('get')
|
||||
->will($this->returnValue(false));
|
||||
|
||||
$this->module
|
||||
->expects($this->once())
|
||||
->method('getOrderedList')
|
||||
->will($this->returnValue(
|
||||
['Crm']
|
||||
));
|
||||
|
||||
$cacheKey = 'entryPoints';
|
||||
|
||||
$result = [
|
||||
'Download' => 'tests\unit\testData\EntryPoints\Espo\EntryPoints\Download',
|
||||
'Test' => 'tests\unit\testData\EntryPoints\Espo\EntryPoints\Test',
|
||||
'InModule' => 'tests\unit\testData\EntryPoints\Espo\Modules\Crm\EntryPoints\InModule',
|
||||
];
|
||||
|
||||
$this->assertEquals(
|
||||
$result,
|
||||
$this->classMap->getData('EntryPoints', $cacheKey, ['run'])
|
||||
);
|
||||
}
|
||||
|
||||
public function testGetDataWithCache(): void
|
||||
{
|
||||
$result = [
|
||||
'Download' => '\\tests\\unit\\testData\\EntryPoints\\Espo\\EntryPoints\\Download',
|
||||
'Download' => 'tests\\unit\\testData\\EntryPoints\\Espo\\EntryPoints\\Download',
|
||||
];
|
||||
|
||||
$this->config
|
||||
@@ -111,113 +180,51 @@ class ClassMapTest extends \PHPUnit\Framework\TestCase
|
||||
->with('entryPoints')
|
||||
->willReturn($result);
|
||||
|
||||
$paths = [
|
||||
'corePath' => '/tests/unit/testData/EntryPoints/Espo/EntryPoints',
|
||||
'modulePath' => '/tests/unit/testData/EntryPoints/Espo/Modules/{*}/EntryPoints',
|
||||
'customPath' => '/tests/unit/testData/EntryPoints/Espo/Custom/EntryPoints',
|
||||
];
|
||||
$this->module
|
||||
->expects($this->never())
|
||||
->method('getOrderedList');
|
||||
|
||||
$this->assertEquals($result, $this->reflection->invokeMethod('getData', [$paths, $cacheKey, ['run']]) );
|
||||
$this->assertEquals($result, $this->classMap->getData('EntryPoints', $cacheKey, ['run']));
|
||||
}
|
||||
|
||||
function testGetDataWithNoCache()
|
||||
public function testGetDataWithNoCacheString(): void
|
||||
{
|
||||
$this->dataCache
|
||||
->expects($this->once())
|
||||
->method('has')
|
||||
->with('entryPoints')
|
||||
->willReturn(true);
|
||||
|
||||
$this->config
|
||||
->expects($this->exactly(2))
|
||||
->method('get')
|
||||
->will($this->returnValue(false));
|
||||
->with('useCache')
|
||||
->will($this->returnValue(true));
|
||||
|
||||
$this->metadata
|
||||
$this->module
|
||||
->expects($this->once())
|
||||
->method('getModuleList')
|
||||
->method('getOrderedList')
|
||||
->will($this->returnValue(
|
||||
[
|
||||
'Crm',
|
||||
]
|
||||
['Crm']
|
||||
));
|
||||
|
||||
$cacheKey = 'entryPoints';
|
||||
|
||||
$paths = [
|
||||
'corePath' => 'tests/unit/testData/EntryPoints/Espo/EntryPoints',
|
||||
'modulePath' => 'tests/unit/testData/EntryPoints/Espo/Modules/{*}/EntryPoints',
|
||||
'customPath' => 'tests/unit/testData/EntryPoints/Espo/Custom/EntryPoints',
|
||||
];
|
||||
|
||||
$result = [
|
||||
'Download' => 'tests\unit\testData\EntryPoints\Espo\EntryPoints\Download',
|
||||
'Test' => 'tests\unit\testData\EntryPoints\Espo\EntryPoints\Test',
|
||||
'InModule' => 'tests\unit\testData\EntryPoints\Espo\Modules\Crm\EntryPoints\InModule'
|
||||
'InModule' => 'tests\unit\testData\EntryPoints\Espo\Modules\Crm\EntryPoints\InModule',
|
||||
];
|
||||
|
||||
$this->assertEquals($result, $this->reflection->invokeMethod('getData', [$paths, $cacheKey, ['run']]));
|
||||
}
|
||||
|
||||
function testGetDataWithNoCacheString()
|
||||
{
|
||||
$this->dataCache
|
||||
->expects($this->once())
|
||||
->method('has')
|
||||
->with('entryPoints')
|
||||
->with($cacheKey)
|
||||
->willReturn(true);
|
||||
|
||||
$this->config
|
||||
->expects($this->exactly(2))
|
||||
$this->dataCache
|
||||
->expects($this->once())
|
||||
->method('get')
|
||||
->will($this->returnValue(false));
|
||||
->with($cacheKey)
|
||||
->willReturn(null);
|
||||
|
||||
$this->metadata
|
||||
->expects($this->never())
|
||||
->method('getModuleList')
|
||||
->will($this->returnValue(
|
||||
[
|
||||
'Crm',
|
||||
]
|
||||
));
|
||||
|
||||
$cacheKey = 'entryPoints';
|
||||
$path = 'tests/unit/testData/EntryPoints/Espo/EntryPoints';
|
||||
|
||||
$result = [
|
||||
'Download' => 'tests\unit\testData\EntryPoints\Espo\EntryPoints\Download',
|
||||
'Test' => 'tests\unit\testData\EntryPoints\Espo\EntryPoints\Test',
|
||||
];
|
||||
|
||||
$this->assertEquals($result, $this->reflection->invokeMethod('getData', [$path, $cacheKey, ['run']]));
|
||||
}
|
||||
|
||||
function testGetDataWithCacheFalse()
|
||||
{
|
||||
$this->config
|
||||
->expects($this->never())
|
||||
->method('get')
|
||||
->will($this->returnValue(false));
|
||||
|
||||
$this->metadata
|
||||
->expects($this->never())
|
||||
->method('getModuleList')
|
||||
->will($this->returnValue(
|
||||
[
|
||||
'Crm',
|
||||
]
|
||||
));
|
||||
|
||||
$paths = [
|
||||
'corePath' => 'tests/unit/testData/EntryPoints/Espo/EntryPoints',
|
||||
'customPath' => 'tests/unit/testData/EntryPoints/Espo/Custom/EntryPoints',
|
||||
];
|
||||
|
||||
$result = [
|
||||
'Download' => 'tests\unit\testData\EntryPoints\Espo\EntryPoints\Download',
|
||||
'Test' => 'tests\unit\testData\EntryPoints\Espo\EntryPoints\Test',
|
||||
];
|
||||
|
||||
$this->assertEquals($result, $this->reflection->invokeMethod('getData', [$paths, null, ['run']]));
|
||||
$this->assertEquals(
|
||||
$result,
|
||||
$this->classMap->getData('EntryPoints', $cacheKey, ['run'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,8 @@ use Espo\Core\Utils\Module;
|
||||
use Espo\Core\Utils\Resource\Reader;
|
||||
use Espo\Core\Utils\Resource\PathProvider;
|
||||
|
||||
use Espo\Core\Utils\Module\PathProvider as ModulePathProvider;
|
||||
|
||||
class MetadataTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected $object;
|
||||
@@ -59,7 +61,7 @@ class MetadataTest extends \PHPUnit\Framework\TestCase
|
||||
|
||||
$module = new Module($this->fileManager);
|
||||
|
||||
$pathProvider = new PathProvider();
|
||||
$pathProvider = new PathProvider(new ModulePathProvider());
|
||||
|
||||
$unifierObj = new UnifierObj($this->fileManager, $module, $pathProvider);
|
||||
$unifier = new Unifier($this->fileManager, $module, $pathProvider);
|
||||
|
||||
Reference in New Issue
Block a user