Merge pull request #11752 from colemanw/CKEditor
authorSeamus Lee <seamuslee001@gmail.com>
Mon, 5 Mar 2018 00:30:50 +0000 (11:30 +1100)
committerGitHub <noreply@github.com>
Mon, 5 Mar 2018 00:30:50 +0000 (11:30 +1100)
CKEditor Advanced Options - Better validation of options

CRM/Admin/Page/CKEditorConfig.php
css/civicrm.css
js/wysiwyg/admin.ckeditor-configurator.js
templates/CRM/Admin/Page/CKEditorConfig.tpl

index 8286bfe06cebbab36206ac053756285d71089e78..3cb00094dd8fa0b755b6e63b86a0e883542c23b1 100644 (file)
@@ -134,6 +134,12 @@ class CRM_Admin_Page_CKEditorConfig extends CRM_Core_Page {
         if ($val != 'true' && $val != 'false' && $val != 'null' && $val[0] != '{' && $val[0] != '[' && !is_numeric($val)) {
           $val = json_encode($val, JSON_UNESCAPED_SLASHES);
         }
+        elseif ($val[0] == '{' || $val[0] == '[') {
+          if (!is_array(json_decode($val, TRUE))) {
+            // Invalid JSON. Do not save.
+            continue;
+          }
+        }
         $pos = strrpos($config, '};');
         $key = preg_replace('/^config_/', 'config.', $key);
         $setting = "\n\t{$key} = {$val};\n";
index c459281324c6b09f3c42b1dd0be0b4ce94745899..6b2fdcd1843ee642af5e6fc55d92febe2acbeba4 100644 (file)
@@ -3124,6 +3124,10 @@ div.m ul#civicrm-menu,
 .crm-container .select2-container[class*=" fa-"]:before {
   display: none;
 }
+.crm-container .select2-results .select2-result.select2-disabled > .select2-result-label {
+  opacity: .6;
+  cursor: default;
+}
 
 /* Restore this property otherwise our css overrides it */
 .select2-search input {
index 17ac199703dd30e823507c46ac1b6bc67717b8c5..6c44806754b7628f144356f1aeac4fb869401c76 100644 (file)
       }
       else {
         $el.after('<span>&nbsp; = &nbsp;<input class="crm-form-text ' + (type==='Number' ? 'eight" type="number"' : 'huge" type="text"') + ' name="config_' + name + '"/></span>');
+        $el.next('span').find('input.crm-form-text[type=text]').change(validateJson);
       }
     } else {
       $el.closest('div').remove();
     }
   }
 
+  function getOptionList() {
+    var list = [];
+    _.forEach(options, function(option) {
+      var opt = _.cloneDeep(option);
+      if ($('[name="config_' + opt.id + '"]').length) {
+        opt.disabled = true;
+      }
+      list.push(opt);
+    });
+    return {results: list, text: 'id'};
+  }
+
+  function validateJson() {
+    var val = $(this).val();
+    $(this).parent().removeClass('crm-error');
+    if (val[0] === '[' || val[0] === '{') {
+      try {
+        JSON.parse(val);
+      } catch (e) {
+        $(this).parent().addClass('crm-error');
+      }
+    }
+  }
+
   function addOption() {
     $('#crm-custom-config-options').append($(configRowTpl({})));
-    $('div:last input.crm-config-option-name', '#crm-custom-config-options').crmSelect2({
-      data: {results: options, text: 'id'},
+    $('.crm-config-option-row:last input.crm-config-option-name', '#crm-custom-config-options').crmSelect2({
+      data: getOptionList,
       formatSelection: function(field) {
         return '<strong>' + field.id + '</strong> (' + field.type + ')';
       },
index 047906aefa13baad20f2148381d1e0e4ae1dd21c..b92082c3bd3be1f86eb9206924a5bcf19e556e2a 100644 (file)
     border-bottom: 0 none;
     padding: 3px 10px 1px !important;
   }
+  .crm-config-option-row span.crm-error:after {
+    font-family: FontAwesome;
+    content: " \f071 Invalid JSON"
+  }
 {/literal}</style>
 {* Force the custom config file to reload by appending a new query string *}
 <script type="text/javascript">
     <div class="crm-block crm-form-block">
       <fieldset>
         <legend>{ts}Advanced Options{/ts}</legend>
-        <div class="description">{ts 1='href="http://docs.ckeditor.com/#!/api/CKEDITOR.config" target="_blank"'}Refer to the <a %1>CKEditor Api Documentation</a> for details.{/ts}</div>
+        <div class="description">{ts 1='href="https://docs.ckeditor.com/ckeditor4/latest/api/CKEDITOR_config.html" target="_blank"'}Refer to the <a %1>CKEditor Api Documentation</a> for details.{/ts}</div>
         <div id="crm-custom-config-options"></div>
       </fieldset>
     </div>