Пример #1
0
 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;
     }
 }
Пример #2
0
 /**
  * Creates a new active user
  * 
  * @param string $user_name user name
  * @param string $password password
  * @param string $email email address
  * @param string $fname first name
  * @param string $lname  last name
  * @return int identifier of the new user
  * @throws SoapFault
  */
 public function createUser($user_name, $password, $email, $fname, $lname)
 {
     $t_user = new ca_users();
     $t_user->set("user_name", $user_name);
     $t_user->set("password", $password);
     $t_user->set("email", $email);
     $t_user->set("fname", $fname);
     $t_user->set("lname", $lname);
     $t_user->set("active", 1);
     $t_user->setMode(ACCESS_WRITE);
     $t_user->insert();
     if ($t_user->numErrors()) {
         throw new SoapFault("Server", "Could not create user: "******" ", $t_user->getErrors()));
     }
     return $t_user->getPrimaryKey();
 }
 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);
 }
Пример #4
0
 /**
  * 
  */
 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;
 }
Пример #5
0
 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');
     }
 }
Пример #6
0
 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;
     }
 }
Пример #7
0
 public function search($pn_subject_tablenum, $ps_search_expression, $pa_filters = array(), $po_rewritten_query = null)
 {
     $vn_i = 0;
     $va_old_signs = $po_rewritten_query->getSigns();
     $va_terms = $va_signs = array();
     foreach ($po_rewritten_query->getSubqueries() as $o_lucene_query_element) {
         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 = null;
                 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;
                     $o_lucene_query_element = new Zend_Search_Lucene_Search_Query_Term(new Zend_Search_Lucene_Index_Term('"' . $vs_term . '"', $vs_access_point));
                 }
                 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;
                         }
                         $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;
                             }
                         }
                         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) {
                                 break;
                             }
                             $vs_fld_num = $this->opo_datamodel->getFieldNum($vs_table, $vs_field);
                             if (!$vs_fld_num) {
                                 // probably attribute
                                 $t_element = new ca_metadata_elements();
                                 if ($t_element->load(array('element_code' => $vs_sub_field ? $vs_sub_field : $vs_field))) {
                                     //
                                     // 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) {
                                                 if ($this->opo_tep->parse($vs_term)) {
                                                     // 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_access_point));
                                                 }
                                             } else {
                                                 if ($this->opo_tep->parse($vs_term)) {
                                                     // 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_access_point));
                                                 }
                                             }
                                             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_access_point));
                                             }
                                             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_access_point));
                                             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_access_point));
                                             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_access_point));
                                             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_access_point));
                                             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_access_point));
                                             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_access_point));
                                             break;
                                     }
                                 }
                             }
                         }
                     }
                 }
                 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 ($vs_filter_query = $this->_filterValueToQueryValue($pa_filters)) {
         $ps_search_expression = "({$ps_search_expression}) AND ({$vs_filter_query})";
     }
     $vo_http_client = new Zend_Http_Client();
     $vo_http_client->setUri($this->ops_elasticsearch_base_url . "/" . $this->ops_elasticsearch_index_name . "/" . $this->opo_datamodel->getTableName($pn_subject_tablenum) . "/" . "_search");
     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("[ElasticSearch] Running query {$ps_search_expression}");
     $vo_http_client->setParameterGet(array('size' => intval($this->opa_options["limit"]), 'q' => $ps_search_expression, 'fields' => ''));
     $vo_http_response = $vo_http_client->request();
     $va_result = json_decode($vo_http_response->getBody(), true);
     return new WLPlugSearchEngineElasticSearchResult($va_result["hits"]["hits"], $pn_subject_tablenum);
 }
