From 0639ab842441fea12f2b9f53531fbf33d5576b80 Mon Sep 17 00:00:00 2001 From: Taras Machyshyn Date: Fri, 9 Jan 2015 17:16:41 +0200 Subject: [PATCH 1/4] Json helper improvements --- application/Espo/Core/Utils/Json.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/application/Espo/Core/Utils/Json.php b/application/Espo/Core/Utils/Json.php index af4d1565e4..841dee02b9 100644 --- a/application/Espo/Core/Utils/Json.php +++ b/application/Espo/Core/Utils/Json.php @@ -51,7 +51,7 @@ class Json } $error = self::getLastError(); - if ($json === null || $error) { + if ($json === null || !empty($error)) { $GLOBALS['log']->error('Json::encode():' . $error . ' - ' . print_r($value, true)); } @@ -69,6 +69,10 @@ class Json */ public static function decode($json, $assoc = false, $depth = 512, $options = 0) { + if (is_null($json) || $json === false) { + return $json; + } + if (is_array($json)) { $GLOBALS['log']->warning('Json::decode() - JSON cannot be decoded - '.$json); return false; @@ -85,14 +89,13 @@ class Json } $error = self::getLastError(); - if ($json === null || $error) { + if ($error) { $GLOBALS['log']->error('Json::decode():' . $error); } return $json; } - /** * Check if the string is JSON * @@ -110,7 +113,6 @@ class Json return static::decode($json) != null; } - /** * Get an array data (if JSON convert to array) * @@ -130,7 +132,6 @@ class Json return $returns; } - protected static function getLastError($error = null) { if (!isset($error)) { From d62c83d869a8ca1222f1b9e39fac3a93cc74db3e Mon Sep 17 00:00:00 2001 From: Taras Machyshyn Date: Fri, 9 Jan 2015 17:25:43 +0200 Subject: [PATCH 2/4] 'Language' saving improvements --- application/Espo/Core/Utils/FieldManager.php | 18 ++- application/Espo/Core/Utils/Language.php | 162 ++++++++++++------- tests/Espo/Core/Utils/LanguageTest.php | 15 ++ 3 files changed, 128 insertions(+), 67 deletions(-) diff --git a/application/Espo/Core/Utils/FieldManager.php b/application/Espo/Core/Utils/FieldManager.php index 707e7bfef5..45169f555e 100644 --- a/application/Espo/Core/Utils/FieldManager.php +++ b/application/Espo/Core/Utils/FieldManager.php @@ -91,13 +91,17 @@ class FieldManager $res = true; if (isset($fieldDef['label'])) { - $res &= $this->setLabel($name, $fieldDef['label'], $scope); + $this->setLabel($name, $fieldDef['label'], $scope); } if (isset($fieldDef['type']) && $fieldDef['type'] == 'enum') { if (isset($fieldDef['translatedOptions'])) { - $res &= $this->setTranslatedOptions($name, $fieldDef['translatedOptions'], $scope); - } + $this->setTranslatedOptions($name, $fieldDef['translatedOptions'], $scope); + } + } + + if (isset($fieldDef['label']) || isset($fieldDef['translatedOptions'])) { + $res &= $this->getLanguage()->save(); } if ($this->isDefsChanged($name, $fieldDef, $scope)) { @@ -119,10 +123,9 @@ class FieldManager ); $res = $this->getMetadata()->delete($unsets, $this->metadataType, $scope); + $res &= $this->deleteLabel($name, $scope); - $this->deleteLabel($name, $scope); - - return $res; + return (bool) $res; } protected function setEntityDefs($name, $fieldDef, $scope) @@ -147,7 +150,8 @@ class FieldManager protected function deleteLabel($name, $scope) { - return $this->getLanguage()->delete($name, 'fields', $scope); + $this->getLanguage()->delete($name, 'fields', $scope); + return $this->getLanguage()->save(); } protected function getFieldDef($name, $scope) diff --git a/application/Espo/Core/Utils/Language.php b/application/Espo/Core/Utils/Language.php index 7bdf4361e1..6a5d504be4 100644 --- a/application/Espo/Core/Utils/Language.php +++ b/application/Espo/Core/Utils/Language.php @@ -38,14 +38,11 @@ class Language * * @var array */ - private $allData = array(); + private $data = array(); - /** - * Data of current language - * - * @var array - */ - private $data = null; + private $deletedData = array(); + + private $changedData = array(); private $name = 'i18n'; @@ -175,7 +172,6 @@ class Language return $value; } - public function get($key = null, $returns = null) { $data = $this->getData(); @@ -187,12 +183,64 @@ class Language return Util::getValueByKey($data, $key, $returns); } - public function getAll() { return $this->get(); } + /** + * Save changes + * + * @return bool + */ + public function save() + { + $path = $this->paths['customPath']; + $currentLanguage = $this->getLanguage(); + + /*echo '
';
+        print_r($this->changedData);
+        print_r($this->deletedData);
+        exit;*/
+
+        $result = true;
+        if (!empty($this->changedData)) {
+            foreach ($this->changedData as $scope => $data) {
+                if (!empty($data)) {
+                    $result &= $this->getFileManager()->mergeContents(array($path, $currentLanguage, $scope.'.json'), $data, true);
+                }
+            }
+        }
+
+        if (!empty($this->deletedData)) {
+            foreach ($this->deletedData as $scope => $unsetData) {
+                if (!empty($unsetData)) {
+                    $result &= $this->getFileManager()->unsetContents(array($path, $currentLanguage, $scope.'.json'), $unsetData, true);
+                }
+            }
+        }
+
+        if ($result == false) {
+            throw new Error("Error saving languages. See log file for details.");
+        }
+
+        $this->clearChanges();
+        $this->init(true);
+
+        return (bool) $result;
+    }
+
+    /**
+     * Clear unsaved changes
+     *
+     * @return void
+     */
+    public function clearChanges()
+    {
+        $this->changedData = array();
+        $this->deletedData = array();
+    }
+
     /**
      * Get data of Unifier language files
      *
@@ -200,44 +248,64 @@ class Language
      */
     protected function getData()
     {
-        if (!isset($this->data)) {
+        $currentLanguage = $this->getLanguage();
+        if (!isset($this->data[$currentLanguage])) {
             $this->init();
         }
 
-        return $this->data;
+        return $this->data[$currentLanguage];
     }
 
+    /**
+     * Set/change a label
+     * @param string | array $label
+     * @param mixed $value
+     * @param string $category
+     * @param string $scope
+     */
     public function set($label, $value, $category = 'labels', $scope = 'Global')
     {
-        $path = $this->paths['customPath'];
-        $currentLanguage = $this->getLanguage();
-
-        $data = $this->normalizeDefs($label, $value, $category);
-
-        $result = $this->getFileManager()->mergeContents(array($path, $currentLanguage, $scope.'.json'), $data, true);
-        if ($result === false) {
-            throw new Error("Error saving languages. See log file for details.");
+        if (is_array($label)) {
+            foreach ($label as $rowLabel => $rowValue) {
+                $this->set($rowLabel, $rowValue, $category, $scope);
+            }
+            return;
         }
 
-        $this->init(true);
+        $this->changedData[$scope][$category][$label] = $value;
 
-        return $result;
+        $currentLanguage = $this->getLanguage();
+        $this->data[$currentLanguage][$scope][$category][$label] = $value;
     }
 
+    /**
+     * Remove a label
+     *
+     * @param  string $label
+     * @param  string $category
+     * @param  string $scope
+     *
+     * @return void
+     */
     public function delete($label, $category = 'labels', $scope = 'Global')
     {
-        $path = $this->paths['customPath'];
+        if (is_array($label)) {
+            foreach ($label as $rowLabel) {
+                $this->delete($rowLabel, $category, $scope);
+            }
+            return;
+        }
+
+        $this->deletedData[$scope][$category][] = $label;
+
         $currentLanguage = $this->getLanguage();
+        if (isset($this->data[$currentLanguage][$scope][$category][$label])) {
+            unset($this->data[$currentLanguage][$scope][$category][$label]);
+        }
 
-        $unsets = array(
-            $category => $label,
-        );
-
-        $result = $this->getFileManager()->unsetContents(array($path, $currentLanguage, $scope.'.json'), $unsets, true);
-
-        $this->init(true);
-
-        return $result;
+        if (isset($this->changedData[$scope][$category][$label])) {
+            unset($this->changedData[$scope][$category][$label]);
+        }
     }
 
     protected function init($reload = false)
@@ -252,7 +320,7 @@ class Language
                     $i18nData = Util::merge($fullData[$this->defaultLanguage], $i18nData);
                 }
 
-                $this->allData[$i18nName] = $i18nData;
+                $this->data[$i18nName] = $i18nData;
 
                 if ($this->getConfig()->get('useCache')) {
                     $i18nCacheFile = str_replace('{*}', $i18nName, $this->cacheFile);
@@ -266,34 +334,8 @@ class Language
         }
 
         $currentLanguage = $this->getLanguage();
-        if (empty($this->allData[$currentLanguage])) {
-            $this->allData[$currentLanguage] = $this->getFileManager()->getContents($this->getLangCacheFile());
+        if (empty($this->data[$currentLanguage])) {
+            $this->data[$currentLanguage] = $this->getFileManager()->getContents($this->getLangCacheFile());
         }
-
-        $this->data = $this->allData[$currentLanguage];
     }
-
-    protected function normalizeDefs($label, $value, $category)
-    {
-        if (!is_array($label)) {
-            $label = array(
-                $label => $value,
-            );
-        }
-
-        $data = array(
-            $category => $label,
-        );
-
-        return $data;
-    }
-
-
-
-
-
-
-
-
-
 }
diff --git a/tests/Espo/Core/Utils/LanguageTest.php b/tests/Espo/Core/Utils/LanguageTest.php
index 1ab1f71a05..d9593c3108 100644
--- a/tests/Espo/Core/Utils/LanguageTest.php
+++ b/tests/Espo/Core/Utils/LanguageTest.php
@@ -204,7 +204,22 @@ class LanguageTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals($result, $this->object->translate('language.en_US', 'options'));
     }
 
