/** * Converts the given list of source names or source_ids into an expanded list of numeric source_ids suitable for enforcing source restrictions. Processing * includes expansion of sources to include subsources and conversion of any source codes to source_ids. * * @param mixed $pm_table_name_or_num Table name or number to which sources apply * @param array $pa_sources List of source codes and/or source_ids that are the basis of the list * @param array $pa_options Array of options: * dont_include_subsources_in_source_restriction = if set, returned list is not expanded to include subsources * dontIncludeSubsourcesInSourceRestriction = synonym for dont_include_subsources_in_source_restriction * * @return array List of numeric source_ids */ function caMakeSourceIDList($pm_table_name_or_num, $pa_sources, $pa_options = null) { $o_dm = Datamodel::load(); if (isset($pa_options['dontIncludeSubsourcesInSourceRestriction']) && (!isset($pa_options['dont_include_subsources_in_source_restriction']) || !$pa_options['dont_include_subsources_in_source_restriction'])) { $pa_options['dont_include_subsources_in_source_restriction'] = $pa_options['dontIncludeSubsourcesInSourceRestriction']; } if (isset($pa_options['dont_include_subsources_in_source_restriction']) && $pa_options['dont_include_subsources_in_source_restriction']) { $pa_options['noChildren'] = true; } if (is_numeric($pm_table_name_or_num)) { $vs_table_name = $o_dm->getTableName($pm_table_name_or_num); } else { $vs_table_name = $pm_table_name_or_num; } $t_instance = $o_dm->getInstanceByTableName($vs_table_name, true); if (!$t_instance) { return null; } // bad table if (!($vs_source_list_code = $t_instance->getSourceListCode())) { return null; } // table doesn't use sources $va_source_ids = array(); $t_list = new ca_lists(); $t_item = new ca_list_items(); $vs_list_code = $t_instance->getSourceListCode(); foreach ($pa_sources as $vm_source) { if (!$vm_source) { continue; } $vn_source_id = null; if (is_numeric($vm_source)) { $vn_source_id = (int) $vm_source; } else { $vn_source_id = (int) $t_list->getItemIDFromList($vs_source_list_code, $vm_source); } if ($vn_source_id && !(isset($pa_options['noChildren']) || $pa_options['noChildren'])) { if ($qr_children = $t_item->getHierarchy($vn_source_id, array())) { while ($qr_children->nextRow()) { $va_source_ids[$qr_children->get('item_id')] = true; } } } else { if ($vn_source_id) { $va_source_ids[$vn_source_id] = true; } } } return array_keys($va_source_ids); }
/** * * * @param array $pa_type_codes_or_ids List of type codes or ids * @param array $pa_options Options include * dontExpandHierarchically = * @return array List of type_ids */ private function _convertTypeCodesToIDs($pa_type_codes_or_ids, $pa_options = null) { $vs_md5 = caMakeCacheKeyFromOptions($pa_type_codes_or_ids); if (isset(BrowseEngine::$s_type_id_cache[$vs_md5])) { return BrowseEngine::$s_type_id_cache[$vs_md5]; } if (isset($pa_options['instance']) && is_object($pa_options['instance'])) { $t_instance = $pa_options['instance']; } else { $t_instance = $this->getSubjectInstance(); } $va_type_ids = array(); if (!$pa_type_codes_or_ids) { return false; } if (is_array($pa_type_codes_or_ids) && !sizeof($pa_type_codes_or_ids)) { return false; } if (!is_array($pa_type_codes_or_ids)) { $pa_type_codes_or_ids = array($pa_type_codes_or_ids); } $t_list = new ca_lists(); if (!method_exists($t_instance, 'getTypeListCode')) { return false; } if (!($vs_list_name = $t_instance->getTypeListCode())) { return false; } $va_type_list = $t_instance->getTypeList(); foreach ($pa_type_codes_or_ids as $vs_code_or_id) { if (!trim($vs_code_or_id)) { continue; } if (!is_numeric($vs_code_or_id)) { $vn_type_id = $t_list->getItemIDFromList($vs_list_name, $vs_code_or_id); } else { $vn_type_id = (int) $vs_code_or_id; } if (!$vn_type_id) { return false; } if (isset($va_type_list[$vn_type_id]) && $va_type_list[$vn_type_id]) { // is valid type for this subject // See if there are any child types if (!caGetOption('dontExpandHierarchically', $pa_options, false) && !$this->opb_dont_expand_type_restrictions) { $t_item = new ca_list_items(); $va_ids = $t_item->getHierarchy($vn_type_id, array('idsOnly' => true)); } $va_ids[] = $vn_type_id; $va_type_ids = array_merge($va_type_ids, $va_ids); } } $va_type_ids = array_keys(array_flip($va_type_ids)); BrowseEngine::$s_type_id_cache[$vs_md5] = $va_type_ids; return $va_type_ids; }
/** * Converts the given list of list item idnos or item_ids into an expanded list of numeric item_ids. Processing * includes expansion of items to include sub-items and conversion of any idnos to item_ids. * * @param mixed $pm_table_name_or_num Table name or number to which types apply * @param array $pa_types List of item idnos and/or item_ids that are the basis of the list * @param array $pa_options Array of options: * dont_include_sub_items = if set, returned list is not expanded to include sub-items * dontIncludeSubItems = synonym for dont_include_sub_items * transaction = transaction to perform database operations within. [Default is null] * * @return array List of numeric item_ids */ public static function getItemIDsFromList($pm_list_name_or_id, $pa_idnos, $pa_options = null) { if (isset($pa_options['dontIncludeSubItems']) && (!isset($pa_options['dont_include_sub_items']) || !$pa_options['dont_include_sub_items'])) { $pa_options['dont_include_sub_items'] = $pa_options['dontIncludeSubItems']; } if (isset($pa_options['dont_include_sub_items']) && $pa_options['dont_include_sub_items']) { $pa_options['noChildren'] = true; } $t_list = new ca_lists(); $t_item = new ca_list_items(); if ($o_trans = caGetOption('transaction', $pa_options, null)) { $t_list->setTransaction($o_trans); $t_item->setTransaction($o_trans); } $va_tmp = $va_item_ids = array(); foreach ($pa_idnos as $vs_idno) { $vn_item_id = null; if (is_numeric($vs_idno)) { $va_tmp = array((int) $vs_idno); } else { $va_tmp = ca_list_items::find(array('idno' => $vs_idno, 'deleted' => 0), array('returnAs' => 'ids', 'transaction' => $o_trans)); } if (sizeof($va_tmp) && !(isset($pa_options['noChildren']) || $pa_options['noChildren'])) { foreach ($va_tmp as $vn_item_id) { if ($qr_children = $t_item->getHierarchy($vn_item_id, array())) { while ($qr_children->nextRow()) { $va_item_ids[$qr_children->get('item_id')] = true; } } } } else { foreach ($va_tmp as $vn_item_id) { $va_item_ids[$vn_item_id] = true; } } } return array_keys($va_item_ids); }
/** * Returns number of elements in system * * @param $pb_root_elements_only boolean If true, then only root elements are counted; default is false * @param $pm_table_name_or_num mixed Optional table name or number to filter list with. If specified then only elements that have a type restriction to the table are counted. If omitted (default) then all elements, regardless of type restrictions, are returned. * @param $pm_type_name_or_id mixed Optional type code or type_id to restrict elements to. If specified then only elements that have a type restriction to the specified table and type are counted. * @return int The number of elements */ public static function getElementCount($pb_root_elements_only = false, $pm_table_name_or_num = null, $pm_type_name_or_id = null) { $o_dm = Datamodel::load(); $vn_table_num = $o_dm->getTableNum($pm_table_name_or_num); $vo_db = new Db(); $va_wheres = array(); if ($pb_root_elements_only) { $va_wheres[] = 'cme.parent_id is NULL'; } if ($vn_table_num) { $va_wheres[] = 'cmtr.table_num = ?'; $va_where_params[] = (int) $vn_table_num; if ($pm_type_name_or_id) { $t_list_item = new ca_list_items(); if (!is_numeric($pm_type_name_or_id)) { $t_list_item->load(array('idno' => $pm_type_name_or_id)); } else { $t_list_item->load((int) $pm_type_name_or_id); } $va_type_ids = array(); if ($vn_type_id = $t_list_item->getPrimaryKey()) { $va_type_ids[$vn_type_id] = true; if ($qr_children = $t_list_item->getHierarchy($vn_type_id, array())) { while ($qr_children->nextRow()) { $va_type_ids[$qr_children->get('item_id')] = true; } } $va_wheres[] = '((cmtr.type_id = ?) OR (cmtr.include_subtypes = 1 AND cmtr.type_id IN (?)))'; $va_where_params[] = (int) $vn_type_id; $va_where_params[] = $va_type_ids; } } $vs_wheres = ' WHERE ' . join(' AND ', $va_wheres); $qr_tmp = $vo_db->query("\n\t\t\t\tSELECT count(*) c\n\t\t\t\tFROM ca_metadata_elements cme\n\t\t\t\tINNER JOIN ca_metadata_type_restrictions AS cmtr ON cme.hier_element_id = cmtr.element_id\n\t\t\t\t{$vs_wheres}\n\t\t\t", $va_where_params); } else { if (sizeof($va_wheres)) { $vs_wheres = ' WHERE ' . join(' AND ', $va_wheres); } else { $vs_wheres = ''; } $qr_tmp = $vo_db->query("\n\t\t\t\tSELECT count(*) c\n\t\t\t\tFROM ca_metadata_elements cme\n\t\t\t\t{$vs_wheres}\n\t\t\t"); } if ($qr_tmp->nextRow()) { return $qr_tmp->get('c'); } return 0; }
/** * Converts the given list of list item idnos or item_ids into an expanded list of numeric item_ids. Processing * includes expansion of items to include sub-items and conversion of any idnos to item_ids. * * @param mixed $pm_table_name_or_num Table name or number to which types apply * @param array $pa_types List of item idnos and/or item_ids that are the basis of the list * @param array $pa_options Array of options: * dont_include_sub_items = if set, returned list is not expanded to include sub-items * dontIncludeSubItems = synonym for dont_include_sub_items * * @return array List of numeric item_ids */ public static function getItemIDsFromList($pm_list_name_or_id, $pa_idnos, $pa_options = null) { if (isset($pa_options['dontIncludeSubItems']) && (!isset($pa_options['dont_include_sub_items']) || !$pa_options['dont_include_sub_items'])) { $pa_options['dont_include_sub_items'] = $pa_options['dontIncludeSubItems']; } if (isset($pa_options['dont_include_sub_items']) && $pa_options['dont_include_sub_items']) { $pa_options['noChildren'] = true; } $t_list = new ca_lists(); $t_item = new ca_list_items(); $va_item_ids = array(); foreach ($pa_idnos as $vs_idno) { $vn_item_id = null; if (is_numeric($vs_idno)) { $vn_item_id = (int) $vs_idno; } else { $vn_item_id = (int) $t_list->getItemIDFromList($pm_list_name_or_id, $vs_idno); } if ($vn_item_id && !(isset($pa_options['noChildren']) || $pa_options['noChildren'])) { if ($qr_children = $t_item->getHierarchy($vn_item_id, array())) { while ($qr_children->nextRow()) { $va_item_ids[$qr_children->get('item_id')] = true; } } } else { if ($vn_item_id) { $va_item_ids[$vn_item_id] = true; } } } return array_keys($va_item_ids); }
/** * 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; }