/**
  *
  *
  */
 public function parseValue($ps_value, $pa_element_info, $pa_options = null)
 {
     $ps_value = trim(preg_replace("![\t\n\r]+!", ' ', $ps_value));
     $vs_service = caGetOption('service', $this->getSettingValuesFromElementArray($pa_element_info, array('service')));
     //if (!trim($ps_value)) {
     //$this->postError(1970, _t('Entry was blank.'), 'InformationServiceAttributeValue->parseValue()');
     //	return false;
     //}
     if (trim($ps_value)) {
         $va_tmp = explode('|', $ps_value);
         $va_info = array();
         if (sizeof($va_tmp) == 3) {
             /// value is already in desired format (from autocomplete lookup)
             // get extra indexing info for this uri from plugin implementation
             $this->opo_plugin = InformationServiceManager::getInformationServiceInstance($vs_service);
             $vs_display_text = $this->opo_plugin->getDisplayValueFromLookupText($va_tmp[0]);
             $va_info['indexing_info'] = $this->opo_plugin->getDataForSearchIndexing($pa_element_info['settings'], $va_tmp[2]);
             $va_info['extra_info'] = $this->opo_plugin->getExtraInfo($pa_element_info['settings'], $va_tmp[2]);
             return array('value_longtext1' => $vs_display_text, 'value_longtext2' => $va_tmp[2], 'value_decimal1' => $va_tmp[1], 'value_blob' => caSerializeForDatabase($va_info));
         } elseif (sizeof($va_tmp) == 1 && (isURL($va_tmp[0], array('strict' => true)) || is_numeric($va_tmp[0]))) {
             // URI or ID -> try to look it up. we match hit when exactly 1 hit comes back
             // try lookup cache
             if (CompositeCache::contains($va_tmp[0], "InformationServiceLookup{$vs_service}")) {
                 return CompositeCache::fetch($va_tmp[0], "InformationServiceLookup{$vs_service}");
             }
             // try lookup
             $this->opo_plugin = InformationServiceManager::getInformationServiceInstance($vs_service);
             $va_ret = $this->opo_plugin->lookup($pa_element_info['settings'], $va_tmp[0]);
             // only match exact results. at some point we might want to try to get fancy
             // and pick one (or rather, have the plugin pick one) if there's more than one
             if (is_array($va_ret['results']) && sizeof($va_ret['results']) == 1) {
                 $va_hit = array_shift($va_ret['results']);
                 $va_info['indexing_info'] = $this->opo_plugin->getDataForSearchIndexing($pa_element_info['settings'], $va_hit['url']);
                 $va_info['extra_info'] = $this->opo_plugin->getExtraInfo($pa_element_info['settings'], $va_hit['url']);
                 $vs_display_text = $this->opo_plugin->getDisplayValueFromLookupText($va_hit['label']);
                 $va_return = array('value_longtext1' => $vs_display_text, 'value_longtext2' => $va_hit['url'], 'value_decimal1' => $va_hit['id'], 'value_blob' => caSerializeForDatabase($va_info));
             } else {
                 $this->postError(1970, _t('Value for InformationService lookup has to be an ID or URL that returns exactly 1 hit. We got more or no hits. Value was %1', $ps_value), 'ListAttributeValue->parseValue()');
                 return false;
             }
             CompositeCache::save($va_tmp[0], $va_return, "InformationServiceLookup{$vs_service}");
             return $va_return;
         } else {
             // don't save if value hasn't changed
             return array('_dont_save' => true);
         }
     }
     return array('value_longtext1' => '', 'value_longtext2' => '', 'value_decimal1' => null, 'value_blob' => null);
 }
