Dependency Injection

This commit is contained in:
Taras Machyshyn
2013-11-15 17:36:28 +02:00
parent e9728454ef
commit 90028da07e
51 changed files with 2181 additions and 2798 deletions
+2 -183
View File
@@ -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();
?>
+9 -8
View File
@@ -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');
}
+5 -9
View File
@@ -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');
}
+7 -19
View File
@@ -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');
}
+257 -22
View File
@@ -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 = <<<EOT
<h1>Main Page of REST API!!!</h1>
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'
);
}); */
}
}
-103
View File
@@ -1,103 +0,0 @@
<?php
namespace Espo\Core;
use Doctrine\ORM\Tools\Setup,
Espo\Utils\Doctrine\ORM\Mapping\Driver\EspoPHPDriver,
Espo\Utils as Utils;
class Base
{
/**
* @var EntityManager of doctrine
*/
public $em;
/**
* @var Object of Configurator
*/
public $utils;
/**
* @var Object of Log
*/
public $log;
/**
* @var Object of config
*/
public $config;
/**
* @var Object of config
*/
public $currentUser;
/**
* Constructor
*/
protected function __construct()
{
$this->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();
}
}
?>
+1 -3
View File
@@ -13,9 +13,7 @@ abstract class RecordService
private $config;
private $entityManager;
private $entityManager;
private $datetime;
public function setConfig($config)
+120 -11
View File
@@ -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')
);
}
}
@@ -0,0 +1,57 @@
<?php
namespace Espo\Core\Controllers;
class Base
{
private $container;
private $serviceFactory;
public function __construct(\Espo\Core\Container $container, \Espo\Core\ServiceFactory $serviceFactory)
{
$this->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)
{
}
}
?>
@@ -1,19 +1,34 @@
<?php
namespace Espo\Utils\Controllers;
namespace Espo\Core\Controllers;
use Espo\Utils as Utils,
Espo\Utils\Api as Api,
Espo\Utils\Controllers\Controller as Controller;
use \Espo\Core\Utils\Util;
class Manager
{
private $config;
public function __construct()
private $metadata;
public function __construct(\Espo\Core\Utils\Config $config, \Espo\Core\Utils\Metadata $metadata)
{
$this->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');
}
@@ -1,10 +1,21 @@
<?php
namespace Espo\Utils;
use Espo\Utils as Utils;
namespace Espo\Core\Doctrine;
class DoctrineConverter extends BaseUtils
class EspoConverter
{
private $metadata;
public function __construct(\Espo\Core\Utils\Metadata $metadata)
{
$this->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
@@ -1,6 +1,6 @@
<?php
namespace Espo\Utils\Doctrine\ORM\Mapping\Driver;
namespace Espo\Core\Doctrine\ORM\Mapping\Driver;
use Doctrine\Common\Persistence\Mapping\ClassMetadata,
Doctrine\Common\Persistence\Mapping\Driver\FileDriver,
+12 -7
View File
@@ -7,24 +7,29 @@ class ServiceFactory
private $container;
private $metadata;
public function __construct(Container $container)
{
$this->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;
}
+14 -15
View File
@@ -1,20 +1,25 @@
<?php
namespace Espo\Utils\Api;
namespace Espo\Core\Utils\Api;
use \Slim\Slim,
\Espo\Entities as Entities;
use \Slim\Slim;
class Auth extends \Slim\Middleware
{
protected $noAuthRoutes = array();
private $container;
function __construct($noAuthRoutes = array())
public function __construct(\Espo\Core\Container $container)
{
$this->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));
+79
View File
@@ -0,0 +1,79 @@
<?php
namespace Espo\Core\Utils\Api;
class Rest
{
private $slim;
public function __construct(\Slim\Slim $slim)
{
$this->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);
}
}
}
?>
+34 -22
View File
@@ -1,9 +1,8 @@
<?php
namespace Espo\Utils;
use Espo\Utils as Utils;
namespace Espo\Core\Utils;
class Configurator extends BaseUtils
class Config
{
/**
* Path of system config file
@@ -11,7 +10,7 @@ class Configurator extends BaseUtils
* @access private
* @var string
*/
private $systemConfigPath = 'application/Espo/Core/systemConfig.php';
private $systemConfigPath = 'application/Espo/Core/defaults/systemConfig.php';
/**
* Array of admin items
@@ -30,6 +29,20 @@ class Configurator extends BaseUtils
*/
private $lastConfigObj;
private $fileManager;
public function __construct(\Espo\Core\Utils\File\Manager $fileManager) //TODO
{
$this->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;
+15 -21
View File
@@ -1,12 +1,22 @@
<?php
namespace Espo\Utils;
namespace Espo\Core\Utils;
use Espo\Utils as Utils;
class Datetime
{
protected $options;
private $config;
public function __construct(\Espo\Core\Utils\Config $config) //TODO
{
$this->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;
}
}
?>
@@ -0,0 +1,48 @@
<?php
namespace Espo\Core\Utils;
use Doctrine\ORM\Tools\Setup,
Espo\Core\Doctrine\ORM\Mapping\Driver\EspoPHPDriver;
class EntityManager
{
private $config;
function __construct(\Espo\Core\Utils\Config $config)
{
$this->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);
}
}
?>
@@ -1,10 +1,10 @@
<?php
namespace Espo\Utils;
namespace Espo\Core\Utils\File;
use Espo\Utils as Utils;
use Espo\Core\Utils;
class FileManager extends BaseUtils
class Manager
{
/**
* @var object - default permission settings
@@ -17,6 +17,21 @@ class FileManager extends BaseUtils
protected $appCache= 'application';
private $params;
public function __construct(\stdClass $params)
{
$this->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 '<hr />';
$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 '<hr />'; */
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 '<?php
return '.var_export($content, true).';
?>';
}
/**
* 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);
@@ -0,0 +1,222 @@
<?php
namespace Espo\Core\Utils\File;
use Espo\Core\Utils;
class UniteFiles
{
private $fileManager;
private $params;
public function __construct(\Espo\Core\Utils\File\Manager $fileManager, \stdClass $params)
{
$this->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 '<hr />';
$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 '<hr />'; */
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();
}
}
?>
+26 -9
View File
@@ -1,9 +1,8 @@
<?php
namespace Espo\Utils;
use Espo\Utils as Utils;
namespace Espo\Core\Utils;
class JSON extends BaseUtils
class Json
{
/**
* JSON encode a string
@@ -32,8 +31,7 @@ class JSON extends BaseUtils
}
if ($json===null) {
$Log= new Utils\Log();
$Log->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();
}
}
+47 -23
View File
@@ -1,15 +1,39 @@
<?php
namespace Espo\Utils;
namespace Espo\Core\Utils;
use Espo\Utils as Utils,
Espo\Core,
Doctrine\ORM\Tools;
class Layout extends FileManager
class Layout
{
protected $layoutConfig;
private $layoutConfig;
private $config;
private $fileManager;
private $metadata;
public function __construct(\Espo\Core\Utils\Config $config, \Espo\Core\Utils\File\Manager $fileManager, \Espo\Core\Utils\Metadata $metadata)
{
$this->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;
}
+46 -34
View File
@@ -1,19 +1,11 @@
<?php
namespace Espo\Utils;
namespace Espo\Core\Utils;
use Espo\Utils as Utils,
Espo\Utils\Api;
class Log extends BaseUtils
class Log
{
/**
* @var object $options - contains options defined in config.php
*/
protected $options;
/**
* @var string $defaultLevel - default level, uses only if level is not defined by user
*/
public $defaultLevel = 'INFO';
@@ -64,6 +56,44 @@ class Log extends BaseUtils
'FATAL',
);
private $fileManager;
private $rest;
private $resolver;
private $params;
public function __construct(\Espo\Core\Utils\File\Manager $fileManager, \Espo\Core\Utils\Api\Rest $rest, \Espo\Core\Utils\Resolver $resolver, \stdClass $params)
{
$this->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;
}
}
+438
View File
@@ -0,0 +1,438 @@
<?php
namespace Espo\Core\Utils;
use Doctrine\ORM\Tools;
class Metadata
{
protected $metadataConfig;
protected $doctrineMetadataName= 'defs'; //Metadata "defs" uses for creating the metadata of Doctri
protected $scopes= array();
private $entityManager;
private $config;
private $doctrineConverter;
private $uniteFiles;
private $fileManager;
public function __construct(\Doctrine\ORM\EntityManager $entityManager, \Espo\Core\Utils\Config $config, \Espo\Core\Utils\File\Manager $fileManager, \Espo\Core\Utils\File\UniteFiles $uniteFiles)
{
$this->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;
}
}
?>
+21 -8
View File
@@ -1,16 +1,29 @@
<?php
namespace Espo\Utils;
namespace Espo\Core\Utils;
use Espo\Utils as Utils;
class Resolver extends BaseUtils
class Resolver
{
protected $exceptions = array(
'Doctrine\DBAL\DBALException' => '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);
}
+75
View File
@@ -0,0 +1,75 @@
<?php
namespace Espo\Core\Utils;
class User
{
private $entityManager;
private $config;
private $currentUser;
public function __construct(\Doctrine\ORM\EntityManager $entityManager, \Espo\Core\Utils\Config $config)
{
$this->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;
}
}
?>
+192
View File
@@ -0,0 +1,192 @@
<?php
namespace Espo\Core\Utils;
class Util
{
/**
* @var string - default directory separator
*/
protected static $separator= DIRECTORY_SEPARATOR;
/**
* Get a folder separator
*
* @return string
*/
public static function getSeparator()
{
return static::$separator;
}
/**
* Convert to format with defined delimeter
* ex. Espo/Utils to Espo\Utils
*
* @param string $name
* @param string $delim - delimiter
*
* @return string
*/
public static 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 static 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 static 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
*/
public static 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] = 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;
}
}
?>
+7 -36
View File
@@ -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;
}
}
-77
View File
@@ -1,77 +0,0 @@
<?php
namespace Espo\Utils\Api;
use \Slim\Slim,
\Espo\Utils as Utils;
class Helper
{
/**
* Output the result
*
* @param mixed $data - JSON
* @param string $errMessage - error message
* @param int $errCode - error status code
*
* @return void - Only echo the result
*/
function output($data=null, $errMessage='Error', $errCode=500)
{
$app= Slim::getInstance();
//check if result is false
if ($data === false) {
global $base;
$logMess= empty($errMessage) ? 'result is not expected' : $errMessage;
$base->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);
}
}
}
?>
-401
View File
@@ -1,401 +0,0 @@
<?php
namespace Espo\Utils\Api;
use \Slim\Slim,
\Espo\Utils as Utils;
class Rest extends BaseUtils
{
/**
* @var string Layout folder path
*/
static $layoutPath= 'application/layouts';
static $metadataPath= 'application/metadata';
static $cachePath= 'data/cache';
static $exModules= array(
'lead',
);
static $defaultResponce= array(
'status' => 'OK',
'responce' => 'default response',
);
//DIRECTORY_SEPARATOR
function main()
{
$template = <<<EOT
<h1>Main Page of REST API!!!</h1>
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() .'}}';
}
}
*/
?>
-144
View File
@@ -1,144 +0,0 @@
<?php
namespace Espo\Utils\Api;
use \Slim\Slim,
\Espo\Utils as Utils,
\Espo\Utils\Api as Api;
class Rest
{
/**
* Index page of API
*
* @return void
*/
function main()
{
$template = <<<EOT
<h1>Main Page of REST API!!!</h1>
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);
} */
}
?>
-345
View File
@@ -1,345 +0,0 @@
<?php
namespace Espo\Utils;
use Espo\Utils as Utils;
class BaseUtils
{
/**
* @var string - default directory separator
*/
protected $separator= DIRECTORY_SEPARATOR;
/**
* @var array - scope list
*/
public $scopes= array();
/**
* Get a folder separator
*
* @return string
*/
public function getSeparator()
{
return $this->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 '<?php
return '.var_export($content, true).';
?>';
}
/**
* 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;
}
}
?>
@@ -1,40 +0,0 @@
<?php
namespace Espo\Utils\Controllers;
use Espo\Utils as Utils,
\Espo\Utils\Api as Api;
class Controller
{
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)
{
}
}
?>
-306
View File
@@ -1,306 +0,0 @@
<?php
namespace Espo\Utils;
use Espo\Utils as Utils,
Espo\Core,
Doctrine\ORM\Tools;
class Metadata extends FileManager
{
protected $metadataConfig;
protected $doctrineMetadataName= 'defs'; //Metadata "defs" uses for creating the metadata of Doctri
/**
* Get Metadata context
*
* @param $isJSON
* @param bool $reload
*
* @return json | array
*/
//HERE --- ADD CREATING DOCTRINE METADATA
public function getMetadata($isJSON=true, $reload=false)
{
$config= $this->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;
}
}
?>
-8
View File
@@ -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;
+11 -8
View File
@@ -1,11 +1,8 @@
<?php
namespace Espo\Tests\Api;
namespace tests\Api;
require_once('bootstrap.php');
use Espo\Utils as Utils,
Espo\Tests\Api as API;
require_once('tests/testBootstrap.php');
class LayoutTest extends \PHPUnit_Framework_TestCase
@@ -14,8 +11,8 @@ class LayoutTest extends \PHPUnit_Framework_TestCase
protected function setUp()
{
require_once('tests/api/RestTesterClass.php');
$this->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();
+12 -8
View File
@@ -1,11 +1,8 @@
<?php
namespace Espo\Tests\Api;
namespace tests\Api;
require_once('bootstrap.php');
use Espo\Utils as Utils,
Espo\Tests\Api as API;
require_once('tests/testBootstrap.php');
class MetadataTest extends \PHPUnit_Framework_TestCase
@@ -14,8 +11,8 @@ class MetadataTest extends \PHPUnit_Framework_TestCase
protected function setUp()
{
require_once('tests/api/RestTesterClass.php');
$this->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'));
}
+19 -8
View File
@@ -1,14 +1,25 @@
<?php
namespace Espo\Tests\Api;
namespace tests\Api;
class RestTesterClass
{
public $mainUrl= 'http://172.20.0.1/espocrm-test/api';
public $username= 'admin';
public $pass= '1';
public $type= 'PATCH';
public $url= '/';
private $apiUrl;
private $username;
private $password;
protected $type= 'PATCH';
protected $url= '/';
function __construct()
{
$config = include('tests/config.php');
$this->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);
+49
View File
@@ -0,0 +1,49 @@
<?php
namespace tests\Api;
require_once('tests/testBootstrap.php');
class SettingsTest extends \PHPUnit_Framework_TestCase
{
protected $fixture;
protected function setUp()
{
require_once('tests/Api/RestTesterClass.php');
$this->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);
}
}
?>
+218
View File
@@ -0,0 +1,218 @@
<?php
namespace tests\Espo\Core\Utils;
require_once('tests/testBootstrap.php');
use Espo\Core\Utils\Util;
class UtilTest extends \PHPUnit_Framework_TestCase
{
function testGetSeparator()
{
$this->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() );
} */
}
?>
-151
View File
@@ -1,151 +0,0 @@
<?php
namespace Espo\Tests\Utils;
require_once('bootstrap.php');
use Espo\Utils as Utils;
class BaseUtilsTest extends \PHPUnit_Framework_TestCase
{
protected $fixture;
protected function setUp()
{
$this->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() );
}
}
?>
-65
View File
@@ -1,65 +0,0 @@
<?php
namespace Espo\Tests\Utils;
require_once('bootstrap.php');
use Espo\Utils as Utils;
class ConfiguratorTest extends \PHPUnit_Framework_TestCase
{
protected $fixture;
protected function setUp()
{
$this->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));
}*/
}
?>
-178
View File
@@ -1,178 +0,0 @@
<?php
namespace Espo\Tests\Utils;
require_once('bootstrap.php');
use Espo\Utils as Utils;
class FileManagerTest extends \PHPUnit_Framework_TestCase
{
protected $fixture;
protected $filesPath= 'tests/testData/FileManager';
protected function setUp()
{
$this->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'));
}
}
?>
-58
View File
@@ -1,58 +0,0 @@
<?php
namespace Espo\Tests\Utils;
require_once('bootstrap.php');
use Espo\Utils as Utils;
class JSONTest extends \PHPUnit_Framework_TestCase
{
protected $fixture;
protected function setUp()
{
$this->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'));
}
}
?>
-42
View File
@@ -1,42 +0,0 @@
<?php
namespace Espo\Tests\Utils;
require_once('bootstrap.php');
use Espo\Utils as Utils;
class LayoutTest extends \PHPUnit_Framework_TestCase
{
protected $fixture;
protected function setUp()
{
$this->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', '.'));
}
}
?>
-56
View File
@@ -1,56 +0,0 @@
<?php
namespace Espo\Tests\Utils;
require_once('bootstrap.php');
use Espo\Utils as Utils;
class LogTest extends \PHPUnit_Framework_TestCase
{
protected $fixture;
protected function setUp()
{
$this->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'));
}
}
?>
-50
View File
@@ -1,50 +0,0 @@
<?php
namespace Espo\Tests\Utils;
require_once('bootstrap.php');
use Espo\Utils as Utils;
class MetadataTest extends \PHPUnit_Framework_TestCase
{
protected $fixture;
protected function setUp()
{
$this->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', '.'));
}
}
?>
-65
View File
@@ -1,65 +0,0 @@
<?php
namespace Espo\Tests\Api;
require_once('bootstrap.php');
use Espo\Utils as Utils,
Espo\Tests\Api as API;
class SettingsTest extends \PHPUnit_Framework_TestCase
{
protected $fixture;
protected function setUp()
{
require_once('tests/api/RestTesterClass.php');
$this->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);
} */
}
}
?>
+9
View File
@@ -0,0 +1,9 @@
<?php
return array(
'apiUrl' => 'http://172.20.0.1/espocrm-new/api',
'username' => 'admin',
'password' => '1',
);
?>
+15
View File
@@ -0,0 +1,15 @@
<?php
error_reporting(E_ALL ^ E_NOTICE);
require_once('bootstrap.php');
$app = new \Espo\Core\Application();
//$app->run();
$GLOBALS['app'] = $app;
?>