Пример #8
0
 private function _doQueriesForSqlSearch($po_rewritten_query, $pn_subject_tablenum, $ps_dest_table, $pn_level = 0, $pa_options = null)
 {
     // query is always of type Zend_Search_Lucene_Search_Query_Boolean
     $vn_i = 0;
     switch (get_class($po_rewritten_query)) {
         case 'Zend_Search_Lucene_Search_Query_MultiTerm':
             $va_elements = $po_rewritten_query->getTerms();
             break;
         default:
             $va_elements = $po_rewritten_query->getSubqueries();
             break;
     }
     $o_base = new SearchBase();
     $va_old_signs = $po_rewritten_query->getSigns();
     foreach ($va_elements 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
         $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)
         $vs_direct_sql_query = null;
         $vn_direct_sql_target_table_num = $pn_subject_tablenum;
         switch ($vs_class = get_class($o_lucene_query_element)) {
             case 'Zend_Search_Lucene_Search_Query_Boolean':
             case 'Zend_Search_Lucene_Search_Query_MultiTerm':
                 $this->_createTempTable('ca_sql_search_temp_' . $pn_level);
                 if ($vs_op == 'AND' && $vn_i == 0) {
                     $this->_doQueriesForSqlSearch($o_lucene_query_element, $pn_subject_tablenum, $ps_dest_table, $pn_level + 1);
                 } else {
                     $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':
                         if ($vn_i > 0) {
                             $this->_createTempTable("{$ps_dest_table}_acc");
                             $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";
                             $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':
                         $qr_res = $this->opo_db->query("SELECT row_id FROM ca_sql_search_temp_{$pn_level}");
                         if (is_array($va_ids = $qr_res->getAllFieldValues()) && sizeof($va_ids)) {
                             $vs_sql = "\n\t\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";
                             $qr_res = $this->opo_db->query($vs_sql, array($va_ids));
                         }
                         break;
                     default:
                     case '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";
                         $qr_res = $this->opo_db->query($vs_sql);
                         break;
                 }
                 $vn_i++;
                 $this->_dropTempTable('ca_sql_search_temp_' . $pn_level);
                 break;
             case 'Zend_Search_Lucene_Search_Query_Term':
             case 'Zend_Search_Lucene_Index_Term':
             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_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($pn_subject_tablenum, $va_lower_term->field);
                         $vn_direct_sql_target_table_num = $va_element['table_num'];
                         $va_indexed_fields = $o_base->getFieldsToIndex($pn_subject_tablenum, $vn_direct_sql_target_table_num);
                         $vn_root_element_id = $va_element['element_info']['hier_element_id'];
                         if (!isset($va_indexed_fields['_ca_attribute_' . $va_element['element_id']]) && (!$vn_root_element_id || $vn_root_element_id && !isset($va_indexed_fields['_ca_attribute_' . $vn_root_element_id]))) {
                             break 2;
                         }
                         // skip if not indexed
                         switch ($va_element['datatype']) {
                             case __CA_ATTRIBUTE_VALUE_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'];
                                 // mysql BETWEEN always wants the lower value first ... BETWEEN 5 AND 3 wouldn't match 4 ... So we swap the values if necessary
                                 if ($vs_upper_lat < $vs_lower_lat) {
                                     $tmp = $vs_upper_lat;
                                     $vs_upper_lat = $vs_lower_lat;
                                     $vs_lower_lat = $tmp;
                                 }
                                 if ($vs_upper_long < $vs_lower_long) {
                                     $tmp = $vs_upper_long;
                                     $vs_upper_long = $vs_lower_long;
                                     $vs_lower_long = $tmp;
                                 }
                                 $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 __CA_ATTRIBUTE_VALUE_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 __CA_ATTRIBUTE_VALUE_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 __CA_ATTRIBUTE_VALUE_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 __CA_ATTRIBUTE_VALUE_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 __CA_ATTRIBUTE_VALUE_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 __CA_ATTRIBUTE_VALUE_NUMERIC__:
                                 $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':
                         if ($this->getOption('strictPhraseSearching')) {
                             $vs_search_tokenizer_regex = $this->opo_search_config->get('search_tokenizer_regex');
                             $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_terms = preg_split("![{$vs_search_tokenizer_regex}]+!u", (string) $o_term->text);
                                 $va_raw_terms[] = (string) $o_term->text;
                                 foreach ($va_terms as $vs_term) {
                                     if (strlen($vs_escaped_text = $this->opo_db->escape($vs_term))) {
                                         $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($pn_subject_tablenum, $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}')";
                                     if (is_array($va_element['relationship_type_ids']) && sizeof($va_element['relationship_type_ids'])) {
                                         $vs_fld_limit_sql .= " AND (swi.rel_type_id IN (" . join(",", $va_element['relationship_type_ids']) . "))";
                                     }
                                 }
                             }
                             $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;
                         }
                     default:
                         switch ($vs_class) {
                             case 'Zend_Search_Lucene_Search_Query_Phrase':
                                 $va_term_objs = $o_lucene_query_element->getQueryTerms();
                                 break;
                             case 'Zend_Search_Lucene_Index_Term':
                                 $va_term_objs = array($o_lucene_query_element);
                                 break;
                             default:
                                 $va_term_objs = array($o_lucene_query_element->getTerm());
                                 break;
                         }
                         foreach ($va_term_objs as $o_term) {
                             $va_access_point_info = $this->_getElementIDForAccessPoint($pn_subject_tablenum, $o_term->field);
                             $vs_access_point = $va_access_point_info['access_point'];
                             $vs_term = $o_term->text;
                             if ($vs_access_point && mb_strtoupper($vs_term) == _t('[BLANK]')) {
                                 $t_ap = $this->opo_datamodel->getInstanceByTableNum($va_access_point_info['table_num'], true);
                                 if (is_a($t_ap, 'BaseLabel')) {
                                     // labels have the literal text "[Blank]" indexed to "blank" to indicate blank-ness
                                     $vb_is_blank_search = false;
                                     $vs_term = _t('blank');
                                 } else {
                                     $vb_is_blank_search = true;
                                     break;
                                 }
                             }
                             $va_terms = array($vs_term);
                             //$this->_tokenize($vs_term, true, $vn_i);
                             $vb_has_wildcard = (bool) preg_match('!\\*$!', $vs_term);
                             $vb_output_term = false;
                             foreach ($va_terms as $vs_term) {
                                 if ($vb_has_wildcard) {
                                     $vs_term .= '*';
                                 }
                                 if (in_array(trim(mb_strtolower($vs_term, 'UTF-8')), WLPlugSearchEngineSqlSearch::$s_stop_words)) {
                                     continue;
                                 }
                                 $vs_stripped_term = preg_replace('!\\*+$!u', '', $vs_term);
                                 if ($vb_has_wildcard) {
                                     $va_ft_like_terms[] = $vs_stripped_term;
                                 } else {
                                     // do stemming
                                     $vb_do_stemming = $this->opb_do_stemming;
                                     if (mb_substr($vs_term, -1) == '|') {
                                         $vs_term = mb_substr($vs_term, 0, mb_strlen($vs_term) - 1);
                                         $vb_do_stemming = false;
                                     }
                                     if ($vb_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;
                             }
                         }
                         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 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 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 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))) {
                             $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;
                                 $vn_direct_sql_target_table_num = $vs_table_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))) {
                                         $va_indexed_fields = $o_base->getFieldsToIndex($pn_subject_tablenum, $vn_direct_sql_target_table_num);
                                         $vn_fld_num = $t_element->getPrimaryKey();
                                         $vn_root_element_id = $t_element->get('hier_element_id');
                                         if (!isset($va_indexed_fields['_ca_attribute_' . $vn_fld_num]) && (!$vn_root_element_id || $vn_root_element_id && !isset($va_indexed_fields['_ca_attribute_' . $vn_root_element_id]))) {
                                             break 2;
                                         }
                                         // skip if not indexed
                                         $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 __CA_ATTRIBUTE_VALUE_DATERANGE__:
                                                     $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\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(\n\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\tAND\n\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)\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\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\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(\n\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\tOR\n\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\tOR\n\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)\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\t";
                                                         }
                                                     }
                                                     break;
                                                 case __CA_ATTRIBUTE_VALUE_GEOCODE__:
                                                     // At this point $va_raw_terms has been tokenized by Lucene into oblivion
                                                     // and is also dependent on the search_tokenizer_regex so we can't really do anything with it.
                                                     // We now build our own un-tokenized term array instead. caParseGISSearch() can handle it.
                                                     $va_gis_terms = array();
                                                     foreach ($o_lucene_query_element->getQueryTerms() as $o_term) {
                                                         $va_gis_terms[] = trim((string) $o_term->text);
                                                     }
                                                     if ($va_coords = caParseGISSearch(join(' ', $va_gis_terms))) {
                                                         $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 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\tAND\n\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\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
                                                     }
                                                     break;
                                                 case __CA_ATTRIBUTE_VALUE_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\tSELECT ca.row_id, 1\n\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\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^JOIN\n\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(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\tAND\n\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\tAND\n\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\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
                                                     break;
                                                 case __CA_ATTRIBUTE_VALUE_LENGTH__:
                                                     // If it looks like a dimension that has been tokenized by Lucene
                                                     // into oblivion rehydrate it here.
                                                     try {
                                                         switch (sizeof($va_raw_terms)) {
                                                             case 2:
                                                                 $vs_dimension = $va_raw_terms[0] . caGetDecimalSeparator() . $va_raw_terms[1];
                                                                 break;
                                                             case 3:
                                                                 $vs_dimension = $va_raw_terms[0] . caGetDecimalSeparator() . $va_raw_terms[1] . " " . $va_raw_terms[2];
                                                                 break;
                                                             default:
                                                                 $vs_dimension = join(' ', $va_raw_terms);
                                                         }
                                                         $vo_parsed_measurement = caParseLengthDimension($vs_dimension);
                                                         $vn_len = $vo_parsed_measurement->convertTo('METER', 6, 'en_US');
                                                     } catch (Exception $e) {
                                                         $vs_direct_sql_query = null;
                                                         break;
                                                     }
                                                     $vs_direct_sql_query = "\n\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\tFROM ca_attribute_values cav\n\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^JOIN\n\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(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\tAND\n\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\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
                                                     break;
                                                 case __CA_ATTRIBUTE_VALUE_WEIGHT__:
                                                     // If it looks like a weight that has been tokenized by Lucene
                                                     // into oblivion rehydrate it here.
                                                     try {
                                                         switch (sizeof($va_raw_terms)) {
                                                             case 2:
                                                                 $vs_dimension = $va_raw_terms[0] . caGetDecimalSeparator() . $va_raw_terms[1];
                                                                 break;
                                                             case 3:
                                                                 $vs_dimension = $va_raw_terms[0] . caGetDecimalSeparator() . $va_raw_terms[1] . " " . $va_raw_terms[2];
                                                                 break;
                                                             default:
                                                                 $vs_dimension = join(' ', $va_raw_terms);
                                                         }
                                                         $vo_parsed_measurement = caParseWeightDimension($vs_dimension);
                                                         $vn_weight = $vo_parsed_measurement->convertTo('KILOGRAM', 6, 'en_US');
                                                     } catch (Exception $e) {
                                                         $vs_direct_sql_query = null;
                                                         break;
                                                     }
                                                     $vs_direct_sql_query = "\n\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\tFROM ca_attribute_values cav\n\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^JOIN\n\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(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\tAND\n\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\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
                                                     break;
                                                 case __CA_ATTRIBUTE_VALUE_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\tSELECT ca.row_id, 1\n\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\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^JOIN\n\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(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\tAND\n\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\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
                                                     break;
                                                 case __CA_ATTRIBUTE_VALUE_INTEGER__:
                                                     $vs_direct_sql_query = "\n\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\tFROM ca_attribute_values cav\n\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^JOIN\n\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(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\tAND\n\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\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
                                                     break;
                                                 case __CA_ATTRIBUTE_VALUE_NUMERIC__:
                                                     $vs_direct_sql_query = "\n\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\tFROM ca_attribute_values cav\n\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^JOIN\n\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(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\tAND\n\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\n\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 (($vs_intrinsic_field_name = $t_table->fieldName($vn_fld_num)) && ($vn_intrinsic_type = $t_table->getFieldInfo($vs_intrinsic_field_name, 'FIELD_TYPE')) == FT_BIT) {
                                 $vb_ft_bit_optimization = true;
                             } elseif ($vn_intrinsic_type == FT_HISTORIC_DATERANGE) {
                                 $vb_all_numbers = true;
                                 foreach ($va_raw_terms as $vs_term) {
                                     if (!is_numeric($vs_term)) {
                                         $vb_all_numbers = false;
                                         break;
                                     }
                                 }
                                 $vs_date_start_fld = $t_table->getFieldInfo($vs_intrinsic_field_name, 'START');
                                 $vs_date_end_fld = $t_table->getFieldInfo($vs_intrinsic_field_name, 'END');
                                 $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\tSELECT " . $t_table->primaryKey() . ", 1\n\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $t_table->tableName() . "\n\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\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t({$vs_date_start_fld} BETWEEN " . floatval($va_dates['start']) . " AND " . floatval($va_dates['end']) . ")\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tAND\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t({$vs_date_end_fld} BETWEEN " . floatval($va_dates['start']) . " AND " . floatval($va_dates['end']) . ")\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\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\tSELECT " . $t_table->primaryKey() . ", 1\n\t\t\t\t\t\t\t\t\t\t\t\tFROM " . $t_table->tableName() . "\n\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\tWHERE\n\t\t\t\t\t\t\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t({$vs_date_start_fld} BETWEEN " . floatval($va_dates['start']) . " AND " . floatval($va_dates['end']) . ")\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t({$vs_date_end_fld} BETWEEN " . floatval($va_dates['start']) . " AND " . floatval($va_dates['end']) . ")\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t({$vs_date_start_fld} <= " . floatval($va_dates['start']) . " AND {$vs_date_end_fld} >= " . floatval($va_dates['end']) . ")\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t";
                                     }
                                 }
                                 $pa_direct_sql_query_params = array();
                             }
                         }
                     }
                 }
                 //
                 // 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();
                 }
                 $vs_rel_type_id_sql = null;
                 if (is_array($va_access_point_info['relationship_type_ids']) && sizeof($va_access_point_info['relationship_type_ids'])) {
                     $vs_rel_type_id_sql = " AND (swi.rel_type_id IN (" . join(",", $va_access_point_info['relationship_type_ids']) . "))";
                 }
                 if (!$vs_fld_num && is_array($va_restrict_to_fields = caGetOption('restrictSearchToFields', $pa_options, null)) && sizeof($va_restrict_to_fields)) {
                     $va_field_restrict_sql = array();
                     foreach ($va_restrict_to_fields as $va_restrict) {
                         $va_field_restrict_sql[] = "((swi.field_table_num = " . intval($va_restrict['table_num']) . ") AND (swi.field_num = '" . $va_restrict['field_num'] . "'))";
                     }
                     $vs_sql_where .= " AND (" . join(" OR ", $va_field_restrict_sql) . ")";
                 }
                 $va_join = array();
                 if ($vn_direct_sql_target_table_num != $pn_subject_tablenum) {
                     // We're doing direct queries on metadata in a related table, fun!
                     // Now let's rewrite the direct query to work...
                     if ($t_target = $this->opo_datamodel->getInstanceByTableNum($vn_direct_sql_target_table_num, true)) {
                         // First we create the join from the related table to our subject
                         $vs_target_table_name = $t_target->tableName();
                         $va_path = array_keys($this->opo_datamodel->getPath($vn_direct_sql_target_table_num, $pn_subject_tablenum));
                         $vs_left_table = array_shift($va_path);
                         $vn_cj = 0;
                         foreach ($va_path as $vs_right_table) {
                             if (sizeof($va_rels = $this->opo_datamodel->getRelationships($vs_left_table, $vs_right_table)) > 0) {
                                 $va_join[] = "INNER JOIN {$vs_right_table} ON {$vs_right_table}." . $va_rels[$vs_left_table][$vs_right_table][0][1] . " = " . ($vn_cj == 0 ? 'ca.row_id' : "{$vs_left_table}." . $va_rels[$vs_left_table][$vs_right_table][0][0]);
                             }
                             $vs_left_table = $vs_right_table;
                             $vn_cj++;
                         }
                         // Next we rewrite the key we're pulling to be from our subject
                         $vs_direct_sql_query = str_replace("SELECT ca.row_id", "SELECT " . $this->opo_datamodel->primaryKey($pn_subject_tablenum, true), $vs_direct_sql_query);
                         // Finally we pray
                     }
                 }
                 if ($vn_i == 0) {
                     if ($vs_direct_sql_query) {
                         $vs_direct_sql_query = str_replace('^JOIN', join("\n", $va_join), $vs_direct_sql_query);
                         $vs_sql = "INSERT IGNORE INTO {$ps_dest_table} {$vs_direct_sql_query}";
                         if (strpos($vs_sql, '?') !== false && (!is_array($pa_direct_sql_query_params) || sizeof($pa_direct_sql_query_params) == 0)) {
                             $pa_direct_sql_query_params = array($vn_direct_sql_target_table_num != $pn_subject_tablenum ? $vn_direct_sql_target_table_num : (int) $pn_subject_tablenum);
                         }
                     } else {
                         $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 swi.row_id, SUM(swi.boost)\n\t\t\t\t\t\t\t\tFROM ca_sql_search_word_index swi\n\t\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\t\tWHERE\n\t\t\t\t\t\t\t\t\t{$vs_sql_where}\n\t\t\t\t\t\t\t\t\tAND\n\t\t\t\t\t\t\t\t\tswi.table_num = ?\n\t\t\t\t\t\t\t\t\t{$vs_rel_type_id_sql}\n\t\t\t\t\t\t\t\t\t" . ($this->getOption('omitPrivateIndexing') ? " AND swi.access = 0" : '') . "\n\t\t\t\t\t\t\t\tGROUP BY swi.row_id\n\t\t\t\t\t\t\t";
                         $pa_direct_sql_query_params = array((int) $pn_subject_tablenum);
                     }
                     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}";
                     }
                     $t = new Timer();
                     $pa_direct_sql_query_params = is_array($pa_direct_sql_query_params) ? $pa_direct_sql_query_params : array();
                     if (strpos($vs_sql, '?') === false) {
                         $pa_direct_sql_query_params = array();
                     }
                     $this->opo_db->query($vs_sql, $pa_direct_sql_query_params);
                     $vn_i++;
                     if ($this->debug) {
                         Debug::msg('FIRST: ' . $vs_sql . " [{$pn_subject_tablenum}] " . $t->GetTime(4));
                     }
                 } else {
                     switch ($vs_op) {
                         case 'AND':
                             if ($vs_direct_sql_query) {
                                 if ($vn_direct_sql_target_table_num != $pn_subject_tablenum) {
                                     array_push($va_join, "INNER JOIN {$ps_dest_table} AS ftmp1 ON ftmp1.row_id = " . $this->opo_datamodel->primaryKey($pn_subject_tablenum, true));
                                 } else {
                                     array_unshift($va_join, "INNER JOIN {$ps_dest_table} AS ftmp1 ON ftmp1.row_id = ca.row_id");
                                 }
                                 $vs_direct_sql_query = str_replace('^JOIN', join("\n", $va_join), $vs_direct_sql_query);
                                 $pa_direct_sql_query_params = array($vn_direct_sql_target_table_num != $pn_subject_tablenum ? $vn_direct_sql_target_table_num : (int) $pn_subject_tablenum);
                             }
                             $vs_sql = $vs_direct_sql_query ? "{$vs_direct_sql_query}" : "\n\t\t\t\t\t\t\t\t\tSELECT swi.row_id\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{$vs_rel_type_id_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\tGROUP BY swi.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}";
                             }
                             $t = new Timer();
                             $pa_direct_sql_query_params = is_array($pa_direct_sql_query_params) ? $pa_direct_sql_query_params : array((int) $pn_subject_tablenum);
                             if (strpos($vs_sql, '?') === false) {
                                 $pa_direct_sql_query_params = array();
                             }
                             $qr_res = $this->opo_db->query($vs_sql, $pa_direct_sql_query_params);
                             if ($this->debug) {
                                 Debug::msg('AND: ' . $vs_sql . ' ' . $t->GetTime(4) . ' ' . $qr_res->numRows());
                             }
                             if (is_array($va_ids = $qr_res->getAllFieldValues($vs_direct_sql_query && $vn_direct_sql_target_table_num != $pn_subject_tablenum ? $this->opo_datamodel->primaryKey($pn_subject_tablenum) : 'row_id')) && sizeof($va_ids)) {
                                 $vs_sql = "DELETE FROM {$ps_dest_table} WHERE row_id NOT IN (?)";
                                 $qr_res = $this->opo_db->query($vs_sql, array($va_ids));
                                 if ($this->debug) {
                                     Debug::msg('AND DELETE: ' . $vs_sql . ' ' . $t->GetTime(4));
                                 }
                             } else {
                                 // we don't have any results left, ie. our AND query should yield an empty result
                                 $this->opo_db->query("DELETE FROM {$ps_dest_table}");
                             }
                             $vn_i++;
                             break;
                         case 'NOT':
                             if ($vs_direct_sql_query) {
                                 $vs_direct_sql_query = str_replace('^JOIN', join("\n", $va_join), $vs_direct_sql_query);
                                 $pa_direct_sql_query_params = array($vn_direct_sql_target_table_num != $pn_subject_tablenum ? $vn_direct_sql_target_table_num : (int) $pn_subject_tablenum);
                             }
                             $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{$vs_rel_type_id_sql}\n\t\t\t\t\t\t\t\t\t\t" . ($this->getOption('omitPrivateIndexing') ? " AND swi.access = 0" : '');
                             $pa_direct_sql_query_params = is_array($pa_direct_sql_query_params) ? $pa_direct_sql_query_params : array((int) $pn_subject_tablenum);
                             if (strpos($vs_sql, '?') === false) {
                                 $pa_direct_sql_query_params = array();
                             }
                             $qr_res = $this->opo_db->query($vs_sql, $pa_direct_sql_query_params);
                             $va_ids = $qr_res->getAllFieldValues($vs_direct_sql_query && $vn_direct_sql_target_table_num != $pn_subject_tablenum ? $this->opo_datamodel->primaryKey($pn_subject_tablenum) : 'row_id');
                             if (sizeof($va_ids) > 0) {
                                 $vs_sql = "\n\t\t\t\t\t\t\t\t\t\tDELETE FROM {$ps_dest_table} \n\t\t\t\t\t\t\t\t\t\tWHERE \n\t\t\t\t\t\t\t\t\t\t\trow_id IN (?)\n\t\t\t\t\t\t\t\t\t";
                                 if ($this->debug) {
                                     Debug::msg('NOT ' . $vs_sql);
                                 }
                                 $qr_res = $this->opo_db->query($vs_sql, array($va_ids));
                             }
                             $vn_i++;
                             break;
                         default:
                         case 'OR':
                             if ($vs_direct_sql_query) {
                                 $vs_direct_sql_query = str_replace('^JOIN', join("\n", $va_join), $vs_direct_sql_query);
                                 $pa_direct_sql_query_params = array($vn_direct_sql_target_table_num != $pn_subject_tablenum ? $vn_direct_sql_target_table_num : (int) $pn_subject_tablenum);
                             }
                             $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{$vs_rel_type_id_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\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) {
                                 Debug::msg('OR ' . $vs_sql);
                             }
                             $vn_i++;
                             $pa_direct_sql_query_params = is_array($pa_direct_sql_query_params) ? $pa_direct_sql_query_params : array((int) $pn_subject_tablenum);
                             if (strpos($vs_sql, '?') === false) {
                                 $pa_direct_sql_query_params = array();
                             }
                             $qr_res = $this->opo_db->query($vs_sql, $pa_direct_sql_query_params);
                             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;
         }
     }
 }
