--- /dev/null
+<?php
+
+require_once 'CiviTest/CiviUnitTestCase.php';
+
+/**
+ * Class for testing new DAO meet required standards.
+ *
+ * Class CRM_Core_DAOTest
+ */
+class CRM_Core_DAOConformanceTest extends CiviUnitTestCase {
+
+ /**
+ * Check all fields have defined titles.
+ *
+ * @dataProvider getAllDAO
+ */
+ public function testFieldsHaveTitles($class) {
+ $dao = new $class();
+ $fields = $dao->fields();
+ foreach ($fields as $name => $field) {
+ $this->assertArrayHasKey('title', $field, "A title must be defined for $name in $class");
+ }
+ }
+
+ /**
+ * Get all DAO classes.
+ */
+ public function getAllDAO() {
+ $classList = CRM_Core_DAO_AllCoreTables::getClasses();
+ $return = array();
+ $notYetTitledDAO = $this->getClassesWithoutTitlesYet();
+ foreach ($classList as $class) {
+ if (!in_array($class, $notYetTitledDAO)) {
+ $return[] = array($class);
+ }
+ }
+ return $return;
+ }
+
+ /**
+ * Classes that do not yet conform to expectation they will have a title for each field.
+ *
+ * When we start enforcing a new standard we have to grandfather it in & these classes need titles added.
+ *
+ * Note that we want titles so that things like views integration can rely on using them and so the person
+ * introducing the DAO is responsible for it's titles - not the person who adds it to the api later.
+ */
+ public function getClassesWithoutTitlesYet() {
+ return array(
+ 'CRM_Contact_DAO_ACLContactCache',
+ 'CRM_Core_DAO_Managed',
+ 'CRM_Core_DAO_PreferencesDate',
+ 'CRM_Event_Cart_DAO_EventInCart',
+ 'CRM_PCP_DAO_PCPBlock',
+ 'CRM_Case_DAO_CaseActivity',
+ 'CRM_Core_DAO_Discount',
+ 'CRM_Price_DAO_PriceSetEntity',
+ 'CRM_Case_DAO_CaseContact',
+ 'CRM_Contribute_DAO_Widget',
+ 'CRM_Contribute_DAO_PremiumsProduct',
+ 'CRM_Core_DAO_Persistent',
+ 'CRM_Mailing_Event_DAO_TrackableURLOpen',
+ 'CRM_Mailing_Event_DAO_Reply',
+ 'CRM_Mailing_Event_DAO_Delivered',
+ 'CRM_Mailing_Event_DAO_Forward',
+ 'CRM_Mailing_Event_DAO_Bounce',
+ 'CRM_Mailing_Event_DAO_Opened',
+ 'CRM_Mailing_DAO_Spool',
+ 'CRM_Mailing_DAO_TrackableURL',
+ 'CRM_Contact_DAO_GroupContactCache',
+ 'CRM_Contact_DAO_SubscriptionHistory',
+ 'CRM_Core_DAO_Menu',
+ 'CRM_Core_DAO_Log',
+ 'CRM_Core_DAO_EntityFile',
+ 'CRM_PCP_DAO_PCP',
+ 'CRM_Queue_DAO_QueueItem',
+ 'CRM_Pledge_DAO_PledgeBlock',
+ 'CRM_Friend_DAO_Friend',
+ 'CRM_Dedupe_DAO_Exception',
+ 'CRM_Dedupe_DAO_Rule',
+ 'CRM_Dedupe_DAO_RuleGroup',
+ 'CRM_Event_Cart_DAO_Cart',
+ 'CRM_Campaign_DAO_CampaignGroup',
+ 'CRM_Financial_DAO_EntityFinancialAccount',
+ 'CRM_Financial_DAO_Currency',
+ 'CRM_Mailing_DAO_BouncePattern',
+ 'CRM_Mailing_DAO_BounceType',
+ );
+ }
+
+}
<add>1.6</add>
<field>
<name>id</name>
+ <title>Cache ID</title>
<type>int unsigned</type>
<required>true</required>
<comment>Unique table ID</comment>
</primaryKey>
<field>
<name>contact_id</name>
+ <title>Cache Contact</title>
<type>int unsigned</type>
<comment>Foreign Key to Contact</comment>
<add>1.6</add>
</foreignKey>
<field>
<name>acl_id</name>
+ <title>Cache ACL</title>
<type>int unsigned</type>
<required>true</required>
<comment>Foreign Key to ACL</comment>
</index>
<field>
<name>modified_date</name>
+ <title>Cache Modified Date</title>
<type>date</type>
<comment>When was this cache entry last modified</comment>
<add>1.6</add>
<add>3.1</add>
<field>
<name>id</name>
+ <title>ACL Contact Cache ID</title>
<type>int unsigned</type>
<required>true</required>
<comment>primary key</comment>
<add>3.4</add>
<field>
<name>id</name>
+ <title>Action Schedule ID</title>
<type>int unsigned</type>
<required>true</required>
<add>3.4</add>
</primaryKey>
<field>
<name>contact_id</name>
+ <title>Action Schedule Contact ID</title>
<type>int unsigned</type>
<comment>FK to Contact ID</comment>
<add>3.4</add>
</foreignKey>
<field>
<name>entity_id</name>
+ <title>Entity ID</title>
<type>int unsigned</type>
<required>true</required>
<comment>FK to id of the entity that the action was performed on. Pseudo - FK.</comment>
<field>
<name>entity_table</name>
<type>varchar</type>
+ <title>Entity Table</title>
<length>255</length>
<comment>name of the entity table for the above id, e.g. civicrm_activity, civicrm_participant</comment>
<add>3.4</add>
</dynamicForeignKey>
<field>
<name>action_schedule_id</name>
+ <title>Schedule</title>
<type>int unsigned</type>
<required>true</required>
<comment>FK to the action schedule that this action originated from.</comment>
</foreignKey>
<field>
<name>action_date_time</name>
+ <title>Action Date And Time</title>
<type>datetime</type>
<comment>date time that the action was performed on.</comment>
<add>3.4</add>
</field>
<field>
<name>is_error</name>
+ <title>Error?</title>
<type>boolean</type>
<default>0</default>
<comment>Was there any error sending the reminder?</comment>
</field>
<field>
<name>message</name>
+ <title>Message</title>
<type>text</type>
<comment>Description / text in case there was an error encountered.</comment>
<add>3.4</add>
</field>
<field>
<name>repetition_number</name>
+ <title>Repetition Number</title>
<type>int unsigned</type>
<comment>Keeps track of the sequence number of this repetition.</comment>
<add>3.4</add>
</field>
<field>
<name>reference_date</name>
+ <title>Reference Date</title>
<type>date</type>
<default>NULL</default>
<comment>Stores the date from the entity which triggered this reminder action (e.g. membership.end_date for most membership renewal reminders)</comment>
<add>3.4</add>
<field>
<name>id</name>
+ <title>Action Mapping ID</title>
<type>int unsigned</type>
<required>true</required>
<add>3.4</add>
</primaryKey>
<field>
<name>entity</name>
+ <title>Action Mapping Entity</title>
<type>varchar</type>
<length>64</length>
<comment>Entity for which the reminder is created</comment>
</field>
<field>
<name>entity_value</name>
+ <title>Action Mapping Entity Value</title>
<type>varchar</type>
<length>64</length>
<comment>Entity value</comment>
</field>
<field>
<name>entity_value_label</name>
+ <title>Value Label</title>
<type>varchar</type>
<length>64</length>
<comment>Entity value label</comment>
</field>
<field>
<name>entity_status</name>
+ <title>Status</title>
<type>varchar</type>
<length>64</length>
<comment>Entity status</comment>
</field>
<field>
<name>entity_status_label</name>
+ <title>Status Label</title>
<type>varchar</type>
<length>64</length>
<comment>Entity status label</comment>
</field>
<field>
<name>entity_date_start</name>
- <type>varchar</type>
+ <title>Entity Start Date</title>
+ <type>varchar</type>
<length>64</length>
<comment>Entity date</comment>
<add>3.4</add>
</field>
<field>
<name>entity_date_end</name>
+ <title>Entity End Date</title>
<type>varchar</type>
<length>64</length>
<comment>Entity date</comment>
</field>
<field>
<name>entity_recipient</name>
+ <title>Entity Recipient</title>
<type>varchar</type>
<length>64</length>
<comment>Entity recipient</comment>
<add>3.2</add>
<field>
<name>id</name>
+ <title>Address Format ID</title>
<type>int unsigned</type>
<required>true</required>
<comment>Address Format Id</comment>
<add>1.1</add>
<field>
<name>id</name>
+ <title>County ID</title>
<type>int unsigned</type>
<required>true</required>
<comment>County ID</comment>
</field>
<field>
<name>state_province_id</name>
+ <title>State</title>
<type>int unsigned</type>
<required>true</required>
<comment>ID of State/Province that County belongs</comment>
<add>4.3</add>
<onDelete>CASCADE</onDelete>
</foreignKey>
- <dynamicForeignKey>
- <idColumn>entity_id</idColumn>
- <typeColumn>entity_table</typeColumn>
- </dynamicForeignKey>
<index>
<name>index_entity_option_id</name>
<fieldName>entity_table</fieldName>
<log>false</log>
<field>
<name>id</name>
+ <title>Managed ID</title>
<type>int unsigned</type>
<required>true</required>
<comment>Surrogate Key</comment>
<log>true</log>
<field>
<name>id</name>
+ <title>Date Preference ID</title>
<type>int unsigned</type>
<required>true</required>
<add>2.0</add>
</primaryKey>
<field>
<name>name</name>
+ <title>Date Preference Name</title>
<type>varchar</type>
<length>64</length>
<required>true</required>
<add>3.4</add>
<field>
<name>id</name>
+ <title>Prev Next Cache ID</title>
<type>int unsigned</type>
<required>true</required>
<add>3.4</add>
</primaryKey>
<field>
<name>entity_table</name>
+ <title>Prev Next Entity Table</title>
<type>varchar</type>
<length>64</length>
<comment>physical tablename for entity being joined to discount, e.g. civicrm_event</comment>
</field>
<field>
<name>entity_id1</name>
+ <title>Prev Next Entity ID 1</title>
<type>int unsigned</type>
<required>true</required>
<comment>FK to entity table specified in entity_table column.</comment>
</field>
<field>
<name>entity_id2</name>
+ <title>Prev Next Entity ID 2</title>
<type>int unsigned</type>
<required>true</required>
<comment>FK to entity table specified in entity_table column.</comment>
</field>
<field>
<name>cacheKey</name>
+ <title>Cache Key</title>
<type>varchar</type>
<length>255</length>
<comment>Unique path name for cache element of the searched item</comment>
</field>
<field>
<name>data</name>
+ <title>Prev Next Data</title>
<type>longtext</type>
<comment>cached snapshot of the serialized data</comment>
<add>3.4</add>
</field>
<field>
<name>is_selected</name>
+ <title>Is Selected</title>
<type>boolean</type>
<default>0</default>
<add>4.2</add>
<add>1.1</add>
<field>
<name>id</name>
+ <title>State ID</title>
<type>int unsigned</type>
<required>true</required>
<comment>State/Province ID</comment>
</field>
<field>
<name>country_id</name>
+ <title>County</title>
<type>int unsigned</type>
<required>true</required>
<comment>ID of Country that State/Province belong</comment>
<add>1.8</add>
<field>
<name>id</name>
+ <title>Timezone ID</title>
<type>int unsigned</type>
<required>true</required>
<comment>Timezone Id</comment>
</primaryKey>
<field>
<name>name</name>
+ <title>Timezone Name</title>
<type>varchar</type>
<length>64</length>
<comment>Timezone full name</comment>
</field>
<field>
<name>abbreviation</name>
+ <title>Timezone Abbreviation</title>
<type>char</type>
<length>3</length>
<comment>ISO Code for timezone abbreviation</comment>
</field>
<field>
<name>gmt</name>
+ <title>GMT Name of Timezone</title>
<type>varchar</type>
<length>64</length>
<comment>GMT name of the timezone</comment>
</field>
<field>
<name>offset</name>
+ <title>GMT Offset</title>
<type>int</type>
<comment></comment>
<add>1.8</add>
</field>
<field>
<name>country_id</name>
+ <title>Country</title>
<type>int unsigned</type>
<required>true</required>
<comment>Country Id</comment>
</dynamicForeignKey>
<index>
<name>index_entity</name>
- <add>1.3</add>
<fieldName>entity_table</fieldName>
<fieldName>entity_id</fieldName>
<add>1.3</add>
<add>4.3</add>
<comment>Links to an id in the entity_table, such as vid in civicrm_financial_type</comment>
</field>
- <dynamicForeignKey>
+ <dynamicForeignKey>
<idColumn>entity_id</idColumn>
<typeColumn>entity_table</typeColumn>
<add>4.3</add>
<archive>true</archive>
<field>
<name>id</name>
+ <title>Mailing Opened ID</title>
<type>int unsigned</type>
<required>true</required>
</field>
</primaryKey>
<field>
<name>event_queue_id</name>
+ <title>Event Queue</title>
<type>int unsigned</type>
<required>true</required>
<comment>FK to EventQueue</comment>
<archive>true</archive>
<field>
<name>id</name>
+ <title>Reply ID</title>
<type>int unsigned</type>
<required>true</required>
</field>
</primaryKey>
<field>
<name>event_queue_id</name>
+ <title>Event Queue</title>
<type>int unsigned</type>
<required>true</required>
<comment>FK to EventQueue</comment>
</foreignKey>
<field>
<name>time_stamp</name>
+ <title>Reply Timestamp</title>
<type>datetime</type>
<required>true</required>
<comment>When this reply event occurred.</comment>
<archive>true</archive>
<field>
<name>id</name>
+ <title>Trackable URL ID</title>
<type>int unsigned</type>
<required>true</required>
</field>
</primaryKey>
<field>
<name>url</name>
- <type>text</type>
+ <title>Url</title>
+ <type>text</type>
<required>true</required>
<comment>The URL to be tracked.</comment>
</field>
<field>
<name>mailing_id</name>
+ <title>Mailing</title>
<type>int unsigned</type>
<required>true</required>
<comment>FK to the mailing</comment>