/**
  * 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;
 }
Пример #3
0
 /**
  * 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;
 }
Пример #4
0
 /**
  *
  *
  * @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;
 }
Пример #5
0
 /**
  * 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');
 }
Пример #6
0
 /**
  * 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;
 }