Example #2
0
 /**
  * Log a change
  * 
  * @access private
  * @param string $ps_change_type 'I', 'U' or 'D', meaning INSERT, UPDATE or DELETE
  * @param int $pn_user_id user identifier, defaults to null
  */
 protected function logChange($ps_change_type, $pn_user_id = null)
 {
     if (defined('__CA_DONT_LOG_CHANGES__')) {
         return null;
     }
     if (!$this->logChanges()) {
         return null;
     }
     $vb_is_metadata = $vb_is_metadata_value = false;
     if ($this->tableName() == 'ca_attributes') {
         $vb_log_changes_to_self = false;
         $va_subject_config = null;
         $vb_is_metadata = true;
     } elseif ($this->tableName() == 'ca_attribute_values') {
         $vb_log_changes_to_self = false;
         $va_subject_config = null;
         $vb_is_metadata_value = true;
     } else {
         $vb_log_changes_to_self = $this->getProperty('LOG_CHANGES_TO_SELF');
         $va_subject_config = $this->getProperty('LOG_CHANGES_USING_AS_SUBJECT');
     }
     global $AUTH_CURRENT_USER_ID;
     if (!$pn_user_id) {
         $pn_user_id = $AUTH_CURRENT_USER_ID;
     }
     if (!$pn_user_id) {
         $pn_user_id = null;
     }
     if (!in_array($ps_change_type, array('I', 'U', 'D'))) {
         return false;
     }
     // invalid change type (shouldn't happen)
     if (!($vn_row_id = $this->getPrimaryKey())) {
         return false;
     }
     // no logging without primary key value
     // get unit id (if set)
     global $g_change_log_unit_id;
     $vn_unit_id = $g_change_log_unit_id;
     if (!$vn_unit_id) {
         $vn_unit_id = null;
     }
     // get subject ids
     $va_subjects = array();
     if ($vb_is_metadata) {
         // special case for logging attribute changes
         if (($vn_id = $this->get('row_id')) > 0) {
             $va_subjects[$this->get('table_num')][] = $vn_id;
         }
     } elseif ($vb_is_metadata_value) {
         // special case for logging metadata changes
         $t_attr = new ca_attributes($this->get('attribute_id'));
         if (($vn_id = $t_attr->get('row_id')) > 0) {
             $va_subjects[$t_attr->get('table_num')][] = $vn_id;
         }
     } else {
         if (is_array($va_subject_config)) {
             if (is_array($va_subject_config['FOREIGN_KEYS'])) {
                 foreach ($va_subject_config['FOREIGN_KEYS'] as $vs_field) {
                     $va_relationships = $this->_DATAMODEL->getManyToOneRelations($this->tableName(), $vs_field);
                     if ($va_relationships['one_table']) {
                         $vn_table_num = $this->_DATAMODEL->getTableNum($va_relationships['one_table']);
                         if (!isset($va_subjects[$vn_table_num]) || !is_array($va_subjects[$vn_table_num])) {
                             $va_subjects[$vn_table_num] = array();
                         }
                         if (($vn_id = $this->get($vs_field)) > 0) {
                             $va_subjects[$vn_table_num][] = $vn_id;
                         }
                     }
                 }
             }
             if (is_array($va_subject_config['RELATED_TABLES'])) {
                 $o_db = $this->getDb();
                 if (!isset($o_db) || !$o_db) {
                     $o_db = new Db();
                     $o_db->dieOnError(false);
                 }
                 foreach ($va_subject_config['RELATED_TABLES'] as $vs_dest_table => $va_path_to_dest) {
                     $t_dest = $this->_DATAMODEL->getTableInstance($vs_dest_table);
                     if (!$t_dest) {
                         continue;
                     }
                     $vn_dest_table_num = $t_dest->tableNum();
                     $vs_dest_primary_key = $t_dest->primaryKey();
                     $va_path_to_dest[] = $vs_dest_table;
                     $vs_cur_table = $this->tableName();
                     $vs_sql = "SELECT " . $vs_dest_table . "." . $vs_dest_primary_key . " FROM " . $this->tableName() . "\n";
                     foreach ($va_path_to_dest as $vs_ltable) {
                         $va_relations = $this->_DATAMODEL->getRelationships($vs_cur_table, $vs_ltable);
                         $vs_sql .= "INNER JOIN {$vs_ltable} ON {$vs_cur_table}." . $va_relations[$vs_cur_table][$vs_ltable][0][0] . " = {$vs_ltable}." . $va_relations[$vs_cur_table][$vs_ltable][0][1] . "\n";
                         $vs_cur_table = $vs_ltable;
                     }
                     $vs_sql .= "WHERE " . $this->tableName() . "." . $this->primaryKey() . " = " . $this->getPrimaryKey();
                     if ($qr_subjects = $o_db->query($vs_sql)) {
                         if (!isset($va_subjects[$vn_dest_table_num]) || !is_array($va_subjects[$vn_dest_table_num])) {
                             $va_subjects[$vn_dest_table_num] = array();
                         }
                         while ($qr_subjects->nextRow()) {
                             if (($vn_id = $qr_subjects->get($vs_dest_primary_key)) > 0) {
                                 $va_subjects[$vn_dest_table_num][] = $vn_id;
                             }
                         }
                     } else {
                         print "<hr>Error in subject logging: ";
                         print "<br>{$vs_sql}<hr>\n";
                     }
                 }
             } else {
                 if (($vn_id = $this->get('row_id')) > 0) {
                     // At a minimum always log self as subject
                     $va_subjects[$this->get('table_num')][] = $vn_id;
                 }
             }
         }
     }
     if (!sizeof($va_subjects) && !$vb_log_changes_to_self) {
         return true;
     }
     if (!$this->opqs_change_log) {
         $o_db = $this->getDb();
         $o_db->dieOnError(false);
         $vs_change_log_database = '';
         if ($vs_change_log_database = $this->_CONFIG->get("change_log_database")) {
             $vs_change_log_database .= ".";
         }
         if (!($this->opqs_change_log = $o_db->prepare("\n\t\t\t\tINSERT INTO " . $vs_change_log_database . "ca_change_log\n\t\t\t\t(\n\t\t\t\t\tlog_datetime, user_id, unit_id, changetype,\n\t\t\t\t\tlogged_table_num, logged_row_id, batch_id\n\t\t\t\t)\n\t\t\t\tVALUES\n\t\t\t\t(?, ?, ?, ?, ?, ?, ?)\n\t\t\t"))) {
             // prepare failed - shouldn't happen
             return false;
         }
         if (!($this->opqs_change_log_snapshot = $o_db->prepare("\n\t\t\t\tINSERT IGNORE INTO " . $vs_change_log_database . "ca_change_log_snapshots\n\t\t\t\t(\n\t\t\t\t\tlog_id, snapshot\n\t\t\t\t)\n\t\t\t\tVALUES\n\t\t\t\t(?, ?)\n\t\t\t"))) {
             // prepare failed - shouldn't happen
             return false;
         }
         if (!($this->opqs_change_log_subjects = $o_db->prepare("\n\t\t\t\tINSERT IGNORE INTO " . $vs_change_log_database . "ca_change_log_subjects\n\t\t\t\t(\n\t\t\t\t\tlog_id, subject_table_num, subject_row_id\n\t\t\t\t)\n\t\t\t\tVALUES\n\t\t\t\t(?, ?, ?)\n\t\t\t"))) {
             // prepare failed - shouldn't happen
             return false;
         }
     }
     // get snapshot of changes made to record
     $va_snapshot = $this->getSnapshot($ps_change_type === 'U' ? true : false);
     $vs_snapshot = caSerializeForDatabase($va_snapshot, true);
     if (!($ps_change_type == 'U' && !sizeof($va_snapshot))) {
         // Create primary log entry
         global $g_change_log_batch_id;
         // Log batch_id as set in global by ca_batch_log model (app/models/ca_batch_log.php)
         $this->opqs_change_log->execute(time(), $pn_user_id, $vn_unit_id, $ps_change_type, $this->tableNum(), $vn_row_id, (int) $g_change_log_batch_id ? (int) $g_change_log_batch_id : null);
         $vn_log_id = $this->opqs_change_log->getLastInsertID();
         $this->opqs_change_log_snapshot->execute($vn_log_id, $vs_snapshot);
         global $g_change_log_delegate;
         if ($g_change_log_delegate && method_exists($g_change_log_delegate, "onLogChange")) {
             call_user_func(array($g_change_log_delegate, 'onLogChange'), $this->tableNum(), $vn_row_id, $vn_log_id);
         }
         foreach ($va_subjects as $vn_subject_table_num => $va_subject_ids) {
             foreach ($va_subject_ids as $vn_subject_row_id) {
                 $this->opqs_change_log_subjects->execute($vn_log_id, $vn_subject_table_num, $vn_subject_row_id);
             }
         }
     }
     return true;
 }