Пример #9
0
 /**
  * Options for addTask()
  *
  *	"user_id" 		= user_id to associate task with; leave blank for "nobody" (aka. system)
  *	"priority"		= priority to give task; lower numbers get processed first; default is 10
  *	"entity_key"	= unique identifier for entity task operates on [optional]. Will be stored as md5 hash
  *	"row_key"		= unique identifier for row task operates on. Will be stored as md5 hash
  *	"notes"			= descriptive text for queued task
  *
  */
 function addTask($ps_handler, $pa_parameters, $pa_options)
 {
     #
     # Check user_id
     #
     $vn_user_id = "";
     if (isset($pa_options["user_id"])) {
         $t_user = new ca_users($pa_options["user_id"]);
         $vn_user_id = $t_user->getPrimaryKey();
     }
     $vn_user_id = $vn_user_id ? intval($vn_user_id) : null;
     #
     # Check priority
     #
     $vn_priority = intval($pa_options["priority"]);
     if ($vn_priority < 1 || $vn_priority > 1000) {
         $vn_priority = 10;
     }
     #
     # Convert parameters to array if it is not one already
     #
     if (!is_array($pa_parameters)) {
         $pa_parameters = array($pa_parameters);
     }
     $o_db = new Db();
     $o_db->query("\n\t\t\tINSERT INTO ca_task_queue\n\t\t\t(user_id, entity_key, row_key, created_on, started_on, completed_on, priority, handler, parameters, notes)\n\t\t\tVALUES\n\t\t\t(?, ?, ?, ?, NULL, NULL, ?, ?, ?, ?)\n\t\t", $vn_user_id, md5($pa_options["entity_key"]), md5($pa_options["row_key"]), time(), $vn_priority, $ps_handler, base64_encode(serialize($pa_parameters)), $pa_options["notes"] ? $pa_options["notes"] : '');
     if ($o_db->numErrors()) {
         $this->postError(503, join('; ', $o_db->getErrors()), "TaskQueue->addTask()");
         return false;
     }
     return $o_db->getLastInsertID();
 }
 /**
  * Checkout an object for a user. Will throw an exception if the item is currently out or object or user_id are invalid;
  *
  * @param int $pn_object_id
  * @param int $pn_user_id
  * @param string $ps_note Optional checkin notes
  * @param string $ps_due_date A valid date time expression for the date item is due to be returned. If omitted the default date as configured will be used.
  * @param array $pa_options
  *
  * @return bool True on success, false on failure
  */
 public function checkout($pn_object_id, $pn_user_id, $ps_note = null, $ps_due_date = null, $pa_options = null)
 {
     global $g_ui_locale_id;
     $vb_we_set_transaction = false;
     if ($this->inTransaction()) {
         $o_trans = $this->getTransaction();
     } else {
         $vb_we_set_transaction = true;
         $this->setTransaction($o_trans = new Transaction());
     }
     $o_request = caGetOption('request', $pa_options, null);
     $t_object = new ca_objects($pn_object_id);
     $t_object->setTransaction($o_trans);
     if (!$t_object->getPrimaryKey()) {
         throw new Exception(_t('Object_id is not valid'));
     }
     if ($o_request && !$t_object->isReadable($o_request)) {
         throw new Exception(_t('Object_id is not accessible'));
     }
     $t_user = new ca_users($pn_user_id);
     if (!$t_user->getPrimaryKey()) {
         throw new Exception(_t('User_id is not valid'));
     }
     // is object available?
     if (!in_array($t_object->getCheckoutStatus(), array(__CA_OBJECTS_CHECKOUT_STATUS_AVAILABLE__, __CA_OBJECTS_CHECKOUT_STATUS_RESERVED__))) {
         throw new Exception(_t('Item is already out'));
     }
     // is there a reservation for this user?
     $o_db = $o_trans->getDb();
     $qr_res = $o_db->query("\n\t\t\tSELECT *\n\t\t\tFROM ca_object_checkouts\n\t\t\tWHERE\n\t\t\t\tuser_id = ? AND object_id = ? AND checkout_date IS NULL AND return_date IS NULL\n\t\t\tORDER BY \n\t\t\t\tcreated_on\n\t\t", array($pn_user_id, $pn_object_id));
     $vb_update = false;
     if ($qr_res->nextRow()) {
         $vs_uuid = $qr_res->get('group_uuid');
         if ($this->load($qr_res->get('checkout_id'))) {
             $vb_update = true;
         }
     } else {
         $vs_uuid = $this->getTransactionUUID();
     }
     $va_checkout_config = ca_object_checkouts::getObjectCheckoutConfigForType($t_object->getTypeCode());
     if (!($va_checkout_config['allow_override_of_due_dates'] && $ps_due_date && caDateToUnixTimestamp($ps_due_date))) {
         // calculate default return date
         $ps_due_date = isset($va_checkout_config['default_checkout_date']) ? $va_checkout_config['default_checkout_date'] : null;
     }
     $this->setMode(ACCESS_WRITE);
     $this->set(array('group_uuid' => $vs_uuid, 'object_id' => $pn_object_id, 'user_id' => $pn_user_id, 'checkout_notes' => $ps_note, 'checkout_date' => _t('today'), 'due_date' => $ps_due_date));
     // Do we need to set values?
     if (is_array($va_checkout_config['set_values']) && sizeof($va_checkout_config['set_values'])) {
         $t_object->setMode(ACCESS_WRITE);
         foreach ($va_checkout_config['set_values'] as $vs_attr => $va_attr_values_by_event) {
             if (!is_array($va_attr_values_by_event['checkout'])) {
                 if ($t_object->hasField($vs_attr)) {
                     // Intrinsic
                     $t_object->set($vs_attr, $va_attr_values_by_event['checkout']);
                 }
             } else {
                 $va_attr_values['locale_id'] = $g_ui_locale_id;
                 $t_object->replaceAttribute($va_attr_values_by_event['checkout'], $vs_attr);
             }
             $t_object->update();
             if ($t_object->numErrors()) {
                 $this->errors = $t_object->errors;
                 if ($vb_we_set_transaction) {
                     $o_trans->rollback();
                 }
                 return false;
             }
         }
     }
     $vn_rc = $vb_update ? $this->update() : $this->insert();
     if ($vb_we_set_transaction) {
         $vn_rc ? $o_trans->commit() : $o_trans->rollback();
     }
     return $vn_rc;
 }
