Attempt to fix paging on contact summary
[civicrm-core.git] / CRM / Utils / JS.php
index 06331b5a2c343b32f68cf200b58ee02b2a4da0e6..5110ac188fea73865faf034a75990dc29749442d 100644 (file)
@@ -143,11 +143,14 @@ class CRM_Utils_JS {
    */
   public static function decode($js) {
     $js = trim($js);
-    if ($js[0] === "'" || $js[0] === '"') {
+    $first = substr($js, 0, 1);
+    $last = substr($js, -1);
+    if ($last === $first && ($first === "'" || $first === '"')) {
       // Use a temp placeholder for escaped backslashes
-      return str_replace(['\\\\', "\\'", '\\"', '\\&', '\\/', '**backslash**'], ['**backslash**', "'", '"', '&', '/', '\\'], substr($js, 1, -1));
+      $backslash = chr(0) . 'backslash' . chr(0);
+      return str_replace(['\\\\', "\\'", '\\"', '\\&', '\\/', $backslash], [$backslash, "'", '"', '&', '/', '\\'], substr($js, 1, -1));
     }
-    if ($js[0] === '{' || $js[0] === '[') {
+    if (($first === '{' && $last === '}') || ($first === '[' && $last === ']')) {
       $obj = self::getRawProps($js);
       foreach ($obj as $idx => $item) {
         $obj[$idx] = self::decode($item);
@@ -157,6 +160,35 @@ class CRM_Utils_JS {
     return json_decode($js);
   }
 
+  /**
+   * Encodes a variable to js notation (not strict json) suitable for e.g. an angular attribute.
+   *
+   * Like json_encode() but the output looks more like native javascript,
+   * with single quotes around strings and no unnecessary quotes around object keys.
+   *
+   * Ex input: [
+   *   'a' => 'Apple',
+   *   'b' => 'Banana',
+   *   'c' => [1, 2, 3],
+   * ]
+   * Ex output: {a: 'Apple', b: 'Banana', c: [1, 2, 3]}
+   *
+   * @param mixed $value
+   * @return string
+   */
+  public static function encode($value) {
+    if (is_array($value)) {
+      return self::writeObject($value, TRUE);
+    }
+    $result = json_encode($value, JSON_UNESCAPED_SLASHES);
+    // Convert double-quotes around string to single quotes
+    if (is_string($value) && substr($result, 0, 1) === '"' && substr($result, -1) === '"') {
+      $backslash = chr(0) . 'backslash' . chr(0);
+      return "'" . str_replace(['\\\\', '\\"', "'", $backslash], [$backslash, '"', "\\'", '\\\\'], substr($result, 1, -1)) . "'";
+    }
+    return $result;
+  }
+
   /**
    * Gets the properties of a javascript object/array WITHOUT decoding them.
    *
@@ -256,7 +288,7 @@ class CRM_Utils_JS {
     $brackets = isset($obj[0]) && array_keys($obj) === range(0, count($obj) - 1) ? ['[', ']'] : ['{', '}'];
     foreach ($obj as $key => $val) {
       if ($encodeValues) {
-        $val = json_encode($val, JSON_UNESCAPED_SLASHES);
+        $val = self::encode($val);
       }
       if ($brackets[0] == '{') {
         // Enclose the key in quotes unless it is purely alphanumeric