Example #3
0
 /**
  *
  */
 function processQueue($ps_handler = "")
 {
     if (!($vn_proc_id = $this->registerProcess())) {
         return false;
     }
     $sql_handler_criteria = "";
     if ($ps_handler) {
         $sql_handler_criteria = " AND (handler = '" . addslashes($ps_handler) . "')";
     }
     if (!sizeof($this->opa_handler_plugin_dirs)) {
         $this->opo_eventlog->log(array("CODE" => "ERR", "SOURCE" => "TaskQueue->processQueue()", "MESSAGE" => "Queue processing failed because no handler directories are configured; queue was halted"));
         $this->postError(510, _t("No handler directories are configured!"), "TaskQueue->processQueue()");
         $this->unregisterProcess($vn_proc_id);
         return false;
     }
     $o_db = new Db();
     $vn_num_rows = 1;
     $vn_processed_count = 0;
     if (($vn_max_process_count = $this->opo_config->get('taskqueue_max_items_processed_per_session')) <= 0) {
         $vn_max_process_count = 1000000;
     }
     while ($vn_num_rows > 0 && $vn_processed_count <= $vn_max_process_count) {
         $qr_tasks = $o_db->query("\n\t\t\t\t\tSELECT * \n\t\t\t\t\tFROM ca_task_queue\n\t\t\t\t\tWHERE \n\t\t\t\t\t\tcompleted_on IS NULL AND started_on IS NULL\n\t\t\t\t\t\t{$sql_handler_criteria}\n\t\t\t\t\tORDER BY\n\t\t\t\t\t\tpriority, created_on\n\t\t\t\t\tLIMIT 1\n\t\t\t");
         if (($vn_num_rows = $qr_tasks->numRows()) > 0) {
             $qr_tasks->nextRow();
             // lock task
             $o_db->query("\n\t\t\t\t\t\tUPDATE ca_task_queue \n\t\t\t\t\t\tSET started_on = ?, error_code = 0\n\t\t\t\t\t\tWHERE task_id = ?", time(), (int) $qr_tasks->get("task_id"));
             $this->updateRegisteredProcess($vn_proc_id, $qr_tasks->get('row_key'), $qr_tasks->get('entity_key'));
             $proc_handler = $qr_tasks->get("handler");
             $vb_found_handler = false;
             foreach ($this->opa_handler_plugin_dirs as $vs_handler_dir) {
                 if (file_exists($vs_handler_dir . "/" . $proc_handler . ".php")) {
                     $vb_found_handler = true;
                     break;
                 }
             }
             if (!$vb_found_handler) {
                 $this->opo_eventlog->log(array("CODE" => "ERR", "SOURCE" => "TaskQueue->processQueue()", "MESSAGE" => "Queue processing failed because of invalid task queue handler '{$proc_handler}'; queue was halted"));
                 $this->postError(500, _t("Invalid task queue handler '%1'", $proc_handler), "TaskQueue->processQueue()");
                 $o_db->query("\n\t\t\t\t\t\tUPDATE ca_task_queue \n\t\t\t\t\t\tSET started_on = NULL\n\t\t\t\t\t\tWHERE task_id = ?", (int) $qr_tasks->get("task_id"));
                 continue;
             }
             $proc_parameters = unserialize(base64_decode($qr_tasks->get("parameters")));
             # load handler
             require_once $vs_handler_dir . "/" . $proc_handler . ".php";
             eval("\$h = new WLPlugTaskQueueHandler" . $proc_handler . "();");
             $vn_start_time = $this->_microtime2float();
             if ($va_report = $h->process($proc_parameters)) {
                 $vn_processed_count++;
                 $va_report['processing_time'] = sprintf("%6.3f", $this->_microtime2float() - $vn_start_time);
                 $o_db->query("\n\t\t\t\t\t\tUPDATE ca_task_queue \n\t\t\t\t\t\tSET completed_on = ?, error_code = 0, notes = ?\n\t\t\t\t\t\tWHERE task_id = ?", time(), caSerializeForDatabase($va_report), (int) $qr_tasks->get("task_id"));
             } else {
                 $this->opo_eventlog->log(array("CODE" => "ERR", "SOURCE" => "TaskQueue->processQueue()", "MESSAGE" => "Queue processing failed using handler {$proc_handler}: " . $h->error->getErrorDescription() . " [" . $h->error->getErrorNumber() . "]; queue was <b>NOT</b> halted"));
                 $this->errors[] = $h->error;
                 // Got error, so mark task as failed (non-zero error_code value)
                 $o_db->query("\n\t\t\t\t\t\tUPDATE ca_task_queue \n\t\t\t\t\t\tSET completed_on = ?, error_code = ? \n\t\t\t\t\t\tWHERE task_id = ?", time(), (int) $h->error->getErrorNumber(), (int) $qr_tasks->get("task_id"));
             }
             if ($o_db->numErrors()) {
                 $this->opo_eventlog->log(array("CODE" => "ERR", "SOURCE" => "TaskQueue->processQueue()", "MESSAGE" => "Queue processing failed while closing task record using {$proc_handler}: " . join('; ', $o_db->getErrors()) . "; queue was halted"));
                 $this->postError(515, _t("Error while closing task record: %1", join('; ', $o_db->getErrors())), "TaskQueue->processQueue()");
                 $this->unregisterProcess($vn_proc_id);
                 return false;
             }
         }
     }
     #
     # Unlock queue processing
     #
     $this->unregisterProcess($vn_proc_id);
     return true;
 }