Пример #11
0
 /**
  * Returns a display label for a given criterion and facet.
  *
  * @param string $ps_facet_name Name of facet 
  * @param mixed $pm_criterion 
  * @return string
  */
 public function getCriterionLabel($ps_facet_name, $pn_row_id)
 {
     if (!($va_facet_info = $this->getInfoForFacet($ps_facet_name))) {
         return null;
     }
     switch ($va_facet_info['type']) {
         # -----------------------------------------------------
         case 'has':
             $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');
             return (bool) $pn_row_id ? $vs_yes_text : $vs_no_text;
             break;
             # -----------------------------------------------------
         # -----------------------------------------------------
         case 'label':
             if (!($t_table = $this->opo_datamodel->getInstanceByTableName(isset($va_facet_info['relative_to']) && $va_facet_info['relative_to'] ? $va_facet_info['relative_to'] : $this->ops_browse_table_name, true))) {
                 break;
             }
             if (!$t_table->load($pn_row_id)) {
                 return '???';
             }
             return $t_table->getLabelForDisplay();
             break;
             # -----------------------------------------------------
         # -----------------------------------------------------
         case 'authority':
             if (!($t_table = $this->opo_datamodel->getInstanceByTableName($va_facet_info['table'], true))) {
                 break;
             }
             if (!$t_table->load($pn_row_id)) {
                 return '???';
             }
             return $t_table->getLabelForDisplay();
             break;
             # -----------------------------------------------------
         # -----------------------------------------------------
         case 'attribute':
             $t_element = new ca_metadata_elements();
             if (!$t_element->load(array('element_code' => $va_facet_info['element_code']))) {
                 return urldecode($pn_row_id);
             }
             $vn_element_id = $t_element->getPrimaryKey();
             switch ($vn_element_type = $t_element->get('datatype')) {
                 case __CA_ATTRIBUTE_VALUE_LIST__:
                     $t_list = new ca_lists();
                     return $t_list->getItemFromListForDisplayByItemID($t_element->get('list_id'), $pn_row_id, true);
                     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)) {
                         return $t_rel_item->load($pn_row_id) ? $t_rel_item->getLabelForDisplay() : "???";
                     }
                     break;
                 default:
                     return urldecode($pn_row_id);
                     break;
             }
             break;
             # -----------------------------------------------------
         # -----------------------------------------------------
         case 'field':
             if (!($t_item = $this->opo_datamodel->getInstanceByTableName($this->ops_browse_table_name, true))) {
                 break;
             }
             if ($vb_is_bit = $t_item->getFieldInfo($va_facet_info['field'], 'FIELD_TYPE') == FT_BIT) {
                 return (bool) $pn_row_id ? caGetOption('label_yes', $va_facet_info, _t('Yes')) : caGetOption('label_no', $va_facet_info, _t('No'));
             }
             return urldecode($pn_row_id);
             break;
             # -----------------------------------------------------
         # -----------------------------------------------------
         case 'violations':
             if (!($t_rule = $this->opo_datamodel->getInstanceByTableName('ca_metadata_dictionary_rules', true))) {
                 break;
             }
             if ($t_rule->load(array('rule_code' => $pn_row_id))) {
                 return $t_rule->getSetting('label');
             }
             return urldecode($pn_row_id);
             break;
             # -----------------------------------------------------
         # -----------------------------------------------------
         case 'checkouts':
             $vs_status_text = null;
             $vs_status_code = isset($va_facet_info['status']) && $va_facet_info['status'] ? $va_facet_info['status'] : $pn_row_id;
             switch ($vs_status_code) {
                 case 'overdue':
                     $vs_status_text = _t('Overdue');
                     break;
                 case 'reserved':
                     $vs_status_text = _t('Reserved');
                     break;
                 case 'available':
                     $vs_status_text = _t('Available');
                     break;
                 default:
                 case 'out':
                     $vs_status_text = _t('Out');
                     break;
             }
             $va_params = array();
             switch ($va_facet_info['mode']) {
                 case 'user':
                     $vs_name = null;
                     $t_user = new ca_users($pn_row_id);
                     if ($t_user->getPrimaryKey()) {
                         $vs_name = $t_user->get('fname') . ' ' . $t_user->get('lname') . (($vs_email = $t_user->get('email')) ? " ({$vs_email})" : "");
                         return _t('%1 for %2', $vs_status_text, $vs_name);
                     }
                     break;
                 default:
                 case 'all':
                     return $vs_status_text;
                     break;
             }
             return urldecode($pn_row_id);
             break;
             # -----------------------------------------------------
         # -----------------------------------------------------
         case 'location':
             $va_tmp = explode(":", urldecode($pn_row_id));
             $vs_loc_table_name = $this->opo_datamodel->getTableName($va_tmp[0]);
             $va_collapse_map = $this->getCollapseMapForLocationFacet($va_facet_info);
             $t_instance = $this->opo_datamodel->getInstanceByTableName($vs_loc_table_name, true);
             if (($vs_table_name = $vs_loc_table_name) == 'ca_objects_x_storage_locations') {
                 $vs_table_name = 'ca_storage_locations';
             }
             if (isset($va_collapse_map[$vs_table_name][$va_tmp[1]])) {
                 // Class/subclass is collapsable
                 return $va_collapse_map[$vs_table_name][$va_tmp[1]];
             } elseif (isset($va_collapse_map[$vs_table_name]['*'])) {
                 // Class is collapsable
                 return $va_collapse_map[$vs_table_name]['*'];
             } elseif ($va_tmp[2] && ($qr_res = caMakeSearchResult($vs_table_name, array($va_tmp[2]))) && $qr_res->nextHit()) {
                 // Return label for id
                 $va_config = ca_objects::getConfigurationForCurrentLocationType($vs_table_name, $va_tmp[1]);
                 $vs_template = isset($va_config['template']) ? $va_config['template'] : "^{$vs_table_name}.preferred_labels";
                 return caTruncateStringWithEllipsis($qr_res->getWithTemplate($vs_template), 30, 'end');
             }
             return '???';
             break;
             # -----------------------------------------------------
         # -----------------------------------------------------
         case 'normalizedLength':
             $vn_start = urldecode($pn_row_id);
             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');
             $vn_end = $vn_start + $vn_increment_in_current_units;
             return "{$vn_start} {$vs_units} - {$vn_end} {$vs_units}";
             break;
             # -----------------------------------------------------
         # -----------------------------------------------------
         case 'normalizedDates':
             return $pn_row_id === 'null' ? _t('Date unknown') : urldecode($pn_row_id);
             break;
             # -----------------------------------------------------
         # -----------------------------------------------------
         case 'fieldList':
             if (!($t_item = $this->opo_datamodel->getInstanceByTableName($this->ops_browse_table_name, true))) {
                 break;
             }
             $vs_field_name = $va_facet_info['field'];
             $va_field_info = $t_item->getFieldInfo($vs_field_name);
             $t_list = new ca_lists();
             if ($vs_list_name = $va_field_info['LIST_CODE']) {
                 $t_list_item = new ca_list_items($pn_row_id);
                 if ($vs_tmp = $t_list_item->getLabelForDisplay()) {
                     return $vs_tmp;
                 }
                 return '???';
             } else {
                 if ($vs_list_name = $va_field_info['LIST']) {
                     if (is_array($va_list_items = $t_list->getItemsForList($vs_list_name))) {
                         $va_list_items = caExtractValuesByUserLocale($va_list_items);
                         foreach ($va_list_items as $vn_id => $va_list_item) {
                             if ($va_list_item['item_value'] == $pn_row_id) {
                                 return $va_list_item['name_plural'];
                             }
                         }
                     }
                 }
             }
             if (isset($va_field_info['BOUNDS_CHOICE_LIST'])) {
                 $va_choice_list = $va_field_info['BOUNDS_CHOICE_LIST'];
                 if (is_array($va_choice_list)) {
                     foreach ($va_choice_list as $vs_val => $vn_id) {
                         if ($vn_id == $pn_row_id) {
                             return $vs_val;
                         }
                     }
                 }
             }
             if ($va_facet_info['table'] && ($t_browse_table = $this->opo_datamodel->getInstanceByTableName($vs_facet_table = $va_facet_info['table'], true))) {
                 if (!($app = AppController::getInstance())) {
                     return '???';
                 }
                 if ($t_browse_table->load($pn_row_id) && $t_browse_table->isReadable($app->getRequest(), 'preferred_labels')) {
                     return $t_browse_table->get("{$vs_facet_table}.preferred_labels");
                 }
             }
             return '???';
             break;
             # -----------------------------------------------------
         # -----------------------------------------------------
         default:
             if ($ps_facet_name == '_search') {
                 return $pn_row_id;
             }
             return 'Invalid type';
             break;
             # -----------------------------------------------------
     }
 }
Пример #12
0
 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++;
     }
 }
