コード例 #1
0
 /**
  * 
  */
 public function Info()
 {
     $o_dm = Datamodel::load();
     $t_display = new ca_bundle_displays($vn_display_id = $this->_getDisplayID());
     $this->view->setVar('bundle_displays', caExtractValuesByUserLocale($t_display->getBundleDisplays(array('user_id' => $this->request->getUserID(), 'access' => __CA_BUNDLE_DISPLAY_EDIT_ACCESS__)), null, array()));
     return $this->render('widget_bundle_display_info_html.php', true);
 }
コード例 #2
0
 public function __construct($ps_widget_path, $pa_settings)
 {
     $this->title = _t('Records by status');
     $this->description = _t('Displays objects or authority items by cataloguing status');
     parent::__construct($ps_widget_path, $pa_settings);
     $this->opo_config = Configuration::load($ps_widget_path . '/conf/recordsByStatus.conf');
     $this->opo_datamodel = Datamodel::load();
     # -- get status values
     $t_lists = new ca_lists();
     $va_statuses = caExtractValuesByUserLocale($t_lists->getItemsForList("workflow_statuses"));
     $va_status_info = array();
     $va_status_values = array();
     foreach ($va_statuses as $i => $va_info) {
         $va_status_info[$va_info["item_value"]] = $va_info["name_singular"];
         $va_status_values[] = $va_info["item_value"];
     }
     $this->opa_status_display_names = $va_status_info;
     $this->opa_status_values = $va_status_values;
     $this->opa_table_display_names = array('ca_objects' => _t('Objects'), 'ca_entities' => _t('Entities'), 'ca_places' => _t('Places'), 'ca_occurrences' => _t('Occurrences'), 'ca_sets' => _t('Sets'), 'ca_collections' => _t('Collections'), 'ca_object_representations' => _t('Object representations'), 'ca_object_lots' => _t('Object lots'));
     foreach ($this->opa_table_display_names as $vs_table => $vs_display) {
         if (!$this->getRequest() || !$this->getRequest()->user->canDoAction("can_use_records_by_status_widget_{$vs_table}")) {
             foreach (BaseWidget::$s_widget_settings['recordsByStatusWidget']["display_type"]["options"] as $vs_setting_display => $vs_setting_table) {
                 if ($vs_setting_table == $vs_table) {
                     unset(BaseWidget::$s_widget_settings['recordsByStatusWidget']["display_type"]["options"][$vs_setting_display]);
                 }
             }
         }
     }
 }
コード例 #3
0
ファイル: ShowController.php プロジェクト: guaykuru/pawtucket
 public function displaySet()
 {
     $pn_set_id = $this->request->getParameter('set_id', pInteger);
     $t_set = new ca_sets($pn_set_id);
     $t_list = new ca_lists();
     $va_access_values = caGetUserAccessValues($this->request);
     $this->view->setVar('t_set', $t_set);
     $this->view->setVar('set_presentation_types', caExtractValuesByUserLocale($t_list->getItemsForList('set_presentation_types')));
     $this->view->setVar('access_values', $va_access_values);
     $this->render('features_contents_html.php');
 }
コード例 #4
0
 public function ListForms()
 {
     AssetLoadManager::register('tableList');
     $t_form = new ca_search_forms();
     $this->view->setVar('t_form', $t_form);
     $this->view->setVar('form_list', $va_forms = caExtractValuesByUserLocale($t_form->getForms(array('user_id' => $this->request->getUserID(), 'access' => __CA_SEARCH_FORM_EDIT_ACCESS__)), null, null, array()));
     $o_result_context = new ResultContext($this->request, 'ca_search_forms', 'basic_search');
     $o_result_context->setAsLastFind();
     $o_result_context->setResultList(is_array($va_forms) ? array_keys($va_forms) : array());
     $o_result_context->saveContext();
     $this->view->setVar('table_list', caFilterTableList($t_form->getFieldInfo('table_num', 'BOUNDS_CHOICE_LIST')));
     $this->render('search_form_list_html.php');
 }
コード例 #5
0
 public function renderWidget($ps_widget_id, &$pa_settings)
 {
     parent::renderWidget($ps_widget_id, $pa_settings);
     $this->opo_view->setVar('request', $this->getRequest());
     $t_set = new ca_sets();
     $va_tables = array("ca_objects", "ca_entities", "ca_places", "ca_object_lots", "ca_storage_locations", "ca_collections", "ca_occurrences");
     $va_sets = array();
     foreach ($va_tables as $vs_table) {
         $va_sets[$vs_table][] = caExtractValuesByUserLocale($t_set->getSets(array('table' => $vs_table, 'user_id' => $this->request->getUserID())));
     }
     $this->opo_view->setVar("sets_by_table", $va_sets);
     return $this->opo_view->render('main_html.php');
 }
コード例 #6
0
 /**
  * Returns string representing the name of the item the browse will return
  *
  * If $ps_mode is 'singular' [default] then the singular version of the name is returned, otherwise the plural is returned
  */
 public function browseName($ps_mode = 'singular')
 {
     $vb_type_restriction_has_changed = false;
     $vn_type_id = $this->opo_result_context->getTypeRestriction($vb_type_restriction_has_changed);
     $t_list = new ca_lists();
     $t_list->load(array('list_code' => 'occurrence_types'));
     $t_list_item = new ca_list_items();
     $t_list_item->load(array('list_id' => $t_list->getPrimaryKey(), 'parent_id' => null));
     $va_hier = caExtractValuesByUserLocale($t_list_item->getHierarchyWithLabels());
     if (!($vs_name = $ps_mode == 'singular' ? $va_hier[$vn_type_id]['name_singular'] : $va_hier[$vn_type_id]['name_plural'])) {
         $vs_name = '???';
     }
     return $vs_name;
 }
 public function testInsertLoadAndDeleteCycleWithCaObjectsModel()
 {
     $t_list = new ca_lists();
     $va_object_types = $t_list->getItemsForList('object_types');
     $this->assertGreaterThan(0, sizeof($va_object_types), "No object types available");
     $va_object_types = caExtractValuesByUserLocale($va_object_types);
     $this->assertGreaterThan(0, sizeof($va_object_types), "No locale-filtered object types available");
     $vn_locale_id = 1;
     $t_object = new ca_objects();
     $t_object->setMode(ACCESS_WRITE);
     $vn_item_id = 0;
     foreach ($va_object_types as $va_object_type) {
         if (intval($va_object_type['is_enabled']) === 1) {
             $vn_item_id = $va_object_type['item_id'];
         }
     }
     $this->assertGreaterThan(0, $vn_item_id, 'No enabled object type found');
     $t_object->set('type_id', $vn_item_id);
     $t_object->set('locale_id', $vn_locale_id);
     $t_object->set('idno', time());
     $t_object->addAttribute(array('description' => 'Test description', 'locale_id' => $vn_locale_id), 'description');
     $vb_res = $t_object->insert();
     $this->assertTrue($vb_res !== false, 'Insert returned non-true value');
     // insert() returns false OR the primary key, therefore simply asserting $vb_res being true doesn't cut it
     $this->assertEquals($t_object->numErrors(), 0, "Errors on insert: " . join('; ', $t_object->getErrors()));
     $this->opa_test_record_ids['ca_objects'][] = $t_object->getPrimaryKey();
     $vb_res = $t_object->addLabel(array('name' => 'Unit test object'), $vn_locale_id, null, true);
     $this->assertGreaterThan(0, $vb_res, 'AddLabel returned zero value but should return non-zero label_id: ' . join('; ', $t_object->getErrors()));
     $t_object2 = new ca_objects();
     $vb_res = $t_object2->load($t_object->getPrimaryKey());
     $this->assertTrue($vb_res, 'Load of newly created record failed [record does not seem to exist or return row id was invalid?]');
     $this->assertEquals($t_object2->getLabelForDisplay(), 'Unit test object', 'Retrieved row label does not match');
     $this->assertEquals($t_object2->getAttributesForDisplay('description'), 'Test description', 'Retrieved value for attribute "description" does not match expected value');
     // try to search for it
     $o_search = new ObjectSearch();
     $qr_hits = $o_search->search("Unit test object");
     $this->assertGreaterThan(0, $qr_hits->numHits(), 'Search for ca_object by label found no results');
     $vb_found_object = false;
     while ($qr_hits->nextHit()) {
         if ($qr_hits->get('object_id') == $t_object->getPrimaryKey()) {
             $vb_found_object = true;
             break;
         }
     }
     $this->assertTrue($vb_found_object, 'ca_object was not in returned search results for ca_object by label');
     // try delete
     $t_object->delete(true, array('hard' => true));
     $this->assertEquals($t_object->numErrors(), 0, "Errors on delete: " . join('; ', $t_object->getErrors()));
 }
コード例 #8
0
 public function Edit($pa_values = null, $pa_options = null)
 {
     AssetLoadManager::register('bundleableEditor');
     $t_element = $this->getElementObject();
     $t_restriction = new ca_metadata_type_restrictions(null, true);
     $this->view->setVar('available_settings', $t_element->getAvailableSettings());
     $this->view->setVar('type_list', $t_restriction->getTypeListsForTables());
     $va_initial_values = array();
     if ($t_element->getPrimaryKey()) {
         $va_sub_elements = array();
         /* BaseModel::getHierarchyChildren orders by PK, but we need to order by rank */
         $vo_db = new Db();
         $qr_result = $vo_db->query("\n\t\t\t\tSELECT cmel.*, cme.* \n\t\t\t\tFROM ca_metadata_elements cme\n\t\t\t\tLEFT JOIN ca_metadata_element_labels AS cmel ON cme.element_id = cmel.element_id\n\t\t\t\tWHERE\n\t\t\t\t\tcme.parent_id = ?\n\t\t\t\tORDER BY\n\t\t\t\t\tcme.rank\n\t\t\t", (int) $t_element->get('element_id'));
         while ($qr_result->nextRow()) {
             $va_row = $qr_result->getRow();
             if (!$va_row['name']) {
                 $va_row['name'] = $va_row['element_code'];
             }
             $va_sub_elements[$qr_result->get('element_id')][$qr_result->get('locale_id')] = $va_row;
         }
         $va_sub_elements = caExtractValuesByUserLocale($va_sub_elements);
         $this->view->setVar('sub_elements', $va_sub_elements);
         // get restrictions
         $this->view->setVar('type_restrictions', $va_type_restrictions = $t_element->getTypeRestrictions());
         $va_restriction_settings = $t_restriction->getAvailableSettings();
         if (is_array($va_type_restrictions)) {
             foreach ($va_type_restrictions as $va_restriction) {
                 if ($t_restriction->load($va_restriction['restriction_id'])) {
                     foreach ($va_restriction_settings as $vs_setting => $va_setting_info) {
                         if (!is_array($va_settings = $t_restriction->getSettings())) {
                             $va_settings = array();
                         }
                         $va_initial_values[$t_restriction->getPrimaryKey()] = array_merge($t_restriction->getFieldValuesArray(), $va_settings);
                     }
                 }
             }
         }
     }
     $this->view->setVar('initial_restriction_values', $va_initial_values);
     if ($vn_parent_id = $this->request->getParameter('parent_id', pInteger)) {
         $this->view->setVar('parent_id', $vn_parent_id);
     }
     $this->view->setVar('t_restriction', $t_restriction);
     $this->render('elements_edit_html.php');
 }
コード例 #9
0
 public function renderWidget($ps_widget_id, &$pa_settings)
 {
     parent::renderWidget($ps_widget_id, $pa_settings);
     $this->opo_view->setVar('request', $this->getRequest());
     $t_form = new ca_search_forms();
     if (!($vn_form_id = (int) $pa_settings["form_code"])) {
         $va_forms = caExtractValuesByUserLocale($t_form->getForms(array('table' => 'ca_objects', 'user_id' => $this->request->getUserID(), 'access' => __CA_SEARCH_FORM_READ_ACCESS__)));
         $va_tmp = array_keys($va_forms);
         $vn_form_id = array_shift($va_tmp);
     }
     $t_form->load($vn_form_id);
     $this->opo_view->setVar("t_form", $t_form);
     if ($t_form->haveAccessToForm($this->getRequest()->user->getUserID(), __CA_SEARCH_FORM_READ_ACCESS__)) {
         $vo_dm = Datamodel::load();
         $vo_result_context = new ResultContext($this->getRequest(), $vo_dm->getTableName($t_form->get("table_num")), "advanced_search");
         $va_form_data = $vo_result_context->getParameter('form_data');
         $this->opo_view->setVar("controller_name", $this->getAdvancedSearchControllerNameForTable($vo_dm->getTableName($t_form->get("table_num"))));
         $this->opo_view->setVar('form_data', $va_form_data);
         $this->opo_view->setVar('form_elements', $t_form->getHTMLFormElements($this->getRequest(), $va_form_data));
     } else {
         $t_form->clear();
     }
     return $this->opo_view->render('main_html.php');
 }
コード例 #10
0
ファイル: ca_users.php プロジェクト: kai-iak/providence
 /**
  *
  */
 public function _getUIList($pn_table_num)
 {
     if (!$this->getPrimaryKey()) {
         return false;
     }
     $vs_group_sql = '';
     if (is_array($va_groups = $this->getUserGroups()) && sizeof($va_groups)) {
         $vs_group_sql = " (\n\t\t\t\t(ceui.ui_id IN (\n\t\t\t\t\t\tSELECT ui_id \n\t\t\t\t\t\tFROM ca_editor_uis_x_user_groups \n\t\t\t\t\t\tWHERE \n\t\t\t\t\t\t\tgroup_id IN (" . join(',', array_keys($va_groups)) . ")\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t) OR ";
     }
     $o_db = $this->getDb();
     $qr_uis = $o_db->query("\n\t\t\tSELECT *\n\t\t\tFROM ca_editor_uis ceui\n\t\t\tINNER JOIN ca_editor_ui_labels AS ceuil ON ceui.ui_id = ceuil.ui_id\n\t\t\tWHERE\n\t\t\t\t(\n\t\t\t\t\tceui.user_id = ? OR \n\t\t\t\t\tceui.is_system_ui = 1 OR\n\t\t\t\t\t{$vs_group_sql}\n\t\t\t\t\t(ceui.ui_id IN (\n\t\t\t\t\t\t\tSELECT ui_id \n\t\t\t\t\t\t\tFROM ca_editor_uis_x_users \n\t\t\t\t\t\t\tWHERE \n\t\t\t\t\t\t\t\tuser_id = ?\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t) AND (ceui.editor_type = ?)\n\t\t", (int) $this->getPrimaryKey(), (int) $this->getPrimaryKey(), (int) $pn_table_num);
     $va_opts = array();
     while ($qr_uis->nextRow()) {
         $va_opts[$qr_uis->get('ui_id')][$qr_uis->get('locale_id')] = $qr_uis->get('name');
     }
     return caExtractValuesByUserLocale($va_opts);
 }
コード例 #11
0
 /**
  * Generates detail detail. Will use a view named according to the following convention:
  *		<table_name>_<type_code>_detail_html.php
  *
  * So for example, the detail for objects of type 'artwork' (where 'artwork' is the type code for the artwork object type)
  * the view would be named "ca_objects_artwork_detail_html.php
  *
  * If the type specific view does not exist, then Show() will attemp to use a generic table-wide view name like this:
  *		<table_name>_detail_html.php
  *
  * For example: "ca_objects_detail_html.php"
  *
  * In general you should always have the table wide views defined. Then you can define type-specific views for your
  * application on an as-needed basis.
  */
 public function Show($pa_options = null)
 {
     JavascriptLoadManager::register('viz');
     JavascriptLoadManager::register("ca", "panel");
     JavascriptLoadManager::register("jit");
     JavascriptLoadManager::register('browsable');
     JavascriptLoadManager::register('imageScroller');
     JavascriptLoadManager::register('jquery', 'expander');
     $va_access_values = caGetUserAccessValues($this->request);
     $this->view->setVar('access_values', $va_access_values);
     if (!($t_item = $this->opo_datamodel->getInstanceByTableName($this->ops_tablename, true))) {
         die("Invalid table name " . $this->ops_tablename . " for detail");
         // shouldn't happen
     }
     if (!($vn_item_id = $this->request->getParameter($t_item->primaryKey(), pInteger))) {
         $this->notification->addNotification(_t("Invalid ID"), "message");
         $this->response->setRedirect(caNavUrl($this->request, "", "", "", ""));
         return;
     }
     if (!$t_item->load($vn_item_id)) {
         $this->notification->addNotification(_t("ID does not exist"), "message");
         $this->response->setRedirect(caNavUrl($this->request, "", "", "", ""));
         return;
     }
     if ($t_item->hasField('deleted') && $t_item->get('deleted')) {
         $this->notification->addNotification(_t("ID has been deleted"), "message");
         $this->response->setRedirect(caNavUrl($this->request, "", "", "", ""));
         return;
     }
     // Check if item conforms to any configured display type restrictions
     if (method_exists($t_item, "getTypeID")) {
         $va_types = caMergeTypeRestrictionLists($t_item, array());
         if (is_array($va_types) && sizeof($va_types) && !in_array($t_item->getTypeID(), $va_types)) {
             $this->notification->addNotification(_t("This item is not viewable"), "message");
             $this->response->setRedirect(caNavUrl($this->request, "", "", "", ""));
             return;
         }
     }
     #
     # Enforce access control
     #
     if (sizeof($va_access_values) && !in_array($t_item->get("access"), $va_access_values)) {
         $this->notification->addNotification(_t("This item is not available for view"), "message");
         $this->response->setRedirect(caNavUrl($this->request, "", "", "", ""));
         return;
     }
     //
     // In-detail browsing of objects - limited to object linked to the item being displayed
     //
     if (($vs_browse_for_table = $this->request->config->get('allow_browse_within_detail_for_' . $this->ops_tablename)) && is_object($this->opo_browse)) {
         // set browse context for controller
         $this->setContext($this->opo_browse->getContext());
         //
         // Restrict facets to specific group for refine browse (if set in app.conf config)
         //
         if ($vs_facet_group = $this->request->config->get('ca_objects_refine_facet_group')) {
             $this->opo_browse->setFacetGroup($vs_facet_group);
         }
         $t_table = $this->opo_datamodel->getInstanceByTableName($this->ops_tablename, true);
         if ($this->request->session->getVar($this->ops_tablename . '_' . $this->ops_appname . '_detail_current_item_id') != $vn_item_id) {
             $this->opo_browse->removeAllCriteria();
         }
         // look for 'authority' facet for current detail table type so we can limit the object browse to the currently displayed item
         //$vs_limit_facet_name = null;
         //foreach($this->opo_browse->getInfoForFacets() as $vs_facet_name => $va_facet_info) {
         //	if (($va_facet_info['type'] === 'authority') && ($va_facet_info['table'] === $this->ops_tablename)) {
         //		$vs_limit_facet_name = $vs_facet_name;
         //		break;
         //	}
         //}
         $this->opo_browse->addFacetConfiguration($vs_limit_facet_name = '_detail_browse_' . $this->ops_tablename, array('type' => 'authority', 'table' => $this->ops_tablename, 'relationship_table' => 'ca_objects_x_entities', 'restrict_to_types' => array(), 'restrict_to_relationship_types' => array(), 'label_singular' => 'Detail browse by ' . $this->ops_tablename, 'label_plural' => 'Detail browse by ' . $this->ops_tablename, 'group_mode' => 'none', 'indefinite_article' => 'a'));
         if ($vs_limit_facet_name) {
             if (($va_configured_type_restrictions = $this->request->config->getList($this->ops_tablename . '_detail_browse_type_restrictions')) && is_array($va_configured_type_restrictions)) {
                 $this->opo_browse->setTypeRestrictions($va_configured_type_restrictions, array('includeChildren' => false));
             }
             $this->opo_browse->addCriteria($vs_limit_facet_name, array($vn_item_id));
             $this->opo_browse->execute(array('checkAccess' => $va_access_values));
             $this->request->session->setVar($this->ops_tablename . '_' . $this->ops_appname . '_detail_current_browse_id', $this->opo_browse->getBrowseID());
             $this->view->setVar('show_browse', true);
             //
             // Browse paging
             //
             $vn_items_per_page = $this->request->config->get("objects_per_page_for_detail_pages");
             if (!$vn_items_per_page) {
                 $vn_items_per_page = 12;
             }
             $this->view->setVar('page', ($vn_p = $this->request->getParameter('page', pInteger)) ? $vn_p : 1);
             $qr_hits = null;
             if ($this->opo_browse) {
                 $va_sort = array();
                 if ($vs_sort = $this->request->config->get('sort_browse_within_detail_for_' . $this->ops_tablename)) {
                     $va_sort = array('sort' => $vs_sort);
                 }
                 $qr_hits = $this->opo_browse->getResults($va_sort);
                 $vn_num_pages = ceil($qr_hits->numHits() / $vn_items_per_page);
                 $qr_hits->seek(($vn_p - 1) * $vn_items_per_page);
             } else {
                 $vn_num_pages = 0;
             }
             $this->view->setVar('browse_results', $qr_hits);
             $this->view->setVar('num_pages', (int) $vn_num_pages);
             $this->view->setVar('items_per_page', (int) $vn_items_per_page);
             $this->view->setVar('opo_browse', $this->opo_browse);
             $this->view->setVar('sorts', $this->opa_sorts);
             // supported sorts for the object browse
             // browse criteria in an easy-to-display format
             $va_browse_criteria = array();
             foreach ($this->opo_browse->getCriteriaWithLabels() as $vs_facet_code => $va_criteria) {
                 $va_facet_info = $this->opo_browse->getInfoForFacet($vs_facet_code);
                 $va_criteria_list = array();
                 foreach ($va_criteria as $vn_criteria_id => $vs_criteria_label) {
                     $va_criteria_list[] = $vs_criteria_label;
                 }
                 $va_browse_criteria[$va_facet_info['label_singular']] = join('; ', $va_criteria_list);
             }
             $this->view->setVar('browse_criteria', $va_browse_criteria);
         } else {
             // not configured for browse
             $this->request->session->setVar($this->ops_tablename . '_' . $this->ops_appname . '_detail_current_browse_id', null);
             $this->view->setVar('show_browse', false);
         }
     }
     $this->request->session->setVar($this->ops_tablename . '_' . $this->ops_appname . '_detail_current_item_id', $vn_item_id);
     # Next and previous navigation
     $opo_result_context = new ResultContext($this->request, $this->ops_tablename, ResultContext::getLastFind($this->request, $this->ops_tablename));
     $this->view->setVar('next_id', $opo_result_context->getNextID($vn_item_id));
     $this->view->setVar('previous_id', $opo_result_context->getPreviousID($vn_item_id));
     # Is the item we're show details for in the result set?
     $this->view->setVar('is_in_result_list', $opo_result_context->getIndexInResultList($vn_item_id) != '?');
     # Item instance and id
     $this->view->setVar('t_item', $t_item);
     $this->view->setVar($t_item->getPrimaryKey(), $vn_item_id);
     # Item  - preferred
     $this->view->setVar('label', $t_item->getLabelForDisplay());
     # Item  - nonpreferred
     $this->view->setVar('nonpreferred_labels', caExtractValuesByUserLocale($t_item->getNonPreferredLabels()));
     # Item timestamps (creation and last change)
     if ($va_entry_info = $t_item->getCreationTimestamp()) {
         $this->view->setVar('date_of_entry', date('m/d/Y', $va_entry_info['timestamp']));
     }
     if ($va_last_change_info = $t_item->getLastChangeTimestamp()) {
         $this->view->setVar('date_of_last_change', date('m/d/Y', $va_last_change_info['timestamp']));
     }
     # Media representations to display (objects only)
     if (method_exists($t_item, 'getPrimaryRepresentationInstance')) {
         if ($t_primary_rep = $t_item->getPrimaryRepresentationInstance()) {
             if (!sizeof($va_access_values) || in_array($t_primary_rep->get('access'), $va_access_values)) {
                 // check rep access
                 $this->view->setVar('t_primary_rep', $t_primary_rep);
                 $va_rep_display_info = caGetMediaDisplayInfo('detail', $t_primary_rep->getMediaInfo('media', 'INPUT', 'MIMETYPE'));
                 $this->view->setVar('primary_rep_display_version', $va_rep_display_info['display_version']);
                 unset($va_display_info['display_version']);
                 $va_rep_display_info['poster_frame_url'] = $t_primary_rep->getMediaUrl('media', $va_rep_display_info['poster_frame_version']);
                 unset($va_display_info['poster_frame_version']);
                 $this->view->setVar('primary_rep_display_options', $va_rep_display_info);
             }
         }
     }
     #
     # User-generated comments, tags and ratings
     #
     $va_user_comments = $t_item->getComments(null, true);
     $va_comments = array();
     if (is_array($va_user_comments)) {
         foreach ($va_user_comments as $va_user_comment) {
             if ($va_user_comment["comment"] || $va_user_comment["media1"] || $va_user_comment["media2"] || $va_user_comment["media3"] || $va_user_comment["media4"]) {
                 # TODO: format date based on locale
                 $va_user_comment["date"] = date("n/j/Y", $va_user_comment["created_on"]);
                 # -- get name of commenter
                 $t_user = new ca_users($va_user_comment["user_id"]);
                 $va_user_comment["author"] = $t_user->getName();
                 $va_comments[] = $va_user_comment;
             }
         }
     }
     $this->view->setVar('comments', $va_comments);
     $va_user_tags = $t_item->getTags(null, true);
     $va_tags = array();
     if (is_array($va_user_tags)) {
         foreach ($va_user_tags as $va_user_tag) {
             if (!in_array($va_user_tag["tag"], $va_tags)) {
                 $va_tags[] = $va_user_tag["tag"];
             }
         }
     }
     $this->view->setVar('tags_array', $va_tags);
     $this->view->setVar('tags', implode(", ", $va_tags));
     $this->view->setVar('result_context', $opo_result_context);
     # -- get average user ranking
     $this->view->setVar('ranking', $t_item->getAverageRating(null));
     // null makes it ignore moderation status
     # -- get number of user rankings
     $this->view->setVar('numRankings', $t_item->getNumRatings(null));
     // null makes it ignore moderation status
     #
     # Miscellaneous useful information
     #
     $this->view->setVar('t_relationship_types', new ca_relationship_types());
     // relationship types object - used for displaying relationship type of related authority information
     if (method_exists($t_item, 'getTypeName')) {
         $this->view->setVar('typename', $t_item->getTypeName());
     }
     // Record view
     $t_item->registerItemView($this->request->getUserID());
     //
     // Render view
     //
     if (isset($pa_options['view']) && $pa_options['view']) {
         $this->render($pa_options['view']);
     } else {
         if ($this->getView()->viewExists($this->ops_tablename . '_' . $t_item->getTypeCode() . '_detail_html.php')) {
             $this->render($this->ops_tablename . '_' . $t_item->getTypeCode() . '_detail_html.php');
         } else {
             $this->render($this->ops_tablename . '_detail_html.php');
         }
     }
 }
コード例 #12
0
 /**
  * Return array containing information about all place hierarchies, including their root_id's
  */
 public function getHierarchyList($pb_dummy = false)
 {
     $t_list = new ca_lists();
     $va_place_hierarchies = caExtractValuesByUserLocale($t_list->getItemsForList('place_hierarchies'));
     $o_db = $this->getDb();
     $va_hierarchy_ids = array();
     foreach ($va_place_hierarchies as $vn_i => $va_item) {
         $va_hierarchy_ids[] = intval($va_item['item_id']);
     }
     if (!sizeof($va_hierarchy_ids)) {
         return array();
     }
     // get root for each hierarchy
     $qr_res = $o_db->query("\n\t\t\tSELECT p.place_id, p.hierarchy_id, count(*) children\n\t\t\tFROM ca_places p\n\t\t\tINNER JOIN ca_places AS p2 ON p.place_id = p2.place_id\n\t\t\tWHERE \n\t\t\t\tp.parent_id IS NULL and p.hierarchy_id IN (" . join(',', $va_hierarchy_ids) . ")\n\t\t\tGROUP BY\n\t\t\t\tp.place_id, p.hierarchy_id\n\t\t");
     while ($qr_res->nextRow()) {
         $vn_hierarchy_id = $qr_res->get('hierarchy_id');
         $va_place_hierarchies[$vn_hierarchy_id]['place_id'] = $va_place_hierarchies[$vn_hierarchy_id]['item_id'] = $qr_res->get('place_id');
         $va_place_hierarchies[$vn_hierarchy_id]['name'] = $va_place_hierarchies[$vn_hierarchy_id]['name_plural'];
         $va_place_hierarchies[$vn_hierarchy_id]['children'] = $qr_res->get('children');
     }
     return $va_place_hierarchies;
 }
コード例 #13
0
 /**
  * Returns associative array, keyed by primary key value with values being
  * the nonpreferred label of the row from a suitable locale, ready for display 
  * 
  * @param array $pa_ids indexed array of primary key values to fetch labels for
  * @param array $pa_options Optional array of options. Supported options include:
  *								returnAllLocales = if set to true, an array indexed by row_id and then locale_id will be returned
  * @return array An array of nonpreferred labels in the current locale indexed by row_id, unless returnAllLocales is set, in which case the array includes preferred labels in all available locales and is indexed by row_id and locale_id
  */
 public function getNonPreferredDisplayLabelsForIDs($pa_ids, $pa_options = null)
 {
     $va_ids = array();
     foreach ($pa_ids as $vn_id) {
         if (intval($vn_id) > 0) {
             $va_ids[] = intval($vn_id);
         }
     }
     if (!is_array($va_ids) || !sizeof($va_ids)) {
         return array();
     }
     $vb_return_all_locales = caGetOption('returnAllLocales', $pa_options, false);
     $vs_cache_key = md5($this->tableName() . "/" . print_r($pa_ids, true) . '/' . print_R($pa_options, true) . '_non_preferred');
     if (!isset($pa_options['noCache']) && !$pa_options['noCache'] && LabelableBaseModelWithAttributes::$s_labels_by_id_cache[$vs_cache_key]) {
         return LabelableBaseModelWithAttributes::$s_labels_by_id_cache[$vs_cache_key];
     }
     $o_db = $this->getDb();
     $vs_display_field = $this->getLabelDisplayField();
     $vs_pk = $this->primaryKey();
     $vs_preferred_sql = '';
     if (($t_label_instance = $this->getLabelTableInstance()) && $t_label_instance->hasField('is_preferred')) {
         $vs_preferred_sql = "AND (is_preferred = 0)";
     }
     $va_labels = array();
     $qr_res = $o_db->query("\n\t\t\t\tSELECT {$vs_pk}, {$vs_display_field}, locale_id\n\t\t\t\tFROM " . $this->getLabelTableName() . "\n\t\t\t\tWHERE\n\t\t\t\t\t({$vs_pk} IN (" . join(',', $va_ids) . ")) {$vs_preferred_sql}\n\t\t\t\tORDER BY\n\t\t\t\t\t{$vs_display_field}\n\t\t\t");
     while ($qr_res->nextRow()) {
         $va_labels[$qr_res->get($vs_pk)][$qr_res->get('locale_id')][] = $qr_res->get($vs_display_field);
     }
     // make sure it's in same order the ids were passed in
     $va_sorted_labels = array();
     foreach ($va_ids as $vn_id) {
         $va_sorted_labels[$vn_id] = $va_labels[$vn_id];
     }
     if ($vb_return_all_locales) {
         return LabelableBaseModelWithAttributes::$s_labels_by_id_cache[$vs_cache_key] = $va_sorted_labels;
     }
     return LabelableBaseModelWithAttributes::$s_labels_by_id_cache[$vs_cache_key] = caExtractValuesByUserLocale($va_sorted_labels);
 }
コード例 #14
0
 public function lookup()
 {
     $vs_search = $this->request->getParameter('q', pString);
     $t_list = new ca_lists();
     $va_data = array();
     $va_access_values = caGetUserAccessValues($this->request);
     #
     # Do "quicksearches" on so-configured tables
     #
     if ($this->request->config->get('quicksearch_return_ca_objects')) {
         $va_results = caExtractValuesByUserLocale(SearchEngine::quickSearch($vs_search, 'ca_objects', 57, array('limit' => 3, 'checkAccess' => $va_access_values)));
         // break found objects out by type
         foreach ($va_results as $vn_id => $va_match_info) {
             $vs_type = unicode_ucfirst($t_list->getItemFromListForDisplayByItemID('object_types', $va_match_info['type_id'], true));
             $va_data['ca_objects'][$vs_type][$vn_id] = $va_match_info;
         }
     }
     if ($this->request->config->get('quicksearch_return_ca_entities')) {
         $va_data['ca_entities'][_t('Entities')] = caExtractValuesByUserLocale(SearchEngine::quickSearch($vs_search, 'ca_entities', 20, array('limit' => 10, 'checkAccess' => $va_access_values)));
     }
     if ($this->request->config->get('quicksearch_return_ca_places')) {
         $va_data['ca_places'][_t('Places')] = caExtractValuesByUserLocale(SearchEngine::quickSearch($vs_search, 'ca_places', 72, array('limit' => 10, 'checkAccess' => $va_access_values)));
     }
     if ($this->request->config->get('quicksearch_return_ca_occurrences')) {
         $va_results = caExtractValuesByUserLocale(SearchEngine::quickSearch($vs_search, 'ca_occurrences', 67, array('limit' => 10, 'checkAccess' => $va_access_values)));
         // break found occurrences out by type
         foreach ($va_results as $vn_id => $va_match_info) {
             $vs_type = unicode_ucfirst($t_list->getItemFromListForDisplayByItemID('occurrence_types', $va_match_info['type_id'], true));
             $va_data['ca_occurrences'][$vs_type][$vn_id] = $va_match_info;
         }
     }
     if ($this->request->config->get('quicksearch_return_ca_collections')) {
         $va_data['ca_collections'][_t('Collections')] = caExtractValuesByUserLocale(SearchEngine::quickSearch($vs_search, 'ca_collections', 13, array('limit' => 10, 'checkAccess' => $va_access_values)));
     }
     $this->view->setVar('matches', $va_data);
     $this->render('Search/ajax_search_lookup_json.php');
 }