+    public function testSet()
+    {
+        $label = 'TEST';
+        $this->object->set('label', $label, 'fields', 'User');
+        $this->assertEquals($label, $this->object->translate('label', 'fields', 'User'));
 
+        $label2 = 'TEST2';
+        $this->object->set('name', $label2, 'fields', 'User');
+        $this->assertEquals($label2, $this->object->translate('name', 'fields', 'User'));
+
+        $label3 = 'TEST3';
+        $this->object->set('name', $label3, 'fields', 'Account');
+        $this->assertEquals($label3, $this->object->translate('name', 'fields', 'Account'));
+
+        $this->reflection->invokeMethod('init', array(true));
+    }
 
 }
 

From 2cb2d2cc2d19456da398003d49b1c34f5f4f6c0a Mon Sep 17 00:00:00 2001
From: Taras Machyshyn 
Date: Fri, 9 Jan 2015 17:38:39 +0200
Subject: [PATCH 3/4] bug fixing in Util

---
 application/Espo/Core/Utils/Util.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/application/Espo/Core/Utils/Util.php b/application/Espo/Core/Utils/Util.php
index a94f34ba92..f752d0f693 100644
--- a/application/Espo/Core/Utils/Util.php
+++ b/application/Espo/Core/Utils/Util.php
@@ -380,7 +380,7 @@ class Util
                     $unsetElem = $currVal . "['{$lastKey}']";
 
                     $currVal = "
