/** * Run all the search queries set by the implementation and check if the number of hits fits! */ public function testSearchQueries() { if (!is_array($this->opa_search_queries)) { $this->assertTrue(false, 'no queries set up!'); } $o_search = caGetSearchInstance($this->ops_primary_table); foreach ($this->opa_search_queries as $vs_query => $vn_expected_num_results) { $o_result = $o_search->search($vs_query); $this->assertEquals($vn_expected_num_results, $o_result->numHits(), 'Must match the expected number of search results. Query was: ' . $vs_query); } }
public function testDelete() { $va_objects = array(); $this->assertGreaterThan(0, $va_objects[] = $this->addTestRecord('ca_objects', array('intrinsic_fields' => array('type_id' => 'dataset'), 'preferred_labels' => array(array("locale" => "en_US", "name" => "My test dataset"))))); $this->assertGreaterThan(0, $va_objects[] = $this->addTestRecord('ca_objects', array('intrinsic_fields' => array('type_id' => 'physical_object'), 'preferred_labels' => array(array("locale" => "en_US", "name" => "Test physical object"))))); foreach ($va_objects as $vn_object_id) { $t_object = new ca_objects($vn_object_id); $t_object->setMode(ACCESS_WRITE); $t_object->delete(true, array('hard' => true)); } $o_search = caGetSearchInstance('ca_objects'); $o_result = $o_search->search('dataset'); $this->assertEquals(0, $o_result->numHits(), 'dataset should not be indexed anymore'); $o_result = $o_search->search('physical'); $this->assertEquals(0, $o_result->numHits(), 'physical object should not be indexed anymore'); }
public function testGets() { $o_search = caGetSearchInstance('ca_objects'); $this->assertInstanceOf('SearchEngine', $o_search); $o_res = $o_search->search('*'); /** @var SearchResult $o_res */ $this->assertInstanceOf('SearchResult', $o_res); $this->assertEquals(10, $o_res->numHits()); //$o_res->disableGetWithTemplatePrefetch(); $i = 0; while ($o_res->nextHit()) { $vs_label = $o_res->getWithTemplate('^ca_objects.preferred_labels'); $this->assertGreaterThan(0, strlen($vs_label)); $this->assertRegExp("/{$i}\$/", $vs_label); $i++; } }
/** * */ protected function search($pa_bundles = null) { if (!($vo_search = caGetSearchInstance($this->getTableName()))) { $this->addError(_t("Invalid table")); return false; } $t_instance = $this->_getTableInstance($vs_table_name = $this->getTableName()); $va_return = array(); $vo_result = $vo_search->search($this->ops_query, array('deletedOnly' => $this->opb_deleted_only, 'sort' => $this->opo_request->getParameter('sort', pString))); $vs_template = $this->opo_request->getParameter('template', pString); // allow user-defined template to be passed; allows flexible formatting of returned label while ($vo_result->nextHit()) { $va_item = array(); $va_item[$t_instance->primaryKey()] = $vn_id = $vo_result->get($t_instance->primaryKey()); $va_item['id'] = $vn_id; if ($vs_idno = $vo_result->get("idno")) { $va_item["idno"] = $vs_idno; } if ($vs_template) { $va_item["display_label"] = caProcessTemplateForIDs($vs_template, $vs_table_name, array($vn_id), array('convertCodesToDisplayText' => true)); } else { if (is_array($va_display_labels = $vo_result->getDisplayLabels())) { $va_item["display_label"] = array_pop($va_display_labels); } } if (is_array($pa_bundles)) { foreach ($pa_bundles as $vs_bundle => $va_options) { if (!is_array($va_options)) { $va_options = array(); } if ($this->_isBadBundle($vs_bundle)) { continue; } $vm_return = $vo_result->get($vs_bundle, $va_options); // render 'empty' arrays as JSON objects, not as lists (which is the default behavior of json_encode) if (is_array($vm_return) && sizeof($vm_return) == 0) { $va_item[$vs_bundle] = new stdClass(); } else { $va_item[$vs_bundle] = $vm_return; } } } $va_return["results"][] = $va_item; } return $va_return; }
public function testGets() { $o_search = caGetSearchInstance('ca_objects'); $this->assertInstanceOf('SearchEngine', $o_search); $o_res = $o_search->search('*', array('sort' => 'ca_object_labels.name')); /** @var SearchResult $o_res */ $this->assertInstanceOf('SearchResult', $o_res); $this->assertEquals(10, $o_res->numHits()); SearchResult::clearGetWithTemplatePrefetch(); // old values may be cached from previous tests $i = 0; while ($o_res->nextHit()) { $vs_label = $o_res->getWithTemplate('^ca_objects.preferred_labels'); $this->assertGreaterThan(0, strlen($vs_label)); $this->assertRegExp("/{$i}\$/", $vs_label); $i++; } }
/** * Perform the browse using currently applied criteria, calculating the result set and browse facets * required for subsequent browse refinement. You need to call execute() after setting up your browse * criteria and options to: * • Get the result set reflecting the current browse state * • Fetch browse facets that reflect the current browse state * * @param array $pa_options Options include: * checkAccess = array of access values to filter facets that have an 'access' field by * noCache = don't use cached browse results * showDeleted = if set to true, related items that have been deleted are returned. Default is false. * limitToModifiedOn = if set returned results will be limited to rows modified within the specified date range. The value should be a date/time expression parse-able by TimeExpressionParser * user_id = If set item level access control is performed relative to specified user_id, otherwise defaults to logged in user * * @return bool True on success, null if the browse could not be executed (Eg. no settings), false no error */ public function execute($pa_options = null) { global $AUTH_CURRENT_USER_ID; if (!is_array($this->opa_browse_settings)) { return null; } if (!is_array($pa_options)) { $pa_options = array(); } $vn_user_id = caGetOption('user_id', $pa_options, $AUTH_CURRENT_USER_ID, array('castTo' => 'int')); $vb_no_cache = caGetOption('noCache', $pa_options, caGetOption('no_cache', $pa_options, false, array('castTo' => 'bool')), array('castTo' => 'bool')); $va_params = $this->opo_ca_browse_cache->getParameters(); $vb_need_to_cache_facets = false; $vb_results_cached = false; $vb_need_to_save_in_cache = false; $vs_cache_key = $this->opo_ca_browse_cache->getCurrentCacheKey(); if ($this->opo_ca_browse_cache->load($vs_cache_key)) { $vn_created_on = $this->opo_ca_browse_cache->getParameter('created_on'); //$t_new_browse->get('created_on', array('getDirectDate' => true)); $va_criteria = $this->getCriteria(); if (!$vb_no_cache && intval(time() - $vn_created_on) < $this->opo_ca_browse_config->get('cache_timeout')) { $vb_results_cached = true; $this->opo_ca_browse_cache->setParameter('created_on', time() + $this->opo_ca_browse_config->get('cache_timeout')); $vb_need_to_save_in_cache = true; Debug::msg("Cache hit for {$vs_cache_key}"); } else { $va_criteria = $this->getCriteria(); //$this->opo_ca_browse_cache->remove(); //$this->opo_ca_browse_cache->setParameter('criteria', $va_criteria); $vb_need_to_save_in_cache = true; $vb_need_to_cache_facets = true; Debug::msg("Cache expire for {$vs_cache_key}"); } } else { $va_criteria = $this->getCriteria(); $vb_need_to_save_in_cache = true; Debug::msg("Cache miss for {$vs_cache_key}"); } if (!$vb_results_cached) { $this->opo_ca_browse_cache->setParameter('sort', null); $this->opo_ca_browse_cache->setParameter('created_on', time()); $this->opo_ca_browse_cache->setParameter('table_num', $this->opn_browse_table_num); $vb_need_to_cache_facets = true; } $this->opb_criteria_have_changed = false; $t_item = $this->opo_datamodel->getInstanceByTableName($this->ops_browse_table_name, true); $va_results = array(); if (is_array($va_criteria) && sizeof($va_criteria) > 0) { if (!$vb_results_cached) { $va_acc = array(); $vn_i = 0; foreach ($va_criteria as $vs_facet_name => $va_row_ids) { $vs_target_browse_table_name = $t_item->tableName(); $vs_target_browse_table_num = $t_item->tableNum(); $vs_target_browse_table_pk = $t_item->primaryKey(); $va_facet_info = $this->getInfoForFacet($vs_facet_name); $va_row_ids = array_keys($va_row_ids); $vs_relative_to_join = ''; switch ($va_facet_info['type']) { # ----------------------------------------------------- case 'has': $vs_rel_table_name = $va_facet_info['table']; $va_joins = array(); if ($va_facet_info['relative_to']) { if ($va_relative_execute_sql_data = $this->_getRelativeExecuteSQLData($va_facet_info['relative_to'], $pa_options)) { $va_joins = array_merge($va_joins, $va_relative_execute_sql_data['relative_joins']); $vs_target_browse_table_name = $va_relative_execute_sql_data['target_table_name']; $vs_target_browse_table_num = $va_relative_execute_sql_data['target_table_num']; $vs_target_browse_table_pk = $va_relative_execute_sql_data['target_table_pk']; } } 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']; $vn_state = array_pop($va_row_ids); if ($vn_state == 0) { $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 { $va_joins[] = "INNER JOIN ca_attributes AS caa ON caa.row_id = " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . " AND caa.table_num = " . $t_item->tableNum(); $va_wheres[] = "caa.element_id = " . $t_element->getPrimaryKey(); } } else { 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_target_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); $vn_state = array_pop($va_row_ids); foreach ($va_path as $vs_join_table) { $va_rel_info = $this->opo_datamodel->getRelationships($vs_cur_table, $vs_join_table); $va_joins[] = ($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_wheres = array(); if (sizeof($va_restrict_to_relationship_types) > 0 && is_object($t_item_rel) && (bool) $vn_state) { $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) && (bool) $vn_state) { $va_wheres[] = "(" . $t_item_rel->tableName() . ".type_id NOT IN (" . join(',', $va_exclude_relationship_types) . "))"; } if (!(bool) $vn_state) { // 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() . "." . $t_rel_item->primaryKey() . " IS NULL) AND (" . $t_rel_item->tableName() . ".access IS NULL)))"; } } 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 ($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[] = "(" . $t_item->tableName() . ".access IN (" . join(',', $pa_options['checkAccess']) . "))"; } $vs_join_sql = join("\n", $va_joins); $vs_where_sql = ''; if (sizeof($va_wheres) > 0) { $vs_where_sql = ' WHERE ' . join(' AND ', $va_wheres); } if ($vn_i == 0) { $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\t\t\t\t\t"; $qr_res = $this->opo_db->query($vs_sql); } else { $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_where_sql}"; $qr_res = $this->opo_db->query($vs_sql); } $va_acc[$vn_i] = $qr_res->getAllFieldValues($this->ops_browse_table_name . '.' . $t_item->primaryKey()); $vn_i++; break; # ----------------------------------------------------- # ----------------------------------------------------- case 'label': if (!($t_label = $t_item->getLabelTableInstance())) { break; } $vs_label_item_pk = $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(); if ($va_facet_info['relative_to']) { if ($va_relative_execute_sql_data = $this->_getRelativeExecuteSQLData($va_facet_info['relative_to'], $pa_options)) { $vs_target_browse_table_name = $va_relative_execute_sql_data['target_table_name']; $vs_target_browse_table_num = $va_relative_execute_sql_data['target_table_num']; $vs_target_browse_table_pk = $va_relative_execute_sql_data['target_table_pk']; $t_target = $this->opo_datamodel->getInstanceByTableName($va_facet_info['relative_to'], true); $t_target_label = $t_target->getLabelTableInstance(); $vs_item_pk = $t_target->primaryKey(); $vs_label_table_name = $t_target_label->tableName(); $vs_label_item_pk = $t_target_label->primaryKey(); $va_relative_to_join = $va_relative_execute_sql_data['relative_joins']; $va_relative_to_join[] = "INNER JOIN {$vs_label_table_name} ON {$vs_label_table_name}.{$vs_label_item_pk} = {$vs_target_browse_table_name}.{$vs_target_browse_table_pk}"; } } else { $va_relative_to_join = array("INNER JOIN {$vs_label_table_name} ON {$vs_label_table_name}.{$vs_label_item_pk} = {$vs_target_browse_table_name}.{$vs_target_browse_table_pk}"); } $vs_relative_to_join = join("\n", $va_relative_to_join); $va_labels = $t_item->getPreferredDisplayLabelsForIDs($va_row_ids); foreach ($va_row_ids as $vn_row_id) { if ($vn_i == 0) { $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . "." . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t\t{$vs_label_table_name}.{$vs_label_display_field} = ?"; //print "$vs_sql [".intval($this->opn_browse_table_num)."]<hr>"; $qr_res = $this->opo_db->query($vs_sql, $va_labels[$vn_row_id]); } else { $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . "." . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t\t{$vs_label_table_name}.{$vs_label_display_field} = ?"; $qr_res = $this->opo_db->query($vs_sql, $va_labels[$vn_row_id]); } $va_acc[$vn_i] = $qr_res->getAllFieldValues($this->ops_browse_table_name . '.' . $t_item->primaryKey()); $vn_i++; } break; # ----------------------------------------------------- # ----------------------------------------------------- case 'field': $vs_field_name = $va_facet_info['field']; $vs_table_name = $this->ops_browse_table_name; if ($va_facet_info['relative_to']) { if ($va_relative_execute_sql_data = $this->_getRelativeExecuteSQLData($va_facet_info['relative_to'], $pa_options)) { $va_relative_to_join = $va_relative_execute_sql_data['relative_joins']; $vs_relative_to_join = join("\n", $va_relative_to_join); $vs_table_name = $vs_target_browse_table_name = $va_relative_execute_sql_data['target_table_name']; $vs_target_browse_table_num = $va_relative_execute_sql_data['target_table_num']; $vs_target_browse_table_pk = $va_relative_execute_sql_data['target_table_pk']; } } foreach ($va_row_ids as $vn_row_id) { $vn_row_id = urldecode(str_replace('/', '/', $vn_row_id)); if ($vn_i == 0) { $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t\t({$vs_table_name}.{$vs_field_name} = ?)"; $qr_res = $this->opo_db->query($vs_sql, (string) $vn_row_id); } else { $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t\t({$vs_table_name}.{$vs_field_name} = ?)"; $qr_res = $this->opo_db->query($vs_sql, (string) $vn_row_id); } $va_acc[$vn_i] = $qr_res->getAllFieldValues($this->ops_browse_table_name . '.' . $t_item->primaryKey()); $vn_i++; } break; # ----------------------------------------------------- # ----------------------------------------------------- case 'attribute': $t_element = new ca_metadata_elements(); if (!$t_element->load(array('element_code' => $va_facet_info['element_code']))) { return array(); } $vn_datatype = $t_element->get('datatype'); if ($va_facet_info['relative_to']) { if ($va_relative_execute_sql_data = $this->_getRelativeExecuteSQLData($va_facet_info['relative_to'], $pa_options)) { $va_relative_to_join = $va_relative_execute_sql_data['relative_joins']; $vs_relative_to_join = join("\n", $va_relative_to_join); $vs_target_browse_table_name = $va_relative_execute_sql_data['target_table_name']; $vs_target_browse_table_num = $va_relative_execute_sql_data['target_table_num']; $vs_target_browse_table_pk = $va_relative_execute_sql_data['target_table_pk']; } } // TODO: check that it is a *single-value* (ie. no hierarchical ca_metadata_elements) Text or Number attribute // (do we support other types as well?) $vn_element_id = $t_element->getPrimaryKey(); $o_attr = Attribute::getValueInstance($vn_datatype); foreach ($va_row_ids as $vn_row_id) { $vn_row_id = urldecode($vn_row_id); $vn_row_id = str_replace('/', '/', $vn_row_id); $va_value = $o_attr->parseValue($vn_row_id, $t_element->getFieldValuesArray()); $va_attr_sql = array(); $va_attr_values = array(intval($vs_target_browse_table_num), $vn_element_id); if (is_array($va_value)) { foreach ($va_value as $vs_f => $vs_v) { if ($vn_datatype == __CA_ATTRIBUTE_VALUE_LIST__) { if ($vs_f != 'item_id') { continue; } // Include sub-items $t_list_item = new ca_list_items(); $va_item_ids = $t_list_item->getHierarchy((int) $vs_v, array('idsOnly' => true, 'includeSelf' => true)); $va_item_ids[] = (int) $vs_v; $va_attr_sql[] = "(ca_attribute_values.{$vs_f} IN (?))"; $va_attr_values[] = $va_item_ids; } else { $va_attr_sql[] = "(ca_attribute_values.{$vs_f} " . (is_null($vs_v) ? " IS " : " = ") . " ?)"; $va_attr_values[] = $vs_v; } } } if ($vs_attr_sql = join(" AND ", $va_attr_sql)) { $vs_attr_sql = " AND " . $vs_attr_sql; } if ($vn_i == 0) { $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_attributes ON ca_attributes.row_id = {$vs_target_browse_table_name}.{$vs_target_browse_table_pk} AND ca_attributes.table_num = ?\n\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_attribute_values ON ca_attribute_values.attribute_id = ca_attributes.attribute_id\n\t\t\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t\t(ca_attribute_values.element_id = ?) {$vs_attr_sql}"; $qr_res = $this->opo_db->query($vs_sql, $va_attr_values); } else { $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_attributes ON ca_attributes.row_id = {$vs_target_browse_table_name}.{$vs_target_browse_table_pk} AND ca_attributes.table_num = ?\n\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_attribute_values ON ca_attribute_values.attribute_id = ca_attributes.attribute_id\n\t\t\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t\t(ca_attribute_values.element_id = ?) {$vs_attr_sql}"; $qr_res = $this->opo_db->query($vs_sql, $va_attr_values); } $va_acc[$vn_i] = $qr_res->getAllFieldValues($this->ops_browse_table_name . '.' . $t_item->primaryKey()); $vn_i++; } break; # ----------------------------------------------------- # ----------------------------------------------------- case 'normalizedDates': $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(); } // TODO: check that it is a *single-value* (ie. no hierarchical ca_metadata_elements) DateRange attribute $vs_normalization = $va_facet_info['normalization']; $o_tep = new TimeExpressionParser(); if ($va_facet_info['relative_to']) { if ($va_relative_execute_sql_data = $this->_getRelativeExecuteSQLData($va_facet_info['relative_to'], $pa_options)) { $va_relative_to_join = $va_relative_execute_sql_data['relative_joins']; $vs_relative_to_join = join("\n", $va_relative_to_join); $vs_target_browse_table_name = $va_relative_execute_sql_data['target_table_name']; $vs_target_browse_table_num = $va_relative_execute_sql_data['target_table_num']; $vs_target_browse_table_pk = $va_relative_execute_sql_data['target_table_pk']; } } $vn_element_id = $vb_is_element ? $t_element->getPrimaryKey() : null; $vs_browse_start_fld = $vs_browse_start_fld = null; if ($vb_is_field) { $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'); } foreach ($va_row_ids as $vn_row_id) { $vn_row_id = urldecode($vn_row_id); $va_dates = null; if ($vn_row_id !== 'null') { if (!$o_tep->parse($vn_row_id)) { continue; } // invalid date? $va_dates = $o_tep->getHistoricTimestamps(); } if ($vb_is_element) { if (is_null($va_dates)) { $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_attributes ON ca_attributes.row_id = " . $vs_target_browse_table_name . '.' . $vs_target_browse_table_pk . " AND ca_attributes.table_num = ?\n\t\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_attribute_values ON ca_attribute_values.attribute_id = ca_attributes.attribute_id\n\t\t\t\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t(ca_attribute_values.element_id = ?) \n\t\t\t\t\t\t\t\t\t\t\t\t\t\tAND\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t(ca_attribute_values.value_decimal1 IS NULL)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tAND \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t(ca_attribute_values.value_decimal2 IS NULL)\n\t\t\t\t\t\t\t\t\t\t\t\t"; $qr_res = $this->opo_db->query($vs_sql, intval($vs_target_browse_table_num), $vn_element_id); } else { $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_attributes ON ca_attributes.row_id = " . $vs_target_browse_table_name . '.' . $vs_target_browse_table_pk . " AND ca_attributes.table_num = ?\n\t\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_attribute_values ON ca_attribute_values.attribute_id = ca_attributes.attribute_id\n\t\t\t\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t(ca_attribute_values.element_id = ?) AND\n\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(\n\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(ca_attribute_values.value_decimal1 <= ?) AND\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(ca_attribute_values.value_decimal2 >= ?)\n\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\tOR\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(ca_attribute_values.value_decimal1 BETWEEN ? AND ?)\n\t\t\t\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\t\t\t(ca_attribute_values.value_decimal2 BETWEEN ? AND ?)\n\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"; $qr_res = $this->opo_db->query($vs_sql, intval($vs_target_browse_table_num), $vn_element_id, $va_dates['start'], $va_dates['end'], $va_dates['start'], $va_dates['end'], $va_dates['start'], $va_dates['end']); } } else { // is intrinsic if (is_null($va_dates)) { $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t({$this->ops_browse_table_name}.{$vs_browse_start_fld} IS NULL)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tAND \n\t\t\t\t\t\t\t\t\t\t\t\t\t\t({$this->ops_browse_table_name}.{$vs_browse_end_fld} IS NULL)\n\t\t\t\t\t\t\t\t\t\t\t\t"; $qr_res = $this->opo_db->query($vs_sql); } else { $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\t\t\tWHERE\n\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(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t({$this->ops_browse_table_name}.{$vs_browse_start_fld} <= ?) AND\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t({$this->ops_browse_table_name}.{$vs_browse_end_fld} >= ?)\n\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\tOR\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t({$this->ops_browse_table_name}.{$vs_browse_start_fld} BETWEEN ? AND ?)\n\t\t\t\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\t\t\t({$this->ops_browse_table_name}.{$vs_browse_end_fld} BETWEEN ? AND ?)\n\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"; $qr_res = $this->opo_db->query($vs_sql, $va_dates['start'], $va_dates['end'], $va_dates['start'], $va_dates['end'], $va_dates['start'], $va_dates['end']); } } $va_acc[$vn_i] = $qr_res->getAllFieldValues($this->ops_browse_table_name . '.' . $t_item->primaryKey()); $vn_i++; } break; # ----------------------------------------------------- # ----------------------------------------------------- case 'normalizedLength': $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(); } // TODO: check that it is a *single-value* (ie. no hierarchical ca_metadata_elements) DateRange attribute $vs_normalization = $va_facet_info['normalization']; $o_tep = new TimeExpressionParser(); if ($va_facet_info['relative_to']) { if ($va_relative_execute_sql_data = $this->_getRelativeExecuteSQLData($va_facet_info['relative_to'], $pa_options)) { $va_relative_to_join = $va_relative_execute_sql_data['relative_joins']; $vs_relative_to_join = join("\n", $va_relative_to_join); $vs_target_browse_table_name = $va_relative_execute_sql_data['target_table_name']; $vs_target_browse_table_num = $va_relative_execute_sql_data['target_table_num']; $vs_target_browse_table_pk = $va_relative_execute_sql_data['target_table_pk']; } } $vn_element_id = $vb_is_element ? $t_element->getPrimaryKey() : null; $vs_browse_start_fld = $vs_browse_start_fld = null; if ($vb_is_field) { $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'); } 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'); foreach ($va_row_ids as $vn_row_id) { $vn_start = urldecode($vn_row_id); // is start dimension // calculate end dimension $vn_end = $vn_start + $vn_increment_in_current_units; // convert to meters $vo_start = new Zend_Measure_Length($vn_start, $vs_output_units, 'en_US'); $vo_end = new Zend_Measure_Length($vn_end, $vs_output_units, 'en_US'); $vn_start_in_meters = (double) $vo_start->convertTo(Zend_Measure_Length::METER, 6, 'en_US'); $vn_end_in_meters = (double) $vo_end->convertTo(Zend_Measure_Length::METER, 6, 'en_US'); $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_attributes ON ca_attributes.row_id = " . $vs_target_browse_table_name . '.' . $vs_target_browse_table_pk . " AND ca_attributes.table_num = ?\n\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_attribute_values ON ca_attribute_values.attribute_id = ca_attributes.attribute_id\n\t\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t(ca_attribute_values.element_id = ?) AND\n\t\t\t\t\t\t\t\t\t\t\t\t(ca_attribute_values.value_decimal1 BETWEEN ? AND ?)\n\t\t\t\t\t\t\t\t\t\t"; $qr_res = $this->opo_db->query($vs_sql, intval($vs_target_browse_table_num), $vn_element_id, $vn_start_in_meters, $vn_end_in_meters); $va_acc[$vn_i] = $qr_res->getAllFieldValues($this->ops_browse_table_name . '.' . $t_item->primaryKey()); $vn_i++; } break; # ----------------------------------------------------- # ----------------------------------------------------- case 'authority': $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); if ($va_facet_info['relative_to']) { if ($va_relative_execute_sql_data = $this->_getRelativeExecuteSQLData($va_facet_info['relative_to'], $pa_options)) { $va_relative_to_join = $va_relative_execute_sql_data['relative_joins']; $vs_relative_to_join = join("\n", $va_relative_to_join); $vs_target_browse_table_name = $va_relative_execute_sql_data['target_table_name']; $vs_target_browse_table_num = $va_relative_execute_sql_data['target_table_num']; $vs_target_browse_table_pk = $va_relative_execute_sql_data['target_table_pk']; } } foreach ($va_row_ids as $vn_row_id) { switch (sizeof($va_path = array_keys($this->opo_datamodel->getPath($vs_target_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 = array(); 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; } $vs_join_sql = join("\n", $va_joins); $va_wheres = array(); 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) . "))"; } $vs_where_sql = ''; if (sizeof($va_wheres) > 0) { $vs_where_sql = ' AND ' . join(' AND ', $va_wheres); } if ((!isset($va_facet_info['dont_expand_hierarchically']) || !$va_facet_info['dont_expand_hierarchically']) && $t_rel_item->isHierarchical() && $t_rel_item->load((int) $vn_row_id)) { $vs_hier_left_fld = $t_rel_item->getProperty('HIERARCHY_LEFT_INDEX_FLD'); $vs_hier_right_fld = $t_rel_item->getProperty('HIERARCHY_RIGHT_INDEX_FLD'); $vs_get_item_sql = "{$vs_rel_table_name}.{$vs_hier_left_fld} >= " . $t_rel_item->get($vs_hier_left_fld) . " AND {$vs_rel_table_name}.{$vs_hier_right_fld} <= " . $t_rel_item->get($vs_hier_right_fld); if ($vn_hier_id_fld = $t_rel_item->getProperty('HIERARCHY_ID_FLD')) { $vs_get_item_sql .= " AND {$vs_rel_table_name}.{$vn_hier_id_fld} = " . (int) $t_rel_item->get($vn_hier_id_fld); } $vs_get_item_sql = "({$vs_get_item_sql})"; } else { $vs_get_item_sql = "({$vs_rel_table_name}.{$vs_rel_table_pk} = " . (int) $vn_row_id . ")"; } if ($vn_i == 0) { $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t\t{$vs_get_item_sql}\n\t\t\t\t\t\t\t\t\t\t\t\t\t{$vs_where_sql}"; $qr_res = $this->opo_db->query($vs_sql); } else { $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t\t{$vs_get_item_sql}\n\t\t\t\t\t\t\t\t\t\t\t\t\t{$vs_where_sql}"; $qr_res = $this->opo_db->query($vs_sql); } $va_acc[$vn_i] = $qr_res->getAllFieldValues($this->ops_browse_table_name . '.' . $t_item->primaryKey()); $vn_i++; } break; # ----------------------------------------------------- # ----------------------------------------------------- case 'location': foreach ($va_row_ids as $vn_row_id) { $vn_row_id = urldecode($vn_row_id); $va_row_tmp = explode(":", $vn_row_id); if ($vn_i == 0) { $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t\t({$this->ops_browse_table_name}.current_loc_class = ?)" . (sizeof($va_row_tmp) > 1 ? " AND ({$this->ops_browse_table_name}.current_loc_subclass = ?)" : "") . (sizeof($va_row_tmp) > 2 ? " AND ({$this->ops_browse_table_name}.current_loc_id = ?)" : ""); $qr_res = $this->opo_db->query($vs_sql, $va_row_tmp); } else { $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t\t({$this->ops_browse_table_name}.current_loc_class = ?)" . (sizeof($va_row_tmp) > 1 ? " AND ({$this->ops_browse_table_name}.current_loc_subclass = ?)" : "") . (sizeof($va_row_tmp) > 2 ? " AND ({$this->ops_browse_table_name}.current_loc_id = ?)" : ""); $qr_res = $this->opo_db->query($vs_sql, $va_row_tmp); } $va_acc[$vn_i] = $qr_res->getAllFieldValues($this->ops_browse_table_name . '.' . $t_item->primaryKey()); $vn_i++; } break; # ----------------------------------------------------- # ----------------------------------------------------- case 'fieldList': $vs_field_name = $va_facet_info['field']; $vs_table_name = $this->ops_browse_table_name; if ($va_facet_info['relative_to']) { if ($va_relative_execute_sql_data = $this->_getRelativeExecuteSQLData($va_facet_info['relative_to'], $pa_options)) { $va_relative_to_join = $va_relative_execute_sql_data['relative_joins']; $vs_relative_to_join = join("\n", $va_relative_to_join); $vs_table_name = $vs_target_browse_table_name = $va_relative_execute_sql_data['target_table_name']; $vs_target_browse_table_num = $va_relative_execute_sql_data['target_table_num']; $vs_target_browse_table_pk = $va_relative_execute_sql_data['target_table_pk']; } } foreach ($va_row_ids as $vn_row_id) { $vn_row_id = urldecode($vn_row_id); if ($vn_i == 0) { $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t\t({$vs_table_name}.{$vs_field_name} = ?)"; $qr_res = $this->opo_db->query($vs_sql, $vn_row_id); } else { $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t\t({$vs_table_name}.{$vs_field_name} = ?)"; $qr_res = $this->opo_db->query($vs_sql, $vn_row_id); } $va_acc[$vn_i] = $qr_res->getAllFieldValues($this->ops_browse_table_name . '.' . $t_item->primaryKey()); $vn_i++; } break; # ----------------------------------------------------- # ----------------------------------------------------- case 'violations': $vs_field_name = $va_facet_info['field']; $vs_table_name = $this->ops_browse_table_name; if ($va_facet_info['relative_to']) { if ($va_relative_execute_sql_data = $this->_getRelativeExecuteSQLData($va_facet_info['relative_to'], $pa_options)) { $va_relative_to_join = $va_relative_execute_sql_data['relative_joins']; $vs_relative_to_join = join("\n", $va_relative_to_join); $vs_table_name = $vs_target_browse_table_name = $va_relative_execute_sql_data['target_table_name']; $vs_target_browse_table_num = $va_relative_execute_sql_data['target_table_num']; $vs_target_browse_table_pk = $va_relative_execute_sql_data['target_table_pk']; } } foreach ($va_row_ids as $vn_row_id) { $vn_row_id = urldecode($vn_row_id); if ($vn_i == 0) { $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_metadata_dictionary_rule_violations ON ca_metadata_dictionary_rule_violations.row_id = " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . " AND ca_metadata_dictionary_rule_violations.table_num = " . $t_item->tableNum() . "\n\t\t\t\t\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\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t(ca_metadata_dictionary_rules.rule_code = ?)"; $qr_res = $this->opo_db->query($vs_sql, $vn_row_id); } else { $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_metadata_dictionary_rule_violations ON ca_metadata_dictionary_rule_violations.row_id = " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . " AND ca_metadata_dictionary_rule_violations.table_num = " . $t_item->tableNum() . "\n\t\t\t\t\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\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t(ca_metadata_dictionary_rules.rule_code = ?)"; $qr_res = $this->opo_db->query($vs_sql, $vn_row_id); } $va_acc[$vn_i] = $qr_res->getAllFieldValues($this->ops_browse_table_name . '.' . $t_item->primaryKey()); $vn_i++; } break; # ----------------------------------------------------- # ----------------------------------------------------- case 'checkouts': $vs_field_name = $va_facet_info['field']; $vs_table_name = $this->ops_browse_table_name; if ($va_facet_info['relative_to']) { if ($va_relative_execute_sql_data = $this->_getRelativeExecuteSQLData($va_facet_info['relative_to'], $pa_options)) { $va_relative_to_join = $va_relative_execute_sql_data['relative_joins']; $vs_relative_to_join = join("\n", $va_relative_to_join); $vs_table_name = $vs_target_browse_table_name = $va_relative_execute_sql_data['target_table_name']; $vs_target_browse_table_num = $va_relative_execute_sql_data['target_table_num']; $vs_target_browse_table_pk = $va_relative_execute_sql_data['target_table_pk']; } } $vs_where = null; $vn_current_time = time(); foreach ($va_row_ids as $vn_row_id) { $vs_checkout_join_sql = "INNER JOIN ca_object_checkouts ON ca_object_checkouts.object_id = ca_objects.object_id"; $vs_status_code = isset($va_facet_info['status']) && $va_facet_info['status'] ? $va_facet_info['status'] : $vn_row_id; switch ($vs_status_code) { 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_checkout_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; case 'all': $vs_where = "(ca_object_checkouts.checkout_date <= {$vn_current_time})"; break; default: case 'out': $vs_where = "((ca_object_checkouts.checkout_date <= {$vn_current_time}) AND (ca_object_checkouts.return_date IS NULL))"; break; } $vs_sql = "\n\t\t\t\t\t\t\t\t\t\tSELECT ca_objects.object_id\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_checkout_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"; $vs_user_sql = null; $va_params = array(); switch ($va_facet_info['mode']) { case 'user': foreach ($va_row_ids as $vn_index => $vn_row_id) { $va_row_ids[$vn_index] = (int) $vn_row_id; } $va_params[] = $va_row_ids; $vs_user_sql .= " AND (ca_object_checkouts.user_id IN (?))"; break; case 'all': default: // noop break; } $qr_res = $this->opo_db->query($vs_sql . $vs_user_sql, $va_params); $va_acc[$vn_i] = $qr_res->getAllFieldValues('ca_objects.object_id'); $vn_i++; } break; # ----------------------------------------------------- # ----------------------------------------------------- default: // handle "search" criteria - search engine queries that can be browsed if ($vs_facet_name === '_search') { if (!($o_search = caGetSearchInstance($this->ops_browse_table_name))) { $this->postError(2900, _t("Invalid search type"), "BrowseEngine->execute()"); break; } $vs_pk = $t_item->primaryKey(); if (is_array($va_type_ids = $this->getTypeRestrictionList()) && sizeof($va_type_ids)) { $o_search->setTypeRestrictions($va_type_ids); } if (is_array($va_source_ids = $this->getSourceRestrictionList()) && sizeof($va_source_ids)) { $o_search->setSourceRestrictions($va_source_ids); } $va_options = $pa_options; unset($va_options['sort']); // browse engine takes care of sort so there is no reason to waste time having the search engine do so $va_options['filterNonPrimaryRepresentations'] = true; // filter out non-primary representations in ca_objects results to save (a bit) of time $o_search->setOption('strictPhraseSearching', caGetOption('strictPhraseSearching', $va_options, true)); $qr_res = $o_search->search($va_row_ids[0], $va_options); if ($qr_res->numHits() > 0) { $va_acc[$vn_i] = $qr_res->getPrimaryKeyValues(); } $vn_i++; } else { $this->postError(2900, _t("Invalid criteria type"), "BrowseEngine->execute()"); } break; # ----------------------------------------------------- } } foreach ($va_acc as $vn_i => $va_hits) { $va_acc[$vn_i] = array_flip($va_hits); } $vn_smallest_list_index = null; foreach ($va_acc as $vn_i => $va_hits) { if (is_null($vn_smallest_list_index)) { $vn_smallest_list_index = $vn_i; continue; } if (sizeof($va_hits) < sizeof($va_acc[$vn_smallest_list_index])) { $vn_smallest_list_index = $vn_i; } } $va_res = array(); $va_acc_indices = array_keys($va_acc); if (is_array($va_acc[$vn_smallest_list_index])) { foreach ($va_acc[$vn_smallest_list_index] as $vn_row_id => $vb_dummy) { foreach ($va_acc_indices as $vn_i) { if ($vn_i == $vn_smallest_list_index) { continue; } if (!isset($va_acc[$vn_i][$vn_row_id])) { continue 2; } } $va_res[$vn_row_id] = true; } } if (sizeof($va_res)) { $vs_filter_join_sql = $vs_filter_where_sql = ''; $va_wheres = array(); $va_joins = array(); $vs_sql_distinct = ''; if (sizeof($this->opa_result_filters)) { $va_tmp = array(); foreach ($this->opa_result_filters as $va_filter) { $vm_val = $this->_filterValueToQueryValue($va_filter); $va_wheres[] = $this->ops_browse_table_name . '.' . $va_filter['field'] . " " . $va_filter['operator'] . " " . $vm_val; } } if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_item->hasField('access')) { $va_wheres[] = "(" . $this->ops_browse_table_name . ".access IN (" . join(',', $pa_options['checkAccess']) . "))"; } if ((!isset($pa_options['showDeleted']) || !$pa_options['showDeleted']) && $t_item->hasField('deleted')) { $va_wheres[] = "(" . $this->ops_browse_table_name . ".deleted = 0)"; } if (isset($pa_options['limitToModifiedOn']) && $pa_options['limitToModifiedOn']) { $o_tep = new TimeExpressionParser(); if ($o_tep->parse($pa_options['limitToModifiedOn'])) { $va_range = $o_tep->getUnixTimestamps(); $va_joins['ca_change_log_subjects'] = "INNER JOIN ca_change_log_subjects ON ca_change_log_subjects.subject_row_id = " . $this->ops_browse_table_name . "." . $t_item->primaryKey() . " AND ca_change_log_subjects.subject_table_num = " . $t_item->tableNum(); $va_joins['ca_change_log'] = "INNER JOIN ca_change_log ON ca_change_log.log_id = ca_change_log_subjects.log_id"; $va_wheres[] = "(((ca_change_log.log_datetime BETWEEN " . (int) $va_range['start'] . " AND " . (int) $va_range['end'] . ") AND (ca_change_log.changetype IN ('I', 'U', 'D'))))"; $vs_sql_distinct = 'DISTINCT'; // need to pull distinct rows since joining the change log can cause dupes } } if (($va_browse_type_ids = $this->getTypeRestrictionList()) && sizeof($va_browse_type_ids)) { $t_subject = $this->getSubjectInstance(); $va_wheres[] = '(' . $this->ops_browse_table_name . '.' . $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_browse_source_ids) && sizeof($va_browse_source_ids)) { $va_wheres[] = '(' . $this->ops_browse_table_name . '.' . $t_subject->getSourceFieldName() . ' IN (' . join(', ', $va_browse_source_ids) . ') OR (' . $this->ops_browse_table_name . '.' . $t_subject->getSourceFieldName() . ' IS NULL))'; } $vs_filter_where_sql = "WHERE (" . $this->ops_browse_table_name . "." . $t_item->primaryKey() . " IN (?)) "; if (sizeof($va_wheres)) { $vs_filter_where_sql .= ' AND (' . join(' AND ', $va_wheres) . ')'; } if (sizeof($va_joins)) { $vs_filter_join_sql = join("\n", $va_joins); } $qr_res = $this->opo_db->query("\n\t\t\t\t\t\t\tSELECT {$vs_sql_distinct} " . $this->ops_browse_table_name . "." . $t_item->primaryKey() . "\n\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t{$vs_filter_join_sql}\n\t\t\t\t\t\t\t{$vs_filter_where_sql}\n\t\t\t\t\t\t", array(array_keys($va_res))); $va_results = $qr_res->getAllFieldValues($t_item->primaryKey()); if ((!isset($pa_options['dontFilterByACL']) || !$pa_options['dontFilterByACL']) && $this->opo_config->get('perform_item_level_access_checking') && method_exists($t_item, "supportsACL") && $t_item->supportsACL()) { $va_results = $this->filterHitsByACL($va_results, $this->opn_browse_table_num, $vn_user_id, __CA_ACL_READONLY_ACCESS__); } $this->opo_ca_browse_cache->setResults($va_results); $vb_need_to_save_in_cache = true; } else { // No results for some reason - we're here because we don't want to throw a SQL error $this->opo_ca_browse_cache->setResults($va_results = array()); $vb_need_to_save_in_cache = true; } } } else { // no criteria - don't try to find anything unless configured to do so $va_settings = $this->opo_ca_browse_config->getAssoc($this->ops_browse_table_name); if (isset($va_settings['show_all_for_no_criteria_browse']) && $va_settings['show_all_for_no_criteria_browse'] || isset($pa_options['showAllForNoCriteriaBrowse']) && $pa_options['showAllForNoCriteriaBrowse']) { $va_wheres = $va_joins = array(); $vs_pk = $t_item->primaryKey(); if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_item->hasField('access')) { $va_wheres[] = "(" . $this->ops_browse_table_name . ".access IN (" . join(',', $pa_options['checkAccess']) . "))"; } if ((!isset($pa_options['showDeleted']) || !$pa_options['showDeleted']) && $t_item->hasField('deleted')) { $va_wheres[] = "(" . $this->ops_browse_table_name . ".deleted = 0)"; } if (isset($pa_options['limitToModifiedOn']) && $pa_options['limitToModifiedOn']) { $o_tep = new TimeExpressionParser(); if ($o_tep->parse($pa_options['limitToModifiedOn'])) { $va_range = $o_tep->getUnixTimestamps(); $va_joins['ca_change_log_subjects'] = "INNER JOIN ca_change_log_subjects ON ca_change_log_subjects.subject_row_id = " . $this->ops_browse_table_name . ".{$vs_pk} AND ca_change_log_subjects.subject_table_num = " . $t_item->tableNum(); $va_joins['ca_change_log'] = "INNER JOIN ca_change_log ON ca_change_log.log_id = ca_change_log_subjects.log_id"; $va_wheres[] = "(((ca_change_log.log_datetime BETWEEN " . (int) $va_range['start'] . " AND " . (int) $va_range['end'] . ") AND (ca_change_log.changetype IN ('I', 'U', 'D'))))"; $vs_sql_distinct = 'DISTINCT'; // need to pull distinct rows since joining the change log can cause dupes } } $va_browse_type_ids = $this->getTypeRestrictionList(); $va_browse_source_ids = $this->getSourceRestrictionList(); if (is_array($va_browse_type_ids) && sizeof($va_browse_type_ids) || is_array($va_browse_source_ids) && sizeof($va_browse_source_ids)) { $t_subject = $this->getSubjectInstance(); if (is_array($va_browse_type_ids) && sizeof($va_browse_type_ids)) { $va_wheres[] = '(' . $this->ops_browse_table_name . '.' . $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_browse_source_ids) && sizeof($va_browse_source_ids)) { $va_wheres[] = '(' . $this->ops_browse_table_name . '.' . $t_subject->getSourceFieldName() . ' IN (' . join(', ', $va_browse_source_ids) . ') OR (' . $this->ops_browse_table_name . '.' . $t_subject->getSourceFieldName() . ' IS NULL))'; } } if (sizeof($va_wheres)) { $vs_filter_where_sql = 'WHERE ' . join(' AND ', $va_wheres); } if (sizeof($va_joins)) { $vs_filter_join_sql = join("\n", $va_joins); } $qr_res = $this->opo_db->query("\n\t\t\t\t\t\tSELECT {$vs_pk}\n\t\t\t\t\t\tFROM " . $t_item->tableName() . "\n\t\t\t\t\t\t{$vs_filter_join_sql}\n\t\t\t\t\t\t{$vs_filter_where_sql}\n\t\t\t\t\t\tORDER BY\n\t\t\t\t\t\t\t{$vs_pk}\n\t\t\t\t\t"); $va_results = $qr_res->getAllFieldValues($vs_pk); if ((!isset($pa_options['dontFilterByACL']) || !$pa_options['dontFilterByACL']) && $this->opo_config->get('perform_item_level_access_checking') && method_exists($t_item, "supportsACL") && $t_item->supportsACL()) { $va_results = array_keys($this->filterHitsByACL($va_results, $this->opn_browse_table_num, $vn_user_id, __CA_ACL_READONLY_ACCESS__)); } $this->opo_ca_browse_cache->setResults($va_results); } else { $this->opo_ca_browse_cache->setResults(array()); } $vb_need_to_save_in_cache = true; } if ($vb_need_to_cache_facets && !$pa_options['dontCheckFacetAvailability']) { $this->loadFacetContent($pa_options); } if ($vb_need_to_save_in_cache) { $this->opo_ca_browse_cache->save(); } return true; }
/** * Perform search * @param array|null $pa_bundles list of bundles to return for search result * @return array|bool */ protected function search($pa_bundles = null) { if (!($vo_search = caGetSearchInstance($this->getTableName()))) { $this->addError(_t("Invalid table")); return false; } $t_instance = $this->_getTableInstance($vs_table_name = $this->getTableName()); $va_return = array(); $vo_result = $vo_search->search($this->ops_query, array('deletedOnly' => $this->opb_deleted_only, 'sort' => $this->opo_request->getParameter('sort', pString), 'sortDirection' => $this->opo_request->getParameter('sortDirection', pString), 'start' => $this->opo_request->getParameter('start', pInteger), 'limit' => $this->opo_request->getParameter('limit', pInteger))); $vs_template = $this->opo_request->getParameter('template', pString); // allow user-defined template to be passed; allows flexible formatting of returned label while ($vo_result->nextHit()) { $va_item = array(); $va_item[$t_instance->primaryKey()] = $vn_id = $vo_result->get($t_instance->primaryKey()); $va_item['id'] = $vn_id; if ($vs_idno = $vo_result->get("idno")) { $va_item["idno"] = $vs_idno; } if ($vs_template) { $va_item["display_label"] = caProcessTemplateForIDs($vs_template, $vs_table_name, array($vn_id), array('convertCodesToDisplayText' => true)); } else { $va_item["display_label"] = $vo_result->get($vs_table_name . '.preferred_labels'); } if (is_array($pa_bundles)) { foreach ($pa_bundles as $vs_bundle => $va_options) { if (!is_array($va_options)) { $va_options = array(); } if ($this->_isBadBundle($vs_bundle)) { continue; } // special treatment for ca_object_representations.media bundle // it should provide a means to get the media info array if (trim($vs_bundle) == 'ca_object_representations.media') { if ($t_instance instanceof RepresentableBaseModel) { $va_reps = $vo_result->getMediaInfo($vs_bundle); if (is_array($va_reps) && sizeof($va_reps) > 0) { $va_item[$vs_bundle] = $va_reps; continue; } } } $vm_return = $vo_result->get($vs_bundle, $va_options); // render 'empty' arrays as JSON objects, not as lists (which is the default behavior of json_encode) if (is_array($vm_return) && sizeof($vm_return) == 0) { $va_item[$vs_bundle] = new stdClass(); } else { $va_item[$vs_bundle] = $vm_return; } } } $va_return["results"][] = $va_item; } return $va_return; }
/** * @param array $pa_config * @param RequestHTTP $po_request * @return array * @throws Exception */ private static function runSearchEndpoint($pa_config, $po_request) { $o_dm = Datamodel::load(); // load blank instance $t_instance = $o_dm->getInstance($pa_config['table']); if (!$t_instance instanceof BundlableLabelableBaseModelWithAttributes) { throw new Exception('invalid table'); } if (!($ps_q = $po_request->getParameter('q', pString))) { throw new Exception('No query specified'); } $o_search = caGetSearchInstance($pa_config['table']); // restrictToTypes if ($pa_config['restrictToTypes'] && is_array($pa_config['restrictToTypes']) && sizeof($pa_config['restrictToTypes']) > 0) { $va_type_filter = array(); foreach ($pa_config['restrictToTypes'] as $vs_type_code) { $va_type_filter[] = caGetListItemID($t_instance->getTypeListCode(), $vs_type_code); } $o_search->addResultFilter($t_instance->tableName() . '.type_id', 'IN', join(",", $va_type_filter)); } $o_res = $o_search->search($ps_q, array('sort' => $po_request->getParameter('sort', pString), 'sortDirection' => $po_request->getParameter('sortDirection', pString), 'start' => $po_request->getParameter('start', pInteger), 'limit' => $po_request->getParameter('limit', pInteger), 'checkAccess' => $pa_config['checkAccess'])); $va_return = array(); while ($o_res->nextHit()) { $va_hit = array(); foreach ($pa_config['content'] as $vs_key => $vs_template) { $va_hit[self::sanitizeKey($vs_key)] = $o_res->getWithTemplate($vs_template); } $va_return[$o_res->get($t_instance->primaryKey(true))] = $va_hit; } return $va_return; }
* the terms of the provided license as published by Whirl-i-Gig * * CollectiveAccess is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTIES whatsoever, including any implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * This source code is free and modifiable under the terms of * GNU General Public License. (http://www.gnu.org/copyleft/gpl.html). See * the "license.txt" file for details, or visit the CollectiveAccess web site at * http://www.CollectiveAccess.org * * ---------------------------------------------------------------------- */ $t_subject = $this->getVar('t_subject'); $vs_search = $this->getVar('search'); ?> <div id="resultBox"> <div class="subTitle"><?php print $this->getVar('search') ? _t("Your search found no %1", $this->getVar('mode_type_plural')) : _t("Please enter a search"); $o_search = caGetSearchInstance($t_subject->tableNum()); if (sizeof($va_suggestions = $o_search->suggest($vs_search, array('returnAsLink' => true, 'request' => $this->request)))) { if (sizeof($va_suggestions) > 1) { print "<div class='searchSuggestion'>" . _t("Did you mean one of these: %1 ?", join(', ', $va_suggestions)) . "</div>"; } else { print "<div class='searchSuggestion'>" . _t("Did you mean %1 ?", join(', ', $va_suggestions)) . "</div>"; } } ?> </div> </div><!-- end resultbox -->
/** * Export a record set as defined by the given search expression and the table_num for this exporter. * This function wraps the record-level exports using the settings 'wrap_before' and 'wrap_after' if they are set. * @param string $ps_exporter_code defines the exporter to use * @param string $ps_expression A valid search expression * @param string $ps_filename Destination filename (we can't keep everything in memory here) * @param array $pa_options * showCLIProgressBar = Show command-line progress bar. Default is false. * logDirectory = path to directory where logs should be written * logLevel = KLogger constant for minimum log level to record. Default is KLogger::INFO. Constants are, in descending order of shrillness: * KLogger::EMERG = Emergency messages (system is unusable) * KLogger::ALERT = Alert messages (action must be taken immediately) * KLogger::CRIT = Critical conditions * KLogger::ERR = Error conditions * KLogger::WARN = Warnings * KLogger::NOTICE = Notices (normal but significant conditions) * KLogger::INFO = Informational messages * KLogger::DEBUG = Debugging messages * @return boolean success state */ public static function exportRecordsFromSearchExpression($ps_exporter_code, $ps_expression, $ps_filename, $pa_options = array()) { ca_data_exporters::$s_exporter_cache = array(); ca_data_exporters::$s_exporter_item_cache = array(); if (!($t_mapping = ca_data_exporters::loadExporterByCode($ps_exporter_code))) { return false; } $o_search = caGetSearchInstance($t_mapping->get('table_num')); $o_result = $o_search->search($ps_expression); return self::exportRecordsFromSearchResult($ps_exporter_code, $o_result, $ps_filename, $pa_options); }
/** * Responds to the two main List verbs, includes resumption and limiting. * * @param string $verb OAI-PMH verb for the request * @param string $metadataPrefix Metadata prefix * @param int $cursor Offset in response to begin output at * @param mixed $set Optional set argument * @param string $from Optional from date argument * @param string $until Optional until date argument * @uses createResumptionToken() */ private function listResponse($oaiData, $verb, $metadataPrefix, $cursor, $set, $from, $until) { $listLimit = $this->_listLimit; $o_dm = Datamodel::load(); // by this point, the mapping code was checked to be valid $t_instance = $o_dm->getInstanceByTableName($this->table, true); $vs_pk = $t_instance->primaryKey(); $va_access_values = caGetUserAccessValues($this->opo_request, $this->opa_provider_info); $vb_show_deleted = (bool) $this->opa_provider_info['show_deleted']; $vb_dont_enforce_access_settings = (bool) $this->opa_provider_info['dont_enforce_access_settings']; $vb_dont_cache = (bool) $this->opa_provider_info['dont_cache']; $vs_table = $t_instance->tableName(); if (!($o_search = caGetSearchInstance($vs_table))) { $this->throwError(self::OAI_ERR_BAD_ARGUMENT); return; } // Construct date range for from/until if defined $o_tep = new TimeExpressionParser(); $o_lang_settings = $o_tep->getLanguageSettings(); $vs_conj = array_shift($o_lang_settings->getList("rangeConjunctions")); $vs_range = $from && $until ? "{$from} {$vs_conj} {$until}" : ''; if ($set && $this->opa_provider_info['setFacet']) { $o_browse = caGetBrowseInstance($this->table); if (($vs_query = $this->opa_provider_info['query']) && $vs_query != "*") { $o_browse->addCriteria("_search", $vs_query); } $o_browse->addCriteria($this->opa_provider_info['setFacet'], $set); $o_browse->execute(array('showDeleted' => $vb_show_deleted, 'no_cache' => $vb_dont_cache, 'limitToModifiedOn' => $vs_range, 'checkAccess' => $vb_dont_enforce_access_settings ? null : $va_access_values)); $qr_res = $o_browse->getResults(); } else { $qr_res = $o_search->search(strlen($this->opa_provider_info['query']) ? $this->opa_provider_info['query'] : "*", array('no_cache' => $vb_dont_cache, 'limitToModifiedOn' => $vs_range, 'showDeleted' => $vb_show_deleted, 'checkAccess' => $vb_dont_enforce_access_settings ? null : $va_access_values)); } if (!$qr_res) { $this->throwError(self::OAI_ERR_NO_RECORDS_MATCH, _t('Query failed')); return; } $rows = $qr_res->numHits(); if (count($qr_res->numHits()) == 0) { $this->throwError(self::OAI_ERR_NO_RECORDS_MATCH, _t('No records match the given criteria')); } else { $verbElement = $oaiData->createElement($verb); $oaiData->documentElement->appendChild($verbElement); $t_change_log = new ApplicationChangeLog(); if ($vb_show_deleted) { // get list of deleted records $va_deleted_items = array(); $qr_res->seek($cursor); $vn_c = 0; $va_get_deleted_timestamps_for = array(); while ($qr_res->nextHit()) { if ((bool) $qr_res->get("{$vs_table}.deleted")) { $va_deleted_items[$vs_pk_val = (int) $qr_res->get("{$vs_table}.{$vs_pk}")] = true; $va_get_deleted_timestamps_for[$vs_pk_val] = true; } else { $vn_access = (int) $qr_res->get("{$vs_table}.access"); if (!in_array($vn_access, $va_access_values)) { $va_deleted_items[(int) $qr_res->get("{$vs_table}.{$vs_pk}")] = true; } } $vn_c++; if ($vn_c >= $listLimit) { break; } } $qr_res->seek(0); $va_deleted_timestamps = $t_change_log->getDeleteOnTimestampsForIDs($vs_table, array_keys($va_get_deleted_timestamps_for)); } // Export data using metadata mapping $va_items = ca_data_exporters::exportRecordsFromSearchResultToArray($this->getMappingCode(), $qr_res, array('start' => $cursor, 'limit' => $listLimit)); if (is_array($va_items) && sizeof($va_items)) { $va_timestamps = $t_change_log->getLastChangeTimestampsForIDs($vs_table, array_keys($va_items)); foreach ($va_items as $vn_id => $vs_item_xml) { if ($vb_show_deleted && $va_deleted_items[$vn_id]) { $headerData = array('identifier' => OaiIdentifier::itemToOaiId($vn_id), 'datestamp' => self::unixToUtc($va_deleted_timestamps[$vn_id]['timestamp'] ? $va_deleted_timestamps[$vn_id]['timestamp'] : $va_timestamps[$vn_id]['timestamp'])); if ($verb == 'ListIdentifiers') { $header = $this->createElementWithChildren($oaiData, $verbElement, 'header', $headerData); $header->setAttribute("status", "deleted"); } else { $recordElement = $verbElement->appendChild($oaiData->createElement('record')); $header = $this->createElementWithChildren($oaiData, $recordElement, 'header', $headerData); $header->setAttribute("status", "deleted"); } } else { $headerData = array('identifier' => OaiIdentifier::itemToOaiId($vn_id), 'datestamp' => self::unixToUtc($va_timestamps[$vn_id]['timestamp'])); if ($verb == 'ListIdentifiers') { $this->createElementWithChildren($oaiData, $verbElement, 'header', $headerData); } else { $recordElement = $verbElement->appendChild($oaiData->createElement('record')); $this->createElementWithChildren($oaiData, $recordElement, 'header', $headerData); $metadataElement = $oaiData->createElement('metadata'); $o_doc_src = DomDocument::loadXML($vs_item_xml); if ($o_doc_src) { // just in case the xml fails to load through DomDocument for some reason (e.g. a bad mapping or very weird characters) $metadataElement->appendChild($oaiData->importNode($o_doc_src->documentElement, true)); } $recordElement->appendChild($metadataElement); } } } } if ($rows > $cursor + $listLimit) { $token = $this->createResumptionToken($verb, $metadataPrefix, $cursor + $listLimit, $set, $from, $until); $tokenElement = $oaiData->createElement('resumptionToken', $token['key']); $tokenElement->setAttribute('expirationDate', self::unixToUtc($token['expiration'])); $tokenElement->setAttribute('completeListSize', $rows); $tokenElement->setAttribute('cursor', $cursor); $verbElement->appendChild($tokenElement); } else { if ($cursor != 0) { $tokenElement = $this->oaiData->createElement('resumptionToken'); $verbElement->appendChild($tokenElement); } } } }
<?php MetaTagManager::setWindowTitle($this->request->config->get("app_display_name") . ": Body of Knowledge"); # --- do a occurrece search to get all the competences $o_search = caGetSearchInstance("ca_occurrences"); $t_lists = new ca_lists(); $vn_category_type_id = $t_lists->getItemIDFromList("occurrence_types", "category"); $qr_res = $o_search->search('type_id:' . $vn_category_type_id, $va_options['sort'] = "ca_occurrences.preferred_labels.name"); $va_all_competences = array(); $va_competences_by_area = array(); if ($qr_res->numHits()) { while ($qr_res->nextHit()) { $va_all_competences[$qr_res->get("ca_occurrences.occurrence_id")] = array("idno" => $qr_res->get("ca_occurrences.idno"), "label" => strtolower($qr_res->get("ca_occurrences.preferred_labels.name"))); $va_competences_by_area[str_replace(" Pa ", " PA ", ucwords(strtolower($qr_res->get("ca_occurrences.area", array("convertCodesToDisplayText" => true)))))][$qr_res->get("ca_occurrences.occurrence_id")] = array("idno" => $qr_res->get("ca_occurrences.idno"), "label" => strtolower($qr_res->get("ca_occurrences.preferred_labels.name"))); } } if (sizeof($va_competences_by_area)) { ?> <div class="container containerTextPadding" id="comp_nav"> <div class="row"> <div class="col-sm-12"> <H2>Choose a competence category to explore:</H2> <?php if ($this->request->config->get("onlyLinkTrpCategory")) { ?> <H5 class="indent red"><i>* Content currently under development. Please use the competence category TRP (Tourism, Recreation, and Public Use) to explore how the Body of Knowledge works.</i></H5> <?php } ?> </div>
/** * Performs search using expression for each provided search "block." A block defines a * search on a specific item (Eg. ca_objects, ca_entities), with or without type restriction, with * results rendered using a provided view. The results for all blocks are returned in an array. * * Used by MultiSearch to generate results. Blame Sophie for the function name. * * @param RequestHTTP $po_request * @param string $ps_search_expression * @param array $pa_blocks * @param array $pa_options * itemsPerPage = * itemsPerColumn = * contexts = * ... any other options passed through as-is to SearchEngine::search() * * @return array */ function caPuppySearch($po_request, $ps_search_expression, $pa_blocks, $pa_options = null) { if (!is_array($pa_options)) { $pa_options = array(); } $va_access_values = caGetUserAccessValues($po_request); if (is_array($va_access_values) && sizeof($va_access_values)) { $pa_options["checkAccess"] = $va_access_values; } $vn_items_per_page_default = caGetOption('itemsPerPage', $pa_options, 10); $vn_items_per_column_default = caGetOption('itemsPerColumn', $pa_options, 1); $vb_match_on_stem = caGetOption('matchOnStem', $pa_options, false); $va_contexts = caGetOption('contexts', $pa_options, array(), array('castTo' => 'array')); unset($pa_options['contexts']); // // Block are lazy-loaded using Ajax requests with additional items as they are scrolled. // "Ajax mode" is used by caPuppySearch to render a single block when it is scrolled // The block to be rendered is specified in the "block" request parameter. The offset // from the beginning of the result to start rendering from is specified in the "s" request parameter. // $vb_ajax_mode = false; if ($po_request->isAjax() && ($ps_block = $po_request->getParameter('block', pString)) && isset($pa_blocks[$ps_block])) { $pa_blocks = array($ps_block => $pa_blocks[$ps_block]); $vb_ajax_mode = true; } $va_ret = array(); $vn_i = 0; $vn_total_cnt = 0; $va_table_counts = array(); foreach ($pa_blocks as $vs_block => $va_block_info) { if (!($o_search = caGetSearchInstance($va_block_info['table']))) { continue; } if (!is_array($va_block_info['options'])) { $va_block_info['options'] = array(); } $va_options = array_merge($pa_options, $va_block_info['options']); $va_sorts = caGetOption('sortBy', $va_block_info, null); $ps_sort = null; $vb_sort_changed = false; if (!($ps_sort = $po_request->getParameter("{$vs_block}Sort", pString))) { if (isset($va_contexts[$vs_block])) { if (!($ps_sort = $va_contexts[$vs_block]->getCurrentSort()) && $va_sorts && sizeof($va_sorts)) { $ps_sort = array_shift(array_keys($va_sorts)); $va_contexts[$vs_block]->setCurrentSort($ps_sort); $vb_sort_changed = true; //} else { // if (isset($va_sorts[$ps_sort])) { // $ps_sort = $va_sorts[$ps_sort]; // } } } } else { $vb_sort_changed = true; } if ($vb_sort_changed && $va_sorts && sizeof($va_sorts)) { # --- set the default sortDirection if available $va_sort_directions = caGetOption('sortDirection', $va_block_info, null); //$ps_sort_key = array_search($ps_sort, $va_sorts); if (is_array($va_sort_directions) && ($ps_sort_direction = $va_sort_directions[$ps_sort])) { $va_contexts[$vs_block]->setCurrentSortDirection($ps_sort_direction); } } if (!($ps_sort_direction = $po_request->getParameter("{$vs_block}SortDirection", pString))) { if (!($ps_sort_direction = $va_contexts[$vs_block]->getCurrentSortDirection())) { $ps_sort_direction = 'asc'; } } $va_contexts[$vs_block]->setCurrentSortDirection($ps_sort_direction); $va_options['sort'] = $ps_sort; $va_options['sort_direction'] = $ps_sort_direction; $va_types = caGetOption('restrictToTypes', $va_block_info, array(), array('castTo' => 'array')); if (is_array($va_types) && sizeof($va_types)) { $o_search->setTypeRestrictions($va_types); } $va_options['restrictSearchToFields'] = caGetOption('restrictSearchToFields', $va_block_info, null); if (caGetOption('dontShowChildren', $va_block_info, false)) { $o_search->addResultFilter('ca_objects.parent_id', 'is', 'null'); } $qr_res = $o_search->search($ps_search_expression . ($vb_match_on_stem && !preg_match('!\\*$!', $ps_search_expression) ? '*' : ''), $va_options); $va_contexts[$vs_block]->setSearchExpression($ps_search_expression); $va_contexts[$vs_block]->setResultList($qr_res->getPrimaryKeyValues()); // In Ajax mode we scroll to an offset $vn_start = 0; if ($vb_ajax_mode) { if (($vn_start = $po_request->getParameter('s', pInteger)) < $qr_res->numHits()) { $qr_res->seek($vn_start); if (isset($va_contexts[$vs_block])) { $va_contexts[$vs_block]->setParameter('start', $vn_start); } } else { // If the offset is past the end of the result return an empty string to halt the continuous scrolling return ''; } } else { // // Reset start if it's a new search // if ($va_contexts[$vs_block]->getSearchExpression(true) != $ps_search_expression) { $va_contexts[$vs_block]->setParameter('start', 0); } } $va_contexts[$vs_block]->saveContext(); $vn_items_per_page = caGetOption('itemsPerPage', $va_block_info, $vn_items_per_page_default); $vn_items_per_column = caGetOption('itemsPerColumn', $va_block_info, $vn_items_per_column_default); $vn_count = $qr_res->numHits(); $va_sort_by = caGetOption('sortBy', $va_block_info, null); $vs_sort_list = ''; if (is_array($va_sort_by)) { $va_sort_list = array(); foreach ($va_sort_by as $vs_sort_label => $vs_sort) { $va_sort_list[] = "<li" . ($vs_sort_label == $ps_sort ? " class='selectedSort'" : '') . "><a href='#' rel='{$vs_sort_label}'>{$vs_sort_label}</a></li>"; } $vs_sort_list = "<ul id='{$vs_block}_sort'>" . join("\n", $va_sort_list) . "</ul>"; } $o_view = new View($po_request, $po_request->getViewsDirectoryPath()); $o_view->setVar('result', $qr_res); $o_view->setVar('count', $vn_count); $o_view->setVar('block', $vs_block); $o_view->setVar('blockInfo', $va_block_info); $o_view->setVar('blockIndex', $vn_i); $o_view->setVar('start', $vn_start); $o_view->setVar('itemsPerPage', $vn_items_per_page); $o_view->setVar('itemsPerColumn', $vn_items_per_column); $o_view->setVar('hasMore', (bool) ($vn_count > $vn_start + $vn_items_per_page)); $o_view->setVar('sortBy', is_array($va_sort_by) ? $va_sort_by : null); $o_view->setVar('sortBySelect', $vs_sort_by_select = is_array($va_sort_by) ? caHTMLSelect("{$vs_block}_sort", $va_sort_by, array('id' => "{$vs_block}_sort", "class" => "form-control input-sm"), array("value" => $ps_sort)) : ''); $o_view->setVar('sortByControl', $va_block_info["sortControlType"] && $va_block_info["sortControlType"] == "list" ? $vs_sort_list : $vs_sort_by_select); // synonym for sortBySelect $o_view->setVar('sortByList', $vs_sort_list); $o_view->setVar('sort', $ps_sort); $o_view->setVar('sortDirectionControl', '<a href="#" id="' . $vs_block . '_sort_direction"><span class="glyphicon glyphicon-sort-by-alphabet' . ($ps_sort_direction == 'desc' ? '-alt' : '') . '"></span></a>'); $o_view->setVar('sortDirection', $ps_sort_direction); $o_view->setVar('search', $ps_search_expression); $o_view->setVar('cacheKey', md5($ps_search_expression)); if (!$vb_ajax_mode) { if (isset($va_contexts[$vs_block])) { $o_view->setVar('initializeWithStart', (int) $va_contexts[$vs_block]->getParameter('start')); } else { $o_view->setVar('initializeWithStart', 0); } } $vs_html = $o_view->render($va_block_info['view']); $va_ret[$vs_block] = array('count' => $vn_count, 'html' => $vs_html, 'displayName' => $va_block_info['displayName'], 'ids' => $qr_res->getPrimaryKeyValues(), 'sort' => $ps_sort, 'sortDirection' => $ps_sort_direction); $va_table_counts[$va_block_info['table']] += $vn_count; $vn_total_cnt += $vn_count; $vn_i++; if ($vb_ajax_mode) { // In Ajax mode return rendered HTML for the single block return $va_ret; } } $va_ret['_info_'] = array('totalCount' => $vn_total_cnt); // Set generic contexts for each table in multisearch (no specific block); // used to house search history and overall counts when there is more than one block for a given table foreach ($va_table_counts as $vs_table => $vn_count) { $va_contexts["_multisearch_{$vs_table}"]->setSearchExpression($ps_search_expression); $va_contexts["_multisearch_{$vs_table}"]->setSearchHistory($vn_count); $va_contexts["_multisearch_{$vs_table}"]->saveContext(); } return $va_ret; }
/** * Actually do the browse * * Options: * checkAccess = array of access values to filter facets that have an 'access' field by * no_cache = don't use cached browse results * showDeleted = if set to true, related items that have been deleted are returned. Default is false. * limitToModifiedOn = if set returned results will be limited to rows modified within the specified date range. The value should be a date/time expression parse-able by TimeExpressionParser * user_id = If set item level access control is performed relative to specified user_id, otherwise defaults to logged in user */ public function execute($pa_options = null) { global $AUTH_CURRENT_USER_ID; if (!is_array($pa_options)) { $pa_options = array(); } $vn_user_id = isset($pa_options['user_id']) && (int) $pa_options['user_id'] ? (int) $pa_options['user_id'] : (int) $AUTH_CURRENT_USER_ID; if (!is_array($this->opa_browse_settings)) { return null; } $va_params = $this->opo_ca_browse_cache->getParameters(); $vb_need_to_cache_facets = false; $vb_results_cached = false; $vb_need_to_save_in_cache = false; $vs_cache_key = $this->opo_ca_browse_cache->getCurrentCacheKey(); if ($this->opo_ca_browse_cache->load($vs_cache_key)) { $vn_created_on = $this->opo_ca_browse_cache->getParameter('created_on'); //$t_new_browse->get('created_on', array('GET_DIRECT_DATE' => true)); $va_criteria = $this->getCriteria(); if ((!isset($pa_options['no_cache']) || !$pa_options['no_cache']) && intval(time() - $vn_created_on) < $this->opo_ca_browse_config->get('cache_timeout')) { $vb_results_cached = true; //print "cache hit for [$vs_cache_key]<br>"; } else { $va_criteria = $this->getCriteria(); $this->opo_ca_browse_cache->remove(); $this->opo_ca_browse_cache->setParameter('criteria', $va_criteria); //print "cache expire for [$vs_cache_key]<br>"; $vb_need_to_save_in_cache = true; $vb_need_to_cache_facets = true; } } else { $va_criteria = $this->getCriteria(); //print "cache miss for [$vs_cache_key]<br>"; $vb_need_to_save_in_cache = true; } if (!$vb_results_cached) { $this->opo_ca_browse_cache->setParameter('sort', null); $this->opo_ca_browse_cache->setParameter('created_on', time()); $this->opo_ca_browse_cache->setParameter('table_num', $this->opn_browse_table_num); $vb_need_to_cache_facets = true; } $this->opb_criteria_have_changed = false; $t_item = $this->opo_datamodel->getInstanceByTableName($this->ops_browse_table_name, true); $va_results = array(); if (is_array($va_criteria) && sizeof($va_criteria) > 0) { if (!$vb_results_cached) { // generate results $this->_createTempTable('ca_browses_acc'); $this->_createTempTable('ca_browses_tmp'); $vn_i = 0; foreach ($va_criteria as $vs_facet_name => $va_row_ids) { $vs_target_browse_table_name = $t_item->tableName(); $vs_target_browse_table_num = $t_item->tableNum(); $vs_target_browse_table_pk = $t_item->primaryKey(); $va_facet_info = $this->getInfoForFacet($vs_facet_name); $va_row_ids = array_keys($va_row_ids); $vs_relative_to_join = ''; switch ($va_facet_info['type']) { # ----------------------------------------------------- case 'has': $vs_rel_table_name = $va_facet_info['table']; $va_joins = array(); if ($va_facet_info['relative_to']) { if ($va_relative_execute_sql_data = $this->_getRelativeExecuteSQLData($va_facet_info['relative_to'], $pa_options)) { $va_joins = array_merge($va_joins, $va_relative_execute_sql_data['relative_joins']); $vs_target_browse_table_name = $va_relative_execute_sql_data['target_table_name']; $vs_target_browse_table_num = $va_relative_execute_sql_data['target_table_num']; $vs_target_browse_table_pk = $va_relative_execute_sql_data['target_table_pk']; } } 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']; $vn_state = array_pop($va_row_ids); if ($vn_state == 0) { $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 { $va_joins[] = "INNER JOIN ca_attributes AS caa ON caa.row_id = " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . " AND caa.table_num = " . $t_item->tableNum(); $va_wheres[] = "caa.element_id = " . $t_element->getPrimaryKey(); } } else { 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_target_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); $vn_state = array_pop($va_row_ids); foreach ($va_path as $vs_join_table) { $va_rel_info = $this->opo_datamodel->getRelationships($vs_cur_table, $vs_join_table); $va_joins[] = ($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_wheres = array(); 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 (!(bool) $vn_state) { // 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() . "." . $t_rel_item->primaryKey() . " IS NULL) AND (" . $t_rel_item->tableName() . ".access IS NULL)))"; } } 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 ($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[] = "(" . $t_item->tableName() . ".access IN (" . join(',', $pa_options['checkAccess']) . "))"; } $vs_join_sql = join("\n", $va_joins); $vs_where_sql = ''; if (sizeof($va_wheres) > 0) { $vs_where_sql = ' WHERE ' . join(' AND ', $va_wheres); } if ($vn_i == 0) { $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\tINSERT IGNORE INTO ca_browses_acc\n\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\t\t\t\t\t"; //print "$vs_sql<hr>"; $qr_res = $this->opo_db->query($vs_sql); } else { $qr_res = $this->opo_db->query("TRUNCATE TABLE ca_browses_tmp"); $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\tINSERT IGNORE INTO ca_browses_tmp\n\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_browses_acc ON ca_browses_acc.row_id = " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_where_sql}"; //print "$vs_sql<hr>"; $qr_res = $this->opo_db->query($vs_sql); $qr_res = $this->opo_db->query("TRUNCATE TABLE ca_browses_acc"); $qr_res = $this->opo_db->query("INSERT IGNORE INTO ca_browses_acc SELECT row_id FROM ca_browses_tmp"); } $vn_i++; break; # ----------------------------------------------------- # ----------------------------------------------------- case 'label': if (!($t_label = $t_item->getLabelTableInstance())) { break; } $vs_label_item_pk = $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(); if ($va_facet_info['relative_to']) { if ($va_relative_execute_sql_data = $this->_getRelativeExecuteSQLData($va_facet_info['relative_to'], $pa_options)) { $vs_target_browse_table_name = $va_relative_execute_sql_data['target_table_name']; $vs_target_browse_table_num = $va_relative_execute_sql_data['target_table_num']; $vs_target_browse_table_pk = $va_relative_execute_sql_data['target_table_pk']; $t_target = $this->opo_datamodel->getInstanceByTableName($va_facet_info['relative_to'], true); $t_target_label = $t_target->getLabelTableInstance(); $vs_item_pk = $t_target->primaryKey(); $vs_label_table_name = $t_target_label->tableName(); $vs_label_item_pk = $t_target_label->primaryKey(); $va_relative_to_join = $va_relative_execute_sql_data['relative_joins']; $va_relative_to_join[] = "INNER JOIN {$vs_label_table_name} ON {$vs_label_table_name}.{$vs_label_item_pk} = {$vs_target_browse_table_name}.{$vs_target_browse_table_pk}"; } } else { $va_relative_to_join = array("INNER JOIN {$vs_label_table_name} ON {$vs_label_table_name}.{$vs_label_item_pk} = {$vs_target_browse_table_name}.{$vs_target_browse_table_pk}"); } $vs_relative_to_join = join("\n", $va_relative_to_join); foreach ($va_row_ids as $vn_row_id) { if ($vn_i == 0) { $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\tINSERT IGNORE INTO ca_browses_acc\n\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . "." . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t\t{$vs_label_table_name}.{$vs_label_item_pk} = ?"; //print "$vs_sql [".intval($this->opn_browse_table_num)."]<hr>"; $qr_res = $this->opo_db->query($vs_sql, $vn_row_id); } else { $qr_res = $this->opo_db->query("TRUNCATE TABLE ca_browses_tmp"); $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\tINSERT IGNORE INTO ca_browses_tmp\n\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . "." . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_browses_acc ON ca_browses_acc.row_id = " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t\t{$vs_label_table_name}.{$vs_label_item_pk} = ?"; //print "$vs_sql [".intval($this->opn_browse_table_num)."]<hr>"; $qr_res = $this->opo_db->query($vs_sql, $vn_row_id); $qr_res = $this->opo_db->query("TRUNCATE TABLE ca_browses_acc"); $qr_res = $this->opo_db->query("INSERT IGNORE INTO ca_browses_acc SELECT row_id FROM ca_browses_tmp"); } $vn_i++; } break; # ----------------------------------------------------- # ----------------------------------------------------- case 'field': $vs_field_name = $va_facet_info['field']; $vs_table_name = $this->ops_browse_table_name; if ($va_facet_info['relative_to']) { if ($va_relative_execute_sql_data = $this->_getRelativeExecuteSQLData($va_facet_info['relative_to'], $pa_options)) { $va_relative_to_join = $va_relative_execute_sql_data['relative_joins']; $vs_relative_to_join = join("\n", $va_relative_to_join); $vs_table_name = $vs_target_browse_table_name = $va_relative_execute_sql_data['target_table_name']; $vs_target_browse_table_num = $va_relative_execute_sql_data['target_table_num']; $vs_target_browse_table_pk = $va_relative_execute_sql_data['target_table_pk']; } } foreach ($va_row_ids as $vn_row_id) { $vn_row_id = urldecode($vn_row_id); if ($vn_i == 0) { $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\tINSERT IGNORE INTO ca_browses_acc\n\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t\t({$vs_table_name}.{$vs_field_name} = ?)"; //print "$vs_sql [".intval($this->opn_browse_table_num)."/".$vn_element_id."/".$vn_row_id."]<hr>"; $qr_res = $this->opo_db->query($vs_sql, (string) $vn_row_id); } else { $qr_res = $this->opo_db->query("TRUNCATE TABLE ca_browses_tmp"); $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\tINSERT IGNORE INTO ca_browses_tmp\n\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_browses_acc ON ca_browses_acc.row_id = " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t\t({$vs_table_name}.{$vs_field_name} = ?)"; //print "$vs_sql [".intval($this->opn_browse_table_num)."/".$vn_element_id."/".$vn_row_id."]<hr>"; $qr_res = $this->opo_db->query($vs_sql, (string) $vn_row_id); $qr_res = $this->opo_db->query("TRUNCATE TABLE ca_browses_acc"); $qr_res = $this->opo_db->query("INSERT IGNORE INTO ca_browses_acc SELECT row_id FROM ca_browses_tmp"); } $vn_i++; } break; # ----------------------------------------------------- # ----------------------------------------------------- case 'attribute': $t_element = new ca_metadata_elements(); if (!$t_element->load(array('element_code' => $va_facet_info['element_code']))) { return array(); } $vn_datatype = $t_element->get('datatype'); if ($va_facet_info['relative_to']) { if ($va_relative_execute_sql_data = $this->_getRelativeExecuteSQLData($va_facet_info['relative_to'], $pa_options)) { $va_relative_to_join = $va_relative_execute_sql_data['relative_joins']; $vs_relative_to_join = join("\n", $va_relative_to_join); $vs_target_browse_table_name = $va_relative_execute_sql_data['target_table_name']; $vs_target_browse_table_num = $va_relative_execute_sql_data['target_table_num']; $vs_target_browse_table_pk = $va_relative_execute_sql_data['target_table_pk']; } } // TODO: check that it is a *single-value* (ie. no hierarchical ca_metadata_elements) Text or Number attribute // (do we support other types as well?) $vn_element_id = $t_element->getPrimaryKey(); $o_attr = Attribute::getValueInstance($t_element->get('datatype')); foreach ($va_row_ids as $vn_row_id) { $vn_row_id = urldecode($vn_row_id); $vn_row_id = str_replace('/', '/', $vn_row_id); $va_value = $o_attr->parseValue($vn_row_id, $t_element->getFieldValuesArray()); $va_attr_sql = array(); $va_attr_values = array(intval($vs_target_browse_table_num), $vn_element_id); if (is_array($va_value)) { foreach ($va_value as $vs_f => $vs_v) { if ($vn_datatype == 3) { // list $t_list_item = new ca_list_items((int) $vs_v); // Include sub-items $va_item_ids = $t_list_item->getHierarchy((int) $vs_v, array('idsOnly' => true, 'includeSelf' => true)); $va_item_ids[] = (int) $vs_v; $va_attr_sql[] = "(ca_attribute_values.{$vs_f} IN (?))"; $va_attr_values[] = $va_item_ids; } else { $va_attr_sql[] = "(ca_attribute_values.{$vs_f} " . (is_null($vs_v) ? " IS " : " = ") . " ?)"; $va_attr_values[] = $vs_v; } } } if ($vs_attr_sql = join(" AND ", $va_attr_sql)) { $vs_attr_sql = " AND " . $vs_attr_sql; } if ($vn_i == 0) { $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\tINSERT IGNORE INTO ca_browses_acc\n\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_attributes ON ca_attributes.row_id = {$vs_target_browse_table_name}.{$vs_target_browse_table_pk} AND ca_attributes.table_num = ?\n\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_attribute_values ON ca_attribute_values.attribute_id = ca_attributes.attribute_id\n\t\t\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t\t(ca_attribute_values.element_id = ?) {$vs_attr_sql}"; //caDebug($vs_sql); //caDebug(intval($vs_target_browse_table_num)."/".$vn_element_id."/".$vn_row_id); //caDebug($va_attr_values); $qr_res = $this->opo_db->query($vs_sql, $va_attr_values); } else { $qr_res = $this->opo_db->query("TRUNCATE TABLE ca_browses_tmp"); $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\tINSERT IGNORE INTO ca_browses_tmp\n\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_attributes ON ca_attributes.row_id = {$vs_target_browse_table_name}.{$vs_target_browse_table_pk} AND ca_attributes.table_num = ?\n\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_attribute_values ON ca_attribute_values.attribute_id = ca_attributes.attribute_id\n\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_browses_acc ON ca_browses_acc.row_id = " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t\t(ca_attribute_values.element_id = ?) {$vs_attr_sql}"; //print "$vs_sql [".intval($vs_target_browse_table_num)."/".$vn_element_id."/".$vn_row_id."]<hr>";print_R($va_attr_values); $qr_res = $this->opo_db->query($vs_sql, $va_attr_values); $qr_res = $this->opo_db->query("TRUNCATE TABLE ca_browses_acc"); $qr_res = $this->opo_db->query("INSERT IGNORE INTO ca_browses_acc SELECT row_id FROM ca_browses_tmp"); } $vn_i++; } break; # ----------------------------------------------------- # ----------------------------------------------------- case 'normalizedDates': $t_element = new ca_metadata_elements(); if (!$t_element->load(array('element_code' => $va_facet_info['element_code']))) { return array(); } // TODO: check that it is a *single-value* (ie. no hierarchical ca_metadata_elements) DateRange attribute $vs_normalization = $va_facet_info['normalization']; $vn_element_id = $t_element->getPrimaryKey(); $o_tep = new TimeExpressionParser(); if ($va_facet_info['relative_to']) { if ($va_relative_execute_sql_data = $this->_getRelativeExecuteSQLData($va_facet_info['relative_to'], $pa_options)) { $va_relative_to_join = $va_relative_execute_sql_data['relative_joins']; $vs_relative_to_join = join("\n", $va_relative_to_join); $vs_target_browse_table_name = $va_relative_execute_sql_data['target_table_name']; $vs_target_browse_table_num = $va_relative_execute_sql_data['target_table_num']; $vs_target_browse_table_pk = $va_relative_execute_sql_data['target_table_pk']; } } foreach ($va_row_ids as $vn_row_id) { $vn_row_id = urldecode($vn_row_id); if (!$o_tep->parse($vn_row_id)) { continue; } // invalid date? $va_dates = $o_tep->getHistoricTimestamps(); if ($vn_i == 0) { $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\tINSERT IGNORE INTO ca_browses_acc\n\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_attributes ON ca_attributes.row_id = " . $vs_target_browse_table_name . '.' . $vs_target_browse_table_pk . " AND ca_attributes.table_num = ?\n\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_attribute_values ON ca_attribute_values.attribute_id = ca_attributes.attribute_id\n\t\t\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t\t(ca_attribute_values.element_id = ?) AND\n\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(\n\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(ca_attribute_values.value_decimal1 <= ?) AND\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(ca_attribute_values.value_decimal2 >= ?)\n\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\tOR\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t(ca_attribute_values.value_decimal1 BETWEEN ? AND ?)\n\t\t\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\t\t(ca_attribute_values.value_decimal2 BETWEEN ? AND ?)\n\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"; //print $vs_sql; $qr_res = $this->opo_db->query($vs_sql, intval($vs_target_browse_table_num), $vn_element_id, $va_dates['start'], $va_dates['end'], $va_dates['start'], $va_dates['end'], $va_dates['start'], $va_dates['end']); } else { $qr_res = $this->opo_db->query("TRUNCATE TABLE ca_browses_tmp"); $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\tINSERT IGNORE INTO ca_browses_tmp\n\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_attributes ON ca_attributes.row_id = " . $vs_target_browse_table_name . '.' . $vs_target_browse_table_pk . " AND ca_attributes.table_num = ?\n\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_attribute_values ON ca_attribute_values.attribute_id = ca_attributes.attribute_id\n\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_browses_acc ON ca_browses_acc.row_id = " . $t_item->tableName() . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t\t(ca_attribute_values.element_id = ?) AND\n\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(\n\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(ca_attribute_values.value_decimal1 <= ?) AND\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(ca_attribute_values.value_decimal2 >= ?)\n\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\tOR\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t(ca_attribute_values.value_decimal1 BETWEEN ? AND ?)\n\t\t\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\t\t(ca_attribute_values.value_decimal2 BETWEEN ? AND ?)\n\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"; //print $vs_sql; $qr_res = $this->opo_db->query($vs_sql, intval($vs_target_browse_table_num), $vn_element_id, $va_dates['start'], $va_dates['end'], $va_dates['start'], $va_dates['end'], $va_dates['start'], $va_dates['end']); $qr_res = $this->opo_db->query("TRUNCATE TABLE ca_browses_acc"); $qr_res = $this->opo_db->query("INSERT IGNORE INTO ca_browses_acc SELECT row_id FROM ca_browses_tmp"); } $vn_i++; } break; # ----------------------------------------------------- # ----------------------------------------------------- case 'authority': $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); if ($va_facet_info['relative_to']) { if ($va_relative_execute_sql_data = $this->_getRelativeExecuteSQLData($va_facet_info['relative_to'], $pa_options)) { $va_relative_to_join = $va_relative_execute_sql_data['relative_joins']; $vs_relative_to_join = join("\n", $va_relative_to_join); $vs_target_browse_table_name = $va_relative_execute_sql_data['target_table_name']; $vs_target_browse_table_num = $va_relative_execute_sql_data['target_table_num']; $vs_target_browse_table_pk = $va_relative_execute_sql_data['target_table_pk']; } } foreach ($va_row_ids as $vn_row_id) { switch (sizeof($va_path = array_keys($this->opo_datamodel->getPath($vs_target_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 = array(); 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; } $vs_join_sql = join("\n", $va_joins); $va_wheres = array(); 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) . "))"; } $vs_where_sql = ''; if (sizeof($va_wheres) > 0) { $vs_where_sql = ' AND ' . join(' AND ', $va_wheres); } if ((!isset($va_facet_info['dont_expand_hierarchically']) || !$va_facet_info['dont_expand_hierarchically']) && $t_rel_item->isHierarchical() && $t_rel_item->load((int) $vn_row_id)) { $vs_hier_left_fld = $t_rel_item->getProperty('HIERARCHY_LEFT_INDEX_FLD'); $vs_hier_right_fld = $t_rel_item->getProperty('HIERARCHY_RIGHT_INDEX_FLD'); $vs_get_item_sql = "{$vs_rel_table_name}.{$vs_hier_left_fld} >= " . $t_rel_item->get($vs_hier_left_fld) . " AND {$vs_rel_table_name}.{$vs_hier_right_fld} <= " . $t_rel_item->get($vs_hier_right_fld); if ($vn_hier_id_fld = $t_rel_item->getProperty('HIERARCHY_ID_FLD')) { $vs_get_item_sql .= " AND {$vs_rel_table_name}.{$vn_hier_id_fld} = " . (int) $t_rel_item->get($vn_hier_id_fld); } $vs_get_item_sql = "({$vs_get_item_sql})"; } else { $vs_get_item_sql = "({$vs_rel_table_name}.{$vs_rel_table_pk} = " . (int) $vn_row_id . ")"; } if ($vn_i == 0) { $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\tINSERT IGNORE INTO ca_browses_acc\n\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t\t{$vs_get_item_sql}\n\t\t\t\t\t\t\t\t\t\t\t\t\t{$vs_where_sql}"; //print "$vs_sql<hr>"; $qr_res = $this->opo_db->query($vs_sql); } else { $qr_res = $this->opo_db->query("TRUNCATE TABLE ca_browses_tmp"); $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\tINSERT IGNORE INTO ca_browses_tmp\n\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_browses_acc ON ca_browses_acc.row_id = " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t\t{$vs_get_item_sql}\n\t\t\t\t\t\t\t\t\t\t\t\t\t{$vs_where_sql}"; //print "$vs_sql<hr>"; $qr_res = $this->opo_db->query($vs_sql); $qr_res = $this->opo_db->query("TRUNCATE TABLE ca_browses_acc"); $qr_res = $this->opo_db->query("INSERT IGNORE INTO ca_browses_acc SELECT row_id FROM ca_browses_tmp"); } $vn_i++; } break; # ----------------------------------------------------- # ----------------------------------------------------- case 'fieldList': $vs_field_name = $va_facet_info['field']; $vs_table_name = $this->ops_browse_table_name; if ($va_facet_info['relative_to']) { if ($va_relative_execute_sql_data = $this->_getRelativeExecuteSQLData($va_facet_info['relative_to'], $pa_options)) { $va_relative_to_join = $va_relative_execute_sql_data['relative_joins']; $vs_relative_to_join = join("\n", $va_relative_to_join); $vs_table_name = $vs_target_browse_table_name = $va_relative_execute_sql_data['target_table_name']; $vs_target_browse_table_num = $va_relative_execute_sql_data['target_table_num']; $vs_target_browse_table_pk = $va_relative_execute_sql_data['target_table_pk']; } } foreach ($va_row_ids as $vn_row_id) { $vn_row_id = urldecode($vn_row_id); if ($vn_i == 0) { $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\tINSERT IGNORE INTO ca_browses_acc\n\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t\t({$vs_table_name}.{$vs_field_name} = ?)"; //print "$vs_sql [".intval($this->opn_browse_table_num)."/".$vn_row_id."]<hr>"; $qr_res = $this->opo_db->query($vs_sql, $vn_row_id); } else { $qr_res = $this->opo_db->query("TRUNCATE TABLE ca_browses_tmp"); $vs_sql = "\n\t\t\t\t\t\t\t\t\t\t\t\tINSERT IGNORE INTO ca_browses_tmp\n\t\t\t\t\t\t\t\t\t\t\t\tSELECT " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $this->ops_browse_table_name . "\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_relative_to_join}\n\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_browses_acc ON ca_browses_acc.row_id = " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t\t({$vs_table_name}.{$vs_field_name} = ?)"; //print "$vs_sql [".intval($this->opn_browse_table_num)."/".$vn_row_id."]<hr>"; $qr_res = $this->opo_db->query($vs_sql, $vn_row_id); $qr_res = $this->opo_db->query("TRUNCATE TABLE ca_browses_acc"); $qr_res = $this->opo_db->query("INSERT IGNORE INTO ca_browses_acc SELECT row_id FROM ca_browses_tmp"); } $vn_i++; } break; # ----------------------------------------------------- # ----------------------------------------------------- default: // handle "search" criteria - search engine queries that can be browsed if ($vs_facet_name === '_search') { $qr_res = $this->opo_db->query("TRUNCATE TABLE ca_browses_acc"); if (!($o_search = caGetSearchInstance($this->ops_browse_table_name))) { $this->postError(2900, _t("Invalid search type"), "BrowseEngine->execute()"); break; } $vs_pk = $t_item->primaryKey(); if (is_array($va_type_ids = $this->getTypeRestrictionList()) && sizeof($va_type_ids)) { $o_search->setTypeRestrictions($va_type_ids); } $va_options = $pa_options; unset($va_options['sort']); // browse engine takes care of sort so there is no reason to waste time having the search engine do so $va_options['filterNonPrimaryRepresentations'] = true; // filter out non-primary representations in ca_objects results to save (a bit) of time $qr_res = $o_search->search($va_row_ids[0], $va_options); if ($qr_res->numHits() > 0) { $va_ids = array(); $va_id_list = $qr_res->getPrimaryKeyValues(); foreach ($va_id_list as $vn_id) { $va_ids[] = "({$vn_id})"; } $this->opo_db->query("INSERT IGNORE INTO ca_browses_acc VALUES " . join(",", $va_ids)); $vn_i++; } } else { $this->postError(2900, _t("Invalid criteria type"), "BrowseEngine->execute()"); } break; # ----------------------------------------------------- } } $vs_filter_join_sql = $vs_filter_where_sql = ''; $va_wheres = array(); $va_joins = array(); $vs_sql_distinct = ''; if (sizeof($this->opa_result_filters)) { $va_joins[$this->ops_browse_table_name] = "INNER JOIN " . $this->ops_browse_table_name . " ON " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_browses_acc.row_id'; $va_tmp = array(); foreach ($this->opa_result_filters as $va_filter) { $vm_val = $this->_filterValueToQueryValue($va_filter); $va_wheres[] = $this->ops_browse_table_name . '.' . $va_filter['field'] . " " . $va_filter['operator'] . " " . $vm_val; } } if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_item->hasField('access')) { $va_joins[$this->ops_browse_table_name] = "INNER JOIN " . $this->ops_browse_table_name . " ON " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_browses_acc.row_id'; $va_wheres[] = "(" . $this->ops_browse_table_name . ".access IN (" . join(',', $pa_options['checkAccess']) . "))"; } if ((!isset($pa_options['showDeleted']) || !$pa_options['showDeleted']) && $t_item->hasField('deleted')) { if (!isset($va_joins[$this->ops_browse_table_name])) { $va_joins[$this->ops_browse_table_name] = "INNER JOIN " . $this->ops_browse_table_name . " ON " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_browses_acc.row_id'; } $va_wheres[] = "(" . $this->ops_browse_table_name . ".deleted = 0)"; } if (isset($pa_options['limitToModifiedOn']) && $pa_options['limitToModifiedOn']) { $o_tep = new TimeExpressionParser(); if ($o_tep->parse($pa_options['limitToModifiedOn'])) { $va_range = $o_tep->getUnixTimestamps(); $va_joins['ca_change_log_subjects'] = "INNER JOIN ca_change_log_subjects ON ca_change_log_subjects.subject_row_id = ca_browses_acc.row_id AND ca_change_log_subjects.subject_table_num = " . $t_item->tableNum(); $va_joins['ca_change_log'] = "INNER JOIN ca_change_log ON ca_change_log.log_id = ca_change_log_subjects.log_id"; $va_wheres[] = "(((ca_change_log.log_datetime BETWEEN " . (int) $va_range['start'] . " AND " . (int) $va_range['end'] . ") AND (ca_change_log.changetype IN ('I', 'U', 'D'))))"; $vs_sql_distinct = 'DISTINCT'; // need to pull distinct rows since joining the change log can cause dupes } } if (($va_browse_type_ids = $this->getTypeRestrictionList()) && sizeof($va_browse_type_ids)) { $t_subject = $this->getSubjectInstance(); $va_joins[$this->ops_browse_table_name] = "INNER JOIN " . $this->ops_browse_table_name . " ON " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_browses_acc.row_id'; $va_wheres[] = '(' . $this->ops_browse_table_name . '.' . $t_subject->getTypeFieldName() . ' IN (' . join(', ', $va_browse_type_ids) . '))'; } if (sizeof($va_wheres)) { $vs_filter_where_sql = 'WHERE ' . join(' AND ', $va_wheres); } if (sizeof($va_joins)) { $vs_filter_join_sql = join("\n", $va_joins); } $qr_res = $this->opo_db->query("\n\t\t\t\t\t\tSELECT {$vs_sql_distinct} row_id\n\t\t\t\t\t\tFROM ca_browses_acc\n\t\t\t\t\t\t{$vs_filter_join_sql}\n\t\t\t\t\t\t{$vs_filter_where_sql}\n\t\t\t\t\t"); while ($qr_res->nextRow()) { $va_results[] = $qr_res->get('row_id', array('binary' => true)); } $this->_dropTempTable('ca_browses_acc'); $this->_dropTempTable('ca_browses_tmp'); if ((!isset($pa_options['dontFilterByACL']) || !$pa_options['dontFilterByACL']) && $this->opo_config->get('perform_item_level_access_checking') && method_exists($t_item, "supportsACL") && $t_item->supportsACL()) { $va_results = array_keys($this->filterHitsByACL(array_flip($va_results), $vn_user_id, __CA_ACL_READONLY_ACCESS__)); } $this->opo_ca_browse_cache->setResults($va_results); $vb_need_to_save_in_cache = true; } } else { // no criteria - don't try to find anything unless configured to do so $va_settings = $this->opo_ca_browse_config->getAssoc($this->ops_browse_table_name); if (isset($va_settings['show_all_for_no_criteria_browse']) && $va_settings['show_all_for_no_criteria_browse']) { $va_wheres = $va_joins = array(); $vs_pk = $t_item->primaryKey(); if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_item->hasField('access')) { $va_wheres[] = "(" . $this->ops_browse_table_name . ".access IN (" . join(',', $pa_options['checkAccess']) . "))"; } if ((!isset($pa_options['showDeleted']) || !$pa_options['showDeleted']) && $t_item->hasField('deleted')) { $va_wheres[] = "(" . $this->ops_browse_table_name . ".deleted = 0)"; } if (isset($pa_options['limitToModifiedOn']) && $pa_options['limitToModifiedOn']) { $o_tep = new TimeExpressionParser(); if ($o_tep->parse($pa_options['limitToModifiedOn'])) { $va_range = $o_tep->getUnixTimestamps(); $va_joins['ca_change_log_subjects'] = "INNER JOIN ca_change_log_subjects ON ca_change_log_subjects.subject_row_id = " . $this->ops_browse_table_name . ".{$vs_pk} AND ca_change_log_subjects.subject_table_num = " . $t_item->tableNum(); $va_joins['ca_change_log'] = "INNER JOIN ca_change_log ON ca_change_log.log_id = ca_change_log_subjects.log_id"; $va_wheres[] = "(((ca_change_log.log_datetime BETWEEN " . (int) $va_range['start'] . " AND " . (int) $va_range['end'] . ") AND (ca_change_log.changetype IN ('I', 'U', 'D'))))"; $vs_sql_distinct = 'DISTINCT'; // need to pull distinct rows since joining the change log can cause dupes } } if (($va_browse_type_ids = $this->getTypeRestrictionList()) && sizeof($va_browse_type_ids)) { $t_subject = $this->getSubjectInstance(); $va_wheres[] = '(' . $this->ops_browse_table_name . '.' . $t_subject->getTypeFieldName() . ' IN (' . join(', ', $va_browse_type_ids) . '))'; } if (sizeof($va_wheres)) { $vs_filter_where_sql = 'WHERE ' . join(' AND ', $va_wheres); } if (sizeof($va_joins)) { $vs_filter_join_sql = join("\n", $va_joins); } $qr_res = $this->opo_db->query("\n\t\t\t\t\t\tSELECT {$vs_pk}\n\t\t\t\t\t\tFROM " . $t_item->tableName() . "\n\t\t\t\t\t\t{$vs_filter_join_sql}\n\t\t\t\t\t\t{$vs_filter_where_sql}\n\t\t\t\t\t"); $va_results = $qr_res->getAllFieldValues($vs_pk); if ((!isset($pa_options['dontFilterByACL']) || !$pa_options['dontFilterByACL']) && $this->opo_config->get('perform_item_level_access_checking') && method_exists($t_item, "supportsACL") && $t_item->supportsACL()) { $va_results = array_keys($this->filterHitsByACL(array_flip($va_results), $vn_user_id, __CA_ACL_READONLY_ACCESS__)); } $this->opo_ca_browse_cache->setResults($va_results); } else { $this->opo_ca_browse_cache->setResults(array()); } $vb_need_to_save_in_cache = true; } if ($vb_need_to_cache_facets) { if (!$pa_options['dontCheckFacetAvailability']) { $this->loadFacetContent($pa_options); } } if ($vb_need_to_save_in_cache) { $this->opo_ca_browse_cache->save(); } return true; }
/** * Export a record set as defined by the given search expression and the table_num for this exporter. * This function wraps the record-level exports using the settings 'wrap_before' and 'wrap_after' if they are set. * @param string $ps_exporter_code defines the exporter to use * @param string $ps_expression A valid search expression * @param string $ps_filename Destination filename (we can't keep everything in memory here) * @param array $pa_options * showCLIProgressBar = Show command-line progress bar. Default is false. * @return boolean success state */ public static function exportRecordsFromSearchExpression($ps_exporter_code, $ps_expression, $ps_filename, $pa_options = array()) { ca_data_exporters::$s_exporter_cache = array(); ca_data_exporters::$s_exporter_item_cache = array(); $vb_show_cli_progress_bar = isset($pa_options['showCLIProgressBar']) && $pa_options['showCLIProgressBar']; $po_request = isset($pa_options['request']) ? $pa_options['request'] : null; if (!($t_mapping = ca_data_exporters::loadExporterByCode($ps_exporter_code))) { return false; } $va_errors = ca_data_exporters::checkMapping($ps_exporter_code); if (sizeof($va_errors) > 0) { if ($po_request && isset($pa_options['progressCallback']) && ($ps_callback = $pa_options['progressCallback'])) { $ps_callback($po_request, 0, -1, _t('Export failed: %1', join("; ", $va_errors)), 0, memory_get_usage(true), 0); } return false; } $vn_start_time = time(); $vs_wrap_before = $t_mapping->getSetting('wrap_before'); $vs_wrap_after = $t_mapping->getSetting('wrap_after'); $t_instance = $t_mapping->getAppDatamodel()->getInstanceByTableNum($t_mapping->get('table_num')); $o_search = caGetSearchInstance($t_mapping->get('table_num')); $o_result = $o_search->search($ps_expression); $vn_num_items = $o_result->numHits(); if ($vs_wrap_before) { file_put_contents($ps_filename, $vs_wrap_before . "\n", FILE_APPEND); } if ($vb_show_cli_progress_bar) { print CLIProgressBar::start($vn_num_items, _t('Processing search result')); } if ($po_request && isset($pa_options['progressCallback']) && ($ps_callback = $pa_options['progressCallback'])) { if ($vn_num_items > 0) { $ps_callback($po_request, 0, $vn_num_items, _t("Exporting result for search expression '%1'", $ps_expression), time() - $vn_start_time, memory_get_usage(true), 0); } else { $ps_callback($po_request, 0, -1, _t('Found no records to export'), time() - $vn_start_time, memory_get_usage(true), 0); } } $vn_num_processed = 0; while ($o_result->nextHit()) { $vs_item_export = ca_data_exporters::exportRecord($ps_exporter_code, $o_result->get($t_instance->primaryKey())); file_put_contents($ps_filename, $vs_item_export . "\n", FILE_APPEND); if ($vb_show_cli_progress_bar) { print CLIProgressBar::next(1, _t("Exporting records ...")); } $vn_num_processed++; if ($po_request && isset($pa_options['progressCallback']) && ($ps_callback = $pa_options['progressCallback'])) { $ps_callback($po_request, $vn_num_processed, $vn_num_items, _t("Exporting ... [%1/%2]", $vn_num_processed, $vn_num_items), time() - $vn_start_time, memory_get_usage(true), $vn_num_processed); } } if ($vs_wrap_after) { file_put_contents($ps_filename, $vs_wrap_after . "\n", FILE_APPEND); } if ($vb_show_cli_progress_bar) { print CLIProgressBar::finish(); } if ($po_request && isset($pa_options['progressCallback']) && ($ps_callback = $pa_options['progressCallback'])) { $ps_callback($po_request, $vn_num_items, $vn_num_items, _t('Export completed'), time() - $vn_start_time, memory_get_usage(true), $vn_num_processed); } return true; }