コード例 #15
0
 /**
  * Set up variables for "tools" widget
  */
 public function Tools($pa_parameters)
 {
     if (!($vn_items_per_page = $this->opo_result_context->getItemsPerPage())) {
         $vn_items_per_page = $this->opa_items_per_page[0];
     }
     if (!($vs_view = $this->opo_result_context->getCurrentView())) {
         $va_tmp = array_keys($this->opa_views);
         $vs_view = array_shift($va_tmp);
     }
     if (!($vs_sort = $this->opo_result_context->getCurrentSort())) {
         $va_tmp = array_keys($this->opa_sorts);
         $vs_sort = array_shift($va_tmp);
     }
     $this->view->setVar('views', $this->opa_views);
     // pass view list to view for rendering
     $this->view->setVar('current_view', $vs_view);
     $vn_type_id = $this->opo_result_context->getTypeRestriction($vb_dummy);
     $va_sortable_elements = ca_metadata_elements::getSortableElements($this->ops_tablename, $vn_type_id);
     if (!is_array($this->opa_sorts)) {
         $this->opa_sorts = array();
     }
     foreach ($va_sortable_elements as $vn_element_id => $va_sortable_element) {
         $this->opa_sorts[$this->ops_tablename . '.' . $va_sortable_element['element_code']] = $va_sortable_element['display_label'];
     }
     $this->view->setVar('sorts', $this->opa_sorts);
     // pass sort list to view for rendering
     $this->view->setVar('current_sort', $vs_sort);
     $this->view->setVar('items_per_page', $this->opa_items_per_page);
     $this->view->setVar('current_items_per_page', $vn_items_per_page);
     //
     // Available sets
     //
     $t_set = new ca_sets();
     $this->view->setVar('available_sets', caExtractValuesByUserLocale($t_set->getSets(array('table' => $this->ops_tablename, 'user_id' => $this->request->getUserID()))));
     $this->view->setVar('last_search', $this->opo_result_context->getSearchExpression());
     $this->view->setVar('result_context', $this->opo_result_context);
     $va_results_id_list = $this->opo_result_context->getResultList();
     $this->view->setVar('result', is_array($va_results_id_list) && sizeof($va_results_id_list) > 0 ? caMakeSearchResult($this->ops_tablename, $va_results_id_list) : null);
     $t_model = $this->opo_datamodel->getInstanceByTableName($this->ops_tablename, true);
     $this->view->setVar('t_subject', $t_model);
 }
コード例 #16
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 GetHierarchyLevel()
 {
     $t_item = $this->opo_item_instance;
     if (!$t_item->isHierarchical()) {
         return;
     }
     $va_items_for_locale = array();
     if (!($pn_id = $this->request->getParameter('id', pInteger)) && method_exists($t_item, "getHierarchyList")) {
         $pn_id = $this->request->getParameter('root_item_id', pInteger);
         $t_item->load($pn_id);
         // no id so by default return list of available hierarchies
         $va_items_for_locale = $t_item->getHierarchyList();
     } else {
         if ($t_item->load($pn_id)) {
             // id is the id of the parent for the level we're going to return
             $vs_label_table_name = $this->opo_item_instance->getLabelTableName();
             $vs_label_display_field_name = $this->opo_item_instance->getLabelDisplayField();
             $vs_pk = $this->opo_item_instance->primaryKey();
             $va_additional_wheres = array();
             $t_label_instance = $this->opo_item_instance->getLabelTableInstance();
             if ($t_label_instance && $t_label_instance->hasField('is_preferred')) {
                 $va_additional_wheres[] = "(({$vs_label_table_name}.is_preferred = 1) OR ({$vs_label_table_name}.is_preferred IS NULL))";
             }
             $qr_children = $t_item->getHierarchyChildrenAsQuery($t_item->getPrimaryKey(), array('additionalTableToJoin' => $vs_label_table_name, 'additionalTableJoinType' => 'LEFT', 'additionalTableSelectFields' => array($vs_label_display_field_name, 'locale_id'), 'additionalTableWheres' => $va_additional_wheres, 'returnChildCounts' => true));
             $va_items = array();
             while ($qr_children->nextRow()) {
                 $va_tmp = $qr_children->getRow();
                 if (!$va_tmp[$vs_label_display_field_name]) {
                     $va_tmp[$vs_label_display_field_name] = $va_tmp['idno'];
                 }
                 if (!$va_tmp[$vs_label_display_field_name]) {
                     $va_tmp[$vs_label_display_field_name] = '???';
                 }
                 $va_tmp['name'] = $va_tmp[$vs_label_display_field_name];
                 // Child count is only valid if has_children is not null
                 $va_tmp['children'] = $qr_children->get('has_children') ? $qr_children->get('child_count') : 0;
                 $va_items[$qr_children->get($this->ops_table_name . '.' . $vs_pk)][$qr_children->get($this->ops_table_name . '.' . 'locale_id')] = $va_tmp;
             }
             $va_items_for_locale = caExtractValuesByUserLocale($va_items);
             $va_sorted_items = array();
             foreach ($va_items_for_locale as $vn_id => $va_node) {
                 $va_sorted_items[($vs_key = preg_replace('![^A-Za-z0-9]!', '_', $va_node['name']) . '_' . $vn_id) ? $vs_key : '000'] = $va_node;
             }
             ksort($va_sorted_items);
             $va_items_for_locale = $va_sorted_items;
         }
     }
     if (!$this->request->getParameter('init', pInteger)) {
         // only set remember "last viewed" if the load is done interactively
         // if the GetHierarchyLevel() call is part of the initialization of the hierarchy browser
         // then all levels are loaded, sometimes out-of-order; if we record these initialization loads
         // as the 'last viewed' we can end up losing the true 'last viewed' value
         //
         // ... so the hierbrowser passes an extra 'init' parameters set to 1 if the GetHierarchyLevel() call
         // is part of a browser initialization
         $this->request->session->setVar($this->ops_table_name . '_browse_last_id', $pn_id);
     }
     $va_items_for_locale['_primaryKey'] = $t_item->primaryKey();
     // pass the name of the primary key so the hierbrowser knows where to look for item_id's
     $this->view->setVar(str_replace(' ', '_', $this->ops_name_singular) . '_list', $va_items_for_locale);
     return $this->render('lookup/' . str_replace(' ', '_', $this->ops_name_singular) . '_hierarchy_level_json.php');
 }
コード例 #17
0
 /**
  * Returns list of placements in the currently loaded display
  *
  * @param array $pa_options Optional array of options. Supported options are:
  *		noCache = if set to true, no caching of placement values is performed. 
  *		no_tooltips = if set no tooltips for available bundles will be emitted. Default is false - tooltips will be emitted.
  *		format = specifies label format for bundles. Valid values are "simple" (just the name of the element) or "full" (name of element, name of type of item element pertains to and alternate label, if defined). Default is "full"
  *		user_id = if specified then placements are only returned if the user has at least read access to the display
  * @return array List of placements. Each element in the list is an array with the following keys:
  *		display = A display label for the bundle
  *		bundle = The bundle name
  */
 public function getPlacementsInDisplay($pa_options = null)
 {
     if (!is_array($pa_options)) {
         $pa_options = array();
     }
     $pb_no_cache = caGetOption('noCache', $pa_options, false);
     $pn_user_id = caGetOption('user_id', $pa_options, null);
     if ($pn_user_id && !$this->haveAccessToDisplay($pn_user_id, __CA_BUNDLE_DISPLAY_READ_ACCESS__)) {
         return array();
     }
     $vb_show_tooltips = !caGetOption('no_tooltips', $pa_options, false);
     $vs_format = caGetOption('format', $pa_options, 'full', array('validValues' => array('simple', 'full')));
     if (!($pn_table_num = $this->getAppDatamodel()->getTableNum($this->get('table_num')))) {
         return null;
     }
     if (!($t_instance = $this->getAppDatamodel()->getInstanceByTableNum($pn_table_num, true))) {
         return null;
     }
     if (!is_array($va_placements = $this->getPlacements($pa_options))) {
         $va_placements = array();
     }
     $va_placements_in_display = array();
     foreach ($va_placements as $vn_placement_id => $va_placement) {
         $vs_label = ($vs_label = $t_instance->getDisplayLabel($va_placement['bundle_name'])) ? $vs_label : $va_placement['bundle_name'];
         if (is_array($va_placement['settings']) && is_array($va_placement['settings']['label'])) {
             $va_tmp = caExtractValuesByUserLocale(array($va_placement['settings']['label']));
             if ($vs_user_set_label = array_shift($va_tmp)) {
                 $vs_label = "{$vs_label} (<em>{$vs_user_set_label}</em>)";
             }
         }
         $vs_display = "<div id='bundleDisplayEditor_{$vn_placement_id}'><span class='bundleDisplayEditorPlacementListItemTitle'>" . caUcFirstUTF8Safe($t_instance->getProperty('NAME_SINGULAR')) . "</span> {$vs_label}</div>";
         $va_placement['display'] = $vs_format == 'simple' ? $vs_label : $vs_display;
         $va_placement['bundle'] = $va_placement['bundle_name'];
         // we used 'bundle' in the arrays, but the database field is called 'bundle_name' and getPlacements() returns data directly from the database
         unset($va_placement['bundle_name']);
         $va_placements_in_display[$vn_placement_id] = $va_placement;
         $vs_description = $t_instance->getDisplayDescription($va_placement['bundle']);
         if ($vb_show_tooltips) {
             TooltipManager::add("#bundleDisplayEditor_{$vn_placement_id}", $this->_formatBundleTooltip($vs_label, $va_placement['bundle'], $vs_description));
         }
     }
     return $va_placements_in_display;
 }
コード例 #18
0
 /**
  * 
  */
 public function Info()
 {
     $t_set = new ca_sets($vn_set_id = $this->request->getParameter('set_id', pInteger));
     $vn_user_id = !(bool) $this->request->config->get('ca_sets_all_users_see_all_sets') ? $this->request->getUserID() : null;
     $va_set_stats = array('mine' => caExtractValuesByUserLocale($t_set->getSets(array('user_id' => $this->request->getUserID(), 'access' => __CA_SET_EDIT_ACCESS__)), null, null, array()));
     if ($this->request->user->canDoAction('is_administrator') || $this->request->user->canDoAction('can_administrate_sets')) {
         $va_set_stats['user'] = caExtractValuesByUserLocale($t_set->getSets(array('user_id' => $vn_user_id, 'allUsers' => true)), null, null, array());
         $va_set_stats['public'] = caExtractValuesByUserLocale($t_set->getSets(array('user_id' => $vn_user_id, 'publicUsers' => true)), null, null, array());
     }
     $o_result_context = new ResultContext($this->request, 'ca_sets', 'basic_search');
     $pn_mode = (int) $o_result_context->getParameter('set_display_mode');
     $this->view->setVar('mode', $pn_mode);
     $this->view->setVar('sets', $va_set_stats);
     return $this->render('widget_set_info_html.php', true);
 }
