diff --git a/application/Espo/Core/Container.php b/application/Espo/Core/Container.php index a139fa2eab..44e73bac53 100644 --- a/application/Espo/Core/Container.php +++ b/application/Espo/Core/Container.php @@ -87,6 +87,13 @@ class Container ); } + private function loadEntryPointManager() + { + return new \Espo\Core\EntryPointManager( + $this + ); + } + private function loadLog() { return new \Espo\Core\Utils\Log( diff --git a/application/Espo/Core/EntryPointManager.php b/application/Espo/Core/EntryPointManager.php new file mode 100644 index 0000000000..776f9923d6 --- /dev/null +++ b/application/Espo/Core/EntryPointManager.php @@ -0,0 +1,153 @@ + 'application/Espo/EntryPoints', + 'modulePath' => 'application/Espo/Modules/{*}/EntryPoints', + ); + + /** + * @var array - path to entryPoint files in a custom folder + */ + private $customPaths = array( + 'corePath' => 'application/Espo/Custom/EntryPoints', + 'modulePath' => 'application/Espo/Custom/Modules/{*}/EntryPoints', + ); + + + + public function __construct(\Espo\Core\Container $container) + { + $this->container = $container; + $this->fileManager = $this->getContainer()->get('fileManager'); + } + + protected function getContainer() + { + return $this->container; + } + + protected function getFileManager() + { + return $this->fileManager; + } + + + public function run($name) + { + $className = $this->get($name); + if ($className === false) { + throw new NotFound(); + } + + $entryPoint = new $className($this->container); + + $entryPoint->run(); + } + + + public function get($name = '') + { + if (!isset($this->data)) { + $this->init(); + } + + if (empty($name)) { + return $this->data; + } + + $name = ucfirst($name); + if (isset($this->data[$name])) { + return $this->data[$name]; + } + + return false; + } + + + public function getAll() + { + return $this->get(); + } + + + protected function init() + { + if (file_exists($this->cacheFile) && $this->getContainer()->get('config')->get('useCache')) { + $this->data = $this->getFileManager()->getContent($this->cacheFile); + } else { + + $this->data = $this->getData( array($this->paths['corePath'], $this->customPaths['corePath']) ); + foreach ($this->getContainer()->get('metadata')->getModuleList() as $moduleName) { + $path = str_replace('{*}', $moduleName, $this->paths['modulePath']); + $customPath = str_replace('{*}', $moduleName, $this->customPaths['modulePath']); + + $this->data = array_merge($this->data, $this->getData(array($path, $customPath))); + } + + $result = $this->getFileManager()->setContentPHP($this->data, $this->cacheFile); + if ($result == false) { + $GLOBALS['log']->add('EXCEPTION', 'EntryPoint::init() - Cannot save EntryPoints to a file'); + throw new \Espo\Core\Exceptions\Error(); + } + } + } + + protected function getData(array $dirs) + { + $entryPoints = array(); + + foreach ($dirs as $dir) { + + if (file_exists($dir)) { + $fileList = $this->getFileManager()->getFileList($dir, false, '\.php$', 'file'); + + foreach ($fileList as $file) { + + $filePath = Util::concatPath($dir, $file); + + $className = Util::getClassName($filePath); + $fileName = $this->getFileManager()->getFileName($filePath); + + foreach ($this->allowMethods as $methodName) { + if (method_exists($className, $methodName)) { + $entryPoints[$fileName] = $className; + } + } + + } + } + + } + + return $entryPoints; + } + + + + + + + +} \ No newline at end of file diff --git a/application/Espo/Core/Utils/Database/Schema/Converter.php b/application/Espo/Core/Utils/Database/Schema/Converter.php index 147e05d8da..997e2fc067 100644 --- a/application/Espo/Core/Utils/Database/Schema/Converter.php +++ b/application/Espo/Core/Utils/Database/Schema/Converter.php @@ -11,7 +11,7 @@ class Converter private $dbalSchema; private $fileManager; - private $customTablePath = 'application/Espo/Core/Utils/Database/Schema/CustomTables'; + private $customTablePath = 'application/Espo/Core/Utils/Database/Schema/tables'; protected $typeList; @@ -62,13 +62,19 @@ class Converter } - //convertToSchema public function process(array $ormMeta, $entityDefs) { $GLOBALS['log']->add('Debug', 'Schema\Converter - Start: building schema'); //check if exist files in "Tables" directory and merge with ormMetadata - $ormMeta = Util::merge($ormMeta, $this->getCustomTables()); + $ormMeta = Util::merge($ormMeta, $this->getCustomTables()); + + //unset some keys in orm + if (isset($ormMeta['unset'])) { + $ormMeta = Util::unsetInArray($ormMeta, $ormMeta['unset']); + unset($ormMeta['unset']); + } //END: unset some keys in orm + $schema = $this->getSchema(); @@ -269,8 +275,8 @@ class Converter foreach($fileList as $fileName) { $fileData = $this->getFileManager()->getContent($this->customTablePath, $fileName); - if (is_array($fileData)) { - $customTables = array_merge($customTables, $fileData); + if (is_array($fileData)) { + $customTables = Util::merge($customTables, $fileData); } } diff --git a/application/Espo/Core/Utils/Database/Schema/tables/preferences.php b/application/Espo/Core/Utils/Database/Schema/tables/preferences.php new file mode 100644 index 0000000000..3c54e4b331 --- /dev/null +++ b/application/Espo/Core/Utils/Database/Schema/tables/preferences.php @@ -0,0 +1,10 @@ + array( + 'Preferences', + ), + +); + diff --git a/application/Espo/Core/Utils/Database/Schema/tables/settings.php b/application/Espo/Core/Utils/Database/Schema/tables/settings.php new file mode 100644 index 0000000000..2e2eb3d0b6 --- /dev/null +++ b/application/Espo/Core/Utils/Database/Schema/tables/settings.php @@ -0,0 +1,10 @@ + array( + 'Settings', + ), + +); + diff --git a/application/Espo/Core/Utils/Database/Schema/CustomTables/Subscription.php b/application/Espo/Core/Utils/Database/Schema/tables/subscription.php similarity index 100% rename from application/Espo/Core/Utils/Database/Schema/CustomTables/Subscription.php rename to application/Espo/Core/Utils/Database/Schema/tables/subscription.php diff --git a/application/Espo/Core/Utils/File/Manager.php b/application/Espo/Core/Utils/File/Manager.php index 24559d82ee..176d9de4af 100644 --- a/application/Espo/Core/Utils/File/Manager.php +++ b/application/Espo/Core/Utils/File/Manager.php @@ -395,26 +395,24 @@ class Manager * * @return array */ - function getFileName($filename, $ext='') - { + public function getFileName($fileName, $ext='') + { if (empty($ext)) { - $realFileName= substr($filename, 0, strrpos($filename, '.', -1)); + $fileName= substr($fileName, 0, strrpos($fileName, '.', -1)); } else { if (substr($ext, 0, 1)!='.') { $ext= '.'.$ext; } - if (substr($filename, -(strlen($ext)))==$ext) { - $realFileName= substr($filename, 0, -(strlen($ext))); + if (substr($fileName, -(strlen($ext)))==$ext) { + $fileName= substr($fileName, 0, -(strlen($ext))); } } - if (!empty($realFileName)) { - return $realFileName; - } + $exFileName = explode('/', Utils\Util::toFormat($fileName, '/')); - return $filename; + return end($exFileName); } diff --git a/application/Espo/Core/Utils/Util.php b/application/Espo/Core/Utils/Util.php index 7bc4a5c80a..2d109c7cf9 100644 --- a/application/Espo/Core/Utils/Util.php +++ b/application/Espo/Core/Utils/Util.php @@ -44,13 +44,12 @@ class Util /** - * Convert name to Camel Case format - * ex. camel-case to camelCase - * - * @param string $name - * - * @return string - */ + * Convert name to Camel Case format, ex. camel-case to camelCase + * @param string $name + * @param boolean $capitaliseFirstChar + * @param string $symbol + * @return string + */ public static function toCamelCase($name, $capitaliseFirstChar = false, $symbol = '-') { if($capitaliseFirstChar) { @@ -276,36 +275,54 @@ class Util * * @param array $content * @param array $unsets in format - array( - $entity['name'] => array( - 'fields.UnsetFieldName', - ), - ) + * array( + * 'EntityName1' => array( 'unset1', 'unset2' ), + * 'EntityName2' => array( 'unset1', 'unset2' ), + * ) + * OR + * array('EntityName1.unset1', 'EntityName1.unset2', .....) * * @return array */ public static function unsetInArray(array $content, array $unsets) { foreach($unsets as $rootKey => $unsetItem){ - if (!empty($unsetItem)){ - foreach($unsetItem as $unsetSett){ - if (!empty($unsetSett)){ - $keyItems = explode('.', $unsetSett); - $currVal = "\$content['{$rootKey}']"; - foreach($keyItems as $keyItem){ - $currVal .= "['{$keyItem}']"; - } - - $currVal = "if (isset({$currVal})) unset({$currVal});"; - eval($currVal); + $unsetItem = is_array($unsetItem) ? $unsetItem : (array) $unsetItem; + + foreach($unsetItem as $unsetSett){ + if (!empty($unsetSett)){ + $keyItems = explode('.', $unsetSett); + $currVal = isset($content[$rootKey]) ? "\$content['{$rootKey}']" : "\$content"; + foreach($keyItems as $keyItem){ + $currVal .= "['{$keyItem}']"; } + + $currVal = "if (isset({$currVal})) unset({$currVal});"; + eval($currVal); } - } + } } return $content; } + + /** + * Get class name from the file path + * + * @param string $filePath + * + * @return string + */ + public static function getClassName($filePath) + { + $className = preg_replace('/\.php$/i', '', $filePath); + $className = preg_replace('/^application\//i', '', $className); + $className = '\\'.static::toFormat($className, '\\'); + + return $className; + } + } diff --git a/application/Espo/EntryPoints/Download.php b/application/Espo/EntryPoints/Download.php index 8cd625ff7a..24dfd8f690 100644 --- a/application/Espo/EntryPoints/Download.php +++ b/application/Espo/EntryPoints/Download.php @@ -1,6 +1,6 @@ objects['container'] = $this->getMockBuilder('\\Espo\\Core\\Container')->disableOriginalConstructor()->getMock(); + + $this->object = new \Espo\Core\EntryPointManager($this->objects['container']); + + $this->reflection = new ReflectionHelper($this->object); + + $fileManager = new \Espo\Core\Utils\File\Manager( (object) array()); + $this->reflection->setProperty('fileManager', $fileManager); + + $this->reflection->setProperty('cacheFile', 'tests/testData/EntryPoints/cache/entryPoints.php'); + $this->reflection->setProperty('paths', array( + 'corePath' => 'tests/testData/EntryPoints/Espo/EntryPoints', + 'modulePath' => 'tests/testData/EntryPoints/Espo/Modules/Crm/EntryPoints', + )); + $this->reflection->setProperty('customPaths', array( + 'corePath' => '', + 'modulePath' => '', + )); + } + + protected function tearDown() + { + $this->object = NULL; + } + + + function testGetData() + { + $result = array( + 'Download' => '\tests\testData\EntryPoints\Espo\EntryPoints\Download', + 'Test' => '\tests\testData\EntryPoints\Espo\EntryPoints\Test', + 'InModule' => '\tests\testData\EntryPoints\Espo\Modules\Crm\EntryPoints\InModule' + ); + $this->assertEquals( $result, $this->reflection->invokeMethod('getData', array($this->reflection->getProperty('paths'))) ); + } + + function testGet() + { + $this->reflection->setProperty('data', array( + 'Test' => '\tests\testData\EntryPoints\Espo\EntryPoints\Test', + )); + + $this->assertEquals('\tests\testData\EntryPoints\Espo\EntryPoints\Test', $this->reflection->invokeMethod('get', array('test')) ); + } + + + function testRun() + { + $this->reflection->setProperty('data', array( + 'Test' => '\tests\testData\EntryPoints\Espo\EntryPoints\Test', + )); + + $this->assertNull( $this->reflection->invokeMethod('run', array('test')) ); + } + +} + +?> diff --git a/tests/Espo/Core/Utils/File/ManagerTest.php b/tests/Espo/Core/Utils/File/ManagerTest.php new file mode 100644 index 0000000000..ef4b3483b3 --- /dev/null +++ b/tests/Espo/Core/Utils/File/ManagerTest.php @@ -0,0 +1,48 @@ +object = new \Espo\Core\Utils\File\Manager( + (object) array( + 'defaultPermissions' => (object) array ( + 'dir' => '0775', + 'file' => '0664', + 'user' => '', + 'group' => '', + ), + ) + ); + } + + protected function tearDown() + { + $this->object = NULL; + } + + + function testGetFileName() + { + $this->assertEquals('Donwload', $this->object->getFileName('Donwload.php')); + + $this->assertEquals('Donwload', $this->object->getFileName('/Donwload.php')); + + $this->assertEquals('Donwload', $this->object->getFileName('\Donwload.php')); + + $this->assertEquals('Donwload', $this->object->getFileName('application/Espo/EntryPoints/Donwload.php')); + } + + +} + +?> diff --git a/tests/Espo/Core/Utils/UtilTest.php b/tests/Espo/Core/Utils/UtilTest.php index 76b9861035..dc3bf99c9a 100644 --- a/tests/Espo/Core/Utils/UtilTest.php +++ b/tests/Espo/Core/Utils/UtilTest.php @@ -211,6 +211,152 @@ class UtilTest extends \PHPUnit_Framework_TestCase } + function testGetClassName() + { + $this->assertEquals('\Espo\EntryPoints\Donwload', Util::getClassName('application/Espo/EntryPoints/Donwload.php')); + + $this->assertEquals('\Espo\EntryPoints\Donwload', Util::getClassName('Espo/EntryPoints/Donwload.php')); + } + + function testUnsetInArrayNotSingle() + { + $input = array( + 'Account' => array( + 'useCache' => true, + 'sub' => array ( + 'subV' => '125', + 'subO' => array( + 'subOV' => '125', + 'subOV2' => '125', + ), + ), + ), + ); + + $unsets = array( + 'Account' => array( + 'sub.subO.subOV', 'sub.subV', + ), + ); + + $result = array( + 'Account' => array( + 'useCache' => true, + 'sub' => array ( + 'subO' => array( + 'subOV2' => '125', + ), + ), + ), + ); + + $this->assertEquals($result, Util::unsetInArray($input, $unsets)); + } + + function testUnsetInArraySingle() + { + $input = array( + 'Account' => array( + 'useCache' => true, + 'sub' => array ( + 'subV' => '125', + 'subO' => array( + 'subOV' => '125', + 'subOV2' => '125', + ), + ), + ), + ); + + $unsets = array( + 'Account.sub.subO.subOV', 'Account.sub.subV', + ); + + $result = array( + 'Account' => array( + 'useCache' => true, + 'sub' => array ( + 'subO' => array( + 'subOV2' => '125', + ), + ), + ), + ); + + $this->assertEquals($result, Util::unsetInArray($input, $unsets)); + } + + + function testUnsetInArrayTogether() + { + $input = array( + 'Account' => array( + 'useCache' => true, + 'sub' => array ( + 'subV' => '125', + 'subO' => array( + 'subOV' => '125', + 'subOV2' => '125', + ), + ), + ), + ); + + $unsets = array( + 'Account' => array( + 'sub.subO.subOV', + ), + 'Account.sub.subV', + ); + + $result = array( + 'Account' => array( + 'useCache' => true, + 'sub' => array ( + 'subO' => array( + 'subOV2' => '125', + ), + ), + ), + ); + + $this->assertEquals($result, Util::unsetInArray($input, $unsets)); + } + + + function testUnsetInArray() + { + $input = array( + 'Account' => array( + 'useCache' => true, + 'sub' => array ( + 'subV' => '125', + 'subO' => array( + 'subOV' => '125', + 'subOV2' => '125', + ), + ), + ), + 'Contact' => array( + 'useCache' => true, + ), + ); + + $unsets = array( + 'Account', + ); + + $result = array( + 'Contact' => array( + 'useCache' => true, + ), + ); + + $this->assertEquals($result, Util::unsetInArray($input, $unsets)); + } + + + /*function testGetScopeModuleName() { $this->assertEquals('Crm', $this->fixture->getScopeModuleName('Account')); diff --git a/tests/testData/EntryPoints/Espo/EntryPoints/Download.php b/tests/testData/EntryPoints/Espo/EntryPoints/Download.php new file mode 100755 index 0000000000..ea9bc53303 --- /dev/null +++ b/tests/testData/EntryPoints/Espo/EntryPoints/Download.php @@ -0,0 +1,15 @@ + array($baseDir . '/'), 'Zend\\Validator\\' => array($vendorDir . '/zendframework/zend-validator'), 'Zend\\Stdlib\\' => array($vendorDir . '/zendframework/zend-stdlib'), 'Zend\\ServiceManager\\' => array($vendorDir . '/zendframework/zend-servicemanager'),