Пример #13
0
 /**
  * Remove current user from one or more groups.
  *
  * @access public
  * @param mixed $pm_groups Single group or list (array) of user_ids to remove from current group. Users must be specified by user_id
  * @return bool Returns true on success, false on error.
  */
 function removeUsers($pm_user_ids)
 {
     if (!is_array($pm_user_ids)) {
         $pm_user_ids = array($pm_user_ids);
     }
     if ($pn_group_id = $this->getPrimaryKey()) {
         $t_user = new ca_users();
         $vn_users_added = 0;
         $va_user_ids = array();
         foreach ($pm_user_ids as $pn_user_id) {
             if (!$t_user->load((int) $pn_user_id)) {
                 continue;
             }
             $va_user_ids[] = intval($t_user->getPrimaryKey());
         }
         if (sizeof($va_user_ids) > 0) {
             $o_db = $this->getDb();
             $o_db->query("\n\t\t\t\t\tDELETE FROM ca_users_x_groups \n\t\t\t\t\tWHERE (group_id = ?) AND (user_id IN (" . join(", ", $va_user_ids) . "))\n\t\t\t\t", (int) $pn_group_id);
             if ($o_db->numErrors()) {
                 $this->postError(936, _t("Database error: %1", join(';', $o_db->getErrors())), "ca_user_groups->removeUsers()");
                 return false;
             } else {
                 return true;
             }
         } else {
             $this->postError(945, _t("No users specified"), "ca_user_groups->removeUsers()");
             return false;
         }
     } else {
         return false;
     }
 }
Пример #14
0
 /**
  * Perform periodic tasks
  *
  * @return boolean true because otherwise it disables subsequent plugins
  */
 public function hookPeriodicTask(&$pa_params)
 {
     global $AUTH_CURRENT_USER_ID;
     $t_log = new Eventlog();
     $o_db = new Db();
     //$t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Could not authenticate to remote system %1', $vs_base_url), 'SOURCE' => 'traveloguePlugin->hookPeriodicTask'));
     // Get new email
     $pn_locale_id = 1;
     // US
     $vs_server = $this->opo_config->get('imap_server');
     $vs_username = $this->opo_config->get('username');
     $vs_password = $this->opo_config->get('password');
     $vs_ssl = $this->opo_config->get('ssl');
     if (!$vs_server) {
         return true;
     }
     if (!$vs_username) {
         return true;
     }
     try {
         $o_mail = new Zend_Mail_Storage_Imap(array('host' => $vs_server, 'user' => $vs_username, 'password' => $vs_password, 'ssl' => $vs_ssl));
     } catch (Exception $e) {
         return true;
     }
     $va_mimetypes = $this->opo_config->getList('mimetypes');
     $va_mail_to_delete = array();
     foreach ($o_mail as $vn_message_num => $o_message) {
         $va_mail_to_delete[$vn_message_num] = true;
         // Extract title from subject line of email
         $vs_subject = $o_message->subject;
         $vs_from = $o_message->headerExists('from') ? $o_message->from : "";
         print "PROCESSING {$vs_subject} FROM {$vs_from}\n";
         // Extract media from email attachments
         // Extract caption from email body
         $va_images = array();
         $va_texts = array();
         foreach (new RecursiveIteratorIterator($o_message) as $o_part) {
             try {
                 if (in_array(strtok($o_part->contentType, ';'), $va_mimetypes)) {
                     $va_images[] = $o_part;
                 } else {
                     if (in_array(strtok($o_part->contentType, ';'), array("text/plain", "text/html"))) {
                         $va_texts[] = (string) $o_part;
                     }
                 }
             } catch (Zend_Mail_Exception $e) {
                 // ignore
             }
         }
         if (!sizeof($va_images)) {
             continue;
         }
         // Get user by email address
         if (preg_match('!<([^>]+)>!', $vs_from, $va_matches)) {
             // extract raw address from "from" header
             $vs_from = $va_matches[1];
         }
         $t_user = new ca_users();
         if ($t_user->load(array('email' => $vs_from))) {
             $AUTH_CURRENT_USER_ID = $vn_user_id = $t_user->getPrimaryKey();
             // force libs to consider matched user as logged in; change log will reflect this name
         } else {
             $vn_user_id = null;
         }
         // Create object
         $t_object = new ca_objects();
         $t_object->setMode(ACCESS_WRITE);
         $t_object->set('type_id', $this->opo_config->get('object_type'));
         // TODO: set idno to autogenerated # and/or allow for configurable policy
         $t_object->set('idno', '');
         $t_object->set('access', $this->opo_config->get('default_access'));
         $t_object->set('status', $this->opo_config->get('default_status'));
         // TODO: make this a configurable mapping ala how media metadata is done
         $t_object->addAttribute(array('locale_id' => $pn_locale_id, 'generalNotes' => join("\n\n", $va_texts)), 'generalNotes');
         $t_object->insert();
         DataMigrationUtils::postError($t_object, "While adding object", "traveloguePlugin");
         // TODO: log this
         $t_object->addLabel(array('name' => $vs_subject), $pn_locale_id, null, true);
         DataMigrationUtils::postError($t_object, "While adding label", "traveloguePlugin");
         // TODO: log this
         // Add representation
         $vs_tmp_file_path = tempnam(caGetTempDirPath(), 'travelogue_');
         foreach ($va_images as $vn_i => $vs_file_content) {
             if (file_put_contents($vs_tmp_file_path, base64_decode((string) $vs_file_content))) {
                 $t_object->addRepresentation($vs_tmp_file_path, $this->opo_config->get('representation_type'), 1, $this->opo_config->get('default_status'), $this->opo_config->get('default_access'), true);
                 DataMigrationUtils::postError($t_object, "While adding media", "traveloguePlugin");
                 // TODO: log this
             }
         }
         // TODO: add option to link user-as-entity to image (probably as creator)
     }
     foreach (array_reverse(array_keys($va_mail_to_delete)) as $vn_message_num) {
         $o_mail->removeMessage($vn_message_num);
     }
     return true;
 }
Пример #15
0
 /**
  * Returns a list of fulfillment events for the currently loaded order
  *
  * @param array $pa_options An array of options (none supported yet)
  * @return array A list of arrays, each containing information about a specific fulfillment event. The list is ordered by date/time starting with the oldest event.
  */
 public function getFulfillmentLog($pa_options = null)
 {
     if (!($vn_order_id = $this->getPrimaryKey())) {
         return null;
     }
     $o_db = $this->getDb();
     $qr_res = $o_db->query("\n\t\t\tSELECT e.*, i.*, o.idno item_idno\n\t\t\tFROM ca_commerce_fulfillment_events e \n\t\t\tINNER JOIN ca_commerce_order_items AS i ON i.item_id = e.item_id\n\t\t\tINNER JOIN ca_objects AS o ON o.object_id = i.object_id\n\t\t\tWHERE \n\t\t\t\te.order_id = ?\n\t\t\tORDER BY e.occurred_on\n\t\t", (int) $vn_order_id);
     $t_object = new ca_objects();
     $va_labels = $t_object->getPreferredDisplayLabelsForIDs($qr_res->getAllFieldValues("object_id"));
     $t_item = new ca_commerce_order_items();
     $va_events = array();
     $qr_res->seek(0);
     $va_user_cache = array();
     while ($qr_res->nextRow()) {
         $va_row = $qr_res->getRow();
         $va_row['fulfillment_details'] = caUnserializeForDatabase($va_row['fulfillment_details']);
         $va_row['item_label'] = $va_labels[$va_row['object_id']];
         $va_row['fulfillment_method_display'] = $t_item->getChoiceListValue('fullfillment_method', $va_row['fullfillment_method']);
         $va_row['service_display'] = $t_item->getChoiceListValue('service', $va_row['service']);
         if ($vn_user_id = (int) $va_row['fulfillment_details']['user_id']) {
             if (!isset($va_user_cache[$vn_user_id])) {
                 $t_user = new ca_users($vn_user_id);
                 if ($t_user->getPrimaryKey()) {
                     $va_user_cache[$vn_user_id] = array('fname' => $t_user->get('fname'), 'lname' => $t_user->get('lname'), 'email' => $t_user->get('email'));
                 } else {
                     $va_user_cache[$vn_user_id] = null;
                 }
             }
             if (is_array($va_user_cache[$vn_user_id])) {
                 $va_row = array_merge($va_row, $va_user_cache[$vn_user_id]);
             }
         }
         $va_events[] = $va_row;
     }
     return $va_events;
 }
Пример #16
0
 public function userCanAccess($pn_user_id, $pa_module_path, $ps_controller, $ps_action, $pa_fake_parameters = array())
 {
     if (!$this->opo_acr_config->get("enforce_access_restrictions")) {
         // admin doesn't want us to enforce any restrictions
         return true;
     }
     if (!$this->opo_request) {
         // there is no "real" request, i.e. we're running a CLI script or something
         // we need some context information from the request to determine if a user
         // can access something though -> always return false here!
         return false;
     }
     if ($this->opt_user->getPrimaryKey() != $pn_user_id) {
         $this->opt_user->load($pn_user_id);
     }
     if ($this->opt_user->canDoAction("is_administrator")) {
         // almighty admin!
         return true;
     }
     $va_groups_to_check = array();
     // check module components
     if (!is_array($pa_module_path)) {
         $pa_module_path = explode("/", $pa_module_path);
     }
     if (is_array($pa_module_path)) {
         $va_modules_to_check = array();
         foreach ($pa_module_path as $vs_module) {
             $va_modules_to_check[] = $vs_module;
             $vs_module_part_path = join("/", $va_modules_to_check);
             if (is_array($this->opa_acr[$vs_module_part_path])) {
                 foreach ($this->opa_acr[$vs_module_part_path] as $va_group) {
                     $va_groups_to_check[] = $va_group;
                 }
             }
         }
     }
     // check controller
     $vs_controller_path = join("/", is_array($pa_module_path) ? $pa_module_path : array()) . "/" . ucfirst($ps_controller) . 'Controller';
     if (is_array($this->opa_acr[$vs_controller_path])) {
         foreach ($this->opa_acr[$vs_controller_path] as $va_group) {
             $va_groups_to_check[] = $va_group;
         }
     }
     // check action
     $vs_action_path = join("/", is_array($pa_module_path) ? $pa_module_path : array()) . "/" . ucfirst($ps_controller) . "Controller/" . $ps_action;
     if (is_array($this->opa_acr[$vs_action_path])) {
         foreach ($this->opa_acr[$vs_action_path] as $va_group) {
             $va_groups_to_check[] = $va_group;
         }
     }
     // check rules
     foreach ($va_groups_to_check as $va_group) {
         if (!is_array($va_group) || !is_array($va_group["actions"])) {
             continue;
         }
         // group without action restrictions
         $vb_group_passed = false;
         // check if parameter restrictions apply
         if (is_array($va_group["parameters"])) {
             if (!$this->_parameterRestrictionsApply($va_group["parameters"], $ps_controller, $ps_action, $pa_fake_parameters)) {
                 continue;
                 // auto-pass
             }
         }
         if (isset($va_group["operator"]) && $va_group["operator"] == "OR") {
             // OR
             foreach ($va_group["actions"] as $vs_action) {
                 if ($this->opt_user->canDoAction($vs_action)) {
                     $vb_group_passed = true;
                     break;
                 }
             }
         } else {
             // AND
             foreach ($va_group["actions"] as $vs_action) {
                 if (!$this->opt_user->canDoAction($vs_action)) {
                     return false;
                 }
             }
             $vb_group_passed = true;
             // passed all AND-ed conditions
         }
         if (!$vb_group_passed) {
             // one has to pass ALL groups!
             return false;
         }
     }
     return true;
     // all groups passed
 }