コード例 #19
0
ファイル: BrowseEngine.php プロジェクト: kai-iak/pawtucket2
 /**
  * Return list of items from the specified table that are related to the current browse set. This is the method that actually
  * pulls the facet content, regardless of whether the facet is cached yet or not. If you want to use the facet cache, call
  * BrowseEngine::getFacet()
  *
  * @see BrowseEngine::getFacet()
  * Options:
  *		checkAccess = array of access values to filter facets that have an 'access' field by
  *		checkAvailabilityOnly = if true then content is not actually fetch - only the availablility of content is verified
  *		user_id = If set item level access control is performed relative to specified user_id, otherwise defaults to logged in user
  */
 public function getFacetContent($ps_facet_name, $pa_options = null)
 {
     global $AUTH_CURRENT_USER_ID;
     $vs_browse_table_name = $this->ops_browse_table_name;
     $vs_browse_table_num = $this->opn_browse_table_num;
     $vn_user_id = isset($pa_options['user_id']) && (int) $pa_options['user_id'] ? (int) $pa_options['user_id'] : (int) $AUTH_CURRENT_USER_ID;
     $vb_show_if_no_acl = (bool) ($this->opo_config->get('default_item_access_level') > __CA_ACL_NO_ACCESS__);
     $t_user = new ca_users($vn_user_id);
     if (is_array($va_groups = $t_user->getUserGroups()) && sizeof($va_groups)) {
         $va_group_ids = array_keys($va_groups);
     } else {
         $va_group_ids = array();
     }
     if (!is_array($this->opa_browse_settings)) {
         return null;
     }
     if (!isset($this->opa_browse_settings['facets'][$ps_facet_name])) {
         return null;
     }
     if (!is_array($pa_options)) {
         $pa_options = array();
     }
     $vb_check_availability_only = isset($pa_options['checkAvailabilityOnly']) ? (bool) $pa_options['checkAvailabilityOnly'] : false;
     $va_all_criteria = $this->getCriteria();
     $va_criteria = $this->getCriteria($ps_facet_name);
     $va_facet_info = $this->opa_browse_settings['facets'][$ps_facet_name];
     $t_subject = $this->getSubjectInstance();
     if ($va_facet_info['relative_to']) {
         $vs_browse_table_name = $va_facet_info['relative_to'];
         $vs_browse_table_num = $this->opo_datamodel->getTableNum($vs_browse_table_name);
     }
     $vs_browse_type_limit_sql = '';
     if (($va_browse_type_ids = $this->getTypeRestrictionList()) && sizeof($va_browse_type_ids)) {
         // type restrictions
         $vs_browse_type_limit_sql = '(' . $t_subject->tableName() . '.' . $t_subject->getTypeFieldName() . ' IN (' . join(', ', $va_browse_type_ids) . ')' . ($t_subject->getFieldInfo('type_id', 'IS_NULL') ? " OR (" . $this->ops_browse_table_name . '.' . $t_subject->getTypeFieldName() . " IS NULL)" : '') . ')';
         if (is_array($va_facet_info['type_restrictions'])) {
             // facet type restrictions bind a facet to specific types; we check them here
             $va_restrict_to_types = $this->_convertTypeCodesToIDs($va_facet_info['type_restrictions']);
             $vb_is_ok_to_browse = false;
             foreach ($va_browse_type_ids as $vn_type_id) {
                 if (in_array($vn_type_id, $va_restrict_to_types)) {
                     $vb_is_ok_to_browse = true;
                     break;
                 }
             }
             if (!$vb_is_ok_to_browse) {
                 return array();
             }
         }
     }
     // Values to exclude from list attributes and authorities; can be idnos or ids
     $va_exclude_values = caGetOption('exclude_values', $va_facet_info, array(), array('castTo' => 'array'));
     $va_results = $this->opo_ca_browse_cache->getResults();
     $vb_single_value_is_present = false;
     $vs_single_value = isset($va_facet_info['single_value']) ? $va_facet_info['single_value'] : null;
     $va_wheres = array();
     switch ($va_facet_info['type']) {
         # -----------------------------------------------------
         case 'has':
             $vn_state = null;
             if (isset($va_all_criteria[$ps_facet_name])) {
                 break;
             }
             // only one instance of this facet allowed per browse
             if (!($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true))) {
                 break;
             }
             $vs_yes_text = isset($va_facet_info['label_yes']) && $va_facet_info['label_yes'] ? $va_facet_info['label_yes'] : _t('Yes');
             $vs_no_text = isset($va_facet_info['label_no']) && $va_facet_info['label_no'] ? $va_facet_info['label_no'] : _t('No');
             $va_facet_values = array('yes' => array('id' => 1, 'label' => $vs_yes_text), 'no' => array('id' => 0, 'label' => $vs_no_text));
             // Actually check that both yes and no values will result in something
             if ($va_facet_info['element_code']) {
                 $t_element = new ca_metadata_elements();
                 if (!$t_element->load(array('element_code' => $va_facet_info['element_code']))) {
                     break;
                 }
                 $vs_element_code = $va_facet_info['element_code'];
                 $va_facet = array();
                 $va_counts = array();
                 foreach ($va_facet_values as $vs_state_name => $va_state_info) {
                     $va_wheres = array();
                     $va_joins = array();
                     if (!(bool) $va_state_info['id']) {
                         // no option
                         $va_wheres[] = $this->ops_browse_table_name . '.' . $t_item->primaryKey() . " NOT IN (select row_id from ca_attributes where table_num = " . $t_item->tableNum() . " AND element_id = " . $t_element->getPrimaryKey() . ")";
                     } else {
                         // yes option
                         $va_joins[] = "LEFT JOIN ca_attributes AS caa ON  " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . " = caa.row_id AND " . $t_item->tableNum() . " = caa.table_num";
                         $va_wheres[] = "caa.element_id = " . $t_element->getPrimaryKey();
                     }
                     if ($t_item->hasField('deleted')) {
                         $va_wheres[] = "(" . $t_item->tableName() . ".deleted = 0)";
                     }
                     if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_item->hasField('access')) {
                         $va_wheres[] = "(" . $vs_browse_table_name . ".access IN (" . join(',', $pa_options['checkAccess']) . "))";
                     }
                     if (sizeof($va_results)) {
                         $va_wheres[] = $vs_browse_table_name . "." . $t_item->primaryKey() . " IN (" . join(",", $va_results) . ")";
                     }
                     if ($va_facet_info['relative_to']) {
                         if ($t_subject->hasField('deleted')) {
                             $va_wheres[] = "(" . $t_subject->tableName() . ".deleted = 0)";
                         }
                         if ($va_relative_sql_data = $this->_getRelativeFacetSQLData($va_facet_info['relative_to'], $pa_options)) {
                             $va_joins = array_merge($va_joins, $va_relative_sql_data['joins']);
                             $va_wheres = array_merge($va_wheres, $va_relative_sql_data['wheres']);
                         }
                     }
                     if ($this->opo_config->get('perform_item_level_access_checking')) {
                         if ($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true)) {
                             // Join to limit what browse table items are used to generate facet
                             $va_joins[] = 'LEFT JOIN ca_acl ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_acl.row_id AND ca_acl.table_num = ' . $t_item->tableNum() . "\n";
                             $va_wheres[] = "(\n\t\t\t\t\t\t\t\t\t\t((\n\t\t\t\t\t\t\t\t\t\t\t(ca_acl.user_id = " . (int) $vn_user_id . ")\n\t\t\t\t\t\t\t\t\t\t\t" . (sizeof($va_group_ids) > 0 ? "OR\n\t\t\t\t\t\t\t\t\t\t\t(ca_acl.group_id IN (" . join(",", $va_group_ids) . "))" : "") . "\n\t\t\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t\t\t(ca_acl.user_id IS NULL and ca_acl.group_id IS NULL)\n\t\t\t\t\t\t\t\t\t\t) AND ca_acl.access >= " . __CA_ACL_READONLY_ACCESS__ . ")\n\t\t\t\t\t\t\t\t\t\t" . ($vb_show_if_no_acl ? "OR ca_acl.acl_id IS NULL" : "") . "\n\t\t\t\t\t\t\t\t\t)";
                         }
                     }
                     $vs_join_sql = join("\n", $va_joins);
                     $vs_where_sql = '';
                     if (sizeof($va_wheres) > 0) {
                         $vs_where_sql = ' WHERE ' . join(' AND ', $va_wheres);
                     }
                     if ($vb_check_availability_only) {
                         $vs_sql = "\n\t\t\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\t\t\tFROM " . $vs_browse_table_name . "\n\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\t\t\tLIMIT 2\n\t\t\t\t\t\t\t\t";
                         //print "$vs_sql<hr>";
                         $qr_res = $this->opo_db->query($vs_sql);
                         if ($qr_res->nextRow()) {
                             $va_counts[$vs_state_name] = (int) $qr_res->numRows();
                         }
                     } else {
                         $vs_sql = "\n\t\t\t\t\t\t\t\t\tSELECT " . $vs_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\tFROM " . $vs_browse_table_name . "\n\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\t\t";
                         //print "$vs_sql<hr>";
                         $qr_res = $this->opo_db->query($vs_sql);
                         if ($qr_res->numRows() > 0) {
                             $va_facet[$vs_state_name] = $va_state_info;
                         } else {
                             return array();
                             // if either option in a "has" facet fails then don't show the facet
                         }
                     }
                 }
             } else {
                 $vs_rel_table_name = $va_facet_info['table'];
                 if (!is_array($va_restrict_to_relationship_types = $va_facet_info['restrict_to_relationship_types'])) {
                     $va_restrict_to_relationship_types = array();
                 }
                 $va_restrict_to_relationship_types = $this->_getRelationshipTypeIDs($va_restrict_to_relationship_types, $va_facet_info['relationship_table']);
                 if (!is_array($va_exclude_relationship_types = $va_facet_info['exclude_relationship_types'])) {
                     $va_exclude_relationship_types = array();
                 }
                 $va_exclude_relationship_types = $this->_getRelationshipTypeIDs($va_exclude_relationship_types, $va_facet_info['relationship_table']);
                 $vn_table_num = $this->opo_datamodel->getTableNum($vs_rel_table_name);
                 $vs_rel_table_pk = $this->opo_datamodel->getTablePrimaryKeyName($vn_table_num);
                 switch (sizeof($va_path = array_keys($this->opo_datamodel->getPath($vs_browse_table_name, $vs_rel_table_name)))) {
                     case 3:
                         $t_item_rel = $this->opo_datamodel->getInstanceByTableName($va_path[1], true);
                         $t_rel_item = $this->opo_datamodel->getInstanceByTableName($va_path[2], true);
                         $vs_key = 'relation_id';
                         break;
                     case 2:
                         $t_item_rel = null;
                         $t_rel_item = $this->opo_datamodel->getInstanceByTableName($va_path[1], true);
                         $vs_key = $t_rel_item->primaryKey();
                         break;
                     default:
                         // bad related table
                         return null;
                         break;
                 }
                 $vs_cur_table = array_shift($va_path);
                 $va_joins_init = array();
                 foreach ($va_path as $vs_join_table) {
                     $va_rel_info = $this->opo_datamodel->getRelationships($vs_cur_table, $vs_join_table);
                     $va_joins_init[] = ($vn_state ? 'INNER' : 'LEFT') . ' JOIN ' . $vs_join_table . ' ON ' . $vs_cur_table . '.' . $va_rel_info[$vs_cur_table][$vs_join_table][0][0] . ' = ' . $vs_join_table . '.' . $va_rel_info[$vs_cur_table][$vs_join_table][0][1] . "\n";
                     $vs_cur_table = $vs_join_table;
                 }
                 $va_facet = array();
                 $va_counts = array();
                 foreach ($va_facet_values as $vs_state_name => $va_state_info) {
                     $va_wheres = array();
                     $va_joins = $va_joins_init;
                     if (!(bool) $va_state_info['id']) {
                         // no option
                         $va_wheres[] = "(" . $t_rel_item->tableName() . "." . $t_rel_item->primaryKey() . " IS NULL)";
                         if ($t_rel_item->hasField('deleted')) {
                             $va_wheres[] = "((" . $t_rel_item->tableName() . ".deleted = 0) OR (" . $t_rel_item->tableName() . ".deleted IS NULL))";
                         }
                         if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_rel_item->hasField('access')) {
                             $va_wheres[] = "((" . $t_rel_item->tableName() . ".access NOT IN (" . join(',', $pa_options['checkAccess']) . ")) OR (" . $t_rel_item->tableName() . ".access IS NULL))";
                         }
                         if (sizeof($va_restrict_to_relationship_types) > 0 && is_object($t_item_rel)) {
                             $va_wheres[] = "((" . $t_item_rel->tableName() . ".type_id NOT IN (" . join(',', $va_restrict_to_relationship_types) . ")) OR (" . $t_item_rel->tableName() . ".type_id IS NULL))";
                         }
                         if (sizeof($va_exclude_relationship_types) > 0 && is_object($t_item_rel)) {
                             $va_wheres[] = "(" . $t_item_rel->tableName() . ".type_id IN (" . join(',', $va_exclude_relationship_types) . "))";
                         }
                     } else {
                         // yes option
                         $va_wheres[] = "(" . $t_rel_item->tableName() . "." . $t_rel_item->primaryKey() . " IS NOT NULL)";
                         if ($t_rel_item->hasField('deleted')) {
                             $va_wheres[] = "(" . $t_rel_item->tableName() . ".deleted = 0)";
                         }
                         if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_rel_item->hasField('access')) {
                             $va_wheres[] = "(" . $t_rel_item->tableName() . ".access IN (" . join(',', $pa_options['checkAccess']) . "))";
                         }
                         if (sizeof($va_restrict_to_relationship_types) > 0 && is_object($t_item_rel)) {
                             $va_wheres[] = "(" . $t_item_rel->tableName() . ".type_id IN (" . join(',', $va_restrict_to_relationship_types) . "))";
                         }
                         if (sizeof($va_exclude_relationship_types) > 0 && is_object($t_item_rel)) {
                             $va_wheres[] = "(" . $t_item_rel->tableName() . ".type_id NOT IN (" . join(',', $va_exclude_relationship_types) . "))";
                         }
                     }
                     if ($t_item->hasField('deleted')) {
                         $va_wheres[] = "(" . $t_item->tableName() . ".deleted = 0)";
                     }
                     if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_item->hasField('access')) {
                         $va_wheres[] = "(" . $vs_browse_table_name . ".access IN (" . join(',', $pa_options['checkAccess']) . "))";
                     }
                     if (sizeof($va_results)) {
                         $va_wheres[] = $vs_browse_table_name . "." . $t_item->primaryKey() . " IN (" . join(",", $va_results) . ")";
                     }
                     if ($va_facet_info['relative_to']) {
                         if ($t_subject->hasField('deleted')) {
                             $va_wheres[] = "(" . $t_subject->tableName() . ".deleted = 0)";
                         }
                         if ($va_relative_sql_data = $this->_getRelativeFacetSQLData($va_facet_info['relative_to'], $pa_options)) {
                             $va_joins = array_merge($va_joins, $va_relative_sql_data['joins']);
                             $va_wheres = array_merge($va_wheres, $va_relative_sql_data['wheres']);
                         }
                     }
                     if ($this->opo_config->get('perform_item_level_access_checking')) {
                         if ($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true)) {
                             // Join to limit what browse table items are used to generate facet
                             $va_joins[] = 'LEFT JOIN ca_acl ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_acl.row_id AND ca_acl.table_num = ' . $t_item->tableNum() . "\n";
                             $va_wheres[] = "(\n\t\t\t\t\t\t\t\t\t\t((\n\t\t\t\t\t\t\t\t\t\t\t(ca_acl.user_id = " . (int) $vn_user_id . ")\n\t\t\t\t\t\t\t\t\t\t\t" . (sizeof($va_group_ids) > 0 ? "OR\n\t\t\t\t\t\t\t\t\t\t\t(ca_acl.group_id IN (" . join(",", $va_group_ids) . "))" : "") . "\n\t\t\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t\t\t(ca_acl.user_id IS NULL and ca_acl.group_id IS NULL)\n\t\t\t\t\t\t\t\t\t\t) AND ca_acl.access >= " . __CA_ACL_READONLY_ACCESS__ . ")\n\t\t\t\t\t\t\t\t\t\t" . ($vb_show_if_no_acl ? "OR ca_acl.acl_id IS NULL" : "") . "\n\t\t\t\t\t\t\t\t\t)";
                         }
                     }
                     $vs_join_sql = join("\n", $va_joins);
                     $vs_where_sql = '';
                     if (sizeof($va_wheres) > 0) {
                         $vs_where_sql = ' WHERE ' . join(' AND ', $va_wheres);
                     }
                     if ($vb_check_availability_only) {
                         $vs_sql = "\n\t\t\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\t\t\tFROM " . $vs_browse_table_name . "\n\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\t\t\tLIMIT 2\n\t\t\t\t\t\t\t\t";
                         //print "$vs_sql<hr>";
                         $qr_res = $this->opo_db->query($vs_sql);
                         if ($qr_res->nextRow()) {
                             $va_counts[$vs_state_name] = (int) $qr_res->numRows();
                         }
                     } else {
                         $vs_sql = "\n\t\t\t\t\t\t\t\t\tSELECT " . $vs_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\tFROM " . $vs_browse_table_name . "\n\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\t\t";
                         //print "$vs_sql<hr>";
                         $qr_res = $this->opo_db->query($vs_sql);
                         if ($qr_res->numRows() > 0) {
                             $va_facet[$vs_state_name] = $va_state_info;
                         } else {
                             return array();
                             // if either option in a "has" facet fails then don't show the facet
                         }
                     }
                 }
             }
             if ($vb_check_availability_only) {
                 return sizeof($va_counts) > 1 ? true : false;
             }
             return $va_facet;
             break;
             # -----------------------------------------------------
         # -----------------------------------------------------
         case 'label':
             if (!($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true))) {
                 break;
             }
             if (!($t_label = $t_item->getLabelTableInstance())) {
                 break;
             }
             if (!is_array($va_restrict_to_types = $va_facet_info['restrict_to_types'])) {
                 $va_restrict_to_types = array();
             }
             $vs_item_pk = $t_item->primaryKey();
             $vs_label_table_name = $t_label->tableName();
             $vs_label_pk = $t_label->primaryKey();
             $vs_label_display_field = $t_item->getLabelDisplayField();
             $vs_label_sort_field = $t_item->getLabelSortField();
             $vs_where_sql = $vs_join_sql = '';
             $vb_needs_join = false;
             $va_where_sql = array();
             $va_joins = array();
             if ($vs_browse_type_limit_sql) {
                 $va_where_sql[] = $vs_browse_type_limit_sql;
             }
             if (isset($va_facet_info['preferred_labels_only']) && $va_facet_info['preferred_labels_only'] && $t_label->hasField('is_preferred')) {
                 $va_where_sql[] = "l.is_preferred = 1";
             }
             if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_item->hasField('access')) {
                 $va_where_sql[] = "(" . $vs_browse_table_name . ".access IN (" . join(',', $pa_options['checkAccess']) . "))";
             }
             if ($t_item->hasField('deleted')) {
                 $va_where_sql[] = "(" . $vs_browse_table_name . ".deleted = 0)";
                 $vb_needs_join = true;
             }
             if (sizeof($va_restrict_to_types)) {
                 $va_restrict_to_type_ids = caMakeTypeIDList($vs_browse_table_name, $va_restrict_to_types, array('dont_include_subtypes_in_type_restriction' => true));
                 if (sizeof($va_restrict_to_type_ids)) {
                     $va_where_sql[] = "(" . $vs_browse_table_name . "." . $t_item->getTypeFieldName() . " IN (" . join(", ", $va_restrict_to_type_ids) . ")" . ($t_item->getFieldInfo('type_id', 'IS_NULL') ? " OR (" . $vs_browse_table_name . '.' . $t_item->getTypeFieldName() . " IS NULL)" : '') . ")";
                     $vb_needs_join = true;
                 }
             }
             if (sizeof($va_exclude_types)) {
                 $va_exclude_type_ids = caMakeTypeIDList($vs_browse_table_name, $va_exclude_types, array('dont_include_subtypes_in_type_restriction' => true));
                 if (sizeof($va_exclude_type_ids)) {
                     $va_where_sql[] = "(" . $vs_browse_table_name . "." . $t_item->getTypeFieldName() . " NOT IN (" . join(", ", $va_exclude_type_ids) . ")" . ($t_item->getFieldInfo('type_id', 'IS_NULL') ? " OR (" . $vs_browse_table_name . '.' . $t_item->getTypeFieldName() . " IS NULL)" : '') . ")";
                     $vb_needs_join = true;
                 }
             }
             if ($vb_needs_join) {
                 $va_joins[] = "INNER JOIN " . $vs_browse_table_name . " ON " . $vs_browse_table_name . "." . $t_item->primaryKey() . " = l." . $t_item->primaryKey();
             }
             if ($va_facet_info['relative_to']) {
                 if ($t_subject->hasField('deleted')) {
                     $va_where_sql[] = "(" . $t_subject->tableName() . ".deleted = 0)";
                 }
                 if ($va_relative_sql_data = $this->_getRelativeFacetSQLData($va_facet_info['relative_to'], $pa_options)) {
                     $va_joins = array_merge($va_joins, $va_relative_sql_data['joins']);
                     $va_where_sql = array_merge($va_where_sql, $va_relative_sql_data['wheres']);
                 }
             }
             if (sizeof($va_results)) {
                 if ($va_facet_info['relative_to']) {
                     $va_where_sql[] = $this->ops_browse_table_name . "." . $t_subject->primaryKey() . " IN (" . join(",", $va_results) . ")";
                 } else {
                     $va_where_sql[] = "l.{$vs_item_pk} IN (" . join(",", $va_results) . ")";
                 }
             }
             if ($this->opo_config->get('perform_item_level_access_checking')) {
                 if ($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true)) {
                     // Join to limit what browse table items are used to generate facet
                     $va_joins[] = 'LEFT JOIN ca_acl ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_acl.row_id AND ca_acl.table_num = ' . $t_item->tableNum() . "\n";
                     $va_where_sql[] = "(\n\t\t\t\t\t\t\t\t((\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id = " . (int) $vn_user_id . ")\n\t\t\t\t\t\t\t\t\t" . (sizeof($va_group_ids) > 0 ? "OR\n\t\t\t\t\t\t\t\t\t(ca_acl.group_id IN (" . join(",", $va_group_ids) . "))" : "") . "\n\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id IS NULL and ca_acl.group_id IS NULL)\n\t\t\t\t\t\t\t\t) AND ca_acl.access >= " . __CA_ACL_READONLY_ACCESS__ . ")\n\t\t\t\t\t\t\t\t" . ($vb_show_if_no_acl ? "OR ca_acl.acl_id IS NULL" : "") . "\n\t\t\t\t\t\t\t)";
                 }
             }
             $vs_join_sql = join("\n", $va_joins);
             if (sizeof($va_where_sql)) {
                 $vs_where_sql = "WHERE " . join(" AND ", $va_where_sql);
             }
             if ($vb_check_availability_only) {
                 $vs_sql = "\n\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\tFROM {$vs_label_table_name} l\n\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\tLIMIT 1\n\t\t\t\t\t\t";
                 $qr_res = $this->opo_db->query($vs_sql);
                 return (int) $qr_res->numRows() > 0 ? true : false;
             } else {
                 $vs_parent_fld = $t_item->getProperty('HIERARCHY_PARENT_ID_FLD');
                 $vs_sql = "\n\t\t\t\t\t\t\tSELECT  l.* " . ($vs_parent_fld ? ", " . $vs_browse_table_name . "." . $vs_parent_fld : '') . " \n\t\t\t\t\t\t\tFROM {$vs_label_table_name} l\n\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t";
                 $qr_res = $this->opo_db->query($vs_sql);
                 $va_values = array();
                 $va_child_counts = array();
                 $vn_parent_id = null;
                 while ($qr_res->nextRow()) {
                     $vn_id = $qr_res->get($t_item->primaryKey());
                     if ($vs_parent_fld) {
                         $vn_parent_id = $qr_res->get($vs_parent_fld);
                         if ($vn_parent_id) {
                             $va_child_counts[$vn_parent_id]++;
                         }
                     }
                     $va_values[$vn_id][$qr_res->get('locale_id')] = array_merge($qr_res->getRow(), array('id' => $vn_id, 'parent_id' => $vn_parent_id, 'label' => $qr_res->get($vs_label_display_field)));
                     if (!is_null($vs_single_value) && $vn_id == $vs_single_value) {
                         $vb_single_value_is_present = true;
                     }
                 }
                 if ($vs_parent_fld) {
                     foreach ($va_values as $vn_id => $va_values_by_locale) {
                         foreach ($va_values_by_locale as $vn_locale_id => $va_value) {
                             $va_values[$vn_id][$vn_locale_id]['child_count'] = (int) $va_child_counts[$vn_id];
                         }
                     }
                 }
                 if (!is_null($vs_single_value) && !$vb_single_value_is_present) {
                     return array();
                 }
                 $va_values = caExtractValuesByUserLocale($va_values);
                 return $va_values;
             }
             break;
             # -----------------------------------------------------
         # -----------------------------------------------------
         case 'attribute':
             $t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true);
             $t_element = new ca_metadata_elements();
             if (!$t_element->load(array('element_code' => $va_facet_info['element_code']))) {
                 return array();
             }
             $vn_element_type = $t_element->get('datatype');
             $vn_element_id = $t_element->getPrimaryKey();
             $va_joins = array('INNER JOIN ca_attribute_values ON ca_attributes.attribute_id = ca_attribute_values.attribute_id', 'INNER JOIN ' . $vs_browse_table_name . ' ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_attributes.row_id AND ca_attributes.table_num = ' . intval($vs_browse_table_num));
             $va_wheres = array();
             if (sizeof($va_results) && $this->numCriteria() > 0) {
                 $va_wheres[] = "(" . $t_subject->tableName() . '.' . $t_subject->primaryKey() . " IN (" . join(',', $va_results) . "))";
             }
             if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_item->hasField('access')) {
                 $va_wheres[] = "(" . $vs_browse_table_name . ".access IN (" . join(',', $pa_options['checkAccess']) . "))";
             }
             if ($vs_browse_type_limit_sql) {
                 $va_wheres[] = $vs_browse_type_limit_sql;
             }
             if ($t_item->hasField('deleted')) {
                 $va_wheres[] = "(" . $vs_browse_table_name . ".deleted = 0)";
             }
             if ($va_facet_info['relative_to']) {
                 if ($t_subject->hasField('deleted')) {
                     $va_wheres[] = "(" . $t_subject->tableName() . ".deleted = 0)";
                 }
                 if ($va_relative_sql_data = $this->_getRelativeFacetSQLData($va_facet_info['relative_to'], $pa_options)) {
                     $va_joins = array_merge($va_joins, $va_relative_sql_data['joins']);
                     $va_wheres = array_merge($va_wheres, $va_relative_sql_data['wheres']);
                 }
             }
             if ($this->opo_config->get('perform_item_level_access_checking')) {
                 if ($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true)) {
                     // Join to limit what browse table items are used to generate facet
                     $va_joins[] = 'LEFT JOIN ca_acl ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_acl.row_id AND ca_acl.table_num = ' . $t_item->tableNum() . "\n";
                     $va_wheres[] = "(\n\t\t\t\t\t\t\t\t((\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id = " . (int) $vn_user_id . ")\n\t\t\t\t\t\t\t\t\t" . (sizeof($va_group_ids) > 0 ? "OR\n\t\t\t\t\t\t\t\t\t(ca_acl.group_id IN (" . join(",", $va_group_ids) . "))" : "") . "\n\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id IS NULL and ca_acl.group_id IS NULL)\n\t\t\t\t\t\t\t\t) AND ca_acl.access >= " . __CA_ACL_READONLY_ACCESS__ . ")\n\t\t\t\t\t\t\t\t" . ($vb_show_if_no_acl ? "OR ca_acl.acl_id IS NULL" : "") . "\n\t\t\t\t\t\t\t)";
                 }
             }
             $vs_join_sql = join("\n", $va_joins);
             if (is_array($va_wheres) && sizeof($va_wheres) && ($vs_where_sql = join(' AND ', $va_wheres))) {
                 $vs_where_sql = ' AND (' . $vs_where_sql . ')';
             }
             if ($vb_check_availability_only) {
                 // exclude criteria values
                 $vs_criteria_exclude_sql = '';
                 if (is_array($va_criteria) && sizeof($va_criteria)) {
                     $vs_criteria_exclude_sql = ' AND (ca_attribute_values.value_longtext1 NOT IN (' . join(", ", caQuoteList(array_keys($va_criteria))) . ')) ';
                 }
                 $vs_sql = "\n\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\tFROM ca_attributes\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t(ca_attribute_values.element_id = ?) {$vs_criteria_exclude_sql} {$vs_where_sql}\n\t\t\t\t\t\t\tLIMIT 2";
                 //print $vs_sql;
                 $qr_res = $this->opo_db->query($vs_sql, $vn_element_id);
                 return (int) $qr_res->numRows() > 1 ? true : false;
             } else {
                 $vs_sql = "\n\t\t\t\t\t\t\tSELECT DISTINCT value_longtext1, value_decimal1, value_longtext2, value_integer1\n\t\t\t\t\t\t\tFROM ca_attributes\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\tca_attribute_values.element_id = ? {$vs_where_sql}";
                 $qr_res = $this->opo_db->query($vs_sql, $vn_element_id);
                 $va_values = array();
                 $va_list_items = null;
                 $va_suppress_values = null;
                 if ($va_facet_info['suppress'] && !is_array($va_facet_info['suppress'])) {
                     $va_facet_info['suppress'] = array($va_facet_info['suppress']);
                 }
                 if (!is_array($va_suppress_values = caGetOption('suppress', $va_facet_info, null))) {
                     $va_suppress_values = caGetOption('exclude_values', $va_facet_info, null);
                 }
                 switch ($vn_element_type) {
                     case __CA_ATTRIBUTE_VALUE_LIST__:
                         $va_values = $qr_res->getAllFieldValues('value_longtext1');
                         $qr_res->seek(0);
                         $t_list_item = new ca_list_items();
                         $va_list_item_cache = $t_list_item->getFieldValuesForIDs($va_values, array('idno', 'item_value', 'parent_id', 'access'));
                         $va_list_child_count_cache = array();
                         if (is_array($va_list_item_cache)) {
                             foreach ($va_list_item_cache as $vn_id => $va_item) {
                                 if (!($vn_parent_id = $va_item['parent_id'])) {
                                     continue;
                                 }
                                 if (is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && !in_array($va_item['access'], $pa_options['checkAccess'])) {
                                     continue;
                                 }
                                 $va_list_child_count_cache[$vn_parent_id]++;
                             }
                         }
                         $va_list_label_cache = $t_list_item->getPreferredDisplayLabelsForIDs($va_values);
                         // Translate value idnos to ids
                         if (is_array($va_suppress_values)) {
                             $va_suppress_values = ca_lists::getItemIDsFromList($t_element->get('list_id'), $va_suppress_values);
                         }
                         $va_facet_list = array();
                         foreach ($va_values as $vn_val) {
                             if (!$vn_val) {
                                 continue;
                             }
                             if (is_array($va_suppress_values) && in_array($vn_val, $va_suppress_values)) {
                                 continue;
                             }
                             if (is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && !in_array($va_item['access'], $pa_options['checkAccess'])) {
                                 continue;
                             }
                             if ($va_criteria[$vn_val]) {
                                 continue;
                             }
                             // skip items that are used as browse critera - don't want to browse on something you're already browsing on
                             $vn_child_count = isset($va_list_child_count_cache[$vn_val]) ? $va_list_child_count_cache[$vn_val] : 0;
                             $va_facet_list[$vn_val] = array('id' => $vn_val, 'label' => html_entity_decode($va_list_label_cache[$vn_val]), 'parent_id' => isset($va_list_item_cache[$vn_val]['parent_id']) ? $va_list_item_cache[$vn_val]['parent_id'] : null, 'child_count' => $vn_child_count);
                         }
                         // preserve order of list
                         $va_values_sorted_by_list_order = array();
                         if (is_array($va_list_item_cache)) {
                             foreach ($va_list_item_cache as $vn_item_id => $va_item) {
                                 if (isset($va_facet_list[$vn_item_id])) {
                                     $va_values_sorted_by_list_order[$vn_item_id] = $va_facet_list[$vn_item_id];
                                 }
                             }
                         }
                         return caSortArrayByKeyInValue($va_values_sorted_by_list_order, array('label'));
                         break;
                     case __CA_ATTRIBUTE_VALUE_OBJECTS__:
                     case __CA_ATTRIBUTE_VALUE_ENTITIES__:
                     case __CA_ATTRIBUTE_VALUE_PLACES__:
                     case __CA_ATTRIBUTE_VALUE_OCCURRENCES__:
                     case __CA_ATTRIBUTE_VALUE_COLLECTIONS__:
                     case __CA_ATTRIBUTE_VALUE_LOANS__:
                     case __CA_ATTRIBUTE_VALUE_MOVEMENTS__:
                     case __CA_ATTRIBUTE_VALUE_STORAGELOCATIONS__:
                     case __CA_ATTRIBUTE_VALUE_OBJECTLOTS__:
                         if ($t_rel_item = AuthorityAttributeValue::elementTypeToInstance($vn_element_type)) {
                             $va_ids = $qr_res->getAllFieldValues('value_integer1');
                             $va_auth_items = $t_rel_item->getPreferredDisplayLabelsForIDs($va_ids);
                             $qr_res->seek(0);
                         }
                         break;
                     default:
                         if (isset($va_facet_info['suppress']) && is_array($va_facet_info['suppress'])) {
                             $va_suppress_values = $va_facet_info['suppress'];
                         }
                         break;
                 }
                 while ($qr_res->nextRow()) {
                     $o_attr = Attribute::getValueInstance($vn_element_type, $qr_res->getRow(), true);
                     if (!($vs_val = trim($o_attr->getDisplayValue()))) {
                         continue;
                     }
                     if (is_array($va_suppress_values) && in_array($vs_val, $va_suppress_values)) {
                         continue;
                     }
                     if ($va_criteria[$vs_val]) {
                         continue;
                     }
                     // skip items that are used as browse critera - don't want to browse on something you're already browsing on
                     switch ($vn_element_type) {
                         case __CA_ATTRIBUTE_VALUE_LIST__:
                             $vn_child_count = 0;
                             if ($va_list_parent_ids[$vs_val]) {
                                 $vn_child_count++;
                             }
                             $va_values[$vs_val] = array('id' => str_replace('/', '&#47;', $vs_val), 'label' => html_entity_decode($va_list_items[$vs_val]['name_plural'] ? $va_list_items[$vs_val]['name_plural'] : $va_list_items[$vs_val]['item_value']), 'parent_id' => $va_list_items[$vs_val]['parent_id'], 'child_count' => $vn_child_count);
                             break;
                         case __CA_ATTRIBUTE_VALUE_OBJECTS__:
                         case __CA_ATTRIBUTE_VALUE_ENTITIES__:
                         case __CA_ATTRIBUTE_VALUE_PLACES__:
                         case __CA_ATTRIBUTE_VALUE_OCCURRENCES__:
                         case __CA_ATTRIBUTE_VALUE_COLLECTIONS__:
                         case __CA_ATTRIBUTE_VALUE_LOANS__:
                         case __CA_ATTRIBUTE_VALUE_MOVEMENTS__:
                         case __CA_ATTRIBUTE_VALUE_STORAGELOCATIONS__:
                         case __CA_ATTRIBUTE_VALUE_OBJECTLOTS__:
                             $va_values[$vs_val] = array('id' => $vn_id, 'label' => html_entity_decode($va_auth_items[$vn_id] ? $va_auth_items[$vn_id] : $vs_val));
                             break;
                         case __CA_ATTRIBUTE_VALUE_CURRENCY__:
                             $va_values[sprintf("%014.2f", preg_replace("![\\D]+!", "", $vs_val))] = array('id' => str_replace('/', '&#47;', $vs_val), 'label' => $vs_val);
                             break;
                         default:
                             $va_values[$vs_val] = array('id' => str_replace('/', '&#47;', $vs_val), 'label' => $vs_val);
                             break;
                     }
                     if (!is_null($vs_single_value) && $vs_val == $vs_single_value) {
                         $vb_single_value_is_present = true;
                     }
                 }
                 if (!is_null($vs_single_value) && !$vb_single_value_is_present) {
                     return array();
                 }
                 ksort($va_values);
                 return $va_values;
             }
             break;
             # -----------------------------------------------------
         # -----------------------------------------------------
         case 'location':
             $t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true);
             $vs_sort_field = null;
             if ($t_item->getProperty('ID_NUMBERING_ID_FIELD') == $vs_field_name) {
                 $vs_sort_field = $t_item->getProperty('ID_NUMBERING_SORT_FIELD');
             }
             $va_joins = array();
             $va_wheres = array();
             $vs_where_sql = '';
             $va_wheres[] = "({$vs_browse_table_name}.current_loc_class IS NOT NULL)";
             if (sizeof($va_results) && $this->numCriteria() > 0) {
                 $va_wheres[] = "(" . $t_subject->tableName() . '.' . $t_subject->primaryKey() . " IN (" . join(',', $va_results) . "))";
             }
             if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_item->hasField('access')) {
                 $va_wheres[] = "(" . $vs_browse_table_name . ".access IN (" . join(',', $pa_options['checkAccess']) . "))";
             }
             if ($vs_browse_type_limit_sql) {
                 $va_wheres[] = $vs_browse_type_limit_sql;
             }
             if ($t_item->hasField('deleted')) {
                 $va_wheres[] = "(" . $vs_browse_table_name . ".deleted = 0)";
             }
             if ($this->opo_config->get('perform_item_level_access_checking')) {
                 if ($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true)) {
                     // Join to limit what browse table items are used to generate facet
                     $va_joins[] = 'LEFT JOIN ca_acl ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_acl.row_id AND ca_acl.table_num = ' . $t_item->tableNum() . "\n";
                     $va_wheres[] = "(\n\t\t\t\t\t\t\t\t((\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id = " . (int) $vn_user_id . ")\n\t\t\t\t\t\t\t\t\t" . (sizeof($va_group_ids) > 0 ? "OR\n\t\t\t\t\t\t\t\t\t(ca_acl.group_id IN (" . join(",", $va_group_ids) . "))" : "") . "\n\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id IS NULL and ca_acl.group_id IS NULL)\n\t\t\t\t\t\t\t\t) AND ca_acl.access >= " . __CA_ACL_READONLY_ACCESS__ . ")\n\t\t\t\t\t\t\t\t" . ($vb_show_if_no_acl ? "OR ca_acl.acl_id IS NULL" : "") . "\n\t\t\t\t\t\t\t)";
                 }
             }
             $vs_join_sql = join("\n", $va_joins);
             if (is_array($va_wheres) && sizeof($va_wheres) && ($vs_where_sql = join(' AND ', $va_wheres))) {
                 $vs_where_sql = '(' . $vs_where_sql . ')';
             }
             if ($vb_check_availability_only) {
                 if (sizeof($va_criteria) > 0) {
                     return false;
                 }
                 // only one current location criteria allowed
                 $vs_sql = "\n\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\tFROM {$vs_browse_table_name}\n\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\tLIMIT 2";
                 $qr_res = $this->opo_db->query($vs_sql);
                 if ($qr_res->nextRow()) {
                     return (int) $qr_res->numRows() > 0 ? true : false;
                 }
                 return false;
             } else {
                 if (sizeof($va_criteria) > 0) {
                     return array();
                 }
                 // only one current location criteria allowed
                 $vs_pk = $t_item->primaryKey();
                 $vs_sql = "\n\t\t\t\t\t\t\tSELECT DISTINCT {$vs_browse_table_name}.current_loc_class, {$vs_browse_table_name}.current_loc_subclass, {$vs_browse_table_name}.current_loc_id\n\t\t\t\t\t\t\tFROM {$vs_browse_table_name}\n\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t{$vs_where_sql}";
                 if ($vs_sort_field) {
                     $vs_sql .= " ORDER BY {$vs_sort_field}";
                 }
                 $qr_res = $this->opo_db->query($vs_sql);
                 $va_collapse_map = $this->getCollapseMapForLocationFacet($va_facet_info);
                 $va_values = $va_values_by_table = array();
                 while ($qr_res->nextRow()) {
                     if (!($vs_loc_class = trim($qr_res->get('current_loc_class')))) {
                         continue;
                     }
                     if (!($vs_loc_subclass = trim($qr_res->get('current_loc_subclass')))) {
                         continue;
                     }
                     if (!($vs_loc_id = trim($qr_res->get('current_loc_id')))) {
                         continue;
                     }
                     $vs_val = "{$vs_loc_class}:{$vs_loc_subclass}:{$vs_loc_id}";
                     if ($va_criteria[$vs_val]) {
                         continue;
                     }
                     // skip items that are used as browse critera - don't want to browse on something you're already browsing on
                     $va_values_by_table[$vs_loc_class][$vs_loc_subclass][$vs_loc_id] = true;
                 }
                 foreach ($va_values_by_table as $vs_loc_class => $va_loc_id_by_subclass) {
                     foreach ($va_loc_id_by_subclass as $vs_loc_subclass => $va_loc_ids) {
                         if (sizeof($va_tmp = array_keys($va_loc_ids))) {
                             $vs_loc_table_name = $this->opo_datamodel->getTableName($vs_loc_class);
                             if (($vs_table_name = $vs_loc_table_name) == 'ca_objects_x_storage_locations') {
                                 $vs_table_name = 'ca_storage_locations';
                             }
                             $qr_res = caMakeSearchResult($vs_table_name, $va_tmp);
                             if (isset($va_collapse_map[$vs_table_name]) && isset($va_collapse_map[$vs_table_name]['*']) && $va_collapse_map[$vs_table_name]['*']) {
                                 $va_values[$vs_id = "{$vs_loc_class}"] = array('id' => $vs_id, 'label' => $va_collapse_map[$vs_table_name]['*']);
                                 continue;
                             }
                             while ($qr_res->nextHit()) {
                                 $vn_id = $qr_res->getPrimaryKey();
                                 $va_config = ca_objects::getConfigurationForCurrentLocationType($vs_table_name, $vs_loc_subclass, array('facet' => isset($va_facet_info['display']) ? $va_facet_info['display'] : null));
                                 $vs_template = isset($va_config['template']) ? $va_config['template'] : "^{$vs_table_name}.preferred_labels";
                                 if (isset($va_collapse_map[$vs_table_name]) && isset($va_collapse_map[$vs_table_name][$vs_loc_subclass]) && $va_collapse_map[$vs_table_name][$vs_loc_subclass]) {
                                     $va_values[$vs_id = "{$vs_loc_class}:{$vs_loc_subclass}"] = array('id' => $vs_id, 'label' => $va_collapse_map[$vs_table_name][$vs_loc_subclass]);
                                     continue;
                                 }
                                 $va_values[$vs_id = "{$vs_loc_class}:{$vs_loc_subclass}:{$vn_id}"] = array('id' => $vs_id, 'label' => $qr_res->getWithTemplate($vs_template));
                             }
                         }
                     }
                 }
                 if (!is_null($vs_single_value) && !$vb_single_value_is_present) {
                     return array();
                 }
                 return caSortArrayByKeyInValue($va_values, array('label'));
             }
             return array();
             break;
             # -----------------------------------------------------
         # -----------------------------------------------------
         case 'fieldList':
             $t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true);
             $vs_field_name = $va_facet_info['field'];
             $va_field_info = $t_item->getFieldInfo($vs_field_name);
             $t_list = new ca_lists();
             $t_list_item = new ca_list_items();
             $va_joins = array();
             $va_wheres = array();
             $vs_where_sql = '';
             if (isset($va_field_info['LIST_CODE']) && ($vs_list_name = $va_field_info['LIST_CODE'])) {
                 // Handle fields containing ca_list_item.item_id's
                 $va_joins = array('INNER JOIN ' . $vs_browse_table_name . ' ON ' . $vs_browse_table_name . '.' . $vs_field_name . ' = li.item_id', 'INNER JOIN ca_lists ON ca_lists.list_id = li.list_id');
                 if (sizeof($va_results) && $this->numCriteria() > 0) {
                     $va_wheres[] = "(" . $t_subject->tableName() . '.' . $t_subject->primaryKey() . " IN (" . join(',', $va_results) . "))";
                 }
                 if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_item->hasField('access')) {
                     $va_wheres[] = "(" . $vs_browse_table_name . ".access IN (" . join(',', $pa_options['checkAccess']) . "))";
                     $va_wheres[] = "(li.access IN (" . join(',', $pa_options['checkAccess']) . "))";
                 }
                 if ($vs_browse_type_limit_sql) {
                     $va_wheres[] = $vs_browse_type_limit_sql;
                 }
                 if ($t_subject->hasField('deleted')) {
                     $va_wheres[] = "(" . $t_subject->tableName() . ".deleted = 0)";
                 }
                 if ($va_facet_info['relative_to']) {
                     if ($va_relative_sql_data = $this->_getRelativeFacetSQLData($va_facet_info['relative_to'], $pa_options)) {
                         $va_joins = array_merge($va_joins, $va_relative_sql_data['joins']);
                         $va_wheres = array_merge($va_wheres, $va_relative_sql_data['wheres']);
                     }
                 }
                 if (is_array($va_criteria) && sizeof($va_criteria)) {
                     $va_wheres[] = "(li.item_id NOT IN (" . join(",", array_keys($va_criteria)) . "))";
                 }
                 if ($this->opo_config->get('perform_item_level_access_checking')) {
                     if ($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true)) {
                         // Join to limit what browse table items are used to generate facet
                         $va_joins[] = 'LEFT JOIN ca_acl ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_acl.row_id AND ca_acl.table_num = ' . $t_item->tableNum() . "\n";
                         $va_wheres[] = "(\n\t\t\t\t\t\t\t\t\t((\n\t\t\t\t\t\t\t\t\t\t(ca_acl.user_id = " . (int) $vn_user_id . ")\n\t\t\t\t\t\t\t\t\t\t" . (sizeof($va_group_ids) > 0 ? "OR\n\t\t\t\t\t\t\t\t\t\t(ca_acl.group_id IN (" . join(",", $va_group_ids) . "))" : "") . "\n\t\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t\t(ca_acl.user_id IS NULL and ca_acl.group_id IS NULL)\n\t\t\t\t\t\t\t\t\t) AND ca_acl.access >= " . __CA_ACL_READONLY_ACCESS__ . ")\n\t\t\t\t\t\t\t\t\t" . ($vb_show_if_no_acl ? "OR ca_acl.acl_id IS NULL" : "") . "\n\t\t\t\t\t\t\t\t)";
                     }
                 }
                 $vs_join_sql = join("\n", $va_joins);
                 if (is_array($va_wheres) && sizeof($va_wheres) && ($vs_where_sql = join(' AND ', $va_wheres))) {
                     $vs_where_sql = ' AND (' . $vs_where_sql . ')';
                 }
                 if ($vb_check_availability_only) {
                     $vs_sql = "\n\t\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\t\tFROM ca_list_items li\n\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\tca_lists.list_code = ? {$vs_where_sql}\n\t\t\t\t\t\t\t\tLIMIT 2";
                     $qr_res = $this->opo_db->query($vs_sql, $vs_list_name);
                     return (int) $qr_res->numRows() > 1 ? true : false;
                 } else {
                     // Get label ordering fields
                     $va_ordering_fields_to_fetch = isset($va_facet_info['order_by_label_fields']) && is_array($va_facet_info['order_by_label_fields']) ? $va_facet_info['order_by_label_fields'] : array();
                     $va_orderbys = array();
                     $t_rel_item_label = new ca_list_item_labels();
                     foreach ($va_ordering_fields_to_fetch as $vs_sort_by_field) {
                         if (!$t_rel_item_label->hasField($vs_sort_by_field)) {
                             continue;
                         }
                         $va_orderbys[] = $va_label_selects[] = 'lil.' . $vs_sort_by_field;
                     }
                     $vs_order_by = sizeof($va_orderbys) ? "ORDER BY " . join(', ', $va_orderbys) : '';
                     $vs_sql = "\n\t\t\t\t\t\t\t\tSELECT DISTINCT lil.item_id, lil.name_singular, lil.name_plural, lil.locale_id\n\t\t\t\t\t\t\t\tFROM ca_list_items li\n\t\t\t\t\t\t\t\tINNER JOIN ca_list_item_labels AS lil ON lil.item_id = li.item_id\n\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\tca_lists.list_code = ?  AND lil.is_preferred = 1 {$vs_where_sql} {$vs_order_by}";
                     //print $vs_sql." [$vs_list_name]";
                     $qr_res = $this->opo_db->query($vs_sql, $vs_list_name);
                     $va_values = array();
                     while ($qr_res->nextRow()) {
                         $vn_id = $qr_res->get('item_id');
                         if ($va_criteria[$vn_id]) {
                             continue;
                         }
                         // skip items that are used as browse critera - don't want to browse on something you're already browsing on
                         $va_values[$vn_id][$qr_res->get('locale_id')] = array('id' => $vn_id, 'label' => $qr_res->get('name_plural'));
                         if (!is_null($vs_single_value) && $vn_id == $vs_single_value) {
                             $vb_single_value_is_present = true;
                         }
                     }
                     if (!is_null($vs_single_value) && !$vb_single_value_is_present) {
                         return array();
                     }
                     return caExtractValuesByUserLocale($va_values);
                 }
             } else {
                 if ($vs_list_name = $va_field_info['LIST']) {
                     $va_list_items_by_value = array();
                     // fields with values set according to ca_list_items (not a foreign key ref)
                     if ($va_list_items = caExtractValuesByUserLocale($t_list->getItemsForList($vs_list_name))) {
                         foreach ($va_list_items as $vn_id => $va_list_item) {
                             $va_list_items_by_value[$va_list_item['item_value']] = $va_list_item['name_plural'];
                         }
                     } else {
                         foreach ($va_field_info['BOUNDS_CHOICE_LIST'] as $vs_val => $vn_id) {
                             $va_list_items_by_value[$vn_id] = $vs_val;
                         }
                     }
                     if (sizeof($va_results) && $this->numCriteria() > 0) {
                         $va_wheres[] = "(" . $t_subject->tableName() . '.' . $t_subject->primaryKey() . " IN (" . join(',', $va_results) . "))";
                     }
                     if ($vs_browse_type_limit_sql) {
                         $va_wheres[] = $vs_browse_type_limit_sql;
                     }
                     if ($t_subject->hasField('deleted')) {
                         $va_wheres[] = "(" . $t_subject->tableName() . ".deleted = 0)";
                     }
                     if ($va_facet_info['relative_to']) {
                         if ($va_relative_sql_data = $this->_getRelativeFacetSQLData($va_facet_info['relative_to'], $pa_options)) {
                             $va_joins = array_merge($va_joins, $va_relative_sql_data['joins']);
                             $va_wheres = array_merge($va_wheres, $va_relative_sql_data['wheres']);
                         }
                     }
                     if ($this->opo_config->get('perform_item_level_access_checking')) {
                         if ($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true)) {
                             // Join to limit what browse table items are used to generate facet
                             $va_joins[] = 'LEFT JOIN ca_acl ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_acl.row_id AND ca_acl.table_num = ' . $t_item->tableNum() . "\n";
                             $va_wheres[] = "(\n\t\t\t\t\t\t\t\t\t\t((\n\t\t\t\t\t\t\t\t\t\t\t(ca_acl.user_id = " . (int) $vn_user_id . ")\n\t\t\t\t\t\t\t\t\t\t\t" . (sizeof($va_group_ids) > 0 ? "OR\n\t\t\t\t\t\t\t\t\t\t\t(ca_acl.group_id IN (" . join(",", $va_group_ids) . "))" : "") . "\n\t\t\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t\t\t(ca_acl.user_id IS NULL and ca_acl.group_id IS NULL)\n\t\t\t\t\t\t\t\t\t\t) AND ca_acl.access >= " . __CA_ACL_READONLY_ACCESS__ . ")\n\t\t\t\t\t\t\t\t\t\t" . ($vb_show_if_no_acl ? "OR ca_acl.acl_id IS NULL" : "") . "\n\t\t\t\t\t\t\t\t\t)";
                         }
                     }
                     if (is_array($va_wheres) && sizeof($va_wheres) && ($vs_where_sql = join(' AND ', $va_wheres))) {
                         $vs_where_sql = '(' . $vs_where_sql . ')';
                     }
                     $vs_join_sql = join("\n", $va_joins);
                     if ($vb_check_availability_only) {
                         $vs_sql = "\n\t\t\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\t\t\tFROM " . $vs_browse_table_name . "\n\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\t" . ($vs_where_sql ? 'WHERE' : '') . "\n\t\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\t\t\tLIMIT 2";
                         $qr_res = $this->opo_db->query($vs_sql);
                         return (int) $qr_res->numRows() > 1 ? true : false;
                     } else {
                         $vs_sql = "\n\t\t\t\t\t\t\t\t\tSELECT DISTINCT " . $vs_browse_table_name . '.' . $vs_field_name . "\n\t\t\t\t\t\t\t\t\tFROM " . $vs_browse_table_name . "\n\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\t" . ($vs_where_sql ? 'WHERE' : '') . "\n\t\t\t\t\t\t\t\t\t\t{$vs_where_sql}";
                         //print $vs_sql." [$vs_list_name]";
                         $qr_res = $this->opo_db->query($vs_sql);
                         $va_values = array();
                         while ($qr_res->nextRow()) {
                             $vn_id = $qr_res->get($vs_field_name);
                             if ($va_criteria[$vn_id]) {
                                 continue;
                             }
                             // skip items that are used as browse critera - don't want to browse on something you're already browsing on
                             if (isset($va_list_items_by_value[$vn_id])) {
                                 $va_values[$vn_id] = array('id' => $vn_id, 'label' => $va_list_items_by_value[$vn_id]);
                                 if (!is_null($vs_single_value) && $vn_id == $vs_single_value) {
                                     $vb_single_value_is_present = true;
                                 }
                             }
                         }
                         if (!is_null($vs_single_value) && !$vb_single_value_is_present) {
                             return array();
                         }
                         return $va_values;
                     }
                 } else {
                     if ($t_browse_table = $this->opo_datamodel->getInstanceByTableName($vs_facet_table = $va_facet_info['table'], true)) {
                         // Handle fields containing ca_list_item.item_id's
                         $va_joins = array('INNER JOIN ' . $vs_browse_table_name . ' ON ' . $vs_browse_table_name . '.' . $vs_field_name . ' = ' . $vs_facet_table . '.' . $t_browse_table->primaryKey());
                         $vs_display_field_name = null;
                         if (method_exists($t_browse_table, 'getLabelTableInstance')) {
                             $t_label_instance = $t_browse_table->getLabelTableInstance();
                             $vs_display_field_name = isset($va_facet_info['display']) && $va_facet_info['display'] ? $va_facet_info['display'] : $t_label_instance->getDisplayField();
                             $va_joins[] = 'INNER JOIN ' . $t_label_instance->tableName() . " AS lab ON lab." . $t_browse_table->primaryKey() . ' = ' . $t_browse_table->tableName() . '.' . $t_browse_table->primaryKey();
                         }
                         if (sizeof($va_results) && $this->numCriteria() > 0) {
                             $va_wheres[] = "(" . $t_subject->tableName() . '.' . $t_subject->primaryKey() . " IN (" . join(',', $va_results) . "))";
                         }
                         if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_item->hasField('access')) {
                             $va_wheres[] = "(" . $vs_browse_table_name . ".access IN (" . join(',', $pa_options['checkAccess']) . "))";
                         }
                         if ($vs_browse_type_limit_sql) {
                             $va_wheres[] = $vs_browse_type_limit_sql;
                         }
                         if ($va_facet_info['relative_to']) {
                             if ($t_subject->hasField('deleted')) {
                                 $va_wheres[] = "(" . $t_subject->tableName() . ".deleted = 0)";
                             }
                             if ($va_relative_sql_data = $this->_getRelativeFacetSQLData($va_facet_info['relative_to'], $pa_options)) {
                                 $va_joins = array_merge($va_joins, $va_relative_sql_data['joins']);
                                 $va_wheres = array_merge($va_wheres, $va_relative_sql_data['wheres']);
                             }
                         }
                         if ($this->opo_config->get('perform_item_level_access_checking')) {
                             if ($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true)) {
                                 // Join to limit what browse table items are used to generate facet
                                 $va_joins[] = 'LEFT JOIN ca_acl ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_acl.row_id AND ca_acl.table_num = ' . $t_item->tableNum() . "\n";
                                 $va_wheres[] = "(\n\t\t\t\t\t\t\t\t\t\t\t((\n\t\t\t\t\t\t\t\t\t\t\t\t(ca_acl.user_id = " . (int) $vn_user_id . ")\n\t\t\t\t\t\t\t\t\t\t\t\t" . (sizeof($va_group_ids) > 0 ? "OR\n\t\t\t\t\t\t\t\t\t\t\t\t(ca_acl.group_id IN (" . join(",", $va_group_ids) . "))" : "") . "\n\t\t\t\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t\t\t\t(ca_acl.user_id IS NULL and ca_acl.group_id IS NULL)\n\t\t\t\t\t\t\t\t\t\t\t) AND ca_acl.access >= " . __CA_ACL_READONLY_ACCESS__ . ")\n\t\t\t\t\t\t\t\t\t\t\t" . ($vb_show_if_no_acl ? "OR ca_acl.acl_id IS NULL" : "") . "\n\t\t\t\t\t\t\t\t\t\t)";
                             }
                         }
                         $vs_join_sql = join("\n", $va_joins);
                         if (is_array($va_wheres) && sizeof($va_wheres) && ($vs_where_sql = join(' AND ', $va_wheres))) {
                             $vs_where_sql = 'WHERE (' . $vs_where_sql . ')';
                         }
                         if ($vb_check_availability_only) {
                             $vs_sql = "\n\t\t\t\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\t\t\t\tFROM {$vs_facet_table}\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\t\t\t\tLIMIT 1";
                             $qr_res = $this->opo_db->query($vs_sql);
                             return (int) $qr_res->numRows() > 0 ? true : false;
                         } else {
                             $vs_sql = "\n\t\t\t\t\t\t\t\t\t\tSELECT DISTINCT *\n\t\t\t\t\t\t\t\t\t\tFROM {$vs_facet_table}\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\t\t{$vs_where_sql}";
                             //print $vs_sql;
                             $qr_res = $this->opo_db->query($vs_sql);
                             $va_values = array();
                             $vs_pk = $t_browse_table->primaryKey();
                             while ($qr_res->nextRow()) {
                                 $vn_id = $qr_res->get($vs_pk);
                                 if ($va_criteria[$vn_id]) {
                                     continue;
                                 }
                                 // skip items that are used as browse critera - don't want to browse on something you're already browsing on
                                 $va_values[$vn_id][$qr_res->get('locale_id')] = array('id' => $vn_id, 'label' => $qr_res->get($vs_display_field_name));
                                 if (!is_null($vs_single_value) && $vn_id == $vs_single_value) {
                                     $vb_single_value_is_present = true;
                                 }
                             }
                             if (!is_null($vs_single_value) && !$vb_single_value_is_present) {
                                 return array();
                             }
                             return caExtractValuesByUserLocale($va_values);
                         }
                     }
                 }
             }
             return array();
             break;
             # -----------------------------------------------------
         # -----------------------------------------------------
         case 'field':
             $t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true);
             if (!is_array($va_restrict_to_types = $va_facet_info['restrict_to_types'])) {
                 $va_restrict_to_types = array();
             }
             if (!is_array($va_restrict_to_types = $this->_convertTypeCodesToIDs($va_restrict_to_types, array('instance' => $t_item, 'dontExpandHierarchically' => true)))) {
                 $va_restrict_to_types = array();
             }
             $va_restrict_to_types_expanded = $this->_convertTypeCodesToIDs($va_restrict_to_types, array('instance' => $t_item));
             $vs_field_name = $va_facet_info['field'];
             $va_field_info = $t_item->getFieldInfo($vs_field_name);
             $vs_sort_field = null;
             if ($t_item->getProperty('ID_NUMBERING_ID_FIELD') == $vs_field_name) {
                 $vs_sort_field = $vs_browse_table_name . '.' . $t_item->getProperty('ID_NUMBERING_SORT_FIELD');
             }
             $t_list = new ca_lists();
             $t_list_item = new ca_list_items();
             $va_joins = array();
             $va_wheres = array();
             $vs_where_sql = '';
             $va_facet_values = null;
             if ($vb_is_bit = $va_field_info['FIELD_TYPE'] == FT_BIT) {
                 $vs_yes_text = caGetOption('label_yes', $va_facet_info, _t('Yes'));
                 $vs_no_text = caGetOption('label_no', $va_facet_info, _t('No'));
                 $va_facet_values = array(1 => array('id' => 1, 'label' => $vs_yes_text), 0 => array('id' => 0, 'label' => $vs_no_text));
             }
             if (is_array($va_restrict_to_types) && sizeof($va_restrict_to_types) > 0 && method_exists($t_rel_item, "getTypeList")) {
                 $va_wheres[] = "{$va_restrict_to_types_expanded}.type_id IN (" . join(',', caGetOption('dont_include_subtypes', $va_facet_info, false) ? $va_restrict_to_types : $va_restrict_to_types_expanded) . ")";
                 $va_selects[] = "{$va_restrict_to_types_expanded}.type_id";
             }
             if (sizeof($va_results) && $this->numCriteria() > 0) {
                 $va_wheres[] = "(" . $t_subject->tableName() . '.' . $t_subject->primaryKey() . " IN (" . join(',', $va_results) . "))";
             }
             if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_item->hasField('access')) {
                 $va_wheres[] = "(" . $vs_browse_table_name . ".access IN (" . join(',', $pa_options['checkAccess']) . "))";
             }
             if ($vs_browse_type_limit_sql) {
                 $va_wheres[] = $vs_browse_type_limit_sql;
             }
             if ($t_item->hasField('deleted')) {
                 $va_wheres[] = "(" . $vs_browse_table_name . ".deleted = 0)";
             }
             if ($va_facet_info['relative_to']) {
                 if ($t_subject->hasField('deleted')) {
                     $va_wheres[] = "(" . $t_subject->tableName() . ".deleted = 0)";
                 }
                 if ($va_relative_sql_data = $this->_getRelativeFacetSQLData($va_facet_info['relative_to'], $pa_options)) {
                     $va_joins = array_merge($va_joins, $va_relative_sql_data['joins']);
                     $va_wheres = array_merge($va_wheres, $va_relative_sql_data['wheres']);
                 }
             }
             if ($this->opo_config->get('perform_item_level_access_checking')) {
                 if ($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true)) {
                     // Join to limit what browse table items are used to generate facet
                     $va_joins[] = 'LEFT JOIN ca_acl ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_acl.row_id AND ca_acl.table_num = ' . $t_item->tableNum() . "\n";
                     $va_wheres[] = "(\n\t\t\t\t\t\t\t\t((\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id = " . (int) $vn_user_id . ")\n\t\t\t\t\t\t\t\t\t" . (sizeof($va_group_ids) > 0 ? "OR\n\t\t\t\t\t\t\t\t\t(ca_acl.group_id IN (" . join(",", $va_group_ids) . "))" : "") . "\n\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id IS NULL and ca_acl.group_id IS NULL)\n\t\t\t\t\t\t\t\t) AND ca_acl.access >= " . __CA_ACL_READONLY_ACCESS__ . ")\n\t\t\t\t\t\t\t\t" . ($vb_show_if_no_acl ? "OR ca_acl.acl_id IS NULL" : "") . "\n\t\t\t\t\t\t\t)";
                 }
             }
             $vs_join_sql = join("\n", $va_joins);
             if (is_array($va_wheres) && sizeof($va_wheres) && ($vs_where_sql = join(' AND ', $va_wheres))) {
                 $vs_where_sql = '(' . $vs_where_sql . ')';
             }
             if ($vb_check_availability_only) {
                 $vs_sql = "\n\t\t\t\t\t\t\tSELECT DISTINCT {$vs_browse_table_name}.{$vs_field_name}\n\t\t\t\t\t\t\tFROM {$vs_browse_table_name}\n\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\tLIMIT 2";
                 $qr_res = $this->opo_db->query($vs_sql);
                 if ($qr_res->numRows() > 1) {
                     return true;
                 }
                 return false;
             } else {
                 $vs_pk = $t_item->primaryKey();
                 $vs_sql = "\n\t\t\t\t\t\t\tSELECT DISTINCT {$vs_browse_table_name}.{$vs_field_name}\n\t\t\t\t\t\t\tFROM {$vs_browse_table_name}\n\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t{$vs_where_sql}";
                 if ($vs_sort_field) {
                     $vs_sql .= " ORDER BY {$vs_sort_field}";
                 }
                 $qr_res = $this->opo_db->query($vs_sql);
                 $va_values = array();
                 while ($qr_res->nextRow()) {
                     if (!($vs_val = trim($qr_res->get($vs_field_name))) && !$vb_is_bit) {
                         continue;
                     }
                     if ($va_criteria[$vs_val]) {
                         continue;
                     }
                     // skip items that are used as browse critera - don't want to browse on something you're already browsing on
                     if ($vb_is_bit && isset($va_facet_values[$vs_val])) {
                         $va_values[$vs_val] = $va_facet_values[$vs_val];
                     } else {
                         $va_values[$vs_val] = array('id' => str_replace('/', '&#47;', $vs_val), 'label' => $vs_val);
                     }
                     if (!is_null($vs_single_value) && $vs_val == $vs_single_value) {
                         $vb_single_value_is_present = true;
                     }
                 }
                 if (!is_null($vs_single_value) && !$vb_single_value_is_present) {
                     return array();
                 }
                 return $va_values;
             }
             return array();
             break;
             # -----------------------------------------------------
         # -----------------------------------------------------
         case 'violations':
             $t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true);
             $vs_field_name = $va_facet_info['field'];
             $va_field_info = $t_item->getFieldInfo($vs_field_name);
             $va_joins = array();
             $va_wheres = array();
             $vs_where_sql = '';
             $va_facet_values = null;
             if (sizeof($va_results) && $this->numCriteria() > 0) {
                 $va_wheres[] = "(" . $t_subject->tableName() . '.' . $t_subject->primaryKey() . " IN (" . join(',', $va_results) . "))";
             }
             if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_item->hasField('access')) {
                 $va_wheres[] = "(" . $vs_browse_table_name . ".access IN (" . join(',', $pa_options['checkAccess']) . "))";
             }
             if ($vs_browse_type_limit_sql) {
                 $va_wheres[] = $vs_browse_type_limit_sql;
             }
             if ($t_item->hasField('deleted')) {
                 $va_wheres[] = "(" . $vs_browse_table_name . ".deleted = 0)";
             }
             if ($va_facet_info['relative_to']) {
                 if ($t_subject->hasField('deleted')) {
                     $va_wheres[] = "(" . $t_subject->tableName() . ".deleted = 0)";
                 }
                 if ($va_relative_sql_data = $this->_getRelativeFacetSQLData($va_facet_info['relative_to'], $pa_options)) {
                     $va_joins = array_merge($va_joins, $va_relative_sql_data['joins']);
                     $va_wheres = array_merge($va_wheres, $va_relative_sql_data['wheres']);
                 }
             }
             if ($this->opo_config->get('perform_item_level_access_checking')) {
                 if ($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true)) {
                     // Join to limit what browse table items are used to generate facet
                     $va_joins[] = 'LEFT JOIN ca_acl ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_acl.row_id AND ca_acl.table_num = ' . $t_item->tableNum() . "\n";
                     $va_wheres[] = "(\n\t\t\t\t\t\t\t\t((\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id = " . (int) $vn_user_id . ")\n\t\t\t\t\t\t\t\t\t" . (sizeof($va_group_ids) > 0 ? "OR\n\t\t\t\t\t\t\t\t\t(ca_acl.group_id IN (" . join(",", $va_group_ids) . "))" : "") . "\n\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id IS NULL and ca_acl.group_id IS NULL)\n\t\t\t\t\t\t\t\t) AND ca_acl.access >= " . __CA_ACL_READONLY_ACCESS__ . ")\n\t\t\t\t\t\t\t\t" . ($vb_show_if_no_acl ? "OR ca_acl.acl_id IS NULL" : "") . "\n\t\t\t\t\t\t\t)";
                 }
             }
             $vs_join_sql = join("\n", $va_joins);
             if (is_array($va_wheres) && sizeof($va_wheres) && ($vs_where_sql = join(' AND ', $va_wheres))) {
                 $vs_where_sql = '(' . $vs_where_sql . ')';
             }
             if ($vb_check_availability_only) {
                 $vs_sql = "\n\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\tFROM {$vs_browse_table_name}\n\t\t\t\t\t\t\tINNER JOIN ca_metadata_dictionary_rule_violations ON ca_metadata_dictionary_rule_violations.row_id = {$vs_browse_table_name}." . $t_item->primaryKey() . " AND ca_metadata_dictionary_rule_violations.table_num = {$vs_browse_table_num}\n\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\tLIMIT 2";
                 $qr_res = $this->opo_db->query($vs_sql);
                 if ($qr_res->nextRow()) {
                     return (int) $qr_res->numRows() > 0 ? true : false;
                 }
                 return false;
             } else {
                 $vs_pk = $t_item->primaryKey();
                 $vs_sql = "\n\t\t\t\t\t\t\tSELECT DISTINCT ca_metadata_dictionary_rules.rule_id\n\t\t\t\t\t\t\tFROM {$vs_browse_table_name}\n\t\t\t\t\t\t\tINNER JOIN ca_metadata_dictionary_rule_violations ON ca_metadata_dictionary_rule_violations.row_id = {$vs_browse_table_name}." . $t_item->primaryKey() . " AND ca_metadata_dictionary_rule_violations.table_num = {$vs_browse_table_num}\n\t\t\t\t\t\t\tINNER JOIN ca_metadata_dictionary_rules ON ca_metadata_dictionary_rules.rule_id = ca_metadata_dictionary_rule_violations.rule_id\n\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t{$vs_where_sql}";
                 $qr_res = $this->opo_db->query($vs_sql);
                 $va_values = array();
                 $t_rule = new ca_metadata_dictionary_rules();
                 while ($qr_res->nextRow()) {
                     if ($t_rule->load($qr_res->get('rule_id'))) {
                         if (!($vs_val = trim($t_rule->getSetting('label')))) {
                             continue;
                         }
                         $vs_code = $t_rule->get('rule_code');
                         if ($va_criteria[$vs_val]) {
                             continue;
                         }
                         // skip items that are used as browse critera - don't want to browse on something you're already browsing on
                         if (isset($va_facet_values[$vs_code])) {
                             $va_values[$vs_code] = $va_facet_values[$vs_code];
                         } else {
                             $va_values[$vs_code] = array('id' => $vs_code, 'label' => $vs_val);
                         }
                         if (!is_null($vs_single_value) && $vs_code == $vs_single_value) {
                             $vb_single_value_is_present = true;
                         }
                     }
                 }
                 if (!is_null($vs_single_value) && !$vb_single_value_is_present) {
                     return array();
                 }
                 return $va_values;
             }
             return array();
             break;
             # -----------------------------------------------------
         # -----------------------------------------------------
         case 'checkouts':
             if ($vs_browse_table_name != 'ca_objects') {
                 return array();
             }
             $t_item = new ca_objects();
             $va_joins = array();
             $va_wheres = array();
             $vs_where_sql = '';
             $va_facet_values = null;
             if (sizeof($va_results) && $this->numCriteria() > 0) {
                 $va_wheres[] = "(" . $t_subject->tableName() . '.' . $t_subject->primaryKey() . " IN (" . join(',', $va_results) . "))";
             }
             if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_item->hasField('access')) {
                 $va_wheres[] = "(" . $vs_browse_table_name . ".access IN (" . join(',', $pa_options['checkAccess']) . "))";
             }
             if ($vs_browse_type_limit_sql) {
                 $va_wheres[] = $vs_browse_type_limit_sql;
             }
             if ($t_item->hasField('deleted')) {
                 $va_wheres[] = "(" . $vs_browse_table_name . ".deleted = 0)";
             }
             if ($va_facet_info['relative_to']) {
                 if ($t_subject->hasField('deleted')) {
                     $va_wheres[] = "(" . $t_subject->tableName() . ".deleted = 0)";
                 }
                 if ($va_relative_sql_data = $this->_getRelativeFacetSQLData($va_facet_info['relative_to'], $pa_options)) {
                     $va_joins = array_merge($va_joins, $va_relative_sql_data['joins']);
                     $va_wheres = array_merge($va_wheres, $va_relative_sql_data['wheres']);
                 }
             }
             $vs_checkout_join_sql = "INNER JOIN ca_object_checkouts ON ca_object_checkouts.object_id = ca_objects.object_id";
             $vn_current_time = time();
             switch ($va_facet_info['status']) {
                 case 'overdue':
                     $va_wheres[] = "((ca_object_checkouts.checkout_date <= {$vn_current_time}) AND (ca_object_checkouts.return_date IS NULL) AND (ca_object_checkouts.due_date <= {$vn_current_time}))";
                     break;
                 case 'reserved':
                     $va_wheres[] = "((ca_object_checkouts.checkout_date IS NULL) AND (ca_object_checkouts.return_date IS NULL))";
                     break;
                 case 'available':
                     $vs_checkout_join_sql = '';
                     $va_wheres[] = "(ca_objects.object_id NOT IN (SELECT object_id FROM ca_object_checkouts WHERE (ca_object_checkouts.checkout_date <= {$vn_current_time}) AND (ca_object_checkouts.return_date IS NULL)))";
                     break;
                 default:
                 case 'out':
                     $va_wheres[] = "((ca_object_checkouts.checkout_date <= {$vn_current_time}) AND (ca_object_checkouts.return_date IS NULL))";
                     break;
             }
             if ($vs_checkout_join_sql) {
                 $va_joins[] = $vs_checkout_join_sql;
                 $va_joins[] = "INNER JOIN ca_users ON ca_object_checkouts.user_id = ca_users.user_id";
             }
             if ($this->opo_config->get('perform_item_level_access_checking')) {
                 if ($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true)) {
                     // Join to limit what browse table items are used to generate facet
                     $va_joins[] = 'LEFT JOIN ca_acl ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_acl.row_id AND ca_acl.table_num = ' . $t_item->tableNum() . "\n";
                     $va_wheres[] = "(\n\t\t\t\t\t\t\t\t((\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id = " . (int) $vn_user_id . ")\n\t\t\t\t\t\t\t\t\t" . (sizeof($va_group_ids) > 0 ? "OR\n\t\t\t\t\t\t\t\t\t(ca_acl.group_id IN (" . join(",", $va_group_ids) . "))" : "") . "\n\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id IS NULL and ca_acl.group_id IS NULL)\n\t\t\t\t\t\t\t\t) AND ca_acl.access >= " . __CA_ACL_READONLY_ACCESS__ . ")\n\t\t\t\t\t\t\t\t" . ($vb_show_if_no_acl ? "OR ca_acl.acl_id IS NULL" : "") . "\n\t\t\t\t\t\t\t)";
                 }
             }
             $vs_join_sql = join("\n", $va_joins);
             if (is_array($va_wheres) && sizeof($va_wheres) && ($vs_where_sql = join(' AND ', $va_wheres))) {
                 $vs_where_sql = '(' . $vs_where_sql . ')';
             }
             if ($vb_check_availability_only) {
                 switch ($va_facet_info['mode']) {
                     case 'user':
                         $vs_sql = "\n\t\t\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\t\t\tFROM ca_objects\n\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t{$vs_where_sql} AND ca_objects.deleted = 0\n\t\t\t\t\t\t\t\t\tLIMIT 2";
                         break;
                     default:
                     case 'all':
                         $vs_sql = "\n\t\t\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\t\t\tFROM ca_objects\n\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\tca_objects.deleted = 0 " . (sizeof($va_results) ? "AND (" . $t_subject->tableName() . '.' . $t_subject->primaryKey() . " IN (" . join(',', $va_results) . "))" : "") . "\n\t\t\t\t\t\t\t\t\tLIMIT 2";
                         break;
                 }
                 $qr_res = $this->opo_db->query($vs_sql);
                 if ($qr_res->nextRow()) {
                     return (int) $qr_res->numRows() > 0 ? true : false;
                 }
                 return false;
             } else {
                 $va_values = array();
                 $vs_pk = $t_item->primaryKey();
                 switch ($va_facet_info['mode']) {
                     case 'user':
                         $vs_sql = "\n\t\t\t\t\t\t\t\t\tSELECT DISTINCT ca_object_checkouts.user_id, ca_users.fname, ca_users.lname, ca_users.email\n\t\t\t\t\t\t\t\t\tFROM ca_objects\n\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t{$vs_where_sql} " . (sizeof($va_results) ? " AND (" . $t_subject->tableName() . '.' . $t_subject->primaryKey() . " IN (" . join(',', $va_results) . "))" : "");
                         $qr_res = $this->opo_db->query($vs_sql);
                         while ($qr_res->nextRow()) {
                             $vn_user_id = $qr_res->get('user_id');
                             $vs_val = $qr_res->get('fname') . ' ' . $qr_res->get('lname') . (($vs_email = $qr_res->get('email')) ? "({$vs_email})" : '');
                             if ($va_criteria[$vs_val]) {
                                 continue;
                             }
                             // skip items that are used as browse critera - don't want to browse on something you're already browsing on
                             if (isset($va_facet_values[$vn_user_id])) {
                                 $va_values[$vn_user_id] = $va_facet_values[$vn_user_id];
                             } else {
                                 $va_values[$vn_user_id] = array('id' => $vn_user_id, 'label' => $vs_val);
                             }
                             if (!is_null($vs_single_value) && $vn_user_id == $vs_single_value) {
                                 $vb_single_value_is_present = true;
                             }
                         }
                         break;
                     case 'all':
                     default:
                         foreach (array(_t('Available') => 'available', _t('Out') => 'out', _t('Reserved') => 'reserved', _t('Overdue') => 'overdue') as $vs_status_text => $vs_status) {
                             $vs_join_sql = "INNER JOIN ca_object_checkouts ON ca_object_checkouts.object_id = ca_objects.object_id";
                             switch ($vs_status) {
                                 case 'overdue':
                                     $vs_where = "((ca_object_checkouts.checkout_date <= {$vn_current_time}) AND (ca_object_checkouts.return_date IS NULL) AND (ca_object_checkouts.due_date <= {$vn_current_time}))";
                                     break;
                                 case 'reserved':
                                     $vs_where = "((ca_object_checkouts.checkout_date IS NULL) AND (ca_object_checkouts.return_date IS NULL))";
                                     break;
                                 case 'available':
                                     $vs_join_sql = '';
                                     $vs_where = "(ca_objects.object_id NOT IN (SELECT object_id FROM ca_object_checkouts WHERE (ca_object_checkouts.checkout_date <= {$vn_current_time}) AND (ca_object_checkouts.return_date IS NULL)))";
                                     break;
                                 default:
                                 case 'out':
                                     $vs_where = "((ca_object_checkouts.checkout_date <= {$vn_current_time}) AND (ca_object_checkouts.return_date IS NULL))";
                                     break;
                             }
                             if (sizeof($va_results) && $this->numCriteria() > 0) {
                                 $vs_where .= " AND (" . $t_subject->tableName() . '.' . $t_subject->primaryKey() . " IN (" . join(',', $va_results) . "))";
                             }
                             $vs_sql = "\n\t\t\t\t\t\t\t\t\t\tSELECT count(*) c\n\t\t\t\t\t\t\t\t\t\tFROM ca_objects\n\t\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t{$vs_where}\n\t\t\t\t\t\t\t\t\t";
                             $qr_res = $this->opo_db->query($vs_sql);
                             $qr_res->nextRow();
                             if (!$qr_res->get('c')) {
                                 continue;
                             }
                             $va_values[$vs_status] = array('id' => $vs_status, 'label' => $vs_status_text);
                             if (!is_null($vs_single_value) && $vs_status == $vs_single_value) {
                                 $vb_single_value_is_present = true;
                             }
                         }
                         break;
                 }
                 if (!is_null($vs_single_value) && !$vb_single_value_is_present) {
                     return array();
                 }
                 return $va_values;
             }
             return array();
             break;
             # -----------------------------------------------------
         # -----------------------------------------------------
         case 'normalizedDates':
             $t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true);
             $t_element = new ca_metadata_elements();
             $vb_is_element = $vb_is_field = false;
             if (!($vb_is_element = $t_element->load(array('element_code' => $va_facet_info['element_code']))) && !($vb_is_field = $t_item->hasField($va_facet_info['element_code']) && $t_item->getFieldInfo($va_facet_info['element_code'], 'FIELD_TYPE') === FT_HISTORIC_DATERANGE)) {
                 return array();
             }
             if ($vb_is_element) {
                 $va_joins = array('INNER JOIN ca_attribute_values ON ca_attributes.attribute_id = ca_attribute_values.attribute_id', 'INNER JOIN ' . $vs_browse_table_name . ' ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_attributes.row_id AND ca_attributes.table_num = ' . intval($vs_browse_table_num));
             } else {
                 $va_joins = array();
             }
             $va_wheres = array();
             $vs_normalization = $va_facet_info['normalization'];
             // how do we construct the date ranges presented to uses. In other words - how do we want to allow users to browse dates? By year, decade, century?
             if (sizeof($va_results) && $this->numCriteria() > 0) {
                 $va_wheres[] = "(" . $t_subject->tableName() . '.' . $t_subject->primaryKey() . " IN (" . join(',', $va_results) . "))";
             }
             if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_item->hasField('access')) {
                 $va_wheres[] = "(" . $vs_browse_table_name . ".access IN (" . join(',', $pa_options['checkAccess']) . "))";
             }
             if ($vs_browse_type_limit_sql) {
                 $va_wheres[] = $vs_browse_type_limit_sql;
             }
             if ($t_item->hasField('deleted')) {
                 $va_wheres[] = "(" . $vs_browse_table_name . ".deleted = 0)";
             }
             if ($va_facet_info['relative_to']) {
                 if ($t_subject->hasField('deleted')) {
                     $va_wheres[] = "(" . $t_subject->tableName() . ".deleted = 0)";
                 }
                 if ($va_relative_sql_data = $this->_getRelativeFacetSQLData($va_facet_info['relative_to'], $pa_options)) {
                     $va_joins = array_merge($va_joins, $va_relative_sql_data['joins']);
                     $va_wheres = array_merge($va_wheres, $va_relative_sql_data['wheres']);
                 }
             }
             if ($this->opo_config->get('perform_item_level_access_checking')) {
                 if ($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true)) {
                     // Join to limit what browse table items are used to generate facet
                     $va_joins[] = 'LEFT JOIN ca_acl ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_acl.row_id AND ca_acl.table_num = ' . $t_item->tableNum() . "\n";
                     $va_wheres[] = "(\n\t\t\t\t\t\t\t\t((\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id = " . (int) $vn_user_id . ")\n\t\t\t\t\t\t\t\t\t" . (sizeof($va_group_ids) > 0 ? "OR\n\t\t\t\t\t\t\t\t\t(ca_acl.group_id IN (" . join(",", $va_group_ids) . "))" : "") . "\n\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id IS NULL and ca_acl.group_id IS NULL)\n\t\t\t\t\t\t\t\t) AND ca_acl.access >= " . __CA_ACL_READONLY_ACCESS__ . ")\n\t\t\t\t\t\t\t\t" . ($vb_show_if_no_acl ? "OR ca_acl.acl_id IS NULL" : "") . "\n\t\t\t\t\t\t\t)";
                 }
             }
             $vs_where_sql = '';
             if (is_array($va_wheres) && sizeof($va_wheres) && ($vs_where_sql = join(' AND ', $va_wheres))) {
                 $vs_where_sql = ' AND (' . $vs_where_sql . ')';
             }
             $vs_join_sql = join("\n", $va_joins);
             if ($vb_is_element) {
                 $vn_element_id = $t_element->getPrimaryKey();
                 $vs_dir = strtoupper($va_facet_info['sort']) === 'DESC' ? "DESC" : "ASC";
                 $o_tep = new TimeExpressionParser();
                 $vn_min_date = $vn_max_date = null;
                 $vs_min_sql = $vs_max_sql = '';
                 if (isset($va_facet_info['minimum_date'])) {
                     if ($o_tep->parse($va_facet_info['minimum_date'])) {
                         $va_tmp = $o_tep->getHistoricTimestamps();
                         $vn_min_date = (double) $va_tmp['start'];
                         $vs_min_sql = " AND (ca_attribute_values.value_decimal1 >= {$vn_min_date})";
                     }
                 }
                 if (isset($va_facet_info['maximum_date'])) {
                     if ($o_tep->parse($va_facet_info['maximum_date'])) {
                         $va_tmp = $o_tep->getHistoricTimestamps();
                         $vn_max_date = (double) $va_tmp['end'];
                         $vs_max_sql = " AND (ca_attribute_values.value_decimal2 <= {$vn_max_date})";
                     }
                 }
                 if ($vb_check_availability_only) {
                     $vs_sql = "\n\t\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\t\tFROM ca_attributes\n\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\tca_attribute_values.element_id = ? \n\t\t\t\t\t\t\t\t\t{$vs_min_sql}\n\t\t\t\t\t\t\t\t\t{$vs_max_sql}\n\t\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\t\t\tLIMIT 1";
                     //print $vs_sql;
                     $qr_res = $this->opo_db->query($vs_sql, $vn_element_id);
                     return (int) $qr_res->numRows() > 0 ? true : false;
                 } else {
                     $vs_sql = "\n\t\t\t\t\t\t\t\tSELECT DISTINCT ca_attribute_values.value_decimal1, ca_attribute_values.value_decimal2\n\t\t\t\t\t\t\t\tFROM ca_attributes\n\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\tca_attribute_values.element_id = ? \n\t\t\t\t\t\t\t\t\t{$vs_min_sql}\n\t\t\t\t\t\t\t\t\t{$vs_max_sql}\n\t\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\t";
                     //print $vs_sql;
                     $qr_res = $this->opo_db->query($vs_sql, $vn_element_id);
                     $vn_current_year = (int) date("Y");
                     $va_values = array();
                     $vb_include_unknown = (bool) caGetOption('include_unknown', $va_facet_info, false);
                     $vb_unknown_is_set = false;
                     while ($qr_res->nextRow()) {
                         $vn_start = $qr_res->get('value_decimal1');
                         $vn_end = $qr_res->get('value_decimal2');
                         if (!($vn_start && $vn_end)) {
                             if ($vb_include_unknown) {
                                 $vb_unknown_is_set = true;
                             }
                             continue;
                         }
                         if ($vn_end > $vn_current_year + 50) {
                             continue;
                         }
                         // bad years can make for large facets that cause timeouts so cut it off 50 years into the future
                         $va_normalized_values = $o_tep->normalizeDateRange($vn_start, $vn_end, $vs_normalization);
                         foreach ($va_normalized_values as $vn_sort_value => $vs_normalized_value) {
                             if ($va_criteria[$vs_normalized_value]) {
                                 continue;
                             }
                             // skip items that are used as browse critera - don't want to browse on something you're already browsing on
                             if (is_numeric($vs_normalized_value) && (int) $vs_normalized_value === 0) {
                                 continue;
                             }
                             // don't include year=0
                             $va_values[$vn_sort_value][$vs_normalized_value] = array('id' => $vs_normalized_value, 'label' => $vs_normalized_value);
                             if (!is_null($vs_single_value) && $vs_normalized_value == $vs_single_value) {
                                 $vb_single_value_is_present = true;
                             }
                         }
                     }
                     if ($vb_include_unknown && !$vb_unknown_is_set) {
                         // Check for rows where no data is set at all as opposed to null dates
                         $vs_sql = "\n\t\t\t\t\t\t\t\t\tSELECT DISTINCT ca_attributes.row_id\n\t\t\t\t\t\t\t\t\tFROM ca_attributes\n\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\tca_attribute_values.element_id = ? \n\t\t\t\t\t\t\t\t\t\t{$vs_min_sql}\n\t\t\t\t\t\t\t\t\t\t{$vs_max_sql}\n\t\t\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\t\t";
                         //print $vs_sql;
                         $qr_res = $this->opo_db->query($vs_sql, $vn_element_id);
                         if ($qr_res->numRows() < sizeof($va_results)) {
                             $vb_unknown_is_set = true;
                         }
                     }
                     if ($vb_unknown_is_set && sizeof($va_values) > 0) {
                         $va_values['999999999'][_t('Date unknown')] = array('id' => 'null', 'label' => _t('Date unknown'));
                     }
                     if (!is_null($vs_single_value) && !$vb_single_value_is_present) {
                         return array();
                     }
                     ksort($va_values);
                     if ($vs_dir == 'DESC') {
                         $va_values = array_reverse($va_values);
                     }
                     $va_sorted_values = array();
                     foreach ($va_values as $vn_sort_value => $va_values_for_sort_value) {
                         $va_sorted_values = array_merge($va_sorted_values, $va_values_for_sort_value);
                     }
                     return $va_sorted_values;
                 }
             } else {
                 // is intrinsic
                 $vs_dir = strtoupper($va_facet_info['sort']) === 'DESC' ? "DESC" : "ASC";
                 $vs_browse_start_fld = $t_item->getFieldInfo($va_facet_info['element_code'], 'START');
                 $vs_browse_end_fld = $t_item->getFieldInfo($va_facet_info['element_code'], 'END');
                 $o_tep = new TimeExpressionParser();
                 $vn_min_date = $vn_max_date = null;
                 $vs_min_sql = $vs_max_sql = '';
                 if (isset($va_facet_info['minimum_date'])) {
                     if ($o_tep->parse($va_facet_info['minimum_date'])) {
                         $va_tmp = $o_tep->getHistoricTimestamps();
                         $vn_min_date = (double) $va_tmp['start'];
                         $vs_min_sql = " AND ({$vs_browse_table_name}.{$vs_browse_start_fld} >= {$vn_min_date})";
                     }
                 }
                 if (isset($va_facet_info['maximum_date'])) {
                     if ($o_tep->parse($va_facet_info['maximum_date'])) {
                         $va_tmp = $o_tep->getHistoricTimestamps();
                         $vn_max_date = (double) $va_tmp['end'];
                         $vs_max_sql = " AND ({$vs_browse_table_name}.{$vs_browse_end_fld} <= {$vn_max_date})";
                     }
                 }
                 if ($vb_check_availability_only) {
                     $vs_sql = "\n\t\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\t\tFROM {$vs_browse_table_name}\n\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t1 = 1\n\t\t\t\t\t\t\t\t\t{$vs_min_sql}\n\t\t\t\t\t\t\t\t\t{$vs_max_sql}\n\t\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\t\t\tLIMIT 1";
                     //print $vs_sql;
                     $qr_res = $this->opo_db->query($vs_sql);
                     return (int) $qr_res->numRows() > 0 ? true : false;
                 } else {
                     $vs_sql = "\n\t\t\t\t\t\t\t\tSELECT DISTINCT {$vs_browse_table_name}.{$vs_browse_start_fld}, {$vs_browse_table_name}.{$vs_browse_end_fld}\n\t\t\t\t\t\t\t\tFROM {$vs_browse_table_name}\n\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t1 = 1\n\t\t\t\t\t\t\t\t\t{$vs_min_sql}\n\t\t\t\t\t\t\t\t\t{$vs_max_sql}\n\t\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\t";
                     //print $vs_sql;
                     $qr_res = $this->opo_db->query($vs_sql);
                     $va_values = array();
                     while ($qr_res->nextRow()) {
                         $vn_start = $qr_res->get($vs_browse_start_fld);
                         $vn_end = $qr_res->get($vs_browse_end_fld);
                         if (!($vn_start && $vn_end)) {
                             continue;
                         }
                         $va_normalized_values = $o_tep->normalizeDateRange($vn_start, $vn_end, $vs_normalization);
                         foreach ($va_normalized_values as $vn_sort_value => $vs_normalized_value) {
                             if ($va_criteria[$vs_normalized_value]) {
                                 continue;
                             }
                             // skip items that are used as browse critera - don't want to browse on something you're already browsing on
                             if (is_numeric($vs_normalized_value) && (int) $vs_normalized_value === 0) {
                                 continue;
                             }
                             // don't include year=0
                             $va_values[$vn_sort_value][$vs_normalized_value] = array('id' => $vs_normalized_value, 'label' => $vs_normalized_value);
                             if (!is_null($vs_single_value) && $vs_normalized_value == $vs_single_value) {
                                 $vb_single_value_is_present = true;
                             }
                         }
                     }
                     if (!is_null($vs_single_value) && !$vb_single_value_is_present) {
                         return array();
                     }
                     ksort($va_values);
                     if ($vs_dir == 'DESC') {
                         $va_values = array_reverse($va_values);
                     }
                     $va_sorted_values = array();
                     foreach ($va_values as $vn_sort_value => $va_values_for_sort_value) {
                         $va_sorted_values = array_merge($va_sorted_values, $va_values_for_sort_value);
                     }
                     return $va_sorted_values;
                 }
             }
             break;
             # -----------------------------------------------------
         # -----------------------------------------------------
         case 'normalizedLength':
             $t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true);
             $t_element = new ca_metadata_elements();
             $vb_is_element = $vb_is_field = false;
             if (!($vb_is_element = $t_element->load(array('element_code' => $va_facet_info['element_code']))) && !($vb_is_field = $t_item->hasField($va_facet_info['element_code']) && $t_item->getFieldInfo($va_facet_info['element_code'], 'FIELD_TYPE') === FT_HISTORIC_DATERANGE)) {
                 return array();
             }
             if ($vb_is_element) {
                 $va_joins = array('INNER JOIN ca_attribute_values ON ca_attributes.attribute_id = ca_attribute_values.attribute_id', 'INNER JOIN ' . $vs_browse_table_name . ' ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_attributes.row_id AND ca_attributes.table_num = ' . intval($vs_browse_table_num));
             } else {
                 $va_joins = array();
             }
             $va_wheres = array();
             $vs_normalization = $va_facet_info['normalization'];
             // how do we construct the dimensions ranges presented to users. In other words - what increments do we can to use to  browse measurments?
             if (sizeof($va_results) && $this->numCriteria() > 0) {
                 $va_wheres[] = "(" . $t_subject->tableName() . '.' . $t_subject->primaryKey() . " IN (" . join(',', $va_results) . "))";
             }
             if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_item->hasField('access')) {
                 $va_wheres[] = "(" . $vs_browse_table_name . ".access IN (" . join(',', $pa_options['checkAccess']) . "))";
             }
             if ($vs_browse_type_limit_sql) {
                 $va_wheres[] = $vs_browse_type_limit_sql;
             }
             if ($t_item->hasField('deleted')) {
                 $va_wheres[] = "(" . $vs_browse_table_name . ".deleted = 0)";
             }
             if ($va_facet_info['relative_to']) {
                 if ($t_subject->hasField('deleted')) {
                     $va_wheres[] = "(" . $t_subject->tableName() . ".deleted = 0)";
                 }
                 if ($va_relative_sql_data = $this->_getRelativeFacetSQLData($va_facet_info['relative_to'], $pa_options)) {
                     $va_joins = array_merge($va_joins, $va_relative_sql_data['joins']);
                     $va_wheres = array_merge($va_wheres, $va_relative_sql_data['wheres']);
                 }
             }
             if ($this->opo_config->get('perform_item_level_access_checking')) {
                 if ($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true)) {
                     // Join to limit what browse table items are used to generate facet
                     $va_joins[] = 'LEFT JOIN ca_acl ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_acl.row_id AND ca_acl.table_num = ' . $t_item->tableNum() . "\n";
                     $va_wheres[] = "(\n\t\t\t\t\t\t\t\t((\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id = " . (int) $vn_user_id . ")\n\t\t\t\t\t\t\t\t\t" . (sizeof($va_group_ids) > 0 ? "OR\n\t\t\t\t\t\t\t\t\t(ca_acl.group_id IN (" . join(",", $va_group_ids) . "))" : "") . "\n\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id IS NULL and ca_acl.group_id IS NULL)\n\t\t\t\t\t\t\t\t) AND ca_acl.access >= " . __CA_ACL_READONLY_ACCESS__ . ")\n\t\t\t\t\t\t\t\t" . ($vb_show_if_no_acl ? "OR ca_acl.acl_id IS NULL" : "") . "\n\t\t\t\t\t\t\t)";
                 }
             }
             $vs_where_sql = '';
             if (is_array($va_wheres) && sizeof($va_wheres) && ($vs_where_sql = join(' AND ', $va_wheres))) {
                 $vs_where_sql = ' AND (' . $vs_where_sql . ')';
             }
             $vs_join_sql = join("\n", $va_joins);
             $vn_element_id = $t_element->getPrimaryKey();
             $vs_dir = strtoupper($va_facet_info['sort']) === 'DESC' ? "DESC" : "ASC";
             $vs_min_sql = $vs_max_sql = '';
             $vo_minimum_dimension = caParseLengthDimension(caGetOption('minimum_dimension', $va_facet_info, "0 in"));
             $vo_maximum_dimension = caParseLengthDimension(caGetOption('maximum_dimension', $va_facet_info, "0 in"));
             if ($vo_minimum_dimension) {
                 $vn_tmp = (double) $vo_minimum_dimension->convertTo('METER', 6, 'en_US');
                 $vs_min_sql = " AND (ca_attribute_values.value_decimal1 >= {$vn_tmp})";
             }
             if (caGetOption('maximum_dimension', $va_facet_info, null) && $vo_maximum_dimension) {
                 $vn_tmp = (double) $vo_maximum_dimension->convertTo('METER', 6, 'en_US');
                 $vs_max_sql = " AND (ca_attribute_values.value_decimal1 <= {$vn_tmp})";
             }
             if ($vb_check_availability_only) {
                 $vs_sql = "\n\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\tFROM ca_attributes\n\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\tca_attribute_values.element_id = ? \n\t\t\t\t\t\t\t\t{$vs_min_sql}\n\t\t\t\t\t\t\t\t{$vs_max_sql}\n\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\t\tLIMIT 1";
                 //print $vs_sql;
                 $qr_res = $this->opo_db->query($vs_sql, $vn_element_id);
                 return (int) $qr_res->numRows() > 0 ? true : false;
             } else {
                 $vs_sql = "\n\t\t\t\t\t\t\tSELECT DISTINCT ca_attribute_values.value_decimal1, ca_attribute_values.value_decimal2, ca_attribute_values.value_longtext1, ca_attribute_values.value_longtext2\n\t\t\t\t\t\t\tFROM ca_attributes\n\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\tca_attribute_values.element_id = ? \n\t\t\t\t\t\t\t\t{$vs_min_sql}\n\t\t\t\t\t\t\t\t{$vs_max_sql}\n\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t";
                 //print $vs_sql;
                 $qr_res = $this->opo_db->query($vs_sql, $vn_element_id);
                 $va_values = array();
                 if (!($vs_output_units = caGetLengthUnitType($vs_units = caGetOption('units', $va_facet_info, 'm')))) {
                     $vs_output_units = Zend_Measure_Length::METER;
                 }
                 $vs_increment = caGetOption('increment', $va_facet_info, '1 m');
                 $vo_increment = caParseLengthDimension($vs_increment);
                 $vn_increment_in_current_units = (double) $vo_increment->convertTo($vs_output_units, 6, 'en_US');
                 while ($qr_res->nextRow()) {
                     $vn_meters = $qr_res->get('value_decimal1');
                     // measurement in meters
                     // convert to target dimensions
                     // normalize
                     $vo_dim = new Zend_Measure_Length($vn_meters, Zend_Measure_Length::METER, 'en_US');
                     $vs_dim = $vo_dim->convertTo($vs_output_units, 6, 'en_US');
                     $vn_dim = (double) $vs_dim;
                     $vn_normalized = floor($vn_dim / $vn_increment_in_current_units) * $vn_increment_in_current_units;
                     if (isset($va_criteria[$vn_normalized])) {
                         continue;
                     }
                     $vs_normalized_range_with_units = "{$vn_normalized} {$vs_units} - " . ($vn_normalized + $vn_increment_in_current_units) . " {$vs_units}";
                     $va_values[$vn_normalized][$vn_normalized] = array('id' => $vn_normalized, 'label' => $vs_normalized_range_with_units);
                     if (!is_null($vs_single_value) && $vn_normalized == $vs_single_value) {
                         $vb_single_value_is_present = true;
                     }
                 }
                 if (!is_null($vs_single_value) && !$vb_single_value_is_present) {
                     return array();
                 }
                 ksort($va_values);
                 if ($vs_dir == 'DESC') {
                     $va_values = array_reverse($va_values);
                 }
                 $va_sorted_values = array();
                 foreach ($va_values as $vn_sort_value => $va_values_for_sort_value) {
                     $va_sorted_values = array_merge($va_sorted_values, $va_values_for_sort_value);
                 }
                 return $va_sorted_values;
             }
             break;
             # -----------------------------------------------------
         # -----------------------------------------------------
         case 'authority':
             $vs_rel_table_name = $va_facet_info['table'];
             $va_params = $this->opo_ca_browse_cache->getParameters();
             // Make sure we honor type restrictions for the related authority
             $va_user_type_restrictions = caGetTypeRestrictionsForUser($vs_rel_table_name);
             $va_restrict_to_types = $va_facet_info['restrict_to_types'];
             if (is_array($va_user_type_restrictions)) {
                 if (!is_array($va_restrict_to_types)) {
                     $va_restrict_to_types = $va_user_type_restrictions;
                 } else {
                     $va_restrict_to_types = array_intersect($va_restrict_to_types, $va_user_type_restrictions);
                 }
             }
             if (!is_array($va_exclude_types = $va_facet_info['exclude_types'])) {
                 $va_exclude_types = array();
             }
             if (!is_array($va_restrict_to_relationship_types = $va_facet_info['restrict_to_relationship_types'])) {
                 $va_restrict_to_relationship_types = array();
             }
             if (!is_array($va_exclude_relationship_types = $va_facet_info['exclude_relationship_types'])) {
                 $va_exclude_relationship_types = array();
             }
             $t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true);
             if ($vs_browse_table_name == $vs_rel_table_name) {
                 // browsing on self-relations not supported
                 break;
             } else {
                 switch (sizeof($va_path = array_keys($this->opo_datamodel->getPath($vs_browse_table_name, $vs_rel_table_name)))) {
                     case __CA_ATTRIBUTE_VALUE_LIST__:
                         $t_item_rel = $this->opo_datamodel->getInstanceByTableName($va_path[1], true);
                         $t_rel_item = $this->opo_datamodel->getInstanceByTableName($va_path[2], true);
                         $vs_key = 'relation_id';
                         break;
                     case __CA_ATTRIBUTE_VALUE_DATERANGE__:
                         $t_item_rel = null;
                         $t_rel_item = $this->opo_datamodel->getInstanceByTableName($va_path[1], true);
                         $vs_key = $t_rel_item->primaryKey();
                         break;
                     default:
                         // bad related table
                         return null;
                         break;
                 }
             }
             $vb_rel_is_hierarchical = (bool) $t_rel_item->isHierarchical();
             //
             // Convert related item type_code specs in restrict_to_types and exclude_types lists to numeric type_ids we need for the query
             //
             if (!is_array($va_restrict_to_types = $this->_convertTypeCodesToIDs($va_restrict_to_types, array('instance' => $t_rel_item, 'dontExpandHierarchically' => true)))) {
                 $va_restrict_to_types = array();
             }
             if (!is_array($va_exclude_types = $this->_convertTypeCodesToIDs($va_exclude_types, array('instance' => $t_rel_item, 'dontExpandHierarchically' => true)))) {
                 $va_exclude_types = array();
             }
             $va_restrict_to_types_expanded = $this->_convertTypeCodesToIDs($va_restrict_to_types, array('instance' => $t_rel_item));
             $va_exclude_types_expanded = $this->_convertTypeCodesToIDs($va_exclude_types, array('instance' => $t_rel_item));
             // look up relationship type restrictions
             $va_restrict_to_relationship_types = $this->_getRelationshipTypeIDs($va_restrict_to_relationship_types, $va_facet_info['relationship_table']);
             $va_exclude_relationship_types = $this->_getRelationshipTypeIDs($va_exclude_relationship_types, $va_facet_info['relationship_table']);
             $va_joins = array();
             $va_selects = array();
             $va_wheres = array();
             $va_orderbys = array();
             if (!$va_facet_info['show_all_when_first_facet'] || $this->numCriteria() > 0) {
                 $vs_cur_table = array_shift($va_path);
                 foreach ($va_path as $vs_join_table) {
                     $va_rel_info = $this->opo_datamodel->getRelationships($vs_cur_table, $vs_join_table);
                     $va_joins[] = 'INNER JOIN ' . $vs_join_table . ' ON ' . $vs_cur_table . '.' . $va_rel_info[$vs_cur_table][$vs_join_table][0][0] . ' = ' . $vs_join_table . '.' . $va_rel_info[$vs_cur_table][$vs_join_table][0][1] . "\n";
                     $vs_cur_table = $vs_join_table;
                 }
             } else {
                 if ($va_facet_info['show_all_when_first_facet']) {
                     $va_path = array_reverse($va_path);
                     // in "show_all" mode we turn the browse on it's head and grab records by the "subject" table, rather than the browse table
                     $vs_cur_table = array_shift($va_path);
                     $vs_join_table = $va_path[0];
                     $va_rel_info = $this->opo_datamodel->getRelationships($vs_cur_table, $vs_join_table);
                     $va_joins[] = 'LEFT JOIN ' . $vs_join_table . ' ON ' . $vs_cur_table . '.' . $va_rel_info[$vs_cur_table][$vs_join_table][0][0] . ' = ' . $vs_join_table . '.' . $va_rel_info[$vs_cur_table][$vs_join_table][0][1] . "\n";
                 }
             }
             if (sizeof($va_results) && $this->numCriteria() > 0) {
                 $va_wheres[] = "(" . $t_subject->tableName() . '.' . $t_subject->primaryKey() . " IN (" . join(',', $va_results) . "))";
             }
             if (!is_array($va_restrict_to_lists = $va_facet_info['restrict_to_lists'])) {
                 $va_restrict_to_lists = array();
             }
             if (is_array($va_restrict_to_lists) && sizeof($va_restrict_to_lists) > 0 && $t_rel_item->tableName() == 'ca_list_items') {
                 $va_list_ids = array();
                 foreach ($va_restrict_to_lists as $vm_list) {
                     if (is_numeric($vm_list)) {
                         $vn_list_id = (int) $vm_list;
                     } else {
                         $vn_list_id = (int) ca_lists::getListID($vm_list);
                     }
                     if ($vn_list_id) {
                         $va_list_ids[] = $vn_list_id;
                     }
                 }
                 if (sizeof($va_list_ids) > 0) {
                     $va_wheres[] = "{$vs_rel_table_name}.list_id IN (" . join(',', $va_list_ids) . ")";
                 }
             }
             if (is_array($va_restrict_to_types) && sizeof($va_restrict_to_types) > 0 && method_exists($t_rel_item, "getTypeList")) {
                 $va_wheres[] = "{$vs_rel_table_name}.type_id IN (" . join(',', caGetOption('dont_include_subtypes', $va_facet_info, false) ? $va_restrict_to_types : $va_restrict_to_types_expanded) . ")" . ($t_rel_item->getFieldInfo('type_id', 'IS_NULL') ? " OR ({$vs_rel_table_name}.type_id IS NULL)" : '');
                 $va_selects[] = "{$vs_rel_table_name}.type_id";
             }
             if (is_array($va_exclude_types) && sizeof($va_exclude_types) > 0 && method_exists($t_rel_item, "getTypeList")) {
                 $va_wheres[] = "{$vs_rel_table_name}.type_id NOT IN (" . join(',', caGetOption('dont_include_subtypes', $va_facet_info, false) ? $va_exclude_types : $va_exclude_types_expanded) . ")";
             }
             if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_rel_item->hasField('access')) {
                 $va_wheres[] = "(" . $t_rel_item->tableName() . ".access IN (" . join(',', $pa_options['checkAccess']) . "))";
                 // exclude non-accessible authority items
                 if (!$va_facet_info['show_all_when_first_facet'] || $this->numCriteria() > 0) {
                     $va_wheres[] = "(" . $vs_browse_table_name . ".access IN (" . join(',', $pa_options['checkAccess']) . "))";
                     // exclude non-accessible browse items
                 }
             }
             if ($t_item->hasField('deleted') && !$va_facet_info['show_all_when_first_facet']) {
                 $va_wheres[] = "(" . $t_item->tableName() . ".deleted = 0)";
             }
             if ($t_rel_item->hasField('deleted')) {
                 $va_wheres[] = "(" . $t_rel_item->tableName() . ".deleted = 0)";
             }
             $vs_rel_pk = $t_rel_item->primaryKey();
             $va_rel_attr_elements = $t_rel_item->getApplicableElementCodes(null, true, false);
             $va_attrs_to_fetch = array();
             if (!$va_facet_info['show_all_when_first_facet'] || $this->numCriteria() > 0) {
                 //$va_selects[] = $t_item->tableName().'.'.$t_item->primaryKey();			// get primary key of subject
             }
             $va_selects[] = $t_rel_item->tableName() . '.' . $vs_rel_pk;
             // get primary key of related
             $vs_hier_parent_id_fld = $vs_hier_id_fld = null;
             if ($vb_rel_is_hierarchical) {
                 $vs_hier_parent_id_fld = $t_rel_item->getProperty('HIERARCHY_PARENT_ID_FLD');
                 $va_selects[] = $t_rel_item->tableName() . '.' . $vs_hier_parent_id_fld;
                 if ($vs_hier_id_fld = $t_rel_item->getProperty('HIERARCHY_ID_FLD')) {
                     $va_selects[] = $t_rel_item->tableName() . '.' . $vs_hier_id_fld;
                 }
             }
             // analyze group_fields (if defined) and add them to the query
             $va_groupings_to_fetch = array();
             if (isset($va_facet_info['groupings']) && is_array($va_facet_info['groupings']) && sizeof($va_facet_info['groupings'])) {
                 foreach ($va_facet_info['groupings'] as $vs_grouping => $vs_grouping_name) {
                     // is grouping type_id?
                     if ($vs_grouping === 'type' && $t_rel_item->hasField('type_id')) {
                         $va_selects[] = $t_rel_item->tableName() . '.type_id';
                         $va_groupings_to_fetch[] = 'type_id';
                     }
                     // is group field a relationship type?
                     if ($vs_grouping === 'relationship_types') {
                         $va_selects[] = $va_facet_info['relationship_table'] . '.type_id rel_type_id';
                         $va_groupings_to_fetch[] = 'rel_type_id';
                     }
                     // is group field an attribute?
                     if (preg_match('!^ca_attribute_([^:]*)!', $vs_grouping, $va_matches)) {
                         if ($vn_element_id = array_search($va_matches[1], $va_rel_attr_elements)) {
                             $va_attrs_to_fetch[] = $vn_element_id;
                         }
                     }
                 }
             }
             if ($va_facet_info['relative_to']) {
                 // TODO: do this everywhere
                 $va_restrict_to_relationship_types = array();
                 $vs_browse_type_limit_sql = '';
                 if ($t_subject->hasField('deleted')) {
                     $va_wheres[] = "(" . $t_subject->tableName() . ".deleted = 0)";
                 }
                 if ($va_relative_sql_data = $this->_getRelativeFacetSQLData($va_facet_info['relative_to'], $pa_options)) {
                     $va_joins = array_merge($va_joins, $va_relative_sql_data['joins']);
                     $va_wheres = array_merge($va_wheres, $va_relative_sql_data['wheres']);
                 }
             }
             if (sizeof($va_restrict_to_relationship_types) > 0 && is_object($t_item_rel)) {
                 $va_wheres[] = $t_item_rel->tableName() . ".type_id IN (" . join(',', $va_restrict_to_relationship_types) . ")";
             }
             if (sizeof($va_exclude_relationship_types) > 0 && is_object($t_item_rel)) {
                 $va_wheres[] = $t_item_rel->tableName() . ".type_id NOT IN (" . join(',', $va_exclude_relationship_types) . ")";
             }
             if ($vs_browse_type_limit_sql) {
                 $va_wheres[] = $vs_browse_type_limit_sql;
             }
             if ($this->opo_config->get('perform_item_level_access_checking')) {
                 if ($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true)) {
                     // Join to limit what browse table items are used to generate facet
                     $va_joins[] = 'LEFT JOIN ca_acl ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_acl.row_id AND ca_acl.table_num = ' . $t_item->tableNum() . "\n";
                     $va_wheres[] = "(\n\t\t\t\t\t\t\t\t((\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id = " . (int) $vn_user_id . ")\n\t\t\t\t\t\t\t\t\t" . (sizeof($va_group_ids) > 0 ? "OR\n\t\t\t\t\t\t\t\t\t(ca_acl.group_id IN (" . join(",", $va_group_ids) . "))" : "") . "\n\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id IS NULL and ca_acl.group_id IS NULL)\n\t\t\t\t\t\t\t\t) AND ca_acl.access >= " . __CA_ACL_READONLY_ACCESS__ . ")\n\t\t\t\t\t\t\t\t" . ($vb_show_if_no_acl ? "OR ca_acl.acl_id IS NULL" : "") . "\n\t\t\t\t\t\t\t)";
                     // Join to limit what related items are used to generate facet
                     $va_joins[] = 'LEFT JOIN ca_acl AS rel_acl ON ' . $t_rel_item->tableName() . '.' . $t_rel_item->primaryKey() . ' = rel_acl.row_id AND rel_acl.table_num = ' . $t_rel_item->tableNum() . "\n";
                     $va_wheres[] = "(\n\t\t\t\t\t\t\t\t((\n\t\t\t\t\t\t\t\t\t(rel_acl.user_id = " . (int) $vn_user_id . ")\n\t\t\t\t\t\t\t\t\t" . (sizeof($va_group_ids) > 0 ? "OR\n\t\t\t\t\t\t\t\t\t(rel_acl.group_id IN (" . join(",", $va_group_ids) . "))" : "") . "\n\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t(rel_acl.user_id IS NULL and rel_acl.group_id IS NULL)\n\t\t\t\t\t\t\t\t) AND rel_acl.access >= " . __CA_ACL_READONLY_ACCESS__ . ")\n\t\t\t\t\t\t\t\t" . ($vb_show_if_no_acl ? "OR rel_acl.acl_id IS NULL" : "") . "\n\t\t\t\t\t\t\t)";
                 }
             }
             $vs_join_sql = join("\n", $va_joins);
             if ($vb_check_availability_only) {
                 if (!$va_facet_info['show_all_when_first_facet'] || $this->numCriteria() > 0) {
                     $vs_sql = "\n\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\tFROM " . $vs_browse_table_name . "\n\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t" . (sizeof($va_wheres) ? ' WHERE ' : '') . join(" AND ", $va_wheres) . " LIMIT 1";
                 } else {
                     $vs_sql = "\n\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\tFROM " . $t_rel_item->tableName() . "\n\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t" . (sizeof($va_wheres) ? ' WHERE ' : '') . join(" AND ", $va_wheres) . " LIMIT 1";
                 }
                 $qr_res = $this->opo_db->query($vs_sql);
                 //print "<hr>$vs_sql<hr>\n";
                 return (int) $qr_res->numRows() > 0 ? true : false;
             } else {
                 if (!$va_facet_info['show_all_when_first_facet'] || $this->numCriteria() > 0) {
                     $vs_sql = "\n\t\t\t\t\t\t\tSELECT DISTINCT " . join(', ', $va_selects) . "\n\t\t\t\t\t\t\tFROM " . $vs_browse_table_name . "\n\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t" . (sizeof($va_wheres) ? ' WHERE ' : '') . join(" AND ", $va_wheres) . "\n\t\t\t\t\t\t\t\t" . (sizeof($va_orderbys) ? "ORDER BY " . join(', ', $va_orderbys) : '');
                 } else {
                     $vs_sql = "\n\t\t\t\t\t\t\tSELECT DISTINCT " . join(', ', $va_selects) . "\n\t\t\t\t\t\t\tFROM " . $t_rel_item->tableName() . "\n\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t" . (sizeof($va_wheres) ? ' WHERE ' : '') . join(" AND ", $va_wheres) . "\n\t\t\t\t\t\t\t\t" . (sizeof($va_orderbys) ? "ORDER BY " . join(', ', $va_orderbys) : '');
                 }
                 //print "<hr>$vs_sql<hr>\n";
                 $qr_res = $this->opo_db->query($vs_sql);
                 $va_facet = $va_facet_items = array();
                 $vs_rel_pk = $t_rel_item->primaryKey();
                 // First get related ids with type and relationship type values
                 // (You could get all of the data we need for the facet in a single query but it turns out to be faster for very large facets to
                 // do it in separate queries, one for the primary ids and another for the labels; a third is done if attributes need to be fetched.
                 // There appears to be a significant [~10%] performance for smaller facets and a larger one [~20-25%] for very large facets)
                 $vn_max_level = caGetOption('maximum_levels', $va_facet_info, null);
                 while ($qr_res->nextRow()) {
                     $va_fetched_row = $qr_res->getRow();
                     $vn_id = $va_fetched_row[$vs_rel_pk];
                     //if (isset($va_facet_items[$vn_id])) { continue; } --- we can't do this as then we don't detect items that have multiple rel_type_ids... argh.
                     if (isset($va_criteria[$vn_id])) {
                         continue;
                     }
                     // skip items that are used as browse critera - don't want to browse on something you're already browsing on
                     if (!$va_facet_items[$va_fetched_row[$vs_rel_pk]]) {
                         // if(!is_null($vn_max_level)) {
                         // 									if (sizeof($va_ancestors) + 1 > $vn_max_level) {
                         // 										if ($va_tmp = $va_ancestors[sizeof($va_ancestors) - $vn_max_level]) {
                         // 											$va_ancestors = array();
                         // 											$va_fetched_row = $va_tmp['NODE'];
                         // 										}
                         // 									}
                         // 								}
                         if (is_array($va_restrict_to_types) && sizeof($va_restrict_to_types) && $va_fetched_row['type_id'] && !in_array($va_fetched_row['type_id'], $va_restrict_to_types)) {
                             continue;
                         }
                         $va_facet_items[$va_fetched_row[$vs_rel_pk]] = array('id' => $va_fetched_row[$vs_rel_pk], 'type_id' => array(), 'parent_id' => $vb_rel_is_hierarchical ? $va_fetched_row[$vs_hier_parent_id_fld] : null, 'hierarchy_id' => $vb_rel_is_hierarchical ? $va_fetched_row[$vs_hier_id_fld] : null, 'rel_type_id' => array(), 'child_count' => 0);
                         if (!is_null($vs_single_value) && $va_fetched_row[$vs_rel_pk] == $vs_single_value) {
                             $vb_single_value_is_present = true;
                         }
                     }
                     if ($va_fetched_row['type_id']) {
                         $va_facet_items[$va_fetched_row[$vs_rel_pk]]['type_id'][] = $va_fetched_row['type_id'];
                     }
                     if ($va_fetched_row['rel_type_id']) {
                         $va_facet_items[$va_fetched_row[$vs_rel_pk]]['rel_type_id'][] = $va_fetched_row['rel_type_id'];
                     }
                 }
                 if (!isset($va_facet_info['dont_expand_hierarchically']) || !$va_facet_info['dont_expand_hierarchically']) {
                     $qr_res->seek(0);
                     $va_ids = $qr_res->getAllFieldValues($vs_rel_pk);
                     $qr_ancestors = call_user_func($t_rel_item->tableName() . '::getHierarchyAncestorsForIDs', $va_ids, array('returnAs' => 'SearchResult'));
                     $vs_rel_table = $t_rel_item->tableName();
                     $vs_rel_pk = $t_rel_item->primaryKey();
                     $vb_check_ancestor_access = (bool) (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_rel_item->hasField('access'));
                     if ($qr_ancestors) {
                         while ($qr_ancestors->nextHit()) {
                             $vn_parent_type_id = $qr_ancestors->get('type_id');
                             if (sizeof($va_exclude_types) > 0 && in_array($vn_parent_type_id, $va_exclude_types)) {
                                 continue;
                             }
                             if (sizeof($va_restrict_to_types) > 0 && !in_array($vn_parent_type_id, $va_restrict_to_types)) {
                                 continue;
                             }
                             if ($vb_check_ancestor_access && !in_array($qr_ancestors->get('access'), $pa_options['checkAccess'])) {
                                 continue;
                             }
                             $va_facet_items[$vn_ancestor_id = (int) $qr_ancestors->get("{$vs_rel_pk}")] = array('id' => $vn_ancestor_id, 'type_id' => array(), 'parent_id' => $vb_rel_is_hierarchical ? $qr_ancestors->get("{$vs_hier_parent_id_fld}") : null, 'hierarchy_id' => $vb_rel_is_hierarchical && $vs_hier_id_fld ? $qr_ancestors->get($vs_hier_id_fld) : null, 'rel_type_id' => array(), 'child_count' => 0);
                         }
                     }
                 }
                 // Set child counts
                 foreach ($va_facet_items as $vn_i => $va_item) {
                     if ($va_item['parent_id'] && isset($va_facet_items[$va_item['parent_id']])) {
                         $va_facet_items[$va_item['parent_id']]['child_count']++;
                     }
                 }
                 // Get labels for facet items
                 if (sizeof($va_row_ids = array_keys($va_facet_items))) {
                     if ($vs_label_table_name = $t_rel_item->getLabelTableName()) {
                         $t_rel_item_label = $this->opo_datamodel->getInstanceByTableName($vs_label_table_name, true);
                         $vs_label_display_field = $t_rel_item_label->getDisplayField();
                         $vs_rel_pk = $t_rel_item->primaryKey();
                         $va_label_wheres = array();
                         if ($t_rel_item_label->hasField('is_preferred')) {
                             $va_label_wheres[] = "({$vs_label_table_name}.is_preferred = 1)";
                         }
                         $va_label_wheres[] = "({$vs_label_table_name}.{$vs_rel_pk} IN (" . join(",", $va_row_ids) . "))";
                         $va_label_selects[] = "{$vs_label_table_name}.{$vs_rel_pk}";
                         $va_label_selects[] = "{$vs_label_table_name}.locale_id";
                         $va_label_fields = $t_rel_item->getLabelUIFields();
                         foreach ($va_label_fields as $vs_label_field) {
                             $va_label_selects[] = "{$vs_label_table_name}.{$vs_label_field}";
                         }
                         // Get label ordering fields
                         $va_ordering_fields_to_fetch = isset($va_facet_info['order_by_label_fields']) && is_array($va_facet_info['order_by_label_fields']) ? $va_facet_info['order_by_label_fields'] : array();
                         $va_orderbys = array();
                         foreach ($va_ordering_fields_to_fetch as $vs_sort_by_field) {
                             if (!$t_rel_item_label->hasField($vs_sort_by_field)) {
                                 continue;
                             }
                             $va_orderbys[] = $va_label_selects[] = $vs_label_table_name . '.' . $vs_sort_by_field;
                         }
                         // get labels
                         $vs_sql = "\n\t\t\t\t\t\t\t\t\tSELECT " . join(', ', $va_label_selects) . "\n\t\t\t\t\t\t\t\t\tFROM " . $vs_label_table_name . "\n\t\t\t\t\t\t\t\t\t\t" . (sizeof($va_label_wheres) ? ' WHERE ' : '') . join(" AND ", $va_label_wheres) . "\n\t\t\t\t\t\t\t\t\t\t" . (sizeof($va_orderbys) ? "ORDER BY " . join(', ', $va_orderbys) : '') . "";
                         //print $vs_sql;
                         $qr_labels = $this->opo_db->query($vs_sql);
                         while ($qr_labels->nextRow()) {
                             $va_fetched_row = $qr_labels->getRow();
                             $va_facet_item = array_merge($va_facet_items[$va_fetched_row[$vs_rel_pk]], array('label' => $va_fetched_row[$vs_label_display_field]));
                             foreach ($va_ordering_fields_to_fetch as $vs_to_fetch) {
                                 $va_facet_item[$vs_to_fetch] = $va_fetched_row[$vs_to_fetch];
                             }
                             $va_facet[$va_fetched_row[$vs_rel_pk]][$va_fetched_row['locale_id']] = $va_facet_item;
                         }
                     }
                     // get attributes for facet items
                     if (sizeof($va_attrs_to_fetch)) {
                         $qr_attrs = $this->opo_db->query("\n\t\t\t\t\t\t\t\t\tSELECT c_av.*, c_a.locale_id, c_a.row_id\n\t\t\t\t\t\t\t\t\tFROM ca_attributes c_a\n\t\t\t\t\t\t\t\t\tINNER JOIN ca_attribute_values c_av ON c_a.attribute_id = c_av.attribute_id\n\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\tc_av.element_id IN (" . join(',', $va_attrs_to_fetch) . ")\n\t\t\t\t\t\t\t\t\t\tAND\n\t\t\t\t\t\t\t\t\t\tc_a.table_num = ? \n\t\t\t\t\t\t\t\t\t\tAND \n\t\t\t\t\t\t\t\t\t\tc_a.row_id IN (" . join(',', $va_row_ids) . ")\n\t\t\t\t\t\t\t\t", $t_rel_item->tableNum());
                         while ($qr_attrs->nextRow()) {
                             $va_fetched_row = $qr_attrs->getRow();
                             $vn_id = $va_fetched_row['row_id'];
                             // if no locale is set for the attribute default it to whatever the locale for the item is
                             if (!($vn_locale_id = $va_fetched_row['locale_id'])) {
                                 $va_tmp = array_keys($va_facet[$vn_id]);
                                 $vn_locale_id = $va_tmp[0];
                             }
                             $va_facet[$vn_id][$vn_locale_id]['ca_attribute_' . $va_fetched_row['element_id']][] = $va_fetched_row;
                         }
                     }
                 }
                 if (!is_null($vs_single_value) && !$vb_single_value_is_present) {
                     return array();
                 }
                 return caExtractValuesByUserLocale($va_facet);
             }
             break;
             # -----------------------------------------------------
         # -----------------------------------------------------
         default:
             return null;
             break;
             # -----------------------------------------------------
     }
 }
