/**
  *
  *
  * @param $ps_field -
  * @param $pa_options -
  *		returnAsArray - 
  * 		delimiter -
  *		template -
  *		locale -
  *		returnAllLocales - Returns requested value in all locales for which it is defined. Default is false. Note that this is not supported for hierarchy specifications (eg. ca_objects.hierarchy).
  *		direction - For hierarchy specifications (eg. ca_objects.hierarchy) this determines the order in which the hierarchy is returned. ASC will return the hierarchy root first while DESC will return it with the lowest node first. Default is ASC.
  *		top - For hierarchy specifications (eg. ca_objects.hierarchy) this option, if set, will limit the returned hierarchy to the first X nodes from the root down. Default is to not limit.
  *		bottom - For hierarchy specifications (eg. ca_objects.hierarchy) this option, if set, will limit the returned hierarchy to the first X nodes from the lowest node up. Default is to not limit.
  * 		hierarchicalDelimiter - Text to place between items in a hierarchy for a hierarchical specification (eg. ca_objects.hierarchy) when returning as a string
  *		removeFirstItems - If set to a non-zero value, the specified number of items at the top of the hierarchy will be omitted. For example, if set to 2, the root and first child of the hierarchy will be omitted. Default is zero (don't delete anything).
  *		checkAccess = array of access values to filter results by; if defined only items with the specified access code(s) are returned. Only supported for <table_name>.hierarchy.preferred_labels and <table_name>.children.preferred_labels because these returns sets of items. For <table_name>.parent.preferred_labels, which returns a single row at most, you should do access checking yourself. (Everything here applies equally to nonpreferred_labels)
  *		sort = optional bundles to sort returned values on. Only supported for <table_name>.children.preferred_labels. The bundle specifiers are fields with or without tablename.
  *		sort_direction = direction to sort results by, either 'asc' for ascending order or 'desc' for descending order; default is 'asc'
  *		convertCodesToDisplayText = if true then non-preferred label type_ids are automatically converted to display text in the current locale; default is false (return non-preferred label type_id raw)
  */
 public function get($ps_field, $pa_options = null)
 {
     $vs_template = isset($pa_options['template']) ? $pa_options['template'] : null;
     $vb_return_as_array = isset($pa_options['returnAsArray']) ? (bool) $pa_options['returnAsArray'] : false;
     $vb_return_all_locales = isset($pa_options['returnAllLocales']) ? (bool) $pa_options['returnAllLocales'] : false;
     $vs_delimiter = isset($pa_options['delimiter']) ? $pa_options['delimiter'] : ' ';
     $vb_convert_codes_to_display_text = isset($pa_options['convertCodesToDisplayText']) ? (bool) $pa_options['convertCodesToDisplayText'] : false;
     if ($vb_return_all_locales && !$vb_return_as_array) {
         $vb_return_as_array = true;
     }
     // if desired try to return values in a preferred language/locale
     $va_preferred_locales = null;
     if (isset($pa_options['locale']) && $pa_options['locale']) {
         $va_preferred_locales = array($pa_options['locale']);
     }
     // does get refer to an attribute?
     $va_tmp = explode('.', $ps_field);
     if ($va_tmp[1] == 'hierarchy' && sizeof($va_tmp) == 2) {
         $va_tmp[2] = 'preferred_labels';
         $ps_field = join('.', $va_tmp);
     }
     $t_label = $this->getLabelTableInstance();
     $t_instance = $this;
     if (sizeof($va_tmp) >= 3 && ($va_tmp[2] == 'preferred_labels' && (!$va_tmp[3] || $t_label->hasField($va_tmp[3]))) || $va_tmp[1] == 'hierarchy') {
         switch ($va_tmp[1]) {
             case 'parent':
                 if ($this->isHierarchical() && ($vn_parent_id = $this->get($this->getProperty('HIERARCHY_PARENT_ID_FLD')))) {
                     $t_instance = $this->getAppDatamodel()->getInstanceByTableNum($this->tableNum());
                     if (!$t_instance->load($vn_parent_id)) {
                         $t_instance = $this;
                     } else {
                         unset($va_tmp[1]);
                         $va_tmp = array_values($va_tmp);
                     }
                 }
                 break;
             case 'children':
                 if ($this->isHierarchical()) {
                     unset($va_tmp[1]);
                     // remove 'children' from field path
                     $va_tmp = array_values($va_tmp);
                     $vs_childless_path = join('.', $va_tmp);
                     $va_data = array();
                     $va_children_ids = $this->getHierarchyChildren(null, array('idsOnly' => true));
                     if (is_array($va_children_ids) && sizeof($va_children_ids)) {
                         $t_instance = $this->getAppDatamodel()->getInstanceByTableNum($this->tableNum());
                         $vb_check_access = is_array($pa_options['checkAccess']) && $t_instance->hasField('access');
                         $va_sort = isset($pa_options['sort']) ? $pa_options['sort'] : null;
                         if (!is_array($va_sort) && $va_sort) {
                             $va_sort = array($va_sort);
                         }
                         if (!is_array($va_sort)) {
                             $va_sort = array();
                         }
                         $vs_sort_direction = isset($pa_options['sort_direction']) && in_array(strtolower($pa_options['sort_direction']), array('asc', 'desc')) ? strtolower($pa_options['sort_direction']) : 'asc';
                         $qr_children = $this->makeSearchResult($this->tableName(), $va_children_ids);
                         $vs_table = $this->tableName();
                         while ($qr_children->nextHit()) {
                             if ($vb_check_access && !in_array($qr_children->get("{$vs_table}.access"), $pa_options['checkAccess'])) {
                                 continue;
                             }
                             $vs_sort_key = '';
                             foreach ($va_sort as $vs_sort) {
                                 $vs_sort_key .= $vs_sort ? $qr_children->get($vs_sort) : 0;
                             }
                             if (!is_array($va_data[$vs_sort_key])) {
                                 $va_data[$vs_sort_key] = array();
                             }
                             $va_data[$vs_sort_key] = array_merge($va_data[$vs_sort_key], $qr_children->get($vs_childless_path, array_merge($pa_options, array('returnAsArray' => true))));
                         }
                         ksort($va_data);
                         if ($vs_sort_direction && $vs_sort_direction == 'desc') {
                             $va_data = array_reverse($va_data);
                         }
                         $va_sorted_data = array();
                         foreach ($va_data as $vs_sort_key => $va_items) {
                             foreach ($va_items as $vs_k => $vs_v) {
                                 $va_sorted_data[] = $vs_v;
                             }
                         }
                         $va_data = $va_sorted_data;
                     }
                     if ($vb_return_as_array) {
                         return $va_data;
                     } else {
                         return join($vs_delimiter, $va_data);
                     }
                 }
                 break;
             case 'hierarchy':
                 $vs_direction = isset($pa_options['direction']) ? strtoupper($pa_options['direction']) : null;
                 if (!in_array($vs_direction, array('ASC', 'DESC'))) {
                     $vs_direction = 'ASC';
                 }
                 $vn_top = (int) isset($pa_options['top']) ? strtoupper($pa_options['top']) : 0;
                 if ($vn_top < 0) {
                     $vn_top = 0;
                 }
                 $vn_bottom = (int) isset($pa_options['bottom']) ? strtoupper($pa_options['bottom']) : 0;
                 if ($vn_bottom < 0) {
                     $vn_bottom = 0;
                 }
                 $vs_pk = $this->primaryKey();
                 $vs_label_table_name = $this->getLabelTableName();
                 $t_label_instance = $this->getLabelTableInstance();
                 if (!$vs_template && ($vs_display_field = $t_label_instance->hasField($va_tmp[2]) ? $t_label_instance->tableName() . "." . $va_tmp[2] : ($this->hasField($va_tmp[2]) ? $this->tableName() . "." . $va_tmp[2] : null))) {
                     $vs_template = "^{$vs_display_field}";
                 }
                 $vn_top_id = null;
                 if (!($va_ancestor_list = $this->getHierarchyAncestors(null, array('idsOnly' => true, 'includeSelf' => true)))) {
                     $va_ancestor_list = array();
                 }
                 // TODO: this should really be in a model subclass
                 if ($this->tableName() == 'ca_objects' && $this->getAppConfig()->get('ca_objects_x_collections_hierarchy_enabled') && ($vs_coll_rel_type = $this->getAppConfig()->get('ca_objects_x_collections_hierarchy_relationship_type'))) {
                     require_once __CA_MODELS_DIR__ . '/ca_objects.php';
                     if ($this->getPrimaryKey() == $vn_top_id) {
                         $t_object = $this;
                     } else {
                         $t_object = new ca_objects($vn_top_id);
                     }
                     if (is_array($va_collections = $t_object->getRelatedItems('ca_collections', array('restrictToRelationshipTypes' => $vs_coll_rel_type)))) {
                         require_once __CA_MODELS_DIR__ . '/ca_collections.php';
                         $t_collection = new ca_collections();
                         foreach ($va_collections as $vn_i => $va_collection) {
                             if ($va_collections_ancestor_list = $t_collection->getHierarchyAncestors($va_collection['collection_id'], array('idsOnly' => true, 'includeSelf' => true))) {
                                 $va_ancestor_list = array_merge($va_ancestor_list, $va_collections_ancestor_list);
                             }
                             break;
                             // for now only process first collection (no polyhierarchies)
                         }
                     }
                 }
                 // remove root and children if so desired
                 if (isset($pa_options['removeFirstItems']) && (int) $pa_options['removeFirstItems'] > 0) {
                     for ($vn_i = 0; $vn_i < (int) $pa_options['removeFirstItems']; $vn_i++) {
                         array_pop($va_ancestor_list);
                     }
                 }
                 if ($vs_display_field != $va_tmp[2]) {
                     if ($this->hasField($va_tmp[2])) {
                         $vs_display_field = $va_tmp[2];
                     }
                 }
                 $vb_check_access = is_array($pa_options['checkAccess']) && $this->hasField('access');
                 if ($vb_check_access) {
                     $va_access_values = $this->getFieldValuesForIDs($va_ancestor_list, array('access'));
                     $va_ancestor_list = array();
                     foreach ($va_access_values as $vn_ancestor_id => $vn_access_value) {
                         if (in_array($vn_access_value, $pa_options['checkAccess'])) {
                             $va_ancestor_list[] = $vn_ancestor_id;
                         }
                     }
                 }
                 if ($vs_template) {
                     $va_tmp = caProcessTemplateForIDs($vs_template, $this->tableName(), $va_ancestor_list, array('returnAsArray' => true));
                 } else {
                     $va_tmp = $this->getPreferredDisplayLabelsForIDs($va_ancestor_list, array('returnAsArray' => true, 'returnAllLocales' => $vb_return_all_locales));
                 }
                 if ($vn_top > 0) {
                     $va_tmp = array_slice($va_tmp, sizeof($va_tmp) - $vn_top, $vn_top, true);
                 } else {
                     if ($vn_bottom > 0) {
                         $va_tmp = array_slice($va_tmp, 0, $vn_bottom, true);
                     }
                 }
                 if ($vs_direction == 'ASC') {
                     $va_tmp = array_reverse($va_tmp, true);
                 }
                 if (caGetOption('returnAsLink', $pa_options, false)) {
                     $va_tmp = caCreateLinksFromText(array_values($va_tmp), $this->tableName(), array_keys($va_tmp));
                 }
                 if ($vb_return_as_array) {
                     return $va_tmp;
                 } else {
                     $vs_hier_delimiter = isset($pa_options['hierarchicalDelimiter']) ? $pa_options['hierarchicalDelimiter'] : $pa_options['delimiter'];
                     return join($vs_hier_delimiter, $va_tmp);
                 }
                 break;
         }
     }
     switch (sizeof($va_tmp)) {
         case 1:
             switch ($va_tmp[0]) {
                 # ---------------------------------------------
                 case 'preferred_labels':
                     if (!$vb_return_as_array) {
                         $va_labels = caExtractValuesByUserLocale($t_instance->getPreferredLabels(), null, $va_preferred_locales);
                         $vs_disp_field = $this->getLabelDisplayField();
                         $va_values = array();
                         foreach ($va_labels as $vn_row_id => $va_label_list) {
                             foreach ($va_label_list as $vn_i => $va_label) {
                                 if ($vs_template) {
                                     $va_values[] = caProcessTemplate($vs_template, $va_label, array('removePrefix' => 'preferred_labels.'));
                                 } else {
                                     $va_values[] = $va_label[$vs_disp_field];
                                 }
                             }
                         }
                         return join($vs_delimiter, $va_values);
                     } else {
                         $va_labels = $t_instance->getPreferredLabels(null, false);
                         if ($vb_return_all_locales) {
                             return $va_labels;
                         } else {
                             // Simplify array by getting rid of third level array which is unnecessary since
                             // there is only ever one preferred label for a locale
                             $va_labels = caExtractValuesByUserLocale($va_labels, null, $va_preferred_locales);
                             $va_processed_labels = array();
                             foreach ($va_labels as $vn_label_id => $va_label_list) {
                                 $va_processed_labels[$vn_label_id] = $va_label_list[0];
                             }
                             return $va_processed_labels;
                         }
                     }
                     break;
                     # ---------------------------------------------
                 # ---------------------------------------------
                 case 'nonpreferred_labels':
                     if (!$vb_return_as_array) {
                         $vs_disp_field = $this->getLabelDisplayField();
                         $va_labels = caExtractValuesByUserLocale($t_instance->getNonPreferredLabels(), null, $va_preferred_locales);
                         $t_list = new ca_lists();
                         if ($vb_convert_codes_to_display_text) {
                             $va_types = $t_list->getItemsForList($this->getLabelTableInstance()->getFieldInfo('type_id', 'LIST_CODE'), array('extractValuesByUserLocale' => true));
                         }
                         $va_values = array();
                         foreach ($va_labels as $vn_row_id => $va_label_list) {
                             foreach ($va_label_list as $vn_i => $va_label) {
                                 if ($vs_template) {
                                     $va_label_values = $va_label;
                                     $va_label_values['typename_singular'] = $va_types[$va_label['type_id']]['name_singular'];
                                     $va_label_values['typename_plural'] = $va_types[$va_label['type_id']]['name_plural'];
                                     if ($vb_convert_codes_to_display_text) {
                                         $va_label_values['type_id'] = $va_types[$va_label['type_id']]['name_singular'];
                                     }
                                     $va_values[] = caProcessTemplate($vs_template, $va_label_values, array('removePrefix' => 'nonpreferred_labels.'));
                                 } else {
                                     if ($vb_convert_codes_to_display_text && $vs_disp_field == 'type_id') {
                                         $va_values[] = $va_types[$va_label[$vs_disp_field]]['name_singular'];
                                     } else {
                                         $va_values[] = $va_label[$vs_disp_field];
                                     }
                                 }
                             }
                         }
                         return join($vs_delimiter, $va_values);
                         $va_labels = caExtractValuesByUserLocale($t_instance->getNonPreferredLabels(null, false));
                         $vs_disp_field = $this->getLabelDisplayField();
                         $va_processed_labels = array();
                         foreach ($va_labels as $vn_label_id => $va_label_list) {
                             foreach ($va_label_list as $vn_i => $va_label) {
                                 $va_processed_labels[] = $va_label[$vs_disp_field];
                             }
                         }
                         return join($vs_delimiter, $va_processed_labels);
                     } else {
                         $va_labels = $t_instance->getNonPreferredLabels(null, false);
                         if ($vb_return_all_locales) {
                             return $va_labels;
                         } else {
                             return caExtractValuesByUserLocale($va_labels, null, $va_preferred_locales);
                         }
                     }
                     break;
                     # ---------------------------------------------
             }
             break;
         case 2:
         case 3:
             if ($va_tmp[0] === $t_instance->tableName()) {
                 switch ($va_tmp[1]) {
                     # ---------------------------------------------
                     case 'preferred_labels':
                         if (!$vb_return_as_array) {
                             if (isset($va_tmp[2]) && $va_tmp[2]) {
                                 $vs_disp_field = $va_tmp[2];
                             } else {
                                 $vs_disp_field = $this->getLabelDisplayField();
                             }
                             $va_labels = caExtractValuesByUserLocale($t_instance->getPreferredLabels(), null, $va_preferred_locales);
                             $va_values = array();
                             foreach ($va_labels as $vn_row_id => $va_label_list) {
                                 foreach ($va_label_list as $vn_i => $va_label) {
                                     if ($vs_template) {
                                         $va_values[] = caProcessTemplate($vs_template, $va_label, array('removePrefix' => 'preferred_labels.'));
                                     } else {
                                         $va_values[] = $va_label[$vs_disp_field];
                                     }
                                 }
                             }
                             return join($vs_delimiter, $va_values);
                         } else {
                             $va_labels = $t_instance->getPreferredLabels(null, false);
                             if (!$vb_return_all_locales) {
                                 // Simplify array by getting rid of third level array which is unnecessary since
                                 // there is only ever one preferred label for a locale
                                 $va_labels = caExtractValuesByUserLocale($va_labels, null, $va_preferred_locales);
                                 $va_processed_labels = array();
                                 foreach ($va_labels as $vn_label_id => $va_label_list) {
                                     $va_processed_labels[$vn_label_id] = $va_label_list[0];
                                 }
                                 $va_labels = $va_processed_labels;
                             }
                             if (isset($va_tmp[2]) && $va_tmp[2]) {
                                 // specific field
                                 if ($vb_return_all_locales) {
                                     foreach ($va_labels as $vn_label_id => $va_labels_by_locale) {
                                         foreach ($va_labels_by_locale as $vn_locale_id => $va_label_list) {
                                             foreach ($va_label_list as $vn_i => $va_label) {
                                                 $va_labels[$vn_label_id][$vn_locale_id][$vn_i] = $va_label[$va_tmp[2]];
                                             }
                                         }
                                     }
                                 } else {
                                     // get specified field value
                                     foreach ($va_labels as $vn_label_id => $va_label_info) {
                                         $va_labels[$vn_label_id] = $va_label_info[$va_tmp[2]];
                                     }
                                 }
                             }
                             return $va_labels;
                         }
                         break;
                         # ---------------------------------------------
                     # ---------------------------------------------
                     case 'nonpreferred_labels':
                         if (!$vb_return_as_array) {
                             if (isset($va_tmp[2]) && $va_tmp[2]) {
                                 $vs_disp_field = $va_tmp[2];
                             } else {
                                 $vs_disp_field = $this->getLabelDisplayField();
                             }
                             $va_labels = caExtractValuesByUserLocale($t_instance->getNonPreferredLabels(), null, $va_preferred_locales);
                             $t_list = new ca_lists();
                             if ($vb_convert_codes_to_display_text) {
                                 $va_types = $t_list->getItemsForList($this->getLabelTableInstance()->getFieldInfo('type_id', 'LIST_CODE'), array('extractValuesByUserLocale' => true));
                             }
                             $va_values = array();
                             foreach ($va_labels as $vn_row_id => $va_label_list) {
                                 foreach ($va_label_list as $vn_i => $va_label) {
                                     if ($vs_template) {
                                         $va_label_values = $va_label;
                                         $va_label_values['typename_singular'] = $va_types[$va_label['type_id']]['name_singular'];
                                         $va_label_values['typename_plural'] = $va_types[$va_label['type_id']]['name_plural'];
                                         if ($vb_convert_codes_to_display_text) {
                                             $va_label_values['type_id'] = $va_types[$va_label['type_id']]['name_singular'];
                                         }
                                         $va_values[] = caProcessTemplate($vs_template, $va_label_values, array('removePrefix' => 'nonpreferred_labels.'));
                                     } else {
                                         if ($vb_convert_codes_to_display_text && $vs_disp_field == 'type_id') {
                                             $va_values[] = $va_types[$va_label[$vs_disp_field]]['name_singular'];
                                         } else {
                                             $va_values[] = $va_label[$vs_disp_field];
                                         }
                                     }
                                 }
                             }
                             return join($vs_delimiter, $va_values);
                         } else {
                             $va_labels = $t_instance->getNonPreferredLabels(null, false);
                             if (!$vb_return_all_locales) {
                                 $va_labels = caExtractValuesByUserLocale($va_labels, null, $va_preferred_locales);
                             }
                             if (isset($va_tmp[2]) && $va_tmp[2]) {
                                 // specific field
                                 if ($vb_return_all_locales) {
                                     foreach ($va_labels as $vn_label_id => $va_labels_by_locale) {
                                         foreach ($va_labels_by_locale as $vn_locale_id => $va_label_list) {
                                             foreach ($va_label_list as $vn_i => $va_label) {
                                                 $va_labels[$vn_label_id][$vn_locale_id][$vn_i] = $va_label[$va_tmp[2]];
                                             }
                                         }
                                     }
                                 } else {
                                     // get specified field value
                                     foreach ($va_labels as $vn_label_id => $va_label_info) {
                                         foreach ($va_label_info as $vn_id => $va_label) {
                                             $va_labels[$vn_label_id] = $va_label[$va_tmp[2]];
                                         }
                                     }
                                 }
                             }
                             return $va_labels;
                         }
                         break;
                         # ---------------------------------------------
                 }
             }
             break;
     }
     return parent::get($ps_field, $pa_options);
 }
 /**
  * Given a item_id (request parameter 'id') returns a list of ancestors for use in the hierarchy browser
  * Returned data is JSON format
  */
 public function GetHierarchyAncestorList()
 {
     $vo_dm = Datamodel::load();
     $pn_id = $this->request->getParameter('id', pString);
     $va_params = $this->getItemIDComponents($pn_id, 'ca_objects');
     $vs_table = $va_params['table'];
     $vn_id = $va_params['id'];
     $vn_start = $va_params['start'];
     $t_item = $vo_dm->getInstanceByTableName($vs_table, true);
     $t_item->load($vn_id);
     $va_ancestors = array();
     if ($t_item->getPrimaryKey()) {
         $va_ancestors = array_reverse($t_item->getHierarchyAncestors(null, array('includeSelf' => true, 'idsOnly' => true)));
     }
     $vn_top_id = $va_ancestors[0];
     foreach ($va_ancestors as $vn_i => $vn_ancestor_id) {
         $va_ancestors[$vn_i] = $vs_table . '-' . $vn_ancestor_id;
     }
     // get collections
     if ($vs_table == 'ca_objects') {
         $t_item->load($vn_top_id);
         // try to pull related collections ��� the first one is considered the parent
         $va_cross_table_items = $t_item->getRelatedItems('ca_collections');
         if (is_array($va_cross_table_items)) {
             $t_collection = new ca_collections();
             foreach ($va_cross_table_items as $vn_x_item_id => $va_x_item) {
                 array_unshift($va_ancestors, 'ca_collections-' . $va_x_item['collection_id']);
                 if (!($va_collection_ancestor_list = $t_collection->getHierarchyAncestors($va_x_item['collection_id'], array('additionalTableToJoin' => 'ca_collection_labels', 'additionalTableJoinType' => 'LEFT', 'additionalTableSelectFields' => array('name', 'locale_id'), 'additionalTableWheres' => array('(ca_collection_labels.is_preferred = 1 OR ca_collection_labels.is_preferred IS NULL)'), 'includeSelf' => false)))) {
                     $va_collection_ancestor_list = array();
                 }
                 foreach ($va_collection_ancestor_list as $vn_id => $va_collection_ancestor) {
                     array_unshift($va_ancestors, 'ca_collections-' . $va_collection_ancestor['NODE']['collection_id']);
                 }
                 break;
                 // for now only show first one
             }
         }
     }
     $this->view->setVar('ancestors', $va_ancestors);
     return $this->render(str_replace(' ', '_', $this->ops_name_singular) . '_hierarchy_ancestors_json.php');
 }
 /**
  *
  */
 private function _getHierarchyLocationHTMLFormBundleInfo($po_request, $ps_form_name, $ps_placement_code, $pa_options = null, $pa_bundle_settings = null)
 {
     $vs_view_path = isset($pa_options['viewPath']) && $pa_options['viewPath'] ? $pa_options['viewPath'] : $po_request->getViewsDirectoryPath();
     $o_view = new View($po_request, "{$vs_view_path}/bundles/");
     if (!is_array($pa_bundle_settings)) {
         $pa_bundle_settings = array();
     }
     if (!($vs_label_table_name = $this->getLabelTableName())) {
         return '';
     }
     $o_view->setVar('id_prefix', $ps_form_name);
     $o_view->setVar('placement_code', $ps_placement_code);
     $o_view->setVar('t_subject', $this);
     if (!($vn_id = $this->getPrimaryKey())) {
         $vn_parent_id = $vn_id = $po_request->getParameter($this->HIERARCHY_PARENT_ID_FLD, pString);
     } else {
         $vn_parent_id = $this->get($this->HIERARCHY_PARENT_ID_FLD);
     }
     $vs_display_fld = $this->getLabelDisplayField();
     if ($this->supportsPreferredLabelFlag()) {
         if (!($va_ancestor_list = $this->getHierarchyAncestors($vn_id, array('additionalTableToJoin' => $vs_label_table_name, 'additionalTableJoinType' => 'LEFT', 'additionalTableSelectFields' => array($vs_display_fld, 'locale_id'), 'additionalTableWheres' => array('(' . $vs_label_table_name . '.is_preferred = 1 OR ' . $vs_label_table_name . '.is_preferred IS NULL)'), 'includeSelf' => true)))) {
             $va_ancestor_list = array();
         }
     } else {
         if (!($va_ancestor_list = $this->getHierarchyAncestors($vn_id, array('additionalTableToJoin' => $vs_label_table_name, 'additionalTableJoinType' => 'LEFT', 'additionalTableSelectFields' => array($vs_display_fld, 'locale_id'), 'includeSelf' => true)))) {
             $va_ancestor_list = array();
         }
     }
     $va_ancestors_by_locale = array();
     $vs_pk = $this->primaryKey();
     $vs_idno_field = $this->getProperty('ID_NUMBERING_ID_FIELD');
     $vs_hierarchy_type = $this->getProperty('HIERARCHY_TYPE');
     foreach ($va_ancestor_list as $vn_ancestor_id => $va_info) {
         switch ($vs_hierarchy_type) {
             case __CA_HIER_TYPE_SIMPLE_MONO__:
                 if (!$va_info['NODE']['parent_id']) {
                     continue 2;
                 }
                 break;
             case __CA_HIER_TYPE_MULTI_MONO__:
                 if (!$va_info['NODE']['parent_id']) {
                     $vn_item_id = $va_info['NODE'][$vs_pk];
                     $va_ancestors_by_locale[$vn_item_id][$vn_locale_id] = array('item_id' => $vn_item_id, 'parent_id' => $va_info['NODE']['parent_id'], 'label' => $this->getHierarchyName($vn_item_id), 'idno' => $va_info['NODE'][$vs_idno_field], 'locale_id' => null, 'table' => $this->tableName());
                     continue 2;
                 }
                 break;
         }
         if (!$va_info['NODE']['parent_id'] && $vb_dont_show_root) {
             continue;
         }
         $vn_locale_id = isset($va_info['NODE']['locale_id']) ? $va_info['NODE']['locale_id'] : null;
         $va_ancestor = array('item_id' => $vn_item_id = $va_info['NODE'][$vs_pk], 'parent_id' => $va_info['NODE']['parent_id'], 'label' => $va_info['NODE'][$vs_display_fld] ? $va_info['NODE'][$vs_display_fld] : $va_info['NODE'][$vs_idno_field], 'idno' => $va_info['NODE'][$vs_idno_field], 'locale_id' => $vn_locale_id, 'table' => $this->tableName());
         $va_ancestors_by_locale[$vn_item_id][$vn_locale_id] = $va_ancestor;
     }
     $va_ancestor_list = array_reverse(caExtractValuesByUserLocale($va_ancestors_by_locale), true);
     if (!$this->getPrimaryKey()) {
         $va_ancestor_list[null] = array($this->primaryKey() => '', $this->getLabelDisplayField() => _t('New %1', $this->getProperty('NAME_SINGULAR')));
     }
     $o_view->setVar('object_collection_collection_ancestors', array());
     // collections to display as object parents when ca_objects_x_collections_hierarchy_enabled is enabled
     if ($this->tableName() == 'ca_objects' && $this->getAppConfig()->get('ca_objects_x_collections_hierarchy_enabled')) {
         $vs_object_collection_rel_type = $this->getAppConfig()->get('ca_objects_x_collections_hierarchy_relationship_type');
         // Is object part of a collection?
         $va_object_ids = array_keys($va_ancestor_list);
         $vn_top_object_id = array_shift($va_object_ids);
         if ($vn_top_object_id != $this->getPrimaryKey()) {
             $t_object = $this->getAppDatamodel()->getInstanceByTableName("ca_objects", true);
             $t_object->load($vn_top_object_id);
         } else {
             $t_object = $this;
         }
         if (is_array($va_collections = $t_object->getRelatedItems('ca_collections', array('restrictToRelationshipTypes' => array($vs_object_collection_rel_type))))) {
             $va_related_collections_by_level = array();
             foreach ($va_collections as $vs_key => $va_collection) {
                 $va_related_collections_by_level[$va_collection['collection_id']] = array('item_id' => $va_collection['collection_id'], 'parent_id' => $va_collection['parent_id'], 'label' => $va_collection['label'], 'idno' => $va_collection['idno'], 'table' => 'ca_collections');
                 $t_collection = new ca_collections();
                 if (!($va_collection_ancestor_list = $t_collection->getHierarchyAncestors($va_collection['collection_id'], array('additionalTableToJoin' => 'ca_collection_labels', 'additionalTableJoinType' => 'LEFT', 'additionalTableSelectFields' => array('name', 'locale_id'), 'additionalTableWheres' => array('(ca_collection_labels.is_preferred = 1 OR ca_collection_labels.is_preferred IS NULL)'), 'includeSelf' => false)))) {
                     $va_collection_ancestor_list = array();
                 }
                 $vn_i = 1;
                 foreach ($va_collection_ancestor_list as $vn_id => $va_collection_ancestor) {
                     $va_related_collections_by_level[$va_collection_ancestor['NODE']['collection_id']] = array('item_id' => $va_collection_ancestor['NODE']['collection_id'], 'parent_id' => $va_collection_ancestor['NODE']['parent_id'], 'label' => $va_collection_ancestor['NODE']['name'], 'idno' => $va_collection_ancestor['NODE']['idno'], 'table' => 'ca_collections');
                     $vn_i++;
                 }
                 break;
                 // only process the first collection (for now)
             }
             $o_view->setVar('object_collection_collection_ancestors', array_reverse($va_related_collections_by_level, true));
         }
     }
     $o_view->setVar('parent_id', $vn_parent_id);
     $o_view->setVar('ancestors', $va_ancestor_list);
     $o_view->setVar('id', $this->getPrimaryKey());
     $o_view->setVar('settings', $pa_bundle_settings);
     return $o_view;
 }
     $vs_label_detail_link = "<p>" . caDetailLink($this->request, $qr_res->get("{$vs_table}.preferred_labels.name"), '', $vs_table, $vn_id) . "</p>";
     $vs_idno_detail_link = "<p class='idno'>" . $qr_res->get("{$vs_table}.idno") . "</p>";
     if ($qr_res->get('ca_objects.dc_date.dc_dates_value')) {
         $vs_date_link = "<p>" . $qr_res->get('ca_objects.dc_date', array('returnAsLink' => true, 'delimiter' => '; ', 'template' => '^dc_dates_value')) . "</p>";
     } else {
         $vs_date_link = "";
     }
     if ($qr_res->get('ca_objects.type_id') == 23 || $qr_res->get('ca_objects.type_id') == 26 || $qr_res->get('ca_objects.type_id') == 25 || $qr_res->get('ca_objects.type_id') == 24 || $qr_res->get('ca_objects.type_id') == 27) {
         $vs_type_link = "<p>" . $qr_res->get('ca_objects.type_id', array('convertCodesToDisplayText' => true)) . "</p>";
     } else {
         $vs_type_link = "";
     }
     if ($qr_res->get('ca_objects.type_id') == 23 || $qr_res->get('ca_objects.type_id') == 26 || $qr_res->get('ca_objects.type_id') == 25 || $qr_res->get('ca_objects.type_id') == 24 || $qr_res->get('ca_objects.type_id') == 27) {
         $va_collection_id = $qr_res->get('ca_collections.collection_id');
         $t_collection = new ca_collections($va_collection_id);
         $vn_parent_ids = $t_collection->getHierarchyAncestors($va_collection_id, array('idsOnly' => true));
         $vn_highest_level = end($vn_parent_ids);
         $t_top_level = new ca_collections($vn_highest_level);
         $vs_collection_link = "<p>" . caNavLink($this->request, $t_top_level->get('ca_collections.preferred_labels'), '', 'Detail', 'collections', $vn_highest_level) . "</p>";
     }
 }
 if ($vs_table == 'ca_objects') {
     if ($qr_res->get('ca_objects.type_id') == 25) {
         $va_icon = "<i class='glyphicon glyphicon-volume-up'></i>";
     } elseif ($qr_res->get('ca_objects.type_id') == 26) {
         $va_icon = "<i class='glyphicon glyphicon-film'></i>";
     } elseif ($qr_res->get('ca_objects.type_id') == 30 && !$qr_res->getMediaTag('ca_object_representations.media', 'medium', array('checkAccess' => $va_access_values))) {
         $va_icon = "<i class='glyphicon glyphicon-book'></i>";
     } elseif ($qr_res->get('ca_objects.type_id') == 1903) {
         $vn_parent_id = $qr_res->get('ca_objects.parent_id');
         $t_copy = new ca_objects($vn_parent_id);