diff --git a/.gitignore b/.gitignore index 5637072d95..20b464b902 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,7 @@ /composer.phar /vendor/ /custom/Espo/Custom/* +/custom/Espo/Modules/* +!/custom/Espo/Custom/.htaccess +!/custom/Espo/Modules/.htaccess /install/config.php diff --git a/Gruntfile.js b/Gruntfile.js index 237c8ec426..44ee22fa3f 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -101,7 +101,9 @@ module.exports = grunt => { beforeFinal: { src: [ 'build/tmp/custom/Espo/Custom/*', + 'build/tmp/custom/Espo/Modules/*', '!build/tmp/custom/Espo/Custom/.htaccess', + '!build/tmp/custom/Espo/Modules/.htaccess', 'build/tmp/install/config.php', 'build/tmp/vendor/*/*/.git', ] diff --git a/application/Espo/Core/Utils/Module.php b/application/Espo/Core/Utils/Module.php index da94fca826..5f07e651cc 100644 --- a/application/Espo/Core/Utils/Module.php +++ b/application/Espo/Core/Utils/Module.php @@ -48,9 +48,13 @@ class Module private $list = null; + private $internalList = null; + private $cacheKey = 'modules'; - private $pathToModules = 'application/Espo/Modules'; + private $internalPath = 'application/Espo/Modules'; + + private $customPath = 'custom/Espo/Modules'; private $moduleFilePath = 'Resources/module.json'; @@ -141,10 +145,34 @@ class Module return array_keys($modulesToSort); } + private function getInternalList(): array + { + if ($this->internalList === null) { + $this->internalList = $this->fileManager->getDirList($this->internalPath); + } + + return $this->internalList; + } + + private function isInternal(string $moduleName): bool + { + return in_array($moduleName, $this->getInternalList()); + } + + public function getModulePath(string $moduleName): string + { + $basePath = $this->isInternal($moduleName) ? $this->internalPath : $this->customPath; + + return $basePath . '/' . $moduleName; + } + private function getList(): array { if ($this->list === null) { - $this->list = $this->fileManager->getDirList($this->pathToModules); + $this->list = array_merge( + $this->getInternalList(), + $this->fileManager->getDirList($this->customPath) + ); } return $this->list; @@ -155,7 +183,7 @@ class Module $data = []; foreach ($this->getList() as $moduleName) { - $path = $this->pathToModules . '/' . $moduleName . '/' . $this->moduleFilePath; + $path = $this->getModulePath($moduleName) . '/' . $this->moduleFilePath; $itemContents = $this->fileManager->getContents($path); diff --git a/application/Espo/Core/Utils/Module/PathProvider.php b/application/Espo/Core/Utils/Module/PathProvider.php index 76db8c93c9..a184cd66e5 100644 --- a/application/Espo/Core/Utils/Module/PathProvider.php +++ b/application/Espo/Core/Utils/Module/PathProvider.php @@ -29,32 +29,33 @@ namespace Espo\Core\Utils\Module; +use Espo\Core\Utils\Module; + class PathProvider { - private $core = 'application/Espo/'; + private $corePath = 'application/Espo/'; - private $module = 'application/Espo/Modules/{*}/'; + private $customPath = 'custom/Espo/Custom/'; - private $custom = 'custom/Espo/Custom/'; + private $module; - public function __construct() {} + public function __construct(Module $module) + { + $this->module = $module; + } public function getCore(): string { - return $this->core; + return $this->corePath; } public function getCustom(): string { - return $this->custom; + return $this->customPath; } - public function getModule(?string $moduleName): string + public function getModule(string $moduleName): string { - if ($moduleName === null) { - return $this->module; - } - - return str_replace('{*}', $moduleName, $this->module); + return $this->module->getModulePath($moduleName) . '/'; } } diff --git a/application/Espo/Core/Utils/Resource/PathProvider.php b/application/Espo/Core/Utils/Resource/PathProvider.php index 5157561871..4078b0c23f 100644 --- a/application/Espo/Core/Utils/Resource/PathProvider.php +++ b/application/Espo/Core/Utils/Resource/PathProvider.php @@ -50,7 +50,7 @@ class PathProvider return $this->provider->getCustom() . 'Resources/'; } - public function getModule(?string $moduleName): string + public function getModule(string $moduleName): string { return $this->provider->getModule($moduleName) . 'Resources/'; } diff --git a/composer.json b/composer.json index 7f538fc518..da5dd882ce 100644 --- a/composer.json +++ b/composer.json @@ -48,7 +48,8 @@ "autoload": { "psr-4": { "Espo\\": "application/Espo/", - "Espo\\Custom\\": "custom/Espo/Custom/" + "Espo\\Custom\\": "custom/Espo/Custom/", + "Espo\\Modules\\": "custom/Espo/Modules/" } }, "autoload-dev": { diff --git a/custom/Espo/Modules/.htaccess b/custom/Espo/Modules/.htaccess new file mode 100644 index 0000000000..2859d7f432 --- /dev/null +++ b/custom/Espo/Modules/.htaccess @@ -0,0 +1,2 @@ +Order Deny,Allow +Deny from all \ No newline at end of file diff --git a/tests/unit/Espo/Core/Utils/MetadataTest.php b/tests/unit/Espo/Core/Utils/MetadataTest.php index fa83c84361..5c7bad4659 100644 --- a/tests/unit/Espo/Core/Utils/MetadataTest.php +++ b/tests/unit/Espo/Core/Utils/MetadataTest.php @@ -60,7 +60,7 @@ class MetadataTest extends \PHPUnit\Framework\TestCase $module = new Module($this->fileManager); - $pathProvider = new PathProvider(new ModulePathProvider()); + $pathProvider = new PathProvider(new ModulePathProvider($module)); $unifierObj = new UnifierObj($this->fileManager, $module, $pathProvider); $unifier = new Unifier($this->fileManager, $module, $pathProvider);