コード例 #20
0
ファイル: BaseModel.php プロジェクト: samrahman/providence
 /**
  * Return list of items specified for the given field.
  *
  * @param string $ps_field The name of the field
  * @param string $ps_list_code Optional list code or list_id to force return of, overriding the list configured in the model
  * @return array A list of items, filtered on the current user locale; the format is the same as that returned by ca_lists::getItemsForList()
  */
 public function getFieldList($ps_field, $ps_list_code = null)
 {
     $t_list = new ca_lists();
     return caExtractValuesByUserLocale($t_list->getItemsForList($ps_list_code ? $ps_list_code : $this->getFieldListCode($ps_field)));
 }
コード例 #21
0
 /**
  * Returns data for annotations attached to current representation
  *
  * @param array $pa_options Optional array of options. Supported options are:
  *			checkAccess = array of access codes to filter count by. Only annotations with an access value set to one of the specified values will be returned
  *			start =
  *			max = 
  *			labelsOnly =
  * @return array List of annotations attached to the current representation, key'ed on annotation_id. Value is an array will all values; annotation labels are returned in the current locale.
  */
 public function getAnnotations($pa_options = null)
 {
     if (!($vn_representation_id = $this->getPrimaryKey())) {
         return null;
     }
     if (!is_array($pa_options)) {
         $pa_options = array();
     }
     if (!($o_coder = $this->getAnnotationPropertyCoderInstance($this->getAnnotationType()))) {
         // does not support annotations
         return null;
     }
     $o_db = $this->getDb();
     $vs_access_sql = '';
     if (is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess'])) {
         $vs_access_sql = ' AND cra.access IN (' . join(',', $pa_options['checkAccess']) . ')';
     }
     $qr_annotations = $o_db->query("\n \t\t\tSELECT \tcra.annotation_id, cra.locale_id, cra.props, cra.representation_id, cra.user_id, cra.type_code, cra.access, cra.status\n \t\t\tFROM ca_representation_annotations cra\n \t\t\tWHERE\n \t\t\t\tcra.representation_id = ? {$vs_access_sql}\n \t\t", (int) $vn_representation_id);
     $vs_sort_by_property = $this->getAnnotationSortProperty();
     $va_annotations = array();
     $vn_start = caGetOption('start', $pa_options, 0, array('castTo' => 'int'));
     $vn_max = caGetOption('max', $pa_options, 100, array('castTo' => 'int'));
     while ($qr_annotations->nextRow()) {
         $va_tmp = $qr_annotations->getRow();
         unset($va_tmp['props']);
         $o_coder->setPropertyValues($qr_annotations->getVars('props'));
         foreach ($o_coder->getPropertyList() as $vs_property) {
             $va_tmp[$vs_property] = $o_coder->getProperty($vs_property);
             $va_tmp[$vs_property . '_raw'] = $o_coder->getProperty($vs_property, true);
             if ($va_tmp[$vs_property] == $va_tmp[$vs_property . '_raw']) {
                 unset($va_tmp[$vs_property . '_raw']);
             }
         }
         if (!($vs_sort_key = $va_tmp[$vs_sort_by_property])) {
             $vs_sort_key = '_default_';
         }
         $va_annotations[$vs_sort_key][$qr_annotations->get('annotation_id')] = $va_tmp;
     }
     ksort($va_annotations, SORT_NUMERIC);
     // get annotation labels
     $qr_annotation_labels = $o_db->query("\n \t\t\tSELECT \tcral.annotation_id, cral.locale_id, cral.name, cral.label_id\n \t\t\tFROM ca_representation_annotation_labels cral\n \t\t\tINNER JOIN ca_representation_annotations AS cra ON cra.annotation_id = cral.annotation_id\n \t\t\tWHERE\n \t\t\t\tcra.representation_id = ? AND cral.is_preferred = 1\n \t\t", (int) $vn_representation_id);
     $va_labels = array();
     while ($qr_annotation_labels->nextRow()) {
         $va_labels[$qr_annotation_labels->get('annotation_id')][$qr_annotation_labels->get('locale_id')][] = $qr_annotation_labels->get('name');
     }
     $va_labels_for_locale = caExtractValuesByUserLocale($va_labels);
     $va_sorted_annotations = array();
     foreach ($va_annotations as $vs_key => $va_values) {
         foreach ($va_values as $va_val) {
             $vs_label = is_array($va_labels_for_locale[$va_val['annotation_id']]) ? array_shift($va_labels_for_locale[$va_val['annotation_id']]) : '';
             $va_val['labels'] = $va_labels[$va_val['annotation_id']] ? $va_labels[$va_val['annotation_id']] : array();
             $va_val['label'] = $vs_label;
             $va_sorted_annotations[$va_val['annotation_id']] = $va_val;
         }
     }
     if ($vn_start > 0 || $vn_max > 0) {
         if ($vn_max > 0) {
             $va_sorted_annotations = array_slice($va_sorted_annotations, $vn_start, $vn_max);
         } else {
             $va_sorted_annotations = array_slice($va_sorted_annotations, $vn_start);
         }
     }
     return $va_sorted_annotations;
 }