Example #4
0
 /**
  *
  */
 public function addItem($pn_row_id, $pa_errors = null)
 {
     if (!$this->opn_last_batch_id) {
         return false;
     }
     if (!$pn_row_id) {
         return false;
     }
     if (!is_array($pa_errors)) {
         $pa_errors = array();
     }
     if (sizeof($pa_errors)) {
         $va_errors = array();
         foreach ($pa_errors as $o_error) {
             $va_errors[$o_error->getErrorNumber()] = $o_error->getErrorDescription();
         }
     }
     $this->o_db->query("\n\t\t\t\tINSERT INTO ca_batch_log_items\n\t\t\t\t(row_id, batch_id, errors)\n\t\t\t\tVALUES\n\t\t\t\t(?, ?, ?)\n\t\t\t", (int) $pn_row_id, (int) $this->opn_last_batch_id, caSerializeForDatabase($va_errors));
     return $this->o_db->numErrors() ? false : true;
 }
 public function save()
 {
     $this->o_db->query("UPDATE ca_application_vars SET vars = ?", caSerializeForDatabase($this->opa_app_vars));
     if ($this->o_db->numErrors()) {
         $this->postError(305, join(';', $this->o_db->getErrors()), "ApplicationVars->save()");
         return false;
     }
     return true;
 }