Пример #17
0
 /**
  * Duplicate all items in this set
  * @param int $pn_user_id
  * @param array $pa_options
  * @return ca_sets|bool
  */
 public function duplicateItemsInSet($pn_user_id, $pa_options = array())
 {
     if (!$this->getPrimaryKey()) {
         return false;
     }
     if ($this->getItemCount() < 1) {
         return false;
     }
     $t_user = new ca_users($pn_user_id);
     if (!$t_user->getPrimaryKey()) {
         return false;
     }
     // we need a user for duplication
     global $g_ui_locale_id;
     if (caGetOption('addToCurrentSet', $pa_options, false)) {
         $t_set_to_add_dupes_to = $this;
     } else {
         // create new set for dupes
         $t_set_to_add_dupes_to = new ca_sets();
         $t_set_to_add_dupes_to->set('type_id', $this->get('type_id'));
         $t_set_to_add_dupes_to->set('table_num', $this->get('table_num'));
         $t_set_to_add_dupes_to->set('user_id', $this->get('user_id'));
         $t_set_to_add_dupes_to->set('set_code', $this->get('set_code') . '-' . _t('dupes'));
         $t_set_to_add_dupes_to->setMode(ACCESS_WRITE);
         $t_set_to_add_dupes_to->insert();
         if (!$t_set_to_add_dupes_to->getPrimaryKey()) {
             $this->errors = $t_set_to_add_dupes_to->errors;
             return false;
         }
         $t_set_to_add_dupes_to->addLabel(array('name' => $this->getLabelForDisplay() . ' ' . _t('[Duplicates]')), $g_ui_locale_id, null, true);
     }
     $va_items = array_keys($this->getItemRowIDs());
     $va_dupes = array();
     foreach ($va_items as $vn_row_id) {
         /** @var BundlableLabelableBaseModelWithAttributes $t_instance */
         $t_instance = $this->getAppDatamodel()->getInstance($this->get('table_num'));
         if (!$t_user->canDoAction('can_duplicate_' . $t_instance->tableName())) {
             $this->postError(2580, _t('You do not have permission to duplicate these items'), 'ca_sets->duplicateItemsInSet()');
             return false;
         }
         if (!$t_instance->load($vn_row_id)) {
             continue;
         }
         // let's dupe
         $t_dupe = $t_instance->duplicate(array('user_id' => $pn_user_id, 'duplicate_nonpreferred_labels' => $t_user->getPreference($t_instance->tableName() . '_duplicate_nonpreferred_labels'), 'duplicate_attributes' => $t_user->getPreference($t_instance->tableName() . '_duplicate_attributes'), 'duplicate_relationships' => $t_user->getPreference($t_instance->tableName() . '_duplicate_relationships'), 'duplicate_media' => $t_user->getPreference($t_instance->tableName() . '_duplicate_media'), 'duplicate_subitems' => $t_user->getPreference($t_instance->tableName() . '_duplicate_subitems')));
         if ($t_dupe instanceof BaseModel) {
             $va_dupes[] = $t_dupe->getPrimaryKey();
         }
     }
     $t_set_to_add_dupes_to->addItems($va_dupes);
     return $t_set_to_add_dupes_to;
 }
 /**
  *
  */
 public function CreateNewOrderFromCommunication()
 {
     if ($pn_communication_id = $this->request->getParameter('communication_id', pInteger)) {
         $t_comm = new ca_commerce_communications($pn_communication_id);
         if (!$t_comm->getPrimaryKey()) {
             $this->notification->addNotification(_t('Invalid message'), __NOTIFICATION_TYPE_ERROR__);
             $this->CustomerInfo();
             return;
         }
         $t_trans = new ca_commerce_transactions($t_comm->get('transaction_id'));
         if (!$t_trans->getPrimaryKey()) {
             $this->notification->addNotification(_t('Message is not associated with a transaction'), __NOTIFICATION_TYPE_ERROR__);
             $this->CustomerInfo();
             return;
         }
         $t_user = new ca_users($t_trans->get('user_id'));
         $this->opt_order->setMode(ACCESS_WRITE);
         $this->opt_order->set('transaction_id', $t_trans->getPrimaryKey());
         if ($t_user->getPrimaryKey()) {
             $this->opt_order->set('billing_fname', $t_user->get('fname'));
             $this->opt_order->set('billing_lname', $t_user->get('lname'));
             $this->opt_order->set('billing_email', $t_user->get('email'));
             $this->opt_order->set('shipping_fname', $t_user->get('fname'));
             $this->opt_order->set('shipping_lname', $t_user->get('lname'));
             $this->opt_order->set('shipping_email', $t_user->get('email'));
             // Pre-populate order with user's profile address
             $va_mapping = array('billing_organization' => 'user_profile_organization', 'billing_address1' => 'user_profile_address1', 'billing_address2' => 'user_profile_address2', 'billing_city' => 'user_profile_city', 'billing_zone' => 'user_profile_state', 'billing_postal_code' => 'user_profile_postalcode', 'billing_country' => 'user_profile_country', 'billing_phone' => 'user_profile_phone', 'billing_fax' => 'user_profile_fax', 'shipping_organization' => 'user_profile_organization', 'shipping_address1' => 'user_profile_address1', 'shipping_address2' => 'user_profile_address2', 'shipping_city' => 'user_profile_city', 'shipping_zone' => 'user_profile_state', 'shipping_postal_code' => 'user_profile_postalcode', 'shipping_country' => 'user_profile_country', 'shipping_phone' => 'user_profile_phone', 'shipping_fax' => 'user_profile_fax');
             foreach ($va_mapping as $vs_field => $vs_pref) {
                 $this->opt_order->set($vs_field, $t_user->getPreference($vs_pref));
             }
         }
         $this->opt_order->set('order_type', 'L');
         // L=loan
         $this->opt_order->insert();
         $this->request->setParameter('order_id', $this->opt_order->getPrimaryKey());
         if (!$this->opt_order->numErrors()) {
             $this->notification->addNotification(_t('Saved changes'), __NOTIFICATION_TYPE_INFO__);
             // Add items
             $t_set = new ca_sets($t_trans->get('set_id'));
             if ($t_set->getPrimaryKey()) {
                 $va_items = $t_set->getItems();
                 foreach ($va_items as $va_item_list) {
                     foreach ($va_item_list as $vn_i => $va_item) {
                         if (!is_array($va_item['selected_services'])) {
                             //$va_item['selected_services'] = array('DIGITAL_COPY');	// TODO: make default configurable
                         }
                         foreach ($va_item['selected_services'] as $vs_service) {
                             if ($t_item = $this->opt_order->addItem($va_item['row_id'], array('service' => $vs_service), array('representations_ids' => is_array($va_item['selected_representations']) && sizeof($va_item['selected_representations']) ? $va_item['selected_representations'] : null))) {
                                 $t_item->updateFee();
                             }
                         }
                     }
                 }
                 // Delete originating set if configured to do so
                 if ($this->opo_client_services_config->get('set_disposal_policy') == 'DELETE_WHEN_ORDER_CREATED') {
                     $t_set->setMode(ACCESS_WRITE);
                     $t_set->delete(true);
                 }
             }
         } else {
             $va_errors['general'] = $this->opt_order->errors();
             $this->notification->addNotification(_t('Errors occurred: %1', join('; ', $this->opt_order->getErrors())), __NOTIFICATION_TYPE_ERROR__);
         }
         $this->view->setVar('errors', $va_errors);
     }
     $this->OrderOverview();
 }
