controller for routes
This commit is contained in:
+123
-80
@@ -3,10 +3,13 @@
|
||||
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 \Slim\Slim();
|
||||
|
||||
@@ -15,10 +18,68 @@ $app = new \Slim\Slim(array(
|
||||
));
|
||||
$app->add(new Api\Auth());
|
||||
|
||||
//convert all url params to camel case format
|
||||
$app->hook('slim.before.dispatch', function () use ($app) {
|
||||
$routeParams= $app->router()->getCurrentRoute()->getParams();
|
||||
|
||||
if (!empty($routeParams)) {
|
||||
$baseUtils= new Utils\BaseUtils();
|
||||
foreach($routeParams as &$param) {
|
||||
$param= $baseUtils->toCamelCase($param);
|
||||
}
|
||||
|
||||
$app->router()->getCurrentRoute()->setParams($routeParams);
|
||||
}
|
||||
});
|
||||
//END: convert all url params to camel case format
|
||||
|
||||
|
||||
$app->hook('slim.before.dispatch', function () use ($app) {
|
||||
|
||||
$currentRoute = $app->router()->getCurrentRoute();
|
||||
$conditions = $currentRoute->getConditions();
|
||||
|
||||
if (isset($conditions['useController']) && !$conditions['useController']) {
|
||||
return;
|
||||
}
|
||||
|
||||
$espoController = call_user_func( $app->router()->getCurrentRoute()->getCallable() );
|
||||
$espoKeys = array_keys($espoController);
|
||||
|
||||
if (!in_array('controller', $espoKeys) || !in_array('action', $espoKeys) || !in_array('scope', $espoKeys)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$ControllerManager = new Utils\Controllers\Manager();
|
||||
|
||||
$params = $currentRoute->getParams();
|
||||
$data = $app->request()->getBody();
|
||||
|
||||
//prepare controller Params
|
||||
$controllerParams = array();
|
||||
$controllerParams['HttpMethod'] = strtolower($app->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
|
||||
$app->hook('slim.after.router', function () use (&$app) {
|
||||
$app->contentType('application/json');
|
||||
//$app->contentType('text/javascript');
|
||||
});
|
||||
//END: return json response
|
||||
|
||||
|
||||
//Setup routes
|
||||
@@ -31,100 +92,82 @@ $app->get('/settings/', '\Espo\Utils\Api\Rest::getSettings')->conditions( array(
|
||||
$app->map('/settings/', '\Espo\Utils\Api\Rest::patchSettings')->via('PATCH');
|
||||
//$app->get('/settings/', '\Espo\Utils\Api\Rest::getSettings')->conditions( array('auth' => false) );
|
||||
|
||||
$app->get('/:controller/layout/:name/', '\Espo\Utils\Api\Rest::getLayout');
|
||||
$app->map('/:controller/layout/:name/', '\Espo\Utils\Api\Rest::patchLayout')->via('PATCH');
|
||||
$app->put('/:controller/layout/:name/', '\Espo\Utils\Api\Rest::putLayout');
|
||||
//$app->get('/:controller/layout/:name/', '\Espo\Utils\Api\Rest::getLayout');
|
||||
//$app->put('/:controller/layout/:name/', '\Espo\Utils\Api\Rest::putLayout');
|
||||
//$app->map('/:controller/layout/:name/', '\Espo\Utils\Api\Rest::patchLayout')->via('PATCH');
|
||||
|
||||
$app->get('/app/user/', '\Espo\Utils\Api\Rest::getAppUser');
|
||||
|
||||
|
||||
/*$app->put('/settings/', 'Rest::putSettings');
|
||||
/*$app->get('/:controller/:id', function() {
|
||||
return array(
|
||||
'controller' => ':controller',
|
||||
'action' => 'read',
|
||||
'id' => ':id'
|
||||
);
|
||||
})->conditions( array('useController' => true) );
|
||||
|
||||
//$app->map('/hello/', 'Rest::putSettings')->via('PATCH');
|
||||
$app->post('/:controller', function() {
|
||||
return array(
|
||||
'controller' => ':controller',
|
||||
'action' => 'create',
|
||||
);
|
||||
})->conditions( array('useController' => true) );
|
||||
|
||||
$app->get('/app/user/', 'Rest::getUserPreferences');
|
||||
$app->map('/app/:action', 'Rest::appAction')->via('GET', 'POST');
|
||||
$app->put('/:controller/:id', function() {
|
||||
return array(
|
||||
'controller' => ':controller',
|
||||
'action' => 'update',
|
||||
'id' => ':id'
|
||||
);
|
||||
})->conditions( array('useController' => true) );
|
||||
|
||||
$app->get('/metadata/:type/:scope/', 'Rest::getMetadata');
|
||||
$app->put('/metadata/:type/:scope/', 'Rest::putMetadata');
|
||||
$app->get('/metadata/:type/', 'Rest::getMetadataByType');
|
||||
|
||||
$app->get('/:controller/', 'Rest::getControllerList');
|
||||
$app->get('/:controller/:id/', 'Rest::getController');
|
||||
|
||||
$app->get('/:controller/layout/:type/', 'Rest::getLayout');
|
||||
|
||||
*/
|
||||
$app->patch('/:controller/:id', function() {
|
||||
return array(
|
||||
'controller' => ':controller',
|
||||
'action' => 'patch',
|
||||
'id' => ':id'
|
||||
);
|
||||
})->conditions( array('useController' => true) );
|
||||
|
||||
|
||||
//$app->put('/:controller/layout/:type/', 'Rest::putLayout');
|
||||
//$app->map('/:controller/layout/:type/', 'Rest::patchLayout')->via('PATCH');
|
||||
$app->get('/:controller/:id/:link/:foreignId', function() {
|
||||
return array(
|
||||
'controller' => ':controller',
|
||||
'action' => 'readRelated',
|
||||
'id' => ':id',
|
||||
'link' => ':link',
|
||||
'foreignId' => ':foreignId'
|
||||
);
|
||||
})->conditions( array('useController' => true) ); */
|
||||
|
||||
//$app->put('/:controller/layout/:type/', 'Rest::putLayout');
|
||||
//Layout
|
||||
$app->get('/:controller/layout/:name/', function() {
|
||||
return array(
|
||||
'controller' => 'Layout',
|
||||
'scope' => ':controller',
|
||||
'action' => ':name',
|
||||
);
|
||||
})->conditions( array('useController' => true) );
|
||||
|
||||
$app->put('/:controller/layout/:name/', function() {
|
||||
return array(
|
||||
'controller' => 'Layout',
|
||||
'scope' => ':controller',
|
||||
'action' => ':name',
|
||||
);
|
||||
})->conditions( array('useController' => true) );
|
||||
|
||||
/*$app->put( '/:controller/layout/:type/', function ($controller, $type) use ( $app ) {
|
||||
$app->map('/:controller/layout/:name/', function() {
|
||||
return array(
|
||||
'controller' => 'Layout',
|
||||
'scope' => ':controller',
|
||||
'action' => ':name',
|
||||
);
|
||||
})->via('PATCH')->conditions( array('useController' => true) );
|
||||
//END: Layout
|
||||
|
||||
|
||||
|
||||
$mysqli = new mysqli('localhost', 'root', '', 'projects_jet');
|
||||
|
||||
$query= "SELECT * FROM layouts
|
||||
WHERE controller='".$controller."' AND layout_type='".$type."' LIMIT 1";
|
||||
$result = $mysqli->query($query);
|
||||
$selectRow = $result->fetch_assoc();
|
||||
|
||||
$data = $app->request()->getBody();
|
||||
//$data = $app->request()->params('payload');
|
||||
//$dataFull = array_keys($dataPut);
|
||||
//$data= $dataFull[0];
|
||||
|
||||
|
||||
if (empty($selectRow)) {
|
||||
//insert
|
||||
$query= "INSERT INTO layouts (
|
||||
controller,
|
||||
layout_type,
|
||||
data
|
||||
)
|
||||
VALUES (
|
||||
'".$controller."',
|
||||
'".$type."',
|
||||
'".$data."'
|
||||
);";
|
||||
}
|
||||
else {
|
||||
$query= "UPDATE layouts SET data='".$data."'
|
||||
WHERE id='".$selectRow['id']."' ";
|
||||
//update
|
||||
}
|
||||
|
||||
$result = $mysqli->query($query);
|
||||
|
||||
echo $data;
|
||||
}); */
|
||||
|
||||
/*$app->map('/app/:action', 'appAction')->via('GET', 'POST');
|
||||
$app->get('/:controller/', 'getControllerList');
|
||||
$app->get('/:controller/:id/', 'getController');*/
|
||||
|
||||
/*
|
||||
// POST route
|
||||
$app->post('/post', function () {
|
||||
echo 'This is a POST route';
|
||||
});
|
||||
|
||||
// PUT route
|
||||
$app->put('/put', function () {
|
||||
echo 'This is a PUT route';
|
||||
});
|
||||
|
||||
// DELETE route
|
||||
$app->delete('/delete', function () {
|
||||
echo 'This is a DELETE route';
|
||||
});
|
||||
*/
|
||||
|
||||
$app->run();
|
||||
|
||||
?>
|
||||
@@ -2,11 +2,18 @@
|
||||
|
||||
return array (
|
||||
'configPath' => 'application/config.php',
|
||||
'customPath' => 'application/Custom',
|
||||
|
||||
'customDir' => 'application/Custom',
|
||||
'cachePath' => 'data/cache',
|
||||
'defaultsPath' => 'application/Espo/Core/defaults',
|
||||
'unsetFileName' => 'unset.json',
|
||||
|
||||
'espoPath' => 'Espo',
|
||||
'espoModulePath' => 'Modules/{*}',
|
||||
'espoCustomPath' => 'Custom',
|
||||
|
||||
'controllerPath' => 'Controllers', //path for controllers in module
|
||||
|
||||
'metadataConfig' =>
|
||||
array (
|
||||
'name' => 'metadata',
|
||||
@@ -40,6 +47,14 @@ return array (
|
||||
),
|
||||
'dateFormat' => 'MM/DD/YYYY',
|
||||
'timeFormat' => 'HH:mm',
|
||||
|
||||
'crud' => array(
|
||||
'get' => 'read',
|
||||
'post' => 'create',
|
||||
'put' => 'update',
|
||||
'patch' => 'patch',
|
||||
'delete' => 'delete',
|
||||
),
|
||||
'systemItems' =>
|
||||
array (
|
||||
'systemItems',
|
||||
@@ -55,6 +70,7 @@ return array (
|
||||
'unsetFileName',
|
||||
'configPathFull',
|
||||
'configCustomPathFull',
|
||||
'crud',
|
||||
),
|
||||
'adminItems' =>
|
||||
array (
|
||||
|
||||
@@ -13,22 +13,21 @@ class Helper
|
||||
* Output the result
|
||||
*
|
||||
* @param mixed $data - JSON
|
||||
* @param string $error - error message
|
||||
* @param int $errorCode - error status code
|
||||
* @param string $errMessage - error message
|
||||
* @param int $errCode - error status code
|
||||
*
|
||||
* @return void - Only echo the result
|
||||
*/
|
||||
function output($data=null, $error='Error', $errorCode=500)
|
||||
function output($data=null, $errMessage='Error', $errCode=500)
|
||||
{
|
||||
$app= Slim::getInstance();
|
||||
|
||||
//check if result is false
|
||||
if ($data === false) {
|
||||
global $base;
|
||||
$logMess= empty($error) ? 'result is not expected' : $error;
|
||||
$base->log->add('ERROR', 'API:'.$app->router()->getCurrentRoute()->getPattern().', Method: '.$app->router()->getCurrentRoute()->getCallable().', InputData: '.$app->request()->getBody().' - '.$logMess);
|
||||
|
||||
Utils\Api\Helper::displayError($error, $errorCode);
|
||||
$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
|
||||
|
||||
|
||||
@@ -56,8 +56,7 @@ EOT;
|
||||
$app= Slim::getInstance();
|
||||
$data = $app->request()->getBody();
|
||||
|
||||
$metadata = new Utils\Metadata();
|
||||
$type = $metadata->toCamelCase($type); //convert to camel case view
|
||||
$metadata = new Utils\Metadata();
|
||||
$result = $metadata->setMetadata($data, $type, $scope);
|
||||
|
||||
if ($result===false) {
|
||||
@@ -123,17 +122,29 @@ EOT;
|
||||
*
|
||||
* @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);
|
||||
} */
|
||||
|
||||
|
||||
public function getLayout($controller, $name)
|
||||
{
|
||||
$layout = new Utils\Layout();
|
||||
|
||||
$controller = $layout->toCamelCase($controller);
|
||||
$name = $layout->toCamelCase($name);
|
||||
$data = $layout->getLayout($controller, $name);
|
||||
|
||||
return Api\Helper::output($data, 'Cannot get this layout', 404);
|
||||
return Api\Helper::output('Rest-get', 'Cannot get layout');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add or change layout
|
||||
*
|
||||
@@ -141,19 +152,7 @@ EOT;
|
||||
*/
|
||||
public function patchLayout($controller, $name)
|
||||
{
|
||||
$app= Slim::getInstance();
|
||||
$data = $app->request()->getBody();
|
||||
|
||||
$layout= new Utils\Layout();
|
||||
$controller = $layout->toCamelCase($controller);
|
||||
$name = $layout->toCamelCase($name);
|
||||
$result= $layout->mergeLayout($data, $controller, $name);
|
||||
|
||||
if ($result === false) {
|
||||
Api\Helper::displayError('Saving error', 500);
|
||||
}
|
||||
|
||||
return Api\Helper::output($data, 'Cannot get layout');
|
||||
return Api\Helper::output('Rest-patch', 'Cannot get layout');
|
||||
}
|
||||
|
||||
|
||||
@@ -164,19 +163,7 @@ EOT;
|
||||
*/
|
||||
public function putLayout($controller, $name)
|
||||
{
|
||||
$app= Slim::getInstance();
|
||||
$data = $app->request()->getBody();
|
||||
|
||||
$layout= new Utils\Layout();
|
||||
$controller = $layout->toCamelCase($controller);
|
||||
$name = $layout->toCamelCase($name);
|
||||
$result= $layout->setLayout($data, $controller, $name);
|
||||
|
||||
if ($result === false) {
|
||||
Api\Helper::displayError('Saving error', 500);
|
||||
}
|
||||
|
||||
return Api\Helper::output($data, 'Cannot get layout');
|
||||
return Api\Helper::output('Rest-put', 'Cannot get layout');
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -6,6 +6,27 @@ use Espo\Utils as Utils;
|
||||
|
||||
class BaseUtils
|
||||
{
|
||||
/**
|
||||
* @var string - default directory separator
|
||||
*/
|
||||
protected $separator= DIRECTORY_SEPARATOR;
|
||||
|
||||
/**
|
||||
* @var array - scope list
|
||||
*/
|
||||
protected $scopes= array();
|
||||
|
||||
|
||||
/**
|
||||
* Get a folder separator
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSeparator()
|
||||
{
|
||||
return $this->separator;
|
||||
}
|
||||
|
||||
|
||||
function getObject($name)
|
||||
{
|
||||
@@ -25,15 +46,15 @@ class BaseUtils
|
||||
/**
|
||||
* Get module name if it's a custom module or empty string for core entity
|
||||
*
|
||||
* @param string $entityName
|
||||
* @param string $scopeName
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getScopeModuleName($entityName)
|
||||
public function getScopeModuleName($scopeName)
|
||||
{
|
||||
$scopeModuleMap= (array) $this->getObject('Configurator')->get('scopeModuleMap');
|
||||
$scopeModuleMap= $this->getScopes();
|
||||
|
||||
$lowerEntityName= strtolower($entityName);
|
||||
$lowerEntityName= strtolower($scopeName);
|
||||
foreach($scopeModuleMap as $rowEntityName => $rowModuleName) {
|
||||
if ($lowerEntityName==strtolower($rowEntityName)) {
|
||||
return $rowModuleName;
|
||||
@@ -43,6 +64,132 @@ class BaseUtils
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
$this->scopes = array(
|
||||
'customTest' => '',
|
||||
'Attachment' => '',
|
||||
'Comment' => '',
|
||||
'Attachment' => '',
|
||||
'EmailTemplate' => '',
|
||||
'Role' => '',
|
||||
'Team' => '',
|
||||
'User' => '',
|
||||
'Product' => 'Crm',
|
||||
'Account' => 'Crm',
|
||||
'Contact' => 'Crm',
|
||||
'Lead' => 'Crm',
|
||||
'Opportunity' => 'Crm',
|
||||
'Calendar' => 'Crm',
|
||||
'Meeting' => 'Crm',
|
||||
'Call' => 'Crm',
|
||||
'Task' => 'Crm',
|
||||
'Case' => 'Crm',
|
||||
'Prospect' => 'Crm',
|
||||
'Email' => 'Crm',
|
||||
'emailTemplate' => 'Crm',
|
||||
'inboundEmail' => 'Crm',
|
||||
);
|
||||
|
||||
return $this->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
|
||||
@@ -134,6 +281,29 @@ class BaseUtils
|
||||
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
|
||||
*
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
<?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)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Espo\Utils\Controllers;
|
||||
|
||||
use Espo\Utils as Utils;
|
||||
|
||||
class Layout extends Controller
|
||||
{
|
||||
|
||||
public function read($params, $data)
|
||||
{
|
||||
$layout = new Utils\Layout();
|
||||
$data = $layout->getLayout($params['controller'], $params['name']);
|
||||
|
||||
return array($data, 'Cannot get this layout', 404);
|
||||
}
|
||||
|
||||
|
||||
public function update($params, $data)
|
||||
{
|
||||
$layout= new Utils\Layout();
|
||||
$result= $layout->setLayout($data, $params['controller'], $params['name']);
|
||||
|
||||
if ($result === false) {
|
||||
return array(false, 'Layout Saving error', 500);
|
||||
}
|
||||
|
||||
return array($data, 'Cannot get this layout');
|
||||
}
|
||||
|
||||
|
||||
public function patch($params, $data)
|
||||
{
|
||||
$layout= new Utils\Layout();
|
||||
$result= $layout->mergeLayout($data, $params['controller'], $params['name']);
|
||||
|
||||
if ($result === false) {
|
||||
return array(false, 'Layout Saving error', 500);
|
||||
}
|
||||
|
||||
return array($data, 'Cannot get this layout');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,269 @@
|
||||
<?php
|
||||
|
||||
namespace Espo\Utils\Controllers;
|
||||
|
||||
use Espo\Utils as Utils,
|
||||
Espo\Utils\Api as Api,
|
||||
Espo\Utils\Controllers\Controller as Controller;
|
||||
|
||||
class Manager
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage of all controllers
|
||||
*
|
||||
* @param array $controllerParams - array('controller' => 'Layout', 'action' => ':name', 'scope' => ':controller');
|
||||
* @param array $params - route params, ex. /:controller/layout/:name/ - array(controller=>Value, name=>Value)
|
||||
* @param array $data - request data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function call($controllerParams, $params, $data = '')
|
||||
{
|
||||
$baseUtils = new Utils\BaseUtils();
|
||||
|
||||
$espoPath = $baseUtils->getObject('Configurator')->get('espoPath');
|
||||
$controllerPath= $baseUtils->concatPath($espoPath, 'Utils/Controllers');
|
||||
|
||||
$crud = $baseUtils->getObject('Configurator')->get('crud');
|
||||
$baseAction = $crud->$controllerParams['HttpMethod'];
|
||||
if (empty($baseAction)) {
|
||||
return $this->response(false, 'Cannot find action for HTTP Method ['.$controllerParams['HttpMethod'].']', 404);
|
||||
}
|
||||
|
||||
$controller = (object) array(
|
||||
'name' => strtolower($controllerParams['controller']),
|
||||
'baseAction' => $baseAction,
|
||||
'scope' => $controllerParams['scope'],
|
||||
'action' => $controllerParams['action'],
|
||||
);
|
||||
|
||||
|
||||
if (!$baseUtils->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($controllerPath, 'Controller');
|
||||
$classInfo->path = $this->getClassPath($classInfo->name);
|
||||
$classInfo->method = $this->getDefinedMethod($classInfo->name, $controller->baseAction, $controller->action);
|
||||
|
||||
|
||||
//Espo\Utils\Controlles\Layout and Custom\Espo\Utils\Controlles\Layout
|
||||
$controllerClass = $this->getClassName($controllerPath, $controller->name);
|
||||
$classInfo = $this->setClassInfo($controllerClass, $classInfo, $controller);
|
||||
//END: Espo\Utils\Controlles\Layout and Custom\Espo\Utils\Controlles\Layout
|
||||
|
||||
|
||||
//path in Modules dir
|
||||
$controllerDir = $baseUtils->concatPath( $baseUtils->getScopePath($controller->scope), $baseUtils->getObject('Configurator')->get('controllerPath') );
|
||||
|
||||
//ex. Modules\Crm\Controllers\Layout and Cusom\Modules\Crm\Controllers\Layout
|
||||
$controllerClass = $this->getClassName($controllerDir, $controller->name);
|
||||
$classInfo = $this->setClassInfo($controllerClass, $classInfo, $controller);
|
||||
//END: ex. Modules\Crm\controllers\Layout and Cusom\Modules\Crm\controllers\Layout
|
||||
|
||||
|
||||
//ex. Modules\Crm\Controllers\AccountLayout and Custom\Modules\Crm\Controllers\AccountLayout
|
||||
$controllerClass = $this->getClassName($controllerDir, $controller->scope.'-'.$controller->name);
|
||||
$classInfo = $this->setClassInfo($controllerClass, $classInfo, $controller);
|
||||
//END: ex. Modules\Crm\Controllers\AccountLayout and Custom\Modules\Crm\Controllers\AccountLayout
|
||||
|
||||
|
||||
//CHECK ACTION
|
||||
if (empty($classInfo->method)) {
|
||||
return $this->response(false, 'Actions ['.$controller->baseAction.'] and ['.$controller->action.'] do not exist.', 404);
|
||||
}
|
||||
//END: CHECK ACTION
|
||||
|
||||
|
||||
//call class method
|
||||
$className = $classInfo->name;
|
||||
$classMethod = $classInfo->method;
|
||||
|
||||
require_once($classInfo->path);
|
||||
$class = new $className();
|
||||
|
||||
//call before method if exists: beforeRead, beforeDetailSmall, beforeReadDetailSmall
|
||||
$beforeMethod = $this->getDefinedMethod($className, $controller->baseAction, $controller->action, 'before');
|
||||
if ( !empty($beforeMethod) ) {
|
||||
$class->$beforeMethod($params, $data);
|
||||
} //END: call before method if exists
|
||||
|
||||
$result = $class->$classMethod($params, $data);
|
||||
|
||||
//call after method if exists: afterRead, afterDetailSmall, afterReadDetailSmall
|
||||
$afterMethod = $this->getDefinedMethod($className, $controller->baseAction, $controller->action, 'after');
|
||||
if ( !empty($afterMethod) ) {
|
||||
try {
|
||||
$class->$afterMethod($params, $data, $result);
|
||||
} catch (\Exception $e) {
|
||||
$class->$afterMethod($params, $data);
|
||||
}
|
||||
} //END: call after method if exists
|
||||
|
||||
|
||||
if (is_array($result)) {
|
||||
|
||||
$returnResult = array_values($result);
|
||||
if (!empty($returnResult[2])) {
|
||||
return $this->response($returnResult[0], $returnResult[1], $returnResult[2]);
|
||||
}
|
||||
if (!empty($returnResult[1])) {
|
||||
return $this->response($returnResult[0], $returnResult[1]);
|
||||
}
|
||||
if (!empty($returnResult[0])) {
|
||||
return $this->response($returnResult[0]);
|
||||
}
|
||||
|
||||
return $this->response(false, 'Cannot find requested controller', 404);
|
||||
}
|
||||
|
||||
return $this->response($result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Check if methods exist in class and return the method name according to priority
|
||||
*
|
||||
* @param string $className
|
||||
*
|
||||
* @return sting
|
||||
*/
|
||||
function getDefinedMethod($className, $baseAction, $action, $prefix = '')
|
||||
{
|
||||
$allActions= get_class_methods($className);
|
||||
$classMethod = '';
|
||||
|
||||
if (!empty($prefix)) {
|
||||
$prefix .= '-';
|
||||
}
|
||||
|
||||
$baseUtils = new Utils\BaseUtils();
|
||||
|
||||
//method as 'read'
|
||||
$prefixBaseAction = $baseUtils->toCamelCase($prefix.$baseAction);
|
||||
if ( method_exists($className, $prefixBaseAction) ) {
|
||||
$classMethod = $prefixBaseAction;
|
||||
}
|
||||
|
||||
//method as 'detailSmall'
|
||||
$prefixAction = $baseUtils->toCamelCase($prefix.$action);
|
||||
if ( method_exists($className, $prefixAction) ) {
|
||||
$classMethod = $prefixAction;
|
||||
}
|
||||
|
||||
//method as 'readDetailSmall'
|
||||
$fullAction = $baseUtils->toCamelCase($prefix.$baseAction.'-'.$action);
|
||||
if (method_exists($className, $fullAction)) {
|
||||
$classMethod = $fullAction;
|
||||
}
|
||||
|
||||
return $classMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* If method exists, then redefine classInfo
|
||||
*
|
||||
* @param string $className
|
||||
* @param object $classInfo
|
||||
* @param object $controller
|
||||
* @param bool $isCustom - is need to check custom folder
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
protected function setClassInfo($className, \stdClass $classInfo, \stdClass $controller, $isCustom = true)
|
||||
{
|
||||
$classPath = $this->getClassPath($className);
|
||||
$classMethod = $this->getDefinedMethod($className, $controller->baseAction, $controller->action);
|
||||
|
||||
if (file_exists($classPath) && !empty($classMethod) ) {
|
||||
$classInfo->name = $className;
|
||||
$classInfo->path = $classPath;
|
||||
$classInfo->method = $classMethod;
|
||||
}
|
||||
|
||||
if ($isCustom) {
|
||||
$baseUtils = new Utils\BaseUtils();
|
||||
$espoCustomDir = $baseUtils->getObject('Configurator')->get('espoCustomPath');
|
||||
$controllerClass = $espoCustomDir.'\\'.$className;
|
||||
$classInfo = $this->setClassInfo($controllerClass, $classInfo, $controller, false);
|
||||
}
|
||||
|
||||
return $classInfo;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get class name from path and name
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getClassName($path, $name = '')
|
||||
{
|
||||
$baseUtils = new Utils\BaseUtils();
|
||||
|
||||
if (!empty($name)) {
|
||||
$path = $baseUtils->concatPath($path, $baseUtils->toCamelCase($name, true));
|
||||
}
|
||||
|
||||
return $baseUtils->toFormat($path, '\\');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get full class path (inc. "application" and file extension) from path and name
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getClassPath($path, $name = '')
|
||||
{
|
||||
$baseUtils = new Utils\BaseUtils();
|
||||
|
||||
if (!empty($name)) {
|
||||
$path = $baseUtils->concatPath($path, $baseUtils->toCamelCase($name, true));
|
||||
}
|
||||
|
||||
return $baseUtils->concatPath('application', $baseUtils->toFormat($path, '/').'.php');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prepare response to output
|
||||
*
|
||||
* @param mixed $data
|
||||
* @param string $errMessage
|
||||
* @param int $errorCode
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function response($data=null, $errMessage='Error', $errorCode=404)
|
||||
{
|
||||
return (object) array(
|
||||
'data' => $data,
|
||||
'errMessage' => $errMessage,
|
||||
'errCode' => $errorCode,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
@@ -7,11 +7,6 @@ use Espo\Utils as Utils;
|
||||
class FileManager extends BaseUtils
|
||||
{
|
||||
/**
|
||||
* @var string - default directory separator
|
||||
*/
|
||||
protected $separator= DIRECTORY_SEPARATOR;
|
||||
|
||||
/**
|
||||
* @var object - default permission settings
|
||||
*/
|
||||
protected $defaultPermissions;
|
||||
@@ -22,16 +17,6 @@ class FileManager extends BaseUtils
|
||||
protected $appCache= 'application';
|
||||
|
||||
|
||||
/**
|
||||
* Get a folder separator
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSeparator()
|
||||
{
|
||||
return $this->separator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of files in specified directory
|
||||
*
|
||||
@@ -274,7 +259,7 @@ class FileManager extends BaseUtils
|
||||
return false;
|
||||
}
|
||||
$unsetFileName = $this->getObject('Configurator')->get('unsetFileName');
|
||||
$scopeModuleMap = $this->getObject('Configurator')->get('scopeModuleMap');
|
||||
//$scopeModuleMap = $this->getObject('Configurator')->get('scopeModuleMap');
|
||||
|
||||
//get matadata files
|
||||
$fileList = $this->getFileList($dirPath, $recursively, '\.json$');
|
||||
@@ -335,7 +320,7 @@ class FileManager extends BaseUtils
|
||||
public function uniteFilesGetContent($folderPath, $fileName, $defaults)
|
||||
{
|
||||
$fileContent= $this->getContent($folderPath, $fileName);
|
||||
$decoded= $this->getArrayData($fileContent);
|
||||
$decoded= $this->getArrayData($fileContent);
|
||||
|
||||
if (empty($decoded)) {
|
||||
$this->getObject('Log')->add('FATAL EXCEPTION', 'Syntax error or empty file - '.$this->concatPath($folderPath, $fileName));
|
||||
@@ -525,29 +510,7 @@ class FileManager extends BaseUtils
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array data (if JSON convert to array)
|
||||
|
||||
@@ -77,6 +77,10 @@ class Layout extends FileManager
|
||||
*/
|
||||
function setLayout($data, $controller, $name)
|
||||
{
|
||||
if (empty($controller) || empty($name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$layoutPath = $this->getLayoutPath($controller);
|
||||
|
||||
return $this->setContent($data, $layoutPath, $name.'.json');
|
||||
|
||||
@@ -70,6 +70,7 @@ class Metadata extends FileManager
|
||||
{
|
||||
$fullPath= $this->getConfig()->corePath;
|
||||
$moduleName= $this->getScopeModuleName($scope);
|
||||
|
||||
if (!empty($moduleName)) {
|
||||
$fullPath= str_replace('{*}', $moduleName, $this->getConfig()->customPath);
|
||||
}
|
||||
|
||||
@@ -126,6 +126,24 @@ class BaseUtilsTest extends \PHPUnit_Framework_TestCase
|
||||
}
|
||||
|
||||
|
||||
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() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -38,11 +38,11 @@ class JSONTest extends \PHPUnit_Framework_TestCase
|
||||
$test= '{"folder":"data\/logs"}';
|
||||
$this->assertEquals('data/logs', $this->fixture->decode($test)->folder);
|
||||
|
||||
$test= '{"folder":"\\Entity\\Logs"}';
|
||||
$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);
|
||||
//$test= '{"folder":"\Entity\\Logs"}';
|
||||
//$this->assertEquals('\Entity\Logs', $this->fixture->decode($test)->folder);
|
||||
}
|
||||
|
||||
function testIsJSON()
|
||||
|
||||
@@ -34,7 +34,7 @@ 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,1 ));
|
||||
$this->assertTrue($this->fixture->isSuccess( $data ));
|
||||
}
|
||||
|
||||
function testPatch()
|
||||
@@ -50,7 +50,7 @@ class LayoutTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
$this->fixture->setType('GET');
|
||||
|
||||
$this->fixture->setUrl('/customTest/layout/detail-view');
|
||||
$this->fixture->setUrl('/custom-test/layout/detail');
|
||||
$this->assertTrue($this->fixture->isSuccess( $this->fixture->getResponse() ));
|
||||
|
||||
$this->fixture->setUrl('/need-to-be-not-real/layout/not-real');
|
||||
|
||||
@@ -40,11 +40,11 @@ class MetadataTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
$this->fixture->setType('PUT');
|
||||
|
||||
$this->fixture->setUrl('/metadata/custom-test/Account');
|
||||
$this->fixture->setUrl('/metadata/custom-test/account');
|
||||
$data= '{"module":"Test"}';
|
||||
$this->assertTrue($this->fixture->isSuccess( $data ));
|
||||
|
||||
$this->fixture->setUrl('/metadata/custom-test/Test');
|
||||
$this->fixture->setUrl('/metadata/custom-test/test');
|
||||
$data= '{"module":"Test","var1":{"subvar1":"NEWsubval1","subvar55":"subval55"}}';
|
||||
$this->assertTrue($this->fixture->isSuccess( $data ));
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace Espo\Tests\Api;
|
||||
|
||||
class RestTesterClass
|
||||
{
|
||||
public $mainUrl= 'http://172.20.0.1/espocrm/api';
|
||||
public $mainUrl= 'http://172.20.0.1/espocrm-test/api';
|
||||
public $username= 'admin';
|
||||
public $pass= '1';
|
||||
public $type= 'PATCH';
|
||||
|
||||
@@ -38,7 +38,7 @@ class SettingsTest extends \PHPUnit_Framework_TestCase
|
||||
"customTest"=> array("test"=> "success"),
|
||||
);
|
||||
$json= json_encode($array);
|
||||
$this->assertTrue( $this->fixture->isSuccess($json, true) );
|
||||
$this->assertTrue( $this->fixture->isSuccess($json) );
|
||||
|
||||
/*
|
||||
$config= new Utils\Configurator();
|
||||
|
||||
Reference in New Issue
Block a user