diff --git a/api/index.php b/api/index.php index d33b862ae4..b5a893c088 100755 --- a/api/index.php +++ b/api/index.php @@ -2,191 +2,10 @@ require_once('../bootstrap.php'); -use \Espo\Utils\Api as Api, - \Espo\Utils as Utils, - \Slim; -/* START: remove for composer */ -require 'vendor/Slim/Slim.php'; -\Slim\Slim::registerAutoloader(); -/* END: remove for composer */ +$app = new \Espo\Core\Application(); -//$routes = new \Slim\Slim(); +$app->run(); -$routes = new \Slim\Slim(array( - 'mode' => 'development' -)); -$routes->add(new Api\Auth()); - -//convert all url params to camel case format -$routes->hook('slim.before.dispatch', function () use ($routes) { - $routeParams= $routes->router()->getCurrentRoute()->getParams(); - - if (!empty($routeParams)) { - $baseUtils= new Utils\BaseUtils(); - foreach($routeParams as &$param) { - $param= $baseUtils->toCamelCase($param); - } - - $routes->router()->getCurrentRoute()->setParams($routeParams); - } -}); -//END: convert all url params to camel case format - - -$routes->hook('slim.before.dispatch', function () use ($routes) { - - $currentRoute = $routes->router()->getCurrentRoute(); - $conditions = $currentRoute->getConditions(); - - if (isset($conditions['useController']) && $conditions['useController'] == false) { - return; - } - - $espoController = call_user_func( $routes->router()->getCurrentRoute()->getCallable() ); - $espoKeys = array_keys($espoController); - - if (!in_array('controller', $espoKeys)) { - return; - } - - $ControllerManager = new Utils\Controllers\Manager(); - - $params = $currentRoute->getParams(); - $data = $routes->request()->getBody(); - - //prepare controller Params - $controllerParams = array(); - $controllerParams['HttpMethod'] = strtolower($routes->request()->getMethod()); - - foreach($espoController as $key => $val) { - if (strstr($val, ':')) { - $paramName = str_replace(':', '', $val); - $val = $params[$paramName]; - } - $controllerParams[$key] = $val; - } - //END: prepare controller Params - - $result = $ControllerManager->call($controllerParams, $params, $data); - - return Api\Helper::output($result->data, $result->errMessage, $result->errCode); -}); - - -//return json response -$routes->hook('slim.after.router', function () use (&$routes) { - $routes->contentType('application/json'); - //$routes->contentType('text/javascript'); -}); -//END: return json response - - -//Setup routes -$routes->get('/', '\Espo\Utils\Api\Rest::main')->conditions( array('useController' => false) ); -$routes->get('/app/user/', '\Espo\Utils\Api\Rest::getAppUser')->conditions( array('useController' => false) ); - -//METADATA -$routes->get('/metadata/', function() { - return array( - 'controller' => 'Metadata', - ); -}); - -$routes->put('/metadata/:type/:scope/', function() { - return array( - 'controller' => 'Metadata', - 'scope' => ':scope', - 'action' => ':type', - ); -}); -//END: METADATA - -//SETTINGS -$routes->get('/settings/', function() { - return array( - 'controller' => 'Settings', - ); -})->conditions( array('auth' => false) ); - -$routes->map('/settings/', function() { - return array( - 'controller' => 'Settings', - ); -})->via('PATCH'); -//END: SETTINGS - -//LAYOUT -$routes->get('/:controller/layout/:name/', function() { - return array( - 'controller' => 'Layout', - 'scope' => ':controller', - 'action' => ':name', - ); -}); - -$routes->put('/:controller/layout/:name/', function() { - return array( - 'controller' => 'Layout', - 'scope' => ':controller', - 'action' => ':name', - ); -}); - -$routes->map('/:controller/layout/:name/', function() { - return array( - 'controller' => 'Layout', - 'scope' => ':controller', - 'action' => ':name', - ); -})->via('PATCH'); -//END: LAYOUT - - -/*$routes->get('/:controller/:id', function() { - return array( - 'controller' => ':controller', - 'action' => 'read', - 'id' => ':id' - ); -}); - -$routes->post('/:controller', function() { - return array( - 'controller' => ':controller', - 'action' => 'create', - ); -}); - -$routes->put('/:controller/:id', function() { - return array( - 'controller' => ':controller', - 'action' => 'update', - 'id' => ':id' - ); -}); - -$routes->patch('/:controller/:id', function() { - return array( - 'controller' => ':controller', - 'action' => 'patch', - 'id' => ':id' - ); -}); - - -$routes->get('/:controller/:id/:link/:foreignId', function() { - return array( - 'controller' => ':controller', - 'action' => 'readRelated', - 'id' => ':id', - 'link' => ':link', - 'foreignId' => ':foreignId' - ); -}); */ - - - -$routes->run(); ?> \ No newline at end of file diff --git a/application/Espo/Controllers/Layout.php b/application/Espo/Controllers/Layout.php index cfd62ef44e..b0dba5c32a 100644 --- a/application/Espo/Controllers/Layout.php +++ b/application/Espo/Controllers/Layout.php @@ -2,15 +2,14 @@ namespace Espo\Controllers; -use Espo\Utils as Utils; +use Espo\Core\Utils as Utils; -class Layout extends Utils\Controllers\Controller +class Layout extends \Espo\Core\Controllers\Base { public function read($params, $data) { - $layout = new Utils\Layout(); - $data = $layout->getLayout($params['controller'], $params['name']); + $data = $this->getContainer()->get('layout')->get($params['controller'], $params['name']); return array($data, 'Cannot get this layout', 404); } @@ -18,26 +17,28 @@ class Layout extends Utils\Controllers\Controller public function update($params, $data) { - $layout= new Utils\Layout(); - $result= $layout->setLayout($data, $params['controller'], $params['name']); + $result= $this->getContainer()->get('layout')->set($data, $params['controller'], $params['name']); if ($result === false) { return array(false, 'Layout Saving error', 500); } + $data = $this->getContainer()->get('layout')->get($params['controller'], $params['name']); + return array($data, 'Cannot get this layout'); } public function patch($params, $data) { - $layout= new Utils\Layout(); - $result= $layout->mergeLayout($data, $params['controller'], $params['name']); + $result= $this->getContainer()->get('layout')->merge($data, $params['controller'], $params['name']); if ($result === false) { return array(false, 'Layout Saving error', 500); } + $data = $this->getContainer()->get('layout')->get($params['controller'], $params['name']); + return array($data, 'Cannot get this layout'); } diff --git a/application/Espo/Controllers/Metadata.php b/application/Espo/Controllers/Metadata.php index 4c42c635d7..2e6126e3b9 100644 --- a/application/Espo/Controllers/Metadata.php +++ b/application/Espo/Controllers/Metadata.php @@ -2,31 +2,27 @@ namespace Espo\Controllers; -use Espo\Utils as Utils; -class Metadata extends Utils\Controllers\Controller +class Metadata extends \Espo\Core\Controllers\Base { public function read($params, $data) { - $metadata= new Utils\Metadata(); - - $data= $metadata->getMetadata(true); + $data= $this->getContainer()->get('metadata')->get(true); return array($data, 'Cannot reach metadata data'); } public function update($params, $data) - { - $metadata = new Utils\Metadata(); - $result = $metadata->setMetadata($data, $params['type'], $params['scope']); + { + $result = $this->getContainer()->get('metadata')->set($data, $params['type'], $params['scope']); if ($result===false) { return array($result, 'Cannot save metadata data'); } - $data= $metadata->getMetadata(true, true); + $data= $this->getContainer()->get('metadata')->get(true, true); return array($data, 'Cannot get metadata data'); } diff --git a/application/Espo/Controllers/Settings.php b/application/Espo/Controllers/Settings.php index 6056ccb3ec..ca1591ecc3 100644 --- a/application/Espo/Controllers/Settings.php +++ b/application/Espo/Controllers/Settings.php @@ -2,22 +2,16 @@ namespace Espo\Controllers; -use Espo\Utils as Utils; +use Espo\Core\Utils as Utils; -class Settings extends Utils\Controllers\Controller +class Settings extends \Espo\Core\Controllers\Base { public function read($params, $data) { - global $base; - $config= new Utils\Configurator(); + $isAdmin = $this->getContainer()->get('user')->isAdmin(); - $isAdmin= false; - if(isset($base->currentUser) && is_object($base->currentUser)) { - $isAdmin= $base->currentUser->isAdmin(); - } - - $data= $config->getJSON($isAdmin); + $data= $this->getContainer()->get('config')->getJsonData($isAdmin); return array($data, 'Cannot get settings'); } @@ -25,21 +19,15 @@ class Settings extends Utils\Controllers\Controller public function patch($params, $data) { - global $base; - $config= new Utils\Configurator(); + $isAdmin = $this->getContainer()->get('user')->isAdmin(); - $isAdmin= false; - if(isset($base->currentUser) && is_object($base->currentUser)) { - $isAdmin= $base->currentUser->isAdmin(); - } - - $result= $config->setJSON($data, $isAdmin); + $result= $this->getContainer()->get('config')->setJsonData($data, $isAdmin); if ($result===false) { return array($result, 'Cannot save settings'); } - $data= $config->getJSON($isAdmin); + $data= $this->getContainer()->get('config')->getJsonData($isAdmin); return array($data, 'Cannot get settings'); } diff --git a/application/Espo/Core/Application.php b/application/Espo/Core/Application.php index a59087bc1d..522416a7bf 100644 --- a/application/Espo/Core/Application.php +++ b/application/Espo/Core/Application.php @@ -2,43 +2,278 @@ namespace Espo\Core; + class Application { + protected static $apps = array(); + + private $metadata; - + private $container; - private $serviceFactory; + private $serviceFactory; + + private $slim; + + - /** * Constructor */ public function __construct() - { - - $this->container = new Container(); - - $this->metadata = $this->container->get('metadata'); - - $this->serviceFactory = new ServiceFactory($this->container); - - //$this->slim = new \Slim\ - } - - public function run($name) { + $this->container = new Container(); + + $GLOBALS['log'] = $this->log = $this->container->get('log'); + set_error_handler(array($this->getLog(), 'catchError'), E_ALL); + set_exception_handler(array($this->getLog(), 'catchException')); + + $this->serviceFactory = new ServiceFactory($this->container); + $this->slim = $this->container->get('slim'); + } + + public function getSlim() + { + return $this->slim; + } + + public function getContainer() + { + return $this->container; + } + + public function getLog() + { + return $this->log; + } + + public function getServiceFactory() + { + return $this->serviceFactory; + } + + + + public function run($name = 'default') + { + //set_error_handler(array($this->getLog(), 'catchError'), E_ALL); + //set_exception_handler(array($this->getLog(), 'catchException')); + + $this->routeHooks(); + $this->routes(); + + $this->getSlim()->run(); + + static::$apps[$name] = $this; - - // TODO place routing HERE - // dispatch which controller to user + // TODO place routing HERE + // dispatch which controller to use // $this->controller = new $controllerClassName($this->container, $this->serviceFactory); // call needed controller method $this->$method($params, $data) - - - + + // dont't return anything here - } + } + + + public static function getInstance($name = 'default') + { + return isset(static::$apps[$name]) ? static::$apps[$name] : null; + } + + + protected function routeHooks() + { + $container = $this->getContainer(); + $slim = $this->getSlim(); + $serviceFactory = $this->getServiceFactory(); + + //check user credentials + $this->getSlim()->add(new \Espo\Core\Utils\Api\Auth( $container )); + + //convert all url params to camel case format + $this->getSlim()->hook('slim.before.dispatch', function () use ($slim, $container) { + + $routeParams= $slim->router()->getCurrentRoute()->getParams(); + + if (!empty($routeParams)) { + foreach($routeParams as &$param) { + $param= \Espo\Core\Utils\Util::toCamelCase($param); + } + + $slim->router()->getCurrentRoute()->setParams($routeParams); + } + }); + //END: convert all url params to camel case format + + + $this->getSlim()->hook('slim.before.dispatch', function () use ($slim, $container, $serviceFactory) { + + $currentRoute = $slim->router()->getCurrentRoute(); + $conditions = $currentRoute->getConditions(); + + if (isset($conditions['useController']) && $conditions['useController'] == false) { + return; + } + + $espoController = call_user_func( $slim->router()->getCurrentRoute()->getCallable() ); + $espoKeys = is_array($espoController) ? array_keys($espoController) : array(); + + if (!in_array('controller', $espoKeys, true)) { + return $container->get('rest')->render($espoController); + } + + + $params = $currentRoute->getParams(); + $data = $slim->request()->getBody(); + + //prepare controller Params + $controllerParams = array(); + $controllerParams['HttpMethod'] = strtolower($slim->request()->getMethod()); + + foreach($espoController as $key => $val) { + if (strstr($val, ':')) { + $paramName = str_replace(':', '', $val); + $val = $params[$paramName]; + } + $controllerParams[$key] = $val; + } + + $controllerParams['container'] = $container; + $controllerParams['serviceFactory'] = $serviceFactory; + //END: prepare controller Params + + $result = $container->get('controllerManager')->call($controllerParams, $params, $data); + + return $container->get('rest')->render($result->data, $result->errMessage, $result->errCode); + }); + + + //return json response + $this->getSlim()->hook('slim.after.router', function () use (&$slim) { + $slim->contentType('application/json'); + //$routes->contentType('text/javascript'); + }); + //END: return json response + } + + + protected function routes() + { + //$this->getSlim()->get('/', '\Espo\Utils\Api\Rest::main')->conditions( array('useController' => false) ); + + $this->getSlim()->get('/', function() { + return $template = <<Main Page of REST API!!! +EOT; + }); // ->conditions( array('useController' => false) ); + + $this->getSlim()->get('/app/user/', function() { + return '{"user":{"modified_by_name":"Administrator","created_by_name":"","id":"1","user_name":"admin","user_hash":"","system_generated_password":"0","pwd_last_changed":"","authenticate_id":"","sugar_login":"1","first_name":"","last_name":"Administrator","full_name":"Administrator","name":"Administrator","is_admin":"1","external_auth_only":"0","receive_notifications":"1","description":"","date_entered":"2013-06-13 12:18:44","date_modified":"2013-06-13 12:19:48","modified_user_id":"1","created_by":"","title":"Administrator","department":"","phone_home":"","phone_mobile":"","phone_work":"","phone_other":"","phone_fax":"","status":"Active","address_street":"","address_city":"","address_state":"","address_country":"","address_postalcode":"","UserType":"","deleted":"0","portal_only":"0","show_on_employees":"1","employee_status":"Active","messenger_id":"","messenger_type":"","reports_to_id":"","reports_to_name":"","email1":"test@letrium.com","email_link_type":"","is_group":"0","c_accept_status_fields":" ","m_accept_status_fields":" ","accept_status_id":"","accept_status_name":""},"preferences":{}}'; + }); //->conditions( array('useController' => false) ); + + //METADATA + $this->getSlim()->get('/metadata/', function() { + return array( + 'controller' => 'Metadata', + ); + }); + + $this->getSlim()->put('/metadata/:type/:scope/', function() { + return array( + 'controller' => 'Metadata', + 'scope' => ':scope', + 'action' => ':type', + ); + }); + //END: METADATA + + //SETTINGS + $this->getSlim()->get('/settings/', function() { + return array( + 'controller' => 'Settings', + ); + }); //->conditions( array('auth' => false) ); + + $this->getSlim()->map('/settings/', function() { + return array( + 'controller' => 'Settings', + ); + })->via('PATCH'); + //END: SETTINGS + + //LAYOUT + $this->getSlim()->get('/:controller/layout/:name/', function() { + return array( + 'controller' => 'Layout', + 'scope' => ':controller', + 'action' => ':name', + ); + }); + + $this->getSlim()->put('/:controller/layout/:name/', function() { + return array( + 'controller' => 'Layout', + 'scope' => ':controller', + 'action' => ':name', + ); + }); + + $this->getSlim()->map('/:controller/layout/:name/', function() { + return array( + 'controller' => 'Layout', + 'scope' => ':controller', + 'action' => ':name', + ); + })->via('PATCH'); + //END: LAYOUT + + + /*$this->getSlim()->get('/:controller/:id', function() { + return array( + 'controller' => ':controller', + 'action' => 'read', + 'id' => ':id' + ); + }); + + $this->getSlim()->post('/:controller', function() { + return array( + 'controller' => ':controller', + 'action' => 'create', + ); + }); + + $this->getSlim()->put('/:controller/:id', function() { + return array( + 'controller' => ':controller', + 'action' => 'update', + 'id' => ':id' + ); + }); + + $this->getSlim()->patch('/:controller/:id', function() { + return array( + 'controller' => ':controller', + 'action' => 'patch', + 'id' => ':id' + ); + }); + + + $this->getSlim()->get('/:controller/:id/:link/:foreignId', function() { + return array( + 'controller' => ':controller', + 'action' => 'readRelated', + 'id' => ':id', + 'link' => ':link', + 'foreignId' => ':foreignId' + ); + }); */ + } + + } diff --git a/application/Espo/Core/Base.php b/application/Espo/Core/Base.php deleted file mode 100755 index fe12b80118..0000000000 --- a/application/Espo/Core/Base.php +++ /dev/null @@ -1,103 +0,0 @@ -config = $this->getUtils()->getObject('Configurator'); - $this->em = $this->getEntityManager(); - /*$doctrineConfig->em->getConfiguration()->getMetadataDriverImpl()->addPaths(array( - "Modules" - ));*/ - - $this->log = $this->getUtils()->getObject('Log'); - } - - /** - * Start the app - */ - public static function start() - { - return new Base(); - } - - /** - * Create or get an EntityManager object - * - */ - private function getEntityManager() - { - if (isset($this->em) && is_object($this->em)) { - return $this->em; - } - - //EspoPHPDriver for Doctrine - $devMode= !$this->config->get('useCache'); - $doctrineConfig = Setup::createConfiguration($devMode, null, null); - $doctrineConfig->setMetadataDriverImpl(new EspoPHPDriver( - array( - $this->config->get('metadataConfig')->doctrineCache, - $this->config->get('defaultsPath').'/doctrine/metadata' - ) - )); - //END: EspoPHPDriver for Doctrine - - $doctrineConn = (array) $this->config->get('database'); - - // obtaining the entity manager - return \Doctrine\ORM\EntityManager::create($doctrineConn, $doctrineConfig); - } - - /** - * Create or get a Configurator object - * - */ - private function getUtils() - { - if (isset($this->utils) && is_object($this->utils)) { - return $this->utils; - } - - return new Utils\BaseUtils(); - } - -} - - -?> \ No newline at end of file diff --git a/application/Espo/Core/Base/RecordService.php b/application/Espo/Core/Base/RecordService.php index ea9ef85527..84ee22e2f9 100644 --- a/application/Espo/Core/Base/RecordService.php +++ b/application/Espo/Core/Base/RecordService.php @@ -13,9 +13,7 @@ abstract class RecordService private $config; private $entityManager; - - private $entityManager; - + private $datetime; public function setConfig($config) diff --git a/application/Espo/Core/Container.php b/application/Espo/Core/Container.php index 7c1af9e1bd..b20e91d415 100644 --- a/application/Espo/Core/Container.php +++ b/application/Espo/Core/Container.php @@ -6,13 +6,14 @@ class Container { private $data = array(); - + + /** * Constructor */ public function __construct() { - + } @@ -24,7 +25,7 @@ class Container $this->load($name); return $this->data[$name]; } - + private function load($name) { $loadMethod = 'load' . ucfirst($name); @@ -34,19 +35,127 @@ class Container // TODO external loader class (\Espo\Core\Loaders\EntityManager::load()) } } - - private function loadMetadata() + + + private function loadSlim() { - + /* START: remove for composer */ + require 'vendor/Slim/Slim.php'; + \Slim\Slim::registerAutoloader(); + /* END: remove for composer */ + + $this->data['slim'] = new \Slim\Slim(); } - - private function loadConfig() + + + private function loadFileManager() { - $this->data['config'] = new \Espo\Utils\Configurator(); + $this->data['fileManager'] = new \Espo\Core\Utils\File\Manager( + (object) array( + 'defaultPermissions' => (object) array ( + 'dir' => '0775', + 'file' => '0664', + 'user' => '', + 'group' => '', + ), + ) + ); } - + + private function loadConfig() + { + $this->data['config'] = new \Espo\Core\Utils\Config( + $this->get('fileManager') + ); + } + + private function loadLog() + { + $this->data['log'] = new \Espo\Core\Utils\Log( + $this->get('fileManager'), + $this->get('rest'), + $this->get('resolver'), + (object) array( + 'options' => $this->get('config')->get('logger'), + 'datetime' => $this->get('datetime')->getDatetime(), + ) + ); + } + + private function loadRest() + { + $this->data['rest'] = new \Espo\Core\Utils\Api\Rest( + $this->get('slim') + ); + } + + private function loadMetadata() + { + $this->data['metadata'] = new \Espo\Core\Utils\Metadata( + $this->get('entityManager'), + $this->get('config'), + $this->get('fileManager'), + $this->get('uniteFiles') + ); + } + + + private function loadLayout() + { + $this->data['layout'] = new \Espo\Core\Utils\Layout( + $this->get('config'), + $this->get('fileManager'), + $this->get('metadata') + ); + } + + private function loadResolver() + { + $this->data['resolver'] = new \Espo\Core\Utils\Resolver( + $this->get('metadata') + ); + } + private function loadEntityManager() { - $this->data['entityManager'] = new \Espo\Utils\EntiryManager($this->get('config')); + $espoEM = new \Espo\Core\Utils\EntityManager( + $this->get('config') + ); + $this->data['entityManager'] = $espoEM->create(); } + + private function loadControllerManager() + { + $this->data['controllerManager'] = new \Espo\Core\Controllers\Manager( + $this->get('config'), + $this->get('metadata') + ); + } + + private function loadDatetime() + { + $this->data['datetime'] = new \Espo\Core\Utils\Datetime( + $this->get('config') + ); + } + + private function loadUniteFiles() + { + $this->data['uniteFiles'] = new \Espo\Core\Utils\File\UniteFiles( + $this->get('fileManager'), + (object) array( + 'unsetFileName' => $this->get('config')->get('unsetFileName'), + 'defaultsPath' => $this->get('config')->get('defaultsPath'), + ) + ); + } + + private function loadUser() + { + $this->data['user'] = new \Espo\Core\Utils\User( + $this->get('entityManager'), + $this->get('config') + ); + } + } diff --git a/application/Espo/Core/Controllers/Base.php b/application/Espo/Core/Controllers/Base.php new file mode 100644 index 0000000000..42c50d2c7a --- /dev/null +++ b/application/Espo/Core/Controllers/Base.php @@ -0,0 +1,57 @@ +container = $container; + $this->serviceFactory = $serviceFactory; + } + + protected function getContainer() + { + return $this->container; + } + + protected function getServiceFactory() + { + return $this->serviceFactory; + } + + + + public function read($params, $data) + { + + } + + public function update($params, $data) + { + + } + + public function patch($params, $data) + { + + } + + public function create($params, $data) + { + + } + + public function delete($params, $data) + { + + } + + +} + + +?> \ No newline at end of file diff --git a/application/Espo/Utils/Controllers/Manager.php b/application/Espo/Core/Controllers/Manager.php old mode 100755 new mode 100644 similarity index 81% rename from application/Espo/Utils/Controllers/Manager.php rename to application/Espo/Core/Controllers/Manager.php index 3b91256122..233a853de7 --- a/application/Espo/Utils/Controllers/Manager.php +++ b/application/Espo/Core/Controllers/Manager.php @@ -1,19 +1,34 @@ config = $config; + $this->metadata = $metadata; } + + protected function getConfig() + { + return $this->config; + } + + protected function getMetadata() + { + return $this->metadata; + } + + /** * Manage of all controllers * @@ -25,13 +40,12 @@ class Manager */ public function call($controllerParams, $params, $data = '') { - $baseUtils = new Utils\BaseUtils(); + $config = $this->getConfig(); - $config = $baseUtils->getObject('Configurator'); $espoPath = $config->get('espoPath'); - $controllerPath= $baseUtils->concatPath($espoPath, $config->get('controllerPath')); + $controllerPath= Util::concatPath($espoPath, $config->get('controllerPath')); - $crud = $baseUtils->getObject('Configurator')->get('crud'); + $crud = $config->get('crud'); $baseAction = $crud->$controllerParams['HttpMethod']; if (empty($baseAction)) { return $this->response(false, 'Cannot find action for HTTP Method ['.$controllerParams['HttpMethod'].']', 404); @@ -45,14 +59,14 @@ class Manager ); - if (!empty($controller->scope) && !$baseUtils->isScopeExists($controller->scope)) { + if (!empty($controller->scope) && !$this->getMetadata()->isScopeExists($controller->scope)) { return $this->response(false, 'Controller for Scope ['.$controller->scope.'] does not exist.', 404); } //define default values $classInfo = new \stdClass(); - $classInfo->name = $this->getClassName($baseUtils->concatPath($espoPath, 'Utils/Controllers'), 'Controller'); + $classInfo->name = $this->getClassName(Util::concatPath($espoPath, 'Core/Base'), 'Controller'); $classInfo->path = $this->getClassPath($classInfo->name); $classInfo->method = $this->getDefinedMethod($classInfo->name, $controller->baseAction, $controller->action); @@ -65,7 +79,7 @@ class Manager if (!empty($controller->scope)) { //path in Modules dir - $controllerDir = $baseUtils->concatPath( $baseUtils->getScopePath($controller->scope), $config->get('controllerPath') ); + $controllerDir = Util::concatPath( $this->getMetadata()->getScopePath($controller->scope), $config->get('controllerPath') ); //ex. Modules\Crm\Controllers\Layout and Cusom\Modules\Crm\Controllers\Layout $controllerClass = $this->getClassName($controllerDir, $controller->name); @@ -93,7 +107,7 @@ class Manager $classMethod = $classInfo->method; require_once($classInfo->path); - $class = new $className(); + $class = new $className($controllerParams['container'], $controllerParams['serviceFactory']); //call before method if exists: beforeRead, beforeDetailSmall, beforeReadDetailSmall $beforeMethod = $this->getDefinedMethod($className, $controller->baseAction, $controller->action, 'before'); @@ -151,10 +165,8 @@ class Manager $prefix .= '-'; } - $baseUtils = new Utils\BaseUtils(); - //method as 'read' - $prefixBaseAction = $baseUtils->toCamelCase($prefix.$baseAction); + $prefixBaseAction = Util::toCamelCase($prefix.$baseAction); if ( method_exists($className, $prefixBaseAction) ) { $classMethod = $prefixBaseAction; } @@ -164,13 +176,13 @@ class Manager } //method as 'detailSmall' - $prefixAction = $baseUtils->toCamelCase($prefix.$action); + $prefixAction = Util::toCamelCase($prefix.$action); if ( method_exists($className, $prefixAction) ) { $classMethod = $prefixAction; } //method as 'readDetailSmall' - $fullAction = $baseUtils->toCamelCase($prefix.$baseAction.'-'.$action); + $fullAction = Util::toCamelCase($prefix.$baseAction.'-'.$action); if (method_exists($className, $fullAction)) { $classMethod = $fullAction; } @@ -200,8 +212,7 @@ class Manager } if ($isCustom) { - $baseUtils = new Utils\BaseUtils(); - $espoCustomDir = $baseUtils->getObject('Configurator')->get('espoCustomPath'); + $espoCustomDir = $this->getConfig()->get('espoCustomPath'); $controllerClass = $espoCustomDir.'\\'.$className; $classInfo = $this->setClassInfo($controllerClass, $classInfo, $controller, false); } @@ -221,13 +232,11 @@ class Manager */ protected function getClassName($path, $name = '') { - $baseUtils = new Utils\BaseUtils(); - if (!empty($name)) { - $path = $baseUtils->concatPath($path, $baseUtils->toCamelCase($name, true)); + $path = Util::concatPath($path, Util::toCamelCase($name, true)); } - return $baseUtils->toFormat($path, '\\'); + return Util::toFormat($path, '\\'); } @@ -241,13 +250,11 @@ class Manager */ protected function getClassPath($path, $name = '') { - $baseUtils = new Utils\BaseUtils(); - if (!empty($name)) { - $path = $baseUtils->concatPath($path, $baseUtils->toCamelCase($name, true)); + $path = Util::concatPath($path, Util::toCamelCase($name, true)); } - return $baseUtils->concatPath('application', $baseUtils->toFormat($path, '/').'.php'); + return Util::concatPath('application', Util::toFormat($path, '/').'.php'); } diff --git a/application/Espo/Utils/DoctrineConverter.php b/application/Espo/Core/Doctrine/EspoConverter.php old mode 100755 new mode 100644 similarity index 66% rename from application/Espo/Utils/DoctrineConverter.php rename to application/Espo/Core/Doctrine/EspoConverter.php index abb113ebf8..951581c71f --- a/application/Espo/Utils/DoctrineConverter.php +++ b/application/Espo/Core/Doctrine/EspoConverter.php @@ -1,10 +1,21 @@ metadata = $metadata; + } + + public function getMetadata() + { + return $this->metadata; + } + /** * Metadata conversion from Espo format into Doctrine * @@ -18,9 +29,7 @@ class DoctrineConverter extends BaseUtils function convert($name, $data, $withName=false) { //HERE SHOULD BE CONVERSION FUNCTIONALITY - $metadata= $this->getObject('Metadata'); - - $entityFullName= $metadata->getEntityPath($name, '\\'); + $entityFullName= $this->getMetadata()->getEntityPath($name, '\\'); $doctrineMeta= array( $entityFullName => $data diff --git a/application/Espo/Utils/Doctrine/ORM/Mapping/Driver/EspoPHPDriver.php b/application/Espo/Core/Doctrine/ORM/Mapping/Driver/EspoPHPDriver.php old mode 100755 new mode 100644 similarity index 99% rename from application/Espo/Utils/Doctrine/ORM/Mapping/Driver/EspoPHPDriver.php rename to application/Espo/Core/Doctrine/ORM/Mapping/Driver/EspoPHPDriver.php index 7053724918..0ca1637b8c --- a/application/Espo/Utils/Doctrine/ORM/Mapping/Driver/EspoPHPDriver.php +++ b/application/Espo/Core/Doctrine/ORM/Mapping/Driver/EspoPHPDriver.php @@ -1,6 +1,6 @@ container = $container; - } - + } + + protected function getCotainer() + { + return $this->container; + } + + public function create($name) { // TODO lookup in metadata which module to use $className = '\\Espo\\Services\\' . $name; if (class_exists($className)) { - $service = new $className(); - $dependencies = $service->dependencies; + $service = new $className(); + $dependencies = $service->dependencies; foreach ($dependencies as $name) { $setMethod = 'set' . ucfirst($name); - $service->$setMethod($this->container->get($name)); + $service->$setMethod($this->getCotainer()->get($name)); } return $service; } diff --git a/application/Espo/Utils/Api/Auth.php b/application/Espo/Core/Utils/Api/Auth.php old mode 100755 new mode 100644 similarity index 68% rename from application/Espo/Utils/Api/Auth.php rename to application/Espo/Core/Utils/Api/Auth.php index 6e588b0523..3361555353 --- a/application/Espo/Utils/Api/Auth.php +++ b/application/Espo/Core/Utils/Api/Auth.php @@ -1,20 +1,25 @@ noAuthRoutes = $noAuthRoutes; - + $this->container = $container; } + protected function getContainer() + { + return $this->container; + } + + + function call() { $req = $this->app->request(); @@ -41,15 +46,9 @@ class Auth extends \Slim\Middleware if ($authKey && $authSec) { - $User= new Entities\User(); - $app= $User->login($authKey, $authSec); - - if($app){ - //set the current user - global $base; - $base->currentUser= $base->em->getRepository('\Espo\Entities\User')->findOneBy(array('username' => $authKey)); - //END: set the current user + $isAuthenticated = $this->getContainer()->get('user')->authenticate($authKey, $authSec); + if($isAuthenticated){ $this->next->call(); }else{ $res->header('WWW-Authenticate', sprintf('Basic realm="%s"', $this->realm)); diff --git a/application/Espo/Core/Utils/Api/Rest.php b/application/Espo/Core/Utils/Api/Rest.php new file mode 100644 index 0000000000..a5ddd6b054 --- /dev/null +++ b/application/Espo/Core/Utils/Api/Rest.php @@ -0,0 +1,79 @@ +slim = $slim; + } + + protected function getSlim() + { + return $this->slim; + } + + + + /** + * Output the result + * + * @param mixed $data - JSON + * @param string $errMessage - error message + * @param int $errCode - error status code + * + * @return void - Only echo the result + */ + public function render($data=null, $errMessage='Error', $errCode=500) + { + if (is_array($data)) { + $dataArr = array_values($data); + + $data = empty($dataArr[0]) ? false : $dataArr[0]; + $errMessage = empty($dataArr[1]) ? $errMessage : $dataArr[1]; + $errCode = empty($dataArr[2]) ? $errCode : $dataArr[2]; + } + + //check if result is false + if ($data === false || !is_string($data)) { + $logMess= empty($errMessage) ? 'result is not expected' : $errMessage; + $GLOBALS['log']->add('ERROR', 'API ['.$this->getSlim()->request()->getMethod().']:'.$this->getSlim()->router()->getCurrentRoute()->getPattern().', Params:'.print_r($this->getSlim()->router()->getCurrentRoute()->getParams(), true).', InputData: '.$this->getSlim()->request()->getBody().' - '.$logMess); + $this->displayError($errMessage, $errCode); + } + //END: check if result is false + + ob_clean(); + echo $data; + $this->getSlim()->stop(); + } + + /** + * Output the error and stop app execution + * + * @param string $text + * @param int $statusCode + * + * @return void + */ + public function displayError($text, $statusCode=500) + { + $GLOBALS['log']->add('INFO', 'Display Error: '.$text.', Code: '.$statusCode.' URL: '.$_SERVER['REQUEST_URI']); + + if ( !empty( $this->slim) ) { + $this->getSlim()->response()->status($statusCode); + $this->getSlim()->response()->header('X-Status-Reason', $text); + $this->getSlim()->stop(); + } + else { + $GLOBALS['log']->add('INFO', 'Could not get Slim instance. It looks like a direct call (bypass API). URL: '.$_SERVER['REQUEST_URI']); + die($text); + } + } + +} + +?> \ No newline at end of file diff --git a/application/Espo/Utils/Configurator.php b/application/Espo/Core/Utils/Config.php old mode 100755 new mode 100644 similarity index 65% rename from application/Espo/Utils/Configurator.php rename to application/Espo/Core/Utils/Config.php index 027c83377a..8ef378a9b7 --- a/application/Espo/Utils/Configurator.php +++ b/application/Espo/Core/Utils/Config.php @@ -1,9 +1,8 @@ fileManager = $fileManager; + } + + protected function getFileManager() + { + return $this->fileManager; + } + + /** * Get an option from system config @@ -58,12 +71,12 @@ class Configurator extends BaseUtils */ public function set($name, $value='') { - if (Utils\JSON::isJSON($value)) { - $value= Utils\JSON::decode($value); + if (Json::isJSON($value)) { + $value= Json::decode($value); } $content= array($name => $value); - $status= $this->getObject('FileManager')->mergeContentPHP($content, $this->get('configPath'), '', true); + $status= $this->getFileManager()->mergeContentPHP($content, $this->get('configPath'), '', true); $this->getConfig(true); return $status; @@ -78,15 +91,15 @@ class Configurator extends BaseUtils */ public function setArray($values) { - if (Utils\JSON::isJSON($values)) { - $values= Utils\JSON::decode($values); + if (Json::isJSON($values)) { + $values= Json::decode($values); } if (!is_array($values)) { return false; } - $status= $this->getObject('FileManager')->mergeContentPHP($values, $this->get('configPath'), '', true); + $status= $this->getFileManager()->mergeContentPHP($values, $this->get('configPath'), '', true); $this->getConfig(true); return $status; @@ -97,21 +110,20 @@ class Configurator extends BaseUtils * * @return object */ - function getConfig($reload=false) + function getConfig($reload=false) { if (!$reload && isset($this->lastConfigObj) && !empty($this->lastConfigObj)) { return $this->lastConfigObj; } - $fileManager= $this->getObject('FileManager'); - $systemConfig= $fileManager->getContent($this->systemConfigPath); + $systemConfig= $this->getFileManager()->getContent($this->systemConfigPath); - $config= $fileManager->getContent($systemConfig['configPath']); + $config= $this->getFileManager()->getContent($systemConfig['configPath']); if (empty($config)) { - $this->getObject('Log')->add('FATAL', 'Check syntax or permission of your '.$systemConfig['configPath']); + $GLOBALS['log']->add('FATAL', 'Check syntax or permission of your '.$systemConfig['configPath']); } - $this->lastConfigObj = $this->arrayToObject( $this->merge((array) $systemConfig, (array) $config) ); + $this->lastConfigObj = Util::arrayToObject( Util::merge((array) $systemConfig, (array) $config) ); $this->adminItems= $this->getRestrictItems(); return $this->lastConfigObj; @@ -124,7 +136,7 @@ class Configurator extends BaseUtils * @param $isAdmin * @return object */ - public function getJSON($isAdmin=false, $encode=true) + public function getJsonData($isAdmin=false, $encode=true) { $configObj = $this->getConfig(); @@ -139,7 +151,7 @@ class Configurator extends BaseUtils return $restrictedConfig; } - return Utils\JSON::encode( $this->objectToArray($restrictedConfig) ); + return Json::encode( Util::objectToArray($restrictedConfig) ); } @@ -150,9 +162,9 @@ class Configurator extends BaseUtils * @return bool */ //HERE - public function setJSON($json, $isAdmin=false) + public function setJsonData($json, $isAdmin=false) { - $decoded= Utils\JSON::decode($json, true); + $decoded= Json::decode($json, true); $restrictItems= $this->getRestrictItems($isAdmin); @@ -171,7 +183,7 @@ class Configurator extends BaseUtils * * @return object */ - function getRestrictItems($onlySystemItems=false) + protected function getRestrictItems($onlySystemItems=false) { if ($onlySystemItems) { return ((array) $this->getConfig()->systemItems); @@ -179,7 +191,7 @@ class Configurator extends BaseUtils if (empty($this->adminItems)) { //$this->adminItems= array_merge( (array) $this->getConfig()->systemItems, (array) $this->getConfig()->adminItems ); - $this->adminItems= $this->merge( (array) $this->getConfig()->systemItems, (array) $this->getConfig()->adminItems ); + $this->adminItems= Util::merge( (array) $this->getConfig()->systemItems, (array) $this->getConfig()->adminItems ); } return $this->adminItems; diff --git a/application/Espo/Utils/Datetime.php b/application/Espo/Core/Utils/Datetime.php old mode 100755 new mode 100644 similarity index 79% rename from application/Espo/Utils/Datetime.php rename to application/Espo/Core/Utils/Datetime.php index 557359243d..d1f531bdb0 --- a/application/Espo/Utils/Datetime.php +++ b/application/Espo/Core/Utils/Datetime.php @@ -1,12 +1,22 @@ config = $config; + } + + protected function getConfig() + { + return $this->config; + } /** * Get date in defined format @@ -71,7 +81,7 @@ class Datetime */ public function getDateFormat() { - return $this->getPhpDateFormat( $this->getOptions()->get('dateFormat') ); + return $this->getPhpDateFormat( $this->getConfig()->get('dateFormat') ); } /** @@ -81,7 +91,7 @@ class Datetime */ public function getTimeFormat() { - return $this->getPhpDateFormat( $this->getOptions()->get('timeFormat') ); + return $this->getPhpDateFormat( $this->getConfig()->get('timeFormat') ); } /** @@ -129,22 +139,6 @@ class Datetime return preg_replace($pattern, $replace, $jsFormat); } - /** - * Set options from the system config - * - * @return object - */ - function getOptions() - { - if (isset($this->options) && is_object($this->options)) { - return $this->options; - } - - $this->options = new Utils\Configurator(); - - return $this->options; - } - } ?> \ No newline at end of file diff --git a/application/Espo/Core/Utils/EntityManager.php b/application/Espo/Core/Utils/EntityManager.php new file mode 100644 index 0000000000..8738f2eea1 --- /dev/null +++ b/application/Espo/Core/Utils/EntityManager.php @@ -0,0 +1,48 @@ +config = $config; + } + + public function getConfig() + { + return $this->config; + } + + + public function create() + { + //EspoPHPDriver for Doctrine + $devMode= !$this->getConfig()->get('useCache'); + $doctrineConfig = Setup::createConfiguration($devMode, null, null); + $doctrineConfig->setMetadataDriverImpl(new EspoPHPDriver( + array( + $this->getConfig()->get('metadataConfig')->doctrineCache, + $this->getConfig()->get('defaultsPath').'/doctrine/metadata' + ) + )); + //END: EspoPHPDriver for Doctrine + + $doctrineConn = (array) $this->getConfig()->get('database'); + + // obtaining the entity manager + return \Doctrine\ORM\EntityManager::create($doctrineConn, $doctrineConfig); + } + + + +} + + +?> \ No newline at end of file diff --git a/application/Espo/Utils/FileManager.php b/application/Espo/Core/Utils/File/Manager.php old mode 100755 new mode 100644 similarity index 64% rename from application/Espo/Utils/FileManager.php rename to application/Espo/Core/Utils/File/Manager.php index b7291c8206..fd38c7131d --- a/application/Espo/Utils/FileManager.php +++ b/application/Espo/Core/Utils/File/Manager.php @@ -1,10 +1,10 @@ params = $params; + } + + protected function getParams() + { + return $this->params; + } + + + /** * Get a list of files in specified directory * @@ -37,9 +52,9 @@ class FileManager extends BaseUtils if (!in_array($value,array(".",".."))) { $add= false; - if (is_dir($path . $this->getSeparator() . $value)) { + if (is_dir($path . Utils\Util::getSeparator() . $value)) { if ($recursively) { - $result[$value] = $this->getFileList($path.$this->getSeparator().$value, $recursively, $filter, $fileType); + $result[$value] = $this->getFileList($path.Utils\Util::getSeparator().$value, $recursively, $filter, $fileType); } else if (in_array($fileType, array('all', 'dir'))){ $add= true; @@ -76,7 +91,7 @@ class FileManager extends BaseUtils */ function getContent($folderPath, $filePath='') { - $fullPath= $this->concatPath($folderPath, $filePath); + $fullPath= Utils\Util::concatPath($folderPath, $filePath); return $this->fileGetContents($fullPath); } @@ -93,7 +108,7 @@ class FileManager extends BaseUtils */ function setContent($content, $folderPath, $filePath='') { - $fullPath= $this->concatPath($folderPath, $filePath); + $fullPath= Utils\Util::concatPath($folderPath, $filePath); return $this->filePutContents($fullPath, $content); } @@ -123,10 +138,8 @@ class FileManager extends BaseUtils */ function setContentJSON($content, $folderPath, $filePath='') { - $json = new Utils\JSON(); - - if (!$json->isJSON($content)) { - $content= $json->encode($data); + if (!Utils\Json::isJSON($content)) { + $content= Utils\Json::encode($data); } return $this->setContent($content, $folderPath, $filePath); } @@ -147,10 +160,9 @@ class FileManager extends BaseUtils $savedDataArray= $this->getArrayData($fileContent); $newDataArray= $this->getArrayData($content); - $data= $this->merge($savedDataArray, $newDataArray); + $data= Utils\Util::merge($savedDataArray, $newDataArray); if ($isJSON) { - $json = new Utils\JSON(); - $data= $json->encode($data); + $data= Utils\Json::encode($data); } return $this->setContent($data, $folderPath, $filePath); @@ -180,7 +192,7 @@ class FileManager extends BaseUtils } } - $data= $this->merge($savedDataArray, $newDataArray); + $data= Utils\Util::merge($savedDataArray, $newDataArray); return $this->setContentPHP($data, $folderPath, $filePath); } @@ -196,203 +208,13 @@ class FileManager extends BaseUtils */ function appendContent($content, $folderPath, $filePath='') { - $fullPath= $this->concatPath($folderPath, $filePath); + $fullPath= Utils\Util::concatPath($folderPath, $filePath); return $this->filePutContents($fullPath, $content, FILE_APPEND | LOCK_EX); } - /** - * Unite file content to the file - * - * @param string $configParams - ["name", "cachePath", "corePath", "customPath"] - * @param bool $recursively - Note: only for first level of sub directory, other levels of sub directories will be ignored - * - * @return array - */ - public function uniteFiles($configParams, $recursively=false) - { - //EXAMPLE OF IMPLEMENTATION IN METADATA CLASS - /*if (empty($configParams) || empty($configParams->name) || empty($configParams->cachePath) || empty($configParams->corePath)) { - return false; - } - //merge matadata files - $content= $this->uniteFilesSingle($configParams->corePath, $configParams->name, $recursively); - - if (!empty($configParams->customPath)) { - $customDir= strstr($configParams->customPath, '{*}', true); - $dirList= $this->getFileList($customDir, false, '', 'dir'); - - foreach($dirList as $dirName) { - $curPath= str_replace('{*}', $dirName, $configParams->customPath); - //$content= array_merge($content, $this->uniteFilesSingle($curPath, $recursively)); - $content= $this->merge($content, $this->uniteFilesSingle($curPath, $configParams->name, $recursively)); - } - } - //END: merge matadata files - - //save medatada to cache files - $jsonData= $this->getObject('JSON')->encode($content); - - $cacheFile= $this->concatPath($configParams->cachePath, $configParams->name); - $result= $this->setContent($jsonData, $cacheFile.'.json'); - $result&= $this->setContent($this->getPHPFormat($content), $cacheFile.'.php'); - //END: save medatada to cache files - - return $result; */ - } - - /** - * Unite file content to the file for one directory [NOW ONLY FOR METADATA, NEED TO CHECK FOR LAYOUTS AND OTHERS] - * - * @param string $dirPath - * @param string $type - name of type ["metadata", "layouts"], ex. metadataConfig->name - * @param bool $recursively - Note: only for first level of sub directory, other levels of sub directories will be ignored - * @param string $moduleName - name of module if exists - * - * @return string - content of the files - */ - public function uniteFilesSingle($dirPath, $type, $recursively=false, $moduleName= '') - { - if (empty($dirPath) || !file_exists($dirPath)) { - return false; - } - $unsetFileName = $this->getObject('Configurator')->get('unsetFileName'); - //$scopeModuleMap = $this->getObject('Configurator')->get('scopeModuleMap'); - - //get matadata files - $fileList = $this->getFileList($dirPath, $recursively, '\.json$'); - - //print_r($fileList); - //echo '
'; - - $defaultValues = $this->loadDefaultValues($this->getDirName($dirPath), $type); - - $content= array(); - $unsets= array(); - foreach($fileList as $dirName => $fileName) { - - if (is_array($fileName)) { /*get content from files in a sub directory*/ - $content[$dirName]= $this->uniteFilesSingle($this->concatPath($dirPath,$dirName), $type, false, $moduleName); //only first level of a sub directory - - } else { /*get content from a single file*/ - if ($fileName == $unsetFileName) { - $fileContent = $this->getContent($dirPath, $fileName); - $unsets = $this->getArrayData($fileContent); - continue; - } /*END: Save data from unset.json*/ - - $mergedValues = $this->uniteFilesGetContent($dirPath, $fileName, $defaultValues); - - if (!empty($mergedValues)) { - $name = $this->getFileName($fileName, '.json'); - - //check if current module is a custom and if defined into scopeModuleMap - /*if (empty($moduleName) || (isset($scopeModuleMap->$name) && $scopeModuleMap->$name == $moduleName) ) { - $content[$name] = $mergedValues; - } */ - $content[$name] = $mergedValues; - } - } - } - - //unset content - $content= $this->uniteFilesUnset($content, $unsets); - //END: unset content - - /*print_r($content); - print_r($unsets); - echo '
'; */ - - return $content; - } - - /** - * Helpful method for get content from files for unite Files - * - * @param string $folderPath string - Folder path, Ex. myfolder - * @param bool $filePath - File path, Ex. file.json - * @param string | array() $defaults - It can be a string like ["metadata","layouts"] OR an array with default values - * - * @return array - */ - public function uniteFilesGetContent($folderPath, $fileName, $defaults) - { - $fileContent= $this->getContent($folderPath, $fileName); - $decoded= $this->getArrayData($fileContent); - - if (empty($decoded)) { - $this->getObject('Log')->add('FATAL EXCEPTION', 'Syntax error or empty file - '.$this->concatPath($folderPath, $fileName)); - } - else { - //Default values - if (is_string($defaults) && !empty($defaults)) { - $defType= $defaults; - unset($defaults); - $name= $this->getFileName($fileName, '.json'); - - $defaults= $this->loadDefaultValues($name, $defType); - } - $mergedValues= $this->merge($defaults, $decoded); - //END: Default values - - return $mergedValues; - } - - return array(); - } - - /** - * Unset content items defined in the unset.json - * - * @param array $content - * @param array $unsets - * - * @return array - */ - public function uniteFilesUnset($content, $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); - } - } - } - } - - return $content; - } - - /** - * Load default values for selected type [metadata, layouts] - * - * @param string $name - * @param string $type - [metadata, layouts] - * - * @return array - */ - function loadDefaultValues($name, $type='metadata') - { - $defaultPath= $this->getObject('Configurator')->get('defaultsPath'); - - $defaultValue= $this->getContent( $this->concatPath($defaultPath, $type), $name.'.json'); - if ($defaultValue!==false) { - //return default array - return $this->getObject('JSON')->decode($defaultValue, true); - } - - return array(); - } /** * Write a string to a file @@ -405,7 +227,7 @@ class FileManager extends BaseUtils */ public function filePutContents($filename, $data, $flags = 0) { - if ($this->checkCreateFile($filename)===false) { + if ($this->checkCreateFile($filename) === false) { return false; } @@ -457,7 +279,7 @@ class FileManager extends BaseUtils $dirPermission= is_string($dirPermission) ? base_convert($dirPermission,8,10) : $dirPermission; if (!mkdir($pathParts['dirname'], $dirPermission, true)) { - $this->getObject('Log')->add('FATAL', 'Permission denied: unable to generate a folder on the server - '.$pathParts['dirname']); + $GLOBALS['log']->add('FATAL', 'Permission denied: unable to generate a folder on the server - '.$pathParts['dirname']); return false; } } @@ -485,7 +307,7 @@ class FileManager extends BaseUtils $result= true; foreach($filePaths as $filePath) { if (!empty($dirPath)) { - $filePath= $this->concatPath($dirPath, $filePath); + $filePath= Utils\Util::concatPath($dirPath, $filePath); } if (file_exists($filePath) && is_file($filePath)) { @@ -512,7 +334,7 @@ class FileManager extends BaseUtils return false; } - /** + /** //TODO remove * Get an array data (if JSON convert to array) * * @param mixed $data - can be JSON, array @@ -521,13 +343,11 @@ class FileManager extends BaseUtils */ protected function getArrayData($data) { - $json = new Utils\JSON(); - if (is_array($data)) { return $data; } - else if ($json->isJSON($data)) { - return $json->decode($data, true); + else if (Utils\Json::isJSON($data)) { + return Utils\Json::decode($data, true); } return array(); @@ -574,7 +394,7 @@ class FileManager extends BaseUtils */ function getDirName($path) { - $pieces= explode($this->getSeparator(), $path); + $pieces= explode(Utils\Util::getSeparator(), $path); if (empty($pieces[count($pieces)-1])) { unset($pieces[count($pieces)-1]); } @@ -587,6 +407,28 @@ class FileManager extends BaseUtils } + /** + * Return content of PHP file + * + * @param string $varName - name of variable which contains the content + * @param array $content + * + * @return string | false + */ + function getPHPFormat($content) + { + if (empty($content)) { + return false; + } + + return ''; + } + + /** * Get default settings * @@ -598,7 +440,8 @@ class FileManager extends BaseUtils return $this->defaultPermissions; } - $this->defaultPermissions = $this->getObject('Configurator')->get('defaultPermissions'); + //$this->defaultPermissions = $this->getConfig()->get('defaultPermissions'); + $this->defaultPermissions = $this->getParams()->defaultPermissions; return $this->defaultPermissions; } @@ -733,7 +576,7 @@ class FileManager extends BaseUtils $items = array_slice($allFiles, 2); foreach ($items as $item) { - $this->chmodRecurse($path. $this->getSeparator() .$item, $fileOctal, $dirOctal); + $this->chmodRecurse($path. Utils\Util::getSeparator() .$item, $fileOctal, $dirOctal); } $this->chmodReal($path, $dirOctal); @@ -812,7 +655,7 @@ class FileManager extends BaseUtils $items = array_slice($allFiles, 2); foreach ($items as $item) { - $this->chownRecurse($path. $this->getSeparator() .$item, $user); + $this->chownRecurse($path. Utils\Util::getSeparator() .$item, $user); } return chowm($path, $user); @@ -865,7 +708,7 @@ class FileManager extends BaseUtils $items = array_slice($allFiles, 2); foreach ($items as $item) { - $this->chgrpRecurse($path. $this->getSeparator() .$item, $group); + $this->chgrpRecurse($path. Utils\Util::getSeparator() .$item, $group); } return chgrp($path, $group); diff --git a/application/Espo/Core/Utils/File/UniteFiles.php b/application/Espo/Core/Utils/File/UniteFiles.php new file mode 100644 index 0000000000..53a9490cfb --- /dev/null +++ b/application/Espo/Core/Utils/File/UniteFiles.php @@ -0,0 +1,222 @@ +fileManager = $fileManager; + $this->params = $params; + } + + + protected function getFileManager() + { + return $this->fileManager; + } + + protected function getParams() + { + return $this->params; + } + + + + + /** + * Unite file content to the file + * + * @param string $configParams - ["name", "cachePath", "corePath", "customPath"] + * @param bool $recursively - Note: only for first level of sub directory, other levels of sub directories will be ignored + * + * @return array + */ + public function uniteFiles($configParams, $recursively=false) + { + //EXAMPLE OF IMPLEMENTATION IN METADATA CLASS + /*if (empty($configParams) || empty($configParams->name) || empty($configParams->cachePath) || empty($configParams->corePath)) { + return false; + } + + //merge matadata files + $content= $this->uniteFilesSingle($configParams->corePath, $configParams->name, $recursively); + + if (!empty($configParams->customPath)) { + $customDir= strstr($configParams->customPath, '{*}', true); + $dirList= $this->getFileList($customDir, false, '', 'dir'); + + foreach($dirList as $dirName) { + $curPath= str_replace('{*}', $dirName, $configParams->customPath); + //$content= array_merge($content, $this->uniteFilesSingle($curPath, $recursively)); + $content= Utils\Util::merge($content, $this->uniteFilesSingle($curPath, $configParams->name, $recursively)); + } + } + //END: merge matadata files + + //save medatada to cache files + $jsonData= $this->getObject('JSON')->encode($content); + + $cacheFile= Utils\Util::concatPath($configParams->cachePath, $configParams->name); + $result= $this->setContent($jsonData, $cacheFile.'.json'); + $result&= $this->setContent($this->getFileManager()->getPHPFormat($content), $cacheFile.'.php'); + //END: save medatada to cache files + + return $result; */ + } + + /** + * Unite file content to the file for one directory [NOW ONLY FOR METADATA, NEED TO CHECK FOR LAYOUTS AND OTHERS] + * + * @param string $dirPath + * @param string $type - name of type ["metadata", "layouts"], ex. metadataConfig->name + * @param bool $recursively - Note: only for first level of sub directory, other levels of sub directories will be ignored + * @param string $moduleName - name of module if exists + * + * @return string - content of the files + */ + public function uniteFilesSingle($dirPath, $type, $recursively=false, $moduleName= '') + { + if (empty($dirPath) || !file_exists($dirPath)) { + return false; + } + $unsetFileName = $this->getParams()->unsetFileName; //TODO + //$unsetFileName = $this->getConfig('unsetFileName'); + + //get matadata files + $fileList = $this->getFileManager()->getFileList($dirPath, $recursively, '\.json$'); + + //print_r($fileList); + //echo '
'; + + $defaultValues = $this->loadDefaultValues($this->getFileManager()->getDirName($dirPath), $type); + + $content= array(); + $unsets= array(); + foreach($fileList as $dirName => $fileName) { + + if (is_array($fileName)) { /*get content from files in a sub directory*/ + $content[$dirName]= $this->uniteFilesSingle(Utils\Util::concatPath($dirPath,$dirName), $type, false, $moduleName); //only first level of a sub directory + + } else { /*get content from a single file*/ + if ($fileName == $unsetFileName) { + $fileContent = $this->getFileManager()->getContent($dirPath, $fileName); + $unsets = Utils\Json::getArrayData($fileContent); + continue; + } /*END: Save data from unset.json*/ + + $mergedValues = $this->uniteFilesGetContent($dirPath, $fileName, $defaultValues); + + if (!empty($mergedValues)) { + $name = $this->getFileManager()->getFileName($fileName, '.json'); + $content[$name] = $mergedValues; + } + } + } + + //unset content + $content= $this->uniteFilesUnset($content, $unsets); + //END: unset content + + /*print_r($content); + print_r($unsets); + echo '
'; */ + + return $content; + } + + /** + * Helpful method for get content from files for unite Files + * + * @param string $folderPath string - Folder path, Ex. myfolder + * @param bool $filePath - File path, Ex. file.json + * @param string | array() $defaults - It can be a string like ["metadata","layouts"] OR an array with default values + * + * @return array + */ + public function uniteFilesGetContent($folderPath, $fileName, $defaults) + { + $fileContent= $this->getFileManager()->getContent($folderPath, $fileName); + $decoded= Utils\Json::getArrayData($fileContent); + + if (empty($decoded)) { + $GLOBALS['log']->add('FATAL EXCEPTION', 'Syntax error or empty file - '.Utils\Util::concatPath($folderPath, $fileName)); + } + else { + //Default values + if (is_string($defaults) && !empty($defaults)) { + $defType= $defaults; + unset($defaults); + $name= $this->getFileManager()->getFileName($fileName, '.json'); + + $defaults= $this->loadDefaultValues($name, $defType); + } + $mergedValues= Utils\Util::merge($defaults, $decoded); + //END: Default values + + return $mergedValues; + } + + return array(); + } + + /** + * Unset content items defined in the unset.json + * + * @param array $content + * @param array $unsets + * + * @return array + */ + public function uniteFilesUnset($content, $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); + } + } + } + } + + return $content; + } + + /** + * Load default values for selected type [metadata, layouts] + * + * @param string $name + * @param string $type - [metadata, layouts] + * + * @return array + */ + function loadDefaultValues($name, $type='metadata') + { + $defaultPath= $this->getParams()->defaultsPath; + //$defaultPath= $this->getConfig('defaultsPath'); + + $defaultValue= $this->getFileManager()->getContent( Utils\Util::concatPath($defaultPath, $type), $name.'.json'); + if ($defaultValue!==false) { + //return default array + return Utils\Json::decode($defaultValue, true); + } + + return array(); + } + +} + +?> \ No newline at end of file diff --git a/application/Espo/Utils/JSON.php b/application/Espo/Core/Utils/Json.php old mode 100755 new mode 100644 similarity index 76% rename from application/Espo/Utils/JSON.php rename to application/Espo/Core/Utils/Json.php index 702b595e7e..906b58f7b1 --- a/application/Espo/Utils/JSON.php +++ b/application/Espo/Core/Utils/Json.php @@ -1,9 +1,8 @@ add('ERROR', 'Value cannot be decoded to JSON - '.print_r($value, true)); + $GLOBALS['log']->add('ERROR', 'Value cannot be decoded to JSON - '.print_r($value, true)); } return $json; @@ -53,8 +51,7 @@ class JSON extends BaseUtils public static function decode($json, $assoc = false, $depth = 512, $options = 0) { if (is_array($json)) { - $Log= new Utils\Log(); - $Log->add('WARNING', 'JSON:decode() - JSON cannot be decoded - '.$json); + $GLOBALS['log']->add('WARNING', 'JSON:decode() - JSON cannot be decoded - '.$json); return false; } @@ -90,9 +87,29 @@ class JSON extends BaseUtils public static function isJSON($json){ if ($json=='[]') { return true; - } + } - return self::decode($json) != null; + return static::decode($json) != null; + } + + + /** + * Get an array data (if JSON convert to array) + * + * @param mixed $data - can be JSON, array + * + * @return array + */ + public static function getArrayData($data) + { + if (is_array($data)) { + return $data; + } + else if (static::isJSON($data)) { + return static::decode($data, true); + } + + return array(); } } diff --git a/application/Espo/Utils/Layout.php b/application/Espo/Core/Utils/Layout.php old mode 100755 new mode 100644 similarity index 52% rename from application/Espo/Utils/Layout.php rename to application/Espo/Core/Utils/Layout.php index 1f59498b14..87f6257b23 --- a/application/Espo/Utils/Layout.php +++ b/application/Espo/Core/Utils/Layout.php @@ -1,15 +1,39 @@ config = $config; + $this->fileManager = $fileManager; + $this->metadata = $metadata; + } + + protected function getConfig() + { + return $this->config; + } + + protected function getFileManager() + { + return $this->fileManager; + } + + protected function getMetadata() + { + return $this->metadata; + } + /** * Get Layout context @@ -19,15 +43,15 @@ class Layout extends FileManager * * @return json */ - function getLayout($controller, $name) + function get($controller, $name) { - $fileFullPath = $this->concatPath($this->getLayoutPath($controller), $name.'.json'); + $fileFullPath = Util::concatPath($this->getLayoutPath($controller), $name.'.json'); if (!file_exists($fileFullPath)) { //load defaults - $defaultPath = $this->getObject('Configurator')->get('defaultsPath'); - $fileFullPath = $this->concatPath( $this->concatPath($defaultPath, $this->getConfig()->name), $name.'.json' ); + $defaultPath = $this->getConfig()->get('defaultsPath'); + $fileFullPath = Util::concatPath( Util::concatPath($defaultPath, $this->getLayoutConfig()->name), $name.'.json' ); //END: load defaults if (!file_exists($fileFullPath)) { @@ -35,7 +59,7 @@ class Layout extends FileManager } } - return $this->getContent($fileFullPath); + return $this->getFileManager()->getContent($fileFullPath); } @@ -49,19 +73,19 @@ class Layout extends FileManager * * @return bool */ - function mergeLayout($data, $controller, $name) + function merge($data, $controller, $name) { $layoutPath = $this->getLayoutPath($controller); /*//merge data with defaults values - $defaults = $this->loadDefaultValues($name, $this->getConfig()->name); + $defaults = $this->loadDefaultValues($name, $this->getLayoutConfig()->name); $decoded = $this->getArrayData($data); $mergedValues= $this->merge($defaults, $decoded); $data= $this->getObject('JSON')->encode($mergedValues); //END: merge data with defaults values */ - return $this->mergeContent($data, $layoutPath, $name.'.json', true); + return $this->getFileManager()->mergeContent($data, $layoutPath, $name.'.json', true); } @@ -75,7 +99,7 @@ class Layout extends FileManager * * @return bool */ - function setLayout($data, $controller, $name) + function set($data, $controller, $name) { if (empty($controller) || empty($name)) { return false; @@ -83,7 +107,7 @@ class Layout extends FileManager $layoutPath = $this->getLayoutPath($controller); - return $this->setContent($data, $layoutPath, $name.'.json'); + return $this->getFileManager()->setContent($data, $layoutPath, $name.'.json'); } /** @@ -96,13 +120,13 @@ class Layout extends FileManager */ public function getLayoutPath($entityName, $delim= '/') { - $moduleName= $this->getScopeModuleName($entityName); + $moduleName= $this->getMetadata()->getScopeModuleName($entityName); - $path= $this->getConfig()->corePath; + $path= $this->getLayoutConfig()->corePath; if (!empty($moduleName)) { - $path= str_replace('{*}', $moduleName, $this->getConfig()->customPath); + $path= str_replace('{*}', $moduleName, $this->getLayoutConfig()->customPath); } - $path= $this->concatPath($path, $entityName); + $path= Util::concatPath($path, $entityName); if ($delim!='/') { $path = str_replace('/', $delim, $path); @@ -117,13 +141,13 @@ class Layout extends FileManager * * @return object */ - function getConfig() + protected function getLayoutConfig() { if (isset($this->layoutConfig) && is_object($this->layoutConfig)) { return $this->layoutConfig; } - $this->layoutConfig = $this->getObject('Configurator')->get('layoutConfig'); + $this->layoutConfig = $this->getConfig()->get('layoutConfig'); return $this->layoutConfig; } diff --git a/application/Espo/Utils/Log.php b/application/Espo/Core/Utils/Log.php old mode 100755 new mode 100644 similarity index 81% rename from application/Espo/Utils/Log.php rename to application/Espo/Core/Utils/Log.php index d27ad446e6..2900978c86 --- a/application/Espo/Utils/Log.php +++ b/application/Espo/Core/Utils/Log.php @@ -1,19 +1,11 @@ fileManager = $fileManager; + $this->rest = $rest; + $this->resolver = $resolver; + $this->params = $params; + } + + + + protected function getFileManager() + { + return $this->fileManager; + } + + protected function getRest() + { + return $this->rest; + } + + protected function getResolver() + { + return $this->resolver; + } + + protected function getParams() + { + return $this->params; + } + + /** * Catch error and save it to the log file * @@ -97,8 +127,8 @@ class Log extends BaseUtils //try to resolve the problem automatically if ($useResolver) { - $this->getObject('Resolver')->handle($Exception); - } + $this->getResolver()->handle($Exception); + } $errorType= $this->phpErrorTypes[$errNo]; if (empty($errorType)) { @@ -117,10 +147,8 @@ class Log extends BaseUtils */ protected function logError($text) { - $datetime= $this->getObject('Datetime')->getDatetime(); - - $text= $datetime.' '.$text; - return $this->getObject('FileManager')->appendContent($text, $this->getOptions()->dir, $this->getOptions()->file); + $text= $this->getParams()->datetime.' '.$text; + return $this->getFileManager()->appendContent($text, $this->getParams()->options->dir, $this->getParams()->options->file); } /** @@ -149,7 +177,7 @@ class Log extends BaseUtils } if (in_array($errorType, $this->dieErrors)) { - Utils\Api\Helper::displayError($text, 500); + $this->getRest()->displayError($text, 500); } return $status; @@ -163,7 +191,7 @@ class Log extends BaseUtils */ protected function isSave($errorType) { - $configLevel= $this->getLevelValue($this->getOptions()->level); + $configLevel= $this->getLevelValue($this->getParams()->options->level); $errorLevel= $this->getLevelValue($errorType); if ($configLevel >= $errorLevel) { @@ -220,22 +248,6 @@ class Log extends BaseUtils } - /** - * Get options from the system config - * - * @return object - */ - function getOptions() - { - if (isset($this->options) && is_object($this->options)) { - return $this->options; - } - - $this->options = $this->getObject('Configurator')->get('logger'); - - return $this->options; - } - } diff --git a/application/Espo/Core/Utils/Metadata.php b/application/Espo/Core/Utils/Metadata.php new file mode 100644 index 0000000000..b322fd00a7 --- /dev/null +++ b/application/Espo/Core/Utils/Metadata.php @@ -0,0 +1,438 @@ +entityManager = $entityManager; + $this->config = $config; + $this->uniteFiles = $uniteFiles; + $this->fileManager = $fileManager; + $this->doctrineConverter = new \Espo\Core\Doctrine\EspoConverter($this); //TODO + } + + + protected function getEntityManager() + { + return $this->entityManager; + } + + protected function getConfig() + { + return $this->config; + } + + protected function getDoctrineConverter() + { + return $this->doctrineConverter; + } + + protected function getUniteFiles() + { + return $this->uniteFiles; + } + + protected function getFileManager() + { + return $this->fileManager; + } + + + /** + * Get Metadata context + * + * @param $isJSON + * @param bool $reload + * + * @return json | array + */ + //HERE --- ADD CREATING DOCTRINE METADATA + public function get($isJSON=true, $reload=false) + { + $config= $this->getMetaConfig(); + + if (!$this->getConfig()->get('useCache')) { + $reload = true; + } + + if (!file_exists($config->cacheFile) || $reload) { + $data= $this->getMetadataOnly(false, true); + if ($data === false) { + return false; + } + + //save medatada to cache files + $this->getFileManager()->setContentPHP($data, $this->getMetaConfig()->cacheFile); + + $GLOBALS['log']->add('Debug', 'Metadata:get() - converting to doctrine metadata'); + if ($this->convertToDoctrine($data)) { + $GLOBALS['log']->add('Debug', 'Metadata:get() - database rebuild'); + + try{ + $this->rebuildDatabase(); + } catch (\Exception $e) { + $GLOBALS['log']->add('EXCEPTION', 'Try to rebuildDatabase'.'. Details: '.$e->getMessage()); + } + } + } + + return $this->getMetadataOnly($isJSON, false); + } + + + + /** + * Get Metadata only without saving it to the a file and database sync + * + * @param $isJSON + * @param bool $reload + * + * @return json | array + */ + + public function getMetadataOnly($isJSON=true, $reload=false) + { + $config= $this->getMetaConfig(); + + if (!$this->getConfig()->get('useCache')) { + $reload = true; + } + + $data = false; + if (!file_exists($config->cacheFile) || $reload) { + $data= $this->uniteFiles($config, true); + + if ($data === false) { + $GLOBALS['log']->add('FATAL', 'Metadata:getMetadata() - metadata unite file cannot be created'); + } + } + else if (file_exists($config->cacheFile)) { + $data= $this->getFileManager()->getContent($config->cacheFile); + } + + if ($isJSON) { + $data= Json::encode($data); + } + + return $data; + } + + + + /** + * Set Metadata data + * Ex. $type= menu, $scope= Account then will be created a file metadataFolder/menu/Account.json + * + * @param JSON string $data + * @param string $type - ex. menu + * @param string $scope - Account + * + * @return bool + */ + public function set($data, $type, $scope) + { + $fullPath= $this->getMetaConfig()->corePath; + $moduleName= $this->getScopeModuleName($scope); + + if (!empty($moduleName)) { + $fullPath= str_replace('{*}', $moduleName, $this->getMetaConfig()->customPath); + } + $fullPath= Util::concatPath($fullPath, $type); + + //merge data with defaults values + $defaults= $this->getUniteFiles()->loadDefaultValues($type, 'metadata'); + + $decoded= Json::getArrayData($data); + $mergedValues= Util::merge($defaults, $decoded); + $data= Json::encode($mergedValues); + //END: merge data with defaults values + + $result= $this->getFileManager()->setContent($data, $fullPath, $scope.'.json'); + + //create classes only for "defs" metadata + if ($type == $this->doctrineMetadataName) { + try{ + $this->generateEntities( array($this->getEntityPath($scope)) ); + } catch (\Exception $e) { + $GLOBALS['log']->add('EXCEPTION', 'Try to generate Entities for '.$this->getEntityPath($scope).'. Details: '.$e->getMessage()); + } + } + + return $result; + } + + + /** + * Metadata conversion from Espo format into Doctrine + * + * @param object $metadata + * + * @return bool + */ + protected function convertToDoctrine($metadata) + { + $cacheDir= $this->getMetaConfig()->doctrineCache; + + //remove all existing files + $this->getFileManager()->removeFilesInDir($cacheDir); + + //create files named like "Espo.Entities.User.php" + $result= true; + foreach($metadata[$this->doctrineMetadataName] as $entityName => $meta) { + $doctrineMetaWithName= $this->getDoctrineConverter()->convert($entityName, $meta, true); + + if (empty($doctrineMetaWithName)) { + $GLOBALS['log']->add('FATAL', 'Metadata:convertToDoctrine(), Entity:'.$entityName.' - metadata cannot be converted into Doctrine format'); + return false; + } + + //create a doctrine metadata file + $fileName= str_replace('\\', '.', $doctrineMetaWithName['name']).'.php'; + $result&= $this->getFileManager()->setContent($this->getFileManager()->getPHPFormat($doctrineMetaWithName['meta']), $cacheDir, $fileName); + //END: create a doctrine metadata file + } + + return $result; + } + + /** + * Rebuild a database accordinly to metadata + * + * @return bool + */ + public function rebuildDatabase() + { + $tool = new \Doctrine\ORM\Tools\SchemaTool($this->getEntityManager()); + + $cmf = new \Doctrine\ORM\Tools\DisconnectedClassMetadataFactory(); + $cmf->setEntityManager($this->getEntityManager()); // $em is EntityManager instance + $classes = $cmf->getAllMetadata(); + + $tool->updateSchema($classes); + + return true; //always true, because updateSchema just returns the VOID + } + + /** + * Rebuild a database accordinly to metadata + * + * @return bool + */ + public function generateEntities($classNames) + { + if (!is_array($classNames)) { + $classNames= (array) $classNames; + } + + $cmf = new \Doctrine\ORM\Tools\DisconnectedClassMetadataFactory(); + $cmf->setEntityManager($this->getEntityManager()); // $em is EntityManager instance + + $metadata= array(); + foreach($classNames as $className) { + $metadata[]= $cmf->getMetadataFor($className); + } + + if (!empty($metadata)) { + $generator = new \Doctrine\ORM\Tools\EntityGenerator(); + $generator->setGenerateAnnotations(false); + $generator->setGenerateStubMethods(true); + $generator->setRegenerateEntityIfExists(false); + $generator->setUpdateEntityIfExists(false); + $generator->generate($metadata, 'application'); + + return true; //always true, because generate just returns the VOID + } + + return false; + } + + /** + * Unite file content to the file + * + * @param string $configParams - ["name", "cachePath", "corePath", "customPath"] + * @param bool $recursively - Note: only for first level of sub directory, other levels of sub directories will be ignored + * + * @return array + */ + function uniteFiles($configParams, $recursively=false) + { + if (empty($configParams) || empty($configParams->name) || empty($configParams->cachePath) || empty($configParams->corePath)) { + return false; + } + + //merge matadata files + $content= $this->getUniteFiles()->uniteFilesSingle($configParams->corePath, $configParams->name, $recursively); + + if (!empty($configParams->customPath)) { + $customDir= strstr($configParams->customPath, '{*}', true); + $dirList= $this->getFileManager()->getFileList($customDir, false, '', 'dir'); + + foreach($dirList as $dirName) { + $curPath= str_replace('{*}', $dirName, $configParams->customPath); + $content= Util::merge($content, $this->getUniteFiles()->uniteFilesSingle($curPath, $configParams->name, $recursively, $dirName)); + } + } + //END: merge matadata files + + return $content; + } + + /** + * Get Entity path, ex. Espo.Entities.Account or Modules\Crm\Entities\MyModule + * + * @param string $entityName + * @param bool $delim - delimiter + * + * @return string + */ + public function getEntityPath($entityName, $delim= '\\') + { + $path = $this->getScopePath($entityName, $delim); + + return implode($delim, array($path, 'Entities', ucfirst($entityName))); + } + + + /** + * Get Scopes + * + * @param string $moduleName + * @param bool $reload + * + * @return array + */ + //NEED TO CHANGE + public function getScopes($moduleName= '', $reload = false) + { + if (!$reload && !empty($this->scopes)) { + return $this->scopes; + } + + $metadata = $this->getMetadataOnly(false); + + $scopes = array(); + foreach($metadata['scopes'] as $name => $details) { + $scopes[$name] = isset($details['module']) ? $details['module'] : ''; + } + + return $this->scopes = $scopes; + } + + + /** + * Get module name if it's a custom module or empty string for core entity + * + * @param string $scopeName + * + * @return string + */ + public function getScopeModuleName($scopeName) + { + $scopeModuleMap= $this->getScopes(); + + $lowerEntityName= strtolower($scopeName); + foreach($scopeModuleMap as $rowEntityName => $rowModuleName) { + if ($lowerEntityName==strtolower($rowEntityName)) { + return $rowModuleName; + } + } + + return ''; + } + + + /** + * Get Scope path, ex. "Modules/Crm" for Account + * + * @param string $scopeName + * @param string $delim - delimiter + * + * @return string + */ + public function getScopePath($scopeName, $delim= '/') + { + $moduleName= $this->getScopeModuleName($scopeName); + + $path= $this->getConfig()->get('espoPath'); + if (!empty($moduleName)) { + $path= str_replace('{*}', $moduleName, $this->getConfig()->get('espoModulePath')); + } + + if ($delim!='/') { + $path = str_replace('/', $delim, $path); + } + + return $path; + } + + /** + * Get Full Scope path, ex. "application/Modules/Crm" for Account + * + * @param string $scopeName + * @param string $delim - delimiter + * + * @return string + */ + public function getScopePathFull($scopeName, $delim= '/') + { + return Util::concatPath('application', $this->getScopePath($scopeName, $delim)); + } + + /** + * Check if scope exists + * + * @param string $scopeName + * + * @return bool + */ + public function isScopeExists($scopeName) + { + $scopeModuleMap= $this->getScopes(); + + $lowerEntityName= strtolower($scopeName); + foreach($scopeModuleMap as $rowEntityName => $rowModuleName) { + if ($lowerEntityName==strtolower($rowEntityName)) { + return true; + } + } + + return false; + } + + /** + * Get settings for Metadata + * + * @return object + */ + protected function getMetaConfig() + { + if (isset($this->metadataConfig) && is_object($this->metadataConfig)) { + return $this->metadataConfig; + } + + $this->metadataConfig = $this->getConfig()->get('metadataConfig'); + $this->metadataConfig->cacheFile= Util::concatPath($this->metadataConfig->cachePath, $this->metadataConfig->name).'.php'; + + return $this->metadataConfig; + } + +} + + +?> \ No newline at end of file diff --git a/application/Espo/Utils/Resolver.php b/application/Espo/Core/Utils/Resolver.php old mode 100755 new mode 100644 similarity index 56% rename from application/Espo/Utils/Resolver.php rename to application/Espo/Core/Utils/Resolver.php index 38e42c8a1d..40e78abf9a --- a/application/Espo/Utils/Resolver.php +++ b/application/Espo/Core/Utils/Resolver.php @@ -1,16 +1,29 @@ 'DBALException', 'ReflectionException' => 'ReflectionException', ); + private $metadata; + + + public function __construct(\Espo\Core\Utils\Metadata $metadata) + { + $this->metadata = $metadata; + } + + + protected function getMetadata() + { + return $this->metadata; + } + public function handle($Exception) { @@ -24,13 +37,13 @@ class Resolver extends BaseUtils if (in_array($handler, array_keys($this->exceptions))) { $method= $this->exceptions[$handler]; - $this->getObject('Log')->add('INFO', 'Try to resolve the exception - '.$handler); + $GLOBALS['log']->add('INFO', 'Try to resolve the exception - '.$handler); $result= false; try { $result= $this->$method($args); } catch(\Exception $e) { - $this->getObject('Log')->add('INFO', 'Could not resolve the exception - '.$handler.'. Details below:'); - $this->getObject('Log')->catchException($e, false); + $GLOBALS['log']->add('INFO', 'Could not resolve the exception - '.$handler.'. Details below:'); + $GLOBALS['log']->catchException($e, false); } return $result; } @@ -41,12 +54,12 @@ class Resolver extends BaseUtils protected function DBALException($args) { - return $this->getObject('Metadata')->rebuildDatabase(); + return $this->getMetadata()->rebuildDatabase(); } protected function ReflectionException($args) { - return $this->getObject('Metadata')->generateEntities($args); + return $this->getMetadata()->generateEntities($args); } diff --git a/application/Espo/Core/Utils/User.php b/application/Espo/Core/Utils/User.php new file mode 100644 index 0000000000..76ebf81982 --- /dev/null +++ b/application/Espo/Core/Utils/User.php @@ -0,0 +1,75 @@ +entityManager = $entityManager; + $this->config = $config; + } + + protected function getEntityManager() + { + return $this->entityManager; + } + + protected function getConfig() + { + return $this->config; + } + + public function getCurrentUser() + { + return $this->currentUser; + } + + + protected function setCurrentUser(\Espo\Entities\User $user) + { + $this->currentUser = $user; + } + + + + public function authenticate($username, $password) + { + $user = $this->getEntityManager()->getRepository('\Espo\Entities\User')->findOneBy(array('username' => $username)); + + if ( $password == $user->getPassword() ) { + $this->setCurrentUser($user); + return true; + } + + return false; + } + + + public function isAdmin(\Espo\Entities\User $user = null) + { + if (is_null($user)) { + $user = $this->getCurrentUser(); + } + + if ($user instanceof \Espo\Entities\User) { + $id = $user->getId(); + if ( !empty($id) ) { + return $user->getIsAdmin(); + } + } + + return false; + } + + + +} + + +?> \ No newline at end of file diff --git a/application/Espo/Core/Utils/Util.php b/application/Espo/Core/Utils/Util.php new file mode 100644 index 0000000000..56655c63b6 --- /dev/null +++ b/application/Espo/Core/Utils/Util.php @@ -0,0 +1,192 @@ + $maVal) { + $found = false; + foreach($array as $aKey => $aVal) { + if ((string)$maKey == (string)$aKey){ + $found = true; + if (is_array($maVal) && is_array($aVal)){ + $array[$maKey] = static::merge($aVal, $maVal); + } + else { + + if (is_array($aVal)){ + $array[$maKey] = static::merge($aVal, array($maVal)); + } + elseif (is_array($maVal)){ + $array[$maKey] = static::merge(array($aVal), $maVal); + } + else { + //merge logic + if (!is_numeric($maKey)){ + $array[$maKey] = $maVal; + } + elseif (!in_array($maVal, $array)) { + $array[] = $maVal; + } + //END: merge ligic + } + } + + break; + } + } + // add an item if key not found + if (!$found){ + $array[$maKey] = $maVal; + } + + } + + return $array; + } + + + /** + * Get a full path of the file + * + * @param string $folderPath - Folder path, Ex. myfolder + * @param string $filePath - File path, Ex. file.json + * + * @return string + */ + public static function concatPath($folderPath, $filePath='') + { + if (empty($filePath)) { + return $folderPath; + } + else { + if (substr($folderPath, -1) == static::getSeparator()) { + return $folderPath . $filePath; + } + return $folderPath . static::getSeparator() . $filePath; + } + } + + + /** + * Convert array to object format recursively + * + * @param array $array + * @return object + */ + public static function arrayToObject($array) + { + if (is_array($array)) { + return (object) array_map("static::arrayToObject", $array); + } else { + return $array; // Return an object + } + } + + + /** + * Convert object to array format recursively + * + * @param object $object + * @return array + */ + public static function objectToArray($object) + { + if (is_object($object)) { + $object = (array) $object; + } + + return is_array($object) ? array_map("static::objectToArray", $object) : $object; + } + +} + + +?> \ No newline at end of file diff --git a/application/Espo/Core/systemConfig.php b/application/Espo/Core/defaults/systemConfig.php similarity index 100% rename from application/Espo/Core/systemConfig.php rename to application/Espo/Core/defaults/systemConfig.php diff --git a/application/Espo/Entities/User.php b/application/Espo/Entities/User.php index b8389c95b5..068dec4f5c 100755 --- a/application/Espo/Entities/User.php +++ b/application/Espo/Entities/User.php @@ -2,13 +2,12 @@ namespace Espo\Entities; -use Doctrine\Common\Collections\ArrayCollection, - \Espo\Core as Core; +use Doctrine\Common\Collections\ArrayCollection; /** * @Entity @Table(name="users") */ -class User extends Core\Base +class User { /** * @var string @@ -38,6 +37,11 @@ class User extends Core\Base return $this->username; } + public function getPassword() + { + return $this->password; + } + public function getIsAdmin() { return $this->isAdmin; @@ -48,37 +52,4 @@ class User extends Core\Base $this->name = $name; } - /** - * Check user's credentials (NEED TO REWRITE) - */ - public function login($username, $password) - { - $dbUsername= 'admin'; - $dbPassword= '1'; - - if ($username==$dbUsername && $password==$dbPassword) { - return true; - } - - return false; - } - - //NEED TO REWRITE - public function isAdmin($username='') - { - if (empty($username)) { - $username= $this->getUsername(); - } - - if ( !isset($this->id) || empty($this->id) ) { - global $base; - return $base->em->getRepository('\Espo\Entities\User')->findOneBy(array('username' => $username))->getIsAdmin(); //$this->getEntityManager() - } - - if ($this->getUsername() == $username) { - return $this->getIsAdmin(); - } - - return false; - } } diff --git a/application/Espo/Utils/Api/Helper.php b/application/Espo/Utils/Api/Helper.php deleted file mode 100755 index 956e64d972..0000000000 --- a/application/Espo/Utils/Api/Helper.php +++ /dev/null @@ -1,77 +0,0 @@ -log->add('ERROR', 'API ['.$app->request()->getMethod().']:'.$app->router()->getCurrentRoute()->getPattern().', Params:'.print_r($app->router()->getCurrentRoute()->getParams(), true).', InputData: '.$app->request()->getBody().' - '.$logMess); - Utils\Api\Helper::displayError($errMessage, $errCode); - } - //END: check if result is false - - //$json= new Utils\JSON(); - //$data= $json->isJSON($data) ? $data : $json->encode($data); - - //Can be optimized to the manual selection of input data type - /*if ($jsonEncode) { - $data= Utils\JSON::encode($data); - }*/ - - ob_clean(); - echo $data; - $app->stop(); - } - - /** - * Output the error and stop app execution - * - * @static - * @param string $text - * @param int $statusCode - * - * @return void - */ - public static function displayError($text, $statusCode=500) - { - $log= new Utils\Log(); - $log->add('INFO', 'Display Error: '.$text.', Code: '.$statusCode.' URL: '.$_SERVER['REQUEST_URI']); - - if (class_exists('Slim\Slim', false)) { - $app = Slim::getInstance(); - - $app->response()->status($statusCode); - $app->response()->header('X-Status-Reason', $text); - //$app->response()->header('X-Status-Reason', 'Fatal Error/Exception. Please check error log file for details.'); - $app->stop(); - } - else { - $log->add('INFO', 'Could not get Slim instance. It looks like a direct call (bypass API). URL: '.$_SERVER['REQUEST_URI']); - die($text); - } - } - -} - -?> \ No newline at end of file diff --git a/application/Espo/Utils/Api/Rest-old.php b/application/Espo/Utils/Api/Rest-old.php deleted file mode 100755 index 6fd0ec3854..0000000000 --- a/application/Espo/Utils/Api/Rest-old.php +++ /dev/null @@ -1,401 +0,0 @@ - 'OK', - 'responce' => 'default response', - ); - - //DIRECTORY_SEPARATOR - - - function main() - { - $template = <<Main Page of REST API!!! -EOT; - self::output($template); - } - - function appAction($action) - { - $returns= array('action' => $action); - self::output(json_encode($returns)); - } - - function getControllerList($controller) - { - $sugarRest= self::sugarConnect(true, $controller); - - if (in_array($controller, self::$exModules)) { - self::output(json_encode(self::$defaultResponce)); - } - - $soap_params= array( - 'module_name'=>$controller, - 'fields'=>array(), - ); - $fields= $sugarRest->call('get_module_fields', $soap_params); - - $filter_fields= array_keys($fields['module_fields']); - $controller_result= $sugarRest->getList($controller, $filter_fields, '', '0', '10'); - - self::output(json_encode($controller_result)); - } - - function getController($controller, $id, $echo=1) - { - $sugarRest= self::sugarConnect(true, $controller); - - if (in_array($controller, self::$exModules)) { - self::output(json_encode(self::$defaultResponce)); - } - - $where= " ".strtolower($controller).".id = '".$id."'"; - $soap_params= array( - 'module_name'=>$controller, - 'fields'=>array(), - ); - $fields= $sugarRest->call('get_module_fields', $soap_params); - - $filter_fields= array_keys($fields['module_fields']); - $controller_result= $sugarRest->getList($controller, $filter_fields, $where, '0', '10'); - - if (!$echo) { - return $controller_result; - } - - self::output(json_encode($controller_result)); - } - - function getLayout($controller, $type, $echo=1) - { - if (!$data = self::getFromFile(self::$layoutPath, $controller, $type)) { - return false; - } - - if (!$echo) { - return $data; - } - - self::output($data); - } - - function putLayout($controller, $type) - { - $app= Slim::getInstance(); - $data = $app->request()->getBody(); - - if (self::saveToFile($data, self::$layoutPath, $controller, $type)) { - self::output($data); - } - else { - self::error('Layout Problem'); - } - } - - function patchLayout($controller, $type) - { - if (!$savedData = self::getFromFile(self::$layoutPath, $controller, $type)) { - return false; - } - if (empty($savedData)) { - $savedData= '{}'; - } - $savedDataArray= json_decode($savedData, true); - - $app= Slim::getInstance(); - $newData = $app->request()->getBody(); - - $newDataArray= json_decode($newData, true); - - $data= json_encode(array_merge($savedDataArray, $newDataArray)); - - if (self::saveToFile($data, self::$layoutPath, $controller, $type)) { - self::output($data); - } - else { - self::error('Layout Problem'); - } - } - - //new - function putMetadata($type, $scope) - { - $app= Slim::getInstance(); - $data = $app->request()->getBody(); - - //die('Here'); - - if (self::saveToFile($data, self::$metadataPath, $type, $scope)) { - self::output($data); - } - else { - self::error('Save Metadata Problem'); - } - } - - //new - function getMetadata($type, $scope) - { - if (!$data = self::getFromFile(self::$metadataPath, $type, $scope)) { - return false; - } - - self::output($data); - } - - function getMetadataByType($type) - { - //$folderPath= implode('/', array(self::$metadataPath, $type)); - $folderPath= self::$metadataPath.'/'.$type; - - require_once('include/FileManager/FileManager.php'); - $Files= new FileManager(); - - //check if cache metadata file exists - $cacheFile= self::$cachePath .$Files->getSeparator(). $folderPath . $Files->getFileExt(); - if (file_exists($cacheFile)) { - $data= $Files->getContent($cacheFile); - self::output($data); - } - //END: check if cache metadata file exists - - //merge matadata files - $fileList= $Files->getFileList($folderPath, false); - - $content= array(); - foreach($fileList as $fileName) { - $fileContent= $Files->getContent($folderPath, $fileName); - if ($fileContent) { - $content[]= json_decode($fileContent); - } - } - $data= json_encode($content); - //END: merge matadata files - - //save medatada to cache file - $Files->setContent($data, $cacheFile); - //END: save medatada to cache file - - self::output($data); - } - - - function getUserPreferences() - { - $module= 'Users'; - $id= '1'; - - $user= self::getController($module, $id, false); - - $userJson= json_encode($user['entry_list'][$id]); - self::output('{"user":'.$userJson.',"preferences":{}}'); - } - - function getSettings() - { - if (!$data = self::getFromFile(self::$layoutPath, 'app', 'settings')) { - return false; - } - - self::output($data); - - /*$returns= array( - 'theme' => 'default', - 'language' => 'en', - ); - - self::output(json_encode($returns));*/ - } - - function putSettings() - { - $app= Slim::getInstance(); - $data = $app->request()->getBody(); - - if (self::saveToFile($data, self::$layoutPath, 'app', 'settings')) { - self::output($data); - } - else { - self::error('Saving Problem'); - } - } - - - function sugarConnect($check=false, $controller='') - { - require_once('api/sugar.REST.php'); - $sugarRest= new sugarRest(); - - if ($check) { - $modules= $sugarRest->modules(); - $modules= array_merge($modules, self::$exModules); - - if (!in_array($controller, $modules)) { - - $app= Slim::getInstance(); - $app->halt(404); - - //echo json_encode(array('error'=>'---Module does not exist')); - return false; - } - } - - return $sugarRest; - } - - - /** - * Save layout from the PUT request - * - * @param string $data JSON string - * @param string $controller Ex. Accounts, Leads - * @param string $type Layout type, ex. list, detail, edit - * - * @return bool - */ - /*function saveLayoutToFile($data, $controller, $type) - { - $folderPath= self::$layoutPath.'/'.$controller; - - if (!file_exists($folderPath)) { - if (!mkdir($folderPath, 0775)) { - self::error('Permission denied: unable to generate a folder on the server - '.$folderPath); - } - } - - $filePath= $folderPath.'/'.$type; - return file_put_contents($filePath, $data); - }*/ - - - /** - * Get layout from the saved file - * - * @param string $controller Ex. Accounts, Leads - * @param string $type Layout type, ex. list, detail, edit - * - * @return string JSON string - */ - /*function getLayoutFromFile($controller, $type) - { - $filePath= self::$layoutPath.'/'.$controller.'/'.$type; - - if (file_exists($filePath)) { - return file_get_contents($filePath); - } - - $filePath= self::$layoutPath.'/default/'.$type; - if (file_exists($filePath)) { - return file_get_contents($filePath); - } - - return false; - } */ - - /** - * Save content to file from the PUT request - * - * @param string $data JSON string - * @param string $folderPath - Ex. layouts, metadata - * @param string $folderName - Ex. Accounts, Leads, defs - * @param string $fileName - Ex. list, detail, edit, contact.json - * - * @return bool - */ - function saveToFile($data, $folderPath, $folderName, $fileName) - { - $currentFolderPath= $folderPath.'/'.$folderName; - if (empty($folderName)) { - $currentFolderPath= $folderPath; - } - - if (!file_exists($currentFolderPath)) { - if (!mkdir($currentFolderPath, 0775)) { - self::error('Permission denied: unable to generate a folder on the server - '.$currentFolderPath); - } - } - - $filePath= $currentFolderPath.'/'.$fileName; - return file_put_contents($filePath, $data); - } - - /** - * Get content from the saved file - * - * @param string $folderPath - Ex. layouts, metadata - * @param string $folderName - Ex. Accounts, Leads, defs - * @param string $fileName - Ex. list, detail, edit, contact.json - * - * @return string JSON string - */ - function getFromFile($folderPath, $folderName, $fileName) - { - $filePath= $folderPath.'/'.$folderName.'/'.$fileName; - if (empty($folderName)) { - $filePath= $folderPath.'/'.$fileName; - } - - if (file_exists($filePath)) { - return file_get_contents($filePath); - } - - $filePath= $folderPath.'/default/'.$fileName; - if (file_exists($filePath)) { - return file_get_contents($filePath); - } - - return false; - } - - function output($data, $jsonConvert=false) - { - ob_clean(); - if ($jsonConvert) { - $data= json_encode($data); - } - echo $data; - - $app= Slim::getInstance(); - $app->stop(); - } - - function error($text) - { - self::output('{"error":{"text":'.$text.'}}'); - } - -} - -/* -function appAction($action) -{ - try { - $returns= array('action' => $action); - echo json_encode($returns); - } catch(PDOException $e) { - echo '{"error":{"text":'. $e->getMessage() .'}}'; - } -} -*/ - - -?> \ No newline at end of file diff --git a/application/Espo/Utils/Api/Rest.php b/application/Espo/Utils/Api/Rest.php deleted file mode 100755 index 55297cc2ab..0000000000 --- a/application/Espo/Utils/Api/Rest.php +++ /dev/null @@ -1,144 +0,0 @@ -Main Page of REST API!!! -EOT; - Api\Helper::output($template); - } - - public function getAppUser() - { - $data= '{"user":{"modified_by_name":"Administrator","created_by_name":"","id":"1","user_name":"admin","user_hash":"","system_generated_password":"0","pwd_last_changed":"","authenticate_id":"","sugar_login":"1","first_name":"","last_name":"Administrator","full_name":"Administrator","name":"Administrator","is_admin":"1","external_auth_only":"0","receive_notifications":"1","description":"","date_entered":"2013-06-13 12:18:44","date_modified":"2013-06-13 12:19:48","modified_user_id":"1","created_by":"","title":"Administrator","department":"","phone_home":"","phone_mobile":"","phone_work":"","phone_other":"","phone_fax":"","status":"Active","address_street":"","address_city":"","address_state":"","address_country":"","address_postalcode":"","UserType":"","deleted":"0","portal_only":"0","show_on_employees":"1","employee_status":"Active","messenger_id":"","messenger_type":"","reports_to_id":"","reports_to_name":"","email1":"test@letrium.com","email_link_type":"","is_group":"0","c_accept_status_fields":" ","m_accept_status_fields":" ","accept_status_id":"","accept_status_name":""},"preferences":{}}'; - return Api\Helper::output($data, 'Cannot login'); - } - - /** - * Get whole metadata - * - * @return void - */ - public function getMetadata() - { - global $base; - $devMode= !$base->config->get('useCache'); - - $metadata= new Utils\Metadata(); - $data= $metadata->getMetadata(true, $devMode); - - return Api\Helper::output($data, 'Cannot reach metadata data'); - } - - /** - * Put the metadata - * ex. metadata/menu/Account - * - * @return void - */ - public function putMetadata($type, $scope) - { - $app= Slim::getInstance(); - $data = $app->request()->getBody(); - - $metadata = new Utils\Metadata(); - $result = $metadata->setMetadata($data, $type, $scope); - - if ($result===false) { - return self::output($result, 'Cannot save metadata data'); - } - - $data= $metadata->getMetadata(true, true); - return Api\Helper::output($data, 'Cannot get the metadata data'); - } - - /** - * Get whole settigs - * - * @return void - */ - public function getSettings() - { - global $base; - $config= new Utils\Configurator(); - - $isAdmin= false; - if(isset($base->currentUser) && is_object($base->currentUser)) { - $isAdmin= $base->currentUser->isAdmin(); - } - - $data= $config->getJSON($isAdmin); - - return Api\Helper::output($data, 'Cannot get settings'); - } - - /** - * Add or change settigs - * - * @return void - */ - public function patchSettings() - { - global $base; - $config= new Utils\Configurator(); - - $isAdmin= false; - if(isset($base->currentUser) && is_object($base->currentUser)) { - $isAdmin= $base->currentUser->isAdmin(); - } - - $app= Slim::getInstance(); - $data = $app->request()->getBody(); - - $result= $config->setJSON($data, $isAdmin); - - if ($result===false) { - return self::output($result, 'Cannot save settings'); - } - - $data= $config->getJSON($isAdmin); - return Api\Helper::output($data, 'Cannot get settings'); - } - - - - /** - * Get requested layout - * - * @return void - */ - /*public function getLayout($controller, $name) - { - $ControllerManager = new Utils\Controllers\Manager(); - - $params = array('controller' => $controller, 'action' => $name); - $action= 'getLayout'; - $result = $ControllerManager->call($action, $params, $data); - - return Api\Helper::output($result->data, $result->errMessage, $result->errCode); - - //$layout = new Utils\Layout(); - //$data = $layout->getLayout($controller, $name); - - //return Api\Helper::output($data, 'Cannot get this layout', 404); - } */ - -} - - -?> \ No newline at end of file diff --git a/application/Espo/Utils/BaseUtils.php b/application/Espo/Utils/BaseUtils.php deleted file mode 100755 index 1dfc04e1d5..0000000000 --- a/application/Espo/Utils/BaseUtils.php +++ /dev/null @@ -1,345 +0,0 @@ -separator; - } - - - function getObject($name) - { - if (isset($this->$name) && is_object($this->$name)) { - return $this->$name; - } - - $fullName= 'Espo\\Utils\\'.$name; - if (class_exists($fullName)) { - $this->$name= new $fullName(); - return $this->$name; - } - - return false; - } - - /** - * Get module name if it's a custom module or empty string for core entity - * - * @param string $scopeName - * - * @return string - */ - public function getScopeModuleName($scopeName) - { - $scopeModuleMap= $this->getScopes(); - - $lowerEntityName= strtolower($scopeName); - foreach($scopeModuleMap as $rowEntityName => $rowModuleName) { - if ($lowerEntityName==strtolower($rowEntityName)) { - return $rowModuleName; - } - } - - return ''; - } - - - /** - * Get Scopes - * - * @param string $moduleName - * @param bool $reload - * - * @return array - */ - //NEED TO CHANGE - public function getScopes($moduleName= '', $reload = false) - { - if (!$reload && !empty($this->scopes)) { - return $this->scopes; - } - - $metadata = new Utils\Metadata(); - $metadataList = $metadata->getMetadataOnly(false); - - $scopes = array(); - foreach($metadataList['scopes'] as $name => $details) { - $scopes[$name] = isset($details['module']) ? $details['module'] : ''; - } - - return $this->scopes = $scopes; - } - - - /** - * Get Scope path, ex. "Modules/Crm" for Account - * - * @param string $scopeName - * @param string $delim - delimiter - * - * @return string - */ - public function getScopePath($scopeName, $delim= '/') - { - $moduleName= $this->getScopeModuleName($scopeName); - - $config = new Utils\Configurator(); - $path= $config->get('espoPath'); - if (!empty($moduleName)) { - $path= str_replace('{*}', $moduleName, $config->get('espoModulePath')); - } - - if ($delim!='/') { - $path = str_replace('/', $delim, $path); - } - - return $path; - } - - - /** - * Get Full Scope path, ex. "application/Modules/Crm" for Account - * - * @param string $scopeName - * @param string $delim - delimiter - * - * @return string - */ - public function getScopePathFull($scopeName, $delim= '/') - { - return $this->concatPath('application', $this->getScopePath($scopeName, $delim)); - } - - /** - * Check if scope exists - * - * @param string $scopeName - * - * @return bool - */ - public function isScopeExists($scopeName) - { - $scopeModuleMap= $this->getScopes(); - - $lowerEntityName= strtolower($scopeName); - foreach($scopeModuleMap as $rowEntityName => $rowModuleName) { - if ($lowerEntityName==strtolower($rowEntityName)) { - return true; - } - } - - return false; - } - - - /** - * Convert to format with defined delimeter - * ex. Espo/Utils to Espo\Utils - * - * @param string $name - * @param string $delim - delimiter - * - * @return string - */ - public function toFormat($name, $delim= '/') - { - //preg_match_all('/[\/]/', $name, $match); - //preg_match_all('/(.*)[\/\\\](.*)/', $name, $match); - //return $match; - - return preg_replace('/[\/\\\]/', $delim, $name); - } - - - /** - * Convert name to Camel Case format - * ex. camel-case to camelCase - * - * @param string $name - * - * @return string - */ - public function toCamelCase($name, $capitaliseFirstChar=false) - { - if($capitaliseFirstChar) { - $name[0] = strtoupper($name[0]); - } - $func = create_function('$c', 'return strtoupper($c[1]);'); - return preg_replace_callback('/-([a-z])/', $func, $name); - } - - /** - * Convert name from Camel Case format. - * ex. camelCase to camel-case - * - * @param string $name - * - * @return string - */ - public function fromCamelCase($name) - { - $name[0] = strtolower($name[0]); - $func = create_function('$c', 'return "-" . strtolower($c[1]);'); - return preg_replace_callback('/([A-Z])/', $func, $name); - } - - - /** - * Merge arrays (default PHP function is not suitable) - * - * @param array $array - * @param array $mainArray - chief array (priority is same as for array_merge()) - * @return array - */ - function merge($array, $mainArray) - { - if (is_array($array) && !is_array($mainArray)) { - return $array; - } else if (!is_array($array) && is_array($mainArray)) { - return $mainArray; - } else if (!is_array($array) && !is_array($mainArray)) { - return array(); - } - - foreach($mainArray as $maKey => $maVal) { - $found = false; - foreach($array as $aKey => $aVal) { - if ((string)$maKey == (string)$aKey){ - $found = true; - if (is_array($maVal) && is_array($aVal)){ - $array[$maKey] = $this->merge($aVal, $maVal); - } - else { - - if (is_array($aVal)){ - $array[$maKey] = $this->merge($aVal, array($maVal)); - } - elseif (is_array($maVal)){ - $array[$maKey] = $this->merge(array($aVal), $maVal); - } - else { - //merge logic - if (!is_numeric($maKey)){ - $array[$maKey] = $maVal; - } - elseif (!in_array($maVal, $array)) { - $array[] = $maVal; - } - //END: merge ligic - } - } - - break; - } - } - // add an item if key not found - if (!$found){ - $array[$maKey] = $maVal; - } - - } - - return $array; - } - - - /** - * Get a full path of the file - * - * @param string $folderPath - Folder path, Ex. myfolder - * @param string $filePath - File path, Ex. file.json - * - * @return string - */ - public function concatPath($folderPath, $filePath='') - { - if (empty($filePath)) { - return $folderPath; - } - else { - if (substr($folderPath, -1)==$this->getSeparator()) { - return $folderPath . $filePath; - } - return $folderPath . $this->getSeparator() . $filePath; - } - } - - - /** - * Return content of PHP file - * - * @param string $varName - name of variable which contains the content - * @param array $content - * - * @return string | false - */ - function getPHPFormat($content) - { - if (empty($content)) { - return false; - } - - return ''; - } - - - /** - * Convert array to object format recursively - * - * @param array $array - * @return object - */ - function arrayToObject($array) - { - if (is_array($array)) { - return (object) array_map(array($this, "arrayToObject"), $array); - } else { - return $array; // Return an object - } - } - - - /** - * Convert object to array format recursively - * - * @param object $object - * @return array - */ - function objectToArray($object) - { - if (is_object($object)) { - $object = (array) $object; - } - - return is_array($object) ? array_map(array($this, "objectToArray"), $object) : $object; - } - -} - - -?> \ No newline at end of file diff --git a/application/Espo/Utils/Controllers/Controller.php b/application/Espo/Utils/Controllers/Controller.php deleted file mode 100755 index 75a5ee1eb9..0000000000 --- a/application/Espo/Utils/Controllers/Controller.php +++ /dev/null @@ -1,40 +0,0 @@ - \ No newline at end of file diff --git a/application/Espo/Utils/Metadata.php b/application/Espo/Utils/Metadata.php deleted file mode 100755 index 2caefbedb0..0000000000 --- a/application/Espo/Utils/Metadata.php +++ /dev/null @@ -1,306 +0,0 @@ -getConfig(); - - if (!$this->getObject('Configurator')->get('useCache')) { - $reload = true; - } - - if (!file_exists($config->cacheFile) || $reload) { - $data= $this->getMetadataOnly(false, true); - if ($data === false) { - return false; - } - - //save medatada to cache files - $this->setContentPHP($data, $this->getConfig()->cacheFile); - - $this->getObject('Log')->add('Debug', 'Metadata:getMetadata() - converting to doctrine metadata'); - if ($this->convertToDoctrine($data)) { - $this->getObject('Log')->add('Debug', 'Metadata:getMetadata() - database rebuild'); - - try{ - $this->rebuildDatabase(); - } catch (\Exception $e) { - $this->getObject('Log')->add('EXCEPTION', 'Try to rebuildDatabase'.'. Details: '.$e->getMessage()); - } - } - } - - return $this->getMetadataOnly($isJSON, false); - } - - - - /** - * Get Metadata only without saving it to the a file and database sync - * - * @param $isJSON - * @param bool $reload - * - * @return json | array - */ - - public function getMetadataOnly($isJSON=true, $reload=false) - { - $config= $this->getConfig(); - - if (!$this->getObject('Configurator')->get('useCache')) { - $reload = true; - } - - $data = false; - if (!file_exists($config->cacheFile) || $reload) { - $data= $this->uniteFiles($config, true); - - if ($data === false) { - $this->getObject('Log')->add('FATAL', 'Metadata:getMetadata() - metadata unite file cannot be created'); - } - } - else if (file_exists($config->cacheFile)) { - $data= $this->getContent($config->cacheFile); - } - - if ($isJSON) { - $data= $this->getObject('JSON')->encode($data); - } - - return $data; - } - - - - /** - * Set Metadata data - * Ex. $type= menu, $scope= Account then will be created a file metadataFolder/menu/Account.json - * - * @param JSON string $data - * @param string $type - ex. menu - * @param string $scope - Account - * - * @return bool - */ - function setMetadata($data, $type, $scope) - { - $fullPath= $this->getConfig()->corePath; - $moduleName= $this->getScopeModuleName($scope); - - if (!empty($moduleName)) { - $fullPath= str_replace('{*}', $moduleName, $this->getConfig()->customPath); - } - $fullPath= $this->concatPath($fullPath, $type); - - //merge data with defaults values - $defaults= $this->loadDefaultValues($type, 'metadata'); - - $decoded= $this->getArrayData($data); - $mergedValues= $this->merge($defaults, $decoded); - $data= $this->getObject('JSON')->encode($mergedValues); - //END: merge data with defaults values - - $result= $this->setContent($data, $fullPath, $scope.'.json'); - - //create classes only for "defs" metadata - if ($type==$this->doctrineMetadataName) { - try{ - $this->generateEntities( array($this->getEntityPath($scope)) ); - } catch (\Exception $e) { - $this->getObject('Log')->add('EXCEPTION', 'Try to generate Entities for '.$this->getEntityPath($scope).'. Details: '.$e->getMessage()); - } - } - - return $result; - } - - - /** - * Metadata conversion from Espo format into Doctrine - * - * @param object $metadata - * - * @return bool - */ - protected function convertToDoctrine($metadata) - { - $cacheDir= $this->getConfig()->doctrineCache; - - //remove all existing files - $this->removeFilesInDir($cacheDir); - - //create files named like "Espo.Entities.User.php" - $result= true; - foreach($metadata[$this->doctrineMetadataName] as $entityName => $meta) { - $doctrineMetaWithName= $this->getObject('DoctrineConverter')->convert($entityName, $meta, true); - - if (empty($doctrineMetaWithName)) { - $this->getObject('Log')->add('FATAL', 'Metadata:convertToDoctrine(), Entity:'.$entityName.' - metadata cannot be converted into Doctrine format'); - return false; - } - - //create a doctrine metadata file - $fileName= str_replace('\\', '.', $doctrineMetaWithName['name']).'.php'; - $result&= $this->setContent($this->getPHPFormat($doctrineMetaWithName['meta']), $cacheDir, $fileName); - //END: create a doctrine metadata file - } - - return $result; - } - - /** - * Rebuild a database accordinly to metadata - * - * @return bool - */ - public function rebuildDatabase() - { - global $base; - if (!is_object($base)) { - $base= \Espo\Core\Base::start(); - } - - $tool = new \Doctrine\ORM\Tools\SchemaTool($base->em); - - $cmf = new \Doctrine\ORM\Tools\DisconnectedClassMetadataFactory(); - $cmf->setEntityManager($base->em); // $em is EntityManager instance - $classes = $cmf->getAllMetadata(); - - $tool->updateSchema($classes); - - return true; //always true, because updateSchema just returns the VOID - } - - /** - * Rebuild a database accordinly to metadata - * - * @return bool - */ - public function generateEntities($classNames) - { - if (!is_array($classNames)) { - $classNames= (array) $classNames; - } - - global $base; - if (!is_object($base)) { - $base= \Espo\Core\Base::start(); - } - - $cmf = new \Doctrine\ORM\Tools\DisconnectedClassMetadataFactory(); - $cmf->setEntityManager($base->em); // $em is EntityManager instance - - $metadata= array(); - foreach($classNames as $className) { - $metadata[]= $cmf->getMetadataFor($className); - } - - if (!empty($metadata)) { - $generator = new \Doctrine\ORM\Tools\EntityGenerator(); - $generator->setGenerateAnnotations(false); - $generator->setGenerateStubMethods(true); - $generator->setRegenerateEntityIfExists(false); - $generator->setUpdateEntityIfExists(false); - $generator->generate($metadata, 'application'); - - return true; //always true, because generate just returns the VOID - } - - return false; - } - - /** - * Unite file content to the file - * - * @param string $configParams - ["name", "cachePath", "corePath", "customPath"] - * @param bool $recursively - Note: only for first level of sub directory, other levels of sub directories will be ignored - * - * @return array - */ - function uniteFiles($configParams, $recursively=false) - { - if (empty($configParams) || empty($configParams->name) || empty($configParams->cachePath) || empty($configParams->corePath)) { - return false; - } - - //merge matadata files - $content= $this->uniteFilesSingle($configParams->corePath, $configParams->name, $recursively); - - if (!empty($configParams->customPath)) { - $customDir= strstr($configParams->customPath, '{*}', true); - $dirList= $this->getFileList($customDir, false, '', 'dir'); - - foreach($dirList as $dirName) { - $curPath= str_replace('{*}', $dirName, $configParams->customPath); - $content= $this->merge($content, $this->uniteFilesSingle($curPath, $configParams->name, $recursively, $dirName)); - } - } - //END: merge matadata files - - return $content; - } - - /** - * Get Entity path, ex. Espo.Entities.Account or Modules\Crm\Entities\MyModule - * - * @param string $entityName - * @param bool $delim - delimiter - * - * @return string - */ - public function getEntityPath($entityName, $delim= '\\') - { - $moduleName= $this->getScopeModuleName($entityName); - - $path= 'Espo'; - if (!empty($moduleName)) { - $path= 'Modules'.$delim.$moduleName; - } - - return implode($delim, array($path, 'Entities', $entityName)); - } - - - /** - * Get settings for Metadata - * - * @return object - */ - function getConfig() - { - if (isset($this->metadataConfig) && is_object($this->metadataConfig)) { - return $this->metadataConfig; - } - - $this->metadataConfig = $this->getObject('Configurator')->get('metadataConfig'); - $this->metadataConfig->cacheFile= $this->concatPath($this->metadataConfig->cachePath, $this->metadataConfig->name).'.php'; - - return $this->metadataConfig; - } - -} - - -?> \ No newline at end of file diff --git a/bootstrap.php b/bootstrap.php index cedf0b94b5..d675c6b70a 100755 --- a/bootstrap.php +++ b/bootstrap.php @@ -4,19 +4,11 @@ set_include_path( dirname(__FILE__) ); require_once "vendor/autoload.php"; - -use Espo\Core; -$base= \Espo\Core\Base::start(); - //error_reporting(-1); -set_error_handler(array($base->log, 'catchError'), E_ALL); -set_exception_handler(array($base->log, 'catchException')); /* use Doctrine\ORM\Tools\Setup; - - $isDevMode = true; //JSON Driver for Doctrine use Doctrine\ORM\Mapping\Driver\JsonDriver; diff --git a/tests/api/LayoutTest.php b/tests/Api/LayoutTest.php old mode 100755 new mode 100644 similarity index 71% rename from tests/api/LayoutTest.php rename to tests/Api/LayoutTest.php index 7908c9e8f9..4c74a16644 --- a/tests/api/LayoutTest.php +++ b/tests/Api/LayoutTest.php @@ -1,11 +1,8 @@ fixture = new API\RestTesterClass(); + require_once('tests/Api/RestTesterClass.php'); + $this->fixture = new RestTesterClass(); /****************************************/ $this->fixture->setUrl('/layout'); @@ -35,6 +32,9 @@ class LayoutTest extends \PHPUnit_Framework_TestCase $this->fixture->setUrl('/custom-test/layout/test-put'); $data= '["amount","account","closeDate","leadSource","stage","probability","assignedUser"]'; $this->assertTrue($this->fixture->isSuccess( $data )); + + //check if file exists + $this->assertTrue(file_exists('application/Espo/Layouts/customTest/testPut.json')); } function testPatch() @@ -44,6 +44,9 @@ class LayoutTest extends \PHPUnit_Framework_TestCase $this->fixture->setUrl('/custom-test/layout/test-patch'); $data= '[{"label":"MyLabel"}]'; $this->assertTrue($this->fixture->isSuccess( $data )); + + //check if file exists + $this->assertTrue(file_exists('application/Espo/Layouts/customTest/testPatch.json')); } function testGet() @@ -51,7 +54,7 @@ class LayoutTest extends \PHPUnit_Framework_TestCase $this->fixture->setType('GET'); $this->fixture->setUrl('/custom-test/layout/detail'); - $this->assertTrue($this->fixture->isSuccess( $this->fixture->getResponse() )); + $this->assertTrue($this->fixture->isSuccess( )); $this->fixture->setUrl('/need-to-be-not-real/layout/not-real'); $response= $this->fixture->getResponse(); diff --git a/tests/api/MetadataTest.php b/tests/Api/MetadataTest.php old mode 100755 new mode 100644 similarity index 65% rename from tests/api/MetadataTest.php rename to tests/Api/MetadataTest.php index 12a1c43e8f..721ddcaa5e --- a/tests/api/MetadataTest.php +++ b/tests/Api/MetadataTest.php @@ -1,11 +1,8 @@ fixture = new API\RestTesterClass(); + require_once('tests/Api/RestTesterClass.php'); + $this->fixture = new RestTesterClass(); /****************************************/ $this->fixture->setUrl('/metadata'); @@ -33,7 +30,7 @@ class MetadataTest extends \PHPUnit_Framework_TestCase $this->fixture->setType('GET'); $this->fixture->setUrl('/metadata'); - $this->assertTrue($this->fixture->isSuccess( $this->fixture->getResponse() )); + $this->assertTrue($this->fixture->isSuccess( )); } function testPut() @@ -44,9 +41,16 @@ class MetadataTest extends \PHPUnit_Framework_TestCase $data= '{"module":"Test"}'; $this->assertTrue($this->fixture->isSuccess( $data )); + //check if file exists + $this->assertTrue(file_exists('application/Modules/Crm/Metadata/customTest/account.json')); + + $this->fixture->setUrl('/metadata/custom-test/custom-test'); $data= '{"module":"Test","var1":{"subvar1":"NEWsubval1","subvar55":"subval55"}}'; $this->assertTrue($this->fixture->isSuccess( $data )); + + //check if file exists + $this->assertTrue(file_exists('application/Espo/Metadata/customTest/customTest.json')); } diff --git a/tests/api/RestTesterClass.php b/tests/Api/RestTesterClass.php old mode 100755 new mode 100644 similarity index 77% rename from tests/api/RestTesterClass.php rename to tests/Api/RestTesterClass.php index 1b352d0728..8477d33018 --- a/tests/api/RestTesterClass.php +++ b/tests/Api/RestTesterClass.php @@ -1,14 +1,25 @@ apiUrl = $config['apiUrl']; + $this->username = $config['username']; + $this->password = $config['password']; + } function setType($name) { @@ -17,7 +28,7 @@ class RestTesterClass function setUrl($url) { - $this->url= (substr($url, 0,1)=='/') ? $this->mainUrl.$url : $this->mainUrl.'/'.$url; + $this->url= (substr($url, 0,1)=='/') ? $this->apiUrl.$url : $this->apiUrl.'/'.$url; } function getResponse($jsonData='', $output=false) @@ -25,7 +36,7 @@ class RestTesterClass $ch = curl_init($this->url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($ch, CURLOPT_USERPWD, $this->username.':'.$this->pass); + curl_setopt($ch, CURLOPT_USERPWD, $this->username.':'.$this->password); curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); diff --git a/tests/Api/SettingsTest.php b/tests/Api/SettingsTest.php new file mode 100644 index 0000000000..8cc0a63b29 --- /dev/null +++ b/tests/Api/SettingsTest.php @@ -0,0 +1,49 @@ +fixture = new RestTesterClass(); + $this->fixture->setUrl('/settings'); + } + + protected function tearDown() + { + $this->fixture = NULL; + } + + + function testGet() + { + $this->fixture->setType('GET'); + $this->assertTrue($this->fixture->isSuccess()); + } + + function testPatch() + { + $this->fixture->setType('PATCH'); + + $array= array( + "customTest"=> array("test"=> "success"), + ); + $json= json_encode($array); + $this->assertTrue( $this->fixture->isSuccess($json) ); + + //config get if the customTest item exists + $savedValue = $GLOBALS['app']->getContainer()->get('config')->get('customTest'); + $this->assertObjectHasAttribute('test', $savedValue); + } + + +} + +?> \ No newline at end of file diff --git a/tests/Espo/Core/Utils/UtilTest.php b/tests/Espo/Core/Utils/UtilTest.php new file mode 100755 index 0000000000..c208ad0a0d --- /dev/null +++ b/tests/Espo/Core/Utils/UtilTest.php @@ -0,0 +1,218 @@ +assertEquals(DIRECTORY_SEPARATOR, Util::getSeparator()); + } + + function testToCamelCase() + { + $this->assertEquals('detail', Util::toCamelCase('detail')); + $this->assertEquals('detailView', Util::toCamelCase('detail-view')); + $this->assertEquals('myDetailView', Util::toCamelCase('my-detail-view')); + } + + function testFromCamelCase() + { + $this->assertEquals('detail', Util::fromCamelCase('detail')); + $this->assertEquals('detail-view', Util::fromCamelCase('detailView')); + $this->assertEquals('my-detail-view', Util::fromCamelCase('myDetailView')); + } + + function testMerge() + { + $array1= array( + 'defaultPermissions', + 'logger', + 'devMode' + ); + $array2Main= array( + 45 => '125', + 'sub' => array ( + 'subV' => '125', + ), + ); + $result= array( + 'defaultPermissions', + 'logger', + 'devMode', + 45 => '125', + 'sub' => array ( + 'subV' => '125', + ), + ); + $this->assertEquals($result, Util::merge($array1, $array2Main)); + + + + $array1= array( + 'datetime' => + array ( + 'dateFormat' => 'Y-m-d', + 'timeFormat' => 'H:i:s', + ), + ); + $array2Main= array( + 'datetime' => + array ( + 'dateFormat' => 'MyDateFormat', + ), + ); + $result= array( + 'datetime' => + array ( + 'dateFormat' => 'MyDateFormat', + 'timeFormat' => 'H:i:s', + ), + ); + $this->assertEquals($result, Util::merge($array1, $array2Main)); + + + $array1= array( + 'database' => + array ( + 'driver' => 'pdo_mysql', + 'host' => 'localhost', + 'dbname' => 'espocrm', + 'user' => 'root', + 'password' => '', + ), + ); + $array2Main= array( + 'database' => + array ( + 'password' => 'MyPass', + ), + ); + $result= array( + 'database' => + array ( + 'driver' => 'pdo_mysql', + 'host' => 'localhost', + 'dbname' => 'espocrm', + 'user' => 'root', + 'password' => 'MyPass', + ), + ); + $this->assertEquals($result, Util::merge($array1, $array2Main)); + } + + function testToFormat() + { + $this->assertEquals('/Espo/Core/Utils', Util::toFormat('/Espo/Core/Utils', '/')); + $this->assertEquals('\Espo\Core\Utils', Util::toFormat('/Espo/Core/Utils', '\\')); + + $this->assertEquals('/Espo/Core/Utils', Util::toFormat('\Espo\Core\Utils', '/')); + $this->assertEquals('\Espo\Core\Utils', Util::toFormat('\Espo\Core\Utils', '\\')); + } + + function testConcatPath() + { + $result= 'dir1/dir2/file1.json'; + $this->assertEquals($result, Util::concatPath('dir1/dir2', 'file1.json')); + + $result= 'dir1/dir2/file1.json'; + $this->assertEquals($result, Util::concatPath('dir1/dir2/', 'file1.json')); + + $result= 'dir1/dir2/file1.json'; + $this->assertEquals($result, Util::concatPath('dir1/dir2/file1.json')); + } + + + function testArrayToObject() + { + $testArr= array( + 'useCache' => true, + 'sub' => array ( + 'subV' => '125', + 'subO' => array( + 'subOV' => '125', + ), + ), + ); + + $testResult= (object) array( + 'useCache' => true, + ); + $testResult->sub = (object) array ( + 'subV' => '125', + ); + $testResult->sub->subO = (object) array ( + 'subOV' => '125', + ); + + $this->assertEquals($testResult, Util::arrayToObject($testArr)); + } + + + function testObjectToArray() + { + $testObj= (object) array( + 'useCache' => true, + ); + $testObj->sub = (object) array ( + 'subV' => '125', + ); + $testObj->sub->subO = (object) array ( + 'subOV' => '125', + ); + + $testResult= array( + 'useCache' => true, + 'sub' => array ( + 'subV' => '125', + 'subO' => array( + 'subOV' => '125', + ), + ), + ); + + $this->assertEquals($testResult, Util::objectToArray($testObj)); + } + + + /*function testGetScopeModuleName() + { + $this->assertEquals('Crm', $this->fixture->getScopeModuleName('Account')); + $this->assertEquals('Crm', $this->fixture->getScopeModuleName('account')); + $this->assertNotEquals('crm', $this->fixture->getScopeModuleName('account')); + + $this->assertEquals('', $this->fixture->getScopeModuleName('User')); + $this->assertEquals('', $this->fixture->getScopeModuleName('user')); + $this->assertNotEquals('Crm', $this->fixture->getScopeModuleName('User')); + } + + + function testGetScopePath() + { + $this->assertEquals('Modules/Crm', $this->fixture->getScopePath('Account', '/')); + $this->assertEquals('Modules\Crm', $this->fixture->getScopePath('Account', '\\')); + $this->assertEquals('Modules\Crm', $this->fixture->getScopePath('account', '\\')); + + $this->assertEquals('Espo', $this->fixture->getScopePath('User', '/')); + $this->assertEquals('Espo', $this->fixture->getScopePath('User', '\\')); + $this->assertEquals('Espo', $this->fixture->getScopePath('user', '\\')); + } + + + function testGetScopes() + { + $this->assertArrayHasKey('User', $this->fixture->getScopes() ); + } */ + + + + +} + +?> \ No newline at end of file diff --git a/tests/Espo/Utils/BaseUtilsTest.php b/tests/Espo/Utils/BaseUtilsTest.php deleted file mode 100755 index b57d87cf4f..0000000000 --- a/tests/Espo/Utils/BaseUtilsTest.php +++ /dev/null @@ -1,151 +0,0 @@ -fixture = new Utils\BaseUtils(); - } - - protected function tearDown() - { - $this->fixture = NULL; - } - - function testMerge() - { - $array1= array( - 'defaultPermissions', - 'logger', - 'devMode' - ); - $array2Main= array( - 45 => '125', - 'sub' => array ( - 'subV' => '125', - ), - ); - $result= array( - 'defaultPermissions', - 'logger', - 'devMode', - 45 => '125', - 'sub' => array ( - 'subV' => '125', - ), - ); - $this->assertEquals($result, $this->fixture->merge($array1, $array2Main)); - - - - $array1= array( - 'datetime' => - array ( - 'dateFormat' => 'Y-m-d', - 'timeFormat' => 'H:i:s', - ), - ); - $array2Main= array( - 'datetime' => - array ( - 'dateFormat' => 'MyDateFormat', - ), - ); - $result= array( - 'datetime' => - array ( - 'dateFormat' => 'MyDateFormat', - 'timeFormat' => 'H:i:s', - ), - ); - $this->assertEquals($result, $this->fixture->merge($array1, $array2Main)); - - - $array1= array( - 'database' => - array ( - 'driver' => 'pdo_mysql', - 'host' => 'localhost', - 'dbname' => 'espocrm', - 'user' => 'root', - 'password' => '', - ), - ); - $array2Main= array( - 'database' => - array ( - 'password' => 'MyPass', - ), - ); - $result= array( - 'database' => - array ( - 'driver' => 'pdo_mysql', - 'host' => 'localhost', - 'dbname' => 'espocrm', - 'user' => 'root', - 'password' => 'MyPass', - ), - ); - $this->assertEquals($result, $this->fixture->merge($array1, $array2Main)); - } - - - function testGetScopeModuleName() - { - $this->assertEquals('Crm', $this->fixture->getScopeModuleName('Account')); - $this->assertEquals('Crm', $this->fixture->getScopeModuleName('account')); - $this->assertNotEquals('crm', $this->fixture->getScopeModuleName('account')); - - $this->assertEquals('', $this->fixture->getScopeModuleName('User')); - $this->assertEquals('', $this->fixture->getScopeModuleName('user')); - $this->assertNotEquals('Crm', $this->fixture->getScopeModuleName('User')); - } - - - function testToCamelCase() - { - $this->assertEquals('detail', $this->fixture->toCamelCase('detail')); - $this->assertEquals('detailView', $this->fixture->toCamelCase('detail-view')); - $this->assertEquals('myDetailView', $this->fixture->toCamelCase('my-detail-view')); - } - - function testFromCamelCase() - { - $this->assertEquals('detail', $this->fixture->fromCamelCase('detail')); - $this->assertEquals('detail-view', $this->fixture->fromCamelCase('detailView')); - $this->assertEquals('my-detail-view', $this->fixture->fromCamelCase('myDetailView')); - } - - - function testGetScopePath() - { - $this->assertEquals('Modules/Crm', $this->fixture->getScopePath('Account', '/')); - $this->assertEquals('Modules\Crm', $this->fixture->getScopePath('Account', '\\')); - $this->assertEquals('Modules\Crm', $this->fixture->getScopePath('account', '\\')); - - $this->assertEquals('Espo', $this->fixture->getScopePath('User', '/')); - $this->assertEquals('Espo', $this->fixture->getScopePath('User', '\\')); - $this->assertEquals('Espo', $this->fixture->getScopePath('user', '\\')); - } - - - function testGetScopes() - { - $this->assertArrayHasKey('User', $this->fixture->getScopes() ); - } - - - - -} - -?> \ No newline at end of file diff --git a/tests/Espo/Utils/ConfiguratorTest.php b/tests/Espo/Utils/ConfiguratorTest.php deleted file mode 100755 index cffcf8dc28..0000000000 --- a/tests/Espo/Utils/ConfiguratorTest.php +++ /dev/null @@ -1,65 +0,0 @@ -fixture = new Utils\Configurator(); - } - - protected function tearDown() - { - $this->fixture = NULL; - } - - - function testGet() - { - $this->assertStringEndsWith('.php', $this->fixture->get('configPath')); - $this->assertNotNull($this->fixture->get('cachePath')); - $this->assertNotNull($this->fixture->get('layoutConfig')); - $this->assertNotNull($this->fixture->get('metadataConfig')); - $this->assertNotNull($this->fixture->get('languageConfig')); - - //permission - $this->assertObjectHasAttribute('dir', $this->fixture->get('defaultPermissions')); - $this->assertObjectHasAttribute('file', $this->fixture->get('defaultPermissions')); - $this->assertObjectHasAttribute('user', $this->fixture->get('defaultPermissions')); - $this->assertObjectHasAttribute('group', $this->fixture->get('defaultPermissions')); - - //database - $this->assertObjectHasAttribute('driver', $this->fixture->get('database')); - - //logger - $this->assertObjectHasAttribute('dir', $this->fixture->get('logger')); - $this->assertObjectHasAttribute('file', $this->fixture->get('logger')); - $this->assertObjectHasAttribute('level', $this->fixture->get('logger')); - } - - function testGetJSON() - { - $this->assertObjectNotHasAttribute('metadataConfig', json_decode($this->fixture->getJSON())); - } - - /*function testSet() - { - $setKey= 'testOption'; - $setValue= 'Test'; - - $this->assertTrue($this->fixture->set($setKey, $setValue)); - $this->assertEquals($setValue, $this->fixture->get($setKey)); - }*/ - - - -} - -?> \ No newline at end of file diff --git a/tests/Espo/Utils/FileManagerTest.php b/tests/Espo/Utils/FileManagerTest.php deleted file mode 100755 index bed82d85a7..0000000000 --- a/tests/Espo/Utils/FileManagerTest.php +++ /dev/null @@ -1,178 +0,0 @@ -fixture = new Utils\FileManager(); - } - - protected function tearDown() - { - $this->fixture = NULL; - } - - - function testGetSeparator() - { - $this->assertNotEmpty($this->fixture->getSeparator()); - } - - function testGetFileList() - { - $result= array('Dir1', 'file1.json','file1.php',); //no recursive - $this->assertEquals($result, $this->fixture->getFileList($this->filesPath.'/getFileList', false)); - - $result= array('Dir1'); //no recursive - $this->assertEquals($result, $this->fixture->getFileList($this->filesPath.'/getFileList', false, '', 'dir')); - - $result= array('file1.json','file1.php',); //no recursive - $this->assertEquals($result, $this->fixture->getFileList($this->filesPath.'/getFileList', false, '', 'file')); - - - $result= array( - 'Dir1' => array( - 'file2.json', - ), - 'file1.json', - 'file1.php', - ); - $this->assertEquals($result, $this->fixture->getFileList($this->filesPath.'/getFileList', true)); - } - - function testGetFileListWithFilter() - { - $result= array('file1.json'); //no recursive - $this->assertEquals($result, $this->fixture->getFileList($this->filesPath.'/getFileList', false, '.*\.json$')); - - - $result= array( - 'Dir1' => array( - 'file2.json', - ), - 'file1.json', - ); - $this->assertEquals($result, $this->fixture->getFileList($this->filesPath.'/getFileList', true, '.*\.json$')); - - $result= array( - 'file1.php', - 'Dir1' => array( - ), - ); - $this->assertEquals($result, $this->fixture->getFileList($this->filesPath.'/getFileList', true, '.*\.php$')); - } - - function testGetContent() - { - $testPath= $this->filesPath.'/getContent'; - - $result= '{"testData":"Test"}'; - $this->assertEquals($result, $this->fixture->getContent($testPath, 'test.json')); - - $result= '{"testData":"Test"}'; - $this->assertEquals($result, $this->fixture->getContent($testPath.'/test.json')); - } - - function testSetContent() - { - $testPath= $this->filesPath.'/setContent'; - - $result= 'next value'; - $this->assertTrue($this->fixture->setContent($result, $testPath, 'test.json')); - //$this->assertEquals($result, $this->fixture->getContent($testPath, 'test.json')); - - //$this->assertTrue($this->fixture->setContent('initial value', $testPath.'/test.json')); - } - - function testMergeContent() - { - $testPath= $this->filesPath.'/setContent'; - - $initialVal= $this->fixture->getContent($testPath, 'test2.json'); - - $result= '{"var1":"val1","var2":"val2"}'; - $this->assertTrue($this->fixture->setContent($result, $testPath, 'test2.json')); - - $result= '{"var2":"new val"}'; - $this->assertTrue($this->fixture->mergeContent($result, $testPath, 'test2.json', true)); - - $result= '{"var1":"val1","var2":"new val"}'; - $this->assertEquals($result, $this->fixture->getContent($testPath, 'test2.json')); - } - - function testGetCurrentPermission() - { - $this->assertEquals(4, strlen($this->fixture->getCurrentPermission($this->filesPath.'/setContent/test.json'))); - $this->assertStringMatchesFormat('%d', $this->fixture->getCurrentPermission($this->filesPath.'/setContent/test.json')); - } - - function testCheckCreateFile() - { - $filePath= $this->filesPath.'/setContent/test.json'; - - $this->assertTrue($this->fixture->checkCreateFile($filePath)); - - $perm= $this->fixture->getDefaultPermissions(); - $this->assertTrue( in_array($this->fixture->getCurrentPermission($filePath), array($perm->file, $perm->dir)) ); - } - - - function testGetDefaultPermissions() - { - $this->assertObjectHasAttribute('dir', $this->fixture->getDefaultPermissions()); - $this->assertObjectHasAttribute('file', $this->fixture->getDefaultPermissions()); - $this->assertObjectHasAttribute('user', $this->fixture->getDefaultPermissions()); - $this->assertObjectHasAttribute('group', $this->fixture->getDefaultPermissions()); - } - - function testConcatPath() - { - $result= 'dir1/dir2/file1.json'; - $this->assertEquals($result, $this->fixture->concatPath('dir1/dir2', 'file1.json')); - - $result= 'dir1/dir2/file1.json'; - $this->assertEquals($result, $this->fixture->concatPath('dir1/dir2/', 'file1.json')); - - $result= 'dir1/dir2/file1.json'; - $this->assertEquals($result, $this->fixture->concatPath('dir1/dir2/file1.json')); - } - - function testGetFileName() - { - $result= 'file1'; - $this->assertEquals($result, $this->fixture->getFileName('file1.json')); - - $result= 'file1'; - $this->assertEquals($result, $this->fixture->getFileName('file1.json', 'json')); - - $result= 'file1'; - $this->assertEquals($result, $this->fixture->getFileName('file1.json', '.json')); - } - - function testGetDirName() - { - $result= 'dirname'; - $this->assertEquals('dirname', $this->fixture->getDirName('test/dirname/Test.json')); - - $result= 'dirname'; - $this->assertEquals('dirname', $this->fixture->getDirName('test/dirname/')); - - $result= 'dirname'; - $this->assertEquals('dirname', $this->fixture->getDirName('test/dirname')); - } - - - -} - -?> \ No newline at end of file diff --git a/tests/Espo/Utils/JSONTest.php b/tests/Espo/Utils/JSONTest.php deleted file mode 100755 index b62f815146..0000000000 --- a/tests/Espo/Utils/JSONTest.php +++ /dev/null @@ -1,58 +0,0 @@ -fixture = new Utils\JSON(); - } - - protected function tearDown() - { - $this->fixture = NULL; - } - - - function testEncode() - { - $testVal= array('testOption'=>'Test'); - $this->assertEquals(json_encode($testVal), $this->fixture->encode($testVal)); - } - - function testDecode() - { - $testVal= array('testOption'=>'Test'); - $this->assertEquals($testVal, $this->fixture->decode(json_encode($testVal), true)); - - $test= '{"folder":"data/logs"}'; - $this->assertEquals('data/logs', $this->fixture->decode($test)->folder); - - $test= '{"folder":"data\/logs"}'; - $this->assertEquals('data/logs', $this->fixture->decode($test)->folder); - - $test= '{"folder":"\\\Entity\\\Logs"}'; - $this->assertEquals('\Entity\Logs', $this->fixture->decode($test)->folder); - - //$test= '{"folder":"\Entity\\Logs"}'; - //$this->assertEquals('\Entity\Logs', $this->fixture->decode($test)->folder); - } - - function testIsJSON() - { - $this->assertTrue($this->fixture->isJSON('{"database":{"driver":"pdo_mysql","host":"localhost"},"devMode":true}')); - $this->assertFalse($this->fixture->isJSON('some string')); - } - - - -} - -?> \ No newline at end of file diff --git a/tests/Espo/Utils/LayoutTest.php b/tests/Espo/Utils/LayoutTest.php deleted file mode 100755 index dbb7a1d207..0000000000 --- a/tests/Espo/Utils/LayoutTest.php +++ /dev/null @@ -1,42 +0,0 @@ -fixture = new Utils\Layout(); - } - - protected function tearDown() - { - $this->fixture = NULL; - } - - function testGetConfig() - { - $this->assertObjectHasAttribute('corePath', $this->fixture->getConfig()); - $this->assertObjectHasAttribute('customPath', $this->fixture->getConfig()); - } - - function testGetLayoutPath() - { - $this->assertEquals('application/Espo/Layouts/User', $this->fixture->getLayoutPath('User', '/')); - $this->assertEquals('application.Espo.Layouts.User', $this->fixture->getLayoutPath('User', '.')); - - $this->assertEquals('application/Modules/Crm/Layouts/Account', $this->fixture->getLayoutPath('Account', '/')); - $this->assertEquals('application.Modules.Crm.Layouts.Account', $this->fixture->getLayoutPath('Account', '.')); - } - - - -} - -?> \ No newline at end of file diff --git a/tests/Espo/Utils/LogTest.php b/tests/Espo/Utils/LogTest.php deleted file mode 100755 index f9dc30a2ff..0000000000 --- a/tests/Espo/Utils/LogTest.php +++ /dev/null @@ -1,56 +0,0 @@ -fixture = new Utils\Log(); - } - - protected function tearDown() - { - $this->fixture = NULL; - } - - - function testGetOptions() - { - $this->assertObjectHasAttribute('dir', $this->fixture->getOptions()); - $this->assertObjectHasAttribute('file', $this->fixture->getOptions()); - $this->assertObjectHasAttribute('level', $this->fixture->getOptions()); - } - - function testDatetime() - { - $this->assertTrue(is_object($this->fixture->getObject('Datetime'))); - } - - function testFileManager() - { - $this->assertTrue(is_object($this->fixture->getObject('FileManager'))); - } - - /*function testAdd() - { - $this->assertTrue($this->fixture->add('UnitTest', 'Test log')); - }*/ - - - function testGetLevelValue() - { - $this->assertEquals(8, $this->fixture->getLevelValue('notice')); - $this->assertEquals(2048, $this->fixture->getLevelValue('STRICT')); - $this->assertEquals(32767, $this->fixture->getLevelValue('error')); - } - -} - -?> \ No newline at end of file diff --git a/tests/Espo/Utils/MetadataTest.php b/tests/Espo/Utils/MetadataTest.php deleted file mode 100755 index c4eabd3d92..0000000000 --- a/tests/Espo/Utils/MetadataTest.php +++ /dev/null @@ -1,50 +0,0 @@ -fixture = new Utils\Metadata(); - } - - protected function tearDown() - { - $this->fixture = NULL; - } - - function testGetFileList() - { - $this->assertTrue(Utils\JSON::isJSON($this->fixture->getMetadata(true, true))); - - $this->assertTrue(is_array($this->fixture->getMetadata(false, true))); - } - - function testGetConfig() - { - $this->assertObjectHasAttribute('name', $this->fixture->getConfig()); - $this->assertObjectHasAttribute('cachePath', $this->fixture->getConfig()); - $this->assertObjectHasAttribute('corePath', $this->fixture->getConfig()); - } - - function testGetEntityPath() - { - $this->assertEquals('Espo\Entities\User', $this->fixture->getEntityPath('User', '\\')); - $this->assertEquals('Espo.Entities.User', $this->fixture->getEntityPath('User', '.')); - - $this->assertEquals('Modules\Crm\Entities\Account', $this->fixture->getEntityPath('Account', '\\')); - $this->assertEquals('Modules.Crm.Entities.Account', $this->fixture->getEntityPath('Account', '.')); - } - - - -} - -?> \ No newline at end of file diff --git a/tests/api/SettingsTest.php b/tests/api/SettingsTest.php deleted file mode 100755 index 9e9a2adf5d..0000000000 --- a/tests/api/SettingsTest.php +++ /dev/null @@ -1,65 +0,0 @@ -fixture = new API\RestTesterClass(); - $this->fixture->setUrl('/settings'); - } - - protected function tearDown() - { - $this->fixture = NULL; - } - - - function testGet() - { - $this->fixture->setType('GET'); - $this->assertTrue($this->fixture->isSuccess()); - } - - function testPatch() - { - $this->fixture->setType('PATCH'); - - - $array= array( - "customTest"=> array("test"=> "success"), - ); - $json= json_encode($array); - $this->assertTrue( $this->fixture->isSuccess($json) ); - - /* - $config= new Utils\Configurator(); - $configPath= $config->get('configPath'); - - $FileManager= new Utils\FileManager(); - $initContent= $FileManager->getContent($configPath); - - if (!empty($initContent)) { - - $array= array( - "customTest"=> array("test"=> "success"), - ); - $json= json_encode($array); - $this->assertTrue( $this->fixture->isSuccess($json) ); - - $FileManager->setContent($initContent, $configPath); - } */ - } - - -} - -?> \ No newline at end of file diff --git a/tests/config.php b/tests/config.php new file mode 100644 index 0000000000..1a9b43dca4 --- /dev/null +++ b/tests/config.php @@ -0,0 +1,9 @@ + 'http://172.20.0.1/espocrm-new/api', + 'username' => 'admin', + 'password' => '1', +); + +?> \ No newline at end of file diff --git a/tests/testBootstrap.php b/tests/testBootstrap.php new file mode 100644 index 0000000000..526b9d54fc --- /dev/null +++ b/tests/testBootstrap.php @@ -0,0 +1,15 @@ +run(); + +$GLOBALS['app'] = $app; + + +?> \ No newline at end of file