Example #6
0
 private function queueUnIndexRow($pa_row_values)
 {
     foreach ($pa_row_values as $vs_fld => &$vm_val) {
         if (!$this->opo_search_indexing_queue->hasField($vs_fld)) {
             return false;
         }
         if (is_null($vm_val)) {
             $vm_val = array();
         }
         if (is_array($vm_val)) {
             $vm_val = caSerializeForDatabase($vm_val);
         }
     }
     self::$s_search_unindexing_queue_inserts[] = array('table_num' => $pa_row_values['table_num'], 'row_id' => $pa_row_values['row_id'], 'is_unindex' => 1, 'dependencies' => $pa_row_values['dependencies']);
     return true;
 }
Example #7
0
 public static function reload_object_current_location_dates($po_opts = null)
 {
     require_once __CA_MODELS_DIR__ . "/ca_movements.php";
     require_once __CA_MODELS_DIR__ . "/ca_movements_x_objects.php";
     require_once __CA_MODELS_DIR__ . "/ca_movements_x_storage_locations.php";
     $o_config = Configuration::load();
     $o_db = new Db();
     // Reload movements-objects
     if ($vs_movement_storage_element = $o_config->get('movement_storage_location_date_element')) {
         $qr_movements = ca_movements::find(['deleted' => 0], ['returnAs' => 'searchResult']);
         print CLIProgressBar::start($qr_movements->numHits(), "Reloading movement dates");
         while ($qr_movements->nextHit()) {
             if ($va_dates = $qr_movements->get("ca_movements.{$vs_movement_storage_element}", ['returnAsArray' => true, 'rawDate' => true])) {
                 $va_date = array_shift($va_dates);
                 // get movement-object relationships
                 if (is_array($va_rel_ids = $qr_movements->get('ca_movements_x_objects.relation_id', ['returnAsArray' => true])) && sizeof($va_rel_ids)) {
                     $qr_res = $o_db->query("UPDATE ca_movements_x_objects SET sdatetime = ?, edatetime = ? WHERE relation_id IN (?)", array($va_date['start'], $va_date['end'], $va_rel_ids));
                 }
                 // get movement-location relationships
                 if (is_array($va_rel_ids = $qr_movements->get('ca_movements_x_storage_locations.relation_id', ['returnAsArray' => true])) && sizeof($va_rel_ids)) {
                     $qr_res = $o_db->query("UPDATE ca_movements_x_storage_locations SET sdatetime = ?, edatetime = ? WHERE relation_id IN (?)", array($va_date['start'], $va_date['end'], $va_rel_ids));
                     // check to see if archived storage locations are set in ca_movements_x_storage_locations.source_info
                     // Databases created prior to the October 2015 location tracking changes won't have this
                     $qr_rels = caMakeSearchResult('ca_movements_x_storage_locations', $va_rel_ids);
                     while ($qr_rels->nextHit()) {
                         if (!is_array($va_source_info = $qr_rels->get('source_info')) || !isset($va_source_info['path'])) {
                             $vn_rel_id = $qr_rels->get('ca_movements_x_storage_locations.relation_id');
                             $qr_res = $o_db->query("UPDATE ca_movements_x_storage_locations SET source_info = ? WHERE relation_id = ?", array(caSerializeForDatabase(array('path' => $qr_rels->get('ca_storage_locations.hierarchy.preferred_labels.name', array('returnAsArray' => true)), 'ids' => $qr_rels->get('ca_storage_locations.hierarchy.location_id', array('returnAsArray' => true)))), $vn_rel_id));
                         }
                     }
                 }
                 print CLIProgressBar::next();
             }
         }
         print CLIProgressBar::finish();
     }
     return true;
 }