service improvements

This commit is contained in:
Yuri Kuznetsov
2020-06-19 17:26:40 +03:00
parent 74e4012fee
commit 4f82ae38cf
4 changed files with 65 additions and 59 deletions

View File

@@ -34,7 +34,8 @@ class ServiceFactory extends Base
public function load()
{
return new \Espo\Core\ServiceFactory(
$this->getContainer()
$this->getContainer()->get('classFinder'),
$this->getContainer()->get('injectableFactory')
);
}
}

View File

@@ -31,26 +31,27 @@ namespace Espo\Core;
use Espo\Core\Exceptions\Error;
use Espo\Core\Utils\ClassFinder;
use Espo\Core\InjectableFactory;
class ServiceFactory
{
private $container;
protected $classFinder;
protected $injectableFactory;
public function __construct(Container $container)
public function __construct(ClassFinder $classFinder, InjectableFactory $injectableFactory)
{
$this->container = $container;
$this->classFinder = $classFinder;
$this->injectableFactory = $injectableFactory;
}
protected function getContainer()
protected function getClassName(string $name)
{
return $this->container;
return $this->classFinder->find('Services', $name, true);
}
protected function getClassName($name)
public function checkExists(string $name) : bool
{
return $this->getContainer()->get('classFinder')->find('Services', $name);
}
public function checkExists($name) {
$className = $this->getClassName($name);
if (!$className) {
return false;
@@ -58,28 +59,19 @@ class ServiceFactory
return true;
}
public function create($name)
public function create(string $name) : object
{
$className = $this->getClassName($name);
if (!$className) {
throw new Error("Service '{$name}' was not found.");
}
return $this->createByClassName($className);
}
protected function createByClassName($className)
{
if (class_exists($className)) {
$service = new $className();
$dependencyList = $service->getDependencyList();
foreach ($dependencyList as $name) {
$service->inject($name, $this->container->get($name));
}
if (method_exists($service, 'prepare')) {
$service->prepare();
}
return $service;
$obj = $this->injectableFactory->create($className);
if (method_exists($obj, 'prepare')) {
$obj->prepare();
}
throw new Error("Class '$className' does not exist.");
return $obj;
}
}

View File

@@ -49,9 +49,9 @@ class ClassFinder
/**
* Find class name by category (e.g. Controllers, Services) and name.
*/
public function find(string $category, string $name) : ?string
public function find(string $category, string $name, bool $subDirs = false) : ?string
{
$map = $this->getMap($category);
$map = $this->getMap($category, $subDirs);
$className = $map[$name] ?? null;
return $className;
}
@@ -59,19 +59,19 @@ class ClassFinder
/**
* Get [name => class-name] map.
*/
public function getMap(string $category) : array
public function getMap(string $category, bool $subDirs = false) : array
{
if (!array_key_exists($category, $this->dataHash)) {
$this->load($category);
$this->load($category, $subDirs);
}
return $this->dataHash[$category] ?? [];
}
protected function load(string $category)
protected function load(string $category, bool $subDirs = false)
{
$path = $this->buildPaths($category);
$cacheFile = $this->buildCacheFilePath($category);
$this->dataHash[$category] = $this->classParser->getData($path, $cacheFile);
$this->dataHash[$category] = $this->classParser->getData($path, $cacheFile, null, $subDirs);
}
protected function buildPaths(string $category) : array

View File

@@ -77,7 +77,7 @@ class ClassParser
* @param $cacheFile Full path for a cache file, ex. data/cache/application/entryPoints.php.
* @param $allowedMethods If specified, classes w/o specified method will be ignored.
*/
public function getData($paths, ?string $cacheFile = null, ?array $allowedMethods = null) : array
public function getData($paths, ?string $cacheFile = null, ?array $allowedMethods = null, bool $subDirs = false) : array
{
$data = null;
@@ -96,18 +96,18 @@ class ClassParser
}
if (!is_array($data)) {
$data = $this->getClassNameHash($paths['corePath'], $allowedMethods);
$data = $this->getClassNameHash($paths['corePath'], $allowedMethods, $subDirs);
if (isset($paths['modulePath'])) {
foreach ($this->getMetadata()->getModuleList() as $moduleName) {
$path = str_replace('{*}', $moduleName, $paths['modulePath']);
$data = array_merge($data, $this->getClassNameHash($path, $allowedMethods));
$data = array_merge($data, $this->getClassNameHash($path, $allowedMethods, $subDirs));
}
}
if (isset($paths['customPath'])) {
$data = array_merge($data, $this->getClassNameHash($paths['customPath'], $allowedMethods));
$data = array_merge($data, $this->getClassNameHash($paths['customPath'], $allowedMethods, $subDirs));
}
if ($cacheFile && $this->getConfig()->get('useCache')) {
@@ -121,7 +121,7 @@ class ClassParser
return $data;
}
protected function getClassNameHash($dirs, ?array $allowedMethods = [])
protected function getClassNameHash($dirs, ?array $allowedMethods = [], bool $subDirs = false)
{
if (is_string($dirs)) {
$dirs = (array) $dirs;
@@ -130,31 +130,44 @@ class ClassParser
$data = [];
foreach ($dirs as $dir) {
if (file_exists($dir)) {
$fileList = $this->getFileManager()->getFileList($dir, false, '\.php$', true);
$fileList = $this->getFileManager()->getFileList($dir, $subDirs, '\.php$', true);
foreach ($fileList as $file) {
$filePath = Util::concatPath($dir, $file);
$className = Util::getClassName($filePath);
$fileName = $this->getFileManager()->getFileName($filePath);
$scopeName = ucfirst($fileName);
$normalizedScopeName = Util::normilizeScopeName($scopeName);
if (empty($allowedMethods)) {
$data[$normalizedScopeName] = $className;
continue;
}
foreach ($allowedMethods as $methodName) {
if (method_exists($className, $methodName)) {
$data[$normalizedScopeName] = $className;
}
}
}
$this->fillHashFromFileList($fileList, $dir, $allowedMethods, $data);
}
}
return $data;
}
protected function fillHashFromFileList(
array $fileList, string $dir, ?array $allowedMethods, array &$data, string $category = ''
) {
foreach ($fileList as $key => $file) {
if (is_string($key)) {
if (is_array($file)) {
$this->fillHashFromFileList($file, $dir . '/'. $key, $allowedMethods, $data, $category . $key . '\\');
}
continue;
}
$filePath = Util::concatPath($dir, $file);
$className = Util::getClassName($filePath);
$fileName = $this->getFileManager()->getFileName($filePath);
$name = Util::normilizeScopeName(ucfirst($fileName));
$name = $category . $name;
if (empty($allowedMethods)) {
$data[$name] = $className;
continue;
}
foreach ($allowedMethods as $methodName) {
if (method_exists($className, $methodName)) {
$data[$name] = $className;
}
}
}
}
}