-                    if (isset({$unsetElem}) || ( is_array({$currVal}) && array_key_exists({$lastKey}, {$currVal}) )) {
+                    if (isset({$unsetElem}) || ( is_array({$currVal}) && array_key_exists('{$lastKey}', {$currVal}) )) {
                         unset({$unsetElem});
                     } ";
                     eval($currVal);

From feb8a300d9f636f7f62f9280e5c8209fa8ee8319 Mon Sep 17 00:00:00 2001
From: Taras Machyshyn 
Date: Fri, 9 Jan 2015 17:43:28 +0200
Subject: [PATCH 4/4] remove test code

---
 application/Espo/Core/Utils/Language.php | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/application/Espo/Core/Utils/Language.php b/application/Espo/Core/Utils/Language.php
index 6a5d504be4..4e8661d2bb 100644
--- a/application/Espo/Core/Utils/Language.php
+++ b/application/Espo/Core/Utils/Language.php
@@ -198,11 +198,6 @@ class Language
         $path = $this->paths['customPath'];
         $currentLanguage = $this->getLanguage();
 
-        /*echo '
';
-        print_r($this->changedData);
-        print_r($this->deletedData);
-        exit;*/
-
         $result = true;
         if (!empty($this->changedData)) {
             foreach ($this->changedData as $scope => $data) {