Пример #19
0
/**
 * 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;
}
Пример #20
0
 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);
 }
Пример #21
0
 /**
  * Checks access control list for the specified row and 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_table_num The table number for the row to check
  * @param int $pn_row_id The primary key value for the row to check.
  * @return int An access value 
  */
 public static function accessForRow($t_user, $pn_table_num, $pn_row_id)
 {
     if (!is_object($t_user)) {
         $t_user = new ca_users();
     }
     $o_db = new Db();
     $vn_user_id = (int) $t_user->getPrimaryKey();
     if (isset(ca_acl::$s_acl_access_value_cache[$vn_user_id][$pn_table_num][$pn_row_id])) {
         return ca_acl::$s_acl_access_value_cache[$vn_user_id][$pn_table_num][$pn_row_id];
     }
     $vn_access = null;
     // try to load ACL for user
     if ($vn_user_id) {
         $qr_res = $o_db->query("\n\t\t\t\tSELECT max(access) a\n\t\t\t\tFROM ca_acl\n\t\t\t\tWHERE\n\t\t\t\t\ttable_num = ? AND row_id = ? AND user_id = ?\n\t\t\t\t\t\n\t\t\t", (int) $pn_table_num, (int) $pn_row_id, $vn_user_id);
         if ($qr_res->nextRow()) {
             if (strlen($vs_access = $qr_res->get('a'))) {
                 $vn_access = (int) $vs_access;
                 if ($vn_access >= __CA_ACL_EDIT_DELETE_ACCESS__) {
                     return ca_acl::$s_acl_access_value_cache[$vn_user_id][$pn_table_num][$pn_row_id] = $vn_access;
                 }
                 // max access found so just return
             }
         }
         $va_groups = $t_user->getUserGroups();
         if (is_array($va_groups)) {
             $va_group_ids = array_keys($va_groups);
             if (is_array($va_group_ids) && sizeof($va_group_ids) > 0) {
                 $qr_res = $o_db->query("\n\t\t\t\t\t\tSELECT max(access) a \n\t\t\t\t\t\tFROM ca_acl\n\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\ttable_num = ? AND row_id = ? AND group_id IN (?)\n\t\t\t\t\t\t\t\n\t\t\t\t\t", (int) $pn_table_num, (int) $pn_row_id, $va_group_ids);
                 if ($qr_res->nextRow()) {
                     if (strlen($vs_access = $qr_res->get('a'))) {
                         $vn_acl_access = (int) $vs_access;
                         if ($vn_acl_access >= $vn_access) {
                             $vn_access = $vn_acl_access;
                         }
                         if ($vn_access >= __CA_ACL_EDIT_DELETE_ACCESS__) {
                             return ca_acl::$s_acl_access_value_cache[$vn_user_id][$pn_table_num][$pn_row_id] = $vn_access;
                         }
                         // max access found so just return
                     }
                 }
             }
         }
     }
     // Get world access
     $qr_res = $o_db->query("\n\t\t\tSELECT max(access) a \n\t\t\tFROM ca_acl\n\t\t\tWHERE\n\t\t\t\ttable_num = ? AND row_id = ? AND group_id IS NULL AND user_id IS NULL\n\t\t\t\t\n\t\t", (int) $pn_table_num, (int) $pn_row_id);
     if ($qr_res->nextRow()) {
         if (strlen($vs_access = $qr_res->get('a')) && (int) $vs_access >= $vn_access) {
             return ca_acl::$s_acl_access_value_cache[$vn_user_id][$pn_table_num][$pn_row_id] = (int) $vs_access;
         }
     }
     if (!is_null($vn_access)) {
         return ca_acl::$s_acl_access_value_cache[$vn_user_id][$pn_table_num][$pn_row_id] = $vn_access;
     }
     // If no ACL exists return default
     $o_config = Configuration::load();
     return ca_acl::$s_acl_access_value_cache[$vn_user_id][$pn_table_num][$pn_row_id] = (int) $o_config->get('default_item_access_level');
 }
 public function Save()
 {
     // Field to user profile preference mapping
     $va_mapping = array('billing_organization' => 'user_profile_organization', 'billing_address1' => 'user_profile_address1', 'billing_address2' => 'user_profile_address2', 'billing_city' => 'user_profile_city', 'billing_zone' => 'user_profile_state', 'billing_postal_code' => 'user_profile_postalcode', 'billing_country' => 'user_profile_country', 'billing_phone' => 'user_profile_phone', 'billing_fax' => 'user_profile_fax', 'shipping_organization' => 'user_profile_organization', 'shipping_address1' => 'user_profile_address1', 'shipping_address2' => 'user_profile_address2', 'shipping_city' => 'user_profile_city', 'shipping_zone' => 'user_profile_state', 'shipping_postal_code' => 'user_profile_postalcode', 'shipping_country' => 'user_profile_country', 'shipping_phone' => 'user_profile_phone', 'shipping_fax' => 'user_profile_fax');
     $va_errors = array();
     $va_failed_insert_list = array();
     $va_fields = $this->opt_order->getFormFields();
     foreach ($va_fields as $vs_f => $va_field_info) {
         switch ($vs_f) {
             case 'transaction_id':
                 // noop
                 break;
             default:
                 if (isset($_REQUEST[$vs_f])) {
                     if (!$this->opt_order->set($vs_f, $this->request->getParameter($vs_f, pString))) {
                         $va_errors[$vs_f] = $this->opt_order->errors();
                     }
                 }
                 break;
         }
     }
     // Set additional fees for order
     $va_fees = $this->opo_client_services_config->getAssoc('additional_order_fees');
     if (is_array($va_fees)) {
         if (!is_array($va_fee_values = $this->opt_order->get('additional_fees'))) {
             $va_fee_values = array();
         }
         foreach ($va_fees as $vs_code => $va_info) {
             $va_fee_values[$vs_code] = (double) $this->request->getParameter("additional_fee_{$vs_code}", pString);
         }
         $this->opt_order->set('additional_fees', $va_fee_values);
     }
     $this->opt_order->setMode(ACCESS_WRITE);
     if ($this->opt_order->getPrimaryKey()) {
         $this->opt_order->update();
         $vn_transaction_id = $this->opt_order->get('transaction_id');
     } else {
         // Set transaction
         if (!($vn_transaction_id = $this->request->getParameter('transaction_id', pInteger))) {
             if (!($vn_user_id = $this->request->getParameter('transaction_user_id', pInteger))) {
                 if ($vs_user_name = $this->request->getParameter('billing_email', pString)) {
                     // Try to create user in-line
                     $t_user = new ca_users();
                     if ($t_user->load(array('user_name' => $vs_user_name))) {
                         if ($t_user->get('active') == 1) {
                             // user is active - if not active don't use
                             if ($t_user->get('userclass') == 255) {
                                 // user is deleted
                                 $t_user->setMode(ACCESS_WRITE);
                                 $t_user->set('userclass', 1);
                                 // 1=public user (no back-end login)
                                 $t_user->update();
                                 if ($t_user->numErrors()) {
                                     $this->notification->addNotification(_t('Errors occurred when undeleting user: %1', join('; ', $t_user->getErrors())), __NOTIFICATION_TYPE_ERROR__);
                                 } else {
                                     $vn_user_id = $t_user->getPrimaryKey();
                                 }
                             } else {
                                 $vn_user_id = $t_user->getPrimaryKey();
                             }
                         } else {
                             $t_user->setMode(ACCESS_WRITE);
                             $t_user->set('active', 1);
                             $t_user->set('userclass', 1);
                             // 1=public user (no back-end login)
                             $t_user->update();
                             if ($t_user->numErrors()) {
                                 $this->notification->addNotification(_t('Errors occurred when reactivating user: %1', join('; ', $t_user->getErrors())), __NOTIFICATION_TYPE_ERROR__);
                             } else {
                                 $vn_user_id = $t_user->getPrimaryKey();
                             }
                         }
                     } else {
                         $t_user->setMode(ACCESS_WRITE);
                         $t_user->set('user_name', $vs_user_name);
                         $t_user->set('password', $vs_password = substr(md5(uniqid(microtime())), 0, 6));
                         $t_user->set('userclass', 1);
                         // 1=public user (no back-end login)
                         $t_user->set('fname', $vs_fname = $this->request->getParameter('billing_fname', pString));
                         $t_user->set('lname', $vs_lname = $this->request->getParameter('billing_lname', pString));
                         $t_user->set('email', $vs_user_name);
                         $t_user->insert();
                         if ($t_user->numErrors()) {
                             $this->notification->addNotification(_t('Errors occurred when creating new user: %1', join('; ', $t_user->getErrors())), __NOTIFICATION_TYPE_ERROR__);
                         } else {
                             $vn_user_id = $t_user->getPrimaryKey();
                             $this->notification->addNotification(_t('Created new client login for <em>%1</em>. Login name is <em>%2</em> and password is <em>%3</em>', $vs_fname . ' ' . $vs_lname, $vs_user_name, $vs_password), __NOTIFICATION_TYPE_INFO__);
                             // Create related entity?
                         }
                     }
                 }
             }
             if ($vn_user_id) {
                 // try to create transaction
                 $t_trans = new ca_commerce_transactions();
                 $t_trans->setMode(ACCESS_WRITE);
                 $t_trans->set('user_id', $vn_user_id);
                 $t_trans->set('short_description', "Created on " . date("c"));
                 $t_trans->set('set_id', null);
                 $t_trans->insert();
                 if ($t_trans->numErrors()) {
                     $this->notification->addNotification(_t('Errors occurred when creating commerce transaction: %1', join('; ', $t_trans->getErrors())), __NOTIFICATION_TYPE_ERROR__);
                 } else {
                     $vn_transaction_id = $t_trans->getPrimaryKey();
                 }
             } else {
                 $this->notification->addNotification(_t('You must specify a client'), __NOTIFICATION_TYPE_ERROR__);
                 $va_errors['general'][] = new Error(1100, _t('You must specify a client'), 'CheckOutController->Save()', false, false, false);
             }
         }
         $this->opt_order->set('transaction_id', $vn_transaction_id);
         if ($vn_transaction_id) {
             $this->opt_order->set('order_type', 'L');
             // L = loan (as opposed to 'O' for sales orders)
             $this->opt_order->set('order_status', 'OPEN');
             $this->opt_order->insert();
             $this->request->setParameter('order_id', $x = $this->opt_order->getPrimaryKey());
         }
     }
     if ($vn_transaction_id) {
         // set user profile if not already set
         $t_trans = new ca_commerce_transactions($vn_transaction_id);
         $t_user = new ca_users($t_trans->get('user_id'));
         $t_user->setMode(ACCESS_WRITE);
         foreach ($va_mapping as $vs_field => $vs_pref) {
             if (!strlen($t_user->getPreference($vs_pref))) {
                 $t_user->setPreference($vs_pref, $this->opt_order->get($vs_field));
             }
         }
         $t_user->update();
         $va_additional_fee_codes = $this->opo_client_services_config->getAssoc('additional_loan_fees');
         // Look for newly added items
         $vn_items_added = 0;
         $vn_item_errors = 0;
         $vs_errors = '';
         foreach ($_REQUEST as $vs_k => $vs_v) {
             if (preg_match("!^item_list_idnew_([\\d]+)\$!", $vs_k, $va_matches)) {
                 if ($vn_object_id = (int) $vs_v) {
                     // add item to order
                     $va_values = array();
                     foreach ($_REQUEST as $vs_f => $vs_value) {
                         if (preg_match("!^item_list_([A-Za-z0-9_]+)_new_" . $va_matches[1] . "\$!", $vs_f, $va_matches2)) {
                             $va_values[$va_matches2[1]] = $vs_value;
                         }
                     }
                     // Set additional fees
                     //
                     $va_fee_values = array();
                     foreach ($va_additional_fee_codes as $vs_code => $va_info) {
                         $va_fee_values[$vs_code] = $_REQUEST['additional_order_item_fee_' . $vs_code . '_new_' . $va_matches[1]];
                     }
                     $t_item = $this->opt_order->addItem($vn_object_id, $va_values, array('additional_fees' => $va_fee_values));
                     if ($t_item && $t_item->getPrimaryKey()) {
                         $vn_items_added++;
                     } else {
                         if ($this->opt_order->numErrors()) {
                             $t_object = new ca_objects($vn_object_id);
                             $this->notification->addNotification(_t('Could not check-out item <em>%1</em> (%2) due to errors: %3', $t_object->get('ca_objects.preferred_labels.name'), $t_object->get('idno'), join("; ", $this->opt_order->getErrors())), __NOTIFICATION_TYPE_ERROR__);
                             $vn_item_errors++;
                             $va_fee_values_proc = array();
                             foreach ($va_fee_values as $vs_k => $vs_v) {
                                 $va_fee_values_proc['ADDITIONAL_FEE_' . $vs_k] = $vs_v;
                             }
                             $va_failed_insert_list[] = array_merge($va_values, $va_fee_values_proc, array('autocomplete' => $_REQUEST['item_list_autocompletenew_' . $va_matches[1]], 'id' => $vn_object_id));
                         }
                     }
                 }
             }
         }
         if (!$this->opt_order->numErrors() && $vn_items_added) {
             $this->notification->addNotification(_t('Checked out %1 %2 for %3 (order %4)', $vn_items_added, $vn_items_added == 1 ? _t('item') : _t('items'), $t_user->get('fname') . ' ' . $t_user->get('lname'), $this->opt_order->getOrderNumber()), __NOTIFICATION_TYPE_INFO__);
             $this->opt_order->set('order_status', 'PROCESSED');
             $this->opt_order->update();
             $this->opt_order = new ca_commerce_orders();
             $this->request->setParameter('order_id', null);
             $this->view->setVar('t_order', $this->opt_order);
             $this->view->setVar('order_id', $this->opt_order->getPrimaryKey());
             $this->view->setVar('t_item', $this->opt_order);
         } else {
             if ($vn_items_added == 0 && $this->opt_order->numErrors() == 0) {
                 $vs_errors = _t('No items were specified');
             } else {
                 if ($vn_item_errors == 0) {
                     $vs_errors = join('; ', $this->opt_order->getErrors());
                 }
             }
             if ($vs_errors) {
                 $va_errors['general'] = $this->opt_order->errors();
                 $this->notification->addNotification(_t('Errors occurred: %1', $vs_errors), __NOTIFICATION_TYPE_ERROR__);
             }
         }
     }
     $this->view->setVar('errors', $va_errors);
     $this->view->setVar('failed_insert_list', $va_failed_insert_list);
     $this->Index();
 }
