/** * @param $mode * @param bool $includeCustomFields * * @return array|null */ public static function defaultReturnProperties($mode = 1) { if (!isset(self::$_defaultReturnProperties)) { self::$_defaultReturnProperties = array(); } if (!isset(self::$_defaultReturnProperties[$mode])) { if (empty(self::$_defaultReturnProperties[$mode])) { self::$_defaultReturnProperties[$mode] = array('contact_id_a' => 1, 'contact_id_b' => 1, 'contact_a' => 1, 'contact_b' => 1, 'relationship_type_id' => 1, 'relationship_type' => 1, 'start_date' => 1, 'end_date' => 1, 'is_active' => 1); } } return self::$_defaultReturnProperties[$mode]; }
public static function exportComponents($selectAll, $ids, $params, $order = NULL, $fields = NULL, $moreReturnProperties = NULL, $exportMode = CRM_Export_Form_Select_Relationship::RELATIONSHIP_EXPORT, $componentClause = NULL, $componentTable = NULL, $mergeSameAddress = FALSE, $mergeSameHousehold = FALSE, $exportParams = array(), $queryOperator = 'AND') { $headerRows = $returnProperties = array(); $queryMode = CRM_Relationship_BAO_Query::MODE_RELATIONSHIPS; //Welke velden exporteren, gezet bij een mapping, indien niet gezet, primary fields. if ($fields) { foreach ($fields as $key => $value) { $fieldName = CRM_Utils_Array::value(0, $value); if (!$fieldName) { continue; } $returnProperties[$fieldName] = 1; } } else { // Copied from CRM_Relationship_BAO_QUERY should be refactored to seperate // method. $fields = CRM_Contact_BAO_Relationship::fields(); // Add display_name for both contacts $contact_fields = CRM_Contact_BAO_Contact::exportableFields('All', FALSE, TRUE, TRUE); $fields['contact_a'] = $contact_fields['display_name']; $fields['contact_a']['where'] = 'contact_a.display_name'; $fields['contact_b'] = $contact_fields['display_name']; $fields['contact_b']['where'] = 'contact_b.display_name'; // Add relationship type field $relationship_type_fields = CRM_Contact_BAO_RelationshipType::fields(); $fields['relationship_type'] = $relationship_type_fields['label_a_b']; $fields['relationship_type']['where'] = 'relationship_type.label_a_b'; // Add custom fields $fields = array_merge($fields, CRM_Core_BAO_CustomField::getFieldsForImport('Relationship')); $returnProperties = CRM_Relationship_BAO_Query::defaultReturnProperties(); } if ($moreReturnProperties) { $returnProperties = array_merge($returnProperties, $moreReturnProperties); } $query = new CRM_Relationship_BAO_Query($params, $returnProperties, NULL, FALSE, FALSE, FALSE, TRUE, $queryOperator); //sort by state //CRM-15301 $query->_sort = $order; list($select, $from, $where, $having) = $query->query(); $allRelContactArray = $relationQuery = array(); if (!$selectAll && $componentTable) { // TODO For not select all //$from .= " INNER JOIN $componentTable ctTable ON ctTable.contact_id = contact_a.id "; } elseif ($componentClause) { if (empty($where)) { $where = "WHERE {$componentClause}"; } else { $where .= " AND {$componentClause}"; } } $queryString = "{$select} {$from} {$where} {$having}"; $groupBy = ""; if ($queryMode & CRM_Relationship_BAO_Query::MODE_RELATIONSHIPS && $query->_useGroupBy) { $groupBy = " GROUP BY relationship.id"; } $queryString .= $groupBy; // always add relationship.id to the ORDER clause // so the order is deterministic if (strpos('relationship.id', $order) === FALSE) { $order .= ", relationship.id"; } if ($order) { list($field, $dir) = explode(' ', $order, 2); $field = trim($field); if (!empty($returnProperties[$field])) { //CRM-15301 $queryString .= " ORDER BY {$order}"; } } $componentDetails = $headerRows = $sqlColumns = array(); $setHeader = TRUE; $rowCount = self::EXPORT_ROW_COUNT; $offset = 0; // we write to temp table often to avoid using too much memory $tempRowCount = 100; $count = -1; // for CRM-3157 purposes $i18n = CRM_Core_I18n::singleton(); $outputColumns = array(); //@todo - it would be clearer to start defining output columns earlier in this function rather than stick with return properties until this point // as the array is not actually 'returnProperties' after the sql query is formed - making the alterations to it confusing foreach ($returnProperties as $key => $value) { $outputColumns[$key] = $value; } while (1) { $limitQuery = "{$queryString} LIMIT {$offset}, {$rowCount}"; $dao = CRM_Core_DAO::executeQuery($limitQuery); if ($dao->N <= 0) { break; } while ($dao->fetch()) { $count++; $row = array(); //convert the pseudo constants // CRM-14398 there is problem in this architecture that is not easily solved. For now we are using the cloned // temporary iterationDAO object to get around it. // the issue is that the convertToPseudoNames function is adding additional properties (e.g for campaign) to the DAO object // these additional properties are NOT reset when the $dao cycles through the while loop // nor are they overwritten as they are not in the loop // the convertToPseudoNames will not adequately over-write them either as it doesn't 'kick-in' unless the // relevant property is set. // It may be that a long-term fix could be introduced there - however, it's probably necessary to figure out how to test the // export class before tackling a better architectural fix $iterationDAO = clone $dao; //first loop through output columns so that we return what is required, and in same order. foreach ($outputColumns as $field => $value) { //we should set header only once if ($setHeader) { $sqlDone = FALSE; $headerRows[] = $query->_fields[$field]['title']; if (!$sqlDone) { self::sqlColumnDefn($query, $sqlColumns, $field); } } //build row values (data) $fieldValue = NULL; if (property_exists($iterationDAO, $field)) { $fieldValue = $iterationDAO->{$field}; } if ($field == 'id') { $row[$field] = $iterationDAO->relationship_id; } elseif (isset($fieldValue) && $fieldValue != '') { //check for custom data if ($cfID = CRM_Core_BAO_CustomField::getKeyID($field)) { $row[$field] = CRM_Core_BAO_CustomField::getDisplayValue($fieldValue, $cfID, $query->_options); } else { //normal fields with a touch of CRM-3157 $row[$field] = $fieldValue; } } else { // if field is empty or null $row[$field] = ''; } } if ($setHeader) { $exportTempTable = self::createTempTable($sqlColumns); } //build header only once $setHeader = FALSE; // add component info // write the row to a file $componentDetails[] = $row; // output every $tempRowCount rows if ($count % $tempRowCount == 0) { self::writeDetailsToTable($exportTempTable, $componentDetails, $sqlColumns); $componentDetails = array(); } } $dao->free(); $offset += $rowCount; } if ($exportTempTable) { self::writeDetailsToTable($exportTempTable, $componentDetails, $sqlColumns); // do merge same address and merge same household processing if ($mergeSameAddress) { self::mergeSameAddress($exportTempTable, $headerRows, $sqlColumns, $exportParams); } // merge the records if they have corresponding households if ($mergeSameHousehold) { self::mergeSameHousehold($exportTempTable, $headerRows, $sqlColumns, $relationKeyMOH); self::mergeSameHousehold($exportTempTable, $headerRows, $sqlColumns, $relationKeyHOH); } // call export hook CRM_Utils_Hook::export($exportTempTable, $headerRows, $sqlColumns, $exportMode); // now write the CSV file self::writeCSVFromTable($exportTempTable, $headerRows, $sqlColumns, $exportMode); // delete the export temp table and component table $sql = "DROP TABLE IF EXISTS {$exportTempTable}"; CRM_Core_DAO::executeQuery($sql); CRM_Utils_System::civiExit(); } else { CRM_Core_Error::fatal(ts('No records to export')); } }
/** * @param CRM_Core_Form $form * @param bool $useTable */ public static function preProcessCommon(&$form, $useTable = FALSE) { $form->_relationshipIds = array(); $values = $form->controller->exportValues($form->get('searchFormName')); $form->_task = $values['task']; $relationshipTasks = CRM_Relationship_Task::tasks(); $form->assign('taskName', $relationshipTasks[$form->_task]); $ids = array(); if ($values['radio_ts'] == 'ts_sel') { foreach ($values as $name => $value) { if (substr($name, 0, CRM_Core_Form::CB_PREFIX_LEN) == CRM_Core_Form::CB_PREFIX) { $ids[] = substr($name, CRM_Core_Form::CB_PREFIX_LEN); } } } else { $queryParams = $form->get('queryParams'); $sortOrder = NULL; if ($form->get(CRM_Utils_Sort::SORT_ORDER)) { $sortOrder = $form->get(CRM_Utils_Sort::SORT_ORDER); } $query = new CRM_Relationship_BAO_Query($queryParams); $query->_distinctComponentClause = 'civicrm_relationship.id'; $query->_groupByComponentClause = ' GROUP BY civicrm_relationship.id '; $result = $query->searchQuery(0, 0, $sortOrder); while ($result->fetch()) { $ids[] = $result->relationship_id; } $form->assign('totalSelectedRelationships', $form->get('rowCount')); } if (!empty($ids)) { $form->_componentClause = ' civicrm_relationship.id IN ( ' . implode(',', $ids) . ' ) '; $form->assign('totalSelectedRelationships', count($ids)); } $form->_relationshipIds = $form->_componentIds = $ids; //set the context for redirection for any task actions $session = CRM_Core_Session::singleton(); $qfKey = CRM_Utils_Request::retrieve('qfKey', 'String', $form); $urlParams = 'force=1'; if (CRM_Utils_Rule::qfKey($qfKey)) { $urlParams .= "&qfKey={$qfKey}"; } $searchFormName = strtolower($form->get('searchFormName')); if ($searchFormName == 'search') { $session->replaceUserContext(CRM_Utils_System::url('civicrm/rel/search', $urlParams)); } else { $session->replaceUserContext(CRM_Utils_System::url("civicrm/contact/search/{$searchFormName}", $urlParams)); } }
public function __construct(&$queryParams, $action = CRM_Core_Action::NONE, $relationshipClause = NULL, $single = FALSE, $limit = NULL, $context = 'search') { // submitted form values $this->_queryParams =& $queryParams; $this->_single = $single; $this->_limit = $limit; $this->_context = $context; $this->_relationshipClause = $relationshipClause; // type of selector $this->_action = $action; $this->_query = new CRM_Relationship_BAO_Query($this->_queryParams, CRM_Relationship_BAO_Query::defaultReturnProperties()); }
/** * The post processing of the form gets done here. * * Key things done during post processing are * - check for reset or next request. if present, skip post processing. * - now check if user requested running a saved search, if so, then * the form values associated with the saved search are used for searching. * - if user has done a submit with new values the regular post submission is * done. * The processing consists of using a Selector / Controller framework for getting the * search results. */ public function postProcess() { // get user submitted values // get it from controller only if form has been submitted, else preProcess has set this if (!empty($_POST)) { $this->_formValues = $this->controller->exportValues($this->_name); $this->normalizeFormValues(); } CRM_Core_BAO_CustomValue::fixCustomFieldValue($this->_formValues); $this->_params = CRM_Relationship_BAO_Query::convertFormValues($this->_formValues); $this->_returnProperties =& $this->returnProperties(); if ($this->_done) { return; } $this->_done = TRUE; //for prev/next pagination $crmPID = CRM_Utils_Request::retrieve('crmPID', 'Integer', CRM_Core_DAO::$_nullObject); if (array_key_exists($this->_searchButtonName, $_POST) || $this->_force && !$crmPID) { //reset the cache table for new search $cacheKey = "civicrm search {$this->controller->_key}"; CRM_Core_BAO_PrevNextCache::deleteItem(NULL, $cacheKey); } //get the button name $buttonName = $this->controller->getButtonName(); if (isset($this->_componentMode) && empty($this->_formValues['component_mode'])) { $this->_formValues['component_mode'] = $this->_componentMode; } if (isset($this->_operator) && empty($this->_formValues['operator'])) { $this->_formValues['operator'] = $this->_operator; } if (empty($this->_formValues['qfKey'])) { $this->_formValues['qfKey'] = $this->controller->_key; } $this->set('type', $this->_action); $this->set('formValues', $this->_formValues); $this->set('queryParams', $this->_params); $this->set('returnProperties', $this->_returnProperties); if ($buttonName == $this->_actionButtonName) { // check actionName and if next, then do not repeat a search, since we are going to the next page // hack, make sure we reset the task values $stateMachine = $this->controller->getStateMachine(); $formName = $stateMachine->getTaskFormName(); $this->controller->resetPage($formName); return; } else { $output = CRM_Core_Selector_Controller::SESSION; // create the selector, controller and run - store results in session $searchChildGroups = TRUE; $setDynamic = FALSE; if (strpos(self::$_selectorName, 'CRM_Relationship_Selector') !== FALSE) { $selector = new self::$_selectorName($this->_customSearchClass, $this->_formValues, $this->_params, $this->_returnProperties, $this->_action, FALSE, $this->_context, $this->_contextMenu); $setDynamic = TRUE; } else { $selector = new self::$_selectorName($this->_params, $this->_action, NULL, FALSE, NULL, "search", "advanced"); } $selector->setKey($this->controller->_key); // added the sorting character to the form array $config = CRM_Core_Config::singleton(); // do this only for contact search $sortID = NULL; if ($this->get(CRM_Utils_Sort::SORT_ID)) { $sortID = CRM_Utils_Sort::sortIDValue($this->get(CRM_Utils_Sort::SORT_ID), $this->get(CRM_Utils_Sort::SORT_DIRECTION)); } $controller = new CRM_Relationship_Selector_Controller($selector, $this->get(CRM_Utils_Pager::PAGE_ID), $sortID, CRM_Core_Action::VIEW, $this, $output); $controller->setEmbedded(TRUE); $controller->setDynamicAction($setDynamic); $controller->run(); } }
/** * @param array $params * @param $action * @param int $sortID * @param string $queryOperator * * @return CRM_Relationship_DAO_Relationship */ public function contactIDQuery($params, $action, $sortID, $queryOperator = 'AND') { $sortOrder =& $this->getSortOrder($this->_action); $sort = new CRM_Utils_Sort($sortOrder, $sortID); $query = new CRM_Relationship_BAO_Query($params, $this->_returnProperties, NULL, FALSE, FALSE, 1, FALSE, TRUE, TRUE, $queryOperator); $value = $query->searchQuery(0, 0, $sort, FALSE, FALSE, FALSE, FALSE, FALSE); return $value; }