public function Index() { # # User-generated comments, tags and ratings # $t_siteComments = new SiteComments(); $va_user_comments = $t_siteComments->getComments(null, true); $va_comments = array(); if (is_array($va_user_comments)) { foreach ($va_user_comments as $va_user_comment) { $va_comment = array(); if ($va_user_comment["comment"]) { $va_comment["comment"] = $va_user_comment["comment"]; # TODO: format date based on locale $va_comment["date"] = date("n/j/Y", $va_user_comment["created_on"]); $va_comment["created_on"] = $va_user_comment["created_on"]; # -- get name of commenter $t_user = new ca_users($va_user_comment["user_id"]); $va_comment["author"] = $t_user->getName(); $va_comment["email"] = $va_user_comment["email"]; $va_comment["name"] = $va_user_comment["name"]; $va_comments[] = $va_comment; } } } $this->view->setVar('comments', $va_comments); $this->render('Comments/comments_html.php'); }
public function renderWidget($ps_widget_id, &$pa_settings) { parent::renderWidget($ps_widget_id, $pa_settings); $vn_threshold = time() - $pa_settings['logins_since'] * 60 * 60; $o_db = new Db(); $qr_res = $o_db->query("\n\t\t\t\tSELECT e.code, e.message, e.date_time\n\t\t\t\tFROM ca_eventlog e\n\t\t\t\tWHERE\n\t\t\t\t\t(e.date_time >= ?) AND (e.code = 'LOGN')\n\t\t\t\tORDER BY\n\t\t\t\t\te.date_time DESC\n\t\t\t", $vn_threshold); $va_login_list = array(); $t_user = new ca_users(); $va_user_cache = array(); while ($qr_res->nextRow()) { $va_log = $qr_res->getRow(); $vs_message = $va_log['message']; $va_tmp = explode(';', $vs_message); $vs_username = '******'; if (preg_match('!\'([^\']+)\'!', $va_tmp[0], $va_matches)) { $vs_username = $va_matches[1]; } $va_log['username'] = $vs_username; if (!isset($va_user_cache[$vs_username])) { if ($t_user->load(array('user_name' => $vs_username))) { $va_user_cache[$vs_username] = array('fname' => $t_user->get('fname'), 'lname' => $t_user->get('lname'), 'email' => $t_user->get('email')); } else { $va_user_cache[$vs_username] = array('fname' => '?', 'lname' => '?', 'email' => '?'); } } $va_log = array_merge($va_log, $va_user_cache[$vs_username]); $va_log['ip'] = str_replace('IP=', '', $va_tmp[1]); $va_login_list[] = $va_log; } $this->opo_view->setVar('request', $this->getRequest()); $this->opo_view->setVar('login_list', $va_login_list); return $this->opo_view->render('main_html.php'); }
public static function authenticate($ps_username, $ps_password = '', $pa_options = null) { $t_user = new ca_users(); $t_user->load($ps_username); if ($t_user->getPrimaryKey() > 0) { $vs_hash = $t_user->get('password'); if (preg_match('/^[a-f0-9]{32}$/', $vs_hash)) { // old-style md5 passwords //throw new CaUsersException(_t('The stored password for this user seems to be in legacy format. Please update the user account by resetting the password.')); if (md5($ps_password) == $vs_hash) { // if the md5 hash matches, authenticate successfully and move the user over to pbkdf2 key $t_user->setMode(ACCESS_WRITE); // ca_users::update takes care of the hashing by calling AuthenticationManager::updatePassword() $t_user->set('password', $ps_password); $t_user->update(); return true; } else { return false; } } return validate_password($ps_password, $vs_hash); } else { return false; } }
public function testBooleanOperators() { $vo_acr = AccessRestrictions::load(true); // OR $va_access_restrictions = array("administrate/setup/list_editor/ListEditorController" => array("default" => array("operator" => "OR", "actions" => array("can_edit_ca_lists", "can_create_ca_lists", "can_delete_ca_lists")))); $vo_acr->opa_acr = $va_access_restrictions; // no role -> can't access controller $this->opt_role->setMode(ACCESS_WRITE); $this->opt_role->setRoleActions(array()); $this->opt_role->update(); ca_users::$s_user_action_access_cache = array(); $vb_access = $vo_acr->userCanAccess($this->opt_user->getPrimaryKey(), array("administrate", "setup", "list_editor"), "ListEditor", "Edit"); $this->assertFalse($vb_access); // has one of the OR-ed roles -> can access controller $this->opt_role->setMode(ACCESS_WRITE); $va_actions = $va_access_restrictions["administrate/setup/list_editor/ListEditorController"]["default"]["actions"]; $this->opt_role->setRoleActions(array($va_actions[array_rand($va_actions)])); $this->opt_role->update(); ca_users::$s_user_action_access_cache = array(); $vb_access = $vo_acr->userCanAccess($this->opt_user->getPrimaryKey(), array("administrate", "setup", "list_editor"), "ListEditor", "Edit"); $this->assertTrue($vb_access); // AND $va_access_restrictions = array("administrate/setup/list_editor/ListEditorController" => array("default" => array("operator" => "AND", "actions" => array("can_edit_ca_lists", "can_create_ca_lists", "can_delete_ca_lists")))); $vo_acr->opa_acr = $va_access_restrictions; // no role -> can't access controller $this->opt_role->setMode(ACCESS_WRITE); $this->opt_role->setRoleActions(array()); $this->opt_role->update(); ca_users::$s_user_action_access_cache = array(); $vb_access = $vo_acr->userCanAccess($this->opt_user->getPrimaryKey(), array("administrate", "setup", "list_editor"), "ListEditor", "Edit"); $this->assertFalse($vb_access); // has one of the AND-ed roles -> can't access controller $this->opt_role->setMode(ACCESS_WRITE); $va_actions = $va_access_restrictions["administrate/setup/list_editor/ListEditorController"]["default"]["actions"]; $this->opt_role->setRoleActions(array($va_actions[array_rand($va_actions)])); $this->opt_role->update(); ca_users::$s_user_action_access_cache = array(); $vb_access = $vo_acr->userCanAccess($this->opt_user->getPrimaryKey(), array("administrate", "setup", "list_editor"), "ListEditor", "Edit"); $this->assertFalse($vb_access); // has all AND-ed roles -> can access controller $this->opt_role->setMode(ACCESS_WRITE); $this->opt_role->setRoleActions($va_actions); $this->opt_role->update(); ca_users::$s_user_action_access_cache = array(); $vb_access = $vo_acr->userCanAccess($this->opt_user->getPrimaryKey(), array("administrate", "setup", "list_editor"), "ListEditor", "Edit"); $this->assertTrue($vb_access); }
/** * */ public static function send($pn_user_id, $ps_message) { global $AUTH_CURRENT_USER_ID, $g_request; if (!function_exists("curl_init")) { return false; } if ($pn_user_id == $AUTH_CURRENT_USER_ID) { $t_user = $g_request->user; // use request user object } else { $t_user = new ca_users($pn_user_id); } if (!$t_user->getPrimaryKey()) { return null; } if (!$t_user->get('sms_number')) { return null; } if (!($vn_sendhub_contact_id = $t_user->getVar('sms_sendhub_contact_id')) || $t_user->getVar('sms_sendhub_phone_number') != $t_user->get('sms_number')) { if (!($vn_sendhub_contact_id = WLPlugSMSSendHub::addContact($t_user))) { // TODO: check and log errors here return null; } } $vs_user = $t_user->getAppConfig()->get('sms_user'); $vs_api_key = $t_user->getAppConfig()->get('sms_api_key'); $vs_url = "https://api.sendhub.com/v1/messages/?username={$vs_user}&api_key={$vs_api_key}"; $o_ch = curl_init(); $ps_message = stripslashes(rawurldecode($ps_message)); $ps_message = trim(preg_replace("!\n+!", "\\" . "n", $ps_message)); curl_setopt($o_ch, CURLOPT_URL, $vs_url); curl_setopt($o_ch, CURLOPT_HEADER, false); curl_setopt($o_ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json')); curl_setopt($o_ch, CURLOPT_POSTFIELDS, '{"contacts":[' . $vn_sendhub_contact_id . '],"text":"' . $ps_message . '"}'); curl_setopt($o_ch, CURLOPT_RETURNTRANSFER, 1); $vs_return = curl_exec($o_ch); $va_return = json_decode($vs_return); // TODO: check and log errors here curl_close($o_ch); return true; }
/** * * * @param array $pa_data * @param array $pa_options * * @return string */ function caClientServicesGetSenderName($pa_data, $pa_options = null) { global $g_caClientServicesNameCache; if (!isset($g_caClientServicesNameCache[$pa_data['from_user_id']])) { $t_user = new ca_users($pa_data['from_user_id']); return $g_caClientServicesNameCache[$pa_data['from_user_id']] = $t_user->get('fname') . ' ' . $t_user->get('lname'); } else { return $g_caClientServicesNameCache[$pa_data['from_user_id']]; } }
/** * Generates detail detail. Will use a view named according to the following convention: * <table_name>_<type_code>_detail_html.php * * So for example, the detail for objects of type 'artwork' (where 'artwork' is the type code for the artwork object type) * the view would be named "ca_objects_artwork_detail_html.php * * If the type specific view does not exist, then Show() will attemp to use a generic table-wide view name like this: * <table_name>_detail_html.php * * For example: "ca_objects_detail_html.php" * * In general you should always have the table wide views defined. Then you can define type-specific views for your * application on an as-needed basis. */ public function Show($pa_options = null) { JavascriptLoadManager::register('viz'); JavascriptLoadManager::register("ca", "panel"); JavascriptLoadManager::register("jit"); JavascriptLoadManager::register('browsable'); JavascriptLoadManager::register('imageScroller'); JavascriptLoadManager::register('jquery', 'expander'); $va_access_values = caGetUserAccessValues($this->request); $this->view->setVar('access_values', $va_access_values); if (!($t_item = $this->opo_datamodel->getInstanceByTableName($this->ops_tablename, true))) { die("Invalid table name " . $this->ops_tablename . " for detail"); // shouldn't happen } if (!($vn_item_id = $this->request->getParameter($t_item->primaryKey(), pInteger))) { $this->notification->addNotification(_t("Invalid ID"), "message"); $this->response->setRedirect(caNavUrl($this->request, "", "", "", "")); return; } if (!$t_item->load($vn_item_id)) { $this->notification->addNotification(_t("ID does not exist"), "message"); $this->response->setRedirect(caNavUrl($this->request, "", "", "", "")); return; } if ($t_item->hasField('deleted') && $t_item->get('deleted')) { $this->notification->addNotification(_t("ID has been deleted"), "message"); $this->response->setRedirect(caNavUrl($this->request, "", "", "", "")); return; } // Check if item conforms to any configured display type restrictions if (method_exists($t_item, "getTypeID")) { $va_types = caMergeTypeRestrictionLists($t_item, array()); if (is_array($va_types) && sizeof($va_types) && !in_array($t_item->getTypeID(), $va_types)) { $this->notification->addNotification(_t("This item is not viewable"), "message"); $this->response->setRedirect(caNavUrl($this->request, "", "", "", "")); return; } } # # Enforce access control # if (sizeof($va_access_values) && !in_array($t_item->get("access"), $va_access_values)) { $this->notification->addNotification(_t("This item is not available for view"), "message"); $this->response->setRedirect(caNavUrl($this->request, "", "", "", "")); return; } // // In-detail browsing of objects - limited to object linked to the item being displayed // if (($vs_browse_for_table = $this->request->config->get('allow_browse_within_detail_for_' . $this->ops_tablename)) && is_object($this->opo_browse)) { // set browse context for controller $this->setContext($this->opo_browse->getContext()); // // Restrict facets to specific group for refine browse (if set in app.conf config) // if ($vs_facet_group = $this->request->config->get('ca_objects_refine_facet_group')) { $this->opo_browse->setFacetGroup($vs_facet_group); } $t_table = $this->opo_datamodel->getInstanceByTableName($this->ops_tablename, true); if ($this->request->session->getVar($this->ops_tablename . '_' . $this->ops_appname . '_detail_current_item_id') != $vn_item_id) { $this->opo_browse->removeAllCriteria(); } // look for 'authority' facet for current detail table type so we can limit the object browse to the currently displayed item //$vs_limit_facet_name = null; //foreach($this->opo_browse->getInfoForFacets() as $vs_facet_name => $va_facet_info) { // if (($va_facet_info['type'] === 'authority') && ($va_facet_info['table'] === $this->ops_tablename)) { // $vs_limit_facet_name = $vs_facet_name; // break; // } //} $this->opo_browse->addFacetConfiguration($vs_limit_facet_name = '_detail_browse_' . $this->ops_tablename, array('type' => 'authority', 'table' => $this->ops_tablename, 'relationship_table' => 'ca_objects_x_entities', 'restrict_to_types' => array(), 'restrict_to_relationship_types' => array(), 'label_singular' => 'Detail browse by ' . $this->ops_tablename, 'label_plural' => 'Detail browse by ' . $this->ops_tablename, 'group_mode' => 'none', 'indefinite_article' => 'a')); if ($vs_limit_facet_name) { if (($va_configured_type_restrictions = $this->request->config->getList($this->ops_tablename . '_detail_browse_type_restrictions')) && is_array($va_configured_type_restrictions)) { $this->opo_browse->setTypeRestrictions($va_configured_type_restrictions, array('includeChildren' => false)); } $this->opo_browse->addCriteria($vs_limit_facet_name, array($vn_item_id)); $this->opo_browse->execute(array('checkAccess' => $va_access_values)); $this->request->session->setVar($this->ops_tablename . '_' . $this->ops_appname . '_detail_current_browse_id', $this->opo_browse->getBrowseID()); $this->view->setVar('show_browse', true); // // Browse paging // $vn_items_per_page = $this->request->config->get("objects_per_page_for_detail_pages"); if (!$vn_items_per_page) { $vn_items_per_page = 12; } $this->view->setVar('page', ($vn_p = $this->request->getParameter('page', pInteger)) ? $vn_p : 1); $qr_hits = null; if ($this->opo_browse) { $va_sort = array(); if ($vs_sort = $this->request->config->get('sort_browse_within_detail_for_' . $this->ops_tablename)) { $va_sort = array('sort' => $vs_sort); } $qr_hits = $this->opo_browse->getResults($va_sort); $vn_num_pages = ceil($qr_hits->numHits() / $vn_items_per_page); $qr_hits->seek(($vn_p - 1) * $vn_items_per_page); } else { $vn_num_pages = 0; } $this->view->setVar('browse_results', $qr_hits); $this->view->setVar('num_pages', (int) $vn_num_pages); $this->view->setVar('items_per_page', (int) $vn_items_per_page); $this->view->setVar('opo_browse', $this->opo_browse); $this->view->setVar('sorts', $this->opa_sorts); // supported sorts for the object browse // browse criteria in an easy-to-display format $va_browse_criteria = array(); foreach ($this->opo_browse->getCriteriaWithLabels() as $vs_facet_code => $va_criteria) { $va_facet_info = $this->opo_browse->getInfoForFacet($vs_facet_code); $va_criteria_list = array(); foreach ($va_criteria as $vn_criteria_id => $vs_criteria_label) { $va_criteria_list[] = $vs_criteria_label; } $va_browse_criteria[$va_facet_info['label_singular']] = join('; ', $va_criteria_list); } $this->view->setVar('browse_criteria', $va_browse_criteria); } else { // not configured for browse $this->request->session->setVar($this->ops_tablename . '_' . $this->ops_appname . '_detail_current_browse_id', null); $this->view->setVar('show_browse', false); } } $this->request->session->setVar($this->ops_tablename . '_' . $this->ops_appname . '_detail_current_item_id', $vn_item_id); # Next and previous navigation $opo_result_context = new ResultContext($this->request, $this->ops_tablename, ResultContext::getLastFind($this->request, $this->ops_tablename)); $this->view->setVar('next_id', $opo_result_context->getNextID($vn_item_id)); $this->view->setVar('previous_id', $opo_result_context->getPreviousID($vn_item_id)); # Is the item we're show details for in the result set? $this->view->setVar('is_in_result_list', $opo_result_context->getIndexInResultList($vn_item_id) != '?'); # Item instance and id $this->view->setVar('t_item', $t_item); $this->view->setVar($t_item->getPrimaryKey(), $vn_item_id); # Item - preferred $this->view->setVar('label', $t_item->getLabelForDisplay()); # Item - nonpreferred $this->view->setVar('nonpreferred_labels', caExtractValuesByUserLocale($t_item->getNonPreferredLabels())); # Item timestamps (creation and last change) if ($va_entry_info = $t_item->getCreationTimestamp()) { $this->view->setVar('date_of_entry', date('m/d/Y', $va_entry_info['timestamp'])); } if ($va_last_change_info = $t_item->getLastChangeTimestamp()) { $this->view->setVar('date_of_last_change', date('m/d/Y', $va_last_change_info['timestamp'])); } # Media representations to display (objects only) if (method_exists($t_item, 'getPrimaryRepresentationInstance')) { if ($t_primary_rep = $t_item->getPrimaryRepresentationInstance()) { if (!sizeof($va_access_values) || in_array($t_primary_rep->get('access'), $va_access_values)) { // check rep access $this->view->setVar('t_primary_rep', $t_primary_rep); $va_rep_display_info = caGetMediaDisplayInfo('detail', $t_primary_rep->getMediaInfo('media', 'INPUT', 'MIMETYPE')); $this->view->setVar('primary_rep_display_version', $va_rep_display_info['display_version']); unset($va_display_info['display_version']); $va_rep_display_info['poster_frame_url'] = $t_primary_rep->getMediaUrl('media', $va_rep_display_info['poster_frame_version']); unset($va_display_info['poster_frame_version']); $this->view->setVar('primary_rep_display_options', $va_rep_display_info); } } } # # User-generated comments, tags and ratings # $va_user_comments = $t_item->getComments(null, true); $va_comments = array(); if (is_array($va_user_comments)) { foreach ($va_user_comments as $va_user_comment) { if ($va_user_comment["comment"] || $va_user_comment["media1"] || $va_user_comment["media2"] || $va_user_comment["media3"] || $va_user_comment["media4"]) { # TODO: format date based on locale $va_user_comment["date"] = date("n/j/Y", $va_user_comment["created_on"]); # -- get name of commenter $t_user = new ca_users($va_user_comment["user_id"]); $va_user_comment["author"] = $t_user->getName(); $va_comments[] = $va_user_comment; } } } $this->view->setVar('comments', $va_comments); $va_user_tags = $t_item->getTags(null, true); $va_tags = array(); if (is_array($va_user_tags)) { foreach ($va_user_tags as $va_user_tag) { if (!in_array($va_user_tag["tag"], $va_tags)) { $va_tags[] = $va_user_tag["tag"]; } } } $this->view->setVar('tags_array', $va_tags); $this->view->setVar('tags', implode(", ", $va_tags)); $this->view->setVar('result_context', $opo_result_context); # -- get average user ranking $this->view->setVar('ranking', $t_item->getAverageRating(null)); // null makes it ignore moderation status # -- get number of user rankings $this->view->setVar('numRankings', $t_item->getNumRatings(null)); // null makes it ignore moderation status # # Miscellaneous useful information # $this->view->setVar('t_relationship_types', new ca_relationship_types()); // relationship types object - used for displaying relationship type of related authority information if (method_exists($t_item, 'getTypeName')) { $this->view->setVar('typename', $t_item->getTypeName()); } // Record view $t_item->registerItemView($this->request->getUserID()); // // Render view // if (isset($pa_options['view']) && $pa_options['view']) { $this->render($pa_options['view']); } else { if ($this->getView()->viewExists($this->ops_tablename . '_' . $t_item->getTypeCode() . '_detail_html.php')) { $this->render($this->ops_tablename . '_' . $t_item->getTypeCode() . '_detail_html.php'); } else { $this->render($this->ops_tablename . '_detail_html.php'); } } }
/** * Check if a user name exists * * @param mixed $ps_user_name_or_id The user name or numeric user_id of the user * @return boolean True if user exists, false if not */ public function exists($ps_user_name_or_id) { $t_user = new ca_users(); if ($t_user->load($ps_user_name_or_id)) { return true; } else { if ($t_user->load(array("user_name" => $ps_user_name_or_id))) { return true; } } return false; }
/** * Get list of all roles supported by the application. If you want to get the current user's roles, use getUserRoles() * * @return array Returns associative array of roles. Key is role id, value is array containing information about the role. * * The role information array contains the following keys: * role_id (numeric id you can use in addRoles(), deleteRoles(), hasRole(), etc.) * name (the full name of the role) * code (a short code used for the role) * description (narrative description of role) */ public function getRoleList() { $t_user = new ca_users(); return $t_user->getRoleList(); }
/** * Checks access control list for currently loaded row for the specified user and returns an access value. Values are: * * __CA_ACL_NO_ACCESS__ (0) * __CA_ACL_READONLY_ACCESS__ (1) * __CA_ACL_EDIT_ACCESS__ (2) * __CA_ACL_EDIT_DELETE_ACCESS__ (3) * * @param ca_users $t_user A ca_users object * @param int $pn_id Optional row_id to check ACL for; if omitted currently loaded row_id is used * @return int An access value */ public function checkACLAccessForUser($t_user, $pn_id = null) { if (!$this->supportsACL()) { return __CA_ACL_EDIT_DELETE_ACCESS__; } if (!$pn_id) { $pn_id = (int) $this->getPrimaryKey(); if (!$pn_id) { return null; } } if ($t_user->canDoAction('is_administrator')) { return __CA_ACL_EDIT_DELETE_ACCESS__; } require_once __CA_MODELS_DIR__ . '/ca_acl.php'; return ca_acl::accessForRow($t_user, $this->tableNum(), $pn_id); }
/** * @param $pa_hits Array of row_ids to filter. *MUST HAVE row_ids AS KEYS, NOT VALUES* */ public function filterHitsByACL($pa_hits, $pn_user_id, $pn_access = __CA_ACL_READONLY_ACCESS__, $pa_options = null) { if (!sizeof($pa_hits)) { return $pa_hits; } if (!(int) $pn_user_id) { $pn_user_id = 0; } if (!($t_table = $this->opo_datamodel->getInstanceByTableNum($this->opn_tablenum, true))) { return $pa_hits; } $vs_search_tmp_table = $this->loadListIntoTemporaryResultTable($pa_hits, md5(isset($pa_options['search']) ? $pa_options['search'] : rand(0, 1000000))); $vs_table_name = $t_table->tableName(); $vs_table_pk = $t_table->primaryKey(); $t_user = new ca_users($pn_user_id); if (is_array($va_groups = $t_user->getUserGroups()) && sizeof($va_groups)) { $va_group_ids = array_keys($va_groups); $vs_group_sql = ' OR (ca_acl.group_id IN (?))'; $va_params = array((int) $this->opn_tablenum, (int) $pn_user_id, $va_group_ids, (int) $pn_access); } else { $va_group_ids = null; $vs_group_sql = ''; $va_params = array((int) $this->opn_tablenum, (int) $pn_user_id, (int) $pn_access); } $va_hits = array(); if ($pn_access <= $this->opo_app_config->get('default_item_access_level')) { // Requested access is more restrictive than default access (so return items with default ACL) // Find records that have ACL that matches $qr_sort = $this->opo_db->query("\n\t\t\t\t\tSELECT ca_acl.row_id\n\t\t\t\t\tFROM ca_acl\n\t\t\t\t\tINNER JOIN {$vs_search_tmp_table} ON {$vs_search_tmp_table}.row_id = ca_acl.row_id\n\t\t\t\t\tWHERE\n\t\t\t\t\t\t(ca_acl.table_num = ?)\n\t\t\t\t\t\tAND\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\t(ca_acl.user_id = ?)\n\t\t\t\t\t\t\t{$vs_group_sql}\n\t\t\t\t\t\t\tOR \n\t\t\t\t\t\t\t(ca_acl.user_id IS NULL AND ca_acl.group_id IS NULL)\n\t\t\t\t\t\t)\n\t\t\t\t\t\tAND\n\t\t\t\t\t\t(ca_acl.access >= ?)\n\t\t\t\t", $va_params); while ($qr_sort->nextRow()) { $va_row = $qr_sort->getRow(); $va_hits[$va_row['row_id']] = true; } // Find records with default ACL $qr_sort = $this->opo_db->query("\n\t\t\t\t\tSELECT {$vs_search_tmp_table}.row_id\n\t\t\t\t\tFROM {$vs_search_tmp_table}\n\t\t\t\t\tLEFT OUTER JOIN ca_acl ON {$vs_search_tmp_table}.row_id = ca_acl.row_id AND ca_acl.table_num = ?\n\t\t\t\t\tWHERE\n\t\t\t\t\t\tca_acl.row_id IS NULL;\n\t\t\t\t", array((int) $this->opn_tablenum)); while ($qr_sort->nextRow()) { $va_row = $qr_sort->getRow(); $va_hits[$va_row['row_id']] = true; } } else { // Default access is more restrictive than requested access (so *don't* return items with default ACL) // Find records that have ACL that matches $qr_sort = $this->opo_db->query("\n\t\t\t\t\tSELECT ca_acl.row_id\n\t\t\t\t\tFROM ca_acl\n\t\t\t\t\tINNER JOIN {$vs_search_tmp_table} ON {$vs_search_tmp_table}.row_id = ca_acl.row_id\n\t\t\t\t\tWHERE\n\t\t\t\t\t\t(ca_acl.table_num = ?)\n\t\t\t\t\t\tAND\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\t(ca_acl.user_id = ?)\n\t\t\t\t\t\t\t{$vs_group_sql}\n\t\t\t\t\t\t\tOR \n\t\t\t\t\t\t\t(ca_acl.user_id IS NULL AND ca_acl.group_id IS NULL)\n\t\t\t\t\t\t)\n\t\t\t\t\t\tAND\n\t\t\t\t\t\t(ca_acl.access >= ?)\n\t\t\t\t", $va_params); while ($qr_sort->nextRow()) { $va_row = $qr_sort->getRow(); $va_hits[$va_row['row_id']] = true; } } $this->cleanupTemporaryResultTable(); return $va_hits; }
/** * Return user profile values for specified user */ public function GetUserProfileInfo() { if (!$this->request->user->canDoAction('can_manage_clients')) { return null; } $pn_user_id = $this->request->getParameter('user_id', pInteger); $t_user = new ca_users($pn_user_id); $va_profile_prefs = $t_user->getValidPreferences('profile'); if (is_array($va_profile_prefs) && sizeof($va_profile_prefs)) { $va_elements = array(); foreach ($va_profile_prefs as $vs_pref) { $va_pref_info = $t_user->getPreferenceInfo($vs_pref); $va_elements[str_replace('user_profile_', '', $vs_pref)] = array($t_user->getPreference($vs_pref)); } $this->view->setVar("profile_values", $va_elements); } $this->view->setVar("user_id", $pn_user_id); $this->render('ajax_user_profile_info_json.php'); }
function resetSave() { MetaTagManager::setWindowTitle($this->request->config->get("app_display_name") . ": " . _t("Reset Password")); $ps_action = $this->request->getParameter('action', pString); if (!$ps_action) { $ps_action = "reset"; } $ps_key = $this->request->getParameter('key', pString); $ps_key = preg_replace("/[^A-Za-z0-9]+/", "", $ps_key); $this->view->setVar("key", $ps_key); $this->view->setVar("email", $this->request->config->get("ca_admin_email")); $o_check_key = new Db(); $qr_check_key = $o_check_key->query("\n\t\t\t\tSELECT user_id \n\t\t\t\tFROM ca_users \n\t\t\t\tWHERE\n\t\t\t\t\tmd5(concat(concat(user_id, '/'), password)) = ?\n\t\t\t", $ps_key); # # Check reset key # if (!$qr_check_key->nextRow() || !($vs_user_id = $qr_check_key->get("user_id"))) { $this->view->setVar("action", "reset_failure"); $this->view->setVar("message", _t("Your password could not be reset")); $this->render('LoginReg/form_reset_html.php'); } else { $ps_password = $this->request->getParameter('password', pString); $ps_password_confirm = $this->request->getParameter('password_confirm', pString); switch ($ps_action) { case 'reset_save': if (!$ps_password || !$ps_password_confirm) { $this->view->setVar("message", _t("Please enter and re-type your password.")); $ps_action = "reset"; break; } if ($ps_password != $ps_password_confirm) { $this->view->setVar("message", _t("Passwords do not match. Please try again.")); $ps_action = "reset"; break; } $t_user = new ca_users(); $t_user->purify(true); $t_user->load($vs_user_id); # verify user exists with this e-mail address if ($t_user->getPrimaryKey()) { # user with e-mail already exists... $t_user->setMode(ACCESS_WRITE); $t_user->set("password", $ps_password); $t_user->update(); if ($t_user->numErrors()) { $this->notification->addNotification(join("; ", $t_user->getErrors()), __NOTIFICATION_TYPE_INFO__); $ps_action = "reset_failure"; } else { $ps_action = "reset_success"; $o_view = new View($this->request, array($this->request->getViewsDirectoryPath())); # -- generate email subject $vs_subject_line = $o_view->render("mailTemplates/notification_subject.tpl"); # -- generate mail text from template - get both the html and text versions $vs_mail_message_text = $o_view->render("mailTemplates/notification.tpl"); $vs_mail_message_html = $o_view->render("mailTemplates/notification_html.tpl"); caSendmail($t_user->get('email'), $this->request->config->get("ca_admin_email"), $vs_subject_line, $vs_mail_message_text, $vs_mail_message_html); } break; } else { $this->notification->addNotification(_t("Invalid user"), __NOTIFICATION_TYPE_INFO__); $ps_action = "reset_failure"; } } $this->view->setVar("action", $ps_action); $this->render('LoginReg/form_reset_html.php'); } }
public function getSetsForUser($pa_options) { if (!is_array($pa_options)) { $pa_options = array(); } $pn_user_id = isset($pa_options['user_id']) ? (int) $pa_options['user_id'] : null; $pm_table_name_or_num = isset($pa_options['table']) ? $pa_options['table'] : null; if ($pm_table_name_or_num && !($vn_table_num = $this->_getTableNum($pm_table_name_or_num))) { return null; } $pm_type = isset($pa_options['setType']) ? $pa_options['setType'] : null; $pn_access = isset($pa_options['access']) ? $pa_options['access'] : null; $pa_public_access = isset($pa_options['checkAccess']) ? $pa_options['checkAccess'] : null; if ($pa_public_access && is_numeric($pa_public_access) && !is_array($pa_public_access)) { $pa_public_access = array($pa_public_access); } for ($vn_i = 0; $vn_i < sizeof($pa_public_access); $vn_i++) { $pa_public_access[$vn_i] = intval($pa_public_access[$vn_i]); } if ($pn_user_id) { $va_extra_joins = array(); $va_sql_wheres = array("(cs.deleted = 0)"); $va_sql_params = array(); $o_db = $this->getDb(); if ($vn_table_num) { $va_sql_wheres[] = "(cs.table_num = ?)"; $va_sql_params[] = (int) $vn_table_num; } if (!is_null($pa_public_access) && is_array($pa_public_access) && sizeof($pa_public_access)) { $va_sql_wheres[] = "(cs.access IN (?))"; $va_sql_params[] = $pa_public_access; } if (isset($pm_type) && $pm_type) { if (is_numeric($pm_type)) { $va_sql_wheres[] = "(cs.type_id = ?)"; $va_sql_params[] = (int) $pm_type; } else { # --- look up code of set type $t_list = new ca_lists(); $vn_type_id = $t_list->getItemIDFromList("set_types", $pm_type); if ($vn_type_id) { $va_sql_wheres[] = "(cs.type_id = ?)"; $va_sql_params[] = (int) $vn_type_id; } } } if ($pa_options["owner"]) { $va_sql_wheres[] = "(cs.user_id = " . $pn_user_id . ")"; } else { # --- if owner is not set to true, we're finding all sets the user has access to or is owner of # --- we also check the users' access to the set if set $t_user = new ca_users(); $t_user->load($pn_user_id); if ($t_user->getPrimaryKey()) { $vs_access_sql = $pn_access > 0 ? " AND (access >= " . intval($pn_access) . ")" : ""; if (is_array($va_groups = $t_user->getUserGroups()) && sizeof($va_groups)) { $vs_sql = "(\n\t\t\t\t\t\t\t(cs.user_id = " . intval($pn_user_id) . ") OR \n\t\t\t\t\t\t\t(cs.set_id IN (\n\t\t\t\t\t\t\t\t\tSELECT set_id \n\t\t\t\t\t\t\t\t\tFROM ca_sets_x_user_groups \n\t\t\t\t\t\t\t\t\tWHERE \n\t\t\t\t\t\t\t\t\t\tgroup_id IN (" . join(',', array_keys($va_groups)) . ") {$vs_access_sql}\n\t\t\t\t\t\t\t\t\t\tAND\n\t\t\t\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\t\t\t\t (sdatetime IS NULL AND edatetime IS NULL)\n\t\t\t\t\t\t\t\t\t\t\t OR \n\t\t\t\t\t\t\t\t\t\t\t (\n\t\t\t\t\t\t\t\t\t\t\t\tsdatetime <= " . time() . " AND edatetime >= " . time() . "\n\t\t\t\t\t\t\t\t\t\t\t )\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)"; } else { $vs_sql = "(cs.user_id = {$pn_user_id})"; } $vs_sql .= " OR (cs.set_id IN (\n\t\t\t\t\t\t\t\t\t\t\tSELECT set_id \n\t\t\t\t\t\t\t\t\t\t\tFROM ca_sets_x_users \n\t\t\t\t\t\t\t\t\t\t\tWHERE \n\t\t\t\t\t\t\t\t\t\t\t\tuser_id = {$pn_user_id} {$vs_access_sql}\n\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(\n\t\t\t\t\t\t\t\t\t\t\t\t\t (sdatetime IS NULL AND edatetime IS NULL)\n\t\t\t\t\t\t\t\t\t\t\t\t\t OR \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\tsdatetime <= " . time() . " AND edatetime >= " . time() . "\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)\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t)"; $va_sql_wheres[] = "({$vs_sql})"; } } $qr_res = $o_db->query("SELECT cs.set_id, cs.user_id, type_id, cu.fname, cu.lname\n\t\t\t\t\t\t\t\t\tFROM ca_sets cs\n\t\t\t\t\t\t\t\t\tINNER JOIN ca_users AS cu ON cs.user_id = cu.user_id\n\t\t\t\t\t\t\t\t\t" . join("\n", $va_extra_joins) . "\n\t\t\t\t\t\t\t\t\t" . (sizeof($va_sql_wheres) ? "WHERE " : "") . " " . join(" AND ", $va_sql_wheres) . "\n\t\t\t\t\t\t\t\t\t", $va_sql_params); $va_sets = array(); $t_list = new ca_lists(); while ($qr_res->nextRow()) { $vn_table_num = $qr_res->get('table_num'); if (!isset($va_type_name_cache[$vn_table_num]) || !($vs_set_type = $va_type_name_cache[$vn_table_num])) { $vs_set_type = $va_type_name_cache[$vn_table_num] = $this->getSetContentTypeName($vn_table_num, array('number' => 'plural')); } $vs_type = $t_list->getItemFromListForDisplayByItemID('set_types', $qr_res->get('type_id')); $va_sets[$qr_res->get('set_id')] = array_merge($qr_res->getRow(), array('set_content_type' => $vs_set_type, 'set_type' => $vs_type)); } return $va_sets; } else { return false; } }
/** * Determines if user has access to a set at a specified access level. * * @param int $pn_user_id user_id of user to check set access for * @param int $pn_access type of access required. Use __CA_SET_READ_ACCESS__ for read-only access or __CA_SET_EDIT_ACCESS__ for editing (full) access * @param int $pn_set_id The id of the set to check. If omitted then currently loaded set will be checked. * @param array $pa_options No options yet * @return bool True if user has access, false if not */ public function haveAccessToSet($pn_user_id, $pn_access, $pn_set_id = null, $pa_options = null) { if ($this->getAppConfig()->get('dont_enforce_access_control_for_ca_sets')) { return true; } if ($pn_set_id) { $vn_set_id = $pn_set_id; $t_set = new ca_sets($vn_set_id); $vn_set_user_id = $t_set->get('user_id'); } else { $t_set = $this; $vn_set_user_id = $t_set->get('user_id'); } if (!$vn_set_id && !($vn_set_id = $t_set->getPrimaryKey())) { return true; // new set } if ($t_set->get('deleted') != 0) { return false; } // set is deleted if (isset(ca_sets::$s_have_access_to_set_cache[$vn_set_id . '/' . $pn_user_id . '/' . $pn_access])) { return ca_sets::$s_have_access_to_set_cache[$vn_set_id . '/' . $pn_user_id . '/' . $pn_access]; } if ($vn_set_user_id == $pn_user_id) { // owners have all access return ca_sets::$s_have_access_to_set_cache[$vn_set_id . '/' . $pn_user_id . '/' . $pn_access] = true; } if ($t_set->get('access') > 0 && $pn_access == __CA_SET_READ_ACCESS__) { // public sets are readable by all return ca_sets::$s_have_access_to_set_cache[$vn_set_id . '/' . $pn_user_id . '/' . $pn_access] = true; } // // If user is admin or has set admin privs allow them access to the set // $t_user = new ca_users(); if ($t_user->load($pn_user_id) && ($t_user->canDoAction('is_administrator') || $t_user->canDoAction('can_administrate_sets'))) { return ca_sets::$s_have_access_to_set_cache[$vn_set_id . '/' . $pn_user_id . '/' . $pn_access] = true; } $o_db = $this->getDb(); $qr_res = $o_db->query($vs_sql = "\n\t\t\tSELECT sxg.set_id \n\t\t\tFROM ca_sets_x_user_groups sxg \n\t\t\tINNER JOIN ca_user_groups AS ug ON sxg.group_id = ug.group_id\n\t\t\tINNER JOIN ca_users_x_groups AS uxg ON uxg.group_id = ug.group_id\n\t\t\tWHERE \n\t\t\t\t(sxg.access >= ?) AND (uxg.user_id = ?) AND (sxg.set_id = ?)\n\t\t\t\tAND\n\t\t\t\t(\n\t\t\t\t\t(sxg.sdatetime <= " . time() . " AND sxg.edatetime >= " . time() . ")\n\t\t\t\t\tOR\n\t\t\t\t\t(sxg.sdatetime IS NULL and sxg.edatetime IS NULL)\n\t\t\t\t)\n\t\t", (int) $pn_access, (int) $pn_user_id, (int) $vn_set_id); if ($qr_res->numRows() > 0) { return ca_sets::$s_have_access_to_set_cache[$vn_set_id . '/' . $pn_user_id . '/' . $pn_access] = true; } $qr_res = $o_db->query("\n\t\t\tSELECT sxu.set_id \n\t\t\tFROM ca_sets_x_users sxu\n\t\t\tINNER JOIN ca_users AS u ON sxu.user_id = u.user_id\n\t\t\tWHERE \n\t\t\t\t(sxu.access >= ?) AND (u.user_id = ?) AND (sxu.set_id = ?)\n\t\t\t\tAND\n\t\t\t\t(\n\t\t\t\t\t(sxu.sdatetime <= " . time() . " AND sxu.edatetime >= " . time() . ")\n\t\t\t\t\tOR\n\t\t\t\t\tsxu.sdatetime IS NULL and sxu.edatetime IS NULL\n\t\t\t\t)\n\t\t", (int) $pn_access, (int) $pn_user_id, (int) $vn_set_id); if ($qr_res->numRows() > 0) { return ca_sets::$s_have_access_to_set_cache[$vn_set_id . '/' . $pn_user_id . '/' . $pn_access] = true; } return ca_sets::$s_have_access_to_set_cache[$vn_set_id . '/' . $pn_user_id . '/' . $pn_access] = false; }
/** * Reset user password */ public static function reset_password($po_opts = null) { if ($vs_user_name = (string) $po_opts->getOption('user')) { if (!($vs_password = (string) $po_opts->getOption('password'))) { CLIUtils::addError(_t("You must specify a password")); return false; } $t_user = new ca_users(); if (!$t_user->load(array("user_name" => $vs_user_name))) { CLIUtils::addError(_t("User name %1 does not exist", $vs_user_name)); return false; } $t_user->setMode(ACCESS_WRITE); $t_user->set('password', $vs_password); $t_user->update(); if ($t_user->numErrors()) { CLIUtils::addError(_t("Password change for user %1 failed: %2", $vs_user_name, join("; ", $t_user->getErrors()))); return false; } CLIUtils::addMessage(_t('Changed password for user %1', $vs_user_name), array('color' => 'bold_green')); return true; } CLIUtils::addError(_t("You must specify a user")); return false; }
public function DoReset() { if (!AuthenticationManager::supports(__CA_AUTH_ADAPTER_FEATURE_RESET_PASSWORDS__)) { $this->Login(); return; } $vs_token = $this->getRequest()->getParameter('token', pString); $vs_username = $this->getRequest()->getParameter('username', pString); $t_user = new ca_users(); $vs_pw = $this->getRequest()->getParameter('password', pString); $vs_pw_check = $this->getRequest()->getParameter('password2', pString); if ($t_user->load($vs_username)) { if ($t_user->isValidToken($vs_token)) { // no password match if ($vs_pw !== $vs_pw_check) { $this->notification->addNotification(_t("Passwords did not match. Please try again."), __NOTIFICATION_TYPE_ERROR__); $this->view->setVar('notifications', $this->notification->getNotifications()); $this->view->setVar('renderForm', true); $this->view->setVar('token', $vs_token); $this->view->setVar('username', $vs_username); $this->render('password_reset_form_html.php'); } else { $t_user->set('password', $vs_pw); $t_user->setMode(ACCESS_WRITE); $t_user->update(); $this->notification->addNotification(_t("Password was successfully changed. You can now log in with your new password."), __NOTIFICATION_TYPE_INFO__); $this->view->setVar('notifications', $this->notification->getNotifications()); $this->Login(); } } } }
public function search($pn_subject_tablenum, $ps_search_expression, $pa_filters = array(), $po_rewritten_query = null) { $va_solr_search_filters = array(); $vn_i = 0; $va_old_signs = is_object($po_rewritten_query) ? $po_rewritten_query->getSigns() : array(); $va_terms = $va_signs = array(); if ($po_rewritten_query) { foreach ($po_rewritten_query->getSubqueries() as $o_lucene_query_element) { if (!$va_old_signs || !is_array($va_old_signs)) { // if array is null then according to Zend Lucene all subqueries should be "are required"... so we AND them $vs_op = "AND"; } else { if (is_null($va_old_signs[$vn_i])) { // is the sign for a particular query is null then OR is (it is "neither required nor prohibited") $vs_op = 'OR'; } else { $vs_op = $va_old_signs[$vn_i] === false ? 'NOT' : 'AND'; // true sign indicated "required" (AND) operation, false indicated "prohibited" (NOT) operation } } if ($vn_i == 0) { $vs_op = 'OR'; } // advanced search queries are for some reason nested 1-element boolean queries in boolean queries if (get_class($o_lucene_query_element) == 'Zend_Search_Lucene_Search_Query_Boolean') { $va_subqueries = $o_lucene_query_element->getSubqueries(); if (sizeof($va_subqueries) == 1) { $o_lucene_query_element = array_shift($va_subqueries); } } switch ($vs_class = get_class($o_lucene_query_element)) { case 'Zend_Search_Lucene_Search_Query_Term': case 'Zend_Search_Lucene_Search_Query_MultiTerm': case 'Zend_Search_Lucene_Search_Query_Phrase': $vs_access_point = ''; if ($vs_class != 'Zend_Search_Lucene_Search_Query_Term') { $va_raw_terms = array(); foreach ($o_lucene_query_element->getQueryTerms() as $o_term) { if (!$vs_access_point && ($vs_field = $o_term->field)) { $vs_access_point = $vs_field; } $va_raw_terms[] = $vs_text = (string) $o_term->text; } $vs_term = join(" ", $va_raw_terms); } else { $vs_access_point = $o_lucene_query_element->getTerm()->field; $vs_term = $o_lucene_query_element->getTerm()->text; } if ($vs_access_point) { list($vs_table, $vs_field, $vs_sub_field) = explode('.', $vs_access_point); if (in_array($vs_table, array('created', 'modified'))) { if (!$this->opo_tep->parse($vs_term)) { break; } $va_range = $this->opo_tep->getUnixTimestamps(); $vn_user_id = null; if ($vs_field = trim($vs_field)) { if (!is_int($vs_field)) { $t_user = new ca_users(); if ($t_user->load(array("user_name" => $vs_field))) { $vn_user_id = (int) $t_user->getPrimaryKey(); } } else { $vn_user_id = (int) $vs_field; } } $vs_user_sql = $vn_user_id ? " AND (ccl.user_id = " . (int) $vn_user_id . ")" : ""; switch ($vs_table) { case 'created': if ($vn_user_id) { $o_lucene_query_element = new Zend_Search_Lucene_Search_Query_Boolean(array(new Zend_Search_Lucene_Index_Term('[' . $this->opo_tep->getText(array('start_as_iso8601' => true)) . " TO " . $this->opo_tep->getText(array('end_as_iso8601' => true)) . ']', 'created'), new Zend_Search_Lucene_Index_Term($vn_user_id, 'created_user_id')), array(true, true)); } else { $o_lucene_query_element = new Zend_Search_Lucene_Search_Query_Term(new Zend_Search_Lucene_Index_Term('[' . $this->opo_tep->getText(array('start_as_iso8601' => true)) . " TO " . $this->opo_tep->getText(array('end_as_iso8601' => true)) . ']', 'created')); } break; case 'modified': if ($vn_user_id) { $o_lucene_query_element = new Zend_Search_Lucene_Search_Query_Boolean(array(new Zend_Search_Lucene_Index_Term('[' . $this->opo_tep->getText(array('start_as_iso8601' => true)) . " TO " . $this->opo_tep->getText(array('end_as_iso8601' => true)) . ']', 'modified'), new Zend_Search_Lucene_Index_Term($vn_user_id, 'modified_user_id')), array(true, true)); } else { $o_lucene_query_element = new Zend_Search_Lucene_Search_Query_Term(new Zend_Search_Lucene_Index_Term('[' . $this->opo_tep->getText(array('start_as_iso8601' => true)) . " TO " . $this->opo_tep->getText(array('end_as_iso8601' => true)) . ']', 'modified')); } break; } } else { if ($vs_table && $vs_field) { $t_table = $this->opo_datamodel->getInstanceByTableName($vs_table, true); if ($t_table) { $vs_table_num = $t_table->tableNum(); if (is_numeric($vs_field)) { $vs_fld_num = 'I' . $vs_field; $vn_fld_num = (int) $vs_field; } else { $vn_fld_num = $this->getFieldNum($vs_table, $vs_field); $vs_fld_num = 'I' . $vn_fld_num; if (!strlen($vn_fld_num)) { $t_element = new ca_metadata_elements(); if ($t_element->load(array('element_code' => $vs_sub_field ? $vs_sub_field : $vs_field))) { $vn_fld_num = $t_element->getPrimaryKey(); $vs_fld_num = 'A' . $vn_fld_num; // // For certain types of attributes we can directly query the // attributes in the database rather than using the full text index // This allows us to do "intelligent" querying... for example on date ranges // parsed from natural language input and for length dimensions using unit conversion // switch ($t_element->get('datatype')) { case 2: // dates $vb_exact = $vs_term[0] == "#" ? true : false; // dates prepended by "#" are considered "exact" or "contained - the matched dates must be wholly contained by the search term if ($vb_exact) { $vs_raw_term = substr($vs_term, 1); if ($this->opo_tep->parse($vs_term)) { $va_dates = $this->opo_tep->getHistoricTimestamps(); // TODO: fix date handling to reflect distinctions in ranges $o_lucene_query_element = new Zend_Search_Lucene_Search_Query_Term(new Zend_Search_Lucene_Index_Term('[' . $this->opo_tep->getText(array('start_as_iso8601' => true)) . " TO " . $this->opo_tep->getText(array('end_as_iso8601' => true)) . ']', $vs_table . '.' . $vs_fld_num)); } } else { if ($this->opo_tep->parse($vs_term)) { $va_dates = $this->opo_tep->getHistoricTimestamps(); // TODO: fix date handling to reflect distinctions in ranges $o_lucene_query_element = new Zend_Search_Lucene_Search_Query_Term(new Zend_Search_Lucene_Index_Term('[' . $this->opo_tep->getText(array('start_as_iso8601' => true)) . " TO " . $this->opo_tep->getText(array('end_as_iso8601' => true)) . ']', $vs_table . '.' . $vs_fld_num)); } } break; case 4: // geocode $t_geocode = new GeocodeAttributeValue(); if ($va_coords = caParseGISSearch($vs_term)) { $o_lucene_query_element = new Zend_Search_Lucene_Search_Query_Term(new Zend_Search_Lucene_Index_Term('[' . $va_coords['min_latitude'] . ',' . $va_coords['min_longitude'] . " TO " . $va_coords['max_latitude'] . ',' . $va_coords['max_longitude'] . ']', $vs_table . '.' . $vs_fld_num)); } break; case 6: // currency $t_cur = new CurrencyAttributeValue(); $va_parsed_value = $t_cur->parseValue($vs_term, $t_element->getFieldValuesArray()); $vn_amount = (double) $va_parsed_value['value_decimal1']; $vs_currency = preg_replace('![^A-Z0-9]+!', '', $va_parsed_value['value_longtext1']); $o_lucene_query_element = new Zend_Search_Lucene_Search_Query_Term(new Zend_Search_Lucene_Index_Term($vn_amount, $vs_table . '.' . $vs_fld_num)); break; case 8: // length $t_len = new LengthAttributeValue(); $va_parsed_value = $t_len->parseValue($vs_term, $t_element->getFieldValuesArray()); $vn_len = (double) $va_parsed_value['value_decimal1']; // this is always in meters so we can compare this value to the one in the database $o_lucene_query_element = new Zend_Search_Lucene_Search_Query_Term(new Zend_Search_Lucene_Index_Term($vn_len, $vs_table . '.' . $vs_fld_num)); break; case 9: // weight $t_weight = new WeightAttributeValue(); $va_parsed_value = $t_weight->parseValue($vs_term, $t_element->getFieldValuesArray()); $vn_weight = (double) $va_parsed_value['value_decimal1']; // this is always in kilograms so we can compare this value to the one in the database $o_lucene_query_element = new Zend_Search_Lucene_Search_Query_Term(new Zend_Search_Lucene_Index_Term($vn_weight, $vs_table . '.' . $vs_fld_num)); break; case 10: // timecode $t_timecode = new TimecodeAttributeValue(); $va_parsed_value = $t_timecode->parseValue($vs_term, $t_element->getFieldValuesArray()); $vn_timecode = (double) $va_parsed_value['value_decimal1']; $o_lucene_query_element = new Zend_Search_Lucene_Search_Query_Term(new Zend_Search_Lucene_Index_Term($vn_timecode, $vs_table . '.' . $vs_fld_num)); break; case 11: // integer $o_lucene_query_element = new Zend_Search_Lucene_Search_Query_Term(new Zend_Search_Lucene_Index_Term((double) $vs_term, $vs_table . '.' . $vs_fld_num)); break; case 12: // decimal $o_lucene_query_element = new Zend_Search_Lucene_Search_Query_Term(new Zend_Search_Lucene_Index_Term((double) $vs_term, $vs_table . '.' . $vs_fld_num)); break; default: // everything else $o_lucene_query_element->getTerm()->field = $vs_table . '.' . $vs_fld_num; break; } } else { $vn_fld_num = false; $vs_fld_num = $vs_field; } } } } } } } break; } $va_terms[] = $o_lucene_query_element; $va_signs[] = is_array($va_old_signs) ? array_key_exists($vn_i, $va_old_signs) ? $va_old_signs[$vn_i] : true : true; $vn_i++; } $o_rewritten_query = new Zend_Search_Lucene_Search_Query_Boolean($va_terms, $va_signs); $ps_search_expression = $this->_queryToString($o_rewritten_query); } if (is_array($pa_filters) && sizeof($pa_filters) && ($vs_filter_query = $this->_filterValueToQueryValue($pa_filters))) { $ps_search_expression = "({$ps_search_expression}) AND ({$vs_filter_query})"; } if (preg_match_all("!([A-Za-z0-9_\\-\\.]+)[/]{1}([A-Za-z0-9_\\-]+):(\"[^\"]*\")!", $ps_search_expression, $va_matches) || preg_match_all("!([A-Za-z0-9_\\-\\.]+)[/]{1}([A-Za-z0-9_\\-]+):([^ ]*)!", $ps_search_expression, $va_matches)) { foreach ($va_matches[0] as $vn_i => $vs_element) { $vs_fld = $va_matches[1][$vn_i]; if (!($vs_rel_type = trim($va_matches[2][$vn_i]))) { continue; } $va_tmp = explode(".", $vs_fld); $vs_rel_table = caGetRelationshipTableName($pn_subject_tablenum, $va_tmp[0]); $va_rel_type_ids = $vs_rel_type && $vs_rel_table ? caMakeRelationshipTypeIDList($vs_rel_table, array($vs_rel_type)) : null; $va_new_elements = array(); foreach ($va_rel_type_ids as $vn_rel_type_id) { $va_new_elements[] = "(" . $va_matches[1][$vn_i] . "/" . $vn_rel_type_id . ":" . $va_matches[3][$vn_i] . ")"; } $ps_search_expression = str_replace($vs_element, "(" . join(" OR ", $va_new_elements) . ")", $ps_search_expression); } } $ps_search_expression = str_replace("/", '\\/', $ps_search_expression); // escape forward slashes used to delimit relationship type qualifier Debug::msg("[SOLR] Running query {$ps_search_expression}"); try { $vo_http_client = new Zend_Http_Client(); $vo_http_client->setUri($this->ops_search_solr_url . "/" . $this->opo_datamodel->getTableName($pn_subject_tablenum) . "/select"); $vo_http_client->setParameterGet($va_get = array('q' => utf8_decode($ps_search_expression), 'wt' => 'json', 'fl' => $this->opo_datamodel->getTablePrimaryKeyName($pn_subject_tablenum), 'start' => $this->getOption('start'), 'rows' => $this->getOption('limit'))); $vo_http_response = $vo_http_client->request(); $va_result = json_decode($vo_http_response->getBody(), true); } catch (Exception $e) { caLogEvent('ERR', _t('Could not connect to SOLR server: %1', $e->getMessage()), 'Solr->search()'); $va_result["response"]["docs"] = array(); } return new WLPlugSearchEngineSolrResult($va_result["response"]["docs"], $pn_subject_tablenum); }
/** * Perform client services-related periodic tasks */ public function hookPeriodicTask(&$pa_params) { $t_log = new Eventlog(); $o_db = new Db(); if (!(bool) $this->opo_config->get('enable_library_services')) { return true; } if ((bool) $this->opo_config->get('enable_object_checkout')) { $t_user = new ca_users(); $t_checkout = new ca_object_checkouts(); $vs_app_name = $this->opo_config->get('app_display_name'); $vs_sender_name = $this->opo_library_services_config->get('notification_sender_name'); $vs_sender_email = $this->opo_library_services_config->get('notification_sender_email'); if (!is_array($va_administrative_email_addresses = $this->opo_library_services_config->getList('administrative_email_addresses'))) { $va_administrative_email_addresses = array(); } // Periodic "coming due" notices if ($this->opo_library_services_config->get('send_coming_due_notices') && ($vs_interval = $this->opo_library_services_config->get('coming_due_interval'))) { try { $va_items_by_user = ca_object_checkouts::getItemsDueWithin($vs_interval, array('groupBy' => 'user_id', 'template' => $this->opo_library_services_config->get('coming_due_item_display_template'), 'notificationInterval' => $this->opo_library_services_config->get('coming_due_notification_interval'))); foreach ($va_items_by_user as $vn_user_id => $va_items_for_user) { if ($t_user->load($vn_user_id)) { if ($vs_user_email = $t_user->get('email')) { $vs_subject = _t('Notice of items coming due for return'); if (caSendMessageUsingView(null, $vs_user_email, $vs_sender_email, "[{$vs_app_name}] {$vs_subject}", "library_coming_due.tpl", array('subject' => $vs_subject, 'from_user_id' => $vn_user_id, 'sender_name' => $vs_sender_name, 'sender_email' => $vs_sender_email, 'sent_on' => time(), 'items' => $va_items_for_user), null, $va_administrative_email_addresses)) { // mark record foreach ($va_items_for_user as $va_item) { if ($t_checkout->load($va_item['checkout_id'])) { $t_checkout->setMode(ACCESS_WRITE); $t_checkout->set('last_sent_coming_due_email', _t('now')); $t_checkout->update(); if ($t_checkout->numErrors()) { $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Could not mark checkout coming due message sent time because update failed: %1', join("; ", $t_checkout->getErrors())), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask')); } } else { $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Could not mark checkout coming due message sent time because checkout id %1 was not found', $va_item['checkout_id']), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask')); } } } } else { // no email $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('No email address set for user %1 (%2)', $t_user->get('user_name'), trim($t_user->get('fname') . ' ' . $t_user->get('lname'))), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask')); } } else { // invalid user $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('User id %1 does not exist', $vn_user_id), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask')); } } } catch (Exception $e) { $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Invalid interval (%1) specified for coming due notices', $vs_interval), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask')); } } // Periodic overdue notices if ($this->opo_library_services_config->get('send_overdue_notices')) { try { $va_items_by_user = ca_object_checkouts::getOverdueItems(array('groupBy' => 'user_id', 'template' => $this->opo_library_services_config->get('overdue_item_display_template'), 'notificationInterval' => $this->opo_library_services_config->get('overdue_notification_interval'))); foreach ($va_items_by_user as $vn_user_id => $va_items_for_user) { if ($t_user->load($vn_user_id)) { if ($vs_user_email = $t_user->get('email')) { $vs_subject = _t('Notice of overdue items'); if (caSendMessageUsingView(null, $vs_user_email, $vs_sender_email, "[{$vs_app_name}] {$vs_subject}", "library_overdue.tpl", array('subject' => $vs_subject, 'from_user_id' => $vn_user_id, 'sender_name' => $vs_sender_name, 'sender_email' => $vs_sender_email, 'sent_on' => time(), 'items' => $va_items_for_user), null, $va_administrative_email_addresses)) { // mark record foreach ($va_items_for_user as $va_item) { if ($t_checkout->load($va_item['checkout_id'])) { $t_checkout->setMode(ACCESS_WRITE); $t_checkout->set('last_sent_overdue_email', _t('now')); $t_checkout->update(); if ($t_checkout->numErrors()) { $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Could not mark checkout overdue message sent time because update failed: %1', join("; ", $t_checkout->getErrors())), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask')); } } else { $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Could not mark checkout overdue message sent time because checkout id %1 was not found', $va_item['checkout_id']), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask')); } } } } else { // no email $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('No email address set for user %1 (%2)', $t_user->get('user_name'), trim($t_user->get('fname') . ' ' . $t_user->get('lname'))), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask')); } } else { // invalid user $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('User id %1 does not exist', $vn_user_id), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask')); } } } catch (Exception $e) { $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Failed to get overdue list'), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask')); } } // Notice when reservation becomes available if ($this->opo_library_services_config->get('send_reservation_available_notices')) { try { $va_items_by_user = ca_object_checkouts::getReservedAvailableItems(array('groupBy' => 'user_id', 'template' => $this->opo_library_services_config->get('overdue_item_display_template'), 'notificationInterval' => $this->opo_library_services_config->get('reservation_available_notification_interval'))); foreach ($va_items_by_user as $vn_user_id => $va_items_for_user) { if ($t_user->load($vn_user_id)) { if ($vs_user_email = $t_user->get('email')) { $vs_subject = _t('Notice of reserved available items'); if (caSendMessageUsingView(null, $vs_user_email, $vs_sender_email, "[{$vs_app_name}] {$vs_subject}", "library_reservation_available.tpl", array('subject' => $vs_subject, 'from_user_id' => $vn_user_id, 'sender_name' => $vs_sender_name, 'sender_email' => $vs_sender_email, 'sent_on' => time(), 'items' => $va_items_for_user), null, $va_administrative_email_addresses)) { // mark record foreach ($va_items_for_user as $va_item) { if ($t_checkout->load($va_item['checkout_id'])) { $t_checkout->setMode(ACCESS_WRITE); $t_checkout->set('last_reservation_available_email', _t('now')); $t_checkout->update(); if ($t_checkout->numErrors()) { $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Could not mark reserved available message sent time because update failed: %1', join("; ", $t_checkout->getErrors())), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask')); } } else { $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Could not mark reserved available message sent time because checkout id %1 was not found', $va_item['checkout_id']), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask')); } } } } else { // no email $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('No email address set for user %1 (%2)', $t_user->get('user_name'), trim($t_user->get('fname') . ' ' . $t_user->get('lname'))), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask')); } } else { // invalid user $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('User id %1 does not exist', $vn_user_id), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask')); } } } catch (Exception $e) { $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Failed to get reserved available list'), 'SOURCE' => 'libraryServicesPlugin->hookPeriodicTask')); } } } return true; }
/** * */ public function SaveTransaction() { $ps_item_list = $this->request->getParameter('item_list', pString); $pa_item_list = json_decode($ps_item_list, true); $t_checkout = new ca_object_checkouts(); $va_ret = array('status' => 'OK', 'errors' => array(), 'checkins' => array()); foreach ($pa_item_list as $vn_i => $va_item) { if ($t_checkout->load($va_item['checkout_id'])) { $vn_object_id = $t_checkout->get('object_id'); $t_object = new ca_objects($vn_object_id); if ($t_checkout->isOut()) { try { $t_checkout->checkin($vn_object_id, $va_item['note'], array('request' => $this->request)); $t_user = new ca_users($t_checkout->get('user_id')); $vs_user_name = $t_user->get('ca_users.fname') . ' ' . $t_user->get('ca_users.lname'); $vs_borrow_date = $t_checkout->get('ca_object_checkouts.checkout_date', array('timeOmit' => true)); if ($t_checkout->numErrors() == 0) { $va_ret['checkins'][] = _t('Returned <em>%1</em> (%2) borrowed by %3 on %4', $t_object->get('ca_objects.preferred_labels.name'), $t_object->get('ca_objects.idno'), $vs_user_name, $vs_borrow_date); } else { $va_ret['errors'][] = _t('Could not check in <em>%1</em> (%2): %3', $t_object->get('ca_objects.preferred_labels.name'), $t_object->get('ca_objects.idno'), join("; ", $t_checkout->getErrors())); } } catch (Exception $e) { $va_ret['errors'][] = _t('<em>%1</em> (%2) is not out', $t_object->get('ca_objects.preferred_labels.name'), $t_object->get('ca_objects.idno')); } } else { $va_ret['errors'][] = _t('<em>%1</em> (%2) is not out', $t_object->get('ca_objects.preferred_labels.name'), $t_object->get('ca_objects.idno')); } } } $this->view->setVar('data', $va_ret); $this->render('checkin/ajax_data_json.php'); }
private function _doQueriesForSqlSearch($po_rewritten_query, $pn_subject_tablenum, $ps_dest_table, $pn_level = 0) { // query is always of type Zend_Search_Lucene_Search_Query_Boolean $vn_i = 0; $va_old_signs = $po_rewritten_query->getSigns(); foreach ($po_rewritten_query->getSubqueries() as $o_lucene_query_element) { $vb_is_blank_search = false; if (is_null($va_old_signs)) { // if array is null then according to Zend Lucene all subqueries should be "are required"... so we AND them $vs_op = "AND"; } else { if (is_null($va_old_signs[$vn_i])) { // is the sign for a particular query is null then OR is (it is "neither required nor prohibited") $vs_op = 'OR'; } else { $vs_op = $va_old_signs[$vn_i] === false ? 'NOT' : 'AND'; // true sign indicated "required" (AND) operation, false indicated "prohibited" (NOT) operation } } if ($vn_i == 0) { $vs_op = 'OR'; } $va_direct_query_temp_tables = array(); // List of temporary tables created by direct search queries; tables listed here are dropped at the end of processing for the query element switch (get_class($o_lucene_query_element)) { case 'Zend_Search_Lucene_Search_Query_Boolean': $this->_createTempTable('ca_sql_search_temp_' . $pn_level); $this->_doQueriesForSqlSearch($o_lucene_query_element, $pn_subject_tablenum, 'ca_sql_search_temp_' . $pn_level, $pn_level + 1); // merge with current destination switch ($vs_op) { case 'AND': // and $this->_createTempTable($ps_dest_table . '_acc'); if ($vn_i == 0) { $vs_sql = "\n\t\t\t\t\t\t\t\t\tINSERT IGNORE INTO {$ps_dest_table}\n\t\t\t\t\t\t\t\t\tSELECT DISTINCT row_id, boost\n\t\t\t\t\t\t\t\t\tFROM ca_sql_search_temp_{$pn_level}\n\t\t\t\t\t\t\t\t"; //print "$vs_sql<hr>"; $qr_res = $this->opo_db->query($vs_sql); } else { $vs_sql = "\n\t\t\t\t\t\t\t\t\tINSERT IGNORE INTO {$ps_dest_table}_acc\n\t\t\t\t\t\t\t\t\tSELECT mfs.row_id, SUM(mfs.boost)\n\t\t\t\t\t\t\t\t\tFROM {$ps_dest_table} mfs\n\t\t\t\t\t\t\t\t\tINNER JOIN ca_sql_search_temp_{$pn_level} AS ftmp1 ON ftmp1.row_id = mfs.row_id\n\t\t\t\t\t\t\t\t\tGROUP BY mfs.row_id\n\t\t\t\t\t\t\t\t"; //print "$vs_sql<hr>"; $qr_res = $this->opo_db->query($vs_sql); $qr_res = $this->opo_db->query("TRUNCATE TABLE {$ps_dest_table}"); $qr_res = $this->opo_db->query("INSERT INTO {$ps_dest_table} SELECT row_id, boost FROM {$ps_dest_table}_acc"); } $this->_dropTempTable($ps_dest_table . '_acc'); break; case 'NOT': $vs_sql = "\n\t\t\t\t\t\t\t\tDELETE FROM {$ps_dest_table} WHERE row_id IN\n\t\t\t\t\t\t\t\t(SELECT row_id FROM ca_sql_search_temp_{$pn_level})\n\t\t\t\t\t\t\t"; //print "$vs_sql<hr>"; $qr_res = $this->opo_db->query($vs_sql); break; default: case 'OR': // or $vs_sql = "\n\t\t\t\t\t\t\t\tINSERT IGNORE INTO {$ps_dest_table}\n\t\t\t\t\t\t\t\tSELECT row_id, SUM(boost)\n\t\t\t\t\t\t\t\tFROM ca_sql_search_temp_{$pn_level}\n\t\t\t\t\t\t\t\tGROUP BY row_id\n\t\t\t\t\t\t\t"; //print "$vs_sql<hr>"; $qr_res = $this->opo_db->query($vs_sql); break; } $this->_dropTempTable('ca_sql_search_temp_' . $pn_level); break; case 'Zend_Search_Lucene_Search_Query_Term': case 'Zend_Search_Lucene_Search_Query_MultiTerm': case 'Zend_Search_Lucene_Search_Query_Phrase': case 'Zend_Search_Lucene_Search_Query_Range': $va_ft_terms = array(); $va_ft_like_terms = array(); $va_ft_stem_terms = array(); $vs_direct_sql_query = null; $pa_direct_sql_query_params = null; // set to array with values to use with direct SQL query placeholders or null to pass single standard table_num value as param (most queries just need this single value) $va_tmp = array(); $vs_access_point = ''; $va_raw_terms = array(); switch (get_class($o_lucene_query_element)) { case 'Zend_Search_Lucene_Search_Query_Range': $va_lower_term = $o_lucene_query_element->getLowerTerm(); $va_upper_term = $o_lucene_query_element->getUpperTerm(); $va_element = $this->_getElementIDForAccessPoint($va_lower_term->field); switch ($va_element['datatype']) { case 4: // geocode $t_geocode = new GeocodeAttributeValue(); $va_parsed_value = $t_geocode->parseValue($va_lower_term->text, $va_element['element_info']); $vs_lower_lat = $va_parsed_value['value_decimal1']; $vs_lower_long = $va_parsed_value['value_decimal2']; $va_parsed_value = $t_geocode->parseValue($va_upper_term->text, $va_element['element_info']); $vs_upper_lat = $va_parsed_value['value_decimal1']; $vs_upper_long = $va_parsed_value['value_decimal2']; $vs_direct_sql_query = "\n\t\t\t\t\t\t\t\t\t\tSELECT ca.row_id, 1\n\t\t\t\t\t\t\t\t\t\tFROM ca_attribute_values cav\n\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_attributes AS ca ON ca.attribute_id = cav.attribute_id\n\t\t\t\t\t\t\t\t\t\t^JOIN\n\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t(cav.element_id = " . intval($va_element['element_id']) . ") AND (ca.table_num = ?)\n\t\t\t\t\t\t\t\t\t\t\tAND\n\t\t\t\t\t\t\t\t\t\t\t(cav.value_decimal1 BETWEEN " . floatval($vs_lower_lat) . " AND " . floatval($vs_upper_lat) . ")\n\t\t\t\t\t\t\t\t\t\t\tAND\n\t\t\t\t\t\t\t\t\t\t\t(cav.value_decimal2 BETWEEN " . floatval($vs_lower_long) . " AND " . floatval($vs_upper_long) . ")\t\n\t\t\t\t\t\t\t\t\t"; break; case 6: // currency $t_cur = new CurrencyAttributeValue(); $va_parsed_value = $t_cur->parseValue($va_lower_term->text, $va_element['element_info']); $vs_currency = preg_replace('![^A-Z0-9]+!', '', $va_parsed_value['value_longtext1']); $vn_lower_val = $va_parsed_value['value_decimal1']; $va_parsed_value = $t_cur->parseValue($va_upper_term->text, $va_element['element_info']); $vn_upper_val = $va_parsed_value['value_decimal1']; $vs_direct_sql_query = "\n\t\t\t\t\t\t\t\t\t\tSELECT ca.row_id, 1\n\t\t\t\t\t\t\t\t\t\tFROM ca_attribute_values cav\n\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_attributes AS ca ON ca.attribute_id = cav.attribute_id\n\t\t\t\t\t\t\t\t\t\t^JOIN\n\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t(cav.element_id = " . intval($va_element['element_id']) . ") AND (ca.table_num = ?)\n\t\t\t\t\t\t\t\t\t\t\tAND\n\t\t\t\t\t\t\t\t\t\t\t(cav.value_decimal1 BETWEEN " . floatval($vn_lower_val) . " AND " . floatval($vn_upper_val) . ")\n\t\t\t\t\t\t\t\t\t\t\tAND\n\t\t\t\t\t\t\t\t\t\t\t(cav.value_longtext1 = '" . $this->opo_db->escape($vs_currency) . "')\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t"; break; case 10: // timecode $t_timecode = new TimecodeAttributeValue(); $va_parsed_value = $t_timecode->parseValue($va_lower_term->text, $va_element['element_info']); $vn_lower_val = $va_parsed_value['value_decimal1']; $va_parsed_value = $t_timecode->parseValue($va_upper_term->text, $va_element['element_info']); $vn_upper_val = $va_parsed_value['value_decimal1']; break; case 8: // length $t_len = new LengthAttributeValue(); $va_parsed_value = $t_len->parseValue($va_lower_term->text, $va_element['element_info']); $vn_lower_val = $va_parsed_value['value_decimal1']; $va_parsed_value = $t_len->parseValue($va_upper_term->text, $va_element['element_info']); $vn_upper_val = $va_parsed_value['value_decimal1']; break; case 9: // weight $t_weight = new WeightAttributeValue(); $va_parsed_value = $t_weight->parseValue($va_lower_term->text, $va_element['element_info']); $vn_lower_val = $va_parsed_value['value_decimal1']; $va_parsed_value = $t_weight->parseValue($va_upper_term->text, $va_element['element_info']); $vn_upper_val = $va_parsed_value['value_decimal1']; break; case 11: // integer $vn_lower_val = intval($va_lower_term->text); $vn_upper_val = intval($va_upper_term->text); $vs_direct_sql_query = "\n\t\t\t\t\t\t\t\t\t\tSELECT ca.row_id, 1\n\t\t\t\t\t\t\t\t\t\tFROM ca_attribute_values cav\n\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_attributes AS ca ON ca.attribute_id = cav.attribute_id\n\t\t\t\t\t\t\t\t\t\t^JOIN\n\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t(cav.element_id = " . intval($va_element['element_id']) . ") AND (ca.table_num = ?)\n\t\t\t\t\t\t\t\t\t\t\tAND\n\t\t\t\t\t\t\t\t\t\t\t(cav.value_integer1 BETWEEN " . floatval($vn_lower_val) . " AND " . floatval($vn_upper_val) . ")\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t"; break; case 12: // decimal $vn_lower_val = floatval($va_lower_term->text); $vn_upper_val = floatval($va_upper_term->text); break; } if (!$vs_direct_sql_query) { $vs_direct_sql_query = "\n\t\t\t\t\t\t\t\t\tSELECT ca.row_id, 1\n\t\t\t\t\t\t\t\t\tFROM ca_attribute_values cav\n\t\t\t\t\t\t\t\t\tINNER JOIN ca_attributes AS ca ON ca.attribute_id = cav.attribute_id\n\t\t\t\t\t\t\t\t\t^JOIN\n\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t(cav.element_id = " . intval($va_element['element_id']) . ") AND (ca.table_num = ?)\n\t\t\t\t\t\t\t\t\t\tAND\n\t\t\t\t\t\t\t\t\t\t(cav.value_decimal1 BETWEEN " . floatval($vn_lower_val) . " AND " . floatval($vn_upper_val) . ")\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t"; } break; case 'Zend_Search_Lucene_Search_Query_Phrase': $va_words = array(); foreach ($o_lucene_query_element->getQueryTerms() as $o_term) { if (!$vs_access_point && ($vs_field = $o_term->field)) { $vs_access_point = $vs_field; } $va_raw_terms[] = $vs_text = (string) $o_term->text; if (strlen($vs_escaped_text = $this->opo_db->escape($vs_text))) { $va_words[] = $vs_escaped_text; } } if (!sizeof($va_words)) { continue 3; } $va_ap_tmp = explode(".", $vs_access_point); $vn_fld_table = $vn_fld_num = null; if (sizeof($va_ap_tmp) == 2) { $va_element = $this->_getElementIDForAccessPoint($vs_access_point); if ($va_element) { $vs_fld_num = $va_element['field_num']; $vs_fld_table_num = $va_element['table_num']; $vs_fld_limit_sql = " AND (swi.field_table_num = {$vs_fld_table_num} AND swi.field_num = '{$vs_fld_num}')"; } } $va_temp_tables = array(); $vn_w = 0; foreach ($va_words as $vs_word) { $vn_w++; $vs_temp_table = 'ca_sql_search_phrase_' . md5($pn_subject_tablenum . "/" . $vs_word . "/" . $vn_w); $this->_createTempTable($vs_temp_table); $vs_sql = "\n\t\t\t\t\t\t\t\t\tINSERT INTO {$vs_temp_table}\n\t\t\t\t\t\t\t\t\tSELECT swi.index_id + 1, 1\n\t\t\t\t\t\t\t\t\tFROM ca_sql_search_words sw \n\t\t\t\t\t\t\t\t\tINNER JOIN ca_sql_search_word_index AS swi ON sw.word_id = swi.word_id \n\t\t\t\t\t\t\t\t\t" . (sizeof($va_temp_tables) ? " INNER JOIN " . $va_temp_tables[sizeof($va_temp_tables) - 1] . " AS tt ON swi.index_id = tt.row_id" : "") . "\n\t\t\t\t\t\t\t\t\tWHERE \n\t\t\t\t\t\t\t\t\t\tsw.word = ? AND swi.table_num = ? {$vs_fld_limit_sql}\n \t\t\t\t\t\t\t\t\t\t" . ($this->getOption('omitPrivateIndexing') ? " AND swi.access = 0" : '') . "\n\t\t\t\t\t\t\t\t"; $qr_res = $this->opo_db->query($vs_sql, $vs_word, (int) $pn_subject_tablenum); $qr_count = $this->opo_db->query("SELECT count(*) c FROM {$vs_temp_table}"); if (!$qr_count->nextRow() || !(int) $qr_count->get('c')) { foreach ($va_temp_tables as $vs_temp_table) { $this->_dropTempTable($vs_temp_table); } break 2; } $va_temp_tables[] = $vs_temp_table; } $vs_results_temp_table = array_pop($va_temp_tables); $this->opo_db->query("UPDATE {$vs_results_temp_table} SET row_id = row_id - 1"); $va_direct_query_temp_tables[$vs_results_temp_table] = true; $vs_direct_sql_query = "SELECT swi.row_id, ca.boost \n\t\t\t\t\t\t\t\t\t\t\t\t\tFROM {$vs_results_temp_table} ca\n\t\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_sql_search_word_index AS swi ON swi.index_id = ca.row_id \n\t\t\t\t\t\t\t"; $pa_direct_sql_query_params = array(); // don't pass any params foreach ($va_temp_tables as $vs_temp_table) { $this->_dropTempTable($vs_temp_table); } break; case 'Zend_Search_Lucene_Search_Query_MultiTerm': $va_ft_like_term_list = array(); foreach ($o_lucene_query_element->getTerms() as $o_term) { $va_raw_terms[] = $vs_term = (string) (method_exists($o_term, "getTerm") ? $o_term->getTerm()->text : $o_term->text); if (!$vs_access_point && ($vs_field = method_exists($o_term, "getTerm") ? $o_term->getTerm()->field : $o_term->field)) { $vs_access_point = $vs_field; } $vs_stripped_term = preg_replace('!\\*+$!u', '', $vs_term); $va_ft_like_terms[] = $vs_stripped_term . ($vb_had_wildcard ? '%' : ''); } break; default: $vs_access_point = $o_lucene_query_element->getTerm()->field; $vs_term = $o_lucene_query_element->getTerm()->text; if ($vs_access_point && mb_strtoupper($vs_term) == _t('[BLANK]')) { $vb_is_blank_search = true; break; } $va_terms = $this->_tokenize($vs_term, true, $vn_i); $vb_output_term = false; foreach ($va_terms as $vs_term) { if (in_array(trim(mb_strtolower($vs_term, 'UTF-8')), WLPlugSearchEngineSqlSearch::$s_stop_words)) { continue; } if (get_class($o_lucene_query_element) != 'Zend_Search_Lucene_Search_Query_MultiTerm') { $vs_stripped_term = preg_replace('!\\*+$!u', '', $vs_term); // do stemming if ($this->opb_do_stemming) { $vs_to_stem = preg_replace('!\\*$!u', '', $vs_term); if (!preg_match('!y$!u', $vs_to_stem) && !preg_match('![0-9]+!', $vs_to_stem)) { // don't stem things ending in 'y' as that can cause problems (eg "Bowery" becomes "Boweri") if (!($vs_stem = trim($this->opo_stemmer->stem($vs_to_stem)))) { $vs_stem = (string) $vs_term; } $va_ft_stem_terms[] = "'" . $this->opo_db->escape($vs_stem) . "'"; } else { $va_ft_terms[] = '"' . $this->opo_db->escape($vs_term) . '"'; } } else { $va_ft_terms[] = '"' . $this->opo_db->escape($vs_term) . '"'; } $vb_output_term = true; } } if ($vb_output_term) { $va_raw_terms[] = $vs_term; } else { $vn_i--; } break; } $vs_fld_num = $vs_table_num = $t_table = null; $vb_ft_bit_optimization = false; if ($vs_access_point) { list($vs_table, $vs_field, $vs_sub_field) = explode('.', $vs_access_point); if (in_array($vs_table, array('created', 'modified'))) { $o_tep = new TimeExpressionParser(); $vs_date = join(' ', $va_raw_terms); if (!$o_tep->parse($vs_date)) { break; } $va_range = $o_tep->getUnixTimestamps(); $vn_user_id = null; if ($vs_field = trim($vs_field)) { if (!is_int($vs_field)) { $t_user = new ca_users(); if ($t_user->load(array("user_name" => $vs_field))) { $vn_user_id = (int) $t_user->getPrimaryKey(); } } else { $vn_user_id = (int) $vs_field; } } $vs_user_sql = $vn_user_id ? " AND (ccl.user_id = " . (int) $vn_user_id . ")" : ""; switch ($vs_table) { case 'created': $vs_direct_sql_query = "\n\t\t\t\t\t\t\t\t\t\t\tSELECT ccl.logged_row_id, 1\n\t\t\t\t\t\t\t\t\t\t\tFROM ca_change_log ccl\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(ccl.log_datetime BETWEEN " . (int) $va_range['start'] . " AND " . (int) $va_range['end'] . ")\n\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(ccl.logged_table_num = ?)\n\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(ccl.changetype = 'I')\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_user_sql}\n\t\t\t\t\t\t\t\t\t\t"; break; case 'modified': $vs_direct_sql_query = "\n\t\t\t\t\t\t\t\t\t\t\tSELECT ccl.logged_row_id, 1\n\t\t\t\t\t\t\t\t\t\t\tFROM ca_change_log ccl\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(ccl.log_datetime BETWEEN " . (int) $va_range['start'] . " AND " . (int) $va_range['end'] . ")\n\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(ccl.logged_table_num = ?)\n\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(ccl.changetype = 'U')\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_user_sql}\n\t\t\t\t\t\t\t\t\t\tUNION\n\t\t\t\t\t\t\t\t\t\t\tSELECT ccls.subject_row_id, 1\n\t\t\t\t\t\t\t\t\t\t\tFROM ca_change_log ccl\n\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_change_log_subjects AS ccls ON ccls.log_id = ccl.log_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(ccl.log_datetime BETWEEN " . (int) $va_range['start'] . " AND " . (int) $va_range['end'] . ")\n\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(ccls.subject_table_num = {$pn_subject_tablenum})\n\t\t\t\t\t\t\t\t\t\t\t\t{$vs_user_sql}\n\t\t\t\t\t\t\t\t\t\t"; break; } } else { if ($vs_table && $vs_field) { $t_table = $this->opo_datamodel->getInstanceByTableName($vs_table, true); if ($t_table) { $vs_table_num = $t_table->tableNum(); if (is_numeric($vs_field)) { $vs_fld_num = 'I' . $vs_field; $vn_fld_num = (int) $vs_field; } else { $vn_fld_num = $this->getFieldNum($vs_table, $vs_field); $vs_fld_num = 'I' . $vn_fld_num; if (!strlen($vn_fld_num)) { $t_element = new ca_metadata_elements(); if ($t_element->load(array('element_code' => $vs_sub_field ? $vs_sub_field : $vs_field))) { $vn_fld_num = $t_element->getPrimaryKey(); $vs_fld_num = 'A' . $vn_fld_num; if (!$vb_is_blank_search) { // // For certain types of attributes we can directly query the // attributes in the database rather than using the full text index // This allows us to do "intelligent" querying... for example on date ranges // parsed from natural language input and for length dimensions using unit conversion // switch ($t_element->get('datatype')) { case 2: // dates $vb_all_numbers = true; foreach ($va_raw_terms as $vs_term) { if (!is_numeric($vs_term)) { $vb_all_numbers = false; break; } } $vs_raw_term = join(' ', $va_raw_terms); $vb_exact = $vs_raw_term[0] == "#" ? true : false; // dates prepended by "#" are considered "exact" or "contained - the matched dates must be wholly contained by the search term if ($vb_exact) { $vs_raw_term = substr($vs_raw_term, 1); if ($this->opo_tep->parse($vs_raw_term)) { $va_dates = $this->opo_tep->getHistoricTimestamps(); $vs_direct_sql_query = "\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tSELECT ca.row_id, 1\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tFROM ca_attribute_values cav\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_attributes AS ca ON ca.attribute_id = cav.attribute_id\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t^JOIN\n\t\t\t\t\t\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\t\t\t\t\t(cav.element_id = {$vn_fld_num}) AND (ca.table_num = ?)\n\t\t\t\t\t\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\t\t\t\t\t(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(cav.value_decimal1 BETWEEN " . floatval($va_dates['start']) . " AND " . floatval($va_dates['end']) . ")\n\t\t\t\t\t\t\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\t\t\t\t\t\t(cav.value_decimal2 BETWEEN " . floatval($va_dates['start']) . " AND " . floatval($va_dates['end']) . ")\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; } } else { if ($this->opo_tep->parse($vs_raw_term)) { $va_dates = $this->opo_tep->getHistoricTimestamps(); $vs_direct_sql_query = "\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tSELECT ca.row_id, 1\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tFROM ca_attribute_values cav\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_attributes AS ca ON ca.attribute_id = cav.attribute_id\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t^JOIN\n\t\t\t\t\t\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\t\t\t\t\t(cav.element_id = {$vn_fld_num}) AND (ca.table_num = ?)\n\t\t\t\t\t\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\t\t\t\t\t(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(cav.value_decimal1 BETWEEN " . floatval($va_dates['start']) . " AND " . floatval($va_dates['end']) . ")\n\t\t\t\t\t\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\t\t\t\t\t(cav.value_decimal2 BETWEEN " . floatval($va_dates['start']) . " AND " . floatval($va_dates['end']) . ")\n\t\t\t\t\t\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\t\t\t\t\t(cav.value_decimal1 <= " . floatval($va_dates['start']) . " AND cav.value_decimal2 >= " . floatval($va_dates['end']) . ")\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; } } break; case 4: // geocode $t_geocode = new GeocodeAttributeValue(); // If it looks like a lat/long pair that has been tokenized by Lucene // into oblivion rehydrate it here. if ($va_coords = caParseGISSearch(join(' ', $va_raw_terms))) { $vs_direct_sql_query = "\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tSELECT ca.row_id, 1\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tFROM ca_attribute_values cav\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_attributes AS ca ON ca.attribute_id = cav.attribute_id\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t^JOIN\n\t\t\t\t\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\t\t\t\t(cav.element_id = {$vn_fld_num}) AND (ca.table_num = ?)\n\t\t\t\t\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\t\t\t\t(cav.value_decimal1 BETWEEN {$va_coords['min_latitude']} AND {$va_coords['max_latitude']})\n\t\t\t\t\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\t\t\t\t(cav.value_decimal2 BETWEEN {$va_coords['min_longitude']} AND {$va_coords['max_longitude']})\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; } break; case 6: // currency $t_cur = new CurrencyAttributeValue(); $va_parsed_value = $t_cur->parseValue(join(' ', $va_raw_terms), $t_element->getFieldValuesArray()); $vn_amount = $va_parsed_value['value_decimal1']; $vs_currency = preg_replace('![^A-Z0-9]+!', '', $va_parsed_value['value_longtext1']); $vs_direct_sql_query = "\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tSELECT ca.row_id, 1\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tFROM ca_attribute_values cav\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_attributes AS ca ON ca.attribute_id = cav.attribute_id\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t^JOIN\n\t\t\t\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\t\t\t(cav.element_id = {$vn_fld_num}) AND (ca.table_num = ?)\n\t\t\t\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\t\t\t(cav.value_decimal1 = " . floatval($vn_amount) . ")\n\t\t\t\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\t\t\t(cav.value_longtext1 = '" . $this->opo_db->escape($vs_currency) . "')\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; break; case 8: // length $t_len = new LengthAttributeValue(); $va_parsed_value = $t_len->parseValue(array_shift($va_raw_terms), $t_element->getFieldValuesArray()); $vn_len = $va_parsed_value['value_decimal1']; // this is always in meters so we can compare this value to the one in the database $vs_direct_sql_query = "\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tSELECT ca.row_id, 1\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tFROM ca_attribute_values cav\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_attributes AS ca ON ca.attribute_id = cav.attribute_id\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t^JOIN\n\t\t\t\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\t\t\t(cav.element_id = {$vn_fld_num}) AND (ca.table_num = ?)\n\t\t\t\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\t\t\t(cav.value_decimal1 = " . floatval($vn_len) . ")\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; break; case 9: // weight $t_weight = new WeightAttributeValue(); $va_parsed_value = $t_weight->parseValue(array_shift($va_raw_terms), $t_element->getFieldValuesArray()); $vn_weight = $va_parsed_value['value_decimal1']; // this is always in kilograms so we can compare this value to the one in the database $vs_direct_sql_query = "\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tSELECT ca.row_id, 1\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tFROM ca_attribute_values cav\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_attributes AS ca ON ca.attribute_id = cav.attribute_id\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t^JOIN\n\t\t\t\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\t\t\t(cav.element_id = {$vn_fld_num}) AND (ca.table_num = ?)\n\t\t\t\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\t\t\t(cav.value_decimal1 = " . floatval($vn_weight) . ")\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; break; case 10: // timecode $t_timecode = new TimecodeAttributeValue(); $va_parsed_value = $t_timecode->parseValue(join(' ', $va_raw_terms), $t_element->getFieldValuesArray()); $vn_timecode = $va_parsed_value['value_decimal1']; $vs_direct_sql_query = "\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tSELECT ca.row_id, 1\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tFROM ca_attribute_values cav\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_attributes AS ca ON ca.attribute_id = cav.attribute_id\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t^JOIN\n\t\t\t\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\t\t\t(cav.element_id = {$vn_fld_num}) AND (ca.table_num = ?)\n\t\t\t\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\t\t\t(cav.value_decimal1 = " . floatval($vn_timecode) . ")\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; break; case 11: // integer $vs_direct_sql_query = "\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tSELECT ca.row_id, 1\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tFROM ca_attribute_values cav\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_attributes AS ca ON ca.attribute_id = cav.attribute_id\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t^JOIN\n\t\t\t\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\t\t\t(cav.element_id = {$vn_fld_num}) AND (ca.table_num = ?)\n\t\t\t\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\t\t\t(cav.value_integer1 = " . intval(array_shift($va_raw_terms)) . ")\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; break; case 12: // decimal $vs_direct_sql_query = "\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tSELECT ca.row_id, 1\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tFROM ca_attribute_values cav\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tINNER JOIN ca_attributes AS ca ON ca.attribute_id = cav.attribute_id\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t^JOIN\n\t\t\t\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\t\t\t(cav.element_id = {$vn_fld_num}) AND (ca.table_num = ?)\n\t\t\t\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\t\t\t(cav.value_decimal1 = " . floatval(array_shift($va_raw_terms)) . ")\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; break; } } } else { // neither table fields nor elements, i.e. 'virtual' fields like _count should $vn_fld_num = false; $vs_fld_num = $vs_field; } } } if ($t_table->getFieldInfo($t_table->fieldName($vn_fld_num), 'FIELD_TYPE') == FT_BIT) { $vb_ft_bit_optimization = true; } } } } } // // If we're querying on the fulltext index then we need to construct // the query here... if we already have a direct SQL query to run then we can skip this // if ($vb_is_blank_search) { $va_sql_where[] = "((swi.field_table_num = " . intval($vs_table_num) . ") AND (swi.field_num = '{$vs_fld_num}') AND (swi.word_id = 0))"; if (!sizeof($va_sql_where)) { continue; } $vs_sql_where = join(' OR ', $va_sql_where); } elseif (!$vs_direct_sql_query) { $va_sql_where = array(); if (sizeof($va_ft_terms)) { if ($t_table && strlen($vs_fld_num) > 1) { $va_sql_where[] = "((swi.field_table_num = " . intval($vs_table_num) . ") AND (swi.field_num = '{$vs_fld_num}') AND (sw.word IN (" . join(',', $va_ft_terms) . ")))"; } else { if (sizeof($va_ft_terms) == 1) { $va_sql_where[] = "(sw.word = " . $va_ft_terms[0] . ")"; } else { $va_sql_where[] = "(sw.word IN (" . join(',', $va_ft_terms) . "))"; } } } if (sizeof($va_ft_like_terms)) { $va_tmp = array(); foreach ($va_ft_like_terms as $vs_term) { if ($vb_ft_bit_optimization) { $va_tmp[] = '(sw.word = \' ' . $this->opo_db->escape(trim($vs_term)) . ' \')'; } else { $va_tmp[] = '(sw.word LIKE \'' . $this->opo_db->escape(trim($vs_term)) . '%\')'; } } if ($t_table && strlen($vs_fld_num) > 1) { $va_sql_where[] = "((swi.field_table_num = " . intval($vs_table_num) . ") AND (swi.field_num = '{$vs_fld_num}') AND (" . join(' AND ', $va_tmp) . "))"; } else { $va_sql_where[] = "(" . join(' AND ', $va_tmp) . ")"; } } if (sizeof($va_ft_stem_terms)) { if ($t_table && strlen($vs_fld_num) > 1) { $va_sql_where[] = "((swi.field_table_num = " . intval($vs_table_num) . ") AND (swi.field_num = '{$vs_fld_num}') AND (sw.stem IN (" . join(',', $va_ft_stem_terms) . ")))"; } else { $va_sql_where[] = "(sw.stem IN (" . join(',', $va_ft_stem_terms) . "))"; } } if (!sizeof($va_sql_where)) { continue; } $vs_sql_where = join(' OR ', $va_sql_where); } else { $va_ft_terms = $va_ft_like_terms = $va_ft_like_terms = array(); } //print "OP=$vs_op<br>"; if ($vn_i == 0) { if ($vs_direct_sql_query) { $vs_direct_sql_query = str_replace('^JOIN', "", $vs_direct_sql_query); } $vs_sql = $vs_direct_sql_query ? "INSERT IGNORE INTO {$ps_dest_table} {$vs_direct_sql_query}" : "\n\t\t\t\t\t\t\tINSERT IGNORE INTO {$ps_dest_table}\n\t\t\t\t\t\t\tSELECT swi.row_id, SUM(swi.boost)\n\t\t\t\t\t\t\tFROM ca_sql_search_word_index swi\n\t\t\t\t\t\t\t" . (!$vb_is_blank_search ? "INNER JOIN ca_sql_search_words AS sw ON sw.word_id = swi.word_id" : '') . "\n\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t{$vs_sql_where}\n\t\t\t\t\t\t\t\tAND\n\t\t\t\t\t\t\t\tswi.table_num = ?\n\t\t\t\t\t\t\t\t" . ($this->getOption('omitPrivateIndexing') ? " AND swi.access = 0" : '') . "\n\t\t\t\t\t\t\tGROUP BY swi.row_id \n\t\t\t\t\t\t"; if (($vn_num_terms = sizeof($va_ft_terms) + sizeof($va_ft_like_terms) + sizeof($va_ft_stem_terms)) > 1 && !$vs_direct_sql_query) { $vs_sql .= " HAVING count(distinct sw.word_id) = {$vn_num_terms}"; } if ($this->debug) { print 'FIRST: ' . $vs_sql . " [{$pn_subject_tablenum}]<hr>\n"; } //print $vs_sql; $qr_res = $this->opo_db->query($vs_sql, is_array($pa_direct_sql_query_params) ? $pa_direct_sql_query_params : array((int) $pn_subject_tablenum)); } else { switch ($vs_op) { case 'AND': if ($vs_direct_sql_query) { $vs_direct_sql_query = str_replace('^JOIN', "INNER JOIN {$ps_dest_table} AS ftmp1 ON ftmp1.row_id = ca.row_id", $vs_direct_sql_query); } $this->_createTempTable($ps_dest_table . '_acc'); $vs_sql = $vs_direct_sql_query ? "INSERT IGNORE INTO {$ps_dest_table}_acc {$vs_direct_sql_query}" : "\n\t\t\t\t\t\t\t\t\tINSERT IGNORE INTO {$ps_dest_table}_acc\n\t\t\t\t\t\t\t\t\tSELECT swi.row_id, SUM(swi.boost)\n\t\t\t\t\t\t\t\t\tFROM ca_sql_search_word_index swi\n\t\t\t\t\t\t\t\t\tINNER JOIN ca_sql_search_words AS sw ON sw.word_id = swi.word_id\n\t\t\t\t\t\t\t\t\tINNER JOIN {$ps_dest_table} AS ftmp1 ON ftmp1.row_id = swi.row_id\n\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t{$vs_sql_where}\n\t\t\t\t\t\t\t\t\t\tAND\n\t\t\t\t\t\t\t\t\t\tswi.table_num = ?\n\t\t\t\t\t\t\t\t\t\t" . ($this->getOption('omitPrivateIndexing') ? " AND swi.access = 0" : '') . "\n\t\t\t\t\t\t\t\t\tGROUP BY\n\t\t\t\t\t\t\t\t\t\tswi.row_id\n\t\t\t\t\t\t\t\t"; if (($vn_num_terms = sizeof($va_ft_terms) + sizeof($va_ft_like_terms) + sizeof($va_ft_stem_terms)) > 1) { $vs_sql .= " HAVING count(distinct sw.word_id) = {$vn_num_terms}"; } if ($this->debug) { print 'AND:' . $vs_sql . "<hr>\n"; } $qr_res = $this->opo_db->query($vs_sql, is_array($pa_direct_sql_query_params) ? $pa_direct_sql_query_params : array((int) $pn_subject_tablenum)); $qr_res = $this->opo_db->query("TRUNCATE TABLE {$ps_dest_table}"); $qr_res = $this->opo_db->query("INSERT INTO {$ps_dest_table} SELECT row_id, boost FROM {$ps_dest_table}_acc"); //$qr_res = $this->opo_db->query("TRUNCATE TABLE ca_sql_search_temp_2"); $this->_dropTempTable($ps_dest_table . '_acc'); break; case 'NOT': if ($vs_direct_sql_query) { $vs_direct_sql_query = str_replace('^JOIN', "", $vs_direct_sql_query); } $vs_sql = "\n\t\t\t\t\t\t\t\t\tSELECT row_id\n\t\t\t\t\t\t\t\t\tFROM ca_sql_search_words sw\n\t\t\t\t\t\t\t\t\tINNER JOIN ca_sql_search_word_index AS swi ON sw.word_id = swi.word_id\n\t\t\t\t\t\t\t\t\tWHERE \n\t\t\t\t\t\t\t\t\t\t" . ($vs_sql_where ? "{$vs_sql_where} AND " : "") . " swi.table_num = ? \n\t\t\t\t\t\t\t\t\t\t" . ($this->getOption('omitPrivateIndexing') ? " AND swi.access = 0" : ''); //print "$vs_sql<hr>"; $qr_res = $this->opo_db->query($vs_sql, is_array($pa_direct_sql_query_params) ? $pa_direct_sql_query_params : array((int) $pn_subject_tablenum)); $va_ids = $qr_res->getAllFieldValues("row_id"); $vs_sql = "\n\t\t\t\t\t\t\t\t\tDELETE FROM {$ps_dest_table} \n\t\t\t\t\t\t\t\t\tWHERE \n\t\t\t\t\t\t\t\t\t\trow_id IN (?)\n\t\t\t\t\t\t\t\t"; $qr_res = $this->opo_db->query($vs_sql, array($va_ids)); //print "$vs_sql<hr>"; break; default: case 'OR': if ($vs_direct_sql_query) { $vs_direct_sql_query = str_replace('^JOIN', "", $vs_direct_sql_query); } $vs_sql = $vs_direct_sql_query ? "INSERT IGNORE INTO {$ps_dest_table} {$vs_direct_sql_query}" : "\n\t\t\t\t\t\t\t\t\tINSERT IGNORE INTO {$ps_dest_table}\n\t\t\t\t\t\t\t\t\tSELECT swi.row_id, SUM(swi.boost)\n\t\t\t\t\t\t\t\t\tFROM ca_sql_search_word_index swi\n\t\t\t\t\t\t\t\t\tINNER JOIN ca_sql_search_words AS sw ON sw.word_id = swi.word_id\n\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t{$vs_sql_where}\n\t\t\t\t\t\t\t\t\t\tAND\n\t\t\t\t\t\t\t\t\t\tswi.table_num = ?\n\t\t\t\t\t\t\t\t\t\t" . ($this->getOption('omitPrivateIndexing') ? " AND swi.access = 0" : '') . "\n\t\t\t\t\t\t\t\t\tGROUP BY\n\t\t\t\t\t\t\t\t\t\tswi.row_id\n\t\t\t\t\t\t\t\t"; if ($this->debug) { print 'OR' . $vs_sql . "<hr>\n"; } $qr_res = $this->opo_db->query($vs_sql, is_array($pa_direct_sql_query_params) ? $pa_direct_sql_query_params : array((int) $pn_subject_tablenum)); break; } } // Drop any temporary tables created by direct search queries foreach (array_keys($va_direct_query_temp_tables) as $vs_temp_table_to_drop) { $this->_dropTempTable($vs_temp_table_to_drop); } break; default: //print get_class($o_lucene_query_element); break; } $vn_i++; } }
<input type="hidden" name="item_id" value="<?php print $t_set->get("set_id"); ?> "> </form> </div> <?php if (sizeof($va_comments)) { ?> <div class="lbSetCommentHeader"><a href="#" onClick="jQuery('.lbComments').toggle(); return false;"><?php print sizeof($va_comments) . " " . (sizeof($va_comments) == 1 ? _t("comment") : _t("comments")); ?> <i class="fa fa-arrows-v"></i></a><HR/></div> <?php if (sizeof($va_comments)) { $t_author = new ca_users(); print "<div class='lbComments' style='display:none;'>"; foreach ($va_comments as $va_comment) { print "<small>"; # --- display link to remove comment? if ($vb_write_access || $va_comment["user_id"] == $this->request->user->get("user_id")) { print "<div class='pull-right'>" . caNavLink($this->request, "<i class='fa fa-times' title='" . _t("remove comment") . "'></i>", "", "", "Sets", "deleteComment", array("comment_id" => $va_comment["comment_id"], "set_id" => $t_set->get("set_id"), "reload" => "detail")) . "</div>"; } $t_author->load($va_comment["user_id"]); print $va_comment["comment"] . "<br/>"; print "<small>" . trim($t_author->get("fname") . " " . $t_author->get("lname")) . " " . date("n/j/y g:i A", $va_comment["created_on"]) . "</small>"; print "</small><HR/>"; } print "</div>"; } }
/** * Returns list of valid display modes as set in user_pref_defs.conf (via ca_users class) * * @return array List of modes */ private function getValidLabelDisplayModes() { $t_user = new ca_users(); $va_pref_info = $t_user->getPreferenceInfo('cataloguing_display_label_mode'); return array_values($va_pref_info['choiceList']); }
/** * */ public function __call($ps_function, $pa_args) { AssetLoadManager::register("panel"); AssetLoadManager::register("mediaViewer"); AssetLoadManager::register("carousel"); AssetLoadManager::register("readmore"); AssetLoadManager::register("maps"); $ps_function = strtolower($ps_function); $ps_id = urldecode($this->request->getActionExtra()); if (!isset($this->opa_detail_types[$ps_function]) || !isset($this->opa_detail_types[$ps_function]['table']) || !($vs_table = $this->opa_detail_types[$ps_function]['table'])) { // invalid detail type – throw error die("Invalid detail type"); } $t_table = $this->opo_datamodel->getInstanceByTableName($vs_table, true); if (($vb_use_identifiers_in_urls = caUseIdentifiersInUrls()) && substr($ps_id, 0, 3) == "id:") { $va_tmp = explode(":", $ps_id); $ps_id = (int) $va_tmp[1]; $vb_use_identifiers_in_urls = false; } if (!$t_table->load($vb_use_identifiers_in_urls && $t_table->getProperty('ID_NUMBERING_ID_FIELD') ? $t_table->hasField('deleted') ? array($t_table->getProperty('ID_NUMBERING_ID_FIELD') => $ps_id, 'deleted' => 0) : array($t_table->getProperty('ID_NUMBERING_ID_FIELD') => $ps_id) : ($t_table->hasField('deleted') ? array($t_table->primaryKey() => (int) $ps_id, 'deleted' => 0) : array($t_table->primaryKey() => (int) $ps_id)))) { // invalid id - throw error die("Invalid id"); } // Printables // merge displays with drop-in print templates // $va_export_options = caGetAvailablePrintTemplates('summary', array('table' => $t_table->tableName())); $this->view->setVar('export_formats', $va_export_options); $va_options = array(); foreach ($va_export_options as $vn_i => $va_format_info) { $va_options[$va_format_info['name']] = $va_format_info['code']; } // Get current display list $t_display = new ca_bundle_displays(); foreach (caExtractValuesByUserLocale($t_display->getBundleDisplays(array('table' => $this->ops_tablename, 'user_id' => $this->request->getUserID(), 'access' => __CA_BUNDLE_DISPLAY_READ_ACCESS__, 'checkAccess' => caGetUserAccessValues($this->request)))) as $va_display) { $va_options[$va_display['name']] = "_display_" . $va_display['display_id']; } ksort($va_options); $this->view->setVar('export_format_select', caHTMLSelect('export_format', $va_options, array('class' => 'searchToolsSelect'), array('value' => $this->view->getVar('current_export_format'), 'width' => '150px'))); # # Enforce access control # if (sizeof($this->opa_access_values) && $t_table->hasField('access') && !in_array($t_table->get("access"), $this->opa_access_values)) { $this->notification->addNotification(_t("This item is not available for view"), "message"); $this->response->setRedirect(caNavUrl($this->request, "", "", "", "")); return; } MetaTagManager::setWindowTitle($this->request->config->get("app_display_name") . ": " . $t_table->getTypeName() . ": " . $t_table->get('preferred_labels') . (($vs_idno = $t_table->get($t_table->getProperty('ID_NUMBERING_ID_FIELD'))) ? " [{$vs_idno}]" : "")); $vs_type = $t_table->getTypeCode(); $this->view->setVar('detailType', $vs_table); $this->view->setVar('item', $t_table); $this->view->setVar('itemType', $vs_type); caAddPageCSSClasses(array($vs_table, $ps_function, $vs_type)); // Do we need to pull in the multisearch result set? if (ResultContext::getLastFind($this->request, $vs_table, array('noSubtype' => true)) === 'multisearch') { $o_context = new ResultContext($this->request, $vs_table, 'multisearch', $ps_function); $o_context->setAsLastFind(); $o_context->saveContext(); } else { $o_context = ResultContext::getResultContextForLastFind($this->request, $vs_table); } $this->view->setVar('previousID', $vn_previous_id = $o_context->getPreviousID($t_table->getPrimaryKey())); $this->view->setVar('nextID', $vn_next_id = $o_context->getNextID($t_table->getPrimaryKey())); $this->view->setVar('previousURL', caDetailUrl($this->request, $vs_table, $vn_previous_id)); $this->view->setVar('nextURL', caDetailUrl($this->request, $vs_table, $vn_next_id)); $this->view->setVar('resultsURL', ResultContext::getResultsUrlForLastFind($this->request, $vs_table)); $va_options = isset($this->opa_detail_types[$ps_function]['options']) && is_array($this->opa_detail_types[$ps_function]['options']) ? $this->opa_detail_types[$ps_function]['options'] : array(); $this->view->setVar('previousLink', $vn_previous_id > 0 ? caDetailLink($this->request, caGetOption('previousLink', $va_options, _t('Previous')), '', $vs_table, $vn_previous_id) : ''); $this->view->setVar('nextLink', $vn_next_id > 0 ? caDetailLink($this->request, caGetOption('nextLink', $va_options, _t('Next')), '', $vs_table, $vn_next_id) : ''); $this->view->setVar('resultsLink', ResultContext::getResultsLinkForLastFind($this->request, $vs_table, caGetOption('resultsLink', $va_options, _t('Back')))); $this->view->setVar('commentsEnabled', (bool) $va_options['enableComments']); // // // if (method_exists($t_table, 'getPrimaryRepresentationInstance')) { if ($pn_representation_id = $this->request->getParameter('representation_id', pInteger)) { $t_representation = $this->opo_datamodel->getInstanceByTableName("ca_object_representations", true); $t_representation->load($pn_representation_id); } else { $t_representation = $t_table->getPrimaryRepresentationInstance(array("checkAccess" => $this->opa_access_values)); } if ($t_representation) { $this->view->setVar("t_representation", $t_representation); $this->view->setVar("representation_id", $t_representation->get("representation_id")); } else { $t_representation = $this->opo_datamodel->getInstanceByTableName("ca_object_representations", true); } $this->view->setVar("representationViewer", caObjectDetailMedia($this->request, $t_table->getPrimaryKey(), $t_representation, $t_table, array("primaryOnly" => caGetOption('representationViewerPrimaryOnly', $va_options, false), "dontShowPlaceholder" => caGetOption('representationViewerDontShowPlaceholder', $va_options, false)))); } // // map // if (!is_array($va_map_attributes = caGetOption('map_attributes', $va_options, array())) || !sizeof($va_map_attributes)) { if ($vs_map_attribute = caGetOption('map_attribute', $va_options, false)) { $va_map_attributes = array($vs_map_attribute); } } $this->view->setVar("map", ""); if (is_array($va_map_attributes) && sizeof($va_map_attributes)) { $o_map = new GeographicMap(($vn_width = caGetOption('map_width', $va_options, false)) ? $vn_width : 285, ($vn_height = caGetOption('map_height', $va_options, false)) ? $vn_height : 200, 'map'); $vn_mapped_count = 0; foreach ($va_map_attributes as $vs_map_attribute) { if ($t_table->get($vs_map_attribute)) { $o_map->mapFrom($t_table, $vs_map_attribute); $vn_mapped_count++; } } if ($vn_mapped_count > 0) { $this->view->setVar("map", $o_map->render('HTML')); } } // // comments, tags, rank // $this->view->setVar('averageRank', $t_table->getAverageRating(true)); $this->view->setVar('numRank', $t_table->getNumRatings(true)); # # User-generated comments, tags and ratings # $va_user_comments = $t_table->getComments(null, true); $va_comments = array(); if (is_array($va_user_comments)) { foreach ($va_user_comments as $va_user_comment) { if ($va_user_comment["comment"] || $va_user_comment["media1"] || $va_user_comment["media2"] || $va_user_comment["media3"] || $va_user_comment["media4"]) { # TODO: format date based on locale $va_user_comment["date"] = date("n/j/Y", $va_user_comment["created_on"]); # -- get name of commenter if ($va_user_comment["user_id"]) { $t_user = new ca_users($va_user_comment["user_id"]); $va_user_comment["author"] = $t_user->getName(); } elseif ($va_user_comment["name"]) { $va_user_comment["author"] = $va_user_comment["name"]; } $va_comments[] = $va_user_comment; } } } $this->view->setVar('comments', $va_comments); $va_user_tags = $t_table->getTags(null, true); $va_tags = array(); if (is_array($va_user_tags)) { foreach ($va_user_tags as $va_user_tag) { if (!in_array($va_user_tag["tag"], $va_tags)) { $va_tags[] = $va_user_tag["tag"]; } } } $this->view->setVar('tags_array', $va_tags); $this->view->setVar('tags', implode(", ", $va_tags)); $this->view->setVar("itemComments", caDetailItemComments($this->request, $t_table->getPrimaryKey(), $t_table, $va_comments, $va_tags)); // // share link // $this->view->setVar("shareLink", "<a href='#' onclick='caMediaPanel.showPanel(\"" . caNavUrl($this->request, '', 'Detail', 'ShareForm', array("tablename" => $t_table->tableName(), "item_id" => $t_table->getPrimaryKey())) . "\"); return false;'>Share</a>"); // find view // first look for type-specific view if (!$this->viewExists($vs_path = "Details/{$vs_table}_{$vs_type}_html.php")) { // If no type specific view use the default $vs_path = "Details/{$vs_table}_default_html.php"; } switch ($ps_view = $this->request->getParameter('view', pString)) { case 'pdf': $this->_genExport($t_table, $this->request->getParameter("export_format", pString), 'Detail', 'Detail'); break; default: // // Tag substitution // // Views can contain tags in the form {{{tagname}}}. Some tags, such as "itemType" and "detailType" are defined by // the detail controller. More usefully, you can pull data from the item being detailed by using a valid "get" expression // as a tag (Eg. {{{ca_objects.idno}}}. Even more usefully for some, you can also use a valid bundle display template // (see http://docs.collectiveaccess.org/wiki/Bundle_Display_Templates) as a tag. The template will be evaluated in the // context of the item being detailed. // $va_defined_vars = array_keys($this->view->getAllVars()); // get list defined vars (we don't want to copy over them) $va_tag_list = $this->getTagListForView($vs_path); // get list of tags in view foreach ($va_tag_list as $vs_tag) { if (in_array($vs_tag, $va_defined_vars)) { continue; } if (strpos($vs_tag, "^") !== false || strpos($vs_tag, "<") !== false) { $this->view->setVar($vs_tag, $t_table->getWithTemplate($vs_tag, array('checkAccess' => $this->opa_access_values))); } elseif (strpos($vs_tag, ".") !== false) { $this->view->setVar($vs_tag, $t_table->get($vs_tag, array('checkAccess' => $this->opa_access_values))); } else { $this->view->setVar($vs_tag, "?{$vs_tag}"); } } $this->render($vs_path); break; } }
/** * Determines if the specified item (and optionally a specific bundle in that item) are readable by the user * * @param int $pn_user_id * @param mixed $pm_table A table name or number * @param mixed $pm_id A primary key value of the row, or an array of values to check. If a single integer value is provided then a boolean result will be returned; if an array of values is provided then an array will be returned with all ids that are readable * @param string $ps_bundle_name An optional bundle to check access for * * @return If $pm_id is an integer return true if user has read access, otherwise false if the user does not have access; if $pm_id is an array of ids, returns an array with all ids the are readable; returns null if one or more parameters are invalid */ function caCanRead($pn_user_id, $pm_table, $pm_id, $ps_bundle_name = null, $pa_options = null) { $pb_return_as_array = caGetOption('returnAsArray', $pa_options, false); $t_user = new ca_users($pn_user_id, true); if (!$t_user->getPrimaryKey()) { return null; } $o_dm = Datamodel::load(); $ps_table_name = is_numeric($pm_table) ? $o_dm->getTableName($pm_table) : $pm_table; if (!is_array($pm_id)) { $pm_id = array($pm_id); } if ($ps_bundle_name) { if ($t_user->getBundleAccessLevel($ps_table_name, $ps_bundle_name) < __CA_BUNDLE_ACCESS_READONLY__) { return sizeof($pm_id) == 1 && !$pb_return_as_array ? false : array(); } } if (!($t_instance = $o_dm->getInstanceByTableName($ps_table_name, true))) { return null; } $vb_do_type_access_check = (bool) $t_instance->getAppConfig()->get('perform_type_access_checking'); $vb_do_item_access_check = (bool) $t_instance->getAppConfig()->get('perform_item_level_access_checking'); list($ps_table_name, $ps_bundle_name) = caTranslateBundlesForAccessChecking($ps_table_name, $ps_bundle_name); if (!($qr_res = caMakeSearchResult($ps_table_name, $pm_id))) { return null; } $va_return_values = array(); while ($qr_res->nextHit()) { $vn_id = $qr_res->getPrimaryKey(); // Check type restrictions if ($vb_do_type_access_check) { $vn_type_access = $t_user->getTypeAccessLevel($ps_table_name, $qr_res->get("{$ps_table_name}.type_id")); if ($vn_type_access < __CA_BUNDLE_ACCESS_READONLY__) { continue; } } // Check item level restrictions if ($vb_do_item_access_check) { $vn_item_access = $t_instance->checkACLAccessForUser($t_user, $vn_id); if ($vn_item_access < __CA_ACL_READONLY_ACCESS__) { continue; } } $va_return_values[] = $vn_id; } if (sizeof($pm_id) == 1 && !$pb_return_as_array) { return sizeof($va_return_values) > 0 ? true : false; } return $va_return_values; }
public function DownloadUserReport() { $vs_download_format = $this->request->getParameter("download_format", pString); if (!$vs_download_format) { $vs_download_format = "tab"; } $this->view->setVar("download_format", $vs_download_format); switch ($vs_download_format) { default: case "tab": $this->view->setVar("file_extension", "txt"); $this->view->setVar("mimetype", "text/plain"); $vs_delimiter_col = "\t"; $vs_delimiter_row = "\n"; break; # ----------------------------------- # ----------------------------------- case "csv": $this->view->setVar("file_extension", "txt"); $this->view->setVar("mimetype", "text/plain"); $vs_delimiter_col = ","; $vs_delimiter_row = "\n"; break; # ----------------------------------- } $o_db = new Db(); $t_user = new ca_users(); $va_fields = array("lname", "fname", "email", "user_name", "userclass", "active", "last_login"); $va_profile_prefs = $t_user->getValidPreferences('profile'); $va_profile_prefs_labels = array(); foreach ($va_profile_prefs as $vs_pref) { $va_pref_info = $t_user->getPreferenceInfo($vs_pref); $va_profile_prefs_labels[$vs_pref] = $va_pref_info["label"]; } $qr_users = $o_db->query("SELECT * FROM ca_users ORDER BY user_id DESC"); if ($qr_users->numRows()) { $va_rows = array(); # --- headings $va_row = array(); # --- headings for field values foreach ($va_fields as $vs_field) { switch ($vs_field) { case "last_login": $va_row[] = _t("Last login"); break; # -------------------- # -------------------- default: $va_row[] = $t_user->getDisplayLabel("ca_users." . $vs_field); break; # -------------------- } } # --- headings for profile prefs foreach ($va_profile_prefs_labels as $vs_pref => $vs_pref_label) { $va_row[] = $vs_pref_label; } $va_rows[] = join($vs_delimiter_col, $va_row); reset($va_fields); reset($va_profile_prefs_labels); $o_tep = new TimeExpressionParser(); while ($qr_users->nextRow()) { $va_row = array(); # --- fields foreach ($va_fields as $vs_field) { switch ($vs_field) { case "userclass": $va_row[] = $t_user->getChoiceListValue($vs_field, $qr_users->get("ca_users." . $vs_field)); break; # ----------------------- # ----------------------- case "active": $va_row[] = $qr_users->get("ca_users." . $vs_field) == 1 ? _t("active") : _t("not active"); break; # ----------------------- # ----------------------- case "last_login": //if (!is_array($va_vars = $qr_users->getVars('vars'))) { $va_vars = array(); } if (!is_array($va_vars = $qr_users->getVars('volatile_vars'))) { $va_vars = array(); } if ($va_vars['last_login'] > 0) { $o_tep->setUnixTimestamps($va_vars['last_login'], $va_vars['last_login']); $va_row[] = $o_tep->getText(); } else { $va_row[] = "-"; } break; # ----------------------- # ----------------------- default: if ($vs_download_format == "csv") { $va_row[] = str_replace(",", "-", $qr_users->get("ca_users." . $vs_field)); } else { $va_row[] = $qr_users->get("ca_users." . $vs_field); } break; # ----------------------- } } # --- profile prefs foreach ($va_profile_prefs_labels as $vs_pref => $vs_pref_label) { $t_user->load($qr_users->get("ca_users.user_id")); $va_row[] = $t_user->getPreference($vs_pref); } $va_rows[] = join($vs_delimiter_col, $va_row); } $vs_file_contents = join($vs_delimiter_row, $va_rows); $this->view->setVar("file_contents", $vs_file_contents); return $this->render('user_report.php'); } else { $this->notification->addNotification(_t("There are no users"), __NOTIFICATION_TYPE_INFO__); $this->ListUsers(); return; } }
/** * * Implements standard username/password and IP-address based user authentication. Applications * requiring completely custom authentication methods should override this method. However, most of * the time if you need custom authentication you can just create a custom user auth handler class ("username/password" authentication). * * One clean way to extend Auth is create a sub-class whose constructor calls addUserHandler() and delegates * everything else to Auth. * * @access private * @param array of login options (same as the associative option array in the class constructor) */ public function doAuthentication($pa_options) { global $AUTH_CURRENT_USER_ID; $o_event_log = new Eventlog(); $vs_app_name = $this->config->get("app_name"); foreach (array('no_headers', 'dont_redirect_to_login', 'dont_create_new_session', 'dont_redirect_to_welcome', 'user_name', 'password', 'options', 'noPublicUsers', 'dont_redirect', 'no_headers', 'redirect') as $vs_key) { if (!isset($pa_options[$vs_key])) { $pa_options[$vs_key] = null; } } if (!is_array($pa_options["options"])) { $pa_options["options"] = array(); } if ($pa_options["no_headers"]) { $pa_options["dont_redirect_to_login"] = true; $pa_options["dont_create_new_session"] = true; $pa_options["dont_redirect_to_welcome"] = true; } if ($pa_options["dont_redirect"]) { $pa_options["dont_redirect_to_login"] = true; $pa_options["dont_redirect_to_welcome"] = true; } $vb_login_successful = false; if (!$pa_options["user_name"]) { // no incoming login // // is a user already logged in? // if ($vn_user_id = $this->session->getVar($vs_app_name . "_user_id")) { // does session have a user attached to it? // user is already logged in $this->user = new ca_users($vn_user_id); // add user object if (!$this->user->isActive() || $this->user->numErrors() || $pa_options['noPublicUsers'] && $this->user->isPublicUser()) { // error means user_id in session is invalid $vb_login_successful = false; } else { $vb_login_successful = true; } if ($vb_login_successful) { // Login was successful $this->session->setVar($vs_app_name . "_lastping", time()); // set last time we heard from client in session $this->user->setLastPing(time()); $AUTH_CURRENT_USER_ID = $vn_user_id; //$this->user->close(); ** will be called externally ** return $vb_login_successful; } } if (!$vb_login_successful) { $this->user = new ca_users(); // add user object $vs_tmp1 = $vs_tmp2 = null; if ($vn_auth_type = $this->user->authenticate($vs_tmp1, $vs_tmp2, $pa_options["options"])) { # error means user_id in session is invalid if ($pa_options['noPublicUsers'] && $this->user->isPublicUser() || !$this->user->isActive()) { $o_event_log->log(array("CODE" => "LOGF", "SOURCE" => "Auth", "MESSAGE" => "Failed login for user id '" . $vn_user_id . "' (" . $_SERVER['REQUEST_URI'] . "); IP=" . $_SERVER["REMOTE_ADDR"] . "; user agent='" . $_SERVER["HTTP_USER_AGENT"] . "'")); $vb_login_successful = false; } else { $vb_login_successful = true; $vn_user_id = $this->user->getUserID(); } } if (!$vb_login_successful) { // throw user to login screen if (!$pa_options["dont_redirect_to_login"]) { $o_event_log->log(array("CODE" => "LOGF", "SOURCE" => "Auth", "MESSAGE" => "Failed login with redirect for user id '" . $vn_user_id . "' (" . $_SERVER['REQUEST_URI'] . "); IP=" . $_SERVER["REMOTE_ADDR"] . "; user agent='" . $_SERVER["HTTP_USER_AGENT"] . "'")); $vs_redirect = $this->getRequestUrl(true); if (strpos($vs_redirect, $this->config->get("auth_login_path") !== -1)) { $vs_redirect = ''; } else { $vs_redirect = '?redirect=' . urlencode($vs_redirect); } $this->opo_response->addHeader("Location", $this->getBaseUrlPath() . '/' . $this->getScriptName() . '/' . $this->config->get("auth_login_path") . $vs_redirect); } return false; } } } // // incoming login // if ($pa_options["user_name"]) { $vb_login_successful = false; $this->user = new ca_users(); if ($vn_auth_type = $this->user->authenticate($pa_options["user_name"], $pa_options["password"], $pa_options["options"])) { # error means user_id in session is invalid if ($pa_options['noPublicUsers'] && $this->user->isPublicUser() || !$this->user->isActive()) { $vb_login_successful = false; } else { $vb_login_successful = true; $vn_user_id = $this->user->getUserID(); } } } if (!$vb_login_successful) { $this->user = null; // auth failed // throw user to login screen if ($pa_options["user_name"]) { $o_event_log->log(array("CODE" => "LOGF", "SOURCE" => "Auth", "MESSAGE" => "Failed login for '" . $pa_options["user_name"] . "' (" . $_SERVER['REQUEST_URI'] . "); IP=" . $_SERVER["REMOTE_ADDR"] . "; user agent='" . $_SERVER["HTTP_USER_AGENT"] . "'")); } if (!$pa_options["dont_redirect_to_login"]) { $vs_auth_login_url = $this->getBaseUrlPath() . '/' . $this->getScriptName() . '/' . $this->config->get("auth_login_path"); $this->opo_response->addHeader("Location", $vs_auth_login_url); } return false; } else { $o_event_log->log(array("CODE" => "LOGN", "SOURCE" => "Auth", "MESSAGE" => "Successful login for '" . $pa_options["user_name"] . "'; IP=" . $_SERVER["REMOTE_ADDR"] . "; user agent=" . $_SERVER["HTTP_USER_AGENT"])); $this->session->setVar($vs_app_name . "_user_auth_type", $vn_auth_type); // type of auth used: 1=username/password; 2=ip-base auth $this->session->setVar($vs_app_name . "_user_id", $vn_user_id); // auth succeeded; set user_id in session $this->session->setVar($vs_app_name . "_logintime", time()); // also set login time (unix timestamp) in session $this->session->setVar($vs_app_name . "_lastping", time()); $this->session->setVar("screen_width", isset($_REQUEST["_screen_width"]) ? intval($_REQUEST["_screen_width"]) : 0); $this->session->setVar("screen_height", isset($_REQUEST["_screen_height"]) ? intval($_REQUEST["_screen_height"]) : 0); $this->session->setVar("has_pdf_plugin", isset($_REQUEST["_has_pdf_plugin"]) ? intval($_REQUEST["_has_pdf_plugin"]) : 0); $this->user->setVar('last_login', time(), array('volatile' => true)); $this->user->setLastLogout($this->user->getLastPing(), array('volatile' => true)); //$this->user->close(); ** will be called externally ** $AUTH_CURRENT_USER_ID = $vn_user_id; if ($pa_options['redirect']) { // redirect to specified URL $this->opo_response->setRedirect($pa_options['redirect']); $this->opo_response->sendResponse(); exit; } if (!$pa_options["dont_redirect_to_welcome"]) { // redirect to "welcome" page $this->opo_response->setRedirect($this->getBaseUrlPath() . '/' . $this->getScriptName() . '/' . $this->config->get("auth_login_welcome_path")); $this->opo_response->sendResponse(); exit; } return true; } }
public function createAdminAccount() { require_once __CA_MODELS_DIR__ . "/ca_users.php"; $ps_password = $this->getRandomPassword(); $t_user = new ca_users(); $t_user->setMode(ACCESS_WRITE); $t_user->set("user_name", 'administrator'); $t_user->set("password", $ps_password); $t_user->set("email", $this->ops_admin_email); $t_user->set("fname", 'CollectiveAccess'); $t_user->set("lname", 'Administrator'); $t_user->set("userclass", 0); $t_user->set("active", 1); $t_user->insert(); if ($t_user->numErrors()) { $this->addError("Errors while adding the default administrator account: " . join("; ", $t_user->getErrors())); return false; } return $ps_password; }
/** * Generates standard-format inspector panels for editors * * @param View $po_view Inspector view object * @param array $pa_options Optional array of options. Supported options are: * backText = a string to use as the "back" button text; default is "Results" * * @return string HTML implementing the inspector */ function caEditorInspector($po_view, $pa_options = null) { require_once __CA_MODELS_DIR__ . '/ca_sets.php'; require_once __CA_MODELS_DIR__ . '/ca_data_exporters.php'; $t_item = $po_view->getVar('t_item'); $vs_table_name = $t_item->tableName(); if (($vs_priv_table_name = $vs_table_name) == 'ca_list_items') { $vs_priv_table_name = 'ca_lists'; } $vn_item_id = $t_item->getPrimaryKey(); $o_result_context = $po_view->getVar('result_context'); $t_ui = $po_view->getVar('t_ui'); $t_type = method_exists($t_item, "getTypeInstance") ? $t_item->getTypeInstance() : null; $vs_type_name = method_exists($t_item, "getTypeName") ? $t_item->getTypeName() : ''; if (!$vs_type_name) { $vs_type_name = $t_item->getProperty('NAME_SINGULAR'); } $va_reps = $po_view->getVar('representations'); $o_dm = Datamodel::load(); if ($t_item->isHierarchical()) { $va_ancestors = $po_view->getVar('ancestors'); $vn_parent_id = $t_item->get($t_item->getProperty('HIERARCHY_PARENT_ID_FLD')); } else { $va_ancestors = array(); $vn_parent_id = null; } // action extra to preserve currently open screen across next/previous links $vs_screen_extra = $po_view->getVar('screen') ? '/' . $po_view->getVar('screen') : ''; if ($vs_type_name == "list item") { $vs_style = "style='height:auto;'"; } if ($vn_item_id | $po_view->request->getAction() === 'Delete') { $vs_buf = '<h3 class="nextPrevious" ' . $vs_style . '>' . caEditorFindResultNavigation($po_view->request, $t_item, $o_result_context, $pa_options) . "</h3>\n"; } $vs_color = null; if ($t_type) { $vs_color = trim($t_type->get('color')); } if (!$vs_color && $t_ui) { $vs_color = trim($t_ui->get('color')); } if (!$vs_color) { $vs_color = "FFFFFF"; } $vs_buf .= "<h4><div id='caColorbox' style='border: 6px solid #{$vs_color};'>\n"; $vs_icon = null; if ($t_type) { $vs_icon = $t_type->getMediaTag('icon', 'icon'); } if (!$vs_icon && $t_ui) { $vs_icon = $t_ui->getMediaTag('icon', 'icon'); } if ($vs_icon) { $vs_buf .= "<div id='inspectoricon' style='border-right: 6px solid #{$vs_color}; border-bottom: 6px solid #{$vs_color}; -moz-border-radius-bottomright: 8px; -webkit-border-bottom-right-radius: 8px;'>\n{$vs_icon}</div>\n"; } if ($po_view->request->getAction() === 'Delete' && $po_view->request->getParameter('confirm', pInteger)) { $vs_buf .= "<strong>" . _t("Deleted %1", $vs_type_name) . "</strong>\n"; $vs_buf .= "<br style='clear: both;'/></div></h4>\n"; } else { if ($vn_item_id) { if (!$po_view->request->config->get("{$vs_priv_table_name}_inspector_disable_headline")) { if ($po_view->request->user->canDoAction("can_edit_" . $vs_priv_table_name) && sizeof($t_item->getTypeList()) > 1) { $vs_buf .= "<strong>" . _t("Editing %1", $vs_type_name) . ": </strong>\n"; } else { $vs_buf .= "<strong>" . _t("Viewing %1", $vs_type_name) . ": </strong>\n"; } } if ($t_item->hasField('is_deaccessioned') && $t_item->get('is_deaccessioned') && $t_item->get('deaccession_date', array('getDirectDate' => true)) <= caDateToHistoricTimestamp(_t('now'))) { // If currently deaccessioned then display deaccession message $vs_buf .= "<br/><div class='inspectorDeaccessioned'>" . _t('Deaccessioned %1', $t_item->get('deaccession_date')) . "</div>\n"; if ($vs_deaccession_notes = $t_item->get('deaccession_notes')) { TooltipManager::add(".inspectorDeaccessioned", $vs_deaccession_notes); } } else { if ($po_view->request->user->canDoAction('can_see_current_location_in_inspector_ca_objects')) { if ($t_ui && method_exists($t_item, "getObjectHistory") && (is_array($va_placements = $t_ui->getPlacementsForBundle('ca_objects_history')) && sizeof($va_placements) > 0)) { // // Output current "location" of object in life cycle. Configuration is taken from a ca_objects_history bundle configured for the current editor // $va_placement = array_shift($va_placements); $va_bundle_settings = $va_placement['settings']; if (is_array($va_history = $t_item->getObjectHistory($va_bundle_settings, array('limit' => 1, 'currentOnly' => true))) && sizeof($va_history) > 0) { $va_current_location = array_shift(array_shift($va_history)); if (!($vs_inspector_current_location_label = $po_view->request->config->get("ca_objects_inspector_current_location_label"))) { $vs_inspector_current_location_label = _t('Current'); } if ($va_current_location['display']) { $vs_buf .= "<div class='inspectorCurrentLocation'><strong>" . $vs_inspector_current_location_label . ':</strong><br/>' . $va_current_location['display'] . "</div>"; } } } elseif (method_exists($t_item, "getLastLocationForDisplay")) { // If no ca_objects_history bundle is configured then display the last storage location if ($vs_current_location = $t_item->getLastLocationForDisplay("<ifdef code='ca_storage_locations.parent.preferred_labels'>^ca_storage_locations.parent.preferred_labels ➜ </ifdef>^ca_storage_locations.preferred_labels.name")) { $vs_buf .= "<br/><div class='inspectorCurrentLocation'>" . _t('Location: %1', $vs_current_location) . "</div>\n"; $vs_full_location_hierarchy = $t_item->getLastLocationForDisplay("^ca_storage_locations.hierarchy.preferred_labels.name%delimiter=_➜_"); if ($vs_full_location_hierarchy !== $vs_current_location) { TooltipManager::add(".inspectorCurrentLocation", $vs_full_location_hierarchy); } } } } } // // Display flags; expressions for these are defined in app.conf in the <table_name>_inspector_display_flags directive // if (is_array($va_display_flags = $po_view->request->config->getAssoc("{$vs_table_name}_inspector_display_flags"))) { $va_display_flag_buf = array(); foreach ($va_display_flags as $vs_exp => $vs_display_flag) { $va_exp_vars = array(); foreach (ExpressionParser::getVariableList($vs_exp) as $vs_var_name) { $va_exp_vars[$vs_var_name] = $t_item->get($vs_var_name, array('returnIdno' => true)); } if (ExpressionParser::evaluate($vs_exp, $va_exp_vars)) { $va_display_flag_buf[] = $t_item->getWithTemplate("{$vs_display_flag}"); } } if (sizeof($va_display_flag_buf) > 0) { $vs_buf .= join("; ", $va_display_flag_buf); } } $vs_label = ''; $vb_dont_use_labels_for_ca_objects = (bool) $t_item->getAppConfig()->get('ca_objects_dont_use_labels'); if (!($vs_table_name === 'ca_objects' && $vb_dont_use_labels_for_ca_objects)) { if ($vs_get_spec = $po_view->request->config->get("{$vs_table_name}_inspector_display_title")) { $vs_label = caProcessTemplateForIDs($vs_get_spec, $vs_table_name, array($t_item->getPrimaryKey())); } else { $va_object_collection_collection_ancestors = $po_view->getVar('object_collection_collection_ancestors'); if ($t_item->tableName() == 'ca_objects' && $t_item->getAppConfig()->get('ca_objects_x_collections_hierarchy_enabled') && is_array($va_object_collection_collection_ancestors) && sizeof($va_object_collection_collection_ancestors)) { $va_collection_links = array(); foreach ($va_object_collection_collection_ancestors as $va_collection_ancestor) { $va_collection_links[] = caEditorLink($po_view->request, $va_collection_ancestor['label'], '', 'ca_collections', $va_collection_ancestor['collection_id']); } $vs_label .= join(" / ", $va_collection_links) . ' > '; } if (method_exists($t_item, 'getLabelForDisplay')) { $vn_parent_index = sizeof($va_ancestors) - 1; if ($vn_parent_id && ($vs_table_name != 'ca_places' || $vn_parent_index > 0)) { $va_parent = $va_ancestors[$vn_parent_index]; $vs_disp_fld = $t_item->getLabelDisplayField(); if ($va_parent['NODE'][$vs_disp_fld] && ($vs_editor_link = caEditorLink($po_view->request, $va_parent['NODE'][$vs_disp_fld], '', $vs_table_name, $va_parent['NODE'][$t_item->primaryKey()]))) { $vs_label .= $vs_editor_link . ' > ' . $t_item->getLabelForDisplay(); } else { $vs_label .= ($va_parent['NODE'][$vs_disp_fld] ? $va_parent['NODE'][$vs_disp_fld] . ' > ' : '') . $t_item->getLabelForDisplay(); } } else { $vs_label .= $t_item->getLabelForDisplay(); if ($vs_table_name === 'ca_editor_uis' && in_array($po_view->request->getAction(), array('EditScreen', 'DeleteScreen', 'SaveScreen'))) { $t_screen = new ca_editor_ui_screens($po_view->request->getParameter('screen_id', pInteger)); if (!($vs_screen_name = $t_screen->getLabelForDisplay())) { $vs_screen_name = _t('new screen'); } $vs_label .= " > " . $vs_screen_name; } } } else { $vs_label .= $t_item->get('name'); } } } $vb_show_idno = (bool) ($vs_idno = $t_item->get($t_item->getProperty('ID_NUMBERING_ID_FIELD'))); if (!$vs_label) { switch ($vs_table_name) { case 'ca_commerce_orders': if ($t_item->get('order_type') == 'L') { if ($vs_org = $t_item->get('billing_organization')) { $vs_label = _t('%5 #%4 on %1 to %2 (%3)', caGetLocalizedDate($t_item->get('created_on', array('getDirectDate' => true)), array('dateFormat' => 'delimited', 'timeOmit' => true)), $t_item->get('billing_fname') . ' ' . $t_item->get('billing_lname'), $vs_org, $t_item->getOrderNumber(), caUcFirstUTF8Safe($t_item->getProperty('NAME_SINGULAR'))); } else { $vs_label = _t('%4 #%3 on %1 to %2', caGetLocalizedDate($t_item->get('created_on', array('getDirectDate' => true)), array('dateFormat' => 'delimited', 'timeOmit' => true)), $t_item->get('billing_fname') . ' ' . $t_item->get('billing_lname'), $t_item->getOrderNumber(), caUcFirstUTF8Safe($t_item->getProperty('NAME_SINGULAR'))); } } else { if ($vs_org = $t_item->get('billing_organization')) { $vs_label = _t('%5 #%4 on %1 from %2 (%3)', caGetLocalizedDate($t_item->get('created_on', array('getDirectDate' => true)), array('dateFormat' => 'delimited', 'timeOmit' => true)), $t_item->get('billing_fname') . ' ' . $t_item->get('billing_lname'), $vs_org, $t_item->getOrderNumber(), caUcFirstUTF8Safe($t_item->getProperty('NAME_SINGULAR'))); } else { $vs_label = _t('%4 #%3 on %1 from %2', caGetLocalizedDate($t_item->get('created_on', array('getDirectDate' => true)), array('dateFormat' => 'delimited', 'timeOmit' => true)), $t_item->get('billing_fname') . ' ' . $t_item->get('billing_lname'), $t_item->getOrderNumber(), caUcFirstUTF8Safe($t_item->getProperty('NAME_SINGULAR'))); } } break; default: if ($vs_table_name === 'ca_objects' && $vb_dont_use_labels_for_ca_objects) { $vs_label = $vs_idno; $vb_show_idno = false; } else { $vs_label = '[' . _t('BLANK') . ']'; } break; } } $vs_buf .= "<div class='recordTitle {$vs_table_name}' style='width:190px; overflow:hidden;'>{$vs_label}" . ($vb_show_idno ? "<a title='{$vs_idno}'>" . ($vs_idno ? " ({$vs_idno})" : '') : "") . "</a></div>"; if ($vs_table_name === 'ca_object_lots' && $t_item->getPrimaryKey()) { $vs_buf .= "<div id='inspectorLotMediaDownload'><strong>" . (($vn_num_objects = $t_item->numObjects()) == 1 ? _t('Lot contains %1 object', $vn_num_objects) : _t('Lot contains %1 objects', $vn_num_objects)) . "</strong>\n"; } if ($po_view->request->config->get("include_custom_inspector")) { if (file_exists($po_view->request->getViewsDirectoryPath() . "/bundles/inspector_info.php")) { $vo_inspector_view = new View($po_view->request, $po_view->request->getViewsDirectoryPath() . "/bundles/"); $vo_inspector_view->setVar('t_item', $t_item); $vs_buf .= $vo_inspector_view->render('inspector_info.php'); } } } else { $vs_parent_name = ''; if ($vn_parent_id = $po_view->request->getParameter('parent_id', pInteger)) { $t_parent = clone $t_item; $t_parent->load($vn_parent_id); $vs_parent_name = $t_parent->getLabelForDisplay(); } $vs_buf .= "<div class='creatingNew'>" . _t("Creating new %1", $vs_type_name) . " " . ($vs_parent_name ? _t("%1 > New %2", $vs_parent_name, $vs_type_name) : '') . "</div>\n"; $vs_buf .= "<br/>\n"; } // ------------------------------------------------------------------------------------- if ($t_item->getPrimaryKey()) { if (sizeof($va_reps) > 0) { $va_imgs = array(); $vs_buf .= "<div id='inspectorMedia'>"; $vn_r = $vn_primary_index = 0; foreach ($va_reps as $va_rep) { if (!($va_rep['info']['preview170']['WIDTH'] && $va_rep['info']['preview170']['HEIGHT'])) { continue; } if ($vb_is_primary = isset($va_rep['is_primary']) && (bool) $va_rep['is_primary']) { $vn_primary_index = $vn_r; } $va_imgs[] = "{url:'" . $va_rep['urls']['preview170'] . "', width: " . $va_rep['info']['preview170']['WIDTH'] . ", height: " . $va_rep['info']['preview170']['HEIGHT'] . ", link: '#', onclick: 'caMediaPanel.showPanel(\\'" . caNavUrl($po_view->request, '*', '*', 'GetMediaOverlay', array($t_item->primaryKey() => $vn_item_id, 'representation_id' => $va_rep['representation_id'])) . "\\')'}"; $vn_r++; } if (sizeof($va_reps) > 1) { $vs_buf .= "\n\t\t\t\t\t<div class='leftScroll'>\n\t\t\t\t\t\t<a href='#' onclick='inspectorInfoRepScroller.scrollToPreviousImage(); return false;'>" . caNavIcon($po_view->request, __CA_NAV_BUTTON_SCROLL_LT__) . "</a>\n\t\t\t\t\t</div>\n\t\t"; } if (sizeof($va_imgs) > 0) { $vs_buf .= "\n\t\t\t\t<div id='inspectorInfoRepScrollingViewer' style='position: relative;'>\n\t\t\t\t\t<div id='inspectorInfoRepScrollingViewerContainer'>\n\t\t\t\t\t\t<div id='inspectorInfoRepScrollingViewerImageContainer'></div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t"; if (sizeof($va_reps) > 1) { $vs_buf .= "\n\t\t\t\t\t<div class='rightScroll'>\n\t\t\t\t\t\t<a href='#' onclick='inspectorInfoRepScroller.scrollToNextImage(); return false;'>" . caNavIcon($po_view->request, __CA_NAV_BUTTON_SCROLL_RT__) . "</a>\n\t\t\t\t\t</div>\n\t\t"; } TooltipManager::add(".leftScroll", _t('Previous')); TooltipManager::add(".rightScroll", _t('Next')); $vs_buf .= "<script type='text/javascript'>"; $vs_buf .= "\n\t\t\t\t\tvar inspectorInfoRepScroller = caUI.initImageScroller([" . join(",", $va_imgs) . "], 'inspectorInfoRepScrollingViewerImageContainer', {\n\t\t\t\t\t\t\tcontainerWidth: 170, containerHeight: 170,\n\t\t\t\t\t\t\timageCounterID: 'inspectorInfoRepScrollingViewerCounter',\n\t\t\t\t\t\t\tscrollingImageClass: 'inspectorInfoRepScrollerImage',\n\t\t\t\t\t\t\tscrollingImagePrefixID: 'inspectorInfoRep',\n\t\t\t\t\t\t\tinitialIndex: {$vn_primary_index}\n\t\t\t\t\t\t\t\n\t\t\t\t\t});\n\t\t\t\t</script>"; } $vs_buf .= "</div>\n"; if ($vs_get_spec = $po_view->request->config->get("{$vs_table_name}_inspector_display_below_media")) { $vs_buf .= caProcessTemplateForIDs($vs_get_spec, $vs_table_name, array($t_item->getPrimaryKey())); } } $vs_buf .= "<div id='toolIcons'>"; if ($vn_item_id) { # --- watch this link $vs_watch = ""; if (in_array($vs_table_name, array('ca_objects', 'ca_object_lots', 'ca_entities', 'ca_places', 'ca_occurrences', 'ca_collections', 'ca_storage_locations'))) { require_once __CA_MODELS_DIR__ . '/ca_watch_list.php'; $t_watch_list = new ca_watch_list(); $vs_watch = "<div class='watchThis'><a href='#' title='" . _t('Add/remove item to/from watch list.') . "' onclick='caToggleItemWatch(); return false;' id='caWatchItemButton'>" . caNavIcon($po_view->request, $t_watch_list->isItemWatched($vn_item_id, $t_item->tableNum(), $po_view->request->user->get("user_id")) ? __CA_NAV_BUTTON_UNWATCH__ : __CA_NAV_BUTTON_WATCH__) . "</a></div>"; $vs_buf .= "\n<script type='text/javascript'>\n\t\tfunction caToggleItemWatch() {\n\t\t\tvar url = '" . caNavUrl($po_view->request, $po_view->request->getModulePath(), $po_view->request->getController(), 'toggleWatch', array($t_item->primaryKey() => $vn_item_id)) . "';\n\t\t\t\n\t\t\tjQuery.getJSON(url, {}, function(data, status) {\n\t\t\t\tif (data['status'] == 'ok') {\n\t\t\t\t\tjQuery('#caWatchItemButton').html((data['state'] == 'watched') ? '" . addslashes(caNavIcon($po_view->request, __CA_NAV_BUTTON_UNWATCH__)) . "' : '" . addslashes(caNavIcon($po_view->request, __CA_NAV_BUTTON_WATCH__)) . "');\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log('Error toggling watch status for item: ' + data['errors']);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\t</script>\n"; } $vs_buf .= "{$vs_watch}\n"; TooltipManager::add("#caWatchItemButton", _t('Watch/Unwatch this record')); if ($po_view->request->user->canDoAction("can_change_type_{$vs_table_name}")) { $vs_buf .= "<div id='inspectorChangeType'><div id='inspectorChangeTypeButton'><a href='#' onclick='caTypeChangePanel.showPanel(); return false;'>" . caNavIcon($po_view->request, __CA_NAV_BUTTON_CHANGE__ . " Change Type", array('title' => _t('Change type'))) . "</a></div></div>\n"; $vo_change_type_view = new View($po_view->request, $po_view->request->getViewsDirectoryPath() . "/bundles/"); $vo_change_type_view->setVar('t_item', $t_item); FooterManager::add($vo_change_type_view->render("change_type_html.php")); TooltipManager::add("#inspectorChangeType", _t('Change Record Type')); } if ($t_item->getPrimaryKey() && $po_view->request->config->get($vs_table_name . '_show_add_child_control_in_inspector')) { $vb_show_add_child_control = true; if (is_array($va_restrict_add_child_control_to_types = $po_view->request->config->getList($vs_table_name . '_restrict_child_control_in_inspector_to_types')) && sizeof($va_restrict_add_child_control_to_types)) { $t_type_instance = $t_item->getTypeInstance(); if (!in_array($t_type_instance->get('idno'), $va_restrict_add_child_control_to_types) && !in_array($t_type_instance->getPrimaryKey(), $va_restrict_add_child_control_to_types)) { $vb_show_add_child_control = false; } } if ($vb_show_add_child_control) { if ((bool) $po_view->request->config->get($vs_table_name . '_enforce_strict_type_hierarchy')) { // strict menu $vs_type_list = $t_item->getTypeListAsHTMLFormElement('type_id', array('style' => 'width: 90px; font-size: 9px;'), array('childrenOfCurrentTypeOnly' => true, 'directChildrenOnly' => $po_view->request->config->get($vs_table_name . '_enforce_strict_type_hierarchy') == '~' ? false : true, 'returnHierarchyLevels' => true, 'access' => __CA_BUNDLE_ACCESS_EDIT__)); } else { // all types $vs_type_list = $t_item->getTypeListAsHTMLFormElement('type_id', array('style' => 'width: 90px; font-size: 9px;'), array('access' => __CA_BUNDLE_ACCESS_EDIT__)); } if ($vs_type_list) { $vs_buf .= "<div id='inspectorCreateChild'><div id='inspectorCreateChildButton'><a href='#' onclick='caCreateChildPanel.showPanel(); return false;'>" . caNavIcon($po_view->request, __CA_NAV_BUTTON_CHILD__, array('title' => _t('Create Child Record'))) . "</a></div></div>\n"; $vo_create_child_view = new View($po_view->request, $po_view->request->getViewsDirectoryPath() . "/bundles/"); $vo_create_child_view->setVar('t_item', $t_item); $vo_create_child_view->setVar('type_list', $vs_type_list); FooterManager::add($vo_create_child_view->render("create_child_html.php")); TooltipManager::add("#inspectorCreateChildButton", _t('Create a child record under this one')); } } } } if ($po_view->request->user->canDoAction('can_duplicate_' . $vs_table_name) && $t_item->getPrimaryKey()) { $vs_buf .= '<div id="caDuplicateItemButton">'; $vs_buf .= caFormTag($po_view->request, 'Edit', 'DuplicateItemForm', $po_view->request->getModulePath() . '/' . $po_view->request->getController(), 'post', 'multipart/form-data', '_top', array('disableUnsavedChangesWarning' => true, 'noTimestamp' => true)); $vs_buf .= caFormSubmitLink($po_view->request, caNavIcon($po_view->request, __CA_NAV_BUTTON_DUPLICATE__), '', 'DuplicateItemForm'); $vs_buf .= caHTMLHiddenInput($t_item->primaryKey(), array('value' => $t_item->getPrimaryKey())); $vs_buf .= caHTMLHiddenInput('mode', array('value' => 'dupe')); $vs_buf .= "</form>"; $vs_buf .= "</div>"; TooltipManager::add("#caDuplicateItemButton", _t('Duplicate this %1', mb_strtolower($vs_type_name, 'UTF-8'))); } // // Download media in lot ($vn_num_objects is only set for object lots) if ($vn_num_objects > 0) { $vs_buf .= "<div id='inspectorLotMediaDownloadButton'>" . caNavLink($po_view->request, caNavIcon($po_view->request, __CA_NAV_BUTTON_DOWNLOAD__), "button", $po_view->request->getModulePath(), $po_view->request->getController(), 'getLotMedia', array('lot_id' => $t_item->getPrimaryKey(), 'download' => 1), array()) . "</div>\n"; TooltipManager::add('#inspectorLotMediaDownloadButton', _t("Download all media associated with objects in this lot")); } // // Download media in set if ($vs_table_name == 'ca_sets' && sizeof($t_item->getItemRowIDs()) > 0) { $vs_buf .= "<div id='inspectorSetMediaDownloadButton'>" . caNavLink($po_view->request, caNavIcon($po_view->request, __CA_NAV_BUTTON_DOWNLOAD__), "button", $po_view->request->getModulePath(), $po_view->request->getController(), 'getSetMedia', array('set_id' => $t_item->getPrimaryKey(), 'download' => 1), array()) . "</div>\n"; TooltipManager::add('#inspectorSetMediaDownloadButton', _t("Download all media associated with records in this set")); } $vs_more_info = ''; // list of sets in which item is a member $t_set = new ca_sets(); if (is_array($va_sets = caExtractValuesByUserLocale($t_set->getSetsForItem($t_item->tableNum(), $t_item->getPrimaryKey(), array('user_id' => $po_view->request->getUserID(), 'access' => __CA_SET_READ_ACCESS__)))) && sizeof($va_sets)) { $va_links = array(); foreach ($va_sets as $vn_set_id => $va_set) { $va_links[] = "<a href='" . caEditorUrl($po_view->request, 'ca_sets', $vn_set_id) . "'>" . $va_set['name'] . "</a>"; } $vs_more_info .= "<div><strong>" . (sizeof($va_links) == 1 ? _t("In set") : _t("In sets")) . "</strong> " . join(", ", $va_links) . "</div>\n"; } // export options if ($vn_item_id && ($vs_select = $po_view->getVar('available_mappings_as_html_select'))) { $vs_more_info .= "<div class='inspectorExportControls'>" . caFormTag($po_view->request, 'exportItem', 'caExportForm', null, 'post', 'multipart/form-data', '_top', array('disableUnsavedChangesWarning' => true)); $vs_more_info .= $vs_select; $vs_more_info .= caHTMLHiddenInput($t_item->primaryKey(), array('value' => $t_item->getPrimaryKey())); $vs_more_info .= caHTMLHiddenInput('download', array('value' => 1)); $vs_more_info .= caFormSubmitLink($po_view->request, 'Export ›', 'button', 'caExportForm'); $vs_more_info .= "</form></div>"; } $va_creation = $t_item->getCreationTimestamp(); $va_last_change = $t_item->getLastChangeTimestamp(); if ($va_creation['timestamp'] || $va_last_change['timestamp']) { $vs_more_info .= "<div class='inspectorChangeDateList'>"; if ($va_creation['timestamp']) { if (!trim($vs_name = $va_creation['fname'] . ' ' . $va_creation['lname'])) { $vs_name = null; } $vs_interval = ($vn_t = time() - $va_creation['timestamp']) == 0 ? _t('Just now') : _t('%1 ago', caFormatInterval($vn_t, 2)); $vs_more_info .= "<div class='inspectorChangeDateListLine' id='caInspectorCreationDate'>" . ($vs_name ? _t('<strong>Created</strong><br/>%1 by %2', $vs_interval, $vs_name) : _t('<strong>Created</strong><br/>%1', $vs_interval)) . "</div>"; TooltipManager::add("#caInspectorCreationDate", "<h2>" . _t('Created on') . "</h2>" . _t('Created on %1', caGetLocalizedDate($va_creation['timestamp'], array('dateFormat' => 'delimited')))); } if ($va_last_change['timestamp'] && $va_creation['timestamp'] != $va_last_change['timestamp']) { if (!trim($vs_name = $va_last_change['fname'] . ' ' . $va_last_change['lname'])) { $vs_name = null; } $vs_interval = ($vn_t = time() - $va_last_change['timestamp']) == 0 ? _t('Just now') : _t('%1 ago', caFormatInterval($vn_t, 2)); $vs_more_info .= "<div class='inspectorChangeDateListLine' id='caInspectorChangeDate'>" . ($vs_name ? _t('<strong>Last changed</strong><br/>%1 by %2', $vs_interval, $vs_name) : _t('<strong>Last changed</strong><br/>%1', $vs_interval)) . "</div>"; TooltipManager::add("#caInspectorChangeDate", "<h2>" . _t('Last changed on') . "</h2>" . _t('Last changed on %1', caGetLocalizedDate($va_last_change['timestamp'], array('dateFormat' => 'delimited')))); } if (method_exists($t_item, 'getMetadataDictionaryRuleViolations') && is_array($va_violations = $t_item->getMetadataDictionaryRuleViolations()) && ($vn_num_violations = sizeof($va_violations)) > 0) { $va_violation_messages = array(); foreach ($va_violations as $vn_violation_id => $va_violation) { $vs_label = $t_item->getDisplayLabel($va_violation['bundle_name']); $va_violation_messages[] = "<li><em><u>{$vs_label}</u></em> " . $va_violation['violationMessage'] . "</li>"; } $vs_more_info .= "<div id='caInspectorViolationsList'>" . ($vs_num_violations_display = "<img src='" . $po_view->request->getThemeUrlPath() . "/graphics/icons/warning_small.gif' border='0'/> " . ($vn_num_violations > 1 ? _t('%1 problems require attention', $vn_num_violations) : _t('%1 problem requires attention', $vn_num_violations))) . "</div>\n"; TooltipManager::add("#caInspectorViolationsList", "<h2>{$vs_num_violations_display}</h2><ol>" . join("\n", $va_violation_messages)) . "</ol>\n"; } $vs_more_info .= "</div>\n"; } if ($vs_get_spec = $po_view->request->config->get("{$vs_table_name}_inspector_display_more_info")) { $vs_more_info .= caProcessTemplateForIDs($vs_get_spec, $vs_table_name, array($t_item->getPrimaryKey())); } if ($vs_more_info) { $vs_buf .= "<div class='button info'><a href='#' id='inspectorMoreInfo'>" . caNavIcon($po_view->request, __CA_NAV_BUTTON_INFO2__) . "</a></div>\n\t\t\t<div id='inspectorInfo' >"; $vs_buf .= $vs_more_info . "</div>\n"; TooltipManager::add("#inspectorMoreInfo", _t('See more information about this record')); } $vs_buf .= "</div><!--End tooIcons-->"; } // ------------------------------------------------------------------------------------- // // Item-specific information // // // Output info for related items // if (!$t_item->getPrimaryKey()) { // only applies to new records $vs_rel_table = $po_view->request->getParameter('rel_table', pString); $vn_rel_type_id = $po_view->request->getParameter('rel_type_id', pString); $vn_rel_id = $po_view->request->getParameter('rel_id', pInteger); if ($vs_rel_table && $po_view->request->datamodel->tableExists($vs_rel_table) && $vn_rel_type_id && $vn_rel_id) { $t_rel = $po_view->request->datamodel->getTableInstance($vs_rel_table); if ($t_rel && $t_rel->load($vn_rel_id)) { $vs_buf .= '<strong>' . _t("Will be related to %1", $t_rel->getTypeName()) . '</strong>: ' . $t_rel->getLabelForDisplay(); } } } // // Output lot info for ca_objects // $vb_is_currently_part_of_lot = true; if (!($vn_lot_id = $t_item->get('lot_id'))) { $vn_lot_id = $po_view->request->getParameter('lot_id', pInteger); $vb_is_currently_part_of_lot = false; } if ($vs_table_name === 'ca_objects' && $vn_lot_id) { require_once __CA_MODELS_DIR__ . '/ca_object_lots.php'; $va_lot_lots = caGetTypeListForUser('ca_object_lots', array('access' => __CA_BUNDLE_ACCESS_READONLY__)); $t_lot = new ca_object_lots($vn_lot_id); if ($t_lot->get('deleted') == 0 && in_array($t_lot->get('type_id'), $va_lot_lots)) { if (!($vs_lot_displayname = $t_lot->get('idno_stub'))) { if (!($vs_lot_displayname = $t_lot->getLabelForDisplay())) { $vs_lot_displayname = "Lot {$vn_lot_id}"; } } if ($vs_lot_displayname) { if (!($vs_part_of_lot_msg = $po_view->request->config->get("ca_objects_inspector_part_of_lot_msg"))) { $vs_part_of_lot_msg = _t('Part of lot'); } if (!($vs_will_be_part_of_lot_msg = $po_view->request->config->get("ca_objects_inspector_will_be_part_of_lot_msg"))) { $vs_will_be_part_of_lot_msg = _t('Will be part of lot'); } $vs_buf .= "<strong>" . ($vb_is_currently_part_of_lot ? $vs_part_of_lot_msg : $vs_will_be_part_of_lot_msg) . "</strong>: " . caNavLink($po_view->request, $vs_lot_displayname, '', 'editor/object_lots', 'ObjectLotEditor', 'Edit', array('lot_id' => $vn_lot_id)); } } } $va_object_container_types = $po_view->request->config->getList('ca_objects_container_types'); $va_object_component_types = $po_view->request->config->getList('ca_objects_component_types'); $vb_can_add_component = $vs_table_name === 'ca_objects' && $t_item->getPrimaryKey() && $po_view->request->user->canDoAction('can_create_ca_objects') && $t_item->canTakeComponents(); if (method_exists($t_item, 'getComponentCount')) { if ($vn_component_count = $t_item->getComponentCount()) { if ($t_ui && ($vs_component_list_screen = $t_ui->getScreenWithBundle("ca_objects_components_list", $po_view->request)) && $vs_component_list_screen !== $po_view->request->getActionExtra()) { $vs_component_count_link = caNavLink($po_view->request, $vn_component_count == 1 ? _t('%1 component', $vn_component_count) : _t('%1 components', $vn_component_count), '', '*', '*', $po_view->request->getAction() . '/' . $vs_component_list_screen, array($t_item->primaryKey() => $t_item->getPrimaryKey())); } else { $vs_component_count_link = $vn_component_count == 1 ? _t('%1 component', $vn_component_count) : _t('%1 components', $vn_component_count); } $vs_buf .= "<br/><strong>" . _t('Has') . ":</strong> {$vs_component_count_link}"; } } if ($vb_can_add_component) { $vs_buf .= ' <a href="#" onclick=\'caObjectComponentPanel.showPanel("' . caNavUrl($po_view->request, '*', 'ObjectComponent', 'Form', array('parent_id' => $t_item->getPrimaryKey())) . '"); return false;\')>' . caNavIcon($po_view->request, __CA_NAV_BUTTON_ADD__) . '</a>'; $vo_change_type_view = new View($po_view->request, $po_view->request->getViewsDirectoryPath() . "/bundles/"); $vo_change_type_view->setVar('t_item', $t_item); FooterManager::add($vo_change_type_view->render("create_component_html.php")); } // // Output lot info for ca_object_lots // if ($vs_table_name === 'ca_object_lots' && $t_item->getPrimaryKey()) { $va_component_types = $po_view->request->config->getList('ca_objects_component_types'); if (is_array($va_component_types) && sizeof($va_component_types)) { $vs_buf .= "<strong>" . (($vn_num_objects = $t_item->numObjects(null, array('return' => 'objects'))) == 1 ? _t('Lot contains %1 object', $vn_num_objects) : _t('Lot contains %1 objects', $vn_num_objects)) . "</strong>\n"; $vs_buf .= "<strong>" . (($vn_num_components = $t_item->numObjects(null, array('return' => 'components'))) == 1 ? _t('Lot contains %1 component', $vn_num_components) : _t('Lot contains %1 components', $vn_num_components)) . "</strong>\n"; } else { $vs_buf .= "<strong>" . (($vn_num_objects = $t_item->numObjects()) == 1 ? _t('Lot contains %1 object', $vn_num_objects) : _t('Lot contains %1 objects', $vn_num_objects)) . "</strong>\n"; } if ((bool) $po_view->request->config->get('allow_automated_renumbering_of_objects_in_a_lot') && ($va_nonconforming_objects = $t_item->getObjectsWithNonConformingIdnos())) { $vs_buf .= '<br/><br/><em>' . (($vn_c = sizeof($va_nonconforming_objects)) == 1 ? _t('There is %1 object with non-conforming numbering', $vn_c) : _t('There are %1 objects with non-conforming numbering', $vn_c)) . "</em>\n"; $vs_buf .= "<a href='#' onclick='jQuery(\"#inspectorNonConformingNumberList\").toggle(250); return false;'>" . caNavIcon($po_view->request, __CA_NAV_BUTTON_ADD__); $vs_buf .= "<div id='inspectorNonConformingNumberList' class='inspectorNonConformingNumberList'><div class='inspectorNonConformingNumberListScroll'><ol>\n"; foreach ($va_nonconforming_objects as $vn_object_id => $va_object_info) { $vs_buf .= '<li>' . caEditorLink($po_view->request, $va_object_info['idno'], '', 'ca_objects', $vn_object_id) . "</li>\n"; } $vs_buf .= "</ol></div>"; $vs_buf .= caNavLink($po_view->request, _t('Re-number objects') . ' ›', 'button', $po_view->request->getModulePath(), $po_view->request->getController(), 'renumberObjects', array('lot_id' => $t_item->getPrimaryKey())); $vs_buf .= "</div>\n"; } require_once __CA_MODELS_DIR__ . '/ca_objects.php'; $t_object = new ca_objects(); $vs_buf .= "<div class='inspectorLotObjectTypeControls'><form action='#' id='caAddObjectToLotForm'>"; if ((bool) $po_view->request->config->get('ca_objects_enforce_strict_type_hierarchy')) { // strict menu $vs_buf .= _t('Add new %1 to lot', $t_object->getTypeListAsHTMLFormElement('type_id', array('id' => 'caAddObjectToLotForm_type_id'), array('childrenOfCurrentTypeOnly' => true, 'directChildrenOnly' => $po_view->request->config->get('ca_objects_enforce_strict_type_hierarchy') == '~' ? false : true, 'returnHierarchyLevels' => true, 'access' => __CA_BUNDLE_ACCESS_EDIT__))); } else { // all types $vs_buf .= _t('Add new %1 to lot', $t_object->getTypeListAsHTMLFormElement('type_id', array('id' => 'caAddObjectToLotForm_type_id'), array('access' => __CA_BUNDLE_ACCESS_EDIT__))); } $vs_buf .= " <a href='#' onclick='caAddObjectToLotForm()'>" . caNavIcon($po_view->request, __CA_NAV_BUTTON_ADD__) . '</a>'; $vs_buf .= "</form></div>\n"; $vs_buf .= "<script type='text/javascript'>\n\tfunction caAddObjectToLotForm() { \n\t\twindow.location='" . caEditorUrl($po_view->request, 'ca_objects', 0, false, array('lot_id' => $t_item->getPrimaryKey(), 'rel' => 1, 'type_id' => '')) . "' + jQuery('#caAddObjectToLotForm_type_id').val();\n\t}\n\tjQuery(document).ready(function() {\n\t\tjQuery('#objectLotsNonConformingNumberList').hide();\n\t});\n</script>\n"; } if ($vs_table_name === 'ca_objects') { // // Output loan info for ca_objects // if ($po_view->request->user->canDoAction('can_manage_clients') && ($va_loan_details = $t_item->isOnLoan())) { $vs_buf .= "<div>" . caNavLink($po_view->request, _t('On loan to %1', $va_loan_details['billing_fname'] . ' ' . $va_loan_details['billing_lname']), 'inspectorOnLoan', 'client/library', 'OrderEditor', 'Edit', array('order_id' => $va_loan_details['order_id'])) . "</div>"; } // // Output checkout info for ca_objects // if ((bool) $po_view->request->config->get('enable_client_services') && ((bool) $po_view->request->config->get('enable_client_services_sales') || (bool) $po_view->request->config->get('enable_client_services_library')) && $t_item->canBeCheckedOut() && ($va_checkout_status = $t_item->getCheckoutStatus(array('returnAsArray' => true)))) { $vs_buf .= "<div class='inspectorCheckedOut'>" . $va_checkout_status['status_display']; if ($va_checkout_status['user_name']) { $vs_buf .= _t("; checked out by %1", $va_checkout_status['user_name']); } $vs_buf .= "</div>"; } } // // Output related objects for ca_object_representations // if ($vs_table_name === 'ca_object_representations') { foreach (array('ca_objects', 'ca_object_lots', 'ca_entities', 'ca_places', 'ca_occurrences', 'ca_collections', 'ca_storage_locations', 'ca_loans', 'ca_movements') as $vs_rel_table) { if (sizeof($va_objects = $t_item->getRelatedItems($vs_rel_table))) { $vs_buf .= "<div><strong>" . _t("Related %1", $o_dm->getTableProperty($vs_rel_table, 'NAME_PLURAL')) . "</strong>: <br/>\n"; $vs_screen = ''; if ($t_ui = ca_editor_uis::loadDefaultUI($vs_rel_table, $po_view->request, null)) { $vs_screen = $t_ui->getScreenWithBundle('ca_object_representations', $po_view->request); } foreach ($va_objects as $vn_rel_id => $va_rel_info) { if ($vs_label = array_shift($va_rel_info['labels'])) { $vs_buf .= caEditorLink($po_view->request, '← ' . $vs_label . ' (' . $va_rel_info['idno'] . ')', '', $vs_rel_table, $va_rel_info[$o_dm->getTablePrimaryKeyName($vs_rel_table)], array(), array(), array('action' => 'Edit' . ($vs_screen ? "/{$vs_screen}" : ""))) . "<br/>\n"; } } $vs_buf .= "</div>\n"; } } } // // Output related object reprsentation for ca_representation_annotation // if ($vs_table_name === 'ca_representation_annotations') { if ($vn_representation_id = $t_item->get('representation_id')) { $vs_buf .= "<div><strong>" . _t("Applied to representation") . "</strong>: <br/>\n"; $t_rep = new ca_object_representations($vn_representation_id); $vs_buf .= caNavLink($po_view->request, '← ' . $t_rep->getLabelForDisplay(), '', 'editor/object_representations', 'ObjectRepresentationEditor', 'Edit/' . $po_view->getVar('representation_editor_screen'), array('representation_id' => $vn_representation_id)) . '<br/>'; $vs_buf .= "</div>\n"; } } // // Output extra useful info for sets // if ($vs_table_name === 'ca_sets') { $vn_set_item_count = $t_item->getItemCount(array('user_id' => $po_view->request->getUserID())); if ($vn_set_item_count > 0 && $po_view->request->user->canDoAction('can_batch_edit_' . $o_dm->getTableName($t_item->get('table_num')))) { $vs_buf .= caNavButton($po_view->request, __CA_NAV_BUTTON_BATCH_EDIT__, _t('Batch edit'), 'editorBatchSetEditorLink', 'batch', 'Editor', 'Edit', array('set_id' => $t_item->getPrimaryKey()), array(), array('icon_position' => __CA_NAV_BUTTON_ICON_POS_LEFT__, 'no_background' => true, 'dont_show_content' => true)); } $vs_buf .= "<div><strong>" . _t("Number of items") . "</strong>: {$vn_set_item_count}<br/>\n"; if ($t_item->getPrimaryKey()) { $vn_set_table_num = $t_item->get('table_num'); $vs_set_table_name = $o_dm->getTableName($vn_set_table_num); $vs_buf .= "<strong>" . _t("Type of content") . "</strong>: " . caGetTableDisplayName($vn_set_table_num) . "<br/>\n"; $vs_buf .= "</div>\n"; } else { if ($vn_set_table_num = $po_view->request->getParameter('table_num', pInteger)) { $vs_buf .= "<div><strong>" . _t("Type of content") . "</strong>: " . caGetTableDisplayName($vn_set_table_num) . "<br/>\n"; $vs_buf .= "</div>\n"; } } $t_user = new ca_users(($vn_user_id = $t_item->get('user_id')) ? $vn_user_id : $po_view->request->getUserID()); if ($t_user->getPrimaryKey()) { $vs_buf .= "<div><strong>" . _t('Owner') . "</strong>: " . $t_user->get('fname') . ' ' . $t_user->get('lname') . "</div>\n"; } if ($po_view->request->user->canDoAction('can_export_' . $vs_set_table_name) && $t_item->getPrimaryKey() && sizeof(ca_data_exporters::getExporters($vn_set_table_num)) > 0) { $vs_buf .= '<div style="border-top: 1px solid #aaaaaa; margin-top: 5px; font-size: 10px; text-align: right;" id="caExportItemButton">'; $vs_buf .= _t('Export this set of records') . " "; $vs_buf .= "<a class='button' onclick='jQuery(\"#exporterFormList\").show();' style='text-align:right;' href='#'>" . caNavIcon($po_view->request, __CA_NAV_BUTTON_ADD__) . "</a>"; $vs_buf .= caFormTag($po_view->request, 'ExportData', 'caExportForm', 'manage/MetadataExport', 'post', 'multipart/form-data', '_top', array('disableUnsavedChangesWarning' => true)); $vs_buf .= "<div id='exporterFormList'>"; $vs_buf .= ca_data_exporters::getExporterListAsHTMLFormElement('exporter_id', $vn_set_table_num, array('id' => 'caExporterList'), array('width' => '135px')); $vs_buf .= caHTMLHiddenInput('set_id', array('value' => $t_item->getPrimaryKey())); $vs_buf .= caFormSubmitLink($po_view->request, _t('Export') . " ›", "button", "caExportForm"); $vs_buf .= "</div>\n"; $vs_buf .= "</form>"; $vs_buf .= "</div>"; $vs_buf .= "<script type='text/javascript'>"; $vs_buf .= "jQuery(document).ready(function() {"; $vs_buf .= "jQuery(\"#exporterFormList\").hide();"; $vs_buf .= "});"; $vs_buf .= "</script>"; } } // // Output extra useful info for set items // if ($vs_table_name === 'ca_set_items') { AssetLoadManager::register("panel"); $t_set = new ca_sets(); if ($t_set->load($vn_set_id = $t_item->get('set_id'))) { $vs_buf .= "<div><strong>" . _t("Part of set") . "</strong>: " . caEditorLink($po_view->request, $t_set->getLabelForDisplay(), '', 'ca_sets', $vn_set_id) . "<br/>\n"; $t_content_instance = $t_item->getAppDatamodel()->getInstanceByTableNum($vn_item_table_num = $t_item->get('table_num')); if ($t_content_instance->load($vn_row_id = $t_item->get('row_id'))) { $vs_label = $t_content_instance->getLabelForDisplay(); if ($vs_id_fld = $t_content_instance->getProperty('ID_NUMBERING_ID_FIELD')) { $vs_label .= " (" . $t_content_instance->get($vs_id_fld) . ")"; } $vs_buf .= "<strong>" . _t("Is %1", caGetTableDisplayName($vn_item_table_num, false) . "</strong>: " . caEditorLink($po_view->request, $vs_label, '', $vn_item_table_num, $vn_row_id)) . "<br/>\n"; } $vs_buf .= "</div>\n"; } } // // Output extra useful info for lists // if ($vs_table_name === 'ca_lists' && $t_item->getPrimaryKey()) { $vs_buf .= "<strong>" . _t("Number of items") . "</strong>: " . $t_item->numItemsInList() . "<br/>\n"; $t_list_item = new ca_list_items(); $t_list_item->load(array('list_id' => $t_item->getPrimaryKey(), 'parent_id' => null)); $vs_type_list = $t_list_item->getTypeListAsHTMLFormElement('type_id', array('style' => 'width: 90px; font-size: 9px;'), array('access' => __CA_BUNDLE_ACCESS_EDIT__)); if ($vs_type_list) { $vs_buf .= '<div style="border-top: 1px solid #aaaaaa; margin-top: 5px; font-size: 10px;">'; $vs_buf .= caFormTag($po_view->request, 'Edit', 'NewChildForm', 'administrate/setup/list_item_editor/ListItemEditor', 'post', 'multipart/form-data', '_top', array('disableUnsavedChangesWarning' => true)); $vs_buf .= _t('Add a %1 to this list', $vs_type_list) . caHTMLHiddenInput($t_list_item->primaryKey(), array('value' => '0')) . caHTMLHiddenInput('parent_id', array('value' => $t_list_item->getPrimaryKey())); $vs_buf .= caFormSubmitLink($po_view->request, caNavIcon($po_view->request, __CA_NAV_BUTTON_ADD__), '', 'NewChildForm'); $vs_buf .= "</form></div>\n"; } } // // Output containing list for list items // if ($vs_table_name === 'ca_list_items') { if ($t_list = $po_view->getVar('t_list')) { $vn_list_id = $t_list->getPrimaryKey(); $vs_buf .= "<strong>" . _t("Part of") . "</strong>: " . caEditorLink($po_view->request, $t_list->getLabelForDisplay(), '', 'ca_lists', $vn_list_id) . "<br/>\n"; if ($t_item->get('is_default')) { $vs_buf .= "<strong>" . _t("Is default for list") . "</strong><br/>\n"; } } } // // Output containing relationship type name for relationship types // if ($vs_table_name === 'ca_relationship_types') { if (!($t_rel_instance = $t_item->getAppDatamodel()->getInstanceByTableNum($t_item->get('table_num'), true))) { if ($vn_parent_id = $po_view->request->getParameter('parent_id', pInteger)) { $t_rel_type = new ca_relationship_types($vn_parent_id); $t_rel_instance = $t_item->getAppDatamodel()->getInstanceByTableNum($t_rel_type->get('table_num'), true); } } if ($t_rel_instance) { $vs_buf .= "<div><strong>" . _t("Is a") . "</strong>: " . $t_rel_instance->getProperty('NAME_SINGULAR') . "<br/></div>\n"; } } // // Output extra useful info for metadata elements // if ($vs_table_name === 'ca_metadata_elements' && $t_item->getPrimaryKey()) { $vs_buf .= "<div><strong>" . _t("Element code") . "</strong>: " . $t_item->get('element_code') . "<br/></div>\n"; if (sizeof($va_uis = $t_item->getUIs()) > 0) { $vs_buf .= "<div><strong>" . _t("Referenced by user interfaces") . "</strong>:<br/>\n"; foreach ($va_uis as $vn_ui_id => $va_ui_info) { $vs_buf .= caNavLink($po_view->request, $va_ui_info['name'], '', 'administrate/setup/interface_screen_editor', 'InterfaceScreenEditor', 'Edit', array('ui_id' => $vn_ui_id, 'screen_id' => $va_ui_info['screen_id'])); $vs_buf .= " (" . $o_dm->getTableProperty($va_ui_info['editor_type'], 'NAME_PLURAL') . ")<br/>\n"; } $vs_buf .= "</div>\n"; } } // // Output related objects for ca_editor_uis and ca_editor_ui_screens // if ($vs_table_name === 'ca_editor_uis') { $vs_buf .= "<div><strong>" . _t("Number of screens") . "</strong>: " . (int) $t_item->getScreenCount() . "\n"; if ($t_item->getPrimaryKey()) { $vs_buf .= "<div><strong>" . _t("Edits") . "</strong>: " . caGetTableDisplayName($t_item->get('editor_type')) . "<br/>\n"; } else { $vs_buf .= "<div><strong>" . _t("Edits") . "</strong>: " . caGetTableDisplayName($po_view->request->getParameter('editor_type', pInteger)) . "<br/>\n"; } $vs_buf .= "</div>\n"; } // // Output related objects for ca_editor_uis and ca_editor_ui_screens // if ($vs_table_name === 'ca_editor_ui_screens') { $t_ui = new ca_editor_uis($vn_ui_id = $t_item->get('ui_id')); $vs_buf .= "<div><strong>" . _t("Part of") . "</strong>: " . caNavLink($po_view->request, $t_ui->getLabelForDisplay(), '', 'administrate/setup/interface_editor', 'InterfaceEditor', 'Edit', array('ui_id' => $vn_ui_id)) . "\n"; $vs_buf .= "</div>\n"; } // // Output extra useful info for bundle displays // if ($vs_table_name === 'ca_bundle_displays') { $vs_buf .= "<div><strong>" . _t("Number of placements") . "</strong>: " . $t_item->getPlacementCount(array('user_id' => $po_view->request->getUserID())) . "<br/>\n"; if ($t_item->getPrimaryKey()) { $vn_content_table_num = $t_item->get('table_num'); $vs_buf .= "<strong>" . _t("Type of content") . "</strong>: " . caGetTableDisplayName($vn_content_table_num) . "\n"; $vs_buf .= "</div>\n"; } else { if ($vn_content_table_num = $po_view->request->getParameter('table_num', pInteger)) { $vs_buf .= "<div><strong>" . _t("Type of content") . "</strong>: " . caGetTableDisplayName($vn_content_table_num) . "\n"; $vs_buf .= "</div>\n"; } } $t_user = new ca_users(($vn_user_id = $t_item->get('user_id')) ? $vn_user_id : $po_view->request->getUserID()); if ($t_user->getPrimaryKey()) { $vs_buf .= "<div><strong>" . _t('Owner') . "</strong>: " . $t_user->get('fname') . ' ' . $t_user->get('lname') . "</div>\n"; } } // // Output extra useful info for search forms // if ($vs_table_name === 'ca_search_forms') { $vs_buf .= "<div><strong>" . _t("Number of placements") . "</strong>: " . $t_item->getPlacementCount(array('user_id' => $po_view->request->getUserID())) . "<br/>\n"; if ($t_item->getPrimaryKey()) { $vn_content_table_num = $t_item->get('table_num'); $vs_buf .= "<strong>" . _t("Searches for") . "</strong>: " . caGetTableDisplayName($vn_content_table_num) . "\n"; $vs_buf .= "</div>\n"; } else { if ($vn_content_table_num = $po_view->request->getParameter('table_num', pInteger)) { $vs_buf .= "<strong>" . _t("Searches for") . "</strong>: " . caGetTableDisplayName($vn_content_table_num) . "\n"; $vs_buf .= "</div>\n"; } } $t_user = new ca_users(($vn_user_id = $t_item->get('user_id')) ? $vn_user_id : $po_view->request->getUserID()); if ($t_user->getPrimaryKey()) { $vs_buf .= "<div><strong>" . _t('Owner') . "</strong>: " . $t_user->get('fname') . ' ' . $t_user->get('lname') . "</div>\n"; } } // // Output extra useful info for tours // if ($vs_table_name === 'ca_tours' && $t_item->getPrimaryKey()) { $vs_buf .= "<br/><strong>" . _t("Number of stops") . "</strong>: " . $t_item->getStopCount() . "<br/>\n"; } // // Output containing tour for tour stops // if ($vs_table_name === 'ca_tour_stops') { $t_tour = new ca_tours($vn_tour_id = $t_item->get('tour_id')); $vs_buf .= "<strong>" . _t("Part of") . "</strong>: " . caEditorLink($po_view->request, $t_tour->getLabelForDisplay(), '', 'ca_tours', $vn_tour_id) . "<br/>\n"; } // // Output extra useful info for bundle mappings // if ($vs_table_name === 'ca_bundle_mappings') { if ($t_item->getPrimaryKey()) { $vn_content_table_num = $t_item->get('table_num'); $vs_buf .= "<br/><strong>" . _t("Type of content") . "</strong>: " . caGetTableDisplayName($vn_content_table_num) . "<br/>\n"; $vs_buf .= "<strong>" . _t("Type") . "</strong>: " . $t_item->getChoiceListValue('direction', $t_item->get('direction')) . "<br/>\n"; $vs_buf .= "<strong>" . _t("Target format") . "</strong>: " . $t_item->get('target') . "<br/>\n"; $va_stats = $t_item->getMappingStatistics(); $vs_buf .= "<div><strong>" . _t("Number of groups") . "</strong>: " . $va_stats['groupCount'] . "<br/>\n"; $vs_buf .= "<strong>" . _t("Number of rules") . "</strong>: " . $va_stats['ruleCount'] . "<br/>\n"; $vs_buf .= "</div>\n"; } else { if ($vn_content_table_num = $po_view->request->getParameter('table_num', pInteger)) { $vs_buf .= "<div><strong>" . _t("Type of content") . "</strong>: " . caGetTableDisplayName($vn_content_table_num) . "<br/>\n"; $vs_buf .= "<strong>" . _t("Type") . "</strong>: " . $t_item->getChoiceListValue('direction', $po_view->request->getParameter('direction', pString)) . "<br/>\n"; $vs_buf .= "<strong>" . _t("Target format") . "</strong>: " . $po_view->request->getParameter('target', pString) . "<br/>\n"; $vs_buf .= "<div><strong>" . _t("Number of groups") . "</strong>: 0<br/>\n"; $vs_buf .= "<strong>" . _t("Number of rules") . "</strong>: 0</div>\n"; $vs_buf .= "</div>\n"; } } } // // Output extra useful info for client services/commerce orders // if ($vs_table_name === 'ca_commerce_orders') { $o_client_services_config = Configuration::load($po_view->request->config->get('client_services_config')); $va_order_totals = $t_item->getOrderTotals(); if ($va_order_totals['fee'] + $va_order_totals['tax'] + $va_order_totals['shipping'] + $va_order_totals['handling'] + $va_order_totals['additional_order_fees'] + $va_order_totals['additional_item_fees'] != 0) { $vs_currency_symbol = $o_client_services_config->get('currency_symbol'); $vs_buf .= "<table style='margin-left: 10px;'>"; $vs_buf .= "<tr><td><strong>" . _t("Items") . '</strong></td><td>' . $vs_currency_symbol . sprintf("%4.2f", $va_order_totals['fee']) . " (" . (int) $va_order_totals['items'] . ")</td></tr>\n"; $vs_buf .= "<tr><td><strong>" . _t("S+H") . '</strong></td><td>' . $vs_currency_symbol . sprintf("%4.2f", $va_order_totals['shipping'] + $va_order_totals['handling']) . "</td></tr>\n"; $vs_buf .= "<tr><td><strong>" . _t("Tax") . '</strong></td><td>' . $vs_currency_symbol . sprintf("%4.2f", $va_order_totals['tax']) . "</td></tr>\n"; $vs_buf .= "<tr><td><strong>" . _t("Addtl fees") . '</strong></td><td>' . $vs_currency_symbol . sprintf("%4.2f", $va_order_totals['additional_order_fees'] + $va_order_totals['additional_item_fees']) . "</td></tr>\n"; $vs_buf .= "<tr><td><strong>" . _t("Total") . '</strong></td><td>' . $vs_currency_symbol . sprintf("%4.2f", $va_order_totals['fee'] + $va_order_totals['tax'] + $va_order_totals['shipping'] + $va_order_totals['handling'] + $va_order_totals['additional_order_fees'] + $va_order_totals['additional_item_fees']) . "</td></tr>\n"; $vs_buf .= "</table>"; $vs_buf .= "<strong>" . $t_item->getFieldInfo('payment_status', 'LABEL') . "</strong>: " . $t_item->getChoiceListValue('payment_status', $t_item->get('payment_status')) . "<br/>\n"; } $vs_buf .= "<br/><strong>" . $t_item->getFieldInfo('order_status', 'LABEL') . "</strong>: " . $t_item->getChoiceListValue('order_status', $t_item->get('order_status')) . "<br/>\n"; if ($vs_shipping_date = $t_item->get('shipping_date', array('dateFormat' => 'delimited', 'timeOmit' => true))) { $vs_buf .= "<strong>" . $t_item->getFieldInfo('shipping_date', 'LABEL') . "</strong>: " . $vs_shipping_date; if ($vs_shipped_on_date = $t_item->get('shipped_on_date', array('dateFormat' => 'delimited'))) { $vs_buf .= " (" . _t('shipped %1', $vs_shipped_on_date) . ")"; } else { $vs_buf .= " (" . _t('not shipped') . ")"; } $vs_buf .= "<br/>\n"; } if (($vn_shipping_method = $t_item->get('shipping_method')) && $t_item->getChoiceListValue('shipping_method', $vn_shipping_method) != 'None') { $vs_buf .= "<strong>" . $t_item->getFieldInfo('shipping_method', 'LABEL') . "</strong>: " . $t_item->getChoiceListValue('shipping_method', $vn_shipping_method) . "<br/>\n"; } } // // Output configurable additional info from config, if set // if ($vs_additional_info = $po_view->request->config->get("{$vs_table_name}_inspector_additional_info")) { if (is_array($vs_additional_info)) { $vs_buf .= "<br/>"; foreach ($vs_additional_info as $vs_info) { $vs_buf .= caProcessTemplateForIDs($vs_info, $vs_table_name, array($t_item->getPrimaryKey()), array('requireLinkTags' => true)) . "<br/>\n"; } } else { $vs_buf .= "<br/>" . caProcessTemplateForIDs($vs_additional_info, $vs_table_name, array($t_item->getPrimaryKey()), array('requireLinkTags' => true)) . "<br/>\n"; } } // ------------------------------------------------------------------------------------- // Export if ($t_item->getPrimaryKey() && $po_view->request->config->get($vs_table_name . '_show_add_child_control_in_inspector')) { $vb_show_add_child_control = true; if (is_array($va_restrict_add_child_control_to_types = $po_view->request->config->getList($vs_table_name . '_restrict_child_control_in_inspector_to_types')) && sizeof($va_restrict_add_child_control_to_types)) { $t_type_instance = $t_item->getTypeInstance(); if (!in_array($t_type_instance->get('idno'), $va_restrict_add_child_control_to_types) && !in_array($t_type_instance->getPrimaryKey(), $va_restrict_add_child_control_to_types)) { $vb_show_add_child_control = false; } } } if ($po_view->request->user->canDoAction('can_export_' . $vs_table_name) && $t_item->getPrimaryKey() && sizeof(ca_data_exporters::getExporters($t_item->tableNum())) > 0) { $vs_buf .= '<div style="border-top: 1px solid #aaaaaa; margin-top: 5px; font-size: 10px; text-align: right;" id="caExportItemButton">'; $vs_buf .= _t('Export this %1', mb_strtolower($vs_type_name, 'UTF-8')) . " "; $vs_buf .= "<a class='button' onclick='jQuery(\"#exporterFormList\").show();' style='text-align:right;' href='#'>" . caNavIcon($po_view->request, __CA_NAV_BUTTON_ADD__) . "</a>"; $vs_buf .= caFormTag($po_view->request, 'ExportSingleData', 'caExportForm', 'manage/MetadataExport', 'post', 'multipart/form-data', '_top', array('disableUnsavedChangesWarning' => true)); $vs_buf .= "<div id='exporterFormList'>"; $vs_buf .= ca_data_exporters::getExporterListAsHTMLFormElement('exporter_id', $t_item->tableNum(), array('id' => 'caExporterList'), array('width' => '120px')); $vs_buf .= caHTMLHiddenInput('item_id', array('value' => $t_item->getPrimaryKey())); $vs_buf .= caFormSubmitLink($po_view->request, _t('Export') . " ›", "button", "caExportForm"); $vs_buf .= "</div>\n"; $vs_buf .= "</form>"; $vs_buf .= "</div>"; $vs_buf .= "<script type='text/javascript'>"; $vs_buf .= "jQuery(document).ready(function() {"; $vs_buf .= "jQuery(\"#exporterFormList\").hide();"; $vs_buf .= "});"; $vs_buf .= "</script>"; } $vs_buf .= "</div></h4>\n"; $vs_buf .= "<script type='text/javascript'>\n\t\t\tvar inspectorCookieJar = jQuery.cookieJar('caCookieJar');"; if ($t_item->getPrimaryKey()) { if ($vs_more_info) { $vs_buf .= "\t\t\t\n\t\t\tif (inspectorCookieJar.get('inspectorMoreInfoIsOpen') == undefined) {\t\t// default is to have info open\n\t\t\t\tinspectorCookieJar.set('inspectorMoreInfoIsOpen', 1);\n\t\t\t}\n\t\t\tif (inspectorCookieJar.get('inspectorMoreInfoIsOpen') == 1) {\n\t\t\t\tjQuery('#inspectorInfo').toggle(0);\n\t\t\t\tjQuery('#inspectorMoreInfo').html('" . addslashes(caNavIcon($po_view->request, __CA_NAV_BUTTON_COLLAPSE__)) . "');\n\t\t\t}\n\t\t\n\t\t\tjQuery('#inspectorMoreInfo').click(function() {\n\t\t\t\tjQuery('#inspectorInfo').slideToggle(350, function() { \n\t\t\t\t\tinspectorCookieJar.set('inspectorMoreInfoIsOpen', (this.style.display == 'block') ? 1 : 0); \n\t\t\t\t\tjQuery('#inspectorMoreInfo').html((this.style.display == 'block') ? '" . addslashes(caNavIcon($po_view->request, __CA_NAV_BUTTON_COLLAPSE__)) . "' : '" . addslashes(caNavIcon($po_view->request, __CA_NAV_BUTTON_INFO2__)) . "');\n\t\t\t\t\tcaResizeSideNav();\n\t\t\t\t}); \n\t\t\t\treturn false;\n\t\t\t});\n\t\t"; } if (sizeof($va_reps)) { $vs_buf .= "\n\t\tif (inspectorCookieJar.get('inspectorShowMediaIsOpen') == undefined) {\t\t// default is to have media open\n\t\t\tinspectorCookieJar.set('inspectorShowMediaIsOpen', 1);\n\t\t}\n\t\t\n\t\tif (inspectorCookieJar.get('inspectorShowMediaIsOpen') == 1) {\n\t\t\tjQuery('#inspectorMedia').toggle();\n\t\t}\n\t\n\t\tjQuery('#caColorbox').on('click', function(e) {\n\t\t\tif (e.altKey) {\n\t\t\t\tjQuery('#inspectorMedia').slideToggle(200, function() { \n\t\t\t\t\tinspectorCookieJar.set('inspectorShowMediaIsOpen', (this.style.display == 'block') ? 1 : 0); \n\t\t\t\t\t\tcaResizeSideNav();\n\t\t\t\t}); \n\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\t\t\t\t\t"; } } $vs_buf .= "</script>\n"; } $o_app_plugin_manager = new ApplicationPluginManager(); $va_hookAppend = $o_app_plugin_manager->hookAppendToEditorInspector(array("t_item" => $t_item)); if (is_string($va_hookAppend["caEditorInspectorAppend"])) { $vs_buf .= $va_hookAppend["caEditorInspectorAppend"]; } return $vs_buf; }
/** * Return list of items from the specified table that are related to the current browse set. This is the method that actually * pulls the facet content, regardless of whether the facet is cached yet or not. If you want to use the facet cache, call * BrowseEngine::getFacet() * * @see BrowseEngine::getFacet() * Options: * checkAccess = array of access values to filter facets that have an 'access' field by * checkAvailabilityOnly = if true then content is not actually fetch - only the availablility of content is verified * user_id = If set item level access control is performed relative to specified user_id, otherwise defaults to logged in user */ public function getFacetContent($ps_facet_name, $pa_options = null) { global $AUTH_CURRENT_USER_ID; $vs_browse_table_name = $this->ops_browse_table_name; $vs_browse_table_num = $this->opn_browse_table_num; $vn_user_id = isset($pa_options['user_id']) && (int) $pa_options['user_id'] ? (int) $pa_options['user_id'] : (int) $AUTH_CURRENT_USER_ID; $vb_show_if_no_acl = (bool) ($this->opo_config->get('default_item_access_level') > __CA_ACL_NO_ACCESS__); $t_user = new ca_users($vn_user_id); if (is_array($va_groups = $t_user->getUserGroups()) && sizeof($va_groups)) { $va_group_ids = array_keys($va_groups); } else { $va_group_ids = array(); } if (!is_array($this->opa_browse_settings)) { return null; } if (!isset($this->opa_browse_settings['facets'][$ps_facet_name])) { return null; } if (!is_array($pa_options)) { $pa_options = array(); } $vb_check_availability_only = isset($pa_options['checkAvailabilityOnly']) ? (bool) $pa_options['checkAvailabilityOnly'] : false; $va_all_criteria = $this->getCriteria(); $va_criteria = $this->getCriteria($ps_facet_name); $va_facet_info = $this->opa_browse_settings['facets'][$ps_facet_name]; $t_subject = $this->getSubjectInstance(); if ($va_facet_info['relative_to']) { $vs_browse_table_name = $va_facet_info['relative_to']; $vs_browse_table_num = $this->opo_datamodel->getTableNum($vs_browse_table_name); } $vs_browse_type_limit_sql = ''; if (($va_browse_type_ids = $this->getTypeRestrictionList()) && sizeof($va_browse_type_ids)) { // type restrictions $vs_browse_type_limit_sql = '(' . $t_subject->tableName() . '.' . $t_subject->getTypeFieldName() . ' IN (' . join(', ', $va_browse_type_ids) . ')' . ($t_subject->getFieldInfo('type_id', 'IS_NULL') ? " OR (" . $this->ops_browse_table_name . '.' . $t_subject->getTypeFieldName() . " IS NULL)" : '') . ')'; if (is_array($va_facet_info['type_restrictions'])) { // facet type restrictions bind a facet to specific types; we check them here $va_restrict_to_types = $this->_convertTypeCodesToIDs($va_facet_info['type_restrictions']); $vb_is_ok_to_browse = false; foreach ($va_browse_type_ids as $vn_type_id) { if (in_array($vn_type_id, $va_restrict_to_types)) { $vb_is_ok_to_browse = true; break; } } if (!$vb_is_ok_to_browse) { return array(); } } } // Values to exclude from list attributes and authorities; can be idnos or ids $va_exclude_values = caGetOption('exclude_values', $va_facet_info, array(), array('castTo' => 'array')); $va_results = $this->opo_ca_browse_cache->getResults(); $vb_single_value_is_present = false; $vs_single_value = isset($va_facet_info['single_value']) ? $va_facet_info['single_value'] : null; $va_wheres = array(); switch ($va_facet_info['type']) { # ----------------------------------------------------- case 'has': $vn_state = null; if (isset($va_all_criteria[$ps_facet_name])) { break; } // only one instance of this facet allowed per browse if (!($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true))) { break; } $vs_yes_text = isset($va_facet_info['label_yes']) && $va_facet_info['label_yes'] ? $va_facet_info['label_yes'] : _t('Yes'); $vs_no_text = isset($va_facet_info['label_no']) && $va_facet_info['label_no'] ? $va_facet_info['label_no'] : _t('No'); $va_facet_values = array('yes' => array('id' => 1, 'label' => $vs_yes_text), 'no' => array('id' => 0, 'label' => $vs_no_text)); // Actually check that both yes and no values will result in something if ($va_facet_info['element_code']) { $t_element = new ca_metadata_elements(); if (!$t_element->load(array('element_code' => $va_facet_info['element_code']))) { break; } $vs_element_code = $va_facet_info['element_code']; $va_facet = array(); $va_counts = array(); foreach ($va_facet_values as $vs_state_name => $va_state_info) { $va_wheres = array(); $va_joins = array(); if (!(bool) $va_state_info['id']) { // no option $va_wheres[] = $this->ops_browse_table_name . '.' . $t_item->primaryKey() . " NOT IN (select row_id from ca_attributes where table_num = " . $t_item->tableNum() . " AND element_id = " . $t_element->getPrimaryKey() . ")"; } else { // yes option $va_joins[] = "LEFT JOIN ca_attributes AS caa ON " . $this->ops_browse_table_name . '.' . $t_item->primaryKey() . " = caa.row_id AND " . $t_item->tableNum() . " = caa.table_num"; $va_wheres[] = "caa.element_id = " . $t_element->getPrimaryKey(); } if ($t_item->hasField('deleted')) { $va_wheres[] = "(" . $t_item->tableName() . ".deleted = 0)"; } if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_item->hasField('access')) { $va_wheres[] = "(" . $vs_browse_table_name . ".access IN (" . join(',', $pa_options['checkAccess']) . "))"; } if (sizeof($va_results)) { $va_wheres[] = $vs_browse_table_name . "." . $t_item->primaryKey() . " IN (" . join(",", $va_results) . ")"; } if ($va_facet_info['relative_to']) { if ($t_subject->hasField('deleted')) { $va_wheres[] = "(" . $t_subject->tableName() . ".deleted = 0)"; } if ($va_relative_sql_data = $this->_getRelativeFacetSQLData($va_facet_info['relative_to'], $pa_options)) { $va_joins = array_merge($va_joins, $va_relative_sql_data['joins']); $va_wheres = array_merge($va_wheres, $va_relative_sql_data['wheres']); } } if ($this->opo_config->get('perform_item_level_access_checking')) { if ($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true)) { // Join to limit what browse table items are used to generate facet $va_joins[] = 'LEFT JOIN ca_acl ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_acl.row_id AND ca_acl.table_num = ' . $t_item->tableNum() . "\n"; $va_wheres[] = "(\n\t\t\t\t\t\t\t\t\t\t((\n\t\t\t\t\t\t\t\t\t\t\t(ca_acl.user_id = " . (int) $vn_user_id . ")\n\t\t\t\t\t\t\t\t\t\t\t" . (sizeof($va_group_ids) > 0 ? "OR\n\t\t\t\t\t\t\t\t\t\t\t(ca_acl.group_id IN (" . join(",", $va_group_ids) . "))" : "") . "\n\t\t\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t\t\t(ca_acl.user_id IS NULL and ca_acl.group_id IS NULL)\n\t\t\t\t\t\t\t\t\t\t) AND ca_acl.access >= " . __CA_ACL_READONLY_ACCESS__ . ")\n\t\t\t\t\t\t\t\t\t\t" . ($vb_show_if_no_acl ? "OR ca_acl.acl_id IS NULL" : "") . "\n\t\t\t\t\t\t\t\t\t)"; } } $vs_join_sql = join("\n", $va_joins); $vs_where_sql = ''; if (sizeof($va_wheres) > 0) { $vs_where_sql = ' WHERE ' . join(' AND ', $va_wheres); } if ($vb_check_availability_only) { $vs_sql = "\n\t\t\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\t\t\tFROM " . $vs_browse_table_name . "\n\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\t\t\tLIMIT 2\n\t\t\t\t\t\t\t\t"; //print "$vs_sql<hr>"; $qr_res = $this->opo_db->query($vs_sql); if ($qr_res->nextRow()) { $va_counts[$vs_state_name] = (int) $qr_res->numRows(); } } else { $vs_sql = "\n\t\t\t\t\t\t\t\t\tSELECT " . $vs_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\tFROM " . $vs_browse_table_name . "\n\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\t\t"; //print "$vs_sql<hr>"; $qr_res = $this->opo_db->query($vs_sql); if ($qr_res->numRows() > 0) { $va_facet[$vs_state_name] = $va_state_info; } else { return array(); // if either option in a "has" facet fails then don't show the facet } } } } else { $vs_rel_table_name = $va_facet_info['table']; if (!is_array($va_restrict_to_relationship_types = $va_facet_info['restrict_to_relationship_types'])) { $va_restrict_to_relationship_types = array(); } $va_restrict_to_relationship_types = $this->_getRelationshipTypeIDs($va_restrict_to_relationship_types, $va_facet_info['relationship_table']); if (!is_array($va_exclude_relationship_types = $va_facet_info['exclude_relationship_types'])) { $va_exclude_relationship_types = array(); } $va_exclude_relationship_types = $this->_getRelationshipTypeIDs($va_exclude_relationship_types, $va_facet_info['relationship_table']); $vn_table_num = $this->opo_datamodel->getTableNum($vs_rel_table_name); $vs_rel_table_pk = $this->opo_datamodel->getTablePrimaryKeyName($vn_table_num); switch (sizeof($va_path = array_keys($this->opo_datamodel->getPath($vs_browse_table_name, $vs_rel_table_name)))) { case 3: $t_item_rel = $this->opo_datamodel->getInstanceByTableName($va_path[1], true); $t_rel_item = $this->opo_datamodel->getInstanceByTableName($va_path[2], true); $vs_key = 'relation_id'; break; case 2: $t_item_rel = null; $t_rel_item = $this->opo_datamodel->getInstanceByTableName($va_path[1], true); $vs_key = $t_rel_item->primaryKey(); break; default: // bad related table return null; break; } $vs_cur_table = array_shift($va_path); $va_joins_init = array(); foreach ($va_path as $vs_join_table) { $va_rel_info = $this->opo_datamodel->getRelationships($vs_cur_table, $vs_join_table); $va_joins_init[] = ($vn_state ? 'INNER' : 'LEFT') . ' JOIN ' . $vs_join_table . ' ON ' . $vs_cur_table . '.' . $va_rel_info[$vs_cur_table][$vs_join_table][0][0] . ' = ' . $vs_join_table . '.' . $va_rel_info[$vs_cur_table][$vs_join_table][0][1] . "\n"; $vs_cur_table = $vs_join_table; } $va_facet = array(); $va_counts = array(); foreach ($va_facet_values as $vs_state_name => $va_state_info) { $va_wheres = array(); $va_joins = $va_joins_init; if (!(bool) $va_state_info['id']) { // no option $va_wheres[] = "(" . $t_rel_item->tableName() . "." . $t_rel_item->primaryKey() . " IS NULL)"; if ($t_rel_item->hasField('deleted')) { $va_wheres[] = "((" . $t_rel_item->tableName() . ".deleted = 0) OR (" . $t_rel_item->tableName() . ".deleted IS NULL))"; } if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_rel_item->hasField('access')) { $va_wheres[] = "((" . $t_rel_item->tableName() . ".access NOT IN (" . join(',', $pa_options['checkAccess']) . ")) OR (" . $t_rel_item->tableName() . ".access IS NULL))"; } if (sizeof($va_restrict_to_relationship_types) > 0 && is_object($t_item_rel)) { $va_wheres[] = "((" . $t_item_rel->tableName() . ".type_id NOT IN (" . join(',', $va_restrict_to_relationship_types) . ")) OR (" . $t_item_rel->tableName() . ".type_id IS NULL))"; } if (sizeof($va_exclude_relationship_types) > 0 && is_object($t_item_rel)) { $va_wheres[] = "(" . $t_item_rel->tableName() . ".type_id IN (" . join(',', $va_exclude_relationship_types) . "))"; } } else { // yes option $va_wheres[] = "(" . $t_rel_item->tableName() . "." . $t_rel_item->primaryKey() . " IS NOT NULL)"; if ($t_rel_item->hasField('deleted')) { $va_wheres[] = "(" . $t_rel_item->tableName() . ".deleted = 0)"; } if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_rel_item->hasField('access')) { $va_wheres[] = "(" . $t_rel_item->tableName() . ".access IN (" . join(',', $pa_options['checkAccess']) . "))"; } if (sizeof($va_restrict_to_relationship_types) > 0 && is_object($t_item_rel)) { $va_wheres[] = "(" . $t_item_rel->tableName() . ".type_id IN (" . join(',', $va_restrict_to_relationship_types) . "))"; } if (sizeof($va_exclude_relationship_types) > 0 && is_object($t_item_rel)) { $va_wheres[] = "(" . $t_item_rel->tableName() . ".type_id NOT IN (" . join(',', $va_exclude_relationship_types) . "))"; } } if ($t_item->hasField('deleted')) { $va_wheres[] = "(" . $t_item->tableName() . ".deleted = 0)"; } if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_item->hasField('access')) { $va_wheres[] = "(" . $vs_browse_table_name . ".access IN (" . join(',', $pa_options['checkAccess']) . "))"; } if (sizeof($va_results)) { $va_wheres[] = $vs_browse_table_name . "." . $t_item->primaryKey() . " IN (" . join(",", $va_results) . ")"; } if ($va_facet_info['relative_to']) { if ($t_subject->hasField('deleted')) { $va_wheres[] = "(" . $t_subject->tableName() . ".deleted = 0)"; } if ($va_relative_sql_data = $this->_getRelativeFacetSQLData($va_facet_info['relative_to'], $pa_options)) { $va_joins = array_merge($va_joins, $va_relative_sql_data['joins']); $va_wheres = array_merge($va_wheres, $va_relative_sql_data['wheres']); } } if ($this->opo_config->get('perform_item_level_access_checking')) { if ($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true)) { // Join to limit what browse table items are used to generate facet $va_joins[] = 'LEFT JOIN ca_acl ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_acl.row_id AND ca_acl.table_num = ' . $t_item->tableNum() . "\n"; $va_wheres[] = "(\n\t\t\t\t\t\t\t\t\t\t((\n\t\t\t\t\t\t\t\t\t\t\t(ca_acl.user_id = " . (int) $vn_user_id . ")\n\t\t\t\t\t\t\t\t\t\t\t" . (sizeof($va_group_ids) > 0 ? "OR\n\t\t\t\t\t\t\t\t\t\t\t(ca_acl.group_id IN (" . join(",", $va_group_ids) . "))" : "") . "\n\t\t\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t\t\t(ca_acl.user_id IS NULL and ca_acl.group_id IS NULL)\n\t\t\t\t\t\t\t\t\t\t) AND ca_acl.access >= " . __CA_ACL_READONLY_ACCESS__ . ")\n\t\t\t\t\t\t\t\t\t\t" . ($vb_show_if_no_acl ? "OR ca_acl.acl_id IS NULL" : "") . "\n\t\t\t\t\t\t\t\t\t)"; } } $vs_join_sql = join("\n", $va_joins); $vs_where_sql = ''; if (sizeof($va_wheres) > 0) { $vs_where_sql = ' WHERE ' . join(' AND ', $va_wheres); } if ($vb_check_availability_only) { $vs_sql = "\n\t\t\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\t\t\tFROM " . $vs_browse_table_name . "\n\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\t\t\tLIMIT 2\n\t\t\t\t\t\t\t\t"; //print "$vs_sql<hr>"; $qr_res = $this->opo_db->query($vs_sql); if ($qr_res->nextRow()) { $va_counts[$vs_state_name] = (int) $qr_res->numRows(); } } else { $vs_sql = "\n\t\t\t\t\t\t\t\t\tSELECT " . $vs_browse_table_name . '.' . $t_item->primaryKey() . "\n\t\t\t\t\t\t\t\t\tFROM " . $vs_browse_table_name . "\n\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\t\t"; //print "$vs_sql<hr>"; $qr_res = $this->opo_db->query($vs_sql); if ($qr_res->numRows() > 0) { $va_facet[$vs_state_name] = $va_state_info; } else { return array(); // if either option in a "has" facet fails then don't show the facet } } } } if ($vb_check_availability_only) { return sizeof($va_counts) > 1 ? true : false; } return $va_facet; break; # ----------------------------------------------------- # ----------------------------------------------------- case 'label': if (!($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true))) { break; } if (!($t_label = $t_item->getLabelTableInstance())) { break; } if (!is_array($va_restrict_to_types = $va_facet_info['restrict_to_types'])) { $va_restrict_to_types = array(); } $vs_item_pk = $t_item->primaryKey(); $vs_label_table_name = $t_label->tableName(); $vs_label_pk = $t_label->primaryKey(); $vs_label_display_field = $t_item->getLabelDisplayField(); $vs_label_sort_field = $t_item->getLabelSortField(); $vs_where_sql = $vs_join_sql = ''; $vb_needs_join = false; $va_where_sql = array(); $va_joins = array(); if ($vs_browse_type_limit_sql) { $va_where_sql[] = $vs_browse_type_limit_sql; } if (isset($va_facet_info['preferred_labels_only']) && $va_facet_info['preferred_labels_only'] && $t_label->hasField('is_preferred')) { $va_where_sql[] = "l.is_preferred = 1"; } if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_item->hasField('access')) { $va_where_sql[] = "(" . $vs_browse_table_name . ".access IN (" . join(',', $pa_options['checkAccess']) . "))"; } if ($t_item->hasField('deleted')) { $va_where_sql[] = "(" . $vs_browse_table_name . ".deleted = 0)"; $vb_needs_join = true; } if (sizeof($va_restrict_to_types)) { $va_restrict_to_type_ids = caMakeTypeIDList($vs_browse_table_name, $va_restrict_to_types, array('dont_include_subtypes_in_type_restriction' => true)); if (sizeof($va_restrict_to_type_ids)) { $va_where_sql[] = "(" . $vs_browse_table_name . "." . $t_item->getTypeFieldName() . " IN (" . join(", ", $va_restrict_to_type_ids) . ")" . ($t_item->getFieldInfo('type_id', 'IS_NULL') ? " OR (" . $vs_browse_table_name . '.' . $t_item->getTypeFieldName() . " IS NULL)" : '') . ")"; $vb_needs_join = true; } } if (sizeof($va_exclude_types)) { $va_exclude_type_ids = caMakeTypeIDList($vs_browse_table_name, $va_exclude_types, array('dont_include_subtypes_in_type_restriction' => true)); if (sizeof($va_exclude_type_ids)) { $va_where_sql[] = "(" . $vs_browse_table_name . "." . $t_item->getTypeFieldName() . " NOT IN (" . join(", ", $va_exclude_type_ids) . ")" . ($t_item->getFieldInfo('type_id', 'IS_NULL') ? " OR (" . $vs_browse_table_name . '.' . $t_item->getTypeFieldName() . " IS NULL)" : '') . ")"; $vb_needs_join = true; } } if ($vb_needs_join) { $va_joins[] = "INNER JOIN " . $vs_browse_table_name . " ON " . $vs_browse_table_name . "." . $t_item->primaryKey() . " = l." . $t_item->primaryKey(); } if ($va_facet_info['relative_to']) { if ($t_subject->hasField('deleted')) { $va_where_sql[] = "(" . $t_subject->tableName() . ".deleted = 0)"; } if ($va_relative_sql_data = $this->_getRelativeFacetSQLData($va_facet_info['relative_to'], $pa_options)) { $va_joins = array_merge($va_joins, $va_relative_sql_data['joins']); $va_where_sql = array_merge($va_where_sql, $va_relative_sql_data['wheres']); } } if (sizeof($va_results)) { if ($va_facet_info['relative_to']) { $va_where_sql[] = $this->ops_browse_table_name . "." . $t_subject->primaryKey() . " IN (" . join(",", $va_results) . ")"; } else { $va_where_sql[] = "l.{$vs_item_pk} IN (" . join(",", $va_results) . ")"; } } if ($this->opo_config->get('perform_item_level_access_checking')) { if ($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true)) { // Join to limit what browse table items are used to generate facet $va_joins[] = 'LEFT JOIN ca_acl ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_acl.row_id AND ca_acl.table_num = ' . $t_item->tableNum() . "\n"; $va_where_sql[] = "(\n\t\t\t\t\t\t\t\t((\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id = " . (int) $vn_user_id . ")\n\t\t\t\t\t\t\t\t\t" . (sizeof($va_group_ids) > 0 ? "OR\n\t\t\t\t\t\t\t\t\t(ca_acl.group_id IN (" . join(",", $va_group_ids) . "))" : "") . "\n\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id IS NULL and ca_acl.group_id IS NULL)\n\t\t\t\t\t\t\t\t) AND ca_acl.access >= " . __CA_ACL_READONLY_ACCESS__ . ")\n\t\t\t\t\t\t\t\t" . ($vb_show_if_no_acl ? "OR ca_acl.acl_id IS NULL" : "") . "\n\t\t\t\t\t\t\t)"; } } $vs_join_sql = join("\n", $va_joins); if (sizeof($va_where_sql)) { $vs_where_sql = "WHERE " . join(" AND ", $va_where_sql); } if ($vb_check_availability_only) { $vs_sql = "\n\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\tFROM {$vs_label_table_name} l\n\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\tLIMIT 1\n\t\t\t\t\t\t"; $qr_res = $this->opo_db->query($vs_sql); return (int) $qr_res->numRows() > 0 ? true : false; } else { $vs_parent_fld = $t_item->getProperty('HIERARCHY_PARENT_ID_FLD'); $vs_sql = "\n\t\t\t\t\t\t\tSELECT l.* " . ($vs_parent_fld ? ", " . $vs_browse_table_name . "." . $vs_parent_fld : '') . " \n\t\t\t\t\t\t\tFROM {$vs_label_table_name} l\n\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t"; $qr_res = $this->opo_db->query($vs_sql); $va_values = array(); $va_child_counts = array(); $vn_parent_id = null; while ($qr_res->nextRow()) { $vn_id = $qr_res->get($t_item->primaryKey()); if ($vs_parent_fld) { $vn_parent_id = $qr_res->get($vs_parent_fld); if ($vn_parent_id) { $va_child_counts[$vn_parent_id]++; } } $va_values[$vn_id][$qr_res->get('locale_id')] = array_merge($qr_res->getRow(), array('id' => $vn_id, 'parent_id' => $vn_parent_id, 'label' => $qr_res->get($vs_label_display_field))); if (!is_null($vs_single_value) && $vn_id == $vs_single_value) { $vb_single_value_is_present = true; } } if ($vs_parent_fld) { foreach ($va_values as $vn_id => $va_values_by_locale) { foreach ($va_values_by_locale as $vn_locale_id => $va_value) { $va_values[$vn_id][$vn_locale_id]['child_count'] = (int) $va_child_counts[$vn_id]; } } } if (!is_null($vs_single_value) && !$vb_single_value_is_present) { return array(); } $va_values = caExtractValuesByUserLocale($va_values); return $va_values; } break; # ----------------------------------------------------- # ----------------------------------------------------- case 'attribute': $t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true); $t_element = new ca_metadata_elements(); if (!$t_element->load(array('element_code' => $va_facet_info['element_code']))) { return array(); } $vn_element_type = $t_element->get('datatype'); $vn_element_id = $t_element->getPrimaryKey(); $va_joins = array('INNER JOIN ca_attribute_values ON ca_attributes.attribute_id = ca_attribute_values.attribute_id', 'INNER JOIN ' . $vs_browse_table_name . ' ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_attributes.row_id AND ca_attributes.table_num = ' . intval($vs_browse_table_num)); $va_wheres = array(); if (sizeof($va_results) && $this->numCriteria() > 0) { $va_wheres[] = "(" . $t_subject->tableName() . '.' . $t_subject->primaryKey() . " IN (" . join(',', $va_results) . "))"; } if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_item->hasField('access')) { $va_wheres[] = "(" . $vs_browse_table_name . ".access IN (" . join(',', $pa_options['checkAccess']) . "))"; } if ($vs_browse_type_limit_sql) { $va_wheres[] = $vs_browse_type_limit_sql; } if ($t_item->hasField('deleted')) { $va_wheres[] = "(" . $vs_browse_table_name . ".deleted = 0)"; } if ($va_facet_info['relative_to']) { if ($t_subject->hasField('deleted')) { $va_wheres[] = "(" . $t_subject->tableName() . ".deleted = 0)"; } if ($va_relative_sql_data = $this->_getRelativeFacetSQLData($va_facet_info['relative_to'], $pa_options)) { $va_joins = array_merge($va_joins, $va_relative_sql_data['joins']); $va_wheres = array_merge($va_wheres, $va_relative_sql_data['wheres']); } } if ($this->opo_config->get('perform_item_level_access_checking')) { if ($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true)) { // Join to limit what browse table items are used to generate facet $va_joins[] = 'LEFT JOIN ca_acl ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_acl.row_id AND ca_acl.table_num = ' . $t_item->tableNum() . "\n"; $va_wheres[] = "(\n\t\t\t\t\t\t\t\t((\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id = " . (int) $vn_user_id . ")\n\t\t\t\t\t\t\t\t\t" . (sizeof($va_group_ids) > 0 ? "OR\n\t\t\t\t\t\t\t\t\t(ca_acl.group_id IN (" . join(",", $va_group_ids) . "))" : "") . "\n\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id IS NULL and ca_acl.group_id IS NULL)\n\t\t\t\t\t\t\t\t) AND ca_acl.access >= " . __CA_ACL_READONLY_ACCESS__ . ")\n\t\t\t\t\t\t\t\t" . ($vb_show_if_no_acl ? "OR ca_acl.acl_id IS NULL" : "") . "\n\t\t\t\t\t\t\t)"; } } $vs_join_sql = join("\n", $va_joins); if (is_array($va_wheres) && sizeof($va_wheres) && ($vs_where_sql = join(' AND ', $va_wheres))) { $vs_where_sql = ' AND (' . $vs_where_sql . ')'; } if ($vb_check_availability_only) { // exclude criteria values $vs_criteria_exclude_sql = ''; if (is_array($va_criteria) && sizeof($va_criteria)) { $vs_criteria_exclude_sql = ' AND (ca_attribute_values.value_longtext1 NOT IN (' . join(", ", caQuoteList(array_keys($va_criteria))) . ')) '; } $vs_sql = "\n\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\tFROM ca_attributes\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t(ca_attribute_values.element_id = ?) {$vs_criteria_exclude_sql} {$vs_where_sql}\n\t\t\t\t\t\t\tLIMIT 2"; //print $vs_sql; $qr_res = $this->opo_db->query($vs_sql, $vn_element_id); return (int) $qr_res->numRows() > 1 ? true : false; } else { $vs_sql = "\n\t\t\t\t\t\t\tSELECT DISTINCT value_longtext1, value_decimal1, value_longtext2, value_integer1\n\t\t\t\t\t\t\tFROM ca_attributes\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\tca_attribute_values.element_id = ? {$vs_where_sql}"; $qr_res = $this->opo_db->query($vs_sql, $vn_element_id); $va_values = array(); $va_list_items = null; $va_suppress_values = null; if ($va_facet_info['suppress'] && !is_array($va_facet_info['suppress'])) { $va_facet_info['suppress'] = array($va_facet_info['suppress']); } if (!is_array($va_suppress_values = caGetOption('suppress', $va_facet_info, null))) { $va_suppress_values = caGetOption('exclude_values', $va_facet_info, null); } switch ($vn_element_type) { case __CA_ATTRIBUTE_VALUE_LIST__: $va_values = $qr_res->getAllFieldValues('value_longtext1'); $qr_res->seek(0); $t_list_item = new ca_list_items(); $va_list_item_cache = $t_list_item->getFieldValuesForIDs($va_values, array('idno', 'item_value', 'parent_id', 'access')); $va_list_child_count_cache = array(); if (is_array($va_list_item_cache)) { foreach ($va_list_item_cache as $vn_id => $va_item) { if (!($vn_parent_id = $va_item['parent_id'])) { continue; } if (is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && !in_array($va_item['access'], $pa_options['checkAccess'])) { continue; } $va_list_child_count_cache[$vn_parent_id]++; } } $va_list_label_cache = $t_list_item->getPreferredDisplayLabelsForIDs($va_values); // Translate value idnos to ids if (is_array($va_suppress_values)) { $va_suppress_values = ca_lists::getItemIDsFromList($t_element->get('list_id'), $va_suppress_values); } $va_facet_list = array(); foreach ($va_values as $vn_val) { if (!$vn_val) { continue; } if (is_array($va_suppress_values) && in_array($vn_val, $va_suppress_values)) { continue; } if (is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && !in_array($va_item['access'], $pa_options['checkAccess'])) { continue; } if ($va_criteria[$vn_val]) { continue; } // skip items that are used as browse critera - don't want to browse on something you're already browsing on $vn_child_count = isset($va_list_child_count_cache[$vn_val]) ? $va_list_child_count_cache[$vn_val] : 0; $va_facet_list[$vn_val] = array('id' => $vn_val, 'label' => html_entity_decode($va_list_label_cache[$vn_val]), 'parent_id' => isset($va_list_item_cache[$vn_val]['parent_id']) ? $va_list_item_cache[$vn_val]['parent_id'] : null, 'child_count' => $vn_child_count); } // preserve order of list $va_values_sorted_by_list_order = array(); if (is_array($va_list_item_cache)) { foreach ($va_list_item_cache as $vn_item_id => $va_item) { if (isset($va_facet_list[$vn_item_id])) { $va_values_sorted_by_list_order[$vn_item_id] = $va_facet_list[$vn_item_id]; } } } return caSortArrayByKeyInValue($va_values_sorted_by_list_order, array('label')); break; case __CA_ATTRIBUTE_VALUE_OBJECTS__: case __CA_ATTRIBUTE_VALUE_ENTITIES__: case __CA_ATTRIBUTE_VALUE_PLACES__: case __CA_ATTRIBUTE_VALUE_OCCURRENCES__: case __CA_ATTRIBUTE_VALUE_COLLECTIONS__: case __CA_ATTRIBUTE_VALUE_LOANS__: case __CA_ATTRIBUTE_VALUE_MOVEMENTS__: case __CA_ATTRIBUTE_VALUE_STORAGELOCATIONS__: case __CA_ATTRIBUTE_VALUE_OBJECTLOTS__: if ($t_rel_item = AuthorityAttributeValue::elementTypeToInstance($vn_element_type)) { $va_ids = $qr_res->getAllFieldValues('value_integer1'); $va_auth_items = $t_rel_item->getPreferredDisplayLabelsForIDs($va_ids); $qr_res->seek(0); } break; default: if (isset($va_facet_info['suppress']) && is_array($va_facet_info['suppress'])) { $va_suppress_values = $va_facet_info['suppress']; } break; } while ($qr_res->nextRow()) { $o_attr = Attribute::getValueInstance($vn_element_type, $qr_res->getRow(), true); if (!($vs_val = trim($o_attr->getDisplayValue()))) { continue; } if (is_array($va_suppress_values) && in_array($vs_val, $va_suppress_values)) { continue; } if ($va_criteria[$vs_val]) { continue; } // skip items that are used as browse critera - don't want to browse on something you're already browsing on switch ($vn_element_type) { case __CA_ATTRIBUTE_VALUE_LIST__: $vn_child_count = 0; if ($va_list_parent_ids[$vs_val]) { $vn_child_count++; } $va_values[$vs_val] = array('id' => str_replace('/', '/', $vs_val), 'label' => html_entity_decode($va_list_items[$vs_val]['name_plural'] ? $va_list_items[$vs_val]['name_plural'] : $va_list_items[$vs_val]['item_value']), 'parent_id' => $va_list_items[$vs_val]['parent_id'], 'child_count' => $vn_child_count); break; case __CA_ATTRIBUTE_VALUE_OBJECTS__: case __CA_ATTRIBUTE_VALUE_ENTITIES__: case __CA_ATTRIBUTE_VALUE_PLACES__: case __CA_ATTRIBUTE_VALUE_OCCURRENCES__: case __CA_ATTRIBUTE_VALUE_COLLECTIONS__: case __CA_ATTRIBUTE_VALUE_LOANS__: case __CA_ATTRIBUTE_VALUE_MOVEMENTS__: case __CA_ATTRIBUTE_VALUE_STORAGELOCATIONS__: case __CA_ATTRIBUTE_VALUE_OBJECTLOTS__: $va_values[$vs_val] = array('id' => $vn_id, 'label' => html_entity_decode($va_auth_items[$vn_id] ? $va_auth_items[$vn_id] : $vs_val)); break; case __CA_ATTRIBUTE_VALUE_CURRENCY__: $va_values[sprintf("%014.2f", preg_replace("![\\D]+!", "", $vs_val))] = array('id' => str_replace('/', '/', $vs_val), 'label' => $vs_val); break; default: $va_values[$vs_val] = array('id' => str_replace('/', '/', $vs_val), 'label' => $vs_val); break; } if (!is_null($vs_single_value) && $vs_val == $vs_single_value) { $vb_single_value_is_present = true; } } if (!is_null($vs_single_value) && !$vb_single_value_is_present) { return array(); } ksort($va_values); return $va_values; } break; # ----------------------------------------------------- # ----------------------------------------------------- case 'location': $t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true); $vs_sort_field = null; if ($t_item->getProperty('ID_NUMBERING_ID_FIELD') == $vs_field_name) { $vs_sort_field = $t_item->getProperty('ID_NUMBERING_SORT_FIELD'); } $va_joins = array(); $va_wheres = array(); $vs_where_sql = ''; $va_wheres[] = "({$vs_browse_table_name}.current_loc_class IS NOT NULL)"; if (sizeof($va_results) && $this->numCriteria() > 0) { $va_wheres[] = "(" . $t_subject->tableName() . '.' . $t_subject->primaryKey() . " IN (" . join(',', $va_results) . "))"; } if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_item->hasField('access')) { $va_wheres[] = "(" . $vs_browse_table_name . ".access IN (" . join(',', $pa_options['checkAccess']) . "))"; } if ($vs_browse_type_limit_sql) { $va_wheres[] = $vs_browse_type_limit_sql; } if ($t_item->hasField('deleted')) { $va_wheres[] = "(" . $vs_browse_table_name . ".deleted = 0)"; } if ($this->opo_config->get('perform_item_level_access_checking')) { if ($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true)) { // Join to limit what browse table items are used to generate facet $va_joins[] = 'LEFT JOIN ca_acl ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_acl.row_id AND ca_acl.table_num = ' . $t_item->tableNum() . "\n"; $va_wheres[] = "(\n\t\t\t\t\t\t\t\t((\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id = " . (int) $vn_user_id . ")\n\t\t\t\t\t\t\t\t\t" . (sizeof($va_group_ids) > 0 ? "OR\n\t\t\t\t\t\t\t\t\t(ca_acl.group_id IN (" . join(",", $va_group_ids) . "))" : "") . "\n\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id IS NULL and ca_acl.group_id IS NULL)\n\t\t\t\t\t\t\t\t) AND ca_acl.access >= " . __CA_ACL_READONLY_ACCESS__ . ")\n\t\t\t\t\t\t\t\t" . ($vb_show_if_no_acl ? "OR ca_acl.acl_id IS NULL" : "") . "\n\t\t\t\t\t\t\t)"; } } $vs_join_sql = join("\n", $va_joins); if (is_array($va_wheres) && sizeof($va_wheres) && ($vs_where_sql = join(' AND ', $va_wheres))) { $vs_where_sql = '(' . $vs_where_sql . ')'; } if ($vb_check_availability_only) { if (sizeof($va_criteria) > 0) { return false; } // only one current location criteria allowed $vs_sql = "\n\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\tFROM {$vs_browse_table_name}\n\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\tLIMIT 2"; $qr_res = $this->opo_db->query($vs_sql); if ($qr_res->nextRow()) { return (int) $qr_res->numRows() > 0 ? true : false; } return false; } else { if (sizeof($va_criteria) > 0) { return array(); } // only one current location criteria allowed $vs_pk = $t_item->primaryKey(); $vs_sql = "\n\t\t\t\t\t\t\tSELECT DISTINCT {$vs_browse_table_name}.current_loc_class, {$vs_browse_table_name}.current_loc_subclass, {$vs_browse_table_name}.current_loc_id\n\t\t\t\t\t\t\tFROM {$vs_browse_table_name}\n\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t{$vs_where_sql}"; if ($vs_sort_field) { $vs_sql .= " ORDER BY {$vs_sort_field}"; } $qr_res = $this->opo_db->query($vs_sql); $va_collapse_map = $this->getCollapseMapForLocationFacet($va_facet_info); $va_values = $va_values_by_table = array(); while ($qr_res->nextRow()) { if (!($vs_loc_class = trim($qr_res->get('current_loc_class')))) { continue; } if (!($vs_loc_subclass = trim($qr_res->get('current_loc_subclass')))) { continue; } if (!($vs_loc_id = trim($qr_res->get('current_loc_id')))) { continue; } $vs_val = "{$vs_loc_class}:{$vs_loc_subclass}:{$vs_loc_id}"; if ($va_criteria[$vs_val]) { continue; } // skip items that are used as browse critera - don't want to browse on something you're already browsing on $va_values_by_table[$vs_loc_class][$vs_loc_subclass][$vs_loc_id] = true; } foreach ($va_values_by_table as $vs_loc_class => $va_loc_id_by_subclass) { foreach ($va_loc_id_by_subclass as $vs_loc_subclass => $va_loc_ids) { if (sizeof($va_tmp = array_keys($va_loc_ids))) { $vs_loc_table_name = $this->opo_datamodel->getTableName($vs_loc_class); if (($vs_table_name = $vs_loc_table_name) == 'ca_objects_x_storage_locations') { $vs_table_name = 'ca_storage_locations'; } $qr_res = caMakeSearchResult($vs_table_name, $va_tmp); if (isset($va_collapse_map[$vs_table_name]) && isset($va_collapse_map[$vs_table_name]['*']) && $va_collapse_map[$vs_table_name]['*']) { $va_values[$vs_id = "{$vs_loc_class}"] = array('id' => $vs_id, 'label' => $va_collapse_map[$vs_table_name]['*']); continue; } while ($qr_res->nextHit()) { $vn_id = $qr_res->getPrimaryKey(); $va_config = ca_objects::getConfigurationForCurrentLocationType($vs_table_name, $vs_loc_subclass, array('facet' => isset($va_facet_info['display']) ? $va_facet_info['display'] : null)); $vs_template = isset($va_config['template']) ? $va_config['template'] : "^{$vs_table_name}.preferred_labels"; if (isset($va_collapse_map[$vs_table_name]) && isset($va_collapse_map[$vs_table_name][$vs_loc_subclass]) && $va_collapse_map[$vs_table_name][$vs_loc_subclass]) { $va_values[$vs_id = "{$vs_loc_class}:{$vs_loc_subclass}"] = array('id' => $vs_id, 'label' => $va_collapse_map[$vs_table_name][$vs_loc_subclass]); continue; } $va_values[$vs_id = "{$vs_loc_class}:{$vs_loc_subclass}:{$vn_id}"] = array('id' => $vs_id, 'label' => $qr_res->getWithTemplate($vs_template)); } } } } if (!is_null($vs_single_value) && !$vb_single_value_is_present) { return array(); } return caSortArrayByKeyInValue($va_values, array('label')); } return array(); break; # ----------------------------------------------------- # ----------------------------------------------------- case 'fieldList': $t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true); $vs_field_name = $va_facet_info['field']; $va_field_info = $t_item->getFieldInfo($vs_field_name); $t_list = new ca_lists(); $t_list_item = new ca_list_items(); $va_joins = array(); $va_wheres = array(); $vs_where_sql = ''; if (isset($va_field_info['LIST_CODE']) && ($vs_list_name = $va_field_info['LIST_CODE'])) { // Handle fields containing ca_list_item.item_id's $va_joins = array('INNER JOIN ' . $vs_browse_table_name . ' ON ' . $vs_browse_table_name . '.' . $vs_field_name . ' = li.item_id', 'INNER JOIN ca_lists ON ca_lists.list_id = li.list_id'); if (sizeof($va_results) && $this->numCriteria() > 0) { $va_wheres[] = "(" . $t_subject->tableName() . '.' . $t_subject->primaryKey() . " IN (" . join(',', $va_results) . "))"; } if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_item->hasField('access')) { $va_wheres[] = "(" . $vs_browse_table_name . ".access IN (" . join(',', $pa_options['checkAccess']) . "))"; $va_wheres[] = "(li.access IN (" . join(',', $pa_options['checkAccess']) . "))"; } if ($vs_browse_type_limit_sql) { $va_wheres[] = $vs_browse_type_limit_sql; } if ($t_subject->hasField('deleted')) { $va_wheres[] = "(" . $t_subject->tableName() . ".deleted = 0)"; } if ($va_facet_info['relative_to']) { if ($va_relative_sql_data = $this->_getRelativeFacetSQLData($va_facet_info['relative_to'], $pa_options)) { $va_joins = array_merge($va_joins, $va_relative_sql_data['joins']); $va_wheres = array_merge($va_wheres, $va_relative_sql_data['wheres']); } } if (is_array($va_criteria) && sizeof($va_criteria)) { $va_wheres[] = "(li.item_id NOT IN (" . join(",", array_keys($va_criteria)) . "))"; } if ($this->opo_config->get('perform_item_level_access_checking')) { if ($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true)) { // Join to limit what browse table items are used to generate facet $va_joins[] = 'LEFT JOIN ca_acl ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_acl.row_id AND ca_acl.table_num = ' . $t_item->tableNum() . "\n"; $va_wheres[] = "(\n\t\t\t\t\t\t\t\t\t((\n\t\t\t\t\t\t\t\t\t\t(ca_acl.user_id = " . (int) $vn_user_id . ")\n\t\t\t\t\t\t\t\t\t\t" . (sizeof($va_group_ids) > 0 ? "OR\n\t\t\t\t\t\t\t\t\t\t(ca_acl.group_id IN (" . join(",", $va_group_ids) . "))" : "") . "\n\t\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t\t(ca_acl.user_id IS NULL and ca_acl.group_id IS NULL)\n\t\t\t\t\t\t\t\t\t) AND ca_acl.access >= " . __CA_ACL_READONLY_ACCESS__ . ")\n\t\t\t\t\t\t\t\t\t" . ($vb_show_if_no_acl ? "OR ca_acl.acl_id IS NULL" : "") . "\n\t\t\t\t\t\t\t\t)"; } } $vs_join_sql = join("\n", $va_joins); if (is_array($va_wheres) && sizeof($va_wheres) && ($vs_where_sql = join(' AND ', $va_wheres))) { $vs_where_sql = ' AND (' . $vs_where_sql . ')'; } if ($vb_check_availability_only) { $vs_sql = "\n\t\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\t\tFROM ca_list_items li\n\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\tca_lists.list_code = ? {$vs_where_sql}\n\t\t\t\t\t\t\t\tLIMIT 2"; $qr_res = $this->opo_db->query($vs_sql, $vs_list_name); return (int) $qr_res->numRows() > 1 ? true : false; } else { // Get label ordering fields $va_ordering_fields_to_fetch = isset($va_facet_info['order_by_label_fields']) && is_array($va_facet_info['order_by_label_fields']) ? $va_facet_info['order_by_label_fields'] : array(); $va_orderbys = array(); $t_rel_item_label = new ca_list_item_labels(); foreach ($va_ordering_fields_to_fetch as $vs_sort_by_field) { if (!$t_rel_item_label->hasField($vs_sort_by_field)) { continue; } $va_orderbys[] = $va_label_selects[] = 'lil.' . $vs_sort_by_field; } $vs_order_by = sizeof($va_orderbys) ? "ORDER BY " . join(', ', $va_orderbys) : ''; $vs_sql = "\n\t\t\t\t\t\t\t\tSELECT DISTINCT lil.item_id, lil.name_singular, lil.name_plural, lil.locale_id\n\t\t\t\t\t\t\t\tFROM ca_list_items li\n\t\t\t\t\t\t\t\tINNER JOIN ca_list_item_labels AS lil ON lil.item_id = li.item_id\n\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\tca_lists.list_code = ? AND lil.is_preferred = 1 {$vs_where_sql} {$vs_order_by}"; //print $vs_sql." [$vs_list_name]"; $qr_res = $this->opo_db->query($vs_sql, $vs_list_name); $va_values = array(); while ($qr_res->nextRow()) { $vn_id = $qr_res->get('item_id'); if ($va_criteria[$vn_id]) { continue; } // skip items that are used as browse critera - don't want to browse on something you're already browsing on $va_values[$vn_id][$qr_res->get('locale_id')] = array('id' => $vn_id, 'label' => $qr_res->get('name_plural')); if (!is_null($vs_single_value) && $vn_id == $vs_single_value) { $vb_single_value_is_present = true; } } if (!is_null($vs_single_value) && !$vb_single_value_is_present) { return array(); } return caExtractValuesByUserLocale($va_values); } } else { if ($vs_list_name = $va_field_info['LIST']) { $va_list_items_by_value = array(); // fields with values set according to ca_list_items (not a foreign key ref) if ($va_list_items = caExtractValuesByUserLocale($t_list->getItemsForList($vs_list_name))) { foreach ($va_list_items as $vn_id => $va_list_item) { $va_list_items_by_value[$va_list_item['item_value']] = $va_list_item['name_plural']; } } else { foreach ($va_field_info['BOUNDS_CHOICE_LIST'] as $vs_val => $vn_id) { $va_list_items_by_value[$vn_id] = $vs_val; } } if (sizeof($va_results) && $this->numCriteria() > 0) { $va_wheres[] = "(" . $t_subject->tableName() . '.' . $t_subject->primaryKey() . " IN (" . join(',', $va_results) . "))"; } if ($vs_browse_type_limit_sql) { $va_wheres[] = $vs_browse_type_limit_sql; } if ($t_subject->hasField('deleted')) { $va_wheres[] = "(" . $t_subject->tableName() . ".deleted = 0)"; } if ($va_facet_info['relative_to']) { if ($va_relative_sql_data = $this->_getRelativeFacetSQLData($va_facet_info['relative_to'], $pa_options)) { $va_joins = array_merge($va_joins, $va_relative_sql_data['joins']); $va_wheres = array_merge($va_wheres, $va_relative_sql_data['wheres']); } } if ($this->opo_config->get('perform_item_level_access_checking')) { if ($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true)) { // Join to limit what browse table items are used to generate facet $va_joins[] = 'LEFT JOIN ca_acl ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_acl.row_id AND ca_acl.table_num = ' . $t_item->tableNum() . "\n"; $va_wheres[] = "(\n\t\t\t\t\t\t\t\t\t\t((\n\t\t\t\t\t\t\t\t\t\t\t(ca_acl.user_id = " . (int) $vn_user_id . ")\n\t\t\t\t\t\t\t\t\t\t\t" . (sizeof($va_group_ids) > 0 ? "OR\n\t\t\t\t\t\t\t\t\t\t\t(ca_acl.group_id IN (" . join(",", $va_group_ids) . "))" : "") . "\n\t\t\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t\t\t(ca_acl.user_id IS NULL and ca_acl.group_id IS NULL)\n\t\t\t\t\t\t\t\t\t\t) AND ca_acl.access >= " . __CA_ACL_READONLY_ACCESS__ . ")\n\t\t\t\t\t\t\t\t\t\t" . ($vb_show_if_no_acl ? "OR ca_acl.acl_id IS NULL" : "") . "\n\t\t\t\t\t\t\t\t\t)"; } } if (is_array($va_wheres) && sizeof($va_wheres) && ($vs_where_sql = join(' AND ', $va_wheres))) { $vs_where_sql = '(' . $vs_where_sql . ')'; } $vs_join_sql = join("\n", $va_joins); if ($vb_check_availability_only) { $vs_sql = "\n\t\t\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\t\t\tFROM " . $vs_browse_table_name . "\n\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\t" . ($vs_where_sql ? 'WHERE' : '') . "\n\t\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\t\t\tLIMIT 2"; $qr_res = $this->opo_db->query($vs_sql); return (int) $qr_res->numRows() > 1 ? true : false; } else { $vs_sql = "\n\t\t\t\t\t\t\t\t\tSELECT DISTINCT " . $vs_browse_table_name . '.' . $vs_field_name . "\n\t\t\t\t\t\t\t\t\tFROM " . $vs_browse_table_name . "\n\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\t" . ($vs_where_sql ? 'WHERE' : '') . "\n\t\t\t\t\t\t\t\t\t\t{$vs_where_sql}"; //print $vs_sql." [$vs_list_name]"; $qr_res = $this->opo_db->query($vs_sql); $va_values = array(); while ($qr_res->nextRow()) { $vn_id = $qr_res->get($vs_field_name); if ($va_criteria[$vn_id]) { continue; } // skip items that are used as browse critera - don't want to browse on something you're already browsing on if (isset($va_list_items_by_value[$vn_id])) { $va_values[$vn_id] = array('id' => $vn_id, 'label' => $va_list_items_by_value[$vn_id]); if (!is_null($vs_single_value) && $vn_id == $vs_single_value) { $vb_single_value_is_present = true; } } } if (!is_null($vs_single_value) && !$vb_single_value_is_present) { return array(); } return $va_values; } } else { if ($t_browse_table = $this->opo_datamodel->getInstanceByTableName($vs_facet_table = $va_facet_info['table'], true)) { // Handle fields containing ca_list_item.item_id's $va_joins = array('INNER JOIN ' . $vs_browse_table_name . ' ON ' . $vs_browse_table_name . '.' . $vs_field_name . ' = ' . $vs_facet_table . '.' . $t_browse_table->primaryKey()); $vs_display_field_name = null; if (method_exists($t_browse_table, 'getLabelTableInstance')) { $t_label_instance = $t_browse_table->getLabelTableInstance(); $vs_display_field_name = isset($va_facet_info['display']) && $va_facet_info['display'] ? $va_facet_info['display'] : $t_label_instance->getDisplayField(); $va_joins[] = 'INNER JOIN ' . $t_label_instance->tableName() . " AS lab ON lab." . $t_browse_table->primaryKey() . ' = ' . $t_browse_table->tableName() . '.' . $t_browse_table->primaryKey(); } if (sizeof($va_results) && $this->numCriteria() > 0) { $va_wheres[] = "(" . $t_subject->tableName() . '.' . $t_subject->primaryKey() . " IN (" . join(',', $va_results) . "))"; } if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_item->hasField('access')) { $va_wheres[] = "(" . $vs_browse_table_name . ".access IN (" . join(',', $pa_options['checkAccess']) . "))"; } if ($vs_browse_type_limit_sql) { $va_wheres[] = $vs_browse_type_limit_sql; } if ($va_facet_info['relative_to']) { if ($t_subject->hasField('deleted')) { $va_wheres[] = "(" . $t_subject->tableName() . ".deleted = 0)"; } if ($va_relative_sql_data = $this->_getRelativeFacetSQLData($va_facet_info['relative_to'], $pa_options)) { $va_joins = array_merge($va_joins, $va_relative_sql_data['joins']); $va_wheres = array_merge($va_wheres, $va_relative_sql_data['wheres']); } } if ($this->opo_config->get('perform_item_level_access_checking')) { if ($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true)) { // Join to limit what browse table items are used to generate facet $va_joins[] = 'LEFT JOIN ca_acl ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_acl.row_id AND ca_acl.table_num = ' . $t_item->tableNum() . "\n"; $va_wheres[] = "(\n\t\t\t\t\t\t\t\t\t\t\t((\n\t\t\t\t\t\t\t\t\t\t\t\t(ca_acl.user_id = " . (int) $vn_user_id . ")\n\t\t\t\t\t\t\t\t\t\t\t\t" . (sizeof($va_group_ids) > 0 ? "OR\n\t\t\t\t\t\t\t\t\t\t\t\t(ca_acl.group_id IN (" . join(",", $va_group_ids) . "))" : "") . "\n\t\t\t\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t\t\t\t(ca_acl.user_id IS NULL and ca_acl.group_id IS NULL)\n\t\t\t\t\t\t\t\t\t\t\t) AND ca_acl.access >= " . __CA_ACL_READONLY_ACCESS__ . ")\n\t\t\t\t\t\t\t\t\t\t\t" . ($vb_show_if_no_acl ? "OR ca_acl.acl_id IS NULL" : "") . "\n\t\t\t\t\t\t\t\t\t\t)"; } } $vs_join_sql = join("\n", $va_joins); if (is_array($va_wheres) && sizeof($va_wheres) && ($vs_where_sql = join(' AND ', $va_wheres))) { $vs_where_sql = 'WHERE (' . $vs_where_sql . ')'; } if ($vb_check_availability_only) { $vs_sql = "\n\t\t\t\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\t\t\t\tFROM {$vs_facet_table}\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\t\t\t\tLIMIT 1"; $qr_res = $this->opo_db->query($vs_sql); return (int) $qr_res->numRows() > 0 ? true : false; } else { $vs_sql = "\n\t\t\t\t\t\t\t\t\t\tSELECT DISTINCT *\n\t\t\t\t\t\t\t\t\t\tFROM {$vs_facet_table}\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\t\t{$vs_where_sql}"; //print $vs_sql; $qr_res = $this->opo_db->query($vs_sql); $va_values = array(); $vs_pk = $t_browse_table->primaryKey(); while ($qr_res->nextRow()) { $vn_id = $qr_res->get($vs_pk); if ($va_criteria[$vn_id]) { continue; } // skip items that are used as browse critera - don't want to browse on something you're already browsing on $va_values[$vn_id][$qr_res->get('locale_id')] = array('id' => $vn_id, 'label' => $qr_res->get($vs_display_field_name)); if (!is_null($vs_single_value) && $vn_id == $vs_single_value) { $vb_single_value_is_present = true; } } if (!is_null($vs_single_value) && !$vb_single_value_is_present) { return array(); } return caExtractValuesByUserLocale($va_values); } } } } return array(); break; # ----------------------------------------------------- # ----------------------------------------------------- case 'field': $t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true); if (!is_array($va_restrict_to_types = $va_facet_info['restrict_to_types'])) { $va_restrict_to_types = array(); } if (!is_array($va_restrict_to_types = $this->_convertTypeCodesToIDs($va_restrict_to_types, array('instance' => $t_item, 'dontExpandHierarchically' => true)))) { $va_restrict_to_types = array(); } $va_restrict_to_types_expanded = $this->_convertTypeCodesToIDs($va_restrict_to_types, array('instance' => $t_item)); $vs_field_name = $va_facet_info['field']; $va_field_info = $t_item->getFieldInfo($vs_field_name); $vs_sort_field = null; if ($t_item->getProperty('ID_NUMBERING_ID_FIELD') == $vs_field_name) { $vs_sort_field = $vs_browse_table_name . '.' . $t_item->getProperty('ID_NUMBERING_SORT_FIELD'); } $t_list = new ca_lists(); $t_list_item = new ca_list_items(); $va_joins = array(); $va_wheres = array(); $vs_where_sql = ''; $va_facet_values = null; if ($vb_is_bit = $va_field_info['FIELD_TYPE'] == FT_BIT) { $vs_yes_text = caGetOption('label_yes', $va_facet_info, _t('Yes')); $vs_no_text = caGetOption('label_no', $va_facet_info, _t('No')); $va_facet_values = array(1 => array('id' => 1, 'label' => $vs_yes_text), 0 => array('id' => 0, 'label' => $vs_no_text)); } if (is_array($va_restrict_to_types) && sizeof($va_restrict_to_types) > 0 && method_exists($t_rel_item, "getTypeList")) { $va_wheres[] = "{$va_restrict_to_types_expanded}.type_id IN (" . join(',', caGetOption('dont_include_subtypes', $va_facet_info, false) ? $va_restrict_to_types : $va_restrict_to_types_expanded) . ")"; $va_selects[] = "{$va_restrict_to_types_expanded}.type_id"; } if (sizeof($va_results) && $this->numCriteria() > 0) { $va_wheres[] = "(" . $t_subject->tableName() . '.' . $t_subject->primaryKey() . " IN (" . join(',', $va_results) . "))"; } if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_item->hasField('access')) { $va_wheres[] = "(" . $vs_browse_table_name . ".access IN (" . join(',', $pa_options['checkAccess']) . "))"; } if ($vs_browse_type_limit_sql) { $va_wheres[] = $vs_browse_type_limit_sql; } if ($t_item->hasField('deleted')) { $va_wheres[] = "(" . $vs_browse_table_name . ".deleted = 0)"; } if ($va_facet_info['relative_to']) { if ($t_subject->hasField('deleted')) { $va_wheres[] = "(" . $t_subject->tableName() . ".deleted = 0)"; } if ($va_relative_sql_data = $this->_getRelativeFacetSQLData($va_facet_info['relative_to'], $pa_options)) { $va_joins = array_merge($va_joins, $va_relative_sql_data['joins']); $va_wheres = array_merge($va_wheres, $va_relative_sql_data['wheres']); } } if ($this->opo_config->get('perform_item_level_access_checking')) { if ($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true)) { // Join to limit what browse table items are used to generate facet $va_joins[] = 'LEFT JOIN ca_acl ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_acl.row_id AND ca_acl.table_num = ' . $t_item->tableNum() . "\n"; $va_wheres[] = "(\n\t\t\t\t\t\t\t\t((\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id = " . (int) $vn_user_id . ")\n\t\t\t\t\t\t\t\t\t" . (sizeof($va_group_ids) > 0 ? "OR\n\t\t\t\t\t\t\t\t\t(ca_acl.group_id IN (" . join(",", $va_group_ids) . "))" : "") . "\n\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id IS NULL and ca_acl.group_id IS NULL)\n\t\t\t\t\t\t\t\t) AND ca_acl.access >= " . __CA_ACL_READONLY_ACCESS__ . ")\n\t\t\t\t\t\t\t\t" . ($vb_show_if_no_acl ? "OR ca_acl.acl_id IS NULL" : "") . "\n\t\t\t\t\t\t\t)"; } } $vs_join_sql = join("\n", $va_joins); if (is_array($va_wheres) && sizeof($va_wheres) && ($vs_where_sql = join(' AND ', $va_wheres))) { $vs_where_sql = '(' . $vs_where_sql . ')'; } if ($vb_check_availability_only) { $vs_sql = "\n\t\t\t\t\t\t\tSELECT DISTINCT {$vs_browse_table_name}.{$vs_field_name}\n\t\t\t\t\t\t\tFROM {$vs_browse_table_name}\n\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\tLIMIT 2"; $qr_res = $this->opo_db->query($vs_sql); if ($qr_res->numRows() > 1) { return true; } return false; } else { $vs_pk = $t_item->primaryKey(); $vs_sql = "\n\t\t\t\t\t\t\tSELECT DISTINCT {$vs_browse_table_name}.{$vs_field_name}\n\t\t\t\t\t\t\tFROM {$vs_browse_table_name}\n\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t{$vs_where_sql}"; if ($vs_sort_field) { $vs_sql .= " ORDER BY {$vs_sort_field}"; } $qr_res = $this->opo_db->query($vs_sql); $va_values = array(); while ($qr_res->nextRow()) { if (!($vs_val = trim($qr_res->get($vs_field_name))) && !$vb_is_bit) { continue; } if ($va_criteria[$vs_val]) { continue; } // skip items that are used as browse critera - don't want to browse on something you're already browsing on if ($vb_is_bit && isset($va_facet_values[$vs_val])) { $va_values[$vs_val] = $va_facet_values[$vs_val]; } else { $va_values[$vs_val] = array('id' => str_replace('/', '/', $vs_val), 'label' => $vs_val); } if (!is_null($vs_single_value) && $vs_val == $vs_single_value) { $vb_single_value_is_present = true; } } if (!is_null($vs_single_value) && !$vb_single_value_is_present) { return array(); } return $va_values; } return array(); break; # ----------------------------------------------------- # ----------------------------------------------------- case 'violations': $t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true); $vs_field_name = $va_facet_info['field']; $va_field_info = $t_item->getFieldInfo($vs_field_name); $va_joins = array(); $va_wheres = array(); $vs_where_sql = ''; $va_facet_values = null; if (sizeof($va_results) && $this->numCriteria() > 0) { $va_wheres[] = "(" . $t_subject->tableName() . '.' . $t_subject->primaryKey() . " IN (" . join(',', $va_results) . "))"; } if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_item->hasField('access')) { $va_wheres[] = "(" . $vs_browse_table_name . ".access IN (" . join(',', $pa_options['checkAccess']) . "))"; } if ($vs_browse_type_limit_sql) { $va_wheres[] = $vs_browse_type_limit_sql; } if ($t_item->hasField('deleted')) { $va_wheres[] = "(" . $vs_browse_table_name . ".deleted = 0)"; } if ($va_facet_info['relative_to']) { if ($t_subject->hasField('deleted')) { $va_wheres[] = "(" . $t_subject->tableName() . ".deleted = 0)"; } if ($va_relative_sql_data = $this->_getRelativeFacetSQLData($va_facet_info['relative_to'], $pa_options)) { $va_joins = array_merge($va_joins, $va_relative_sql_data['joins']); $va_wheres = array_merge($va_wheres, $va_relative_sql_data['wheres']); } } if ($this->opo_config->get('perform_item_level_access_checking')) { if ($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true)) { // Join to limit what browse table items are used to generate facet $va_joins[] = 'LEFT JOIN ca_acl ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_acl.row_id AND ca_acl.table_num = ' . $t_item->tableNum() . "\n"; $va_wheres[] = "(\n\t\t\t\t\t\t\t\t((\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id = " . (int) $vn_user_id . ")\n\t\t\t\t\t\t\t\t\t" . (sizeof($va_group_ids) > 0 ? "OR\n\t\t\t\t\t\t\t\t\t(ca_acl.group_id IN (" . join(",", $va_group_ids) . "))" : "") . "\n\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id IS NULL and ca_acl.group_id IS NULL)\n\t\t\t\t\t\t\t\t) AND ca_acl.access >= " . __CA_ACL_READONLY_ACCESS__ . ")\n\t\t\t\t\t\t\t\t" . ($vb_show_if_no_acl ? "OR ca_acl.acl_id IS NULL" : "") . "\n\t\t\t\t\t\t\t)"; } } $vs_join_sql = join("\n", $va_joins); if (is_array($va_wheres) && sizeof($va_wheres) && ($vs_where_sql = join(' AND ', $va_wheres))) { $vs_where_sql = '(' . $vs_where_sql . ')'; } if ($vb_check_availability_only) { $vs_sql = "\n\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\tFROM {$vs_browse_table_name}\n\t\t\t\t\t\t\tINNER JOIN ca_metadata_dictionary_rule_violations ON ca_metadata_dictionary_rule_violations.row_id = {$vs_browse_table_name}." . $t_item->primaryKey() . " AND ca_metadata_dictionary_rule_violations.table_num = {$vs_browse_table_num}\n\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\tLIMIT 2"; $qr_res = $this->opo_db->query($vs_sql); if ($qr_res->nextRow()) { return (int) $qr_res->numRows() > 0 ? true : false; } return false; } else { $vs_pk = $t_item->primaryKey(); $vs_sql = "\n\t\t\t\t\t\t\tSELECT DISTINCT ca_metadata_dictionary_rules.rule_id\n\t\t\t\t\t\t\tFROM {$vs_browse_table_name}\n\t\t\t\t\t\t\tINNER JOIN ca_metadata_dictionary_rule_violations ON ca_metadata_dictionary_rule_violations.row_id = {$vs_browse_table_name}." . $t_item->primaryKey() . " AND ca_metadata_dictionary_rule_violations.table_num = {$vs_browse_table_num}\n\t\t\t\t\t\t\tINNER JOIN ca_metadata_dictionary_rules ON ca_metadata_dictionary_rules.rule_id = ca_metadata_dictionary_rule_violations.rule_id\n\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t{$vs_where_sql}"; $qr_res = $this->opo_db->query($vs_sql); $va_values = array(); $t_rule = new ca_metadata_dictionary_rules(); while ($qr_res->nextRow()) { if ($t_rule->load($qr_res->get('rule_id'))) { if (!($vs_val = trim($t_rule->getSetting('label')))) { continue; } $vs_code = $t_rule->get('rule_code'); if ($va_criteria[$vs_val]) { continue; } // skip items that are used as browse critera - don't want to browse on something you're already browsing on if (isset($va_facet_values[$vs_code])) { $va_values[$vs_code] = $va_facet_values[$vs_code]; } else { $va_values[$vs_code] = array('id' => $vs_code, 'label' => $vs_val); } if (!is_null($vs_single_value) && $vs_code == $vs_single_value) { $vb_single_value_is_present = true; } } } if (!is_null($vs_single_value) && !$vb_single_value_is_present) { return array(); } return $va_values; } return array(); break; # ----------------------------------------------------- # ----------------------------------------------------- case 'checkouts': if ($vs_browse_table_name != 'ca_objects') { return array(); } $t_item = new ca_objects(); $va_joins = array(); $va_wheres = array(); $vs_where_sql = ''; $va_facet_values = null; if (sizeof($va_results) && $this->numCriteria() > 0) { $va_wheres[] = "(" . $t_subject->tableName() . '.' . $t_subject->primaryKey() . " IN (" . join(',', $va_results) . "))"; } if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_item->hasField('access')) { $va_wheres[] = "(" . $vs_browse_table_name . ".access IN (" . join(',', $pa_options['checkAccess']) . "))"; } if ($vs_browse_type_limit_sql) { $va_wheres[] = $vs_browse_type_limit_sql; } if ($t_item->hasField('deleted')) { $va_wheres[] = "(" . $vs_browse_table_name . ".deleted = 0)"; } if ($va_facet_info['relative_to']) { if ($t_subject->hasField('deleted')) { $va_wheres[] = "(" . $t_subject->tableName() . ".deleted = 0)"; } if ($va_relative_sql_data = $this->_getRelativeFacetSQLData($va_facet_info['relative_to'], $pa_options)) { $va_joins = array_merge($va_joins, $va_relative_sql_data['joins']); $va_wheres = array_merge($va_wheres, $va_relative_sql_data['wheres']); } } $vs_checkout_join_sql = "INNER JOIN ca_object_checkouts ON ca_object_checkouts.object_id = ca_objects.object_id"; $vn_current_time = time(); switch ($va_facet_info['status']) { case 'overdue': $va_wheres[] = "((ca_object_checkouts.checkout_date <= {$vn_current_time}) AND (ca_object_checkouts.return_date IS NULL) AND (ca_object_checkouts.due_date <= {$vn_current_time}))"; break; case 'reserved': $va_wheres[] = "((ca_object_checkouts.checkout_date IS NULL) AND (ca_object_checkouts.return_date IS NULL))"; break; case 'available': $vs_checkout_join_sql = ''; $va_wheres[] = "(ca_objects.object_id NOT IN (SELECT object_id FROM ca_object_checkouts WHERE (ca_object_checkouts.checkout_date <= {$vn_current_time}) AND (ca_object_checkouts.return_date IS NULL)))"; break; default: case 'out': $va_wheres[] = "((ca_object_checkouts.checkout_date <= {$vn_current_time}) AND (ca_object_checkouts.return_date IS NULL))"; break; } if ($vs_checkout_join_sql) { $va_joins[] = $vs_checkout_join_sql; $va_joins[] = "INNER JOIN ca_users ON ca_object_checkouts.user_id = ca_users.user_id"; } if ($this->opo_config->get('perform_item_level_access_checking')) { if ($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true)) { // Join to limit what browse table items are used to generate facet $va_joins[] = 'LEFT JOIN ca_acl ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_acl.row_id AND ca_acl.table_num = ' . $t_item->tableNum() . "\n"; $va_wheres[] = "(\n\t\t\t\t\t\t\t\t((\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id = " . (int) $vn_user_id . ")\n\t\t\t\t\t\t\t\t\t" . (sizeof($va_group_ids) > 0 ? "OR\n\t\t\t\t\t\t\t\t\t(ca_acl.group_id IN (" . join(",", $va_group_ids) . "))" : "") . "\n\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id IS NULL and ca_acl.group_id IS NULL)\n\t\t\t\t\t\t\t\t) AND ca_acl.access >= " . __CA_ACL_READONLY_ACCESS__ . ")\n\t\t\t\t\t\t\t\t" . ($vb_show_if_no_acl ? "OR ca_acl.acl_id IS NULL" : "") . "\n\t\t\t\t\t\t\t)"; } } $vs_join_sql = join("\n", $va_joins); if (is_array($va_wheres) && sizeof($va_wheres) && ($vs_where_sql = join(' AND ', $va_wheres))) { $vs_where_sql = '(' . $vs_where_sql . ')'; } if ($vb_check_availability_only) { switch ($va_facet_info['mode']) { case 'user': $vs_sql = "\n\t\t\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\t\t\tFROM ca_objects\n\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t{$vs_where_sql} AND ca_objects.deleted = 0\n\t\t\t\t\t\t\t\t\tLIMIT 2"; break; default: case 'all': $vs_sql = "\n\t\t\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\t\t\tFROM ca_objects\n\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\tca_objects.deleted = 0 " . (sizeof($va_results) ? "AND (" . $t_subject->tableName() . '.' . $t_subject->primaryKey() . " IN (" . join(',', $va_results) . "))" : "") . "\n\t\t\t\t\t\t\t\t\tLIMIT 2"; break; } $qr_res = $this->opo_db->query($vs_sql); if ($qr_res->nextRow()) { return (int) $qr_res->numRows() > 0 ? true : false; } return false; } else { $va_values = array(); $vs_pk = $t_item->primaryKey(); switch ($va_facet_info['mode']) { case 'user': $vs_sql = "\n\t\t\t\t\t\t\t\t\tSELECT DISTINCT ca_object_checkouts.user_id, ca_users.fname, ca_users.lname, ca_users.email\n\t\t\t\t\t\t\t\t\tFROM ca_objects\n\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t{$vs_where_sql} " . (sizeof($va_results) ? " AND (" . $t_subject->tableName() . '.' . $t_subject->primaryKey() . " IN (" . join(',', $va_results) . "))" : ""); $qr_res = $this->opo_db->query($vs_sql); while ($qr_res->nextRow()) { $vn_user_id = $qr_res->get('user_id'); $vs_val = $qr_res->get('fname') . ' ' . $qr_res->get('lname') . (($vs_email = $qr_res->get('email')) ? "({$vs_email})" : ''); if ($va_criteria[$vs_val]) { continue; } // skip items that are used as browse critera - don't want to browse on something you're already browsing on if (isset($va_facet_values[$vn_user_id])) { $va_values[$vn_user_id] = $va_facet_values[$vn_user_id]; } else { $va_values[$vn_user_id] = array('id' => $vn_user_id, 'label' => $vs_val); } if (!is_null($vs_single_value) && $vn_user_id == $vs_single_value) { $vb_single_value_is_present = true; } } break; case 'all': default: foreach (array(_t('Available') => 'available', _t('Out') => 'out', _t('Reserved') => 'reserved', _t('Overdue') => 'overdue') as $vs_status_text => $vs_status) { $vs_join_sql = "INNER JOIN ca_object_checkouts ON ca_object_checkouts.object_id = ca_objects.object_id"; switch ($vs_status) { case 'overdue': $vs_where = "((ca_object_checkouts.checkout_date <= {$vn_current_time}) AND (ca_object_checkouts.return_date IS NULL) AND (ca_object_checkouts.due_date <= {$vn_current_time}))"; break; case 'reserved': $vs_where = "((ca_object_checkouts.checkout_date IS NULL) AND (ca_object_checkouts.return_date IS NULL))"; break; case 'available': $vs_join_sql = ''; $vs_where = "(ca_objects.object_id NOT IN (SELECT object_id FROM ca_object_checkouts WHERE (ca_object_checkouts.checkout_date <= {$vn_current_time}) AND (ca_object_checkouts.return_date IS NULL)))"; break; default: case 'out': $vs_where = "((ca_object_checkouts.checkout_date <= {$vn_current_time}) AND (ca_object_checkouts.return_date IS NULL))"; break; } if (sizeof($va_results) && $this->numCriteria() > 0) { $vs_where .= " AND (" . $t_subject->tableName() . '.' . $t_subject->primaryKey() . " IN (" . join(',', $va_results) . "))"; } $vs_sql = "\n\t\t\t\t\t\t\t\t\t\tSELECT count(*) c\n\t\t\t\t\t\t\t\t\t\tFROM ca_objects\n\t\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t{$vs_where}\n\t\t\t\t\t\t\t\t\t"; $qr_res = $this->opo_db->query($vs_sql); $qr_res->nextRow(); if (!$qr_res->get('c')) { continue; } $va_values[$vs_status] = array('id' => $vs_status, 'label' => $vs_status_text); if (!is_null($vs_single_value) && $vs_status == $vs_single_value) { $vb_single_value_is_present = true; } } break; } if (!is_null($vs_single_value) && !$vb_single_value_is_present) { return array(); } return $va_values; } return array(); break; # ----------------------------------------------------- # ----------------------------------------------------- case 'normalizedDates': $t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true); $t_element = new ca_metadata_elements(); $vb_is_element = $vb_is_field = false; if (!($vb_is_element = $t_element->load(array('element_code' => $va_facet_info['element_code']))) && !($vb_is_field = $t_item->hasField($va_facet_info['element_code']) && $t_item->getFieldInfo($va_facet_info['element_code'], 'FIELD_TYPE') === FT_HISTORIC_DATERANGE)) { return array(); } if ($vb_is_element) { $va_joins = array('INNER JOIN ca_attribute_values ON ca_attributes.attribute_id = ca_attribute_values.attribute_id', 'INNER JOIN ' . $vs_browse_table_name . ' ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_attributes.row_id AND ca_attributes.table_num = ' . intval($vs_browse_table_num)); } else { $va_joins = array(); } $va_wheres = array(); $vs_normalization = $va_facet_info['normalization']; // how do we construct the date ranges presented to uses. In other words - how do we want to allow users to browse dates? By year, decade, century? if (sizeof($va_results) && $this->numCriteria() > 0) { $va_wheres[] = "(" . $t_subject->tableName() . '.' . $t_subject->primaryKey() . " IN (" . join(',', $va_results) . "))"; } if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_item->hasField('access')) { $va_wheres[] = "(" . $vs_browse_table_name . ".access IN (" . join(',', $pa_options['checkAccess']) . "))"; } if ($vs_browse_type_limit_sql) { $va_wheres[] = $vs_browse_type_limit_sql; } if ($t_item->hasField('deleted')) { $va_wheres[] = "(" . $vs_browse_table_name . ".deleted = 0)"; } if ($va_facet_info['relative_to']) { if ($t_subject->hasField('deleted')) { $va_wheres[] = "(" . $t_subject->tableName() . ".deleted = 0)"; } if ($va_relative_sql_data = $this->_getRelativeFacetSQLData($va_facet_info['relative_to'], $pa_options)) { $va_joins = array_merge($va_joins, $va_relative_sql_data['joins']); $va_wheres = array_merge($va_wheres, $va_relative_sql_data['wheres']); } } if ($this->opo_config->get('perform_item_level_access_checking')) { if ($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true)) { // Join to limit what browse table items are used to generate facet $va_joins[] = 'LEFT JOIN ca_acl ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_acl.row_id AND ca_acl.table_num = ' . $t_item->tableNum() . "\n"; $va_wheres[] = "(\n\t\t\t\t\t\t\t\t((\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id = " . (int) $vn_user_id . ")\n\t\t\t\t\t\t\t\t\t" . (sizeof($va_group_ids) > 0 ? "OR\n\t\t\t\t\t\t\t\t\t(ca_acl.group_id IN (" . join(",", $va_group_ids) . "))" : "") . "\n\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id IS NULL and ca_acl.group_id IS NULL)\n\t\t\t\t\t\t\t\t) AND ca_acl.access >= " . __CA_ACL_READONLY_ACCESS__ . ")\n\t\t\t\t\t\t\t\t" . ($vb_show_if_no_acl ? "OR ca_acl.acl_id IS NULL" : "") . "\n\t\t\t\t\t\t\t)"; } } $vs_where_sql = ''; if (is_array($va_wheres) && sizeof($va_wheres) && ($vs_where_sql = join(' AND ', $va_wheres))) { $vs_where_sql = ' AND (' . $vs_where_sql . ')'; } $vs_join_sql = join("\n", $va_joins); if ($vb_is_element) { $vn_element_id = $t_element->getPrimaryKey(); $vs_dir = strtoupper($va_facet_info['sort']) === 'DESC' ? "DESC" : "ASC"; $o_tep = new TimeExpressionParser(); $vn_min_date = $vn_max_date = null; $vs_min_sql = $vs_max_sql = ''; if (isset($va_facet_info['minimum_date'])) { if ($o_tep->parse($va_facet_info['minimum_date'])) { $va_tmp = $o_tep->getHistoricTimestamps(); $vn_min_date = (double) $va_tmp['start']; $vs_min_sql = " AND (ca_attribute_values.value_decimal1 >= {$vn_min_date})"; } } if (isset($va_facet_info['maximum_date'])) { if ($o_tep->parse($va_facet_info['maximum_date'])) { $va_tmp = $o_tep->getHistoricTimestamps(); $vn_max_date = (double) $va_tmp['end']; $vs_max_sql = " AND (ca_attribute_values.value_decimal2 <= {$vn_max_date})"; } } if ($vb_check_availability_only) { $vs_sql = "\n\t\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\t\tFROM ca_attributes\n\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\tca_attribute_values.element_id = ? \n\t\t\t\t\t\t\t\t\t{$vs_min_sql}\n\t\t\t\t\t\t\t\t\t{$vs_max_sql}\n\t\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\t\t\tLIMIT 1"; //print $vs_sql; $qr_res = $this->opo_db->query($vs_sql, $vn_element_id); return (int) $qr_res->numRows() > 0 ? true : false; } else { $vs_sql = "\n\t\t\t\t\t\t\t\tSELECT DISTINCT ca_attribute_values.value_decimal1, ca_attribute_values.value_decimal2\n\t\t\t\t\t\t\t\tFROM ca_attributes\n\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\tca_attribute_values.element_id = ? \n\t\t\t\t\t\t\t\t\t{$vs_min_sql}\n\t\t\t\t\t\t\t\t\t{$vs_max_sql}\n\t\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\t"; //print $vs_sql; $qr_res = $this->opo_db->query($vs_sql, $vn_element_id); $vn_current_year = (int) date("Y"); $va_values = array(); $vb_include_unknown = (bool) caGetOption('include_unknown', $va_facet_info, false); $vb_unknown_is_set = false; while ($qr_res->nextRow()) { $vn_start = $qr_res->get('value_decimal1'); $vn_end = $qr_res->get('value_decimal2'); if (!($vn_start && $vn_end)) { if ($vb_include_unknown) { $vb_unknown_is_set = true; } continue; } if ($vn_end > $vn_current_year + 50) { continue; } // bad years can make for large facets that cause timeouts so cut it off 50 years into the future $va_normalized_values = $o_tep->normalizeDateRange($vn_start, $vn_end, $vs_normalization); foreach ($va_normalized_values as $vn_sort_value => $vs_normalized_value) { if ($va_criteria[$vs_normalized_value]) { continue; } // skip items that are used as browse critera - don't want to browse on something you're already browsing on if (is_numeric($vs_normalized_value) && (int) $vs_normalized_value === 0) { continue; } // don't include year=0 $va_values[$vn_sort_value][$vs_normalized_value] = array('id' => $vs_normalized_value, 'label' => $vs_normalized_value); if (!is_null($vs_single_value) && $vs_normalized_value == $vs_single_value) { $vb_single_value_is_present = true; } } } if ($vb_include_unknown && !$vb_unknown_is_set) { // Check for rows where no data is set at all as opposed to null dates $vs_sql = "\n\t\t\t\t\t\t\t\t\tSELECT DISTINCT ca_attributes.row_id\n\t\t\t\t\t\t\t\t\tFROM ca_attributes\n\t\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\tca_attribute_values.element_id = ? \n\t\t\t\t\t\t\t\t\t\t{$vs_min_sql}\n\t\t\t\t\t\t\t\t\t\t{$vs_max_sql}\n\t\t\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\t\t"; //print $vs_sql; $qr_res = $this->opo_db->query($vs_sql, $vn_element_id); if ($qr_res->numRows() < sizeof($va_results)) { $vb_unknown_is_set = true; } } if ($vb_unknown_is_set && sizeof($va_values) > 0) { $va_values['999999999'][_t('Date unknown')] = array('id' => 'null', 'label' => _t('Date unknown')); } if (!is_null($vs_single_value) && !$vb_single_value_is_present) { return array(); } ksort($va_values); if ($vs_dir == 'DESC') { $va_values = array_reverse($va_values); } $va_sorted_values = array(); foreach ($va_values as $vn_sort_value => $va_values_for_sort_value) { $va_sorted_values = array_merge($va_sorted_values, $va_values_for_sort_value); } return $va_sorted_values; } } else { // is intrinsic $vs_dir = strtoupper($va_facet_info['sort']) === 'DESC' ? "DESC" : "ASC"; $vs_browse_start_fld = $t_item->getFieldInfo($va_facet_info['element_code'], 'START'); $vs_browse_end_fld = $t_item->getFieldInfo($va_facet_info['element_code'], 'END'); $o_tep = new TimeExpressionParser(); $vn_min_date = $vn_max_date = null; $vs_min_sql = $vs_max_sql = ''; if (isset($va_facet_info['minimum_date'])) { if ($o_tep->parse($va_facet_info['minimum_date'])) { $va_tmp = $o_tep->getHistoricTimestamps(); $vn_min_date = (double) $va_tmp['start']; $vs_min_sql = " AND ({$vs_browse_table_name}.{$vs_browse_start_fld} >= {$vn_min_date})"; } } if (isset($va_facet_info['maximum_date'])) { if ($o_tep->parse($va_facet_info['maximum_date'])) { $va_tmp = $o_tep->getHistoricTimestamps(); $vn_max_date = (double) $va_tmp['end']; $vs_max_sql = " AND ({$vs_browse_table_name}.{$vs_browse_end_fld} <= {$vn_max_date})"; } } if ($vb_check_availability_only) { $vs_sql = "\n\t\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\t\tFROM {$vs_browse_table_name}\n\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t1 = 1\n\t\t\t\t\t\t\t\t\t{$vs_min_sql}\n\t\t\t\t\t\t\t\t\t{$vs_max_sql}\n\t\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\t\t\tLIMIT 1"; //print $vs_sql; $qr_res = $this->opo_db->query($vs_sql); return (int) $qr_res->numRows() > 0 ? true : false; } else { $vs_sql = "\n\t\t\t\t\t\t\t\tSELECT DISTINCT {$vs_browse_table_name}.{$vs_browse_start_fld}, {$vs_browse_table_name}.{$vs_browse_end_fld}\n\t\t\t\t\t\t\t\tFROM {$vs_browse_table_name}\n\t\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t1 = 1\n\t\t\t\t\t\t\t\t\t{$vs_min_sql}\n\t\t\t\t\t\t\t\t\t{$vs_max_sql}\n\t\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\t"; //print $vs_sql; $qr_res = $this->opo_db->query($vs_sql); $va_values = array(); while ($qr_res->nextRow()) { $vn_start = $qr_res->get($vs_browse_start_fld); $vn_end = $qr_res->get($vs_browse_end_fld); if (!($vn_start && $vn_end)) { continue; } $va_normalized_values = $o_tep->normalizeDateRange($vn_start, $vn_end, $vs_normalization); foreach ($va_normalized_values as $vn_sort_value => $vs_normalized_value) { if ($va_criteria[$vs_normalized_value]) { continue; } // skip items that are used as browse critera - don't want to browse on something you're already browsing on if (is_numeric($vs_normalized_value) && (int) $vs_normalized_value === 0) { continue; } // don't include year=0 $va_values[$vn_sort_value][$vs_normalized_value] = array('id' => $vs_normalized_value, 'label' => $vs_normalized_value); if (!is_null($vs_single_value) && $vs_normalized_value == $vs_single_value) { $vb_single_value_is_present = true; } } } if (!is_null($vs_single_value) && !$vb_single_value_is_present) { return array(); } ksort($va_values); if ($vs_dir == 'DESC') { $va_values = array_reverse($va_values); } $va_sorted_values = array(); foreach ($va_values as $vn_sort_value => $va_values_for_sort_value) { $va_sorted_values = array_merge($va_sorted_values, $va_values_for_sort_value); } return $va_sorted_values; } } break; # ----------------------------------------------------- # ----------------------------------------------------- case 'normalizedLength': $t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true); $t_element = new ca_metadata_elements(); $vb_is_element = $vb_is_field = false; if (!($vb_is_element = $t_element->load(array('element_code' => $va_facet_info['element_code']))) && !($vb_is_field = $t_item->hasField($va_facet_info['element_code']) && $t_item->getFieldInfo($va_facet_info['element_code'], 'FIELD_TYPE') === FT_HISTORIC_DATERANGE)) { return array(); } if ($vb_is_element) { $va_joins = array('INNER JOIN ca_attribute_values ON ca_attributes.attribute_id = ca_attribute_values.attribute_id', 'INNER JOIN ' . $vs_browse_table_name . ' ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_attributes.row_id AND ca_attributes.table_num = ' . intval($vs_browse_table_num)); } else { $va_joins = array(); } $va_wheres = array(); $vs_normalization = $va_facet_info['normalization']; // how do we construct the dimensions ranges presented to users. In other words - what increments do we can to use to browse measurments? if (sizeof($va_results) && $this->numCriteria() > 0) { $va_wheres[] = "(" . $t_subject->tableName() . '.' . $t_subject->primaryKey() . " IN (" . join(',', $va_results) . "))"; } if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_item->hasField('access')) { $va_wheres[] = "(" . $vs_browse_table_name . ".access IN (" . join(',', $pa_options['checkAccess']) . "))"; } if ($vs_browse_type_limit_sql) { $va_wheres[] = $vs_browse_type_limit_sql; } if ($t_item->hasField('deleted')) { $va_wheres[] = "(" . $vs_browse_table_name . ".deleted = 0)"; } if ($va_facet_info['relative_to']) { if ($t_subject->hasField('deleted')) { $va_wheres[] = "(" . $t_subject->tableName() . ".deleted = 0)"; } if ($va_relative_sql_data = $this->_getRelativeFacetSQLData($va_facet_info['relative_to'], $pa_options)) { $va_joins = array_merge($va_joins, $va_relative_sql_data['joins']); $va_wheres = array_merge($va_wheres, $va_relative_sql_data['wheres']); } } if ($this->opo_config->get('perform_item_level_access_checking')) { if ($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true)) { // Join to limit what browse table items are used to generate facet $va_joins[] = 'LEFT JOIN ca_acl ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_acl.row_id AND ca_acl.table_num = ' . $t_item->tableNum() . "\n"; $va_wheres[] = "(\n\t\t\t\t\t\t\t\t((\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id = " . (int) $vn_user_id . ")\n\t\t\t\t\t\t\t\t\t" . (sizeof($va_group_ids) > 0 ? "OR\n\t\t\t\t\t\t\t\t\t(ca_acl.group_id IN (" . join(",", $va_group_ids) . "))" : "") . "\n\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id IS NULL and ca_acl.group_id IS NULL)\n\t\t\t\t\t\t\t\t) AND ca_acl.access >= " . __CA_ACL_READONLY_ACCESS__ . ")\n\t\t\t\t\t\t\t\t" . ($vb_show_if_no_acl ? "OR ca_acl.acl_id IS NULL" : "") . "\n\t\t\t\t\t\t\t)"; } } $vs_where_sql = ''; if (is_array($va_wheres) && sizeof($va_wheres) && ($vs_where_sql = join(' AND ', $va_wheres))) { $vs_where_sql = ' AND (' . $vs_where_sql . ')'; } $vs_join_sql = join("\n", $va_joins); $vn_element_id = $t_element->getPrimaryKey(); $vs_dir = strtoupper($va_facet_info['sort']) === 'DESC' ? "DESC" : "ASC"; $vs_min_sql = $vs_max_sql = ''; $vo_minimum_dimension = caParseLengthDimension(caGetOption('minimum_dimension', $va_facet_info, "0 in")); $vo_maximum_dimension = caParseLengthDimension(caGetOption('maximum_dimension', $va_facet_info, "0 in")); if ($vo_minimum_dimension) { $vn_tmp = (double) $vo_minimum_dimension->convertTo('METER', 6, 'en_US'); $vs_min_sql = " AND (ca_attribute_values.value_decimal1 >= {$vn_tmp})"; } if (caGetOption('maximum_dimension', $va_facet_info, null) && $vo_maximum_dimension) { $vn_tmp = (double) $vo_maximum_dimension->convertTo('METER', 6, 'en_US'); $vs_max_sql = " AND (ca_attribute_values.value_decimal1 <= {$vn_tmp})"; } if ($vb_check_availability_only) { $vs_sql = "\n\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\tFROM ca_attributes\n\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\tca_attribute_values.element_id = ? \n\t\t\t\t\t\t\t\t{$vs_min_sql}\n\t\t\t\t\t\t\t\t{$vs_max_sql}\n\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t\t\tLIMIT 1"; //print $vs_sql; $qr_res = $this->opo_db->query($vs_sql, $vn_element_id); return (int) $qr_res->numRows() > 0 ? true : false; } else { $vs_sql = "\n\t\t\t\t\t\t\tSELECT DISTINCT ca_attribute_values.value_decimal1, ca_attribute_values.value_decimal2, ca_attribute_values.value_longtext1, ca_attribute_values.value_longtext2\n\t\t\t\t\t\t\tFROM ca_attributes\n\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\tca_attribute_values.element_id = ? \n\t\t\t\t\t\t\t\t{$vs_min_sql}\n\t\t\t\t\t\t\t\t{$vs_max_sql}\n\t\t\t\t\t\t\t\t{$vs_where_sql}\n\t\t\t\t\t\t"; //print $vs_sql; $qr_res = $this->opo_db->query($vs_sql, $vn_element_id); $va_values = array(); if (!($vs_output_units = caGetLengthUnitType($vs_units = caGetOption('units', $va_facet_info, 'm')))) { $vs_output_units = Zend_Measure_Length::METER; } $vs_increment = caGetOption('increment', $va_facet_info, '1 m'); $vo_increment = caParseLengthDimension($vs_increment); $vn_increment_in_current_units = (double) $vo_increment->convertTo($vs_output_units, 6, 'en_US'); while ($qr_res->nextRow()) { $vn_meters = $qr_res->get('value_decimal1'); // measurement in meters // convert to target dimensions // normalize $vo_dim = new Zend_Measure_Length($vn_meters, Zend_Measure_Length::METER, 'en_US'); $vs_dim = $vo_dim->convertTo($vs_output_units, 6, 'en_US'); $vn_dim = (double) $vs_dim; $vn_normalized = floor($vn_dim / $vn_increment_in_current_units) * $vn_increment_in_current_units; if (isset($va_criteria[$vn_normalized])) { continue; } $vs_normalized_range_with_units = "{$vn_normalized} {$vs_units} - " . ($vn_normalized + $vn_increment_in_current_units) . " {$vs_units}"; $va_values[$vn_normalized][$vn_normalized] = array('id' => $vn_normalized, 'label' => $vs_normalized_range_with_units); if (!is_null($vs_single_value) && $vn_normalized == $vs_single_value) { $vb_single_value_is_present = true; } } if (!is_null($vs_single_value) && !$vb_single_value_is_present) { return array(); } ksort($va_values); if ($vs_dir == 'DESC') { $va_values = array_reverse($va_values); } $va_sorted_values = array(); foreach ($va_values as $vn_sort_value => $va_values_for_sort_value) { $va_sorted_values = array_merge($va_sorted_values, $va_values_for_sort_value); } return $va_sorted_values; } break; # ----------------------------------------------------- # ----------------------------------------------------- case 'authority': $vs_rel_table_name = $va_facet_info['table']; $va_params = $this->opo_ca_browse_cache->getParameters(); // Make sure we honor type restrictions for the related authority $va_user_type_restrictions = caGetTypeRestrictionsForUser($vs_rel_table_name); $va_restrict_to_types = $va_facet_info['restrict_to_types']; if (is_array($va_user_type_restrictions)) { if (!is_array($va_restrict_to_types)) { $va_restrict_to_types = $va_user_type_restrictions; } else { $va_restrict_to_types = array_intersect($va_restrict_to_types, $va_user_type_restrictions); } } if (!is_array($va_exclude_types = $va_facet_info['exclude_types'])) { $va_exclude_types = array(); } if (!is_array($va_restrict_to_relationship_types = $va_facet_info['restrict_to_relationship_types'])) { $va_restrict_to_relationship_types = array(); } if (!is_array($va_exclude_relationship_types = $va_facet_info['exclude_relationship_types'])) { $va_exclude_relationship_types = array(); } $t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true); if ($vs_browse_table_name == $vs_rel_table_name) { // browsing on self-relations not supported break; } else { switch (sizeof($va_path = array_keys($this->opo_datamodel->getPath($vs_browse_table_name, $vs_rel_table_name)))) { case __CA_ATTRIBUTE_VALUE_LIST__: $t_item_rel = $this->opo_datamodel->getInstanceByTableName($va_path[1], true); $t_rel_item = $this->opo_datamodel->getInstanceByTableName($va_path[2], true); $vs_key = 'relation_id'; break; case __CA_ATTRIBUTE_VALUE_DATERANGE__: $t_item_rel = null; $t_rel_item = $this->opo_datamodel->getInstanceByTableName($va_path[1], true); $vs_key = $t_rel_item->primaryKey(); break; default: // bad related table return null; break; } } $vb_rel_is_hierarchical = (bool) $t_rel_item->isHierarchical(); // // Convert related item type_code specs in restrict_to_types and exclude_types lists to numeric type_ids we need for the query // if (!is_array($va_restrict_to_types = $this->_convertTypeCodesToIDs($va_restrict_to_types, array('instance' => $t_rel_item, 'dontExpandHierarchically' => true)))) { $va_restrict_to_types = array(); } if (!is_array($va_exclude_types = $this->_convertTypeCodesToIDs($va_exclude_types, array('instance' => $t_rel_item, 'dontExpandHierarchically' => true)))) { $va_exclude_types = array(); } $va_restrict_to_types_expanded = $this->_convertTypeCodesToIDs($va_restrict_to_types, array('instance' => $t_rel_item)); $va_exclude_types_expanded = $this->_convertTypeCodesToIDs($va_exclude_types, array('instance' => $t_rel_item)); // look up relationship type restrictions $va_restrict_to_relationship_types = $this->_getRelationshipTypeIDs($va_restrict_to_relationship_types, $va_facet_info['relationship_table']); $va_exclude_relationship_types = $this->_getRelationshipTypeIDs($va_exclude_relationship_types, $va_facet_info['relationship_table']); $va_joins = array(); $va_selects = array(); $va_wheres = array(); $va_orderbys = array(); if (!$va_facet_info['show_all_when_first_facet'] || $this->numCriteria() > 0) { $vs_cur_table = array_shift($va_path); foreach ($va_path as $vs_join_table) { $va_rel_info = $this->opo_datamodel->getRelationships($vs_cur_table, $vs_join_table); $va_joins[] = 'INNER JOIN ' . $vs_join_table . ' ON ' . $vs_cur_table . '.' . $va_rel_info[$vs_cur_table][$vs_join_table][0][0] . ' = ' . $vs_join_table . '.' . $va_rel_info[$vs_cur_table][$vs_join_table][0][1] . "\n"; $vs_cur_table = $vs_join_table; } } else { if ($va_facet_info['show_all_when_first_facet']) { $va_path = array_reverse($va_path); // in "show_all" mode we turn the browse on it's head and grab records by the "subject" table, rather than the browse table $vs_cur_table = array_shift($va_path); $vs_join_table = $va_path[0]; $va_rel_info = $this->opo_datamodel->getRelationships($vs_cur_table, $vs_join_table); $va_joins[] = 'LEFT JOIN ' . $vs_join_table . ' ON ' . $vs_cur_table . '.' . $va_rel_info[$vs_cur_table][$vs_join_table][0][0] . ' = ' . $vs_join_table . '.' . $va_rel_info[$vs_cur_table][$vs_join_table][0][1] . "\n"; } } if (sizeof($va_results) && $this->numCriteria() > 0) { $va_wheres[] = "(" . $t_subject->tableName() . '.' . $t_subject->primaryKey() . " IN (" . join(',', $va_results) . "))"; } if (!is_array($va_restrict_to_lists = $va_facet_info['restrict_to_lists'])) { $va_restrict_to_lists = array(); } if (is_array($va_restrict_to_lists) && sizeof($va_restrict_to_lists) > 0 && $t_rel_item->tableName() == 'ca_list_items') { $va_list_ids = array(); foreach ($va_restrict_to_lists as $vm_list) { if (is_numeric($vm_list)) { $vn_list_id = (int) $vm_list; } else { $vn_list_id = (int) ca_lists::getListID($vm_list); } if ($vn_list_id) { $va_list_ids[] = $vn_list_id; } } if (sizeof($va_list_ids) > 0) { $va_wheres[] = "{$vs_rel_table_name}.list_id IN (" . join(',', $va_list_ids) . ")"; } } if (is_array($va_restrict_to_types) && sizeof($va_restrict_to_types) > 0 && method_exists($t_rel_item, "getTypeList")) { $va_wheres[] = "{$vs_rel_table_name}.type_id IN (" . join(',', caGetOption('dont_include_subtypes', $va_facet_info, false) ? $va_restrict_to_types : $va_restrict_to_types_expanded) . ")" . ($t_rel_item->getFieldInfo('type_id', 'IS_NULL') ? " OR ({$vs_rel_table_name}.type_id IS NULL)" : ''); $va_selects[] = "{$vs_rel_table_name}.type_id"; } if (is_array($va_exclude_types) && sizeof($va_exclude_types) > 0 && method_exists($t_rel_item, "getTypeList")) { $va_wheres[] = "{$vs_rel_table_name}.type_id NOT IN (" . join(',', caGetOption('dont_include_subtypes', $va_facet_info, false) ? $va_exclude_types : $va_exclude_types_expanded) . ")"; } if (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_rel_item->hasField('access')) { $va_wheres[] = "(" . $t_rel_item->tableName() . ".access IN (" . join(',', $pa_options['checkAccess']) . "))"; // exclude non-accessible authority items if (!$va_facet_info['show_all_when_first_facet'] || $this->numCriteria() > 0) { $va_wheres[] = "(" . $vs_browse_table_name . ".access IN (" . join(',', $pa_options['checkAccess']) . "))"; // exclude non-accessible browse items } } if ($t_item->hasField('deleted') && !$va_facet_info['show_all_when_first_facet']) { $va_wheres[] = "(" . $t_item->tableName() . ".deleted = 0)"; } if ($t_rel_item->hasField('deleted')) { $va_wheres[] = "(" . $t_rel_item->tableName() . ".deleted = 0)"; } $vs_rel_pk = $t_rel_item->primaryKey(); $va_rel_attr_elements = $t_rel_item->getApplicableElementCodes(null, true, false); $va_attrs_to_fetch = array(); if (!$va_facet_info['show_all_when_first_facet'] || $this->numCriteria() > 0) { //$va_selects[] = $t_item->tableName().'.'.$t_item->primaryKey(); // get primary key of subject } $va_selects[] = $t_rel_item->tableName() . '.' . $vs_rel_pk; // get primary key of related $vs_hier_parent_id_fld = $vs_hier_id_fld = null; if ($vb_rel_is_hierarchical) { $vs_hier_parent_id_fld = $t_rel_item->getProperty('HIERARCHY_PARENT_ID_FLD'); $va_selects[] = $t_rel_item->tableName() . '.' . $vs_hier_parent_id_fld; if ($vs_hier_id_fld = $t_rel_item->getProperty('HIERARCHY_ID_FLD')) { $va_selects[] = $t_rel_item->tableName() . '.' . $vs_hier_id_fld; } } // analyze group_fields (if defined) and add them to the query $va_groupings_to_fetch = array(); if (isset($va_facet_info['groupings']) && is_array($va_facet_info['groupings']) && sizeof($va_facet_info['groupings'])) { foreach ($va_facet_info['groupings'] as $vs_grouping => $vs_grouping_name) { // is grouping type_id? if ($vs_grouping === 'type' && $t_rel_item->hasField('type_id')) { $va_selects[] = $t_rel_item->tableName() . '.type_id'; $va_groupings_to_fetch[] = 'type_id'; } // is group field a relationship type? if ($vs_grouping === 'relationship_types') { $va_selects[] = $va_facet_info['relationship_table'] . '.type_id rel_type_id'; $va_groupings_to_fetch[] = 'rel_type_id'; } // is group field an attribute? if (preg_match('!^ca_attribute_([^:]*)!', $vs_grouping, $va_matches)) { if ($vn_element_id = array_search($va_matches[1], $va_rel_attr_elements)) { $va_attrs_to_fetch[] = $vn_element_id; } } } } if ($va_facet_info['relative_to']) { // TODO: do this everywhere $va_restrict_to_relationship_types = array(); $vs_browse_type_limit_sql = ''; if ($t_subject->hasField('deleted')) { $va_wheres[] = "(" . $t_subject->tableName() . ".deleted = 0)"; } if ($va_relative_sql_data = $this->_getRelativeFacetSQLData($va_facet_info['relative_to'], $pa_options)) { $va_joins = array_merge($va_joins, $va_relative_sql_data['joins']); $va_wheres = array_merge($va_wheres, $va_relative_sql_data['wheres']); } } if (sizeof($va_restrict_to_relationship_types) > 0 && is_object($t_item_rel)) { $va_wheres[] = $t_item_rel->tableName() . ".type_id IN (" . join(',', $va_restrict_to_relationship_types) . ")"; } if (sizeof($va_exclude_relationship_types) > 0 && is_object($t_item_rel)) { $va_wheres[] = $t_item_rel->tableName() . ".type_id NOT IN (" . join(',', $va_exclude_relationship_types) . ")"; } if ($vs_browse_type_limit_sql) { $va_wheres[] = $vs_browse_type_limit_sql; } if ($this->opo_config->get('perform_item_level_access_checking')) { if ($t_item = $this->opo_datamodel->getInstanceByTableName($vs_browse_table_name, true)) { // Join to limit what browse table items are used to generate facet $va_joins[] = 'LEFT JOIN ca_acl ON ' . $vs_browse_table_name . '.' . $t_item->primaryKey() . ' = ca_acl.row_id AND ca_acl.table_num = ' . $t_item->tableNum() . "\n"; $va_wheres[] = "(\n\t\t\t\t\t\t\t\t((\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id = " . (int) $vn_user_id . ")\n\t\t\t\t\t\t\t\t\t" . (sizeof($va_group_ids) > 0 ? "OR\n\t\t\t\t\t\t\t\t\t(ca_acl.group_id IN (" . join(",", $va_group_ids) . "))" : "") . "\n\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t(ca_acl.user_id IS NULL and ca_acl.group_id IS NULL)\n\t\t\t\t\t\t\t\t) AND ca_acl.access >= " . __CA_ACL_READONLY_ACCESS__ . ")\n\t\t\t\t\t\t\t\t" . ($vb_show_if_no_acl ? "OR ca_acl.acl_id IS NULL" : "") . "\n\t\t\t\t\t\t\t)"; // Join to limit what related items are used to generate facet $va_joins[] = 'LEFT JOIN ca_acl AS rel_acl ON ' . $t_rel_item->tableName() . '.' . $t_rel_item->primaryKey() . ' = rel_acl.row_id AND rel_acl.table_num = ' . $t_rel_item->tableNum() . "\n"; $va_wheres[] = "(\n\t\t\t\t\t\t\t\t((\n\t\t\t\t\t\t\t\t\t(rel_acl.user_id = " . (int) $vn_user_id . ")\n\t\t\t\t\t\t\t\t\t" . (sizeof($va_group_ids) > 0 ? "OR\n\t\t\t\t\t\t\t\t\t(rel_acl.group_id IN (" . join(",", $va_group_ids) . "))" : "") . "\n\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t(rel_acl.user_id IS NULL and rel_acl.group_id IS NULL)\n\t\t\t\t\t\t\t\t) AND rel_acl.access >= " . __CA_ACL_READONLY_ACCESS__ . ")\n\t\t\t\t\t\t\t\t" . ($vb_show_if_no_acl ? "OR rel_acl.acl_id IS NULL" : "") . "\n\t\t\t\t\t\t\t)"; } } $vs_join_sql = join("\n", $va_joins); if ($vb_check_availability_only) { if (!$va_facet_info['show_all_when_first_facet'] || $this->numCriteria() > 0) { $vs_sql = "\n\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\tFROM " . $vs_browse_table_name . "\n\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t" . (sizeof($va_wheres) ? ' WHERE ' : '') . join(" AND ", $va_wheres) . " LIMIT 1"; } else { $vs_sql = "\n\t\t\t\t\t\t\tSELECT 1\n\t\t\t\t\t\t\tFROM " . $t_rel_item->tableName() . "\n\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t" . (sizeof($va_wheres) ? ' WHERE ' : '') . join(" AND ", $va_wheres) . " LIMIT 1"; } $qr_res = $this->opo_db->query($vs_sql); //print "<hr>$vs_sql<hr>\n"; return (int) $qr_res->numRows() > 0 ? true : false; } else { if (!$va_facet_info['show_all_when_first_facet'] || $this->numCriteria() > 0) { $vs_sql = "\n\t\t\t\t\t\t\tSELECT DISTINCT " . join(', ', $va_selects) . "\n\t\t\t\t\t\t\tFROM " . $vs_browse_table_name . "\n\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t" . (sizeof($va_wheres) ? ' WHERE ' : '') . join(" AND ", $va_wheres) . "\n\t\t\t\t\t\t\t\t" . (sizeof($va_orderbys) ? "ORDER BY " . join(', ', $va_orderbys) : ''); } else { $vs_sql = "\n\t\t\t\t\t\t\tSELECT DISTINCT " . join(', ', $va_selects) . "\n\t\t\t\t\t\t\tFROM " . $t_rel_item->tableName() . "\n\t\t\t\t\t\t\t{$vs_join_sql}\n\t\t\t\t\t\t\t\t" . (sizeof($va_wheres) ? ' WHERE ' : '') . join(" AND ", $va_wheres) . "\n\t\t\t\t\t\t\t\t" . (sizeof($va_orderbys) ? "ORDER BY " . join(', ', $va_orderbys) : ''); } //print "<hr>$vs_sql<hr>\n"; $qr_res = $this->opo_db->query($vs_sql); $va_facet = $va_facet_items = array(); $vs_rel_pk = $t_rel_item->primaryKey(); // First get related ids with type and relationship type values // (You could get all of the data we need for the facet in a single query but it turns out to be faster for very large facets to // do it in separate queries, one for the primary ids and another for the labels; a third is done if attributes need to be fetched. // There appears to be a significant [~10%] performance for smaller facets and a larger one [~20-25%] for very large facets) $vn_max_level = caGetOption('maximum_levels', $va_facet_info, null); while ($qr_res->nextRow()) { $va_fetched_row = $qr_res->getRow(); $vn_id = $va_fetched_row[$vs_rel_pk]; //if (isset($va_facet_items[$vn_id])) { continue; } --- we can't do this as then we don't detect items that have multiple rel_type_ids... argh. if (isset($va_criteria[$vn_id])) { continue; } // skip items that are used as browse critera - don't want to browse on something you're already browsing on if (!$va_facet_items[$va_fetched_row[$vs_rel_pk]]) { // if(!is_null($vn_max_level)) { // if (sizeof($va_ancestors) + 1 > $vn_max_level) { // if ($va_tmp = $va_ancestors[sizeof($va_ancestors) - $vn_max_level]) { // $va_ancestors = array(); // $va_fetched_row = $va_tmp['NODE']; // } // } // } if (is_array($va_restrict_to_types) && sizeof($va_restrict_to_types) && $va_fetched_row['type_id'] && !in_array($va_fetched_row['type_id'], $va_restrict_to_types)) { continue; } $va_facet_items[$va_fetched_row[$vs_rel_pk]] = array('id' => $va_fetched_row[$vs_rel_pk], 'type_id' => array(), 'parent_id' => $vb_rel_is_hierarchical ? $va_fetched_row[$vs_hier_parent_id_fld] : null, 'hierarchy_id' => $vb_rel_is_hierarchical ? $va_fetched_row[$vs_hier_id_fld] : null, 'rel_type_id' => array(), 'child_count' => 0); if (!is_null($vs_single_value) && $va_fetched_row[$vs_rel_pk] == $vs_single_value) { $vb_single_value_is_present = true; } } if ($va_fetched_row['type_id']) { $va_facet_items[$va_fetched_row[$vs_rel_pk]]['type_id'][] = $va_fetched_row['type_id']; } if ($va_fetched_row['rel_type_id']) { $va_facet_items[$va_fetched_row[$vs_rel_pk]]['rel_type_id'][] = $va_fetched_row['rel_type_id']; } } if (!isset($va_facet_info['dont_expand_hierarchically']) || !$va_facet_info['dont_expand_hierarchically']) { $qr_res->seek(0); $va_ids = $qr_res->getAllFieldValues($vs_rel_pk); $qr_ancestors = call_user_func($t_rel_item->tableName() . '::getHierarchyAncestorsForIDs', $va_ids, array('returnAs' => 'SearchResult')); $vs_rel_table = $t_rel_item->tableName(); $vs_rel_pk = $t_rel_item->primaryKey(); $vb_check_ancestor_access = (bool) (isset($pa_options['checkAccess']) && is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess']) && $t_rel_item->hasField('access')); if ($qr_ancestors) { while ($qr_ancestors->nextHit()) { $vn_parent_type_id = $qr_ancestors->get('type_id'); if (sizeof($va_exclude_types) > 0 && in_array($vn_parent_type_id, $va_exclude_types)) { continue; } if (sizeof($va_restrict_to_types) > 0 && !in_array($vn_parent_type_id, $va_restrict_to_types)) { continue; } if ($vb_check_ancestor_access && !in_array($qr_ancestors->get('access'), $pa_options['checkAccess'])) { continue; } $va_facet_items[$vn_ancestor_id = (int) $qr_ancestors->get("{$vs_rel_pk}")] = array('id' => $vn_ancestor_id, 'type_id' => array(), 'parent_id' => $vb_rel_is_hierarchical ? $qr_ancestors->get("{$vs_hier_parent_id_fld}") : null, 'hierarchy_id' => $vb_rel_is_hierarchical && $vs_hier_id_fld ? $qr_ancestors->get($vs_hier_id_fld) : null, 'rel_type_id' => array(), 'child_count' => 0); } } } // Set child counts foreach ($va_facet_items as $vn_i => $va_item) { if ($va_item['parent_id'] && isset($va_facet_items[$va_item['parent_id']])) { $va_facet_items[$va_item['parent_id']]['child_count']++; } } // Get labels for facet items if (sizeof($va_row_ids = array_keys($va_facet_items))) { if ($vs_label_table_name = $t_rel_item->getLabelTableName()) { $t_rel_item_label = $this->opo_datamodel->getInstanceByTableName($vs_label_table_name, true); $vs_label_display_field = $t_rel_item_label->getDisplayField(); $vs_rel_pk = $t_rel_item->primaryKey(); $va_label_wheres = array(); if ($t_rel_item_label->hasField('is_preferred')) { $va_label_wheres[] = "({$vs_label_table_name}.is_preferred = 1)"; } $va_label_wheres[] = "({$vs_label_table_name}.{$vs_rel_pk} IN (" . join(",", $va_row_ids) . "))"; $va_label_selects[] = "{$vs_label_table_name}.{$vs_rel_pk}"; $va_label_selects[] = "{$vs_label_table_name}.locale_id"; $va_label_fields = $t_rel_item->getLabelUIFields(); foreach ($va_label_fields as $vs_label_field) { $va_label_selects[] = "{$vs_label_table_name}.{$vs_label_field}"; } // Get label ordering fields $va_ordering_fields_to_fetch = isset($va_facet_info['order_by_label_fields']) && is_array($va_facet_info['order_by_label_fields']) ? $va_facet_info['order_by_label_fields'] : array(); $va_orderbys = array(); foreach ($va_ordering_fields_to_fetch as $vs_sort_by_field) { if (!$t_rel_item_label->hasField($vs_sort_by_field)) { continue; } $va_orderbys[] = $va_label_selects[] = $vs_label_table_name . '.' . $vs_sort_by_field; } // get labels $vs_sql = "\n\t\t\t\t\t\t\t\t\tSELECT " . join(', ', $va_label_selects) . "\n\t\t\t\t\t\t\t\t\tFROM " . $vs_label_table_name . "\n\t\t\t\t\t\t\t\t\t\t" . (sizeof($va_label_wheres) ? ' WHERE ' : '') . join(" AND ", $va_label_wheres) . "\n\t\t\t\t\t\t\t\t\t\t" . (sizeof($va_orderbys) ? "ORDER BY " . join(', ', $va_orderbys) : '') . ""; //print $vs_sql; $qr_labels = $this->opo_db->query($vs_sql); while ($qr_labels->nextRow()) { $va_fetched_row = $qr_labels->getRow(); $va_facet_item = array_merge($va_facet_items[$va_fetched_row[$vs_rel_pk]], array('label' => $va_fetched_row[$vs_label_display_field])); foreach ($va_ordering_fields_to_fetch as $vs_to_fetch) { $va_facet_item[$vs_to_fetch] = $va_fetched_row[$vs_to_fetch]; } $va_facet[$va_fetched_row[$vs_rel_pk]][$va_fetched_row['locale_id']] = $va_facet_item; } } // get attributes for facet items if (sizeof($va_attrs_to_fetch)) { $qr_attrs = $this->opo_db->query("\n\t\t\t\t\t\t\t\t\tSELECT c_av.*, c_a.locale_id, c_a.row_id\n\t\t\t\t\t\t\t\t\tFROM ca_attributes c_a\n\t\t\t\t\t\t\t\t\tINNER JOIN ca_attribute_values c_av ON c_a.attribute_id = c_av.attribute_id\n\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\tc_av.element_id IN (" . join(',', $va_attrs_to_fetch) . ")\n\t\t\t\t\t\t\t\t\t\tAND\n\t\t\t\t\t\t\t\t\t\tc_a.table_num = ? \n\t\t\t\t\t\t\t\t\t\tAND \n\t\t\t\t\t\t\t\t\t\tc_a.row_id IN (" . join(',', $va_row_ids) . ")\n\t\t\t\t\t\t\t\t", $t_rel_item->tableNum()); while ($qr_attrs->nextRow()) { $va_fetched_row = $qr_attrs->getRow(); $vn_id = $va_fetched_row['row_id']; // if no locale is set for the attribute default it to whatever the locale for the item is if (!($vn_locale_id = $va_fetched_row['locale_id'])) { $va_tmp = array_keys($va_facet[$vn_id]); $vn_locale_id = $va_tmp[0]; } $va_facet[$vn_id][$vn_locale_id]['ca_attribute_' . $va_fetched_row['element_id']][] = $va_fetched_row; } } } if (!is_null($vs_single_value) && !$vb_single_value_is_present) { return array(); } return caExtractValuesByUserLocale($va_facet); } break; # ----------------------------------------------------- # ----------------------------------------------------- default: return null; break; # ----------------------------------------------------- } }