$returnProperties[$householdRelationshipType][$key] = $value;
}
}
+ // @todo - don't use returnProperties above.
+ $processor->setHouseholdMergeReturnProperties($returnProperties[$householdRelationshipType]);
}
}
}
- list($relationQuery, $allRelContactArray) = self::buildRelatedContactArray($selectAll, $ids, $processor, $componentTable, $returnProperties);
+ self::buildRelatedContactArray($selectAll, $ids, $processor, $componentTable);
// make sure the groups stuff is included only if specifically specified
// by the fields param (CRM-1969), else we limit the contacts outputted to only
}
if ($processor->isRelationshipTypeKey($field)) {
- $relDAO = CRM_Utils_Array::value($iterationDAO->contact_id, $allRelContactArray[$field]);
- $relationQuery[$field]->convertToPseudoNames($relDAO);
- self::fetchRelationshipDetails($relDAO, $value, $field, $row);
+ foreach (array_keys($value) as $property) {
+ if ($property === 'location') {
+ // @todo just undo all this nasty location wrangling!
+ foreach ($value['location'] as $locationKey => $locationFields) {
+ foreach (array_keys($locationFields) as $locationField) {
+ $fieldKey = str_replace(' ', '_', $locationKey . '-' . $locationField);
+ $row[$field . '_' . $fieldKey] = $processor->getRelationshipValue($field, $iterationDAO->contact_id, $fieldKey);
+ }
+ }
+ }
+ else {
+ $row[$field . '_' . $property] = $processor->getRelationshipValue($field, $iterationDAO->contact_id, $property);
+ }
+ }
}
else {
$row[$field] = self::getTransformedFieldValue($field, $iterationDAO, $fieldValue, $i18n, $metadata, $paymentDetails, $processor);
$phoneTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Phone', 'phone_type_id');
$imProviders = CRM_Core_PseudoConstant::get('CRM_Core_DAO_IM', 'provider_id');
$i18n = CRM_Core_I18n::singleton();
+ $field = $field . '_';
+
foreach ($value as $relationField => $relationValue) {
if (is_object($relDAO) && property_exists($relDAO, $relationField)) {
$fieldValue = $relDAO->$relationField;
else {
$fieldValue = '';
}
- $field = $field . '_';
$relPrefix = $field . $relationField;
if (is_object($relDAO) && $relationField == 'id') {
* @param $ids
* @param \CRM_Export_BAO_ExportProcessor $processor
* @param $componentTable
- * @param $returnProperties
- *
- * @return array
*/
- protected static function buildRelatedContactArray($selectAll, $ids, $processor, $componentTable, $returnProperties) {
+ protected static function buildRelatedContactArray($selectAll, $ids, $processor, $componentTable) {
$allRelContactArray = $relationQuery = array();
$queryMode = $processor->getQueryMode();
$exportMode = $processor->getExportMode();
- foreach (self::$relationshipTypes as $rel => $dnt) {
- if ($relationReturnProperties = CRM_Utils_Array::value($rel, $returnProperties)) {
- $allRelContactArray[$rel] = array();
- // build Query for each relationship
- $relationQuery[$rel] = new CRM_Contact_BAO_Query(NULL, $relationReturnProperties,
- NULL, FALSE, FALSE, $queryMode
- );
- list($relationSelect, $relationFrom, $relationWhere, $relationHaving) = $relationQuery[$rel]->query();
-
- list($id, $direction) = explode('_', $rel, 2);
- // identify the relationship direction
- $contactA = 'contact_id_a';
- $contactB = 'contact_id_b';
- if ($direction == 'b_a') {
- $contactA = 'contact_id_b';
- $contactB = 'contact_id_a';
- }
- $relIDs = self::getIDsForRelatedContact($ids, $exportMode);
- $relationshipJoin = $relationshipClause = '';
- if (!$selectAll && $componentTable) {
- $relationshipJoin = " INNER JOIN {$componentTable} ctTable ON ctTable.contact_id = {$contactA}";
- }
- elseif (!empty($relIDs)) {
- $relID = implode(',', $relIDs);
- $relationshipClause = " AND crel.{$contactA} IN ( {$relID} )";
- }
+ foreach ($processor->getRelationshipReturnProperties() as $relationshipKey => $relationReturnProperties) {
+ $allRelContactArray[$relationshipKey] = array();
+ // build Query for each relationship
+ $relationQuery = new CRM_Contact_BAO_Query(NULL, $relationReturnProperties,
+ NULL, FALSE, FALSE, $queryMode
+ );
+ list($relationSelect, $relationFrom, $relationWhere, $relationHaving) = $relationQuery->query();
+
+ list($id, $direction) = explode('_', $relationshipKey, 2);
+ // identify the relationship direction
+ $contactA = 'contact_id_a';
+ $contactB = 'contact_id_b';
+ if ($direction == 'b_a') {
+ $contactA = 'contact_id_b';
+ $contactB = 'contact_id_a';
+ }
+ $relIDs = self::getIDsForRelatedContact($ids, $exportMode);
+
+ $relationshipJoin = $relationshipClause = '';
+ if (!$selectAll && $componentTable) {
+ $relationshipJoin = " INNER JOIN {$componentTable} ctTable ON ctTable.contact_id = {$contactA}";
+ }
+ elseif (!empty($relIDs)) {
+ $relID = implode(',', $relIDs);
+ $relationshipClause = " AND crel.{$contactA} IN ( {$relID} )";
+ }
- $relationFrom = " {$relationFrom}
- INNER JOIN civicrm_relationship crel ON crel.{$contactB} = contact_a.id AND crel.relationship_type_id = {$id}
- {$relationshipJoin} ";
-
- //check for active relationship status only
- $today = date('Ymd');
- $relationActive = " AND (crel.is_active = 1 AND ( crel.end_date is NULL OR crel.end_date >= {$today} ) )";
- $relationWhere = " WHERE contact_a.is_deleted = 0 {$relationshipClause} {$relationActive}";
- $relationGroupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($relationQuery[$rel]->_select, "crel.{$contactA}");
- $relationSelect = "{$relationSelect}, {$contactA} as refContact ";
- $relationQueryString = "$relationSelect $relationFrom $relationWhere $relationHaving $relationGroupBy";
-
- $allRelContactDAO = CRM_Core_DAO::executeQuery($relationQueryString);
- while ($allRelContactDAO->fetch()) {
- //FIX Me: Migrate this to table rather than array
- // build the array of all related contacts
- $allRelContactArray[$rel][$allRelContactDAO->refContact] = clone($allRelContactDAO);
+ $relationFrom = " {$relationFrom}
+ INNER JOIN civicrm_relationship crel ON crel.{$contactB} = contact_a.id AND crel.relationship_type_id = {$id}
+ {$relationshipJoin} ";
+
+ //check for active relationship status only
+ $today = date('Ymd');
+ $relationActive = " AND (crel.is_active = 1 AND ( crel.end_date is NULL OR crel.end_date >= {$today} ) )";
+ $relationWhere = " WHERE contact_a.is_deleted = 0 {$relationshipClause} {$relationActive}";
+ $relationGroupBy = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($relationQuery->_select, "crel.{$contactA}");
+ $relationSelect = "{$relationSelect}, {$contactA} as refContact ";
+ $relationQueryString = "$relationSelect $relationFrom $relationWhere $relationHaving $relationGroupBy";
+
+ $allRelContactDAO = CRM_Core_DAO::executeQuery($relationQueryString);
+ while ($allRelContactDAO->fetch()) {
+ $relationQuery->convertToPseudoNames($allRelContactDAO);
+ $row = [];
+ // @todo pass processor to fetchRelationshipDetails and set fields directly within it.
+ self::fetchRelationshipDetails($allRelContactDAO, $relationReturnProperties, $relationshipKey, $row);
+ foreach (array_keys($relationReturnProperties) as $property) {
+ if ($property === 'location') {
+ // @todo - simplify location in self::fetchRelationshipDetails - remove handling here. Or just call
+ // $processor->setRelationshipValue from fetchRelationshipDetails
+ foreach ($relationReturnProperties['location'] as $locationName => $locationValues) {
+ foreach (array_keys($locationValues) as $locationValue) {
+ $key = str_replace(' ', '_', $locationName) . '-' . $locationValue;
+ $processor->setRelationshipValue($relationshipKey, $allRelContactDAO->refContact, $key, $row[$relationshipKey . '__' . $key]);
+ }
+ }
+ }
+ else {
+ $processor->setRelationshipValue($relationshipKey, $allRelContactDAO->refContact, $property, $row[$relationshipKey . '_' . $property]);
+ }
}
- $allRelContactDAO->free();
}
}
- return array($relationQuery, $allRelContactArray);
}
/**
*/
protected $relationshipReturnProperties = [];
+ /**
+ * Get return properties by relationship.
+ * @return array
+ */
+ public function getRelationshipReturnProperties() {
+ return $this->relationshipReturnProperties;
+ }
+
+ /**
+ * Export values for related contacts.
+ *
+ * @var array
+ */
+ protected $relatedContactValues = [];
+
/**
* @var array
*/
$this->requestedFields = $requestedFields;
}
-
/**
* @return array
*/
);
}
+ /**
+ * Set the value for a relationship type field.
+ *
+ * In this case we are building up an array of properties for a related contact.
+ *
+ * These may be used for direct exporting or for merge to household depending on the
+ * options selected.
+ *
+ * @param string $relationshipType
+ * @param int $contactID
+ * @param string $field
+ * @param string $value
+ */
+ public function setRelationshipValue($relationshipType, $contactID, $field, $value) {
+ $this->relatedContactValues[$relationshipType][$contactID][$field] = $value;
+ }
+
+ /**
+ * Get the value for a relationship type field.
+ *
+ * In this case we are building up an array of properties for a related contact.
+ *
+ * These may be used for direct exporting or for merge to household depending on the
+ * options selected.
+ *
+ * @param string $relationshipType
+ * @param int $contactID
+ * @param string $field
+ *
+ * @return string
+ */
+ public function getRelationshipValue($relationshipType, $contactID, $field) {
+ return isset($this->relatedContactValues[$relationshipType][$contactID][$field]) ? $this->relatedContactValues[$relationshipType][$contactID][$field] : '';
+ }
+
/**
* @return bool
*/
return $this->relationshipReturnProperties[$relationshipKey];
}
+ /**
+ * Add the main return properties to the household merge properties if needed for merging.
+ *
+ * If we are using household merge we need to add these to the relationship properties to
+ * be retrieved.
+ *
+ * @param $returnProperties
+ */
+ public function setHouseholdMergeReturnProperties($returnProperties) {
+ foreach ($this->getHouseholdRelationshipTypes() as $householdRelationshipType) {
+ $this->relationshipReturnProperties[$householdRelationshipType] = $returnProperties;
+ }
+ }
+
/**
* Get the default location fields to request.
*
$this->assertEquals('Big campaign,', CRM_Core_DAO::singleValueQuery("SELECT GROUP_CONCAT(contribution_campaign_title) FROM {$tableName}"));
}
+ /**
+ * Test exporting relationships.
+ */
+ public function testExportRelationships() {
+ $organization1 = $this->organizationCreate(['organization_name' => 'Org 1', 'legal_name' => 'pretty legal']);
+ $organization2 = $this->organizationCreate(['organization_name' => 'Org 2', 'legal_name' => 'well dodgey']);
+ $contact1 = $this->individualCreate(['employer_id' => $organization1, 'first_name' => 'one']);
+ $contact2 = $this->individualCreate(['employer_id' => $organization2, 'first_name' => 'one']);
+ $employerRelationshipTypeID = $this->callAPISuccessGetValue('RelationshipType', ['return' => 'id', 'label_a_b' => 'Employee of']);
+ $selectedFields = [
+ ['Individual', 'first_name', ''],
+ ['Individual', $employerRelationshipTypeID . '_a_b', 'organization_name', ''],
+ ['Individual', $employerRelationshipTypeID . '_a_b', 'legal_name', ''],
+ ];
+ list($tableName, $sqlColumns, $headerRows) = CRM_Export_BAO_Export::exportComponents(
+ FALSE,
+ [$contact1, $contact2],
+ [],
+ NULL,
+ $selectedFields,
+ NULL,
+ CRM_Export_Form_Select::CONTACT_EXPORT,
+ "contact_a.id IN ( $contact1, $contact2 )",
+ NULL,
+ FALSE,
+ FALSE,
+ [
+ 'exportOption' => CRM_Export_Form_Select::CONTACT_EXPORT,
+ 'suppress_csv_for_testing' => TRUE,
+ ]
+ );
+
+ $dao = CRM_Core_DAO::executeQuery("SELECT * FROM {$tableName}");
+ $dao->fetch();
+ $this->assertEquals('one', $dao->first_name);
+ $this->assertEquals('Org 1', $dao->{$employerRelationshipTypeID . '_a_b_organization_name'});
+ $this->assertEquals('pretty legal', $dao->{$employerRelationshipTypeID . '_a_b_legal_name'});
+
+ $dao->fetch();
+ $this->assertEquals('Org 2', $dao->{$employerRelationshipTypeID . '_a_b_organization_name'});
+ $this->assertEquals('well dodgey', $dao->{$employerRelationshipTypeID . '_a_b_legal_name'});
+ }
+
/**
* Test exporting relationships.
*