コード例 #22
0
 public function getSetItemRep()
 {
     $pn_set_id = $this->request->getParameter('set_id', pInteger);
     $t_set = new ca_sets($pn_set_id);
     $t_set->load($pn_set_id);
     $va_set_items = caExtractValuesByUserLocale($t_set->getItems(array("thumbnailVersions" => array("icon"), "checkAccess" => $this->opa_access_values)));
     $this->view->setVar("set_id", $pn_set_id);
     $pn_item_id = $this->request->getParameter('item_id', pInteger);
     $t_rep = new ca_object_representations($va_set_items[$pn_item_id]["representation_id"]);
     $va_rep_info = $t_rep->getMediaInfo("media", "mediumlarge");
     $this->view->setVar("rep", $t_rep->getMediaTag("media", "mediumlarge"));
     $this->view->setVar("repToolBar", caRepToolbar($this->request, $t_rep, $va_set_items[$pn_item_id]["row_id"]));
     $this->view->setVar("representation_id", $va_set_items[$pn_item_id]["representation_id"]);
     $this->view->setVar("object_id", $va_set_items[$pn_item_id]["row_id"]);
     $pn_previous_id = 0;
     $pn_next_id = 0;
     $va_set_item_ids = array_keys($va_set_items);
     $vn_current_index = array_search($pn_item_id, $va_set_item_ids);
     if ($va_set_item_ids[$vn_current_index - 1]) {
         $pn_previous_id = $va_set_item_ids[$vn_current_index - 1];
     }
     if ($va_set_item_ids[$vn_current_index + 1]) {
         $pn_next_id = $va_set_item_ids[$vn_current_index + 1];
     }
     $this->view->setVar("next_item_id", $pn_next_id);
     $this->view->setVar("previous_item_id", $pn_previous_id);
     $this->render("Gallery/set_item_rep_html.php");
 }
