Add 'readonly' attribute to schema fields
authorColeman Watts <coleman@civicrm.org>
Thu, 18 Feb 2021 15:41:28 +0000 (10:41 -0500)
committerColeman Watts <coleman@civicrm.org>
Thu, 18 Feb 2021 15:41:28 +0000 (10:41 -0500)
For core fields, applies to primaryKey fields and fields tagged <readonly>.
For custom fields, this comes through via the 'is_view' property.

This will help autogenerated forms to know whether a field is appropriate to show to the user.

CRM/Contact/DAO/Contact.php
CRM/Core/CodeGen/Specification.php
Civi/Api4/Generic/BasicGetFieldsAction.php
Civi/Api4/Service/Spec/FieldSpec.php
Civi/Api4/Service/Spec/Provider/CustomValueSpecProvider.php
Civi/Api4/Service/Spec/SpecFormatter.php
ext/search/ang/crmSearchActions/crmSearchActionUpdate.ctrl.js
xml/schema/Contact/Contact.xml
xml/templates/dao.tpl

index 95f45151b52ddf5dfc53f0f9d0dcc67d3e4a18bf..1ffa441fb1a7d8de1afa1ec8d5ca6ef4b7ecb32e 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Generated from xml/schema/CRM/Contact/Contact.xml
  * DO NOT EDIT.  Generated by CRM_Core_CodeGen
- * (GenCodeChecksum:d72db3da5f0a3646c35296c43880b425)
+ * (GenCodeChecksum:cfed69c9e09acada46340971415ec767)
  */
 
 /**
@@ -465,6 +465,7 @@ class CRM_Contact_DAO_Contact extends CRM_Core_DAO {
           'html' => [
             'type' => 'Number',
           ],
+          'readonly' => TRUE,
           'add' => '1.1',
         ],
         'contact_type' => [
@@ -490,6 +491,7 @@ class CRM_Contact_DAO_Contact extends CRM_Core_DAO {
             'labelColumn' => 'label',
             'condition' => 'parent_id IS NULL',
           ],
+          'readonly' => TRUE,
           'add' => '1.1',
         ],
         'contact_sub_type' => [
@@ -699,6 +701,7 @@ class CRM_Contact_DAO_Contact extends CRM_Core_DAO {
           'html' => [
             'type' => 'Text',
           ],
+          'readonly' => TRUE,
           'add' => '1.1',
         ],
         'display_name' => [
@@ -717,6 +720,7 @@ class CRM_Contact_DAO_Contact extends CRM_Core_DAO {
           'html' => [
             'type' => 'Text',
           ],
+          'readonly' => TRUE,
           'add' => '1.1',
         ],
         'nick_name' => [
@@ -869,6 +873,7 @@ class CRM_Contact_DAO_Contact extends CRM_Core_DAO {
           'entity' => 'Contact',
           'bao' => 'CRM_Contact_BAO_Contact',
           'localizable' => 0,
+          'readonly' => TRUE,
           'add' => '1.1',
         ],
         'api_key' => [
@@ -1528,6 +1533,7 @@ class CRM_Contact_DAO_Contact extends CRM_Core_DAO {
           'html' => [
             'label' => ts("Modified Date"),
           ],
+          'readonly' => TRUE,
           'add' => '4.3',
         ],
       ];
index 015b56560c42a64aee80d4ba20de0a8ffdd9d01b..0cf18432865b0dd41934e62704f7e9074508e6c4 100644 (file)
@@ -317,8 +317,6 @@ class CRM_Core_CodeGen_Specification {
         $field['cols'] = isset($fieldXML->html) ? $this->value('cols', $fieldXML->html) : NULL;
         break;
 
-      break;
-
       case 'datetime':
         $field['sqlType'] = $field['phpType'] = $type;
         $field['crmType'] = 'CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME';
@@ -377,6 +375,7 @@ class CRM_Core_CodeGen_Specification {
     }
     $field['headerPattern'] = $this->value('headerPattern', $fieldXML);
     $field['dataPattern'] = $this->value('dataPattern', $fieldXML);
+    $field['readonly'] = $this->value('readonly', $fieldXML);
     $field['uniqueName'] = $this->value('uniqueName', $fieldXML);
     $field['uniqueTitle'] = $this->value('uniqueTitle', $fieldXML);
     $field['serialize'] = $this->value('serialize', $fieldXML);
index 7f4faf7ae9885ea7d6831403b13b5b01e2b2832c..49af587ffb2dfe5beb53257cff2ba71187225909 100644 (file)
@@ -125,6 +125,7 @@ class BasicGetFieldsAction extends BasicGetAction {
         'title' => empty($field['name']) ? NULL : ucwords(str_replace('_', ' ', $field['name'])),
         'entity' => $this->getEntityName(),
         'required' => FALSE,
+        'readonly' => FALSE,
         'options' => !empty($field['pseudoconstant']),
         'data_type' => \CRM_Utils_Array::value('type', $field, 'String'),
       ], array_flip($fields));
@@ -295,6 +296,10 @@ class BasicGetFieldsAction extends BasicGetAction {
         'name' => 'entity',
         'data_type' => 'String',
       ],
+      [
+        'name' => 'readonly',
+        'data_type' => 'Boolean',
+      ],
     ];
   }
 
index 0d503ad748b29d15fd346989b1d39000d8709a52..3aa807a5725715847070e5a7e6c3bf1ee1ab1a30 100644 (file)
@@ -112,6 +112,11 @@ class FieldSpec {
    */
   protected $columnName;
 
