/** * Persist the object to the database * @return boolean Success or failure of the save operation * @throws ValidationException */ public function save($clear_checkout = true) { $success = false; if ($this->_logger == null) { $this->_logger = new Logger($this->_mysqli); } $valid = $this->validate(); if ($valid === true) { // Clear any existing checkout if ($clear_checkout) { $this->checkout_author_id = null; $this->checkout_time = null; } // Make sure plain versions of scenario and leadin are up to date $this->get_scenario_plain(); $this->get_leadin_plain(); $this->serialize_settings(); if ($this->bloom == '') { $this->bloom = null; } // If $id is -1 we're inserting a new record if ($this->id == -1) { $this->created = date('Y-m-d H:i:s'); $this->last_edited = date('Y-m-d H:i:s'); $server_ipaddress = str_replace('.', '', NetworkUtils::get_server_address()); $this->guid = $server_ipaddress . uniqid('', true); $params = array_merge(array('ssssssssssssssissssisssssss'), $this->_data); $query = <<<QUERY INSERT INTO questions (q_type, theme, scenario, scenario_plain, leadin, leadin_plain, notes, correct_fback, incorrect_fback, score_method, display_method, q_option_order, std, bloom, ownerID, q_media, q_media_width, q_media_height, checkout_time, checkout_authorID, creation_date, last_edited, locked, deleted, status, settings, guid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) QUERY; } else { // Otherwise we're updating an existing one $params = array_merge(array('ssssssssssssssissssisssssssi'), $this->_data, array(&$this->id)); $this->last_edited = date('Y-m-d H:i:s'); $query = <<<QUERY UPDATE questions SET q_type = ?, theme = ?, scenario = ?, scenario_plain = ?, leadin = ?, leadin_plain = ?, notes = ?, correct_fback = ?, incorrect_fback = ?, score_method = ?, display_method = ?, q_option_order = ?, std = ?, bloom = ?, ownerID = ?, q_media = ?, q_media_width = ?, q_media_height = ?, checkout_time = ?, checkout_authorID = ?, creation_date = ?, last_edited = ?, locked = ?, deleted = ?, status = ?, settings = ?, guid = ? WHERE q_id = ? QUERY; } $result = $this->_mysqli->prepare($query); call_user_func_array(array($result, 'bind_param'), $params); $result->execute(); $success = $result->affected_rows > -1; if ($this->_mysqli->error) { try { throw new Exception("MySQL error " . $this->_mysqli->error . "<br /> Query:<br /> {$query}", $this->_mysqli->errno); } catch (Exception $e) { echo "Error No: " . $e->getCode() . " - " . $e->getMessage() . "<br />"; echo nl2br($e->getTraceAsString()); } } if ($success) { if ($this->id == -1) { $this->id = $this->_mysqli->insert_id; $this->_logger->track_change('New Question', $this->id, $this->_user_id, $this->get_leadin(), '', ''); } else { // Log any changes foreach ($this->_modified_fields as $key => $value) { $db_field = in_array($key, array_keys($this->_field_map)) ? $this->_field_map[$key] : $key; $change_field = in_array($db_field, array_keys($this->_change_field_map)) ? $this->_change_field_map[$db_field] : $db_field; // Exception for media as it returns an array. Need better solution if other properties do the same in the future $get_method = 'get_' . $key . ($key == 'media' ? '_filename' : ''); if ($value['message'] == '') { $this->_logger->track_change($this->_lang_strings['editquestion'], $this->id, $this->_user_id, $value['value'], $this->{$get_method}(), $change_field); } else { $this->_logger->track_change($value['message'], $this->id, $this->_user_id, $value['value'], $this->{$get_method}(), $change_field); } } } } $result->close(); if ($success) { // Updates the teams/question modules QuestionUtils::update_modules($this->teams, $this->id, $this->_mysqli, $this->_userObj); } if ($success) { $success = $this->save_options(); } $this->_modified_fields = array(); } else { throw new ValidationException($valid); } return $success; }