From 3d001e733e854cccde1dacaae499df525507fe19 Mon Sep 17 00:00:00 2001 From: Taras Machyshyn Date: Tue, 29 Apr 2014 18:30:43 +0300 Subject: [PATCH 1/2] fixed bugs with enum field type in metadata --- application/Espo/Core/Utils/File/Manager.php | 15 +- application/Espo/Core/Utils/File/Unifier.php | 66 ++--- application/Espo/Core/Utils/Metadata.php | 4 +- application/Espo/Core/Utils/Util.php | 48 +++- tests/Espo/Core/Utils/UtilTest.php | 263 ++++++++++++++++--- 5 files changed, 299 insertions(+), 97 deletions(-) diff --git a/application/Espo/Core/Utils/File/Manager.php b/application/Espo/Core/Utils/File/Manager.php index ad30a0dba1..8fa325a152 100644 --- a/application/Espo/Core/Utils/File/Manager.php +++ b/application/Espo/Core/Utils/File/Manager.php @@ -214,19 +214,20 @@ class Manager * @param string | array $path * @param string $content JSON string * @param bool $isJSON + * @param array $mergeOptions * * @return bool */ - public function mergeContents($path, $content, $isJSON = false) + public function mergeContents($path, $content, $isJSON = false, $mergeOptions = null) { $fileContent = $this->getContents($path); $savedDataArray = Utils\Json::getArrayData($fileContent); $newDataArray = Utils\Json::getArrayData($content); - $data= Utils\Util::merge($savedDataArray, $newDataArray); + $data = Utils\Util::merge($savedDataArray, $newDataArray, $mergeOptions); if ($isJSON) { - $data= Utils\Json::encode($data, JSON_PRETTY_PRINT); + $data = Utils\Json::encode($data, JSON_PRETTY_PRINT); } return $this->putContents($path, $data); @@ -241,7 +242,7 @@ class Manager * * @return bool */ - public function mergeContentsPHP($path, $content, $onlyFirstLevel= false) + public function mergeContentsPHP($path, $content, $onlyFirstLevel = false, $mergeOptions = null) { $fileContent = $this->getContents($path); @@ -250,12 +251,12 @@ class Manager if ($onlyFirstLevel) { foreach($newDataArray as $key => $val) { - $setVal= is_array($val) ? array() : ''; - $savedDataArray[$key]= $setVal; + $setVal = is_array($val) ? array() : ''; + $savedDataArray[$key] = $setVal; } } - $data= Utils\Util::merge($savedDataArray, $newDataArray); + $data = Utils\Util::merge($savedDataArray, $newDataArray, $mergeOptions); return $this->putContentsPHP($path, $data); } diff --git a/application/Espo/Core/Utils/File/Unifier.php b/application/Espo/Core/Utils/File/Unifier.php index ae7cbbed27..788ca6fa03 100644 --- a/application/Espo/Core/Utils/File/Unifier.php +++ b/application/Espo/Core/Utils/File/Unifier.php @@ -18,7 +18,7 @@ * * You should have received a copy of the GNU General Public License * along with EspoCRM. If not, see http://www.gnu.org/licenses/. - ************************************************************************/ + ************************************************************************/ namespace Espo\Core\Utils\File; @@ -35,7 +35,7 @@ class Unifier public function __construct(\Espo\Core\Utils\File\Manager $fileManager) { - $this->fileManager = $fileManager; + $this->fileManager = $fileManager; } @@ -46,29 +46,31 @@ class Unifier /** - * Unite file content to the file + * Unite file content to the file * - * @param bool $recursively - Note: only for first level of sub directory, other levels of sub directories will be ignored + * @param [type] $name [description] + * @param [type] $paths [description] + * @param boolean $recursively Note: only for first level of sub directory, other levels of sub directories will be ignored + * @param [type] $mergeLevel - merge level, see Espo\Core\Utils\Util::merge() * * @return array */ - public function unify($name, $paths, $recursively = false) + public function unify($name, $paths, $recursively = false, $mergeLevel = null, $mergeKeyName = null) { - $content = $this->unifySingle($paths['corePath'], $name, $recursively); + $content = $this->unifySingle($paths['corePath'], $name, $recursively); if (!empty($paths['modulePath'])) { $customDir = strstr($paths['modulePath'], '{*}', true); - $dirList = $this->getFileManager()->getFileList($customDir, false, '', 'dir'); + $dirList = $this->getFileManager()->getFileList($customDir, false, '', 'dir'); foreach ($dirList as $dirName) { $curPath = str_replace('{*}', $dirName, $paths['modulePath']); - $content = Utils\Util::merge($content, $this->unifySingle($curPath, $name, $recursively, $dirName)); + $content = Utils\Util::merge($content, $this->unifySingle($curPath, $name, $recursively, $dirName), $mergeLevel, $mergeKeyName); } } - //todo check customPaths - if (!empty($paths['customPath'])) { - $content = Utils\Util::merge($content, $this->unifySingle($paths['customPath'], $name, $recursively)); + if (!empty($paths['customPath'])) { + $content = Utils\Util::merge($content, $this->unifySingle($paths['customPath'], $name, $recursively), $mergeLevel, $mergeKeyName); } return $content; @@ -76,8 +78,8 @@ class Unifier - /** - * Unite file content to the file for one directory [NOW ONLY FOR METADATA, NEED TO CHECK FOR LAYOUTS AND OTHERS] + /** + * 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 array("metadata", "layouts"), ex. $this->name @@ -91,7 +93,7 @@ class Unifier if (empty($dirPath) || !file_exists($dirPath)) { return false; } - $unsetFileName = $this->params['unsetFileName']; + $unsetFileName = $this->params['unsetFileName']; //get matadata files $fileList = $this->getFileManager()->getFileList($dirPath, $recursively, '\.json$'); @@ -104,7 +106,7 @@ class Unifier foreach($fileList as $dirName => $fileName) { if (is_array($fileName)) { /*get content from files in a sub directory*/ - $content[$dirName]= $this->unifySingle(Utils\Util::concatPath($dirPath,$dirName), $type, false, $moduleName); //only first level of a sub directory + $content[$dirName]= $this->unifySingle(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) { @@ -116,23 +118,23 @@ class Unifier $mergedValues = $this->unifyGetContents(array($dirPath, $fileName), $defaultValues); if (!empty($mergedValues)) { - $name = $this->getFileManager()->getFileName($fileName, '.json'); + $name = $this->getFileManager()->getFileName($fileName, '.json'); $content[$name] = $mergedValues; } } } //unset content - $content= Utils\Util::unsetInArray($content, $unsets); + $content= Utils\Util::unsetInArray($content, $unsets); //END: unset content return $content; } - /** - * Helpful method for get content from files for unite Files + /** + * Helpful method for get content from files for unite Files * - * @param string | array $paths + * @param string | array $paths * @param string | array() $defaults - It can be a string like ["metadata","layouts"] OR an array with default values * * @return array @@ -143,27 +145,27 @@ class Unifier $decoded= Utils\Json::getArrayData($fileContent); if (empty($decoded) && !is_array($decoded)) { - $GLOBALS['log']->emergency('Syntax error or empty file - '.Utils\Util::concatPath($folderPath, $fileName)); + $GLOBALS['log']->emergency('Syntax error or empty file - '.Utils\Util::concatPath($folderPath, $fileName)); } else { - //Default values - if (is_string($defaults) && !empty($defaults)) { - $defType= $defaults; + //Default values + if (is_string($defaults) && !empty($defaults)) { + $defType= $defaults; unset($defaults); - $name= $this->getFileManager()->getFileName($fileName, '.json'); + $name= $this->getFileManager()->getFileName($fileName, '.json'); $defaults= $this->loadDefaultValues($name, $defType); } - $mergedValues= Utils\Util::merge($defaults, $decoded); - //END: Default values + $mergedValues= Utils\Util::merge($defaults, $decoded); + //END: Default values - return $mergedValues; + return $mergedValues; } return array(); } /** - * Load default values for selected type [metadata, layouts] + * Load default values for selected type [metadata, layouts] * * @param string $name * @param string $type - [metadata, layouts] @@ -172,15 +174,15 @@ class Unifier */ protected function loadDefaultValues($name, $type='metadata') { - $defaultPath= $this->params['defaultsPath']; + $defaultPath= $this->params['defaultsPath']; $defaultValue= $this->getFileManager()->getContents( array($defaultPath, $type, $name.'.json') ); if ($defaultValue!==false) { - //return default array + //return default array return Utils\Json::decode($defaultValue, true); } - return array(); + return array(); } } diff --git a/application/Espo/Core/Utils/Metadata.php b/application/Espo/Core/Utils/Metadata.php index 51278eeaff..b2dc765067 100644 --- a/application/Espo/Core/Utils/Metadata.php +++ b/application/Espo/Core/Utils/Metadata.php @@ -186,7 +186,7 @@ class Metadata { $data = false; if (!file_exists($this->cacheFile) || $reload) { - $data = $this->getUnifier()->unify($this->name, $this->paths, true); + $data = $this->getUnifier()->unify($this->name, $this->paths, true, 5, 'options'); if ($data === false) { $GLOBALS['log']->emergency('Metadata:getMetadata() - metadata unite file cannot be created'); @@ -246,7 +246,7 @@ class Metadata { $path = $this->paths['customPath']; - $result = $this->getFileManager()->mergeContents(array($path, $type, $scope.'.json'), $data, true); + $result = $this->getFileManager()->mergeContents(array($path, $type, $scope.'.json'), $data, true, array(3, 'options')); if ($result === false) { throw new Error("Error saving metadata. See log file for details."); } diff --git a/application/Espo/Core/Utils/Util.php b/application/Espo/Core/Utils/Util.php index 1365dfcb84..fdc594881a 100644 --- a/application/Espo/Core/Utils/Util.php +++ b/application/Espo/Core/Utils/Util.php @@ -118,14 +118,16 @@ class Util * 'level1' => array( * 'level2' => array( * 'level3' => array( - * 'key' => 'value', + * 'key1' => 'value', + * 'key2' => 'value', * ), * ), * ), * ) - * @return array + * @param $rewriteKeyName string - Rewrite key name + * @return array * */ - public static function merge($array, $mainArray, $rewriteLevel = null) + public static function merge($array, $mainArray, $rewriteLevel = null, $rewriteKeyName = null) { if (is_array($array) && !is_array($mainArray)) { return $array; @@ -135,22 +137,41 @@ class Util return array(); } + if (is_array($rewriteLevel)) { + if (isset($rewriteLevel[1])) { + $rewriteKeyName = $rewriteLevel[1]; + } + if (isset($rewriteLevel[0])) { + $rewriteLevel = $rewriteLevel[0]; + } + } + foreach($mainArray as $mainKey => $mainValue) { $found = false; foreach($array as $key => $value) { - if ((string)$mainKey == (string)$key){ + if ((string)$mainKey == (string)$key) { $found = true; - if (is_array($mainValue) || is_array($value)){ + if (is_array($mainValue) || is_array($value)) { - if (!isset($rewriteLevel) || $rewriteLevel != 1) { - $array[$mainKey] = static::merge((array) $value, (array) $mainValue, --$rewriteLevel); + $rowRewriteLevel = $rewriteLevel; + + /** check the $rewriteKeyName */ + if (isset($rowRewriteLevel) && $rowRewriteLevel == 1 && isset($rewriteKeyName)) { + $rewriteKeyName = is_array($rewriteKeyName) ? $rewriteKeyName : (array) $rewriteKeyName; + + if (!in_array((string)$key, $rewriteKeyName)) { + $rowRewriteLevel = null; + } + } /** END: check the $rewriteKeyName */ + + if (!isset($rowRewriteLevel) || $rowRewriteLevel != 1) { + $array[$mainKey] = static::merge((array) $value, (array) $mainValue, --$rowRewriteLevel, $rewriteKeyName); continue; } - /* merge only 1st level*/ $mergeValue = array('mergeLevel' => (array) $value); $mergeMainValue = array('mergeLevel' => (array) $mainValue); $mergeRes = array_merge($mergeValue, $mergeMainValue); @@ -158,20 +179,19 @@ class Util continue; } - //merge logic - if (!is_numeric($mainKey)){ + /** merge logic */ + if (!is_numeric($mainKey)) { $array[$mainKey] = $mainValue; } elseif (!in_array($mainValue, $array)) { $array[] = $mainValue; - } - //END: merge ligic + } /** END: merge logic */ break; } } - // add an item if key not found - if (!$found){ + /** add an item if key not found */ + if (!$found) { $array[$mainKey] = $mainValue; } diff --git a/tests/Espo/Core/Utils/UtilTest.php b/tests/Espo/Core/Utils/UtilTest.php index 82f5e373e4..1e78ccc98f 100644 --- a/tests/Espo/Core/Utils/UtilTest.php +++ b/tests/Espo/Core/Utils/UtilTest.php @@ -169,6 +169,94 @@ class UtilTest extends \PHPUnit_Framework_TestCase ); $this->assertEquals($result, Util::merge($basicArr, $advArr, 1)); + $this->assertEquals($result, Util::merge($basicArr, $advArr, array(1))); + } + + + public function testMergeLevel1WithMergeKeyName() + { + $basicArr = array( + 'useCache' => 111, + 'useCache1' => 111, + 'sub' => array ( + 'subV' => '1111', + 'subV1' => '1111', + 'subO' => array( + 'subOV' => '11111', + 'subOV1' => '11111', + 'subOT' => array( + 'subOTT' => '11111', + 'subOT1' => '11111', + ), + ), + ), + ); + + $advArr = array( + 'useCache' => 222, + 'useCache2' => 222, + 'sub' => array ( + 'subV' => '222222', + 'subV2' => '222222', + 'subO' => array( + 'subOV' => '22222', + 'subOV2' => '22222', + 'subOT' => array( + 'subOTT' => '22222', + 'subOT2' => '22222', + ), + ), + ), + ); + + $result = array ( + 'useCache' => 222, + 'useCache1' => 111, + 'sub' => + array ( + 'subV' => '222222', + 'subV1' => '1111', + 'subO' => + array ( + 'subOV' => '22222', + 'subOV1' => '11111', + 'subOT' => + array ( + 'subOTT' => '22222', + 'subOT1' => '11111', + 'subOT2' => '22222', + ), + 'subOV2' => '22222', + ), + 'subV2' => '222222', + ), + 'useCache2' => 222, + ); + + $this->assertEquals($result, Util::merge($basicArr, $advArr, 1, 'useCache')); + $this->assertEquals( $result, Util::merge($basicArr, $advArr, array(1, 'useCache')) ); + + $result = array ( + 'useCache' => 222, + 'useCache1' => 111, + 'sub' => + array ( + 'subV' => '222222', + 'subV2' => '222222', + 'subO' => array( + 'subOV' => '22222', + 'subOV2' => '22222', + 'subOT' => array( + 'subOTT' => '22222', + 'subOT2' => '22222', + ), + ), + ), + 'useCache2' => 222, + ); + + $this->assertEquals($result, Util::merge($basicArr, $advArr, 1, 'sub')); + $this->assertEquals( $result, Util::merge($basicArr, $advArr, array(1, 'sub')) ); } public function testMergeLevel2() @@ -212,26 +300,117 @@ class UtilTest extends \PHPUnit_Framework_TestCase 'useCache1' => 111, 'sub' => array ( - 'subV' => '222222', - 'subV1' => '1111', - 'subO' => - array ( - 'subOV' => '22222', - 'subOV2' => '22222', - 'subOT' => - array ( - 'subOTT' => '22222', - 'subOT2' => '22222', - ), - ), - 'subV2' => '222222', + 'subV' => '222222', + 'subV1' => '1111', + 'subO' => + array ( + 'subOV' => '22222', + 'subOV2' => '22222', + 'subOT' => + array ( + 'subOTT' => '22222', + 'subOT2' => '22222', + ), + ), + 'subV2' => '222222', ), 'useCache2' => 222, ); $this->assertEquals($result, Util::merge($basicArr, $advArr, 2)); + $this->assertEquals($result, Util::merge($basicArr, $advArr, array(2))); } + public function testMergeLevel2WithMergeKeyName() + { + $basicArr = array( + 'useCache' => 111, + 'useCache1' => 111, + 'sub' => array ( + 'subV' => '1111', + 'subV1' => '1111', + 'subO' => array( + 'subOV' => '11111', + 'subOV1' => '11111', + 'subOT' => array( + 'subOTT' => '11111', + 'subOT1' => '11111', + ), + ), + ), + ); + + $advArr = array( + 'useCache' => 222, + 'useCache2' => 222, + 'sub' => array ( + 'subV' => '222222', + 'subV2' => '222222', + 'subO' => array( + 'subOV' => '22222', + 'subOV2' => '22222', + 'subOT' => array( + 'subOTT' => '22222', + 'subOT2' => '22222', + ), + ), + ), + ); + + $result = array ( + 'useCache' => 222, + 'useCache1' => 111, + 'sub' => + array ( + 'subV' => '222222', + 'subV1' => '1111', + 'subO' => + array ( + 'subOV' => '22222', + 'subOV1' => '11111', + 'subOT' => + array ( + 'subOTT' => '22222', + 'subOT1' => '11111', + 'subOT2' => '22222', + ), + 'subOV2' => '22222', + ), + 'subV2' => '222222', + ), + 'useCache2' => 222, + ); + + $this->assertEquals($result, Util::merge($basicArr, $advArr, 2, 'subOV')); + $this->assertEquals( $result, Util::merge($basicArr, $advArr, array(2, 'subOV')) ); + + $result = array ( + 'useCache' => 222, + 'useCache1' => 111, + 'sub' => + array ( + 'subV' => '222222', + 'subV1' => '1111', + 'subO' => + array ( + 'subOV' => '22222', + 'subOV2' => '22222', + 'subOT' => + array ( + 'subOTT' => '22222', + 'subOT2' => '22222', + ), + ), + 'subV2' => '222222', + ), + 'useCache2' => 222, + ); + + $this->assertEquals($result, Util::merge($basicArr, $advArr, 2, 'subO')); + $this->assertEquals( $result, Util::merge($basicArr, $advArr, array(2, 'subO')) ); + } + + public function testMergeLevel3() { $basicArr = array( @@ -273,20 +452,20 @@ class UtilTest extends \PHPUnit_Framework_TestCase 'useCache1' => 111, 'sub' => array ( - 'subV' => '222222', - 'subV1' => '1111', - 'subO' => - array ( - 'subOV' => '22222', - 'subOV1' => '11111', - 'subOT' => - array ( - 'subOTT' => '22222', - 'subOT2' => '22222', - ), - 'subOV2' => '22222', - ), - 'subV2' => '222222', + 'subV' => '222222', + 'subV1' => '1111', + 'subO' => + array ( + 'subOV' => '22222', + 'subOV1' => '11111', + 'subOT' => + array ( + 'subOTT' => '22222', + 'subOT2' => '22222', + ), + 'subOV2' => '22222', + ), + 'subV2' => '222222', ), 'useCache2' => 222, ); @@ -335,21 +514,21 @@ class UtilTest extends \PHPUnit_Framework_TestCase 'useCache1' => 111, 'sub' => array ( - 'subV' => '222222', - 'subV1' => '1111', - 'subO' => - array ( - 'subOV' => '22222', - 'subOV1' => '11111', - 'subOT' => - array ( - 'subOTT' => '22222', - 'subOT1' => '11111', - 'subOT2' => '22222', - ), - 'subOV2' => '22222', - ), - 'subV2' => '222222', + 'subV' => '222222', + 'subV1' => '1111', + 'subO' => + array ( + 'subOV' => '22222', + 'subOV1' => '11111', + 'subOT' => + array ( + 'subOTT' => '22222', + 'subOT1' => '11111', + 'subOT2' => '22222', + ), + 'subOV2' => '22222', + ), + 'subV2' => '222222', ), 'useCache2' => 222, ); From c3ac826462b629ab1e208979812e98110c2083e1 Mon Sep 17 00:00:00 2001 From: Taras Machyshyn Date: Wed, 30 Apr 2014 11:05:05 +0300 Subject: [PATCH 2/2] changed method description --- application/Espo/Core/Utils/Util.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/application/Espo/Core/Utils/Util.php b/application/Espo/Core/Utils/Util.php index fdc594881a..22359906dc 100644 --- a/application/Espo/Core/Utils/Util.php +++ b/application/Espo/Core/Utils/Util.php @@ -124,8 +124,9 @@ class Util * ), * ), * ) - * @param $rewriteKeyName string - Rewrite key name - * @return array * + * @param $rewriteKeyName string - Rewrite key name. It is ignored if $rewriteLevel is NULL. + * + * @return array */ public static function merge($array, $mainArray, $rewriteLevel = null, $rewriteKeyName = null) {