+  /**
+   * @var bool
+   */
+  protected $readonly = FALSE;
+
   /**
    * Aliases for the valid data types
    *
@@ -361,6 +366,23 @@ class FieldSpec {
     return $this;
   }
 
+  /**
+   * @return bool
+   */
+  public function getreadonly() {
+    return $this->readonly;
+  }
+
+  /**
+   * @param bool $readonly
+   * @return $this
+   */
+  public function setreadonly($readonly) {
+    $this->readonly = (bool) $readonly;
+
+    return $this;
+  }
+
   /**
    * @return string|NULL
    */
index 19c4cdbb6c9a091a41c97aaa3ef7208cb2ba6436..5e61b2a54f43dc4fb303762ed8a65f93cc132fbf 100644 (file)
@@ -32,12 +32,14 @@ class CustomValueSpecProvider implements Generic\SpecProviderInterface {
     if ($action !== 'create') {
       $idField = new FieldSpec('id', $spec->getEntity(), 'Integer');
       $idField->setTitle(ts('Custom Value ID'));
+      $idField->setreadonly(TRUE);
       $spec->addFieldSpec($idField);
     }
     $entityField = new FieldSpec('entity_id', $spec->getEntity(), 'Integer');
     $entityField->setTitle(ts('Entity ID'));
     $entityField->setRequired($action === 'create');
     $entityField->setFkEntity('Contact');
+    $entityField->setreadonly(TRUE);
     $spec->addFieldSpec($entityField);
   }
 
index 9e00ba09f59cadadeab394d66f1ea5a12f6bb1dc..a860e60b0bb61d0c073fb89794269ef535cbc5ad 100644 (file)
@@ -67,6 +67,7 @@ class SpecFormatter {
       $field->setHelpPre($data['help_pre'] ?? NULL);
       $field->setHelpPost($data['help_post'] ?? NULL);
       $field->setOptions(self::customFieldHasOptions($data));
+      $field->setreadonly($data['is_view']);
     }
     else {
       $name = $data['name'] ?? NULL;
@@ -75,6 +76,7 @@ class SpecFormatter {
       $field->setTitle($data['title'] ?? NULL);
       $field->setLabel($data['html']['label'] ?? NULL);
       $field->setOptions(!empty($data['pseudoconstant']));
+      $field->setreadonly(!empty($data['readonly']));
     }
     $field->setSerialize($data['serialize'] ?? NULL);
     $field->setDefaultValue($data['default'] ?? NULL);
index 0a3af265eaac993de40e48ebb98d94863207f50d..b55b605d2723077b581e3018fae378125dfb5140 100644 (file)
     this.add = null;
     this.fields = null;
 
-    crmApi4(model.entity, 'getFields', {action: 'update', loadOptions: ['id', 'name', 'label', 'description', 'color', 'icon']})
-      .then(function(fields) {
+    crmApi4(model.entity, 'getFields', {
+      action: 'update',
+      loadOptions: ['id', 'name', 'label', 'description', 'color', 'icon'],
+      where: [["readonly", "=", false]],
+    }).then(function(fields) {
         ctrl.fields = fields;
       });
 
@@ -58,9 +61,6 @@
         if (fieldInUse(item.name)) {
           formatted.disabled = true;
         }
-        if (item.name !== 'id') {
-          result.push(formatted);
-        }
       }, []);
       return {results: results};
     };
index b89166a2e9c02c86b13fa86f3576df384f60fb6f..e539c2805c9201809c95fe690eaea5c092e8cc95 100644 (file)
@@ -48,6 +48,7 @@
     <html>
       <type>Select</type>
     </html>
+    <readonly>true</readonly>
     <add>1.1</add>
     <change>3.1</change>
     <contactType>null</contactType>
       <type>Text</type>
       <size>30</size>
     </html>
-
+    <readonly>true</readonly>
     <export>true</export>
     <comment>Name used for sorting different contact types</comment>
     <add>1.1</add>
       <type>Text</type>
       <size>30</size>
     </html>
-
+    <readonly>true</readonly>
     <export>true</export>
     <comment>Formatted name representing preferred format for display/print/other output.</comment>
     <add>1.1</add>
     <add>1.1</add>
     <change>1.5</change>
     <export>true</export>
+    <readonly>true</readonly>
   </field>
   <index>
     <name>index_hash</name>
     <html>
       <label>Modified Date</label>
     </html>
+    <readonly>true</readonly>
     <add>4.3</add>
   </field>
   <index>
index e9e94f70c33d3dcc4c6c13730ccc134573392434..c5bf31fb01626019cbf4d748e88709ff0784b46a 100644 (file)
@@ -201,6 +201,9 @@ class {$table.className} extends CRM_Core_DAO {ldelim}
 {/if}
 {if $field.pseudoconstant}
   'pseudoconstant' => {$field.pseudoconstant|@print_array},
+{/if}
+{if $field.readonly || $field.name === $table.primaryKey.name}
+  'readonly' => TRUE,
 {/if}
   'add' => {if $field.add}'{$field.add}'{else}NULL{/if},
 ),