public static function update() { // lets build the tree in memory first $sql = "\nSELECT n.child_group_id as child ,\n n.parent_group_id as parent\nFROM civicrm_group_nesting n,\n civicrm_group gc,\n civicrm_group gp\nWHERE n.child_group_id = gc.id\n AND n.parent_group_id = gp.id\n"; $dao = CRM_Core_DAO::executeQuery($sql); $tree = array(); while ($dao->fetch()) { if (!array_key_exists($dao->child, $tree)) { $tree[$dao->child] = array('children' => array(), 'parents' => array()); } if (!array_key_exists($dao->parent, $tree)) { $tree[$dao->parent] = array('children' => array(), 'parents' => array()); } $tree[$dao->child]['parents'][] = $dao->parent; $tree[$dao->parent]['children'][] = $dao->child; } if (self::checkCyclicGraph($tree)) { CRM_Core_Error::fatal(ts('We detected a cycle which we cant handle. aborting')); } // first reset the current cache entries $sql = "\nUPDATE civicrm_group\nSET parents = null,\n children = null\n"; CRM_Core_DAO::executeQuery($sql); $values = array(); foreach (array_keys($tree) as $id) { $parents = implode(',', $tree[$id]['parents']); $children = implode(',', $tree[$id]['children']); $parents = $parents == NULL ? 'null' : "'{$parents}'"; $children = $children == NULL ? 'null' : "'{$children}'"; $sql = "\nUPDATE civicrm_group\nSET parents = {$parents} ,\n children = {$children}\nWHERE id = {$id}\n"; CRM_Core_DAO::executeQuery($sql); } // this tree stuff is quite useful, so lets store it in the cache CRM_Core_BAO_Cache::setItem($tree, 'contact groups', 'nestable tree hierarchy'); }
/** * combine all the importable fields from the lower levels object * * The ordering is important, since currently we do not have a weight * scheme. Adding weight is super important * * @param int $contactType contact Type * @param boolean $status status is used to manipulate first title * @param boolean $showAll if true returns all fields (includes disabled fields) * @param boolean $isProfile if its profile mode * @param boolean $checkPermission if false, do not include permissioning clause (for custom data) * * @return array array of importable Fields * @access public * @static */ static function importableFields($contactType = 'HRJobLeave', $status = FALSE, $showAll = FALSE, $isProfile = FALSE, $checkPermission = TRUE, $withMultiCustomFields = FALSE) { if (empty($contactType)) { $contactType = 'HRJobLeave'; } $cacheKeyString = ""; $cacheKeyString .= $status ? '_1' : '_0'; $cacheKeyString .= $showAll ? '_1' : '_0'; $cacheKeyString .= $isProfile ? '_1' : '_0'; $cacheKeyString .= $checkPermission ? '_1' : '_0'; $fields = CRM_Utils_Array::value($cacheKeyString, self::$_importableFields); if (!$fields) { $fields = CRM_HRJob_DAO_HRJobLeave::import(); $fields = array_merge($fields, CRM_HRJOB_DAO_HRJOBLEAVE::import()); foreach ($fields as $key => $v) { $fields[$key]['hasLocationType'] = TRUE; } //Sorting fields in alphabetical order $fields = CRM_Utils_Array::crmArraySortByField($fields, 'title'); $fields = CRM_Utils_Array::index(array('name'), $fields); CRM_Core_BAO_Cache::setItem($fields, 'contact fields', $cacheKeyString); } self::$_importableFields[$cacheKeyString] = $fields; if (!$isProfile) { $fields = array_merge(array('do_not_import' => array('title' => ts('- do not import -'))), self::$_importableFields[$cacheKeyString]); } return $fields; }
static function importableFields($contactType = 'HRJobContractRevision', $status = FALSE, $showAll = FALSE, $isProfile = FALSE, $checkPermission = TRUE, $withMultiCustomFields = FALSE) { if (empty($contactType)) { $contactType = 'HRJobContractRevision'; } $cacheKeyString = ""; $cacheKeyString .= $status ? '_1' : '_0'; $cacheKeyString .= $showAll ? '_1' : '_0'; $cacheKeyString .= $isProfile ? '_1' : '_0'; $cacheKeyString .= $checkPermission ? '_1' : '_0'; $fields = CRM_Utils_Array::value($cacheKeyString, self::$_importableFields); if (!$fields) { $fields = CRM_Hrjobcontract_DAO_HRJobContractRevision::import(); $fields = array_merge($fields, CRM_Hrjobcontract_DAO_HRJobContractRevision::import()); //Sorting fields in alphabetical order(CRM-1507) $fields = CRM_Utils_Array::crmArraySortByField($fields, 'title'); $fields = CRM_Utils_Array::index(array('name'), $fields); CRM_Core_BAO_Cache::setItem($fields, 'contact fields', $cacheKeyString); } self::$_importableFields[$cacheKeyString] = $fields; if (!$isProfile) { $fields = array_merge(array('do_not_import' => array('title' => ts('- do not import -'))), self::$_importableFields[$cacheKeyString]); } return $fields; }
function batchSave() { // save in cache table $batchId = CRM_Utils_Type::escape($_POST['batch_id'], 'Positive'); $cacheKeyString = CRM_Core_BAO_Batch::getCacheKeyForBatch($batchId); // check if we can retrieve from database cache unset($_POST['qfKey']); CRM_Core_BAO_Cache::setItem($_POST, 'batch entry', $cacheKeyString); // return true if saved correctly CRM_Utils_System::civiExit(); }
/** * Test system flush. */ public function testFlush() { // Note: this operation actually flushes several different caches; we don't // check all of them -- just enough to make sure that the API is doing // something $this->assertTrue(NULL === CRM_Core_BAO_Cache::getItem(self::TEST_CACHE_GROUP, self::TEST_CACHE_PATH)); $data = 'abc'; CRM_Core_BAO_Cache::setItem($data, self::TEST_CACHE_GROUP, self::TEST_CACHE_PATH); $this->assertEquals('abc', CRM_Core_BAO_Cache::getItem(self::TEST_CACHE_GROUP, self::TEST_CACHE_PATH)); $params = array(); $result = $this->callAPIAndDocument('system', 'flush', $params, __FUNCTION__, __FILE__, "Flush all system caches", 'Flush'); $this->assertTrue(NULL === CRM_Core_BAO_Cache::getItem(self::TEST_CACHE_GROUP, self::TEST_CACHE_PATH)); }
public function testSetGetItem() { $originalValue = array('abc' => 'def'); CRM_Core_BAO_Cache::setItem($originalValue, __CLASS__, 'testSetGetItem'); $return_1 = CRM_Core_BAO_Cache::getItem(__CLASS__, 'testSetGetItem'); $this->assertEquals($originalValue, $return_1); // Wipe out any in-memory copies of the cache. Check to see if the SQL // read is correct. CRM_Core_BAO_Cache::$_cache = NULL; CRM_Utils_Cache::$_singleton = NULL; $return_2 = CRM_Core_BAO_Cache::getItem(__CLASS__, 'testSetGetItem'); $this->assertEquals($originalValue, $return_2); }
/** * Combine all the exportable fields from the lower levels object. * * Currently we are using importable fields as exportable fields * * @param int|string $contactType contact Type * @param bool $status * True while exporting primary contacts. * @param bool $export * True when used during export. * @param bool $search * True when used during search, might conflict with export param?. * * @param bool $withMultiRecord * * @return array * array of exportable Fields */ public static function &exportableFields($contactType = 'Individual', $status = FALSE, $export = FALSE, $search = FALSE, $withMultiRecord = FALSE) { if (empty($contactType)) { $contactType = 'All'; } $cacheKeyString = "exportableFields {$contactType}"; $cacheKeyString .= $export ? '_1' : '_0'; $cacheKeyString .= $status ? '_1' : '_0'; $cacheKeyString .= $search ? '_1' : '_0'; //CRM-14501 it turns out that the impact of permissioning here is sometimes inconsistent. The field that //calculates custom fields takes into account the logged in user & caches that for all users //as an interim fix we will cache the fields by contact $cacheKeyString .= '_' . CRM_Core_Session::getLoggedInContactID(); if (!self::$_exportableFields || !CRM_Utils_Array::value($cacheKeyString, self::$_exportableFields)) { if (!self::$_exportableFields) { self::$_exportableFields = array(); } // check if we can retrieve from database cache $fields = CRM_Core_BAO_Cache::getItem('contact fields', $cacheKeyString); if (!$fields) { $fields = CRM_Contact_DAO_Contact::export(); // The fields are meant for contact types. if (in_array($contactType, array('Individual', 'Household', 'Organization', 'All'))) { $fields = array_merge($fields, CRM_Core_OptionValue::getFields('', $contactType)); } // add current employer for individuals $fields = array_merge($fields, array('current_employer' => array('name' => 'organization_name', 'title' => ts('Current Employer')))); $locationType = array('location_type' => array('name' => 'location_type', 'where' => 'civicrm_location_type.name', 'title' => ts('Location Type'))); $IMProvider = array('im_provider' => array('name' => 'im_provider', 'where' => 'civicrm_im.provider_id', 'title' => ts('IM Provider'))); $locationFields = array_merge($locationType, CRM_Core_DAO_Address::export(), CRM_Core_DAO_Phone::export(), CRM_Core_DAO_Email::export(), $IMProvider, CRM_Core_DAO_IM::export(TRUE), CRM_Core_DAO_OpenID::export()); $locationFields = array_merge($locationFields, CRM_Core_BAO_CustomField::getFieldsForImport('Address')); foreach ($locationFields as $key => $field) { $locationFields[$key]['hasLocationType'] = TRUE; } $fields = array_merge($fields, $locationFields); //add world region $fields = array_merge($fields, CRM_Core_DAO_Worldregion::export()); $fields = array_merge($fields, CRM_Contact_DAO_Contact::export()); //website fields $fields = array_merge($fields, CRM_Core_DAO_Website::export()); if ($contactType != 'All') { $fields = array_merge($fields, CRM_Core_BAO_CustomField::getFieldsForImport($contactType, $status, FALSE, $search, TRUE, $withMultiRecord)); } else { foreach (array('Individual', 'Household', 'Organization') as $type) { $fields = array_merge($fields, CRM_Core_BAO_CustomField::getFieldsForImport($type, FALSE, FALSE, $search, TRUE, $withMultiRecord)); } } //fix for CRM-791 if ($export) { $fields = array_merge($fields, array('groups' => array('title' => ts('Group(s)'), 'name' => 'groups'), 'tags' => array('title' => ts('Tag(s)'), 'name' => 'tags'), 'notes' => array('title' => ts('Note(s)'), 'name' => 'notes'))); } else { $fields = array_merge($fields, array('group' => array('title' => ts('Group(s)'), 'name' => 'group'), 'tag' => array('title' => ts('Tag(s)'), 'name' => 'tag'), 'note' => array('title' => ts('Note(s)'), 'name' => 'note'))); } //Sorting fields in alphabetical order(CRM-1507) foreach ($fields as $k => $v) { $sortArray[$k] = CRM_Utils_Array::value('title', $v); } $fields = array_merge($sortArray, $fields); //unset the field which are not related to their contact type. if ($contactType != 'All') { $commonValues = array('Individual' => array('household_name', 'legal_name', 'sic_code', 'organization_name', 'email_greeting_custom', 'postal_greeting_custom', 'addressee_custom'), 'Household' => array('first_name', 'middle_name', 'last_name', 'formal_title', 'job_title', 'gender_id', 'prefix_id', 'suffix_id', 'birth_date', 'organization_name', 'legal_name', 'legal_identifier', 'sic_code', 'home_URL', 'is_deceased', 'deceased_date', 'current_employer', 'email_greeting_custom', 'postal_greeting_custom', 'addressee_custom', 'prefix_id', 'suffix_id'), 'Organization' => array('first_name', 'middle_name', 'last_name', 'formal_title', 'job_title', 'gender_id', 'prefix_id', 'suffix_id', 'birth_date', 'household_name', 'email_greeting_custom', 'postal_greeting_custom', 'prefix_id', 'suffix_id', 'gender_id', 'addressee_custom', 'is_deceased', 'deceased_date', 'current_employer')); foreach ($commonValues[$contactType] as $value) { unset($fields[$value]); } } CRM_Core_BAO_Cache::setItem($fields, 'contact fields', $cacheKeyString); } self::$_exportableFields[$cacheKeyString] = $fields; } if (!$status) { $fields = self::$_exportableFields[$cacheKeyString]; } else { $fields = array_merge(array('' => array('title' => ts('- Contact Fields -'))), self::$_exportableFields[$cacheKeyString]); } return $fields; }
/** * Check that setting defined in extension can be retrieved. */ public function testGetExtensionSetting() { $this->hookClass->setHook('civicrm_alterSettingsFolders', array($this, 'setExtensionMetadata')); $data = NULL; // the caching of data to all duplicates the caching of data to the empty string CRM_Core_BAO_Cache::setItem($data, 'CiviCRM setting Spec', 'All'); CRM_Core_BAO_Cache::setItem($data, 'CiviCRM setting Specs', 'settingsMetadata__'); $fields = $this->callAPISuccess('setting', 'getfields', array('filters' => array('group_name' => 'Test Settings'))); $this->assertArrayHasKey('test_key', $fields['values']); $this->callAPISuccess('setting', 'create', array('test_key' => 'keyset')); $result = $this->callAPISuccess('setting', 'getvalue', array('name' => 'test_key', 'group' => 'Test Settings')); $this->assertEquals('keyset', $result); }
function buildPrevNextCache($sort) { //for prev/next pagination $crmPID = CRM_Utils_Request::retrieve('crmPID', 'Integer', CRM_Core_DAO::$_nullObject); if (!$crmPID) { $cacheKey = "civicrm search {$this->_key}"; CRM_Core_BAO_PrevNextCache::deleteItem(NULL, $cacheKey, 'civicrm_contact'); $sql = $this->_query->searchQuery(0, 0, $sort, FALSE, FALSE, FALSE, FALSE, TRUE, $this->_campaignWhereClause, NULL, $this->_campaignFromClause); list($select, $from) = explode(' FROM ', $sql); $insertSQL = "\nINSERT INTO civicrm_prevnext_cache ( entity_table, entity_id1, entity_id2, cacheKey, data )\nSELECT 'civicrm_contact', contact_a.id, contact_a.id, '{$cacheKey}', contact_a.display_name\nFROM {$from}\n"; CRM_Core_Error::ignoreException(); $result = CRM_Core_DAO::executeQuery($insertSQL); CRM_Core_Error::setCallback(); if (is_a($result, 'DB_Error')) { return; } // also record an entry in the cache key table, so we can delete it periodically CRM_Core_BAO_Cache::setItem($cacheKey, 'CiviCRM Search PrevNextCache', $cacheKey); } }
function set($key, &$value) { CRM_Core_BAO_Cache::setItem($value, $this->group, $key, $this->componentID); $this->frontCache[$key] = $value; }
/** * Fetch all feeds & cache results. * * @return array */ protected function getFeeds() { $blogFeed = $this->getFeed($this->getBlogUrl()); // If unable to fetch the first feed, give up and return empty results. if (!$blogFeed) { return array_fill_keys(array_keys($this->get_template_vars('tabs')), array()); } $eventFeed = $this->getFeed($this->getEventUrl()); $feeds = array('blog' => $this->formatItems($blogFeed), 'events' => $this->formatItems($eventFeed)); CRM_Core_BAO_Cache::setItem($feeds, 'dashboard', 'blog'); return $feeds; }
/** * Get all groups that are children of the parent group * (iterate through all levels) * * @param integer $groupID * @param boolean $includeParent * @return array:child groups */ function _multisite_get_all_child_groups($groupID, $includeParent = TRUE) { static $_cache = array(); if (!array_key_exists($groupID, $_cache)) { $childGroups =& CRM_Core_BAO_Cache::getItem('descendant groups for an org', $groupID); if (empty($childGroups)) { $childGroups = array(); $query = "\nSELECT children\nFROM civicrm_group\nWHERE children IS NOT NULL\nAND id IN "; if (!is_array($groupID)) { $groupIDs = array($groupID); } while (!empty($groupIDs)) { $groupIDString = implode(',', $groupIDs); $realQuery = $query . " ( {$groupIDString} )"; $dao = CRM_Core_DAO::executeQuery($realQuery); $groupIDs = array(); while ($dao->fetch()) { if ($dao->children) { $childIDs = explode(',', $dao->children); foreach ($childIDs as $childID) { if (!array_key_exists($childID, $childGroups)) { $childGroups[$childID] = 1; $groupIDs[] = $childID; } } } } } CRM_Core_BAO_Cache::setItem($childGroups, 'descendant groups for an org', $groupID); } $_cache[$groupID] = $childGroups; } if ($includeParent || CRM_Core_Permission::check('administer Multiple Organizations')) { return array_keys(array($groupID => 1) + $_cache[$groupID]); } else { return array_keys($_cache[$groupID]); } }
/** * @param object $sort * @param string $cacheKey * @param int $start * @param int $end */ function fillupPrevNextCache($sort, $cacheKey, $start = 0, $end = 500) { // For custom searches, use the contactIDs method if (is_a($this, 'CRM_Contact_Selector_Custom')) { $sql = $this->_search->contactIDs($start, $end, $sort, TRUE); $replaceSQL = "SELECT contact_a.id as contact_id"; } else { $sql = $this->_query->searchQuery($start, $end, $sort, FALSE, FALSE, FALSE, TRUE, TRUE, NULL); $replaceSQL = "SELECT contact_a.id as id"; } // CRM-9096 // due to limitations in our search query writer, the above query does not work // in cases where the query is being sorted on a non-contact table // this results in a fatal error :( // see below for the gross hack of trapping the error and not filling // the prev next cache in this situation // the other alternative of running the FULL query will just be incredibly inefficient // and slow things down way too much on large data sets / complex queries $insertSQL = "\nINSERT INTO civicrm_prevnext_cache ( entity_table, entity_id1, entity_id2, cacheKey, data )\nSELECT 'civicrm_contact', contact_a.id, contact_a.id, '{$cacheKey}', contact_a.display_name\n"; $sql = str_replace($replaceSQL, $insertSQL, $sql); CRM_Core_Error::ignoreException(); $result = CRM_Core_DAO::executeQuery($sql); CRM_Core_Error::setCallback(); if (is_a($result, 'DB_Error')) { // oops the above query failed, so lets just ignore it // and return // we print a sorry cant figure it out on view page return; } // also record an entry in the cache key table, so we can delete it periodically CRM_Core_BAO_Cache::setItem($cacheKey, 'CiviCRM Search PrevNextCache', $cacheKey); }
/** * combine all the exportable fields from the lower levels object * * currentlty we are using importable fields as exportable fields * * @param int $contactType contact Type * $param boolean $status true while exporting primary contacts * $param boolean $export true when used during export * * @return array array of exportable Fields * @access public */ function &exportableFields($contactType = 'Individual', $status = false, $export = false) { if (empty($contactType)) { $contactType = 'All'; } $cacheKeyString = "exportableFields {$contactType}"; $cacheKeyString .= $export ? "_1" : "_0"; $cacheKeyString .= $status ? "_1" : "_0"; if (!self::$_exportableFields || !CRM_Utils_Array::value($cacheKeyString, self::$_exportableFields)) { if (!self::$_exportableFields) { self::$_exportableFields = array(); } // check if we can retrieve from database cache require_once 'CRM/Core/BAO/Cache.php'; $fields =& CRM_Core_BAO_Cache::getItem('contact fields', $cacheKeyString); if (!$fields) { $fields = array(); $fields = array_merge($fields, CRM_Contact_DAO_Contact::export()); // the fields are meant for contact types if (in_array($contactType, array('Individual', 'Household', 'Organization', 'All'))) { require_once 'CRM/Core/OptionValue.php'; $fields = array_merge($fields, CRM_Core_OptionValue::getFields('', $contactType)); } // add current employer for individuals $fields = array_merge($fields, array('current_employer' => array('name' => 'organization_name', 'title' => ts('Current Employer')))); $locationType = array(); if ($status) { $locationType['location_type'] = array('name' => 'location_type', 'where' => 'civicrm_location_type.name', 'title' => ts('Location Type')); } $IMProvider = array(); if ($status) { $IMProvider['im_provider'] = array('name' => 'im_provider', 'where' => 'im_provider.name', 'title' => ts('IM Provider')); } $locationFields = array_merge($locationType, CRM_Core_DAO_Address::export(), CRM_Core_DAO_Phone::export(), CRM_Core_DAO_Email::export(), $IMProvider, CRM_Core_DAO_IM::export(true), CRM_Core_DAO_OpenID::export()); foreach ($locationFields as $key => $field) { $locationFields[$key]['hasLocationType'] = true; } $fields = array_merge($fields, $locationFields); //add world region require_once "CRM/Core/DAO/Worldregion.php"; $fields = array_merge($fields, CRM_Core_DAO_Worldregion::export()); $fields = array_merge($fields, CRM_Contact_DAO_Contact::export()); if ($contactType != 'All') { $fields = array_merge($fields, CRM_Core_BAO_CustomField::getFieldsForImport($contactType, $status, true)); } else { foreach (array('Individual', 'Household', 'Organization') as $type) { $fields = array_merge($fields, CRM_Core_BAO_CustomField::getFieldsForImport($type)); } } //fix for CRM-791 if ($export) { $fields = array_merge($fields, array('groups' => array('title' => ts('Group(s)')), 'tags' => array('title' => ts('Tag(s)')), 'notes' => array('title' => ts('Note(s)')))); } else { $fields = array_merge($fields, array('group' => array('title' => ts('Group(s)')), 'tag' => array('title' => ts('Tag(s)')), 'note' => array('title' => ts('Note(s)')))); } //Sorting fields in alphabetical order(CRM-1507) foreach ($fields as $k => $v) { $sortArray[$k] = CRM_Utils_Array::value('title', $v); } $fields = array_merge($sortArray, $fields); //unset the field which are not related to their contact type. if ($contactType != 'All') { $commonValues = array('Individual' => array('household_name', 'legal_name', 'sic_code', 'organization_name', 'email_greeting_custom', 'postal_greeting_custom', 'addressee_custom'), 'Household' => array('first_name', 'middle_name', 'last_name', 'job_title', 'gender_id', 'birth_date', 'organization_name', 'legal_name', 'legal_identifier', 'sic_code', 'home_URL', 'is_deceased', 'deceased_date', 'current_employer', 'email_greeting_custom', 'postal_greeting_custom', 'addressee_custom', 'individual_prefix', 'individual_suffix', 'gender'), 'Organization' => array('first_name', 'middle_name', 'last_name', 'job_title', 'gender_id', 'birth_date', 'household_name', 'email_greeting', 'postal_greeting', 'email_greeting_custom', 'postal_greeting_custom', 'individual_prefix', 'individual_suffix', 'gender', 'addressee_custom', 'is_deceased', 'deceased_date', 'current_employer')); foreach ($commonValues[$contactType] as $value) { unset($fields[$value]); } } CRM_Core_BAO_Cache::setItem($fields, 'contact fields', $cacheKeyString); } self::$_exportableFields[$cacheKeyString] = $fields; } if (!$status) { $fields = self::$_exportableFields[$cacheKeyString]; } else { $fields = array_merge(array('' => array('title' => ts('- Contact Fields -'))), self::$_exportableFields[$cacheKeyString]); } return $fields; }
/** * Fetch all feeds & cache results. * * @return array */ protected function getFeeds() { $newsFeed = $this->getFeed($this->getNewsUrl()); // If unable to fetch the feed, return empty results. if (!$newsFeed) { return array(); } $feeds = $this->formatItems($newsFeed); CRM_Core_BAO_Cache::setItem($feeds, 'dashboard', 'newsfeed'); return $feeds; }
/** * Store and return an array of all active custom fields. * * @param string $customDataType type of Custom Data * @param boolean $showAll If true returns all fields (includes disabled fields) * @param boolean $inline If true returns all inline fields (includes disabled fields) * @param int $customDataSubType Custom Data sub type value * @param int $customDataSubName Custom Data sub name value * @param boolean $onlyParent return only top level custom data, for eg, only Participant and ignore subname and subtype * * @return array $fields - an array of active custom fields. * * @access public * @static */ public static function &getFields($customDataType = 'Individual', $showAll = false, $inline = false, $customDataSubType = null, $customDataSubName = null, $onlyParent = false) { $onlySubType = false; if ($customDataType && !is_array($customDataType)) { if (in_array($customDataType, CRM_Contact_BAO_ContactType::subTypes())) { // This is the case when getFieldsForImport() requires fields // limited strictly to a subtype. $customDataSubType = $customDataType; $customDataType = CRM_Contact_BAO_ContactType::getBasicType($customDataType); $onlySubType = true; } if (in_array($customDataType, array_keys(CRM_Core_SelectValues::customGroupExtends()))) { // this makes the method flexible to support retrieving fields // for multiple extends value. $customDataType = array($customDataType); } } if (is_array($customDataType)) { $cacheKey = implode('_', $customDataType); } else { $cacheKey = $customDataType; } $cacheKey .= $customDataSubType ? "{$customDataSubType}_" : "_0"; $cacheKey .= $customDataSubName ? "{$customDataSubName}_" : "_0"; $cacheKey .= $showAll ? "_1" : "_0"; $cacheKey .= $inline ? "_1_" : "_0_"; $cacheKey .= $onlyParent ? "_1_" : "_0_"; $cacheKey .= $onlySubType ? "_1_" : "_0_"; $cgTable = CRM_Core_DAO_CustomGroup::getTableName(); // also get the permission stuff here require_once 'CRM/Core/Permission.php'; $permissionClause = CRM_Core_Permission::customGroupClause(CRM_Core_Permission::VIEW, "{$cgTable}."); // lets md5 permission clause and take first 8 characters $cacheKey .= substr(md5($permissionClause), 0, 8); if (strlen($cacheKey) > 40) { $cacheKey = md5($cacheKey); } if (!self::$_importFields || CRM_Utils_Array::value($cacheKey, self::$_importFields) === null) { if (!self::$_importFields) { self::$_importFields = array(); } // check if we can retrieve from database cache require_once 'CRM/Core/BAO/Cache.php'; $fields =& CRM_Core_BAO_Cache::getItem('contact fields', "custom importableFields {$cacheKey}"); if ($fields === null) { $cfTable = self::getTableName(); $extends = ''; if (is_array($customDataType)) { $value = null; foreach ($customDataType as $dataType) { if (in_array($dataType, array_keys(CRM_Core_SelectValues::customGroupExtends()))) { if (in_array($dataType, array('Individual', 'Household', 'Organization'))) { $val = "'" . CRM_Utils_Type::escape($dataType, 'String') . "', 'Contact' "; } else { $val = "'" . CRM_Utils_Type::escape($dataType, 'String') . "'"; } $value = $value ? $value . ", {$val}" : $val; } } if ($value) { $extends = "AND {$cgTable}.extends IN ( {$value} ) "; } } if ($onlyParent) { $extends .= " AND {$cgTable}.extends_entity_column_value IS NULL AND {$cgTable}.extends_entity_column_id IS NULL "; } $query = "SELECT {$cfTable}.id, {$cfTable}.label,\n {$cgTable}.title,\n {$cfTable}.data_type, {$cfTable}.html_type,\n {$cfTable}.options_per_line,\n {$cgTable}.extends, {$cfTable}.is_search_range,\n {$cgTable}.extends_entity_column_value,\n {$cgTable}.extends_entity_column_id,\n {$cfTable}.is_view,\n {$cfTable}.option_group_id,\n {$cfTable}.date_format,\n {$cfTable}.time_format,\n {$cgTable}.is_multiple\n FROM {$cfTable}\n INNER JOIN {$cgTable}\n ON {$cfTable}.custom_group_id = {$cgTable}.id\n WHERE ( 1 ) "; if (!$showAll) { $query .= " AND {$cfTable}.is_active = 1 AND {$cgTable}.is_active = 1 "; } if ($inline) { $query .= " AND {$cgTable}.style = 'Inline' "; } //get the custom fields for specific type in //combination with fields those support any type. if ($customDataSubType) { $customDataSubType = CRM_Core_DAO::VALUE_SEPARATOR . $customDataSubType . CRM_Core_DAO::VALUE_SEPARATOR; $query .= " AND ( {$cgTable}.extends_entity_column_value LIKE '%{$customDataSubType}%'"; if (!$onlySubType) { $query .= " OR {$cgTable}.extends_entity_column_value IS NULL"; } $query .= " )"; } if ($customDataSubName) { $query .= " AND ( {$cgTable}.extends_entity_column_id = {$customDataSubName} ) "; } // also get the permission stuff here require_once 'CRM/Core/Permission.php'; $permissionClause = CRM_Core_Permission::customGroupClause(CRM_Core_Permission::VIEW, "{$cgTable}.", true); $query .= " {$extends} AND {$permissionClause}\n ORDER BY {$cgTable}.weight, {$cgTable}.title,\n {$cfTable}.weight, {$cfTable}.label"; $dao =& CRM_Core_DAO::executeQuery($query); $fields = array(); while ($dao->fetch() != null) { $fields[$dao->id]['label'] = $dao->label; $fields[$dao->id]['groupTitle'] = $dao->title; $fields[$dao->id]['data_type'] = $dao->data_type; $fields[$dao->id]['html_type'] = $dao->html_type; $fields[$dao->id]['options_per_line'] = $dao->options_per_line; $fields[$dao->id]['extends'] = $dao->extends; $fields[$dao->id]['is_search_range'] = $dao->is_search_range; $fields[$dao->id]['extends_entity_column_value'] = $dao->extends_entity_column_value; $fields[$dao->id]['extends_entity_column_id'] = $dao->extends_entity_column_id; $fields[$dao->id]['is_view'] = $dao->is_view; $fields[$dao->id]['is_multiple'] = $dao->is_multiple; $fields[$dao->id]['option_group_id'] = $dao->option_group_id; $fields[$dao->id]['date_format'] = $dao->date_format; $fields[$dao->id]['time_format'] = $dao->time_format; } CRM_Core_BAO_Cache::setItem($fields, 'contact fields', "custom importableFields {$cacheKey}"); } self::$_importFields[$cacheKey] = $fields; } return self::$_importFields[$cacheKey]; }
/** * Load up settings metadata from files. */ public static function loadSettingsMetadata($metaDataFolder) { $settingMetaData = array(); $settingsFiles = CRM_Utils_File::findFiles($metaDataFolder, '*.setting.php'); foreach ($settingsFiles as $file) { $settings = (include $file); $settingMetaData = array_merge($settingMetaData, $settings); } CRM_Core_BAO_Cache::setItem($settingMetaData, 'CiviCRM setting Spec', 'All'); return $settingMetaData; }
/** * Parse rss feed and cache results. * * @param $url * * @return array|NULL * array of blog items; or NULL if not available */ public function _getFeed($url) { $httpClient = new CRM_Utils_HttpClient(self::CHECK_TIMEOUT); list($status, $rawFeed) = $httpClient->get($url); if ($status !== CRM_Utils_HttpClient::STATUS_OK) { return NULL; } $feed = @simplexml_load_string($rawFeed); $blog = array(); if ($feed && !empty($feed->channel->item)) { foreach ($feed->channel->item as $item) { $item = (array) $item; // Clean up description - remove tags that would break dashboard layout $description = preg_replace('#<h[1-3][^>]*>(.+?)</h[1-3][^>]*>#s', '<h4>$1</h4>', $item['description']); $item['description'] = strip_tags($description, "<a><p><h4><h5><h6><b><i><em><strong><ol><ul><li><dd><dt><code><pre><br/>"); $blog[] = $item; } if ($blog) { CRM_Core_BAO_Cache::setItem($blog, 'dashboard', 'blog'); } } return $blog; }
/** * Get formatted menu list * * @return array $navigations returns associated array * @static */ static function getNavigationList() { $cacheKeyString = "navigationList "; $whereClause = ''; $config = CRM_Core_Config::singleton(); if ($config->userFramework == 'Joomla') { $whereClause = " AND name NOT IN ('Access Control') "; $cacheKeyString .= "_1"; } // check if we can retrieve from database cache require_once 'CRM/Core/BAO/Cache.php'; $navigations =& CRM_Core_BAO_Cache::getItem('navigation', $cacheKeyString); if (!$navigations) { $domainID = CRM_Core_Config::domainID(); $query = "\nSELECT id, label, parent_id, weight, is_active, name \nFROM civicrm_navigation WHERE domain_id = {$domainID} {$whereClause} ORDER BY parent_id, weight ASC"; $result = CRM_Core_DAO::executeQuery($query); $pidGroups = array(); while ($result->fetch()) { $pidGroups[$result->parent_id][$result->label] = $result->id; } foreach ($pidGroups[''] as $label => $val) { $pidGroups[''][$label] = self::_getNavigationValue($val, $pidGroups); } $navigations = array(); self::_getNavigationLabel($pidGroups[''], $navigations); CRM_Core_BAO_Cache::setItem($navigations, 'navigation', $cacheKeyString); } return $navigations; }
/** * Store and return an array of all active custom fields. * * @param string $customDataType * Type of Custom Data; empty is a synonym for "all contact data types". * @param bool $showAll * If true returns all fields (includes disabled fields). * @param bool $inline * If true returns all inline fields (includes disabled fields). * @param int $customDataSubType * Custom Data sub type value. * @param int $customDataSubName * Custom Data sub name value. * @param bool $onlyParent * Return only top level custom data, for eg, only Participant and ignore subname and subtype. * @param bool $onlySubType * Return only custom data for subtype. * @param bool $checkPermission * If false, do not include permissioning clause. * * @return array * an array of active custom fields. * */ public static function &getFields($customDataType = 'Individual', $showAll = FALSE, $inline = FALSE, $customDataSubType = NULL, $customDataSubName = NULL, $onlyParent = FALSE, $onlySubType = FALSE, $checkPermission = TRUE) { if (empty($customDataType)) { $customDataType = array('Contact', 'Individual', 'Organization', 'Household'); } if ($customDataType && !is_array($customDataType)) { if (in_array($customDataType, CRM_Contact_BAO_ContactType::subTypes())) { // This is the case when getFieldsForImport() requires fields // limited strictly to a subtype. $customDataSubType = $customDataType; $customDataType = CRM_Contact_BAO_ContactType::getBasicType($customDataType); $onlySubType = TRUE; } if (in_array($customDataType, array_keys(CRM_Core_SelectValues::customGroupExtends()))) { // this makes the method flexible to support retrieving fields // for multiple extends value. $customDataType = array($customDataType); } } $customDataSubType = CRM_Utils_Array::explodePadded($customDataSubType); if (is_array($customDataType)) { $cacheKey = implode('_', $customDataType); } else { $cacheKey = $customDataType; } $cacheKey .= !empty($customDataSubType) ? '_' . implode('_', $customDataSubType) : '_0'; $cacheKey .= $customDataSubName ? "{$customDataSubName}_" : '_0'; $cacheKey .= $showAll ? '_1' : '_0'; $cacheKey .= $inline ? '_1_' : '_0_'; $cacheKey .= $onlyParent ? '_1_' : '_0_'; $cacheKey .= $onlySubType ? '_1_' : '_0_'; $cacheKey .= $checkPermission ? '_1_' : '_0_'; $cgTable = CRM_Core_DAO_CustomGroup::getTableName(); // also get the permission stuff here if ($checkPermission) { $permissionClause = CRM_Core_Permission::customGroupClause(CRM_Core_Permission::VIEW, "{$cgTable}."); } else { $permissionClause = '(1)'; } // lets md5 permission clause and take first 8 characters $cacheKey .= substr(md5($permissionClause), 0, 8); if (strlen($cacheKey) > 40) { $cacheKey = md5($cacheKey); } if (!self::$_importFields || CRM_Utils_Array::value($cacheKey, self::$_importFields) === NULL) { if (!self::$_importFields) { self::$_importFields = array(); } // check if we can retrieve from database cache $fields = CRM_Core_BAO_Cache::getItem('contact fields', "custom importableFields {$cacheKey}"); if ($fields === NULL) { $cfTable = self::getTableName(); $extends = ''; if (is_array($customDataType)) { $value = NULL; foreach ($customDataType as $dataType) { if (in_array($dataType, array_keys(CRM_Core_SelectValues::customGroupExtends()))) { if (in_array($dataType, array('Individual', 'Household', 'Organization'))) { $val = "'" . CRM_Utils_Type::escape($dataType, 'String') . "', 'Contact' "; } else { $val = "'" . CRM_Utils_Type::escape($dataType, 'String') . "'"; } $value = $value ? $value . ", {$val}" : $val; } } if ($value) { $extends = "AND {$cgTable}.extends IN ( {$value} ) "; } } if (!empty($customDataType) && empty($extends)) { // $customDataType specified a filter, but there is no corresponding SQL ($extends) self::$_importFields[$cacheKey] = array(); return self::$_importFields[$cacheKey]; } if ($onlyParent) { $extends .= " AND {$cgTable}.extends_entity_column_value IS NULL AND {$cgTable}.extends_entity_column_id IS NULL "; } $query = "SELECT {$cfTable}.id, {$cfTable}.label,\n {$cgTable}.title,\n {$cfTable}.data_type,\n {$cfTable}.html_type,\n {$cfTable}.default_value,\n {$cfTable}.options_per_line, {$cfTable}.text_length,\n {$cfTable}.custom_group_id,\n {$cfTable}.is_required,\n {$cgTable}.extends, {$cfTable}.is_search_range,\n {$cgTable}.extends_entity_column_value,\n {$cgTable}.extends_entity_column_id,\n {$cfTable}.is_view,\n {$cfTable}.option_group_id,\n {$cfTable}.date_format,\n {$cfTable}.time_format,\n {$cgTable}.is_multiple,\n og.name as option_group_name\n FROM {$cfTable}\n INNER JOIN {$cgTable}\n ON {$cfTable}.custom_group_id = {$cgTable}.id\n LEFT JOIN civicrm_option_group og\n ON {$cfTable}.option_group_id = og.id\n WHERE ( 1 ) "; if (!$showAll) { $query .= " AND {$cfTable}.is_active = 1 AND {$cgTable}.is_active = 1 "; } if ($inline) { $query .= " AND {$cgTable}.style = 'Inline' "; } //get the custom fields for specific type in //combination with fields those support any type. if (!empty($customDataSubType)) { $subtypeClause = array(); foreach ($customDataSubType as $subtype) { $subtype = CRM_Core_DAO::VALUE_SEPARATOR . $subtype . CRM_Core_DAO::VALUE_SEPARATOR; $subtypeClause[] = "{$cgTable}.extends_entity_column_value LIKE '%{$subtype}%'"; } if (!$onlySubType) { $subtypeClause[] = "{$cgTable}.extends_entity_column_value IS NULL"; } $query .= " AND ( " . implode(' OR ', $subtypeClause) . " )"; } if ($customDataSubName) { $query .= " AND ( {$cgTable}.extends_entity_column_id = {$customDataSubName} ) "; } // also get the permission stuff here if ($checkPermission) { $permissionClause = CRM_Core_Permission::customGroupClause(CRM_Core_Permission::VIEW, "{$cgTable}.", TRUE); } else { $permissionClause = '(1)'; } $query .= " {$extends} AND {$permissionClause}\n ORDER BY {$cgTable}.weight, {$cgTable}.title,\n {$cfTable}.weight, {$cfTable}.label"; $dao = CRM_Core_DAO::executeQuery($query); $fields = array(); while ($dao->fetch() != NULL) { $fields[$dao->id]['label'] = $dao->label; $fields[$dao->id]['groupTitle'] = $dao->title; $fields[$dao->id]['data_type'] = $dao->data_type; $fields[$dao->id]['html_type'] = $dao->html_type; $fields[$dao->id]['default_value'] = $dao->default_value; $fields[$dao->id]['text_length'] = $dao->text_length; $fields[$dao->id]['options_per_line'] = $dao->options_per_line; $fields[$dao->id]['custom_group_id'] = $dao->custom_group_id; $fields[$dao->id]['extends'] = $dao->extends; $fields[$dao->id]['is_search_range'] = $dao->is_search_range; $fields[$dao->id]['extends_entity_column_value'] = $dao->extends_entity_column_value; $fields[$dao->id]['extends_entity_column_id'] = $dao->extends_entity_column_id; $fields[$dao->id]['is_view'] = $dao->is_view; $fields[$dao->id]['is_multiple'] = $dao->is_multiple; $fields[$dao->id]['option_group_id'] = $dao->option_group_id; $fields[$dao->id]['date_format'] = $dao->date_format; $fields[$dao->id]['time_format'] = $dao->time_format; $fields[$dao->id]['is_required'] = $dao->is_required; self::getOptionsForField($fields[$dao->id], $dao->option_group_name); } CRM_Core_BAO_Cache::setItem($fields, 'contact fields', "custom importableFields {$cacheKey}"); } self::$_importFields[$cacheKey] = $fields; } return self::$_importFields[$cacheKey]; }
/** * combine all the importable fields from the lower levels object * * The ordering is important, since currently we do not have a weight * scheme. Adding weight is super important * * @param int $contactType contact Type * @param boolean $status status is used to manipulate first title * @param boolean $showAll if true returns all fields (includes disabled fields) * @param boolean $isProfile if its profile mode * @param boolean $checkPermission if false, do not include permissioning clause (for custom data) * * @return array array of importable Fields * @access public * @static */ static function importableFields($contactType = 'Individual', $status = FALSE, $showAll = FALSE, $isProfile = FALSE, $checkPermission = TRUE, $withMultiCustomFields = FALSE) { $cacheKeyString = ""; $cacheKeyString .= $status ? '_1' : '_0'; $cacheKeyString .= $showAll ? '_1' : '_0'; $cacheKeyString .= $isProfile ? '_1' : '_0'; $cacheKeyString .= $checkPermission ? '_1' : '_0'; $contactType = 'Individual'; $fields = CRM_Utils_Array::value($cacheKeyString, self::$_importableFields); if (!$fields) { $fields = CRM_Appraisals_DAO_AppraisalCycle::import(); $tmpContactField = $contactFields = array(); $contactFields = CRM_Contact_BAO_Contact::importableFields($contactType, NULL); // Using new Dedupe rule. $ruleParams = array('contact_type' => $contactType, 'used' => 'Unsupervised'); $fieldsArray = CRM_Dedupe_BAO_Rule::dedupeRuleFields($ruleParams); if (is_array($fieldsArray)) { foreach ($fieldsArray as $value) { $customFieldId = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomField', $value, 'id', 'column_name'); $value = $customFieldId ? 'custom_' . $customFieldId : $value; $tmpContactField[trim($value)] = CRM_Utils_Array::value(trim($value), $contactFields); if (!$status) { $title = $tmpContactField[trim($value)]['title'] . ' (match to contact)'; } else { $title = $tmpContactField[trim($value)]['title']; } $tmpContactField[trim($value)]['title'] = $title; } } $extIdentifier = CRM_Utils_Array::value('external_identifier', $contactFields); if ($extIdentifier) { $tmpContactField['external_identifier'] = $extIdentifier; $tmpContactField['external_identifier']['title'] = CRM_Utils_Array::value('title', $extIdentifier) . ' (match to contact)'; } $fields = array_merge($fields, $tmpContactField); //Sorting fields in alphabetical order(CRM-1507) $fields = CRM_Utils_Array::crmArraySortByField($fields, 'title'); $fields = CRM_Utils_Array::index(array('name'), $fields); CRM_Core_BAO_Cache::setItem($fields, 'contact fields', $cacheKeyString); } self::$_importableFields[$cacheKeyString] = $fields; if (!$isProfile) { $fields = array_merge(array('do_not_import' => array('title' => ts('- do not import -'))), self::$_importableFields[$cacheKeyString]); } return $fields; }
/** * Get html and cache results. * * @param $url * * @return array|NULL * array of gettingStarted items; or NULL if not available */ public function _getHtml($url) { $httpClient = new CRM_Utils_HttpClient(self::CHECK_TIMEOUT); list($status, $html) = $httpClient->get($url); if ($status !== CRM_Utils_HttpClient::STATUS_OK) { return NULL; } $tokensList = CRM_Utils_Token::getTokens($html); $this->replaceLinkToken($tokensList, $html); if ($html) { CRM_Core_BAO_Cache::setItem($html, 'dashboard', 'gettingStarted'); } return $html; }
/** * @param object $sort * @param string $cacheKey * @param int $start * @param int $end */ function fillupPrevNextCache($sort, $cacheKey, $start = 0, $end = 500) { $coreSearch = TRUE; // For custom searches, use the contactIDs method if (is_a($this, 'CRM_Contact_Selector_Custom')) { $sql = $this->_search->contactIDs($start, $end, $sort, TRUE); $replaceSQL = "SELECT contact_a.id as contact_id"; $coreSearch = FALSE; } else { $sql = $this->_query->searchQuery($start, $end, $sort, FALSE, $this->_query->_includeContactIds, FALSE, TRUE, TRUE); $replaceSQL = "SELECT contact_a.id as id"; } // CRM-9096 // due to limitations in our search query writer, the above query does not work // in cases where the query is being sorted on a non-contact table // this results in a fatal error :( // see below for the gross hack of trapping the error and not filling // the prev next cache in this situation // the other alternative of running the FULL query will just be incredibly inefficient // and slow things down way too much on large data sets / complex queries $insertSQL = "\nINSERT INTO civicrm_prevnext_cache ( entity_table, entity_id1, entity_id2, cacheKey, data )\nSELECT DISTINCT 'civicrm_contact', contact_a.id, contact_a.id, '{$cacheKey}', contact_a.display_name\n"; $sql = str_replace($replaceSQL, $insertSQL, $sql); $errorScope = CRM_Core_TemporaryErrorScope::ignoreException(); $result = CRM_Core_DAO::executeQuery($sql); unset($errorScope); if (is_a($result, 'DB_Error')) { // check if we get error during core search if ($coreSearch) { // in the case of error, try rebuilding cache using full sql which is used for search selector display // this fixes the bugs reported in CRM-13996 & CRM-14438 $this->rebuildPreNextCache($start, $end, $sort, $cacheKey); } else { // return if above query fails return; } } // also record an entry in the cache key table, so we can delete it periodically CRM_Core_BAO_Cache::setItem($cacheKey, 'CiviCRM Search PrevNextCache', $cacheKey); }
/** * Function returns formatted groupTree, sothat form can be easily build in template * * @param array $groupTree * @param int $groupCount * Group count by default 1, but can varry for multiple value custom data. * @param object $form * * @return array */ public static function formatGroupTree(&$groupTree, $groupCount = 1, &$form = NULL) { $formattedGroupTree = array(); $uploadNames = $formValues = array(); // retrieve qf key from url $qfKey = CRM_Utils_Request::retrieve('qf', 'String'); // fetch submitted custom field values later use to set as a default values if ($qfKey) { $submittedValues = CRM_Core_BAO_Cache::getItem('custom data', $qfKey); } foreach ($groupTree as $key => $value) { if ($key === 'info') { continue; } // add group information $formattedGroupTree[$key]['name'] = CRM_Utils_Array::value('name', $value); $formattedGroupTree[$key]['title'] = CRM_Utils_Array::value('title', $value); $formattedGroupTree[$key]['help_pre'] = CRM_Utils_Array::value('help_pre', $value); $formattedGroupTree[$key]['help_post'] = CRM_Utils_Array::value('help_post', $value); $formattedGroupTree[$key]['collapse_display'] = CRM_Utils_Array::value('collapse_display', $value); $formattedGroupTree[$key]['collapse_adv_display'] = CRM_Utils_Array::value('collapse_adv_display', $value); $formattedGroupTree[$key]['style'] = CRM_Utils_Array::value('style', $value); // this params needed of bulding multiple values $formattedGroupTree[$key]['is_multiple'] = CRM_Utils_Array::value('is_multiple', $value); $formattedGroupTree[$key]['extends'] = CRM_Utils_Array::value('extends', $value); $formattedGroupTree[$key]['extends_entity_column_id'] = CRM_Utils_Array::value('extends_entity_column_id', $value); $formattedGroupTree[$key]['extends_entity_column_value'] = CRM_Utils_Array::value('extends_entity_column_value', $value); $formattedGroupTree[$key]['subtype'] = CRM_Utils_Array::value('subtype', $value); $formattedGroupTree[$key]['max_multiple'] = CRM_Utils_Array::value('max_multiple', $value); // add field information foreach ($value['fields'] as $k => $properties) { $properties['element_name'] = "custom_{$k}_-{$groupCount}"; if ($value = CRM_Utils_Request::retrieve($properties['element_name'], 'String', $form, FALSE, NULL, 'POST')) { $formValues[$properties['element_name']] = $value; } elseif (isset($submittedValues[$properties['element_name']])) { $properties['element_value'] = $submittedValues[$properties['element_name']]; } if (isset($properties['customValue']) && !CRM_Utils_System::isNull($properties['customValue']) && !isset($properties['element_value'])) { if (isset($properties['customValue'][$groupCount])) { $properties['element_name'] = "custom_{$k}_{$properties['customValue'][$groupCount]['id']}"; $formattedGroupTree[$key]['table_id'] = $properties['customValue'][$groupCount]['id']; if ($properties['data_type'] == 'File') { $properties['element_value'] = $properties['customValue'][$groupCount]; $uploadNames[] = $properties['element_name']; } else { $properties['element_value'] = $properties['customValue'][$groupCount]['data']; } } } unset($properties['customValue']); $formattedGroupTree[$key]['fields'][$k] = $properties; } } if ($form) { if (count($formValues)) { $qf = $form->get('qfKey'); $form->assign('qfKey', $qf); CRM_Core_BAO_Cache::setItem($formValues, 'custom data', $qf); } // hack for field type File $formUploadNames = $form->get('uploadNames'); if (is_array($formUploadNames)) { $uploadNames = array_unique(array_merge($formUploadNames, $uploadNames)); } $form->set('uploadNames', $uploadNames); } return $formattedGroupTree; }