add merging hooks file in cache

This commit is contained in:
Taras Machyshyn
2014-01-13 16:20:17 +02:00
parent 411319adc0
commit 92f532f0b4
8 changed files with 402 additions and 27 deletions
+82 -10
View File
@@ -2,7 +2,8 @@
namespace Espo\Core;
use \Espo\Core\Exceptions\Error;
use \Espo\Core\Exceptions\Error,
\Espo\Core\Utils\Util;
class HookManager
{
@@ -14,33 +15,51 @@ class HookManager
protected $cacheFile = 'data/cache/application/hooks.php';
/**
* List of defined hooks
*
* @var array
*/
protected $hookList = array(
'beforeSave',
'afterSave',
);
public function __construct(Container $container)
{
$this->container = $container;
$this->loadHooks();
}
protected getConfig()
protected function getConfig()
{
return $this->container->get('config');
}
protected function getFileManager()
{
return $this->container->get('fileManager');
}
protected function loadHooks()
{
{
if ($this->getConfig()->get('useCache') && file_exists($this->cacheFile)) {
$this->hooks = include($this->cacheFile);
$this->hooks = $this->getFileManager()->getContent($this->cacheFile);
//$this->hooks = include($this->cacheFile);
return;
}
$metadata = $this->container->get('metadata');
// TODO scan Espo/Hooks/{ScopeName}/{HookName}.php
$this->hooks = $this->getHookData( array('Espo/Hooks', 'Espo/Custom/Hooks') );
foreach ($metadata->getModuleList() as $moduleName) {
// TODO scan Espo/Modules/{$moduleName}/ScopeName/HookName.php
$this->hooks = array_merge($this->hooks, $this->getHookData( array('Espo/Modules/'.$moduleName.'/Hooks', 'Espo/Custom/Modules/'.$moduleName.'/Hooks') ));
}
if ($this->getConfig()->get('useCache')) {
// TODO write $this->hooks into cache file
$this->getFileManager()->setContentPHP($this->hooks, $this->cacheFile);
}
}
@@ -71,5 +90,58 @@ class HookManager
}
throw new Error("Class '$className' does not exist");
}
/**
* Get and merge hook data by checking the files exist in $hookDirs
*
* @param array $hookDirs - it can be an array('Espo/Hooks', 'Espo/Custom/Hooks', 'Espo/Custom/Modules/Crm/Hooks')
*
* @return array
*/
protected function getHookData(array $hookDirs)
{
$hooks = array();
foreach($hookDirs as $hookDir) {
$fullHookDir = 'application/'.$hookDir;
if (file_exists($fullHookDir)) {
$fileList = $this->getFileManager()->getFileList($fullHookDir, 1, '\.php$', 'file');
foreach($fileList as $scopeName => $hookFiles) {
$hookScopeDirPath = Util::concatPath($hookDir, $scopeName);
$scopeHooks = array();
foreach($hookFiles as $hookFile) {
$hookFilePath = Util::concatPath($hookScopeDirPath, $hookFile);
$className = '\\'.Util::toFormat(preg_replace('/\.php$/i', '', $hookFilePath), '\\');
foreach($this->hookList as $hookName) {
if (method_exists($className, $hookName)) {
$scopeHooks[$hookName][$className::$order][] = $className;
}
}
}
//sort hooks by order
foreach($scopeHooks as $hookName => $hookList) {
ksort($hookList);
$sortedHookList = array();
foreach($hookList as $hookDetails) {
$sortedHookList = array_merge($sortedHookList, $hookDetails);
}
$hooks[$scopeName][$hookName] = isset($hooks[$scopeName][$hookName]) ? array_merge($hooks[$scopeName][$hookName], $sortedHookList) : $sortedHookList;
}
}
}
}
return $hooks;
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
<?php
namespace \Espo\Core\Hooks;
namespace Espo\Core\Hooks;
class Base
{
+37 -7
View File
@@ -20,7 +20,7 @@ class Manager
private $params;
public function __construct(\stdClass $params)
public function __construct(\stdClass $params)
{
$this->params = $params;
}
@@ -36,13 +36,14 @@ class Manager
* Get a list of files in specified directory
*
* @param string $path string - Folder path, Ex. myfolder
* @param bool $recursively - Find files in subfolders
* @param bool | int $recursively - Find files in subfolders
* @param string $filter - Filter for files. Use regular expression, Ex. \.json$
* @param string $fileType [all, file, dir] - Filter for type of files/directories.
* @param bool $isReturnSingleArray - if need to return a single array of file list
*
* @return array
*/
function getFileList($path, $recursively=false, $filter='', $fileType='all')
function getFileList($path, $recursively=false, $filter='', $fileType='all', $isReturnSingleArray = false)
{
if (!file_exists($path)) {
return false;
@@ -57,8 +58,9 @@ class Manager
{
$add= false;
if (is_dir($path . Utils\Util::getSeparator() . $value)) {
if ($recursively) {
$result[$value] = $this->getFileList($path.Utils\Util::getSeparator().$value, $recursively, $filter, $fileType);
if ($recursively || (is_int($recursively) && $recursively!=0) ) {
$nextRecursively = is_int($recursively) ? ($recursively-1) : $recursively;
$result[$value] = $this->getFileList($path.Utils\Util::getSeparator().$value, $nextRecursively, $filter, $fileType);
}
else if (in_array($fileType, array('all', 'dir'))){
$add= true;
@@ -82,9 +84,37 @@ class Manager
}
}
if ($isReturnSingleArray) {
return $this->getSingeFileList($result);
}
return $result;
}
/**
* Convert file list to a single array
*
* @param aray $fileList
* @param string $parentDirName
*
* @return aray
*/
protected function getSingeFileList(array $fileList, $parentDirName = '')
{
$singleFileList = array();
foreach($fileList as $dirName => $fileName) {
if (is_array($fileName)) {
$currentDir = Utils\Util::concatPath($parentDirName, $dirName);
$singleFileList = array_merge($singleFileList, $this->getSingeFileList($fileName, $currentDir));
} else {
$singleFileList[] = Utils\Util::concatPath($parentDirName, $fileName);
}
}
return $singleFileList;
}
/**
* Get content from file
*
@@ -419,7 +449,7 @@ class Manager
*
* @return string | false
*/
function getPHPFormat($content)
public function getPHPFormat($content)
{
if (empty($content)) {
return false;
@@ -759,4 +789,4 @@ return '.var_export($content, true).';
}
?>
?>
+8 -8
View File
@@ -295,7 +295,7 @@ class Metadata
//NEED TO CHANGE
public function getScopes()
{
if (!$reload && !empty($this->scopes)) {
if (!empty($this->scopes)) {
return $this->scopes;
}
@@ -314,16 +314,16 @@ class Metadata
if (is_null($this->moduleList)) {
$this->moduleList = array();
$scopes = $this->getScopes();
// TODO order
foreach ($this->scopes as $defs) {
if (!empty($defs['module'])) {
$module = $defs['module'];
if (!in_array($module, $this->moduleList)) {
$this->moduleList[] = $module;
}
foreach ($scopes as $moduleName) {
if (!empty($moduleName)) {
if (!in_array($moduleName, $this->moduleList)) {
$this->moduleList[] = $moduleName;
}
}
}
}
}
return $this->moduleList;
}
+4
View File
@@ -161,6 +161,10 @@ class Util
if (empty($filePath)) {
return $folderPath;
}
if (empty($folderPath)) {
return $filePath;
}
else {
if (substr($folderPath, -1) == static::getSeparator()) {
return $folderPath . $filePath;
@@ -1,6 +1,6 @@
<?php
namespace \Espo\Modules\Crm\Hooks\Prospect;
namespace Espo\Modules\Crm\Hooks\Prospect;
class Test extends \Espo\Core\Hooks\Base
{
+269
View File
@@ -0,0 +1,269 @@
<?php
namespace tests\Espo\Core\Utils\File;
class ManagerTest extends \PHPUnit_Framework_TestCase
{
protected $object;
protected $filesPath= 'tests/testData/FileManager';
protected function setUp()
{
$this->object = new \Espo\Core\Utils\File\Manager(
(object) array(
'defaultPermissions' => (object) array (
'dir' => '0775',
'file' => '0664',
'user' => '',
'group' => '',
),
)
);
}
protected function tearDown()
{
$this->object = NULL;
}
public function invokeMethod($methodName, array $parameters = array())
{
$reflection = new \ReflectionClass(get_class($this->object));
$method = $reflection->getMethod($methodName);
$method->setAccessible(true);
return $method->invokeArgs($this->object, $parameters);
}
function testGetFileList()
{
$result= array('Dir1', 'file1.json','file1.php',); //no recursive
$this->assertEquals($result, $this->object->getFileList($this->filesPath.'/getFileList', false));
$result= array('Dir1'); //no recursive
$this->assertEquals($result, $this->object->getFileList($this->filesPath.'/getFileList', false, '', 'dir'));
$result= array('file1.json','file1.php',); //no recursive
$this->assertEquals($result, $this->object->getFileList($this->filesPath.'/getFileList', false, '', 'file'));
$result= array(
'Dir1' => array(
'file2.json',
'Dir2' => array (
'file3.json'
),
),
'file1.json',
'file1.php',
);
$this->assertEquals($result, $this->object->getFileList($this->filesPath.'/getFileList', true));
}
function testGetFileListWithFilter()
{
$result= array('file1.json'); //no recursive
$this->assertEquals($result, $this->object->getFileList($this->filesPath.'/getFileList', false, '.*\.json$'));
$result= array(
'Dir1' => array(
'file2.json',
'Dir2' => array (
'file3.json'
),
),
'file1.json',
);
$this->assertEquals($result, $this->object->getFileList($this->filesPath.'/getFileList', true, '.*\.json$'));
$result= array(
'file1.php',
'Dir1' => array(
'Dir2' => array (
),
),
);
$this->assertEquals($result, $this->object->getFileList($this->filesPath.'/getFileList', true, '.*\.php$'));
}
function testGetFileListRecursively()
{
$result= array(
'Dir1',
'file1.json',
'file1.php',
);
$this->assertEquals($result, $this->object->getFileList($this->filesPath.'/getFileList', false));
$result= array(
'Dir1' => array(
'file2.json',
'Dir2' => array (
'file3.json'
),
),
'file1.json',
'file1.php',
);
$this->assertEquals($result, $this->object->getFileList($this->filesPath.'/getFileList', true));
$result= array(
'Dir1' => array(
'Dir2',
'file2.json',
),
'file1.json',
'file1.php',
);
$this->assertEquals($result, $this->object->getFileList($this->filesPath.'/getFileList', 1));
$result= array(
'Dir1' => array(
'file2.json',
'Dir2' => array (
'file3.json'
),
),
'file1.json',
'file1.php',
);
$this->assertEquals($result, $this->object->getFileList($this->filesPath.'/getFileList', 2));
$result= array(
'Dir1' => array(
'file2.json',
'Dir2' => array (
'file3.json'
),
),
'file1.json',
'file1.php',
);
$this->assertEquals($result, $this->object->getFileList($this->filesPath.'/getFileList', 3));
}
function testGetContent()
{
$testPath= $this->filesPath.'/getContent';
$result= '{"testData":"Test"}';
$this->assertEquals($result, $this->object->getContent($testPath, 'test.json'));
$result= '{"testData":"Test"}';
$this->assertEquals($result, $this->object->getContent($testPath.'/test.json'));
}
/*function testSetContent()
{
$testPath= $this->filesPath.'/setContent';
$result= 'next value';
$this->assertTrue($this->object->setContent($result, $testPath, 'test.json'));
//$this->assertEquals($result, $this->object->getContent($testPath, 'test.json'));
//$this->assertTrue($this->object->setContent('initial value', $testPath.'/test.json'));
} */
/*function testMergeContent()
{
$testPath= $this->filesPath.'/setContent';
$initialVal= $this->object->getContent($testPath, 'test2.json');
$result= '{"var1":"val1","var2":"val2"}';
$this->assertTrue($this->object->setContent($result, $testPath, 'test2.json'));
$result= '{"var2":"new val"}';
$this->assertTrue($this->object->mergeContent($result, $testPath, 'test2.json', true));
$result= '{"var1":"val1","var2":"new val"}';
$this->assertEquals($result, $this->object->getContent($testPath, 'test2.json'));
} */
function testGetCurrentPermission()
{
$this->assertEquals(4, strlen($this->object->getCurrentPermission($this->filesPath.'/setContent/test.json')));
$this->assertStringMatchesFormat('%d', $this->object->getCurrentPermission($this->filesPath.'/setContent/test.json'));
}
/*function testCheckCreateFile()
{
$filePath= $this->filesPath.'/setContent/test.json';
$this->assertTrue($this->object->checkCreateFile($filePath));
$perm= $this->object->getDefaultPermissions();
$this->assertTrue( in_array($this->object->getCurrentPermission($filePath), array($perm->file, $perm->dir)) );
}*/
function testGetDefaultPermissions()
{
$this->assertObjectHasAttribute('dir', $this->object->getDefaultPermissions());
$this->assertObjectHasAttribute('file', $this->object->getDefaultPermissions());
$this->assertObjectHasAttribute('user', $this->object->getDefaultPermissions());
$this->assertObjectHasAttribute('group', $this->object->getDefaultPermissions());
}
function testGetFileName()
{
$result= 'file1';
$this->assertEquals($result, $this->object->getFileName('file1.json'));
$result= 'file1';
$this->assertEquals($result, $this->object->getFileName('file1.json', 'json'));
$result= 'file1';
$this->assertEquals($result, $this->object->getFileName('file1.json', '.json'));
}
function testGetDirName()
{
$result= 'dirname';
$this->assertEquals('dirname', $this->object->getDirName('test/dirname/Test.json'));
$result= 'dirname';
$this->assertEquals('dirname', $this->object->getDirName('test/dirname/'));
$result= 'dirname';
$this->assertEquals('dirname', $this->object->getDirName('test/dirname'));
}
function testGetSingeFileList()
{
$input = array(
'Dir1' => array(
'file2.json',
'Dir2' => array (
'file3.json'
),
),
'file1.json',
'file1.php',
);
$result = array(
'Dir1/file2.json',
'Dir1/Dir2/file3.json',
'file1.json',
'file1.php',
);
$this->assertEquals($result, $this->invokeMethod('getSingeFileList', array($input)));
}
}
?>