Пример #23
0
/**
 * 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 int $pn_id The primary key value of the row
 * @param string $ps_bundle_name An optional bundle to check access for
 *
 * @return True if user has read access, otherwise false if the user does not have access or null if one or more parameters are invalid
 */
function caCanRead($pn_user_id, $pm_table, $pn_id, $ps_bundle_name = null)
{
    $o_dm = Datamodel::load();
    $ps_table_name = is_numeric($pm_table) ? $o_dm->getTableName($pm_table) : $pm_table;
    if (!($t_instance = $o_dm->getInstanceByTableName($ps_table_name, true))) {
        return null;
    }
    if (!$t_instance->load($pn_id)) {
        return null;
    }
    $t_user = new ca_users($pn_user_id);
    if (!$t_user->getPrimaryKey()) {
        return null;
    }
    list($ps_table_name, $ps_bundle_name) = caTranslateBundlesForAccessChecking($ps_table_name, $ps_bundle_name);
    // Check type restrictions
    if ((bool) $t_instance->getAppConfig()->get('perform_type_access_checking')) {
        $vn_type_access = $t_user->getTypeAccessLevel($ps_table_name, $t_instance->getTypeID());
        if ($vn_type_access < __CA_BUNDLE_ACCESS_READONLY__) {
            return false;
        }
    }
    // Check item level restrictions
    if ((bool) $t_instance->getAppConfig()->get('perform_item_level_access_checking')) {
        $vn_item_access = $t_instance->checkACLAccessForUser($t_user);
        if ($vn_item_access < __CA_ACL_READONLY_ACCESS__) {
            return false;
        }
    }
    if ($ps_bundle_name) {
        if ($t_user->getBundleAccessLevel($ps_table_name, $ps_bundle_name) < __CA_BUNDLE_ACCESS_READONLY__) {
            return false;
        }
    }
    return true;
}
Пример #24
0
 public function search($pn_subject_tablenum, $ps_search_expression, $pa_filters = array(), $po_rewritten_query = null)
 {
     $t = new Timer();
     $va_solr_search_filters = array();
     $vn_i = 0;
     $va_old_signs = $po_rewritten_query->getSigns();
     $va_terms = $va_signs = array();
     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';
         }
         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':
                 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 = $vs_field;
                                 } else {
                                     $vs_fld_num = $this->opo_datamodel->getFieldNum($vs_table, $vs_field);
                                     if (!$vs_fld_num) {
                                         $t_element = new ca_metadata_elements();
                                         if ($t_element->load(array('element_code' => $vs_sub_field ? $vs_sub_field : $vs_field))) {
                                             $vs_fld_num = $t_element->getPrimaryKey();
                                             //
                                             // 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_access_point));
                                                         }
                                                     } 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_access_point));
                                                         }
                                                     }
                                                     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_access_point));
                                                     }
                                                     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_access_point));
                                                     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_access_point));
                                                     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_access_point));
                                                     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_access_point));
                                                     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_access_point));
                                                     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_access_point));
                                                     break;
                                             }
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
                 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 ($vs_filter_query = $this->_filterValueToQueryValue($pa_filters)) {
         $ps_search_expression .= ' AND (' . $vs_filter_query . ')';
     }
     $vo_http_client = new Zend_Http_Client();
     $vo_http_client->setUri($this->opo_search_config->get('search_elasticsearch_base_url') . "/" . $this->opo_search_config->get('search_elasticsearch_index_name') . "/" . $this->opo_datamodel->getTableName($pn_subject_tablenum) . "/" . "_search");
     $vo_http_client->setParameterGet(array('size' => intval($this->opa_options["limit"]), 'q' => $ps_search_expression));
     $vo_http_response = $vo_http_client->request();
     $va_result = json_decode($vo_http_response->getBody(), true);
     return new WLPlugSearchEngineElasticSearchResult($va_result["hits"]["hits"], $pn_subject_tablenum);
 }
Пример #25
0
 /**
  * Checks access control list for the specified row and 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_table_num The table number for the row to check
  * @param int $pn_row_id The primary key value for the row to check.
  * @return int An access value 
  */
 public static function accessForRow($t_user, $pn_table_num, $pn_row_id)
 {
     if (!is_object($t_user)) {
         $t_user = new ca_users();
     }
     $o_db = new Db();
     $vn_user_id = (int) $t_user->getPrimaryKey();
     if (isset(ca_acl::$s_acl_access_value_cache[$vn_user_id][$pn_table_num][$pn_row_id])) {
         return ca_acl::$s_acl_access_value_cache[$vn_user_id][$pn_table_num][$pn_row_id];
     }
     $vn_access = null;
     // try to load ACL for user
     if ($vn_user_id) {
         $qr_res = $o_db->query("\n\t\t\t\tSELECT max(access) a\n\t\t\t\tFROM ca_acl\n\t\t\t\tWHERE\n\t\t\t\t\ttable_num = ? AND row_id = ? AND user_id = ?\n\t\t\t\t\t\n\t\t\t", (int) $pn_table_num, (int) $pn_row_id, $vn_user_id);
         if ($qr_res->nextRow()) {
             if (strlen($vs_access = $qr_res->get('a'))) {
                 $vn_access = (int) $vs_access;
                 if ($vn_access >= __CA_ACL_EDIT_DELETE_ACCESS__) {
                     return ca_acl::$s_acl_access_value_cache[$vn_user_id][$pn_table_num][$pn_row_id] = $vn_access;
                 }
                 // max access found so just return
             }
         }
         // user group acls
         $va_groups = $t_user->getUserGroups();
         if (is_array($va_groups)) {
             $va_group_ids = array_keys($va_groups);
             if (is_array($va_group_ids) && sizeof($va_group_ids) > 0) {
                 $qr_res = $o_db->query("\n\t\t\t\t\t\tSELECT max(access) a \n\t\t\t\t\t\tFROM ca_acl\n\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\ttable_num = ? AND row_id = ? AND group_id IN (?)\n\t\t\t\t\t\t\t\n\t\t\t\t\t", (int) $pn_table_num, (int) $pn_row_id, $va_group_ids);
                 if ($qr_res->nextRow()) {
                     if (strlen($vs_access = $qr_res->get('a'))) {
                         $vn_acl_access = (int) $vs_access;
                         if ($vn_acl_access >= $vn_access) {
                             $vn_access = $vn_acl_access;
                         }
                         if ($vn_access >= __CA_ACL_EDIT_DELETE_ACCESS__) {
                             return ca_acl::$s_acl_access_value_cache[$vn_user_id][$pn_table_num][$pn_row_id] = $vn_access;
                         }
                         // max access found so just return
                     }
                 }
             }
         }
         // exceptions trump global access and the config setting so if we found some ACLs for either
         // the user or one of their groups, we use the maximum access value from that list of ACLs
         if (!is_null($vn_access)) {
             return $vn_access;
         }
     }
     // If no valid exceptions found, get world access for this item
     $qr_res = $o_db->query("\n\t\t\tSELECT max(access) a \n\t\t\tFROM ca_acl\n\t\t\tWHERE\n\t\t\t\ttable_num = ? AND row_id = ? AND group_id IS NULL AND user_id IS NULL\n\t\t\t\t\n\t\t", (int) $pn_table_num, (int) $pn_row_id);
     if ($qr_res->nextRow()) {
         if (strlen($vs_access = $qr_res->get('a')) && (int) $vs_access >= $vn_access) {
             return ca_acl::$s_acl_access_value_cache[$vn_user_id][$pn_table_num][$pn_row_id] = (int) $vs_access;
         }
     }
     if (!is_null($vn_access)) {
         return ca_acl::$s_acl_access_value_cache[$vn_user_id][$pn_table_num][$pn_row_id] = $vn_access;
     }
     // If no valid ACL exists return default from config
     $o_config = Configuration::load();
     return ca_acl::$s_acl_access_value_cache[$vn_user_id][$pn_table_num][$pn_row_id] = (int) $o_config->get('default_item_access_level');
 }
Пример #26
0
/**
 * 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) . ' &gt; ';
                    }
                    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 . ' &gt; ' . $t_item->getLabelForDisplay();
                            } else {
                                $vs_label .= ($va_parent['NODE'][$vs_disp_fld] ? $va_parent['NODE'][$vs_disp_fld] . ' &gt; ' : '') . $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 .= " &gt; " . $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 &gt; 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 &rsaquo;', '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') . ' &rsaquo;', '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, '&larr; ' . $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, '&larr; ' . $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') . "&nbsp; ";
                $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') . " &rsaquo;", "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') . " &rsaquo;", "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;
}
Пример #27
0
 function resetSave()
 {
     $ps_action = $this->request->getParameter('action', pString);
     $ps_key = $this->request->getParameter('key', pString);
     $ps_key = preg_replace("/[^A-Za-z0-9]+/", "", $ps_key);
     $this->view->setVar("key", $ps_key);
     $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->render('LoginReg/resetpw_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("password_error", _t("Please enter and re-type your password."));
                     $ps_action = "reset";
                     break;
                 }
                 if ($ps_password != $ps_password_confirm) {
                     $this->view->setVar("password_error", _t("Passwords do not match. Please try again."));
                     $ps_action = "reset";
                     break;
                 }
                 $t_user = new ca_users();
                 $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";
                         # -- generate mail text from template
                         ob_start();
                         require $this->request->getViewsDirectoryPath() . "/mailTemplates/notification.tpl";
                         $vs_mail_message = ob_get_contents();
                         ob_end_clean();
                         caSendmail($t_user->get('email'), $this->request->config->get("ca_admin_email"), "[" . $this->request->config->get("app_display_name") . "] " . _t("Your password has been reset"), $vs_mail_message);
                     }
                     break;
                 } else {
                     $this->notification->addNotification(_t("Invalid user"), __NOTIFICATION_TYPE_INFO__);
                     $ps_action = "reset_failure";
                 }
         }
         $this->view->setVar("action", $ps_action);
         $this->render('LoginReg/resetpw_html.php');
     }
 }