/** * Given a item_id (request parameter 'id') returns a list of direct children for use in the hierarchy browser * Returned data is JSON format */ public function getFacetHierarchyLevel() { $va_access_values = caGetUserAccessValues($this->request); $ps_facet_name = $this->request->getParameter('facet', pString); $this->opo_browse->setTypeRestrictions(array($this->opn_type_restriction_id)); if (!is_array($va_facet_info = $this->opo_browse->getInfoForFacet($ps_facet_name))) { return null; } $va_facet = $this->opo_browse->getFacet($ps_facet_name, array('sort' => 'name', 'checkAccess' => $va_access_values)); $pa_ids = explode(";", $ps_ids = $this->request->getParameter('id', pString)); if (!sizeof($pa_ids)) { $pa_ids = array(null); } $va_level_data = array(); if (($vn_max_items_per_page = $this->request->getParameter('max', pInteger)) < 1 || $vn_max_items_per_page > 1000) { $vn_max_items_per_page = null; } $t_model = $this->opo_datamodel->getInstanceByTableName($this->ops_tablename, true); $o_config = Configuration::load(); if (!is_array($va_sorts = $o_config->getList($this->ops_tablename . '_hierarchy_browser_sort_values')) || !sizeof($va_sorts)) { $va_sorts = array(); } foreach ($va_sorts as $vn_i => $vs_sort_fld) { $va_tmp = explode(".", $vs_sort_fld); if ($va_tmp[1] == 'preferred_labels') { $va_tmp[0] = $vs_label_table_name; if (!($va_tmp[1] = $va_tmp[2])) { $va_tmp[1] = $vs_label_display_field_name; } unset($va_tmp[2]); $va_sorts[$vn_i] = join(".", $va_tmp); } } if (!in_array($vs_sort_dir = strtolower($o_config->get($this->ops_tablename . '_hierarchy_browser_sort_direction')), array('asc', 'desc'))) { $vs_sort_dir = 'asc'; } $va_expanded_facet = array(); $t_item = new ca_list_items(); foreach ($va_facet as $vn_id => $va_facet_item) { $va_expanded_facet[$vn_id] = true; $va_ancestors = $t_item->getHierarchyAncestors($vn_id, array('idsOnly' => true)); if (is_array($va_ancestors)) { foreach ($va_ancestors as $vn_ancestor_id) { $va_expanded_facet[$vn_ancestor_id] = true; } } } foreach ($pa_ids as $pn_id) { $va_json_data = array('_primaryKey' => 'item_id'); $va_tmp = explode(":", $pn_id); $vn_id = $va_tmp[0]; $vn_start = (int) $va_tmp[1]; if ($vn_start < 0) { $vn_start = 0; } switch ($va_facet_info['type']) { case 'attribute': // is it a list attribute? $t_element = new ca_metadata_elements(); if ($t_element->load(array('element_code' => $va_facet_info['element_code']))) { if ($t_element->get('datatype') == 3) { // 3=list $t_list = new ca_lists(); if (!$vn_id) { $vn_id = $t_list->getRootListItemID($t_element->get('list_id')); } $t_item = new ca_list_items($vn_id); $va_children = $t_item->getHierarchyChildren(null, array('idsOnly' => true)); $va_child_counts = $t_item->getHierarchyChildCountsForIDs($va_children); $qr_res = caMakeSearchResult('ca_list_items', $va_children); $vs_pk = $t_model->primaryKey(); if ($qr_res) { while ($qr_res->nextHit()) { $vn_parent_id = $qr_res->get('ca_list_items.parent_id'); $vn_item_id = $qr_res->get('ca_list_items.item_id'); if (!isset($va_expanded_facet[$vn_item_id])) { continue; } $va_item = array(); $va_item['item_id'] = $vn_item_id; $va_item['name'] = $qr_res->get('ca_list_items.preferred_labels'); $va_item['children'] = isset($va_child_counts[$vn_item_id]) && $va_child_counts[$vn_item_id] ? $va_child_counts[$vn_item_id] : 0; $va_json_data[$vn_item_id] = $va_item; } } } } break; case 'label': // label facet $va_facet_info['table'] = $this->ops_tablename; // fall through to default case // fall through to default case default: if (!$vn_id) { $va_hier_ids = $this->opo_browse->getHierarchyIDsForFacet($ps_facet_name, array('checkAccess' => $va_access_values)); $t_item = $this->opo_datamodel->getInstanceByTableName($va_facet_info['table']); $t_item->load($vn_id); $vn_id = $vn_root = $t_item->getHierarchyRootID(); $va_hierarchy_list = $t_item->getHierarchyList(true); $vn_last_id = null; $vn_c = 0; foreach ($va_hierarchy_list as $vn_i => $va_item) { if (!in_array($vn_i, $va_hier_ids)) { continue; } // only show hierarchies that have items in browse result if ($vn_start <= $vn_c) { $va_item['item_id'] = $va_item[$t_item->primaryKey()]; if (!isset($va_facet[$va_item['item_id']]) && $vn_root == $va_item['item_id']) { continue; } unset($va_item['parent_id']); unset($va_item['label']); $va_json_data[$va_item['item_id']] = $va_item; $vn_last_id = $va_item['item_id']; } $vn_c++; if (!is_null($vn_max_items_per_page) && $vn_c >= $vn_max_items_per_page + $vn_start) { break; } } if (sizeof($va_json_data) == 2) { // if only one hierarchy root (root + _primaryKey in array) then don't bother showing it $vn_id = $vn_last_id; unset($va_json_data[$vn_last_id]); } } if ($vn_id) { $vn_c = 0; foreach ($va_facet as $vn_i => $va_item) { if ($va_item['parent_id'] == $vn_id) { if ($vn_start <= $vn_c) { $va_item['item_id'] = $va_item['id']; $va_item['name'] = $va_item['label']; $va_item['children'] = $va_item['child_count']; unset($va_item['label']); unset($va_item['child_count']); unset($va_item['id']); $va_json_data[$va_item['item_id']] = $va_item; } $vn_c++; if (!is_null($vn_max_items_per_page) && $vn_c >= $vn_max_items_per_page + $vn_start) { break; } } } } break; } $vs_rank_fld = $t_item->getProperty('RANK'); $va_sorted_items = array(); foreach ($va_json_data as $vn_id => $va_node) { if (!is_array($va_node)) { continue; } $vs_key = preg_replace('![^A-Za-z0-9]!', '_', $va_node['name']); if (isset($va_node['sort']) && $va_node['sort']) { $va_sorted_items[$va_node['sort']][$vs_key] = $va_node; } else { if ($vs_rank_fld && ($vs_rank = (int) sprintf("%08d", $va_node[$vs_rank_fld]))) { $va_sorted_items[$vs_rank][$vs_key] = $va_node; } else { $va_sorted_items[$vs_key][$vs_key] = $va_node; } } } ksort($va_sorted_items); if ($vs_sort_dir == 'desc') { $va_sorted_items = array_reverse($va_sorted_items); } $va_json_data = array(); $va_sorted_items = array_slice($va_sorted_items, $vn_start, $vn_max_items_per_page); foreach ($va_sorted_items as $vs_k => $va_v) { ksort($va_v); if ($vs_sort_dir == 'desc') { $va_v = array_reverse($va_v); } $va_json_data = array_merge($va_json_data, $va_v); } $va_json_data['_itemCount'] = sizeof($va_json_data); $va_json_data['_sortOrder'] = array_keys($va_json_data); $va_json_data['_primaryKey'] = $t_model->primaryKey(); // pass the name of the primary key so the hierbrowser knows where to look for item_id's $va_level_data[$pn_id] = $va_json_data; } if (!trim($this->request->getParameter('init', pString))) { $this->opo_result_context->setParameter($ps_facet_name . '_browse_last_id', $pn_id); $this->opo_result_context->saveContext(); } $this->view->setVar('facet_list', $va_level_data); return $this->render('Browse/facet_hierarchy_level_json.php'); }
/** * Returns labels associated with this row. By default all labels - preferred and non-preferred, and from all locales - * are returned. You can limit the returned labels to specified locales by passing a list of locale_ids (numeric ids, *not* locale codes) * in $pn_locale_ids. Similarly you can limit return labels to preferred on non-preferred by setting $pn_mode to __CA_LABEL_TYPE_PREFERRED__ * or __CA_LABEL_TYPE_NONPREFERRED__ * * getLabels() returns an associated array keyed by the primary key of the item the label is attached to; each value is an array keyed by locale_id, the values of which * is a list of associative arrays with the label table data. This return format is designed to be digested by the displayHelper function caExtractValuesByUserLocale() * * @param array $pa_locale_ids * @param int $pn_mode * @param boolean $pb_dont_cache * @param array $pa_options Array of options. Supported options are: * row_id = The row_id to return labels for. If omitted the id of the currently loaded row is used. If row_id is not set and now row is loaded then getLabels() will return null. * restrict_to_types = an optional array of numeric type ids or alphanumeric type identifiers to restrict the returned labels to. The types are list items in a list specified in app.conf (or, if not defined there, by hardcoded constants in the model) * restrictToTypes = synonym for restrict_to_types * extractValuesByUserLocale = if set returned array of values is filtered to include only values appropriate for the current user's locale * forDisplay = if true, a simple list of labels ready for display is returned; implies the extractValuesByUserLocale option * * @return array List of labels */ public function getLabels($pa_locale_ids = null, $pn_mode = __CA_LABEL_TYPE_ANY__, $pb_dont_cache = true, $pa_options = null) { if (isset($pa_options['restrictToTypes']) && (!isset($pa_options['restrict_to_types']) || !$pa_options['restrict_to_types'])) { $pa_options['restrict_to_types'] = $pa_options['restrictToTypes']; } if (!($vn_id = $this->getPrimaryKey()) && !(isset($pa_options['row_id']) && ($vn_id = $pa_options['row_id']))) { return null; } if (isset($pa_options['forDisplay']) && $pa_options['forDisplay']) { $pa_options['extractValuesByUserLocale'] = true; } if ($pn_mode == __CA_LABEL_TYPE_ANY__ && caGetBundleAccessLevel($this->tableName(), 'preferred_labels') == __CA_BUNDLE_ACCESS_NONE__) { $pn_mode = __CA_LABEL_TYPE_NONPREFERRED__; } if ($pn_mode == __CA_LABEL_TYPE_ANY__ && caGetBundleAccessLevel($this->tableName(), 'nonpreferred_labels') == __CA_BUNDLE_ACCESS_NONE__) { $pn_mode = __CA_LABEL_TYPE_PREFERRED__; } if ($pn_mode == __CA_LABEL_TYPE_PREFERRED__ && caGetBundleAccessLevel($this->tableName(), 'preferred_labels') == __CA_BUNDLE_ACCESS_NONE__) { return null; } if ($pn_mode == __CA_LABEL_TYPE_NONPREFERRED__ && caGetBundleAccessLevel($this->tableName(), 'nonpreferred_labels') == __CA_BUNDLE_ACCESS_NONE__) { return null; } if (!is_array($pa_options)) { $pa_options = array(); } $vs_cache_key = caMakeCacheKeyFromOptions(array_merge($pa_options, array('table_name' => $this->tableName(), 'id' => $vn_id, 'mode' => (int) $pn_mode))); if (!$pb_dont_cache && is_array($va_tmp = LabelableBaseModelWithAttributes::$s_label_cache[$this->tableName()][$vn_id][$vs_cache_key])) { return $va_tmp; } if (!($t_label = $this->_DATAMODEL->getInstanceByTableName($this->getLabelTableName(), true))) { return null; } if ($this->inTransaction()) { $o_trans = $this->getTransaction(); $t_label->setTransaction($o_trans); } $vs_label_where_sql = 'WHERE (l.' . $this->primaryKey() . ' = ?)'; $vs_locale_join_sql = ''; if ($pa_locale_ids) { $vs_label_where_sql .= ' AND (l.locale_id IN (' . join(',', $pa_locale_ids) . '))'; } $vs_locale_join_sql = 'INNER JOIN ca_locales AS loc ON loc.locale_id = l.locale_id'; $vs_list_code = null; if ($t_label->hasField('is_preferred')) { switch ($pn_mode) { case __CA_LABEL_TYPE_PREFERRED__: $vs_list_code = $this->_CONFIG->get($this->tableName() . '_preferred_label_type_list'); $vs_label_where_sql .= ' AND (l.is_preferred = 1)'; break; case __CA_LABEL_TYPE_NONPREFERRED__: $vs_list_code = $this->_CONFIG->get($this->tableName() . '_nonpreferred_label_type_list'); $vs_label_where_sql .= ' AND (l.is_preferred = 0)'; break; default: $vs_list_code = $this->_CONFIG->get($this->tableName() . '_preferred_label_type_list'); break; } if (!$vs_list_code) { if ($t_label_instance = $this->getLabelTableInstance()) { $vs_list_code = $t_label_instance->getFieldInfo('type_id', 'LIST_CODE'); } } } // limit related items to a specific type $vs_restrict_to_type_sql = ''; if (isset($pa_options['restrict_to_type']) && $pa_options['restrict_to_type']) { if (!isset($pa_options['restrict_to_types']) || !is_array($pa_options['restrict_to_types'])) { $pa_options['restrict_to_types'] = array(); } $pa_options['restrict_to_types'][] = $pa_options['restrict_to_type']; } if (isset($pa_options['restrict_to_types']) && $pa_options['restrict_to_types'] && is_array($pa_options['restrict_to_types']) && $vs_list_code) { $t_list = new ca_lists(); $t_list_item = new ca_list_items(); $va_ids = array(); foreach ($pa_options['restrict_to_types'] as $vs_type) { if (!($vn_restrict_to_type_id = (int) $t_list->getItemIDFromList($vs_list_code, $vs_type))) { $vn_restrict_to_type_id = (int) $vs_type; } if ($vn_restrict_to_type_id) { $va_children = $t_list_item->getHierarchyChildren($vn_restrict_to_type_id, array('idsOnly' => true)); $va_ids = array_merge($va_ids, $va_children); $va_ids[] = $vn_restrict_to_type_id; } } if (sizeof($va_ids) > 0) { $vs_restrict_to_type_sql = ' AND l.type_id IN (' . join(',', $va_ids) . ')'; } } $o_db = $this->getDb(); $qr_res = $o_db->query("\n \t\t\t\tSELECT l.*, loc.country locale_country, loc.language locale_language, loc.dialect locale_dialect, loc.name locale_name\n \t\t\t\tFROM " . $this->getLabelTableName() . " l\n \t\t\t\t{$vs_locale_join_sql}\n \t\t\t\t{$vs_label_where_sql}\n \t\t\t\t{$vs_restrict_to_type_sql}\n \t\t\t\tORDER BY\n \t\t\t\t\tloc.name\n \t\t\t", (int) $vn_id); $va_labels = array(); $t_label->clear(); while ($qr_res->nextRow()) { $va_labels[$vn_id][$qr_res->get('locale_id')][] = array_merge($qr_res->getRow(), array('form_element' => $t_label->htmlFormElement($this->getLabelDisplayField(), null))); } if (isset($pa_options['extractValuesByUserLocale']) && $pa_options['extractValuesByUserLocale']) { $va_labels = caExtractValuesByUserLocale($va_labels); } if (isset($pa_options['forDisplay']) && $pa_options['forDisplay']) { $vs_display_field = $this->getLabelDisplayField(); $va_flattened_labels = array(); foreach ($va_labels as $vn_id => $va_label_list) { foreach ($va_label_list as $vn_i => $va_label) { $va_flattened_labels[] = $va_label[$vs_display_field]; } } $va_labels = $va_flattened_labels; } LabelableBaseModelWithAttributes::$s_label_cache[$this->tableName()][$vn_id][$vs_cache_key] = $va_labels; return $va_labels; }
/** * When source restrictions are specified, the search will only consider items of the given sources. * If you specify a source that has hierarchical children then the children will automatically be included * in the restriction. You may pass numeric source_id and alphanumeric source codes interchangeably. * * @param array $pa_source_codes_or_ids List of source_id or code values to filter search by. When set, the search will only consider items of the specified sources. Using a hierarchical parent source will automatically include its children in the restriction. * @param array $pa_options Options include * includeSubsources = include any child sources in the restriction. Default is true. * @return boolean True on success, false on failure */ public function setSourceRestrictions($pa_source_codes_or_ids, $pa_options = null) { $t_instance = $this->opo_datamodel->getInstanceByTableName($this->ops_tablename, true); if (!$pa_source_codes_or_ids) { return false; } if (is_array($pa_source_codes_or_ids) && !sizeof($pa_source_codes_or_ids)) { return false; } if (!is_array($pa_source_codes_or_ids)) { $pa_source_codes_or_ids = array($pa_source_codes_or_ids); } $t_list = new ca_lists(); if (!method_exists($t_instance, 'getSourceListCode')) { return false; } if (!($vs_list_name = $t_instance->getSourceListCode())) { return false; } $va_source_list = $t_instance->getSourceList(); $this->opa_search_source_ids = array(); foreach ($pa_source_codes_or_ids as $vs_code_or_id) { if (!strlen($vs_code_or_id)) { continue; } if (!is_numeric($vs_code_or_id)) { $vn_source_id = $t_list->getItemIDFromList($vs_list_name, $vs_code_or_id); } else { $vn_source_id = (int) $vs_code_or_id; } if (!$vn_source_id) { return false; } if (isset($va_source_list[$vn_source_id]) && $va_source_list[$vn_source_id]) { // is valid source for this subject if (caGetOption('includeSubsources', $pa_options, true)) { // See if there are any child sources $t_item = new ca_list_items($vn_source_id); $va_ids = $t_item->getHierarchyChildren(null, array('idsOnly' => true)); $va_ids[] = $vn_source_id; $this->opa_search_source_ids = array_merge($this->opa_search_source_ids, $va_ids); } } } return true; }
/** * * * @param array $pa_source_codes_or_ids List of source codes or ids * @param array $pa_options Options include * includeSubsources = include any child sources in the restriction. Default is true. * @return array List of source_ids */ private function _convertSourceCodesToIDs($pa_source_codes_or_ids, $pa_options = null) { $vs_md5 = caMakeCacheKeyFromOptions($pa_source_codes_or_ids); if (isset(BrowseEngine::$s_source_id_cache[$vs_md5])) { return BrowseEngine::$s_source_id_cache[$vs_md5]; } if (isset($pa_options['instance']) && is_object($pa_options['instance'])) { $t_instance = $pa_options['instance']; } else { $t_instance = $this->getSubjectInstance(); } $va_source_ids = array(); if (!$pa_source_codes_or_ids) { return false; } if (is_array($pa_source_codes_or_ids) && !sizeof($pa_source_codes_or_ids)) { return false; } if (!is_array($pa_source_codes_or_ids)) { $pa_source_codes_or_ids = array($pa_source_codes_or_ids); } $t_list = new ca_lists(); if (!method_exists($t_instance, 'getSourceListCode')) { return false; } if (!($vs_list_name = $t_instance->getSourceListCode())) { return false; } $va_source_list = $t_instance->getSourceList(); foreach ($pa_source_codes_or_ids as $vs_code_or_id) { if (!trim($vs_code_or_id)) { continue; } if (!is_numeric($vs_code_or_id)) { $vn_source_id = $t_list->getItemIDFromList($vs_list_name, $vs_code_or_id); } else { $vn_source_id = (int) $vs_code_or_id; } if (!$vn_source_id) { return false; } if (isset($va_source_list[$vn_source_id]) && $va_source_list[$vn_source_id]) { // is valid source for this subject // See if there are any child sources if (caGetOption('includeSubsources', $pa_options, true) && $this->opb_dont_expand_source_restrictions) { $t_item = new ca_list_items($vn_source_id); $va_ids = $t_item->getHierarchyChildren(null, array('idsOnly' => true)); } $va_ids[] = $vn_source_id; $va_source_ids = array_merge($va_source_ids, $va_ids); } } $va_source_ids = array_keys(array_flip($va_source_ids)); BrowseEngine::$s_source_id_cache[$vs_md5] = $va_source_ids; return $va_source_ids; }
/** * Given a item_id (request parameter 'id') returns a list of direct children for use in the hierarchy browser * Returned data is JSON format */ public function getFacetHierarchyLevel() { $va_access_values = caGetUserAccessValues($this->request); $ps_facet_name = $this->request->getParameter('facet', pString); $this->opo_browse->setTypeRestrictions(array($this->opn_type_restriction_id)); if (!is_array($va_facet_info = $this->opo_browse->getInfoForFacet($ps_facet_name))) { return null; } $va_facet = $this->opo_browse->getFacet($ps_facet_name, array('sort' => 'name', 'checkAccess' => $va_access_values)); $pa_ids = explode(";", $ps_ids = $this->request->getParameter('id', pString)); if (!sizeof($pa_ids)) { $pa_ids = array(null); } $va_level_data = array(); if (($vn_max_items_per_page = $this->request->getParameter('max', pInteger)) < 1 || $vn_max_items_per_page > 1000) { $vn_max_items_per_page = null; } $t_model = $this->opo_datamodel->getInstanceByTableName($this->ops_tablename, true); $va_expanded_facet = array(); $t_item = new ca_list_items(); foreach ($va_facet as $vn_id => $va_facet_item) { $va_expanded_facet[$vn_id] = true; $va_ancestors = $t_item->getHierarchyAncestors($vn_id, array('idsOnly' => true)); if (is_array($va_ancestors)) { foreach ($va_ancestors as $vn_ancestor_id) { $va_expanded_facet[$vn_ancestor_id] = true; } } } foreach ($pa_ids as $pn_id) { $va_json_data = array('_primaryKey' => 'item_id'); $va_tmp = explode(":", $pn_id); $vn_id = $va_tmp[0]; $vn_start = (int) $va_tmp[1]; if ($vn_start < 0) { $vn_start = 0; } switch ($va_facet_info['type']) { case 'attribute': // is it a list attribute? $t_element = new ca_metadata_elements(); if ($t_element->load(array('element_code' => $va_facet_info['element_code']))) { if ($t_element->get('datatype') == 3) { // 3=list $t_list = new ca_lists(); if (!$vn_id) { $vn_id = $t_list->getRootListItemID($t_element->get('list_id')); } $t_item = new ca_list_items($vn_id); $va_children = $t_item->getHierarchyChildren(null, array('idsOnly' => true)); $va_child_counts = $t_item->getHierarchyChildCountsForIDs($va_children); $qr_res = caMakeSearchResult('ca_list_items', $va_children); $vs_pk = $t_model->primaryKey(); if ($qr_res) { while ($qr_res->nextHit()) { $vn_parent_id = $qr_res->get('ca_list_items.parent_id'); $vn_item_id = $qr_res->get('ca_list_items.item_id'); if (!isset($va_expanded_facet[$vn_item_id])) { continue; } $va_item = array(); $va_item['item_id'] = $vn_item_id; $va_item['name'] = $qr_res->get('ca_list_items.preferred_labels'); $va_item['children'] = isset($va_child_counts[$vn_item_id]) && $va_child_counts[$vn_item_id] ? $va_child_counts[$vn_item_id] : 0; $va_json_data[$vn_item_id] = $va_item; } } } } break; case 'label': // label facet $va_facet_info['table'] = $this->ops_tablename; // fall through to default case // fall through to default case default: if (!$vn_id) { $va_hier_ids = $this->opo_browse->getHierarchyIDsForFacet($ps_facet_name, array('checkAccess' => $va_access_values)); $t_item = $this->opo_datamodel->getInstanceByTableName($va_facet_info['table']); $t_item->load($vn_id); $vn_id = $vn_root = $t_item->getHierarchyRootID(); $va_hierarchy_list = $t_item->getHierarchyList(true); $vn_last_id = null; $vn_c = 0; foreach ($va_hierarchy_list as $vn_i => $va_item) { if (!in_array($vn_i, $va_hier_ids)) { continue; } // only show hierarchies that have items in browse result if ($vn_start <= $vn_c) { $va_item['item_id'] = $va_item[$t_item->primaryKey()]; if (!isset($va_facet[$va_item['item_id']]) && $vn_root == $va_item['item_id']) { continue; } unset($va_item['parent_id']); unset($va_item['label']); $va_json_data[$va_item['item_id']] = $va_item; $vn_last_id = $va_item['item_id']; } $vn_c++; if (!is_null($vn_max_items_per_page) && $vn_c >= $vn_max_items_per_page + $vn_start) { break; } } if (sizeof($va_json_data) == 2) { // if only one hierarchy root (root + _primaryKey in array) then don't bother showing it $vn_id = $vn_last_id; unset($va_json_data[$vn_last_id]); } } if ($vn_id) { $vn_c = 0; foreach ($va_facet as $vn_i => $va_item) { if ($va_item['parent_id'] == $vn_id) { if ($vn_start <= $vn_c) { $va_item['item_id'] = $va_item['id']; $va_item['name'] = isset($va_facet_info['use_idno']) && $va_facet_info['use_idno'] ? $va_item['idno'] : $va_item['label']; $va_item['children'] = $va_item['child_count']; unset($va_item['label']); unset($va_item['child_count']); unset($va_item['id']); $va_json_data[$va_item['item_id']] = $va_item; } $vn_c++; if (!is_null($vn_max_items_per_page) && $vn_c >= $vn_max_items_per_page + $vn_start) { break; } } } } break; } $va_level_data[$pn_id] = $va_json_data; } if (!trim($this->request->getParameter('init', pString))) { $this->opo_result_context->setParameter($ps_facet_name . '_browse_last_id', $pn_id); $this->opo_result_context->saveContext(); } $this->view->setVar('facet_list', $va_level_data); return $this->render('Browse/facet_hierarchy_level_json.php'); }
/** * Returns an associative array of relationship types for the relationship * organized by the sub_type_id specified by $ps_orientation. If $ps_orientation is the name of the "right" table * then sub_type_left_id is used for keys in the array, if $ps_orientation is the name of the "left" table * then sub_type_right_id is used for keys. * * For example, for ca_objects_x_entities, if $ps_orientation is ca_objects then then sub_type_right_id is * used as the key; if ca_entities is passed then sub_type_left_id is used; if a table name is passed that * is not either side of the relation then an empty array is returned * */ public function getRelationshipTypesBySubtype($ps_orientation, $pn_type_id, $pa_options = null) { unset($pa_options['request']); if (!$this->hasField('type_id')) { return array(); } $vs_left_table_name = $this->getLeftTableName(); $vs_right_table_name = $this->getRightTableName(); $vb_dont_include_subtypes_in_type_restriction = caGetOptions('dont_include_subtypes_in_type_restriction', $pa_options, false); $o_db = $this->getDb(); $t_rel_type = new ca_relationship_types(); $vs_restrict_to_relationship_type_sql = ''; if (isset($pa_options['restrict_to_relationship_types']) && $pa_options['restrict_to_relationship_types']) { if (!is_array($pa_options['restrict_to_relationship_types'])) { $pa_options['restrict_to_relationship_types'] = array($pa_options['restrict_to_relationship_types']); } if (sizeof($pa_options['restrict_to_relationship_types'])) { $va_restrict_to_type_list = array(); foreach ($pa_options['restrict_to_relationship_types'] as $vs_type_code) { if (!strlen(trim($vs_type_code))) { continue; } $va_criteria = array('table_num' => $this->tableNum()); if (is_numeric($vs_type_code)) { $va_criteria['type_id'] = (int) $vs_type_code; } else { $va_criteria['type_code'] = $vs_type_code; } if ($t_rel_type->load($va_criteria)) { $va_restrict_to_type_list[] = "(crt.hier_left >= " . $t_rel_type->get('hier_left') . " AND crt.hier_right <= " . $t_rel_type->get('hier_right') . ")"; } } if (sizeof($va_restrict_to_type_list)) { $vs_restrict_to_relationship_type_sql = " AND (" . join(' OR ', $va_restrict_to_type_list) . ")"; } } } $qr_res = $o_db->query("\n\t\t\t\tSELECT *\n\t\t\t\tFROM ca_relationship_types crt\n\t\t\t\tINNER JOIN ca_relationship_type_labels AS crtl ON crt.type_id = crtl.type_id\n\t\t\t\tWHERE\n\t\t\t\t\t(crt.table_num = ?)\n\t\t\t\t\t{$vs_restrict_to_relationship_type_sql}\n\t\t\t", $this->tableNum()); // Support hierarchical subtypes - if the subtype restriction is a type with parents then include those as well // Allows subtypes to "inherit" bindings from parent types $t_list_item = new ca_list_items($pn_type_id); if (!$vb_dont_include_subtypes_in_type_restriction) { if (!is_array($va_ancestor_ids = $t_list_item->getHierarchyAncestors(null, array('idsOnly' => true, 'includeSelf' => true)))) { $va_ancestor_ids = array(); } // remove hierarchy root from ancestor list, otherwise invalid bindings // from root nodes (which are not "real" rel types) may be inherited array_pop($va_ancestor_ids); } else { $va_ancestor_ids = array($pn_type_id); } $va_types = array(); $va_parent_ids = array(); $vn_l = 0; $vn_root_id = $t_rel_type->load(array('parent_id' => null, 'table_num' => $this->tableNum())) ? $t_rel_type->getPrimaryKey() : null; $va_hier = array(); if ($vs_left_table_name === $vs_right_table_name) { // ---------------------------------------------------------------------------------------- // self relationship while ($qr_res->nextRow()) { $va_row = $qr_res->getRow(); $vn_parent_id = $va_row['parent_id']; $va_hier[$vn_parent_id][] = $va_row['type_id']; // skip type if it has a subtype set and it's not in our list $vs_subtype_orientation = null; $vs_subtype = null; if ($va_row['sub_type_left_id'] && !in_array($va_row['sub_type_left_id'], $va_ancestor_ids)) { // not left if ($va_row['sub_type_right_id'] && !in_array($va_row['sub_type_right_id'], $va_ancestor_ids)) { // not left and not right continue; } else { // not left and right $vs_subtype = $va_row['sub_type_left_id']; $vs_subtype_orientation = "left"; } } else { if ($va_row['sub_type_left_id'] && in_array($va_row['sub_type_left_id'], $va_ancestor_ids)) { // left if ($va_row['sub_type_right_id'] && in_array($va_row['sub_type_right_id'], $va_ancestor_ids)) { // left and right $vs_subtype = $va_row['sub_type_right_id']; $vs_subtype_orientation = ""; } else { // left and not right $vs_subtype_orientation = "right"; $vs_subtype = $va_row['sub_type_right_id']; } } } if (!$vs_subtype) { $vs_subtype = 'NULL'; } switch ($vs_subtype_orientation) { case 'left': $va_tmp = $va_row; $vs_key = strlen($va_tmp['rank']) > 0 ? sprintf("%08d", (int) $va_tmp['rank']) . preg_replace('![^A-Za-z0-9_]+!', '_', $va_tmp['typename_reverse']) : preg_replace('![^A-Za-z0-9_]+!', '_', $va_tmp['typename_reverse']); $va_tmp['typename'] = $va_tmp['typename_reverse']; unset($va_tmp['typename_reverse']); // we pass the typename adjusted for direction in 'typename', so there's no need to include typename_reverse in the returned values $va_types[$vn_parent_id][$vs_subtype][$vs_key][$va_row['type_id']][$va_row['locale_id']] = $va_tmp; break; case 'right': $va_tmp = $va_row; $vs_key = strlen($va_tmp['rank']) > 0 ? sprintf("%08d", (int) $va_tmp['rank']) . preg_replace('![^A-Za-z0-9_]+!', '_', $va_tmp['typename']) : preg_replace('![^A-Za-z0-9_]+!', '_', $va_tmp['typename']); unset($va_tmp['typename_reverse']); // we pass the typename adjusted for direction in 'typename', so there's no need to include typename_reverse in the returned values $va_types[$vn_parent_id][$vs_subtype][$vs_key][$va_row['type_id']][$va_row['locale_id']] = $va_tmp; break; default: $va_tmp = $va_row; if (trim($va_tmp['typename']) == trim($va_tmp['typename_reverse'])) { // // If the sides of the self-relationship are the same then treat it like a normal relationship type: one entry in the // list and a plain type_id value // unset($va_tmp['typename_reverse']); // we pass the typename adjusted for direction in 'typename', so there's no need to include typename_reverse in the returned values $va_tmp['direction'] = null; $vs_key = strlen($va_tmp['rank']) > 0 ? sprintf("%08d", (int) $va_tmp['rank']) . preg_replace('![^A-Za-z0-9_]+!', '_', $va_tmp['typename']) : preg_replace('![^A-Za-z0-9_]+!', '_', $va_tmp['typename']); $va_types[$vn_parent_id][$vs_subtype][$vs_key][$va_row['type_id']][$va_row['locale_id']] = $va_tmp; } else { // // If each side of the self-relationship type are different then add both to the list with special type_id values that // indicate the directionality of the typename (ltor = left to right = "typename"; rtor = right to left = "typename_reverse") // $va_tmp = $va_row; unset($va_tmp['typename_reverse']); // we pass the typename adjusted for direction in 'typename', so there's no need to include typename_reverse in the returned values $vs_key = strlen($va_tmp['rank']) > 0 ? sprintf("%08d", (int) $va_tmp['rank']) . preg_replace('![^A-Za-z0-9_]+!', '_', $va_tmp['typename']) : preg_replace('![^A-Za-z0-9_]+!', '_', $va_tmp['typename']); $va_tmp['direction'] = 'ltor'; $va_types[$vn_parent_id][$vs_subtype][$vs_key]['ltor_' . $va_row['type_id']][$va_row['locale_id']] = $va_tmp; $va_tmp = $va_row; $va_tmp['typename'] = $va_tmp['typename_reverse']; unset($va_tmp['typename_reverse']); // we pass the typename adjusted for direction in 'typename', so there's no need to include typename_reverse in the returned values $vs_key = strlen($va_tmp['rank']) > 0 ? sprintf("%08d", (int) $va_tmp['rank']) . preg_replace('![^A-Za-z0-9_]+!', '_', $va_tmp['typename_reverse']) : preg_replace('![^A-Za-z0-9_]+!', '_', $va_tmp['typename_reverse']); $va_tmp['direction'] = 'rtol'; $va_types[$vn_parent_id][$vs_subtype][$vs_key]['rtol_' . $va_row['type_id']][$va_row['locale_id']] = $va_tmp; } break; } } $va_types = $this->_processRelationshipHierarchy($vn_root_id, $va_hier, $va_types, 1); $va_processed_types = array('_type_map' => array()); $va_subtype_lookups = array(); foreach ($va_types as $vs_subtype => $va_types_by_subtype) { $va_types_by_locale = array(); foreach ($va_types_by_subtype as $vs_key => $va_types_by_key) { foreach ($va_types_by_key as $vs_k => $va_v) { foreach ($va_v as $vs_k2 => $vs_v2) { $va_types_by_locale[$vs_k][$vs_k2] = $vs_v2; } } } if (!$vb_dont_include_subtypes_in_type_restriction) { // include mapping from parent type used in restriction to child types that inherit the binding if ($vs_subtype != 'NULL' && (!isset($va_subtype_lookups[$vs_subtype]) || !$va_subtype_lookups[$vs_subtype])) { $va_children = $t_list_item->getHierarchyChildren($vs_subtype, array('idsOnly' => true)); foreach ($va_children as $vn_child) { $va_processed_types['_type_map'][$vn_child] = $vs_subtype; } $va_subtype_lookups[$vs_subtype] = true; } } $va_processed_types[$vs_subtype] = caExtractValuesByUserLocale($va_types_by_locale, null, null, array('returnList' => true)); } } else { // ---------------------------------------------------------------------------------------- // regular relationship if (!in_array($ps_orientation, array($vs_left_table_name, $vs_right_table_name))) { return array(); } while ($qr_res->nextRow()) { $va_row = $qr_res->getRow(); $vn_parent_id = $va_row['parent_id']; $va_hier[$vn_parent_id][] = $va_row['type_id']; if ($ps_orientation == $vs_left_table_name) { // right-to-left // expand subtype $va_subtypes_to_check = $va_row['sub_type_left_id'] > 0 ? caMakeTypeIDList($vs_left_table_name, array($va_row['sub_type_left_id'])) : null; // skip type if it has a subtype set and it's not in our list if (!(!$va_subtypes_to_check || sizeof(array_intersect($va_subtypes_to_check, $va_ancestor_ids)))) { continue; } $vs_subtype = $va_row['sub_type_right_id']; $vs_key = strlen($va_row['rank']) > 0 ? sprintf("%08d", (int) $va_row['rank']) . preg_replace('![^A-Za-z0-9_]+!', '_', $va_row['typename']) : preg_replace('![^A-Za-z0-9_]+!', '_', $va_row['typename']); } else { // left-to-right // expand subtype $va_subtypes_to_check = $va_row['sub_type_right_id'] > 0 ? caMakeTypeIDList($vs_right_table_name, array($va_row['sub_type_right_id'])) : null; // skip type if it has a subtype set and it's not in our list if (!(!$va_subtypes_to_check || sizeof(array_intersect($va_subtypes_to_check, $va_ancestor_ids)))) { continue; } $vs_subtype = $va_row['sub_type_left_id']; $va_row['typename'] = $va_row['typename_reverse']; $vs_key = strlen($va_row['rank']) > 0 ? sprintf("%08d", (int) $va_row['rank']) . preg_replace('![^A-Za-z0-9_]+!', '_', $va_row['typename_reverse']) : preg_replace('![^A-Za-z0-9_]+!', '_', $va_row['typename_reverse']); } unset($va_row['typename_reverse']); // we pass the typename adjusted for direction in '_display', so there's no need to include typename_reverse in the returned values if (!$vs_subtype) { $vs_subtype = 'NULL'; } $vn_type_id = $va_row['type_id']; $va_types[$vn_parent_id][$vs_subtype][$vs_key][$vn_type_id][$va_row['locale_id']] = $va_row; } $va_types = $this->_processRelationshipHierarchy($vn_root_id, $va_hier, $va_types, 1); $va_processed_types = array('_type_map' => array()); $va_subtype_lookups = array(); foreach ($va_types as $vs_subtype => $va_types_by_subtype) { $va_types_by_locale = array(); foreach ($va_types_by_subtype as $vs_key => $va_types_by_key) { foreach ($va_types_by_key as $vn_locale_id => $va_t) { if (!is_array($va_types_by_locale[$vn_locale_id])) { $va_types_by_locale[$vn_locale_id] = array(); } $va_types_by_locale[$vn_locale_id] += $va_t; } } if (!$vb_dont_include_subtypes_in_type_restriction) { // include mapping from parent type used in restriction to child types that inherit the binding if ($vs_subtype != 'NULL' && (!isset($va_subtype_lookups[$vs_subtype]) || !$va_subtype_lookups[$vs_subtype])) { $va_children = $t_list_item->getHierarchyChildren($vs_subtype, array('idsOnly' => true)); foreach ($va_children as $vn_child) { $va_processed_types['_type_map'][$vn_child] = $vs_subtype; } $va_subtype_lookups[$vs_subtype] = true; } } $va_processed_types[$vs_subtype] = caExtractValuesByUserLocale($va_types_by_locale, null, null, array('returnList' => true)); } } return $va_processed_types; }