/** * Adds a new task * @param array $args array containing all task properties. unknown properties will be ignored * @access public * @return array(error type, msg, false) or array(task ID, token, true) * @version 1.0 * @notes $args is POST data, bad..bad user.. */ function create_task($args) { global $db, $user, $proj, $fs; if ($proj->id != $args['project_id']) { $proj = new Project($args['project_id']); } if (!$user->can_open_task($proj) || count($args) < 3) { return array(ERROR_RECOVER, L('missingrequired'), false); } // check required fields if (!(($item_summary = $args['item_summary']) && ($detailed_desc = $args['detailed_desc']))) { return array(ERROR_RECOVER, L('summaryanddetails'), false); } foreach ($proj->fields as $field) { if ($field->prefs['value_required'] && !array_get($args, 'field' . $field->id) && !($field->prefs['force_default'] && !$user->perms('modify_all_tasks'))) { return array(ERROR_RECOVER, L('missingrequired') . ' (' . $field->prefs['field_name'] . ')', false); } } if ($user->isAnon() && $fs->prefs['use_recaptcha']) { include_once BASEDIR . '/includes/external/recaptchalib.php'; $solution = new reCAPTCHA_Solution(); $solution->privatekey = $fs->prefs['recaptcha_priv_key']; $solution->challenge = Post::val('recaptcha_challenge_field'); $solution->response = Post::val('recaptcha_response_field'); $solution->remoteip = $_SERVER['REMOTE_ADDR']; if (!$solution->isValid()) { return array(ERROR_RECOVER, $solution->error_code, false); } } $sql_values = array(time(), time(), $args['project_id'], $item_summary, $detailed_desc, intval($user->id), 0); $sql_params[] = 'mark_private'; $sql_values[] = isset($args['mark_private']) && $args['mark_private'] == '1'; $sql_params[] = 'closure_comment'; $sql_values[] = ''; $sql_params[] = 'syntax_plugins'; $plugins = trim(implode(' ', array_get($args, 'detailed_desc_syntax_plugins', array()))); if (!$plugins) { $plugins = $proj->prefs['syntax_plugins']; } $sql_values[] = $plugins; // Token for anonymous users $token = ''; if ($user->isAnon()) { $token = md5(uniqid(mt_rand(), true)); $sql_params[] = 'task_token'; $sql_values[] = $token; } $sql_params[] = 'anon_email'; $sql_values[] = array_get($args, 'anon_email', ''); $sql_cols = array_merge(array('date_opened', 'last_edited_time', 'project_id', 'item_summary', 'detailed_desc', 'opened_by', 'percent_complete'), $sql_params); $db->x->autoExecute('{tasks}', array_combine($sql_cols, $sql_values)); $task_id = $db->lastInsertID(); // [RED] Add task to redundancy table (opened by, last_changed_time) $db->x->autoExecute('{redundant}', array('task_id' => $task_id, 'last_changed_time' => time(), 'opened_by_real_name' => $user->infos['real_name'], 'opened_by_user_name' => $user->infos['user_name'], 'last_changed_by_real_name' => $user->infos['real_name'], 'last_changed_by_user_name' => $user->infos['user_name'])); // Per project task ID $prefix_id = $db->x->GetOne('SELECT MAX(prefix_id)+1 FROM {tasks} WHERE project_id = ?', null, $proj->id); $db->x->execParam('UPDATE {tasks} SET prefix_id = ? WHERE task_id = ?', array($prefix_id, $task_id)); // Now the custom fields if (count($proj->fields)) { $stmt = $db->x->autoPrepare('{field_values}', array('task_id', 'field_id', 'field_value')); foreach ($proj->fields as $field) { $stmt->execute(array($task_id, $field->id, $field->read(array_get($args, 'field' . $field->id, 0)))); } $stmt->free(); } $assignees = array(); if (isset($args['assigned_to'])) { // Prepare assignee list $assignees = explode(';', trim($args['assigned_to'])); $assignees = array_map(array('Flyspray', 'UserNameToId'), $assignees); $assignees = array_filter($assignees, create_function('$x', 'return ($x > 0);')); // Log the assignments and send notifications to the assignees if (count($assignees)) { // Convert assigned_to and store them in the 'assigned' table foreach ($assignees as $val) { $fields = array('user_id' => array('value' => $val, 'key' => true), 'task_id' => array('value' => $task_id, 'key' => true)); $db->Replace('{assigned}', $fields); } Flyspray::logEvent($task_id, 14, implode(' ', $assignees)); // Notify the new assignees what happened. This obviously won't happen if the task is now assigned to no-one. Notifications::send($assignees, ADDRESS_USER, NOTIFY_NEW_ASSIGNEE, array('task_id' => $task_id)); } } // Log that the task was opened Flyspray::logEvent($task_id, 1); // find category owners $owners = array(); foreach ($proj->fields as $field) { if ($field->prefs['list_type'] != LIST_CATEGORY) { continue; } $cat = $db->x->getRow('SELECT * FROM {list_category} WHERE category_id = ?', null, array_get($args, 'field' . $field->id, 0)); if ($cat['category_owner']) { $owners[] = $cat['category_owner']; } else { // check parent categories $sql = $db->x->getAll('SELECT * FROM {list_category} WHERE lft < ? AND rgt > ? AND list_id = ? ORDER BY lft DESC', null, array($cat['lft'], $cat['rgt'], $cat['list_id'])); foreach ($sql as $row) { // If there's a parent category owner, send to them if ($row['category_owner']) { $owners[] = $row['category_owner']; break; } } } } // last try... if (!count($owners) && $proj->prefs['default_cat_owner']) { $owners[] = $proj->prefs['default_cat_owner']; } if (count($owners)) { foreach ($owners as $owner) { if ($proj->prefs['auto_assign'] && !in_array($owner, $assignees)) { Backend::add_to_assignees($owner, $task_id, true); } Backend::add_notification($owner, $task_id, true); } } // Create the Notification if (Backend::upload_files($task_id)) { Notifications::send($task_id, ADDRESS_TASK, NOTIFY_TASK_OPENED, array('files' => true)); } else { Notifications::send($task_id, ADDRESS_TASK, NOTIFY_TASK_OPENED); } // If the reporter wanted to be added to the notification list if (isset($args['notifyme']) && $args['notifyme'] == '1' && !in_array($user->id, $owners)) { Backend::add_notification($user->id, $task_id, true); } // this is relaxed, if the anonymous email is not valid, just dont bother.. if ($user->isAnon() && Flyspray::check_email($args['anon_email'])) { Notifications::send($args['anon_email'], ADDRESS_EMAIL, NOTIFY_ANON_TASK, array('task_id' => $task_id, 'token' => $token)); } return array($task_id, $token, true); }
function action_sendcode() { global $user, $db, $fs, $conf, $baseurl; if (!Post::val('user_name') || !Post::val('real_name') || !Post::val('email_address')) { // If the form wasn't filled out correctly, show an error return array(ERROR_RECOVER, L('registererror')); } $email = Post::val('email_address'); $jabber_id = Post::val('jabber_id'); //email is mandatory if (!$email || !Flyspray::check_email($email)) { return array(ERROR_RECOVER, L('novalidemail')); } //jabber_id is optional if ($jabber_id && !Jabber::check_jid($jabber_id)) { return array(ERROR_RECOVER, L('novalidjabber')); } $user_name = Backend::clean_username(Post::val('user_name')); // Limit lengths $real_name = substr(trim(Post::val('real_name')), 0, 100); // Remove doubled up spaces and control chars $real_name = preg_replace('![\\x00-\\x1f\\s]+!u', ' ', $real_name); if (!$user_name || !$real_name) { return array(ERROR_RECOVER, L('entervalidusername')); } // Delete registration codes older than 24 hours $yesterday = time() - 86400; $db->x->execParam('DELETE FROM {registrations} WHERE reg_time < ?', $yesterday); $taken = $db->x->getRow('SELECT u.user_id FROM {users} u, {registrations} r WHERE u.user_name = ? OR r.user_name = ?', null, array($user_name, $user_name)); if ($taken) { return array(ERROR_RECOVER, L('usernametaken')); } $taken = $db->x->getRow("SELECT user_id\n FROM {users}\n WHERE jabber_id = ? AND jabber_id != NULL\n OR email_address = ? AND email_address != NULL", null, array($jabber_id, $email)); if ($taken) { return array(ERROR_RECOVER, L('emailtaken')); } if ($fs->prefs['use_recaptcha']) { $solution = new reCAPTCHA_Solution(); $solution->privatekey = $fs->prefs['recaptcha_priv_key']; $solution->challenge = Post::val('recaptcha_challenge_field'); $solution->response = Post::val('recaptcha_response_field'); $solution->remoteip = $_SERVER['REMOTE_ADDR']; if (!$solution->isValid()) { return array(ERROR_RECOVER, $solution->error_code); } } $magic_url = substr(md5(uniqid(rand(), true)), 0, 20); //send the email first. if (Notifications::send(Post::val('email_address'), ADDRESS_EMAIL, NOTIFY_CONFIRMATION, array($baseurl, $magic_url, $user_name))) { //email sent succefully, now update the database. $reg_values = array('reg_time' => time(), 'user_name' => $user_name, 'real_name' => $real_name, 'email_address' => Post::val('email_address'), 'jabber_id' => Post::val('jabber_id'), 'notify_type' => Post::num('notify_type'), 'magic_url' => $magic_url, 'time_zone' => Post::num('time_zone')); // Insert everything into the database $query = $db->x->autoExecute('{registrations}', $reg_values); if (!PEAR::isError($query)) { return array(SUBMIT_OK, L('codesent'), $baseurl); } } else { return array(ERROR_INPUT, L('codenotsent')); } }