コード例 #23
0
ファイル: ca_tours.php プロジェクト: samrahman/providence
 /**
  * Returns list of stops for a given tour. 
  */
 public function getStops($po_request = null, $pa_options = null)
 {
     if (!$this->getPrimaryKey()) {
         return false;
     }
     if (ca_tours::$s_stop_info_cache[$this->getPrimaryKey()]) {
         return ca_tours::$s_stop_info_cache[$this->getPrimaryKey()];
     }
     $o_db = $this->getDb();
     $va_bundles_to_return = isset($pa_options['bundles']) && is_array($pa_options['bundles']) ? $pa_options['bundles'] : array();
     $qr_res = $o_db->query("\n\t\t\tSELECT ts.*, tsl.*\n\t\t\tFROM ca_tour_stops ts\n\t\t\tINNER JOIN ca_tour_stop_labels AS tsl ON ts.stop_id = tsl.stop_id\n\t\t\tWHERE\n\t\t\t\t(ts.tour_id = ?) AND (ts.deleted = 0)\n\t\t\tORDER BY \n\t\t\t\tts.rank, ts.stop_id\n\t\t", (int) $this->getPrimaryKey());
     $va_stops = array();
     $t_list = new ca_lists();
     $t_stop = new ca_tour_stops();
     if (is_array($va_bundles_to_return)) {
         foreach ($va_bundles_to_return as $vs_k => $vs_v) {
             $va_tmp = explode(".", $vs_v);
             $vs_tmp = array_pop($va_tmp);
             unset($va_bundles_to_return[$vs_k]);
             $va_bundles_to_return[$vs_tmp] = $vs_v;
         }
     }
     $va_bundles_to_return += array("stop_id" => "ca_tour_stops.stop_id", "tour_id" => "ca_tour_stops.tour_id", "idno" => "ca_tour_stops.idno", "name" => "ca_tour_stops.preferred_labels.name", "locale_id" => "ca_tour_stops.preferred_labels.locale_id", "parent_id" => "ca_tour_stops.parent_id");
     $va_stop_ids = $qr_res->getAllFieldValues("stop_id");
     if (is_array($va_stop_ids) && sizeof($va_stop_ids) > 0) {
         $qr_stops = $t_stop->makeSearchResult("ca_tour_stops", $va_stop_ids);
         while ($qr_stops->nextHit()) {
             if (!$va_stops[$vn_stop_id = $qr_stops->get('stop_id')][$vn_screen_locale_id = $qr_stops->get('locale_id')]) {
                 //$va_tmp =  $qr_res->getRow();
                 //$va_tmp['typename'] = $t_list->getItemForDisplayByItemID($va_tmp['type_id'], false);
                 if ($va_bundles_to_return) {
                     foreach ($va_bundles_to_return as $vs_fld_name => $vs_bundle) {
                         $va_tmp[$vs_fld_name] = $qr_stops->get($vs_bundle, array('convertValueToDisplayText' => true));
                     }
                 }
                 $va_stops[$vn_stop_id][$vn_screen_locale_id] = $va_tmp;
             }
         }
     } else {
         $va_stops = array();
     }
     return ca_tours::$s_stop_info_cache[$this->getPrimaryKey()] = caExtractValuesByUserLocale($va_stops);
 }
コード例 #24
0
ファイル: ShowController.php プロジェクト: guaykuru/pawtucket
 public function displaySet()
 {
     # --- set info
     $pn_set_id = $this->request->getParameter('set_id', pInteger);
     $t_set = new ca_sets($pn_set_id);
     $va_access_values = caGetUserAccessValues($this->request);
     # Enforce access control
     if (sizeof($va_access_values) && !in_array($t_set->get("access"), $va_access_values)) {
         $this->notification->addNotification(_t("This set is not available for view"), "message");
         $this->response->setRedirect(caNavUrl($this->request, "", "", "", ""));
         return;
     }
     $this->view->setVar('t_set', $t_set);
     $va_items = caExtractValuesByUserLocale($t_set->getItems(array('thumbnailVersions' => array('widepreview', 'medium', 'setimage'), "checkAccess" => $va_access_values)));
     $this->view->setVar('items', $va_items);
     $va_row_ids = array();
     foreach ($va_items as $vn_item_id => $va_item_info) {
         $va_row_ids[] = $va_item_info['row_id'];
     }
     # --- all featured sets - for display in right hand column
     // get sets for public display
     $t_list = new ca_lists();
     $vn_public_set_type_id = $t_list->getItemIDFromList('set_types', $t_list->getAppConfig()->get('simpleGallery_set_type'));
     $t_set = new ca_sets($pn_set_id);
     $va_sets = caExtractValuesByUserLocale($t_set->getSets(array('table' => 'ca_objects', 'checkAccess' => $va_access_values, 'setType' => $vn_public_set_type_id)));
     $va_set_first_items = array();
     $va_set_first_items = $t_set->getFirstItemsFromSets(array_keys($va_sets), array("version" => "icon", "checkAccess" => $va_access_values));
     $this->view->setVar('sets', $va_sets);
     $this->view->setVar('first_items_from_sets', $va_set_first_items);
     $this->view->setVar('set_title', $t_set->getLabelForDisplay());
     $this->view->setVar('set_description', $t_set->get($this->opo_plugin_config->get('set_description_element_code'), array('convertLinkBreaks' => true)));
     // Needed to figure out what result context to use on details
     $this->opo_result_context->setParameter('set_id', $pn_set_id);
     $this->opo_result_context->setResultList($va_row_ids);
     $this->opo_result_context->setAsLastFind();
     $this->opo_result_context->saveContext();
     $this->render($this->ops_theme . '/set_info_html.php');
 }
コード例 #25
0
ファイル: ItemService.php プロジェクト: guaykuru/pawtucket
 /**
  * Get a record summary that is easier to parse when importing to another system
  */
 private function getItemInfoForImport()
 {
     if (!($t_instance = $this->_getTableInstance($this->ops_table, $this->opn_id))) {
         return false;
     }
     $o_dm = Datamodel::load();
     $t_list = new ca_lists();
     $t_locales = new ca_locales();
     //
     // Options
     //
     if (!($vs_delimiter = $this->opo_request->getParameter('delimiter', pString))) {
         $vs_delimiter = "; ";
     }
     if (!($vs_flatten = $this->opo_request->getParameter('flatten', pString))) {
         $vs_flatten = null;
     }
     $va_flatten = preg_split("![ ]*[;]+[ ]*!", $vs_flatten);
     $va_flatten = array_flip($va_flatten);
     $va_locales = $t_locales->getLocaleList(array("available_for_cataloguing_only" => true));
     $va_return = array();
     // allow user-defined template to be passed; allows flexible formatting of returned "display" value
     if (!($vs_template = $this->opo_request->getParameter('template', pString))) {
         $vs_template = '';
     }
     if ($vs_template) {
         $va_return['display'] = caProcessTemplateForIDs($vs_template, $this->ops_table, array($this->opn_id));
     }
     // "intrinsic" fields
     foreach ($t_instance->getFieldsArray() as $vs_field_name => $va_field_info) {
         $vs_list = null;
         if (!is_null($vs_val = $t_instance->get($vs_field_name))) {
             if (preg_match("/^hier\\_/", $vs_field_name)) {
                 continue;
             }
             if (preg_match("/\\_sort\$/", $vs_field_name)) {
                 continue;
             }
             if ($vs_field_name == $t_instance->primaryKey()) {
                 continue;
             }
             if (isset($va_field_info["LIST_CODE"])) {
                 // typical example: type_id
                 $va_item = $t_list->getItemFromListByItemID($va_field_info["LIST_CODE"], $vs_val);
                 if ($t_item = new ca_list_items($va_item["item_id"])) {
                     $vs_val = $t_item->get('idno');
                 }
             }
             $va_return['intrinsic'][$vs_field_name] = $vs_val;
         }
     }
     // preferred labels
     $va_labels = $t_instance->get($this->ops_table . ".preferred_labels", array("returnAllLocales" => true));
     $va_labels = end($va_labels);
     $vs_display_field_name = $t_instance->getLabelDisplayField();
     if (is_array($va_labels)) {
         foreach ($va_labels as $vn_locale_id => $va_labels_by_locale) {
             foreach ($va_labels_by_locale as $va_tmp) {
                 $va_label = array();
                 $va_label['locale'] = $va_locales[$vn_locale_id]["code"];
                 // add only UI fields to return
                 foreach (array_merge($t_instance->getLabelUIFields(), array('type_id')) as $vs_label_fld) {
                     $va_label[$vs_label_fld] = $va_tmp[$vs_label_fld];
                 }
                 $va_label[$vs_label_fld] = $va_tmp[$vs_label_fld];
                 $va_label['label'] = $va_tmp[$vs_display_field_name];
                 $va_return["preferred_labels"][$va_label['locale']] = $va_label;
             }
         }
         if (isset($va_flatten['locales'])) {
             $va_return["preferred_labels"] = array_pop(caExtractValuesByUserLocale(array($va_return["preferred_labels"])));
         }
     }
     // nonpreferred labels
     $va_labels = $t_instance->get($this->ops_table . ".nonpreferred_labels", array("returnAllLocales" => true));
     $va_labels = end($va_labels);
     if (is_array($va_labels)) {
         foreach ($va_labels as $vn_locale_id => $va_labels_by_locale) {
             foreach ($va_labels_by_locale as $va_tmp) {
                 $va_label = array();
                 $va_label['locale'] = $va_locales[$vn_locale_id]["code"];
                 // add only UI fields to return
                 foreach (array_merge($t_instance->getLabelUIFields(), array('type_id')) as $vs_label_fld) {
                     $va_label[$vs_label_fld] = $va_tmp[$vs_label_fld];
                 }
                 $va_return["nonpreferred_labels"][$va_label['locale']] = $va_label;
             }
         }
         if (isset($va_flatten['locales'])) {
             $va_return["nonpreferred_labels"] = array_pop(caExtractValuesByUserLocale(array($va_return["nonpreferred_labels"])));
         }
     }
     // attributes
     $va_codes = $t_instance->getApplicableElementCodes();
     foreach ($va_codes as $vs_code) {
         if ($va_vals = $t_instance->get($this->ops_table . "." . $vs_code, array("convertCodesToDisplayText" => false, "returnAllLocales" => true))) {
             $va_vals_as_text = end($t_instance->get($this->ops_table . "." . $vs_code, array("convertCodesToDisplayText" => true, "returnAllLocales" => true)));
             $va_vals_by_locale = end($va_vals);
             foreach ($va_vals_by_locale as $vn_locale_id => $va_locale_vals) {
                 foreach ($va_locale_vals as $vs_val_id => $va_actual_data) {
                     if (!is_array($va_actual_data)) {
                         continue;
                     }
                     $vs_locale_code = isset($va_locales[$vn_locale_id]["code"]) ? $va_locales[$vn_locale_id]["code"] : "none";
                     foreach ($va_actual_data as $vs_f => $vs_v) {
                         if (isset($va_vals_as_text[$vn_locale_id][$vs_val_id][$vs_f]) && $vs_v != $va_vals_as_text[$vn_locale_id][$vs_val_id][$vs_f]) {
                             $va_actual_data[$vs_f . '_display'] = $va_vals_as_text[$vn_locale_id][$vs_val_id][$vs_f];
                             if ($vs_item_idno = caGetListItemIdno($va_actual_data[$vs_f])) {
                                 $va_actual_data[$vs_f] = $vs_item_idno;
                             }
                         }
                     }
                     $va_return['attributes'][$vs_code][$vs_locale_code][] = array_merge(array('locale' => $vs_locale_code), $va_actual_data);
                 }
             }
         }
     }
     if (isset($va_flatten['locales'])) {
         $va_return['attributes'] = caExtractValuesByUserLocale($va_return['attributes']);
     }
     // relationships
     // yes, not all combinations between these tables have
     // relationships but it also doesn't hurt to query
     foreach ($this->opa_valid_tables as $vs_rel_table) {
         $t_rel = $o_dm->getInstanceByTableName($vs_rel_table, true);
         //
         // set-related hacks
         if ($this->ops_table == "ca_sets" && $vs_rel_table == "ca_tours") {
             // throw SQL error in getRelatedItems
             continue;
         }
         $va_related_items = $t_instance->get($vs_rel_table, array("returnAsArray" => true, 'returnLocaleCodes' => true, 'groupFields' => true));
         if ($this->ops_table == "ca_objects" && $vs_rel_table == "ca_object_representations") {
             $va_versions = $t_instance->getMediaVersions('media');
             if (isset($va_flatten['all'])) {
                 $va_reps = $t_instance->getRepresentations(array('original'));
                 $va_urls = array();
                 foreach ($va_reps as $vn_i => $va_rep) {
                     $va_urls[] = $va_rep['urls']['original'];
                 }
                 $va_return['representations'] = join($vs_delimiter, $va_urls);
             } else {
                 $va_return['representations'] = $t_instance->getRepresentations($va_versions);
             }
             foreach ($va_return['representations'] as $vn_i => $va_rep) {
                 unset($va_return['representations'][$vn_i]['media']);
                 unset($va_return['representations'][$vn_i]['media_metadata']);
             }
         }
         if (is_array($va_related_items) && sizeof($va_related_items) > 0) {
             foreach ($va_related_items as $va_rel_item) {
                 $va_item_add = array();
                 foreach ($va_rel_item as $vs_fld => $vs_val) {
                     if (!is_array($vs_val) && strlen(trim($vs_val)) > 0) {
                         // rewrite and ignore certain field names
                         switch ($vs_fld) {
                             case 'item_type_id':
                                 $va_item_add[$vs_fld] = $vs_val;
                                 $va_item_add['type_id'] = $vs_val;
                                 break;
                             default:
                                 $va_item_add[$vs_fld] = $vs_val;
                                 break;
                         }
                     } else {
                         if (in_array($vs_fld, array('preferred_labels', 'intrinsic'))) {
                             $va_item_add[$vs_fld] = $vs_val;
                         }
                     }
                 }
                 if ($vs_rel_table == "ca_object_representations") {
                     $t_rep = new ca_object_representations($va_rel_item['representation_id']);
                     $va_item_add['media'] = $t_rep->getMediaUrl('media', 'original');
                 }
                 $va_return["related"][$vs_rel_table][] = $va_item_add;
             }
         }
     }
     return $va_return;
 }
コード例 #26
0
 /**
  *
  *
  */
 protected function GetHierarchyLevelData($pa_ids)
 {
     $vo_dm = Datamodel::load();
     $o_config = Configuration::load();
     $t_object = new ca_objects();
     $va_level_data = array();
     foreach ($pa_ids as $pn_id) {
         $va_params = $this->getItemIDComponents($pn_id);
         $vs_table = $va_params['table'];
         $vn_id = $va_params['id'];
         $vn_start = $va_params['start'];
         $vn_item_count = 0;
         $t_item = $vo_dm->getInstanceByTableName($vs_table, true);
         $vs_label_table_name = $t_item->getLabelTableName();
         $vs_label_display_field_name = $t_item->getLabelDisplayField();
         $vs_pk = $t_item->primaryKey();
         if ($vn_start < 0) {
             $vn_start = 0;
         }
         $va_items_for_locale = array();
         if (!$vn_id && method_exists($t_item, "getHierarchyList")) {
             $vn_id = $this->request->getParameter('root_item_id', pString);
             $va_params = $this->getItemIDComponents($vn_id);
             $vs_table = $va_params['table'];
             $vn_id = $va_params['id'];
             $vn_start = $va_params['start'];
             $t_item = $vo_dm->getInstanceByTableName($vs_table, true);
             $vs_label_table_name = $t_item->getLabelTableName();
             $vs_label_display_field_name = $t_item->getLabelDisplayField();
             $vs_pk = $t_item->primaryKey();
             $t_item->load($vn_id);
             $va_tmp = array($vs_pk => $vn_id = $t_item->get($vs_table . '.' . $vs_pk), 'item_id' => $vs_table . '-' . $vn_id, 'parent_id' => $t_item->get($vs_table . '.parent_id'), 'idno' => $t_item->get($vs_table . '.idno'), $vs_label_display_field_name => $t_item->get($vs_table . '.preferred_labels.' . $vs_label_display_field_name), 'locale_id' => $t_item->get($vs_table . '.' . 'locale_id'));
             if (!$va_tmp[$vs_label_display_field_name]) {
                 $va_tmp[$vs_label_display_field_name] = $va_tmp['idno'];
             }
             if (!$va_tmp[$vs_label_display_field_name]) {
                 $va_tmp[$vs_label_display_field_name] = '???';
             }
             if (!($vs_item_template = trim($o_config->get("{$vs_table}_hierarchy_browser_display_settings")))) {
                 $vs_item_template = "^{$vs_table}.preferred_labels.{$vs_label_display_field_name}";
             }
             $va_tmp['name'] = caProcessTemplateForIDs($vs_item_template, $vs_table, array($va_tmp[$vs_pk]));
             // Child count is only valid if has_children is not null
             $va_tmp['children'] = $t_item->get('has_children') ? (int) $t_item->get('child_count') : 1;
             // TODO: fix
             $va_items[$va_tmp[$vs_pk]][$va_tmp['locale_id']] = $va_tmp;
             $va_items_for_locale = caExtractValuesByUserLocale($va_items);
         } else {
             if ($t_item->load($vn_id)) {
                 // id is the id of the parent for the level we're going to return
                 $va_additional_wheres = array();
                 $t_label_instance = $t_item->getLabelTableInstance();
                 if ($t_label_instance && $t_label_instance->hasField('is_preferred')) {
                     $va_additional_wheres[] = "(({$vs_label_table_name}.is_preferred = 1) OR ({$vs_label_table_name}.is_preferred IS NULL))";
                 }
                 if (!is_array($va_sorts = $o_config->getList($vs_table . '_hierarchy_browser_sort_values')) || !sizeof($va_sorts)) {
                     $va_sorts = null;
                 }
                 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($vs_table . '_hierarchy_browser_sort_direction')), array('asc', 'desc'))) {
                     $vs_sort_dir = 'asc';
                 }
                 $qr_children = $t_item->getHierarchyChildrenAsQuery($t_item->getPrimaryKey(), array('additionalTableToJoin' => $vs_label_table_name, 'additionalTableJoinType' => 'LEFT', 'additionalTableSelectFields' => array($vs_label_display_field_name, 'locale_id'), 'additionalTableWheres' => $va_additional_wheres, 'returnChildCounts' => true, 'sort' => $va_sorts, 'sortDirection' => $vs_sort_dir));
                 $va_items = array();
                 if (!($vs_item_template = trim($o_config->get("{$vs_table}_hierarchy_browser_display_settings")))) {
                     $vs_item_template = "^{$vs_table}.preferred_labels.{$vs_label_display_field_name}";
                 }
                 $va_child_counts = 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;
                 }
                 $vn_c = 0;
                 $vn_item_count = $qr_children->numRows();
                 $qr_children->seek($vn_start);
                 while ($qr_children->nextRow()) {
                     $va_tmp = array($vs_pk => $vn_id = $qr_children->get($vs_table . '.' . $vs_pk), 'item_id' => $vs_table . '-' . $vn_id, 'parent_id' => $qr_children->get($vs_table . '.parent_id'), 'idno' => $qr_children->get($vs_table . '.idno'), 'locale_id' => $qr_children->get($vs_table . '.' . 'locale_id'));
                     if (!$va_tmp[$vs_label_display_field_name]) {
                         $va_tmp[$vs_label_display_field_name] = $va_tmp['idno'];
                     }
                     if (!$va_tmp[$vs_label_display_field_name]) {
                         $va_tmp[$vs_label_display_field_name] = '???';
                     }
                     $va_tmp['name'] = caProcessTemplateForIDs($vs_item_template, $vs_table, array($va_tmp[$vs_pk]));
                     // Child count is only valid if has_children is not null
                     $va_tmp['children'] = $qr_children->get('has_children') ? (int) $qr_children->get('child_count') : 0;
                     if (is_array($va_sorts)) {
                         $vs_sort_acc = array();
                         foreach ($va_sorts as $vs_sort) {
                             $vs_sort_acc[] = $qr_children->get($vs_sort);
                         }
                         $va_tmp['sort'] = join(";", $vs_sort_acc);
                     }
                     $va_items[$va_tmp['item_id']][$va_tmp['locale_id']] = $va_tmp;
                     $vn_c++;
                     if (!is_null($vn_max_items_per_page) && $vn_c >= $vn_max_items_per_page) {
                         break;
                     }
                 }
                 if ($t_item->tableName() == 'ca_collections') {
                     $va_cross_table_items = $t_item->getRelatedItems('ca_objects');
                     $vn_item_count += sizeof($va_cross_table_items);
                     $va_ids = array();
                     foreach ($va_cross_table_items as $vn_x_item_id => $va_x_item) {
                         $va_items['ca_objects-' . $vn_x_item_id][$va_x_item['locale_id']] = $va_x_item;
                         //$va_x_item_extracted = caExtractValuesByUserLocale(array(0 => $va_x_item['labels']));
                         //$va_items[$va_x_item['object_id']][$va_x_item['locale_id']]['name'] = $va_x_item_extracted[0];
                         $va_items['ca_objects-' . $va_x_item['object_id']][$va_x_item['locale_id']]['item_id'] = 'ca_objects-' . $va_x_item['object_id'];
                         $va_items['ca_objects-' . $va_x_item['object_id']][$va_x_item['locale_id']]['parent_id'] = $vn_id;
                         unset($va_items['ca_objects-' . $vn_x_item_id][$va_x_item['locale_id']]['labels']);
                         $va_items['ca_objects-' . $va_x_item['object_id']][$va_x_item['locale_id']]['children'] = 0;
                         $va_ids[] = $va_x_item['object_id'];
                     }
                     if (!($vs_item_template = trim($o_config->get("ca_objects_hierarchy_browser_display_settings")))) {
                         $vs_item_template = "^ca_objects.preferred_labels.name";
                     }
                     if (sizeof($va_ids)) {
                         $va_child_counts = $t_object->getHierarchyChildCountsForIDs($va_ids);
                         $va_templates = caProcessTemplateForIDs($vs_item_template, 'ca_objects', $va_ids, array('returnAsArray' => true));
                         foreach ($va_child_counts as $vn_id => $vn_c) {
                             $va_items['ca_objects-' . $vn_id][$va_x_item['locale_id']]['children'] = $vn_c;
                         }
                         foreach ($va_ids as $vn_i => $vn_id) {
                             $va_items['ca_objects-' . $vn_id][$va_x_item['locale_id']]['name'] = $va_templates[$vn_i];
                         }
                     }
                 }
                 $va_items_for_locale = caExtractValuesByUserLocale($va_items);
                 $vs_rank_fld = $t_item->getProperty('RANK');
                 $va_sorted_items = array();
                 foreach ($va_items_for_locale as $vn_id => $va_node) {
                     $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_items_for_locale = array();
                 foreach ($va_sorted_items as $vs_k => $va_v) {
                     ksort($va_v);
                     if ($vs_sort_dir == 'desc') {
                         $va_v = array_reverse($va_v);
                     }
                     $va_items_for_locale = array_merge($va_items_for_locale, $va_v);
                 }
             }
         }
         $va_items_for_locale['_sortOrder'] = array_keys($va_items_for_locale);
         $va_items_for_locale['_primaryKey'] = $t_item->primaryKey();
         // pass the name of the primary key so the hierbrowser knows where to look for item_id's
         $va_items_for_locale['_itemCount'] = $vn_item_count;
         //$qr_children ? $qr_children->numRows() : 0;
         $va_level_data[$pn_id] = $va_items_for_locale;
     }
     return $va_level_data;
 }
コード例 #27
0
ファイル: pageHeader.php プロジェクト: guaykuru/pawtucket
 $o_client_services_config = caGetClientServicesConfiguration();
 if ($vb_client_services && (bool) $o_client_services_config->get('enable_user_communication')) {
     //
     // Unread client communications
     //
     $t_comm = new ca_commerce_communications();
     $va_unread_messages = $t_comm->getMessages(array('unreadOnly' => true, 'user_id' => $this->request->getUserID()));
     $va_message_set_ids = array();
     foreach ($va_unread_messages as $vn_transaction_id => $va_messages) {
         $va_message_set_ids[] = $va_messages[0]['set_id'];
     }
 }
 if (!$this->request->config->get('disable_my_collections')) {
     # --- get all sets for user
     $t_set = new ca_sets();
     $va_sets = caExtractValuesByUserLocale($t_set->getSets(array('table' => 'ca_objects', 'user_id' => $this->request->getUserID())));
     if (is_array($va_sets) && sizeof($va_sets) > 1) {
         print "<div id='lightboxLink'>\n\t\t\t\t\t\t\t\t\t\t<a href='#' onclick='\$(\"#lightboxList\").toggle(0, function(){\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif(\$(\"#lightboxLink\").hasClass(\"lightboxLinkActive\")) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\$(\"#lightboxLink\").removeClass(\"lightboxLinkActive\");\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\$(\"#lightboxLink\").addClass(\"lightboxLinkActive\");\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t});')>Lightbox</a>";
         if (is_array($va_message_set_ids) && sizeof($va_message_set_ids)) {
             print " <img src='" . $this->request->getThemeUrlPath() . "/graphics/icons/envelope.gif' border='0'>";
         }
         print "<div id='lightboxList'><b>" . _t("your lightboxes") . ":</b><br/>";
         foreach ($va_sets as $va_set) {
             print caNavLink($this->request, strlen($va_set["name"]) > 30 ? substr($va_set["name"], 0, 30) . "..." : $va_set["name"], "", "", "Sets", "Index", array("set_id" => $va_set["set_id"]));
             if ($vb_client_services && is_array($va_message_set_ids) && in_array($va_set["set_id"], $va_message_set_ids)) {
                 print " <img src='" . $this->request->getThemeUrlPath() . "/graphics/icons/envelope.gif' border='0'>";
             }
             print "<br/>";
         }
         print "</div>";
         print "</div>";
 /**
  * Prepopulate record fields according to rules in prepopulate.conf
  *
  * @param array $pa_options Options array. Available options are:
  * 		prepopulateConfig = override path to prepopulate.conf, e.g. for testing purposes
  * @return bool success or not
  */
 public function prepopulateFields($pa_options = null)
 {
     if (!$this->getPrimaryKey()) {
         return false;
     }
     if (!($vs_prepopulate_cfg = caGetOption('prepopulateConfig', $pa_options, null))) {
         $vs_prepopulate_cfg = $this->getAppConfig()->get('prepopulate_config');
     }
     $o_prepopulate_conf = Configuration::load($vs_prepopulate_cfg);
     if (!($o_prepopulate_conf->get('prepopulate_fields_on_save') || $o_prepopulate_conf->get('prepopulate_fields_on_load'))) {
         return false;
     }
     $va_rules = $o_prepopulate_conf->get('prepopulate_rules');
     if (!$va_rules || !is_array($va_rules) || sizeof($va_rules) < 1) {
         return false;
     }
     global $g_ui_locale_id;
     // we need to unset the form timestamp to disable the 'Changes have been made since you loaded this data' warning when we update() $this
     // the warning makes sense because an update()/insert() is called before we arrive here but after the form_timestamp ... but we chose to ignore it
     $vn_timestamp = $_REQUEST['form_timestamp'];
     unset($_REQUEST['form_timestamp']);
     $vb_we_set_transaction = true;
     if (!$this->inTransaction()) {
         $this->setTransaction(new Transaction($this->getDb()));
         $vb_we_set_transaction = true;
     }
     // process rules
     $va_expression_vars = array();
     // we only process those if and when we need them
     foreach ($va_rules as $vs_rule_key => $va_rule) {
         if ($this->tableName() != $va_rule['table']) {
             continue;
         }
         // check target
         $vs_target = $va_rule['target'];
         if (strlen($vs_target) < 1) {
             Debug::msg("[prepopulateFields()] skipping rule {$vs_rule_key} because target is not set");
             continue;
         }
         // check template
         $vs_template = $va_rule['template'];
         if (strlen($vs_template) < 1) {
             Debug::msg("[prepopulateFields()] skipping rule {$vs_rule_key} because template is not set");
             continue;
         }
         $vs_mode = caGetOption('mode', $va_rule, 'merge');
         // respect restrictToTypes option
         if ($va_rule['restrictToTypes'] && is_array($va_rule['restrictToTypes']) && sizeof($va_rule['restrictToTypes']) > 0) {
             if (!in_array($this->getTypeCode(), $va_rule['restrictToTypes'])) {
                 Debug::msg("[prepopulateFields()] skipping rule {$vs_rule_key} because current record type " . $this->getTypeCode() . " is not in restrictToTypes");
                 continue;
             }
         }
         // skip this rule if expression is true
         if ($va_rule['skipIfExpression'] && strlen($va_rule['skipIfExpression']) > 0) {
             $va_tags = caGetTemplateTags($va_rule['skipIfExpression']);
             foreach ($va_tags as $vs_tag) {
                 if (!isset($va_expression_vars[$vs_tag])) {
                     $va_expression_vars[$vs_tag] = $this->get($vs_tag, array('returnIdno' => true, 'delimiter' => ';'));
                 }
             }
             if (ExpressionParser::evaluate($va_rule['skipIfExpression'], $va_expression_vars)) {
                 Debug::msg("[prepopulateFields()] skipping rule {$vs_rule_key} because skipIfExpression evaluated true");
                 continue;
             }
         }
         // evaluate template
         $vs_value = caProcessTemplateForIDs($vs_template, $this->tableNum(), array($this->getPrimaryKey()), array('path' => true));
         Debug::msg("[prepopulateFields()] processed template for rule {$vs_rule_key} value is: " . $vs_value);
         // inject into target
         $va_parts = explode('.', $vs_target);
         // intrinsic or simple (non-container) attribute
         if (sizeof($va_parts) == 2) {
             // intrinsic
             if ($this->hasField($va_parts[1])) {
                 switch (strtolower($vs_mode)) {
                     case 'overwrite':
                         // always set
                         $this->set($va_parts[1], $vs_value);
                         break;
                     case 'addifempty':
                     default:
                         if (!$this->get($va_parts[1])) {
                             $this->set($va_parts[1], $vs_value);
                         } else {
                             Debug::msg("[prepopulateFields()] rule {$vs_rule_key}: intrinsic skipped because it already has value and mode is addIfEmpty or merge");
                         }
                         break;
                 }
                 // attribute/element
             } elseif ($this->hasElement($va_parts[1])) {
                 $va_attributes = $this->getAttributesByElement($va_parts[1]);
                 if (sizeof($va_attributes) > 1) {
                     Debug::msg("[prepopulateFields()] containers with multiple values are not supported");
                     continue;
                 }
                 switch (strtolower($vs_mode)) {
                     case 'overwrite':
                         // always replace first value we find
                         $this->replaceAttribute(array($va_parts[1] => $vs_value, 'locale_id' => $g_ui_locale_id), $va_parts[1]);
                         break;
                     default:
                     case 'addifempty':
                         // only add value if none exists
                         if (!$this->get($vs_target)) {
                             $this->replaceAttribute(array($va_parts[1] => $vs_value, 'locale_id' => $g_ui_locale_id), $va_parts[1]);
                         }
                         break;
                 }
             }
             // "container"
         } elseif (sizeof($va_parts) == 3) {
             // actual container
             if ($this->hasElement($va_parts[1])) {
                 $va_attr = $this->getAttributesByElement($va_parts[1]);
                 switch (sizeof($va_attr)) {
                     case 1:
                         switch (strtolower($vs_mode)) {
                             case 'overwrite':
                                 $vo_attr = array_pop($va_attr);
                                 $va_value = array($va_parts[2] => $vs_value);
                                 foreach ($vo_attr->getValues() as $o_val) {
                                     if ($o_val->getElementCode() != $va_parts[2]) {
                                         $va_value[$o_val->getElementCode()] = $o_val->getDisplayValue();
                                     }
                                 }
                                 $this->_editAttribute($vo_attr->getAttributeID(), $va_value);
                                 break;
                             case 'addifempty':
                                 $vo_attr = array_pop($va_attr);
                                 $va_value = array($va_parts[2] => $vs_value);
                                 $vb_update = false;
                                 foreach ($vo_attr->getValues() as $o_val) {
                                     if ($o_val->getElementCode() != $va_parts[2]) {
                                         $va_value[$o_val->getElementCode()] = $o_val->getDisplayValue();
                                     } else {
                                         if (!$o_val->getDisplayValue()) {
                                             $vb_update = true;
                                         }
                                     }
                                 }
                                 if ($vb_update) {
                                     $this->editAttribute($vo_attr->getAttributeID(), $va_parts[1], $va_value);
                                 }
                                 break;
                             default:
                                 Debug::msg("[prepopulateFields()] unsupported mode {$vs_mode} for target bundle");
                                 break;
                         }
                         break;
                     case 0:
                         // if no container value exists, always add it (ignoring mode)
                         $this->addAttribute(array($va_parts[2] => $vs_value, 'locale_id' => $g_ui_locale_id), $va_parts[1]);
                         break;
                     default:
                         Debug::msg("[prepopulateFields()] containers with multiple values are not supported");
                         break;
                 }
                 // labels
             } elseif ($va_parts[1] == 'preferred_labels' || $va_parts[1] == 'nonpreferred_labels') {
                 $vb_preferred = $va_parts[1] == 'preferred_labels';
                 if (!($t_label = $this->getAppDatamodel()->getInstanceByTableName($this->getLabelTableName(), true))) {
                     continue;
                 }
                 if (!$t_label->hasField($va_parts[2])) {
                     continue;
                 }
                 switch ($this->getLabelCount($vb_preferred)) {
                     case 0:
                         // if no value exists, always add it (ignoring mode)
                         $this->addLabel(array($va_parts[2] => $vs_value), $g_ui_locale_id, null, $vb_preferred);
                         break;
                     case 1:
                         switch (strtolower($vs_mode)) {
                             case 'overwrite':
                             case 'addifempty':
                                 $va_labels = $this->getLabels(null, $vb_preferred ? __CA_LABEL_TYPE_PREFERRED__ : __CA_LABEL_TYPE_NONPREFERRED__);
                                 if (sizeof($va_labels)) {
                                     $va_labels = caExtractValuesByUserLocale($va_labels);
                                     $va_label = array_shift($va_labels);
                                     $va_label = $va_label[0];
                                     $va_label[$va_parts[2]] = $vs_value;
                                     $vb_update = false;
                                     if (strtolower($vs_mode) == 'overwrite') {
                                         $va_label[$va_parts[2]] = $vs_value;
                                         $vb_update = true;
                                     } else {
                                         if (strlen(trim($va_label[$va_parts[2]])) == 0) {
                                             // in addifempty mode only edit label when field is not set
                                             $va_label[$va_parts[2]] = $vs_value;
                                             $vb_update = true;
                                         }
                                     }
                                     if ($vb_update) {
                                         $this->editLabel($va_label['label_id'], $va_label, $g_ui_locale_id, null, $vb_preferred);
                                     }
                                 } else {
                                     $this->addLabel(array($va_parts[2] => $vs_value), $g_ui_locale_id, null, $vb_preferred);
                                 }
                                 break;
                             default:
                                 Debug::msg("[prepopulateFields()] unsupported mode {$vs_mode} for target bundle");
                                 break;
                         }
                         break;
                     default:
                         Debug::msg("[prepopulateFields()] records with multiple labels are not supported");
                         break;
                 }
             }
         }
     }
     $vn_old_mode = $this->getMode();
     $this->setMode(ACCESS_WRITE);
     $this->update();
     $this->setMode($vn_old_mode);
     $_REQUEST['form_timestamp'] = $vn_timestamp;
     if ($this->numErrors() > 0) {
         foreach ($this->getErrors() as $vs_error) {
             Debug::msg("[prepopulateFields()] there was an error while updating the record: " . $vs_error);
         }
         if ($vb_we_set_transaction) {
             $this->removeTransaction(false);
         }
         return false;
     }
     if ($vb_we_set_transaction) {
         $this->removeTransaction(true);
     }
     return true;
 }
コード例 #29
0
ファイル: displayHelpers.php プロジェクト: kai-iak/providence
/**
 * Replace "^" prefixed tags (eg. ^forename) in a template with values from an array
 *
 * @param string $ps_template String with embedded tags. Tags are just alphanumeric strings prefixed with a caret ("^")
 * @param string $pm_tablename_or_num Table name or number of table from which values are being formatted
 * @param string $pa_row_ids An array of primary key values in the specified table to be pulled into the template
 * @param array $pa_options Supported options are:
 *		returnAsArray = if true an array of processed template values is returned, otherwise the template values are returned as a string joined together with a delimiter. Default is false.
 *		delimiter = value to string together template values with when returnAsArray is false. Default is ';' (semicolon)
 *		relatedValues = array of field values to return in template when directly referenced. Array should be indexed numerically in parallel with $pa_row_ids
 *		relationshipValues = array of field values to return in template for relationship when directly referenced. Should be indexed by row_id and then by relation_id
 *		placeholderPrefix = attribute container to implicitly place primary record fields into. Ex. if the table is "ca_entities" and the placeholder is "address" then tags like ^city will resolve to ca_entities.address.city
 *		requireLinkTags = if set then links are only added when explicitly defined with <l> tags. Default is to make the entire text a link in the absence of <l> tags.
 *		resolveLinksUsing = 
 *		primaryIDs = row_ids for primary rows in related table, keyed by table name; when resolving ambiguous relationships the row_ids will be excluded from consideration. This option is rarely used and exists primarily to take care of a single
 *						edge case: you are processing a template relative to a self-relationship such as ca_entities_x_entities that includes references to the subject table (ca_entities, in the case of ca_entities_x_entities). There are
 *						two possible paths to take in this situations; primaryIDs lets you specify which ones you *don't* want to take by row_id. For interstitial editors, the ids will be set to a single id: that of the subject (Eg. ca_entities) row
 *						from which the interstitial was launched.
 *		sort = optional list of tag values to sort repeating values within a row template on. The tag must appear in the template. You can specify more than one tag by separating the tags with semicolons.
 *		sortDirection = The direction of the sort of repeating values within a row template. May be either ASC (ascending) or DESC (descending). [Default is ASC]
 *		linkTarget = Optional target to use when generating <l> tag-based links. By default links point to standard detail pages, but plugins may define linkTargets that point elsewhere.
 * 		skipIfExpression = skip the elements in $pa_row_ids for which the given expression does not evaluate true
 *		includeBlankValuesInArray = include blank template values in returned array when returnAsArray is set. If you need the returned array of values to line up with the row_ids in $pa_row_ids this should be set. [Default is false]
 *
 * @return mixed Output of processed templates
 */
function caProcessTemplateForIDs($ps_template, $pm_tablename_or_num, $pa_row_ids, $pa_options = null)
{
    foreach (array('request', 'template', 'restrictToTypes', 'restrict_to_types', 'restrict_to_relationship_types', 'restrictToRelationshipTypes', 'useLocaleCodes') as $vs_k) {
        unset($pa_options[$vs_k]);
    }
    if (!isset($pa_options['convertCodesToDisplayText'])) {
        $pa_options['convertCodesToDisplayText'] = true;
    }
    $pb_return_as_array = (bool) caGetOption('returnAsArray', $pa_options, false);
    if (($pa_sort = caGetOption('sort', $pa_options, null)) && !is_array($pa_sort)) {
        $pa_sort = explode(";", $pa_sort);
    }
    $ps_sort_direction = caGetOption('sortDirection', $pa_options, null, array('forceUppercase' => true));
    if (!in_array($ps_sort_direction, array('ASC', 'DESC'))) {
        $ps_sort_direction = 'ASC';
    }
    $pa_check_access = caGetOption('checkAccess', $pa_options, null);
    if (!is_array($pa_row_ids) || !sizeof($pa_row_ids) || !$ps_template) {
        return $pb_return_as_array ? array() : "";
    }
    unset($pa_options['returnAsArray']);
    if (!isset($pa_options['requireLinkTags'])) {
        $pa_options['requireLinkTags'] = true;
    }
    $ps_skip_if_expression = caGetOption('skipIfExpression', $pa_options, false);
    $va_primary_ids = caGetOption("primaryIDs", $pa_options, null);
    $o_dm = Datamodel::load();
    $ps_tablename = is_numeric($pm_tablename_or_num) ? $o_dm->getTableName($pm_tablename_or_num) : $pm_tablename_or_num;
    $ps_resolve_links_using = caGetOption('resolveLinksUsing', $pa_options, $ps_tablename);
    $t_instance = $o_dm->getInstanceByTableName($ps_tablename, true);
    if ($ps_resolve_links_using != $ps_tablename) {
        $t_resolve_links_instance = $o_dm->getInstanceByTableName($ps_resolve_links_using, true);
        $vs_resolve_links_using_pk = $t_resolve_links_instance->primaryKey();
    }
    $vs_pk = $t_instance->primaryKey();
    $vs_delimiter = isset($pa_options['delimiter']) ? $pa_options['delimiter'] : '; ';
    $ps_template = str_replace("^_parent", "^{$ps_resolve_links_using}.parent.preferred_labels", $ps_template);
    $ps_template = str_replace("^_hierarchy", "^{$ps_resolve_links_using}._hierarchyName", $ps_template);
    $va_related_values = isset($pa_options['relatedValues']) && is_array($pa_options['relatedValues']) ? $pa_options['relatedValues'] : array();
    $va_relationship_values = isset($pa_options['relationshipValues']) && is_array($pa_options['relationshipValues']) ? $pa_options['relationshipValues'] : array();
    $o_doc = str_get_dom($ps_template);
    // parse template
    $ps_template = str_replace("<~root~>", "", str_replace("</~root~>", "", $o_doc->html()));
    // replace template with parsed version; this allows us to do text find/replace later
    // Parse units from template
    $o_units = $o_doc('unit');
    // only process non-nested <unit> tags
    $va_units = array();
    $vn_unit_id = 1;
    foreach ($o_units as $o_unit) {
        if (!$o_unit) {
            continue;
        }
        $vs_html = str_replace("<~root~>", "", str_replace("</~root~>", "", $o_unit->html()));
        $vs_content = $o_unit->getInnerText();
        // is this nested in another unit? We skip these
        foreach ($va_units as $va_tmp) {
            if (strpos($va_tmp['directive'], $vs_html) !== false) {
                continue 2;
            }
        }
        $va_units[] = $va_unit = array('tag' => $vs_unit_tag = "[[#{$vn_unit_id}]]", 'directive' => $vs_html, 'content' => $vs_content, 'relativeTo' => (string) $o_unit->getAttribute("relativeto"), 'delimiter' => ($vs_d = (string) $o_unit->getAttribute("delimiter")) ? $vs_d : null, 'restrictToTypes' => (string) $o_unit->getAttribute("restricttotypes"), 'restrictToRelationshipTypes' => (string) $o_unit->getAttribute("restricttorelationshiptypes"), 'sort' => explode(";", $o_unit->getAttribute("sort")), 'sortDirection' => (string) $o_unit->getAttribute("sortDirection"), 'skipIfExpression' => (string) $o_unit->getAttribute("skipIfExpression"));
        $ps_template = str_ireplace($va_unit['directive'], $vs_unit_tag, $ps_template);
        $vn_unit_id++;
    }
    $o_doc = str_get_dom($ps_template);
    // parse template again with units replaced by unit tags in the format [[#X]]
    $ps_template = str_replace("<~root~>", "", str_replace("</~root~>", "", $o_doc->html()));
    // replace template with parsed version; this allows us to do text find/replace later
    $va_tags = array();
    if (preg_match_all(__CA_BUNDLE_DISPLAY_TEMPLATE_TAG_REGEX__, $ps_template, $va_matches)) {
        $va_tags = $va_matches[1];
    }
    $va_directive_tags = array();
    $va_directive_tag_vals = array();
    $qr_res = caMakeSearchResult($ps_tablename, $pa_row_ids);
    if (!$qr_res) {
        return '';
    }
    $va_proc_templates = array();
    $vn_i = 0;
    $o_ifs = $o_doc("if");
    // if
    $o_ifdefs = $o_doc("ifdef");
    // if defined
    $o_ifnotdefs = $o_doc("ifnotdef");
    // if not defined
    $o_mores = $o_doc("more");
    // more tags - content suppressed if there are no defined values following the tag pair
    $o_betweens = $o_doc("between");
    // between tags - content suppressed if there are not defined values on both sides of the tag pair
    $va_if = array();
    foreach ($o_ifs as $o_if) {
        if (!$o_if) {
            continue;
        }
        $vs_html = $o_if->html();
        $vs_content = $o_if->getInnerText();
        $va_if[] = array('directive' => $vs_html, 'content' => $vs_content, 'rule' => $vs_rule = (string) $o_if->getAttribute('rule'));
    }
    foreach ($o_ifdefs as $o_ifdef) {
        if (!$o_ifdef) {
            continue;
        }
        $vs_code = (string) $o_ifdef->getAttribute('code');
        $vs_code_proc = preg_replace("!%(.*)\$!", '', $vs_code);
        $va_directive_tags = array_merge($va_directive_tags, preg_split('![,\\|]{1}!', $vs_code_proc));
    }
    foreach ($o_ifnotdefs as $o_ifnotdef) {
        if (!$o_ifnotdef) {
            continue;
        }
        $vs_code = (string) $o_ifnotdef->getAttribute('code');
        $vs_code_proc = preg_replace("!%(.*)\$!", '', $vs_code);
        $va_directive_tags = array_merge($va_directive_tags, preg_split('![,\\|]{1}!', $vs_code_proc));
    }
    $va_mores = array();
    foreach ($o_mores as $o_more) {
        if (!$o_more) {
            continue;
        }
        $vs_html = str_replace("<~root~>", "", str_replace("</~root~>", "", $o_more->html()));
        $vs_content = $o_more->getInnerText();
        $va_mores[] = array('directive' => $vs_html, 'content' => $vs_content);
    }
    $va_betweens = array();
    foreach ($o_betweens as $o_between) {
        if (!$o_between) {
            continue;
        }
        $vs_html = str_replace("<~root~>", "", str_replace("</~root~>", "", $o_between->html()));
        $vs_content = $o_between->getInnerText();
        $va_betweens[] = array('directive' => $vs_html, 'content' => $vs_content);
    }
    $va_resolve_links_using_row_ids = array();
    $va_tag_val_list = $va_defined_tag_list = array();
    $va_expression_vars = array();
    /** @var $qr_res SearchResult */
    while ($qr_res->nextHit()) {
        $vs_pk_val = $qr_res->get($vs_pk, array('checkAccess' => $pa_check_access));
        if (is_array($pa_check_access) && sizeof($pa_check_access) && !in_array($qr_res->get("{$ps_tablename}.access"), $pa_check_access)) {
            continue;
        }
        $vs_template = $ps_template;
        // check if we skip this row because of skipIfExpression
        if (strlen($ps_skip_if_expression) > 0) {
            $va_expression_tags = caGetTemplateTags($ps_skip_if_expression);
            foreach ($va_expression_tags as $vs_expression_tag) {
                if (!isset($va_expression_vars[$vs_expression_tag])) {
                    $va_expression_vars[$vs_expression_tag] = $qr_res->get($vs_expression_tag, array('assumeDisplayField' => true, 'returnIdno' => true, 'delimiter' => ';'));
                }
            }
            if (ExpressionParser::evaluate($ps_skip_if_expression, $va_expression_vars)) {
                continue;
            }
        }
        // Grab values for codes used in ifdef and ifnotdef directives
        $va_directive_tag_vals = array();
        foreach ($va_directive_tags as $vs_directive_tag) {
            $va_directive_tag_vals[$vs_directive_tag] = $qr_res->get($vs_directive_tag, array('assumeDisplayField' => true, 'convertCodesToDisplayText' => true, 'dontUseElementTemplate' => true));
        }
        $o_parsed_template = str_get_dom($vs_template);
        while (sizeof($vo_templates = $o_parsed_template('ifcount:not(:has(ifdef,ifndef,ifcount)),ifdef:not(:has(ifdef,ifndef,ifcount)),ifndef:not(:has(ifdef,ifndef,ifcount))')) > 0) {
            foreach ($vo_templates as $vn_index => $vo_element) {
                $vs_code = $vo_element->code;
                switch ($vo_element->tag) {
                    case 'ifdef':
                        if (strpos($vs_code, "|") !== false) {
                            $vs_bool = 'OR';
                            $va_tag_list = explode("|", $vs_code);
                            $vb_output = false;
                        } else {
                            $vs_bool = 'AND';
                            $va_tag_list = explode(",", $vs_code);
                            $vb_output = true;
                        }
                        foreach ($va_tag_list as $vs_tag_to_test) {
                            $vs_tag_to_test = preg_replace("!%.*\$!", "", $vs_tag_to_test);
                            $vb_value_is_set = isset($va_directive_tag_vals[$vs_tag_to_test]) && strlen($va_directive_tag_vals[$vs_tag_to_test]) > 1;
                            switch ($vs_bool) {
                                case 'OR':
                                    if ($vb_value_is_set) {
                                        $vb_output = true;
                                        break 2;
                                    }
                                    // any must be defined; if any is defined output
                                    break;
                                case 'AND':
                                default:
                                    if (!$vb_value_is_set) {
                                        $vb_output = false;
                                        break 2;
                                    }
                                    // all must be defined; if any is not defined don't output
                                    break;
                            }
                        }
                        if ($vb_output) {
                            $vs_template = str_replace($vo_element->html(), $vo_element->getInnerText(), $vs_template);
                        } else {
                            $vs_template = str_replace($vo_element->html(), '', $vs_template);
                        }
                        break;
                    case 'ifndef':
                        if (strpos($vs_code, "|") !== false) {
                            $vs_bool = 'OR';
                            $va_tag_list = explode("|", $vs_code);
                            $vb_output = false;
                        } else {
                            $vs_bool = 'AND';
                            $va_tag_list = explode(",", $vs_code);
                            $vb_output = true;
                        }
                        $vb_output = true;
                        foreach ($va_tag_list as $vs_tag_to_test) {
                            $vb_value_is_set = (bool) (isset($va_directive_tag_vals[$vs_tag_to_test]) && strlen($va_directive_tag_vals[$vs_tag_to_test]) > 0);
                            switch ($vs_bool) {
                                case 'OR':
                                    if (!$vb_value_is_set) {
                                        $vb_output = true;
                                        break 2;
                                    }
                                    // any must be not defined; if anything is not set output
                                    break;
                                case 'AND':
                                default:
                                    if ($vb_value_is_set) {
                                        $vb_output = false;
                                        break 2;
                                    }
                                    // all must be not defined; if anything is set don't output
                                    break;
                            }
                        }
                        if ($vb_output) {
                            $vs_template = str_replace($vo_element->html(), $vo_element->getInnerText(), $vs_template);
                        } else {
                            $vs_template = str_replace($vo_element->html(), '', $vs_template);
                        }
                        break;
                    case 'ifcount':
                        if (is_array($va_if_codes = preg_split("![\\|,;]+!", $vs_code))) {
                            $vn_min = (int) $vo_element->min;
                            $vn_max = (int) $vo_element->max;
                            $va_restrict_to_types = preg_split("![,; ]+!", $vo_element->restrictToTypes);
                            $va_restrict_to_relationship_types = preg_split("![,; ]+!", $vo_element->restrictToRelationshipTypes);
                            $vn_count = 0;
                            foreach ($va_if_codes as $vs_if_code) {
                                if ($t_table = $o_dm->getInstanceByTableName($vs_if_code, true)) {
                                    $va_count_vals = $qr_res->get($vs_if_code . "." . $t_table->primaryKey(), array('restrictToTypes' => $va_restrict_to_types, 'restrictToRelationshipTypes' => $va_restrict_to_relationship_types, 'returnAsArray' => true, 'checkAccess' => $pa_check_access));
                                } else {
                                    $va_count_vals = $qr_res->get($vs_if_code, array('returnAsArray' => true, 'restrictToTypes' => $va_restrict_to_types, 'restrictToRelationshipTypes' => $va_restrict_to_relationship_types, 'checkAccess' => $pa_check_access));
                                }
                                if (is_array($va_count_vals)) {
                                    $va_bits = explode(".", $vs_if_code);
                                    $vs_fld = array_pop($va_bits);
                                    foreach ($va_count_vals as $vs_count_val) {
                                        if (is_array($vs_count_val)) {
                                            if (isset($vs_count_val[$vs_fld]) && !trim($vs_count_val[$vs_fld])) {
                                                continue;
                                            }
                                            $vb_is_set = false;
                                            foreach ($vs_count_val as $vs_f => $vs_v) {
                                                if (trim($vs_v)) {
                                                    $vb_is_set = true;
                                                    break;
                                                }
                                            }
                                            if (!$vb_is_set) {
                                                continue;
                                            }
                                        } else {
                                            if (!trim($vs_count_val)) {
                                                continue;
                                            }
                                        }
                                        $vn_count++;
                                    }
                                }
                            }
                            if ($vn_min <= $vn_count && ($vn_max >= $vn_count || !$vn_max)) {
                                $vs_template = str_replace($vo_element->html(), $vo_element->getInnerText(), $vs_template);
                            } else {
                                $vs_template = str_replace($vo_element->html(), '', $vs_template);
                            }
                        }
                        break;
                }
            }
            $o_parsed_template = str_get_dom($vs_template);
            // reparse
        }
        $va_proc_templates[$vn_i] = $vs_template;
        foreach ($va_units as $k => $va_unit) {
            if (!$va_unit['content']) {
                continue;
            }
            $va_relative_to_tmp = $va_unit['relativeTo'] ? explode(".", $va_unit['relativeTo']) : array($ps_tablename);
            if (!($t_rel_instance = $o_dm->getInstanceByTableName($va_relative_to_tmp[0], true))) {
                continue;
            }
            $vs_unit_delimiter = caGetOption('delimiter', $va_unit, $vs_delimiter);
            $vs_unit_skip_if_expression = caGetOption('skipIfExpression', $va_unit, false);
            // additional get options for pulling related records
            $va_get_options = array('returnAsArray' => true, 'checkAccess' => $pa_check_access);
            if ($va_unit['restrictToTypes'] && strlen($va_unit['restrictToTypes']) > 0) {
                $va_get_options['restrictToTypes'] = preg_split('![\\|,;]+!', $va_unit['restrictToTypes']);
            }
            if ($va_unit['restrictToRelationshipTypes'] && strlen($va_unit['restrictToRelationshipTypes']) > 0) {
                $va_get_options['restrictToRelationshipTypes'] = preg_split('![\\|,;]+!', $va_unit['restrictToRelationshipTypes']);
            }
            if ($va_unit['sort'] && is_array($va_unit['sort'])) {
                $va_get_options['sort'] = $va_unit['sort'];
                $va_get_options['sortDirection'] = $va_unit['sortDirection'];
            }
            if (sizeof($va_relative_to_tmp) == 1 && $va_relative_to_tmp[0] == $ps_tablename || sizeof($va_relative_to_tmp) >= 1 && $va_relative_to_tmp[0] == $ps_tablename && $va_relative_to_tmp[1] != 'related') {
                switch (strtolower($va_relative_to_tmp[1])) {
                    case 'hierarchy':
                        $va_relative_ids = $qr_res->get($t_rel_instance->tableName() . ".hierarchy." . $t_rel_instance->primaryKey(), $va_get_options);
                        $va_relative_ids = array_values($va_relative_ids);
                        break;
                    case 'parent':
                        $va_relative_ids = $qr_res->get($t_rel_instance->tableName() . ".parent." . $t_rel_instance->primaryKey(), $va_get_options);
                        $va_relative_ids = array_values($va_relative_ids);
                        break;
                    case 'children':
                        $va_relative_ids = $qr_res->get($t_rel_instance->tableName() . ".children." . $t_rel_instance->primaryKey(), $va_get_options);
                        $va_relative_ids = array_values($va_relative_ids);
                        break;
                    default:
                        $va_relative_ids = array($vs_pk_val);
                        break;
                }
                // process template for all records selected by unit tag
                $va_tmpl_val = caProcessTemplateForIDs($va_unit['content'], $va_relative_to_tmp[0], $va_relative_ids, array_merge($pa_options, array('sort' => $va_get_options['sort'], 'sortDirection' => $va_get_options['sortDirection'], 'returnAsArray' => true, 'delimiter' => $vs_unit_delimiter, 'resolveLinksUsing' => null, 'skipIfExpression' => $vs_unit_skip_if_expression)));
                $va_proc_templates[$vn_i] = str_ireplace($va_unit['tag'], join($vs_unit_delimiter, $va_tmpl_val), $va_proc_templates[$vn_i]);
            } else {
                switch (strtolower($va_relative_to_tmp[1])) {
                    case 'hierarchy':
                        $va_relative_ids = $qr_res->get($t_rel_instance->tableName() . ".hierarchy." . $t_rel_instance->primaryKey(), $va_get_options);
                        $va_relative_ids = array_values($va_relative_ids);
                        break;
                    case 'parent':
                        $va_relative_ids = $qr_res->get($t_rel_instance->tableName() . ".parent." . $t_rel_instance->primaryKey(), $va_get_options);
                        $va_relative_ids = array_values($va_relative_ids);
                        break;
                    case 'children':
                        $va_relative_ids = $qr_res->get($t_rel_instance->tableName() . ".children." . $t_rel_instance->primaryKey(), $va_get_options);
                        $va_relative_ids = array_values($va_relative_ids);
                        break;
                    case 'related':
                        $va_relative_ids = $qr_res->get($t_rel_instance->tableName() . ".related." . $t_rel_instance->primaryKey(), $va_get_options);
                        $va_relative_ids = array_values($va_relative_ids);
                        break;
                    default:
                        if (method_exists($t_instance, 'isSelfRelationship') && $t_instance->isSelfRelationship()) {
                            $va_relative_ids = array_values($t_instance->getRelatedIDsForSelfRelationship($va_primary_ids[$t_rel_instance->tableName()], array($vs_pk_val)));
                        } else {
                            $va_relative_ids = array_values($qr_res->get($t_rel_instance->tableName() . "." . $t_rel_instance->primaryKey(), $va_get_options));
                        }
                        break;
                }
                $vs_tmpl_val = caProcessTemplateForIDs($va_unit['content'], $va_relative_to_tmp[0], $va_relative_ids, array_merge($pa_options, array('sort' => $va_unit['sort'], 'sortDirection' => $va_unit['sortDirection'], 'delimiter' => $vs_unit_delimiter, 'resolveLinksUsing' => null, 'skipIfExpression' => $vs_unit_skip_if_expression)));
                $va_proc_templates[$vn_i] = str_ireplace($va_unit['tag'], $vs_tmpl_val, $va_proc_templates[$vn_i]);
            }
        }
        if (!strlen(trim($va_proc_templates[$vn_i]))) {
            $va_proc_templates[$vn_i] = null;
        }
        if (!sizeof($va_tags)) {
            $vn_i++;
            continue;
        }
        // if there are no tags in the template then we don't need to process further
        if ($ps_resolve_links_using !== $ps_tablename) {
            $va_resolve_links_using_row_ids += $qr_res->get("{$ps_resolve_links_using}.{$vs_resolve_links_using_pk}", array('returnAsArray' => true, 'checkAccess' => $pa_check_access));
            // we need to remove "primary_ids" from the list, since for self-relations these will be the side(s) of the relations we're viewing *from*
            if (is_array($va_primary_ids[$ps_resolve_links_using]) && sizeof($va_primary_ids[$ps_resolve_links_using])) {
                $va_resolve_links_using_row_ids = array_values(array_diff($va_resolve_links_using_row_ids, $va_primary_ids[$ps_resolve_links_using]));
            }
        }
        $va_tag_val_list[$vn_i] = array();
        $va_defined_tag_list[$vn_i] = array();
        $va_tag_opts = $va_tag_filters = array();
        foreach ($va_tags as $vs_tag) {
            $va_tmp = explode('.', $vs_tag);
            $vs_last_element = $va_tmp[sizeof($va_tmp) - 1];
            $va_tag_opt_tmp = explode("%", $vs_last_element);
            if (sizeof($va_tag_opt_tmp) > 1) {
                $vs_tag_bit = array_shift($va_tag_opt_tmp);
                // get rid of getspec
                foreach ($va_tag_opt_tmp as $vs_tag_opt_raw) {
                    if (preg_match("!^\\[([^\\]]+)\\]\$!", $vs_tag_opt_raw, $va_matches)) {
                        if (sizeof($va_filter = explode("=", $va_matches[1])) == 2) {
                            $va_tag_filters[$va_filter[0]] = $va_filter[1];
                        }
                        continue;
                    }
                    $va_tag_tmp = explode("=", $vs_tag_opt_raw);
                    $va_tag_tmp[0] = trim($va_tag_tmp[0]);
                    $va_tag_tmp[1] = trim($va_tag_tmp[1]);
                    if (in_array($va_tag_tmp[0], array('delimiter', 'hierarchicalDelimiter'))) {
                        $va_tag_tmp[1] = str_replace("_", " ", $va_tag_tmp[1]);
                    }
                    if (sizeof($va_tag_line_tmp = explode("|", $va_tag_tmp[1])) > 1) {
                        $va_tag_opts[trim($va_tag_tmp[0])] = $va_tag_line_tmp;
                    } else {
                        $va_tag_opts[trim($va_tag_tmp[0])] = $va_tag_tmp[1];
                    }
                }
                $va_tmp[sizeof($va_tmp) - 1] = $vs_tag_bit;
                // remove option from tag-part array
                $vs_tag_proc = join(".", $va_tmp);
                $va_proc_templates[$vn_i] = str_replace($vs_tag, $vs_tag_proc, $va_proc_templates[$vn_i]);
                $vs_tag = $vs_tag_proc;
            }
            switch ($vs_tag) {
                case 'DATE':
                    $vs_format = urldecode(caGetOption('format', $va_tag_opts, 'd M Y'));
                    $va_proc_templates[$vn_i] = str_replace("^{$vs_tag}", date($vs_format), $va_proc_templates[$vn_i]);
                    continue 2;
                    break;
            }
            $pa_options = array_merge($pa_options, $va_tag_opts);
            // Default label tag to hierarchies
            if (isset($pa_options['showHierarchicalLabels']) && $pa_options['showHierarchicalLabels'] && $vs_tag == 'label') {
                unset($va_related_values[$vs_pk_val][$vs_tag]);
                unset($va_relationship_values[$vs_pk_val][$vs_tag]);
                $va_tmp = array($ps_tablename, 'hierarchy', 'preferred_labels');
            }
            if (!isset($va_relationship_values[$vs_pk_val])) {
                $va_relationship_values[$vs_pk_val] = array(0 => null);
            }
            foreach ($va_relationship_values[$vs_pk_val] as $vn_relation_id => $va_relationship_value_array) {
                $vb_is_related = false;
                $va_val = null;
                if (isset($va_relationship_value_array[$vs_tag]) && !(isset($pa_options['showHierarchicalLabels']) && $pa_options['showHierarchicalLabels'] && $vs_tag == 'label')) {
                    $va_val = array($vs_val = $va_relationship_value_array[$vs_tag]);
                } elseif (isset($va_relationship_value_array[$vs_tag])) {
                    $va_val = array($vs_val = $va_relationship_value_array[$vs_tag]);
                } else {
                    if (isset($va_related_values[$vs_pk_val][$vs_tag])) {
                        $va_val = array($vs_val = $va_related_values[$vs_pk_val][$vs_tag]);
                    } else {
                        //
                        // see if this is a reference to a related table
                        //
                        if (in_array($vs_tag, array("relationship_typename", "relationship_type_id", "relationship_typecode", "relationship_type_code"))) {
                            $vb_is_related = true;
                            switch ($vs_tag) {
                                case 'relationship_typename':
                                    $vs_spec = 'preferred_labels.' . (caGetOption('orientation', $pa_options, 'LTOR') == 'LTOR' ? 'typename' : 'typename_reverse');
                                    break;
                                case 'relationship_type_id':
                                    $vs_spec = 'type_id';
                                    break;
                                case 'relationship_typecode':
                                case 'relationship_type_code':
                                default:
                                    $vs_spec = 'type_code';
                                    break;
                            }
                            $vs_rel = $qr_res->get("ca_relationship_types.{$vs_spec}", array_merge($pa_options, $va_tag_opts, array('returnAsArray' => false)));
                            $va_val = array($vs_rel);
                        } elseif ($ps_tablename != $va_tmp[0] && ($t_tmp = $o_dm->getInstanceByTableName($va_tmp[0], true))) {
                            // if the part of the tag before a "." (or the tag itself if there are no periods) is a related table then try to fetch it as related to the current record
                            if (isset($pa_options['placeholderPrefix']) && $pa_options['placeholderPrefix'] && $va_tmp[0] != $pa_options['placeholderPrefix'] && sizeof($va_tmp) == 1) {
                                $vs_get_spec = array_shift($va_tmp) . "." . $pa_options['placeholderPrefix'];
                                if (sizeof($va_tmp) > 0) {
                                    $vs_get_spec .= "." . join(".", $va_tmp);
                                }
                            } else {
                                $vs_get_spec = $vs_tag;
                            }
                            $va_spec_bits = explode(".", $vs_get_spec);
                            if (sizeof($va_spec_bits) == 1 && $o_dm->getTableNum($va_spec_bits[0])) {
                                $vs_get_spec .= ".preferred_labels";
                            }
                            $va_additional_options = array('returnAsArray' => true, 'checkAccess' => $pa_check_access);
                            $vs_hierarchy_name = null;
                            $vb_is_hierarchy = false;
                            if (in_array($va_spec_bits[1], array('hierarchy', '_hierarchyName'))) {
                                $t_rel = $o_dm->getInstanceByTableName($va_spec_bits[0], true);
                                switch ($t_rel->getProperty('HIERARCHY_TYPE')) {
                                    case __CA_HIER_TYPE_SIMPLE_MONO__:
                                        $va_additional_options['removeFirstItems'] = 1;
                                        break;
                                    case __CA_HIER_TYPE_MULTI_MONO__:
                                        $vs_hierarchy_name = $t_rel->getHierarchyName($qr_res->get($t_rel->tableName() . "." . $t_rel->primaryKey(), array('checkAccess' => $pa_check_access)));
                                        $va_additional_options['removeFirstItems'] = 1;
                                        break;
                                }
                            }
                            if ($va_spec_bits[1] != '_hierarchyName') {
                                $va_val = $qr_res->get($vs_get_spec, array_merge($pa_options, $va_additional_options, array('returnWithStructure' => true, 'returnBlankValues' => true, 'returnAllLocales' => true, 'useLocaleCodes' => false, 'filters' => $va_tag_filters, 'primaryIDs' => $va_primary_ids)));
                            } else {
                                $va_val = array();
                            }
                            if (is_array($va_primary_ids) && isset($va_primary_ids[$va_spec_bits[0]]) && is_array($va_primary_ids[$va_spec_bits[0]])) {
                                foreach ($va_primary_ids[$va_spec_bits[0]] as $vn_primary_id) {
                                    unset($va_val[$vn_primary_id]);
                                }
                            }
                            if ($va_spec_bits[1] !== 'hierarchy') {
                                $va_val = caExtractValuesByUserLocale($va_val);
                                $va_val_tmp = array();
                                foreach ($va_val as $vn_d => $va_vals) {
                                    if (is_array($va_vals)) {
                                        $va_val_tmp = array_merge($va_val_tmp, array_values($va_vals));
                                    } else {
                                        $va_val_tmp[] = $va_vals;
                                    }
                                }
                                $va_val = $va_val_tmp;
                            }
                            $va_val_proc = array();
                            switch ($va_spec_bits[1]) {
                                case '_hierarchyName':
                                    if ($vs_hierarchy_name) {
                                        $va_val_proc[] = $vs_hierarchy_name;
                                    }
                                    break;
                                case 'hierarchy':
                                    if (is_array($va_val) && sizeof($va_val) > 0) {
                                        $va_hier_list = array();
                                        if ($vs_hierarchy_name) {
                                            array_unshift($va_hier_list, $vs_hierarchy_name);
                                        }
                                        $vs_name = end($va_spec_bits);
                                        foreach ($va_val as $va_hier) {
                                            $va_hier = caExtractValuesByUserLocale($va_hier);
                                            foreach ($va_hier as $va_hier_item) {
                                                foreach ($va_hier_item as $va_hier_value) {
                                                    $va_hier_list[] = $va_hier_value[$vs_name] ? $va_hier_value[$vs_name] : array_shift($va_hier_value);
                                                }
                                            }
                                        }
                                        $va_val_proc[] = join(caGetOption("delimiter", $va_tag_opts, $vs_delimiter), $va_hier_list);
                                    }
                                    break;
                                case 'parent':
                                    if (is_array($va_val)) {
                                        foreach ($va_val as $vm_label) {
                                            if (is_array($vm_label)) {
                                                $t_rel = $o_dm->getInstanceByTableName($va_spec_bits[0], true);
                                                if (!$t_rel || !method_exists($t_rel, "getLabelDisplayField")) {
                                                    $va_val_proc[] = join("; ", $vm_label);
                                                } else {
                                                    $va_val_proc[] = $vm_label[$t_rel->getLabelDisplayField()];
                                                }
                                            } else {
                                                $va_val_proc[] = $vm_label;
                                            }
                                        }
                                    }
                                    break;
                                default:
                                    $vs_terminal = end($va_spec_bits);
                                    foreach ($va_val as $va_val_container) {
                                        if (!is_array($va_val_container)) {
                                            if ($va_val_container) {
                                                $va_val_proc[] = $va_val_container;
                                            }
                                            continue;
                                        }
                                        // Add display field to *_labels terminals
                                        if (in_array($vs_terminal, array('preferred_labels', 'nonpreferred_labels')) && !$va_val_container[$vs_terminal]) {
                                            $t_rel = $o_dm->getInstanceByTableName($va_spec_bits[0], true);
                                            $vs_terminal = $t_rel->getLabelDisplayField();
                                        }
                                        $va_val_proc[] = $va_val_container[$vs_terminal];
                                    }
                                    break;
                            }
                            $va_val = $va_val_proc;
                            $vb_is_related = true;
                        } else {
                            //
                            // Handle non-related gets
                            //
                            // Default specifiers that end with a modifier to preferred labels
                            if (sizeof($va_tmp) == 2 && in_array($va_tmp[1], array('hierarchy', 'children', 'parent', 'related'))) {
                                array_push($va_tmp, 'preferred_labels');
                            }
                            $vs_hierarchy_name = null;
                            if (in_array($va_tmp[1], array('hierarchy', '_hierarchyName'))) {
                                switch ($t_instance->getProperty('HIERARCHY_TYPE')) {
                                    case __CA_HIER_TYPE_SIMPLE_MONO__:
                                        $va_additional_options['removeFirstItems'] = 1;
                                        break;
                                    case __CA_HIER_TYPE_MULTI_MONO__:
                                        $vs_hierarchy_name = $t_instance->getHierarchyName($qr_res->get($t_instance->tableName() . "." . $t_instance->primaryKey(), array('checkAccess' => $pa_check_access)));
                                        $va_additional_options['removeFirstItems'] = 1;
                                        break;
                                }
                            }
                            if ($va_tmp[0] == $ps_tablename) {
                                array_shift($va_tmp);
                            }
                            // get rid of primary table if it's in the field spec
                            if (!sizeof($va_tmp) && $t_instance->getProperty('LABEL_TABLE_NAME')) {
                                $va_tmp[] = "preferred_labels";
                            }
                            if (isset($pa_options['showHierarchicalLabels']) && $pa_options['showHierarchicalLabels']) {
                                if (!in_array($va_tmp[0], array('hierarchy', 'children', 'parent', 'related')) && $va_tmp[1] == 'preferred_labels') {
                                    array_unshift($va_tmp, 'hierarchy');
                                }
                            }
                            if (isset($pa_options['placeholderPrefix']) && $pa_options['placeholderPrefix'] && $va_tmp[0] != $pa_options['placeholderPrefix']) {
                                array_splice($va_tmp, -1, 0, $pa_options['placeholderPrefix']);
                            }
                            $vs_get_spec = "{$ps_tablename}." . join(".", $va_tmp);
                            if (in_array($va_tmp[0], array('parent'))) {
                                $va_val[] = $qr_res->get($vs_get_spec, array_merge($pa_options, $va_tag_opts, array('returnAsArray' => false)));
                            } elseif ($va_tmp[0] == '_hierarchyName') {
                                $va_val[] = $vs_hierarchy_name;
                            } else {
                                $va_val_tmp = $qr_res->get($vs_get_spec, array_merge($pa_options, $va_tag_opts, array('returnAsArray' => true, 'returnBlankValues' => true, 'assumeDisplayField' => true, 'filters' => $va_tag_filters, 'checkAccess' => $pa_check_access)));
                                $va_val = array();
                                if (is_array($va_val_tmp)) {
                                    //$va_val_tmp = array_reverse($va_val_tmp);
                                    if ($va_tmp[0] == 'hierarchy') {
                                        if ($vs_hierarchy_name) {
                                            array_shift($va_val_tmp);
                                            // remove root
                                            array_unshift($va_val_tmp, $vs_hierarchy_name);
                                            // replace with hierarchy name
                                        }
                                        if ($vs_delimiter_tmp = caGetOption('hierarchicalDelimiter', $va_tag_opts)) {
                                            $vs_tag_val_delimiter = $vs_delimiter_tmp;
                                        } elseif ($vs_delimiter_tmp = caGetOption('hierarchicalDelimiter', $pa_options)) {
                                            $vs_tag_val_delimiter = $vs_delimiter_tmp;
                                        } elseif ($vs_delimiter_tmp = caGetOption('delimiter', $va_tag_opts, $vs_delimiter)) {
                                            $vs_tag_val_delimiter = $vs_delimiter_tmp;
                                        } else {
                                            $vs_tag_val_delimiter = $vs_delimiter;
                                        }
                                    } else {
                                        $vs_tag_val_delimiter = caGetOption('delimiter', $va_tag_opts, $vs_delimiter);
                                    }
                                    foreach ($va_val_tmp as $vn_attr_id => $vm_attr_val) {
                                        if (is_array($vm_attr_val)) {
                                            $va_val[] = join($vs_tag_val_delimiter, $vm_attr_val);
                                        } else {
                                            $va_val[] = $vm_attr_val;
                                        }
                                    }
                                }
                                if (sizeof($va_val) > 1 && $va_tmp[0] == 'hierarchy') {
                                    $vs_tag_val_delimiter = caGetOption('delimiter', $va_tag_opts, $vs_delimiter);
                                    $va_val = array(join($vs_tag_val_delimiter, $va_val));
                                }
                            }
                        }
                    }
                }
                if (is_array($va_val)) {
                    if (sizeof($va_val) > 0) {
                        foreach ($va_val as $vn_j => $vs_val) {
                            if (!is_array($va_tag_val_list[$vn_i][$vn_j][$vs_tag]) || !in_array($vs_val, $va_tag_val_list[$vn_i][$vn_j][$vs_tag])) {
                                $va_tag_val_list[$vn_i][$vn_j][$vs_tag][] = $vs_val;
                                if (is_array($vs_val) && sizeof($vs_val) || strlen($vs_val) > 0) {
                                    $va_defined_tag_list[$vn_i][$vn_j][$vs_tag] = true;
                                }
                            }
                        }
                    } else {
                        $va_tag_val_list[$vn_i][0][$vs_tag] = null;
                        $va_defined_tag_list[$vn_i][0][$vs_tag] = false;
                    }
                }
            }
        }
        $vn_i++;
    }
    foreach ($va_tag_val_list as $vn_i => $va_tags_list) {
        // do sorting?
        if (is_array($pa_sort)) {
            $va_sorted_values = $va_sorted_values_tmp = array();
            foreach ($va_tags_list as $vn_j => $va_values_by_field) {
                $vs_key = '';
                foreach ($pa_sort as $vn_k => $vs_sort) {
                    if (!isset($va_values_by_field[$vs_sort])) {
                        continue;
                    }
                    $vs_subkey = null;
                    foreach ($va_values_by_field[$vs_sort] as $vn_x => $vs_sort_subval) {
                        if ($va_date = caDateToHistoricTimestamps($vs_sort_subval)) {
                            // try to treat it as a date
                            if ($ps_sort_direction == 'DESC' && ($va_date[0] < $vs_subkey || is_null($vs_subkey))) {
                                $vs_subkey = $va_date[0];
                            } elseif ($va_date[0] > $vs_subkey || is_null($vs_subkey)) {
                                $vs_subkey = $va_date[0];
                            }
                        } else {
                            $vs_sort_subval = str_pad($vs_sort_subval, 20, ' ', STR_PAD_LEFT);
                            if ($ps_sort_direction == 'DESC' && ($vs_sort_subval < $vs_subkey || is_null($vs_subkey))) {
                                $vs_subkey = $vs_sort_subval;
                            } elseif ($vs_sort_subval > $vs_subkey || is_null($vs_subkey)) {
                                $vs_subkey = $vs_sort_subval;
                            }
                        }
                    }
                    $vs_key .= $vs_subkey;
                    $va_sorted_values_tmp[$vs_key][] = $va_values_by_field;
                }
            }
            ksort($va_sorted_values_tmp);
            foreach ($va_sorted_values_tmp as $vs_key => $va_value_list) {
                foreach ($va_value_list as $vn_x => $va_val) {
                    $va_sorted_values[$vs_key . $vn_x] = $va_val;
                }
            }
            if ($ps_sort_direction == 'DESC') {
                $va_sorted_values = array_reverse($va_sorted_values);
            }
            if (sizeof($va_sorted_values) > 0) {
                $va_tag_val_list[$vn_i] = $va_tags_list = $va_sorted_values;
            }
        }
        $va_acc = array();
        foreach ($va_tags_list as $vn_j => $va_tags) {
            $va_tag_list = array();
            $va_pt_vals = array();
            $vs_template = $va_proc_templates[$vn_i];
            // Process <if>
            foreach ($va_if as $va_def_con) {
                if (ExpressionParser::evaluate($va_def_con['rule'], $va_tags)) {
                    $vs_template = str_replace($va_def_con['directive'], $va_def_con['content'], $vs_template);
                } else {
                    $vs_template = str_replace($va_def_con['directive'], '', $vs_template);
                }
            }
            // Process <more> tags
            foreach ($va_mores as $vn_more_index => $va_more) {
                if (($vn_pos = strpos($vs_template, $va_more['directive'])) !== false) {
                    if (isset($va_mores[$vn_more_index + 1]) && ($vn_next_more_pos = strpos(substr($vs_template, $vn_pos + strlen($va_more['directive'])), $va_mores[$vn_more_index + 1]['directive'])) !== false) {
                        $vn_next_more_pos += $vn_pos;
                        $vs_partial_template = substr($vs_template, $vn_pos + strlen($va_more['directive']), $vn_next_more_pos - $vn_pos);
                    } else {
                        $vs_partial_template = substr($vs_template, $vn_pos + strlen($va_more['directive']));
                    }
                    $vb_output = false;
                    foreach (array_keys($va_defined_tag_list[$vn_i][$vn_j]) as $vs_defined_tag) {
                        if (strpos($vs_partial_template, $vs_defined_tag) !== false) {
                            // content is defined
                            $vb_output = true;
                            break;
                        }
                    }
                    if ($vb_output) {
                        $vs_template = preg_replace('!' . $va_more['directive'] . '!', $va_more['content'], $vs_template, 1);
                    } else {
                        $vs_template = preg_replace('!' . $va_more['directive'] . '!', '', $vs_template, 1);
                    }
                }
            }
            // Process <between> tags - text to be output if it is between two defined values
            $va_between_positions = array();
            foreach ($va_betweens as $vn_between_index => $va_between) {
                $vb_output_before = $vb_output_after = false;
                if (($vn_cur_pos = strpos($vs_template, $va_between['directive'])) !== false) {
                    $va_between_positions[$vn_between_index] = $vn_cur_pos;
                    // Get parts of template before tag and after tag
                    $vs_partial_template_before = substr($vs_template, 0, $vn_cur_pos);
                    $vs_partial_template_after = substr($vs_template, $vn_cur_pos + strlen($va_between['directive']));
                    // Only get the template between our current position and the next <between> tag
                    if (isset($va_betweens[$vn_between_index + 1]) && ($vn_after_pos_relative = strpos($vs_partial_template_after, $va_betweens[$vn_between_index + 1]['directive'])) !== false) {
                        $vs_partial_template_after = substr($vs_partial_template_after, 0, $vn_after_pos_relative);
                    }
                    // Check for defined value before and after tag
                    foreach (array_keys($va_defined_tag_list[$vn_i][$vn_j]) as $vs_defined_tag) {
                        if (strpos($vs_partial_template_before, $vs_defined_tag) !== false) {
                            // content is defined
                            $vb_output_after = true;
                        }
                        if (strpos($vs_partial_template_after, $vs_defined_tag) !== false) {
                            // content is defined
                            $vb_output_before = true;
                            break;
                        }
                        if ($vb_output_before && $vb_output_after) {
                            break;
                        }
                    }
                }
                if ($vb_output_before && $vb_output_after) {
                    $vs_template = preg_replace('!' . $va_between['directive'] . '!', $va_between['content'], $vs_template, 1);
                } else {
                    $vs_template = preg_replace('!' . $va_between['directive'] . '!', '', $vs_template, 1);
                }
            }
            //
            // Need to sort tags by length descending (longest first)
            // so that when we go to substitute and you have a tag followed by itself with a suffix
            // (ex. ^measurements and ^measurements2) we don't substitute both for the stub (ex. ^measurements)
            //
            $va_tags_tmp = array_keys($va_tags);
            usort($va_tags_tmp, function ($a, $b) {
                return strlen($b) - strlen($a);
            });
            $vs_pt = $vs_template;
            foreach ($va_tags_tmp as $vs_tag) {
                $vs_pt = str_replace('^' . $vs_tag, is_array($va_tags[$vs_tag]) ? join(" | ", $va_tags[$vs_tag]) : $va_tags[$vs_tag], $vs_pt);
            }
            if ($vs_pt) {
                $va_pt_vals[] = $vs_pt;
            }
            if ($vs_acc_val = join(isset($pa_options['delimiter']) ? $pa_options['delimiter'] : $vs_delimiter, $va_pt_vals)) {
                $va_acc[] = $vs_acc_val;
            }
        }
        $va_proc_templates[$vn_i] = join($vs_delimiter, $va_acc);
    }
    if ($pb_return_as_array && !caGetOption('includeBlankValuesInArray', $pa_options, false)) {
        foreach ($va_proc_templates as $vn_i => $vs_template) {
            if (!strlen(trim($vs_template))) {
                unset($va_proc_templates[$vn_i]);
            }
        }
    }
    // Transform links
    $va_proc_templates = caCreateLinksFromText($va_proc_templates, $ps_resolve_links_using, $ps_resolve_links_using != $ps_tablename ? $va_resolve_links_using_row_ids : $pa_row_ids, null, caGetOption('linkTarget', $pa_options, null), array_merge(array('addRelParameter' => true), $pa_options));
    // Kill any lingering tags (just in case)
    foreach ($va_proc_templates as $vn_i => $vs_proc_template) {
        $va_proc_templates[$vn_i] = preg_replace("!\\^([A-Za-z0-9_\\.]+[%]{1}[^ \\^\t\r\n\"\\'<>\\(\\)\\{\\}\\/\\[\\]]*|[A-Za-z0-9_\\.]+)!", "", $vs_proc_template);
        $va_proc_templates[$vn_i] = str_replace("<![CDATA[", "", $va_proc_templates[$vn_i]);
        $va_proc_templates[$vn_i] = str_replace("]]>", "", $va_proc_templates[$vn_i]);
    }
    if ($pb_return_as_array) {
        return $va_proc_templates;
    }
    return join($vs_delimiter, $va_proc_templates);
}
コード例 #30
0
<?php

$t_object = $this->getVar("item");
$vn_object_id = $t_object->get('ca_objects.object_id');
$va_comments = $this->getVar("comments");
$pn_rep_id = $this->getVar("representation_id");
$va_export_formats = $this->getVar('export_formats');
$vs_export_format_select = $this->getVar('export_format_select');
$t_set = new ca_sets();
$va_sets = caExtractValuesByUserLocale($t_set->getSetsForItem("ca_objects", $t_object->get("object_id"), array("user_id" => $this->request->user->get("user_id"))));
$va_lightbox_crumbs = array();
foreach ($va_sets as $vn_set_id => $va_set) {
    $va_lightbox_crumbs[] = caNavLink($this->request, _t("Lightbox"), "", "", "Sets", "Index") . " &#8594; " . caNavLink($this->request, $va_set["name"], "", "", "Sets", "SetDetail", array("set_id" => $vn_set_id)) . " &#8594; " . $t_object->get("ca_objects.preferred_labels.name");
}
$vs_lightbox_crumbs = "";
if (sizeof($va_lightbox_crumbs)) {
    $vs_lightbox_crumbs = join("<br/>", $va_lightbox_crumbs);
}
?>
<div class="row">
	<div class='col-xs-1 col-sm-1 col-md-1 col-lg-1'>
		<div class="detailNavBgLeft">
			{{{resultsLink}}}<div class='detailPrevLink'>{{{previousLink}}}</div>
		</div><!-- end detailNavBgLeft -->
	</div><!-- end col -->
	<div class='col-xs-10 col-sm-10 col-md-10 col-lg-10'>
	
	</div>
	<div class='col-xs-1 col-sm-1 col-md-1 col-lg-1'>
		<div class="detailNavBgRight">
			{{{nextLink}}}