/** * Creates a user object for the given contact * * Default attempted username is firstname.surname * * Failing that, initial.surname */ public function createUserForContact(Contact $contact) { // try and find a user for the given username $username = $contact->firstname . '.' . $contact->lastname; $username = trim($username, '.'); $username = mb_strtolower(preg_replace('/[^a-zA-Z.+_-]/', '', $username)); if ($username == '.') { throw new ExistingUserException("Contact must have a firstname and surname"); } if ($this->userService->getByName($username)) { // try a different username $username = $username[0] . $contact->lastname; $username = trim($username, '.'); $username = mb_strtolower(preg_replace('/[^a-zA-Z.+_-]/', '', $username)); if ($this->userService->getByName($username)) { // crapp it throw new Exception("All possible usernames taken"); } } try { $this->dbService->beginTransaction(); $new_pass = substr(md5(uniqid(rand(), 1)), 3, 5); $params = array('username' => $username, 'email' => $contact->email, 'firstname' => $contact->firstname, 'lastname' => $contact->lastname, 'contactid' => $contact->id, 'password' => $new_pass); $user = $this->userService->createUser($params, false, User::ROLE_EXTERNAL); $this->trackerService->track('create-contact-user', $contact->id); $this->dbService->commit(); } catch (Exception $e) { $this->log->debug($e->getMessage() . ": \r\n" . $e->getTraceAsString()); $this->dbService->rollback(); throw $e; } return $user; }
/** * Called to redirect after saving a model object * */ protected function onModelSaved($model) { $project = $this->projectService->getProject((int) $this->_getParam('projectid')); // after saving a task, we should probably notify the user about it hey? if (!$this->_getParam('id')) { $message = new TemplatedMessage('new-task.php', array('model' => $model)); $this->notificationService->notifyUser('New task', $model->userid, $message); // Create a watch for the creator $this->notificationService->createWatch(za()->getUser(), $model->id, 'Task'); } // Check to see if the assignee has a watch, if not, add one foreach ($model->userid as $username) { $assignedTo = $this->userService->getByName($username); if ($assignedTo) { $existing = $this->notificationService->getWatch($assignedTo, $model->id, 'Task'); if (!$existing) { $this->notificationService->createWatch($assignedTo, $model->id, 'Task'); } } } if ($this->_getParam('_ajax')) { echo $this->ajaxResponse("Saved " . $model->title); } else { $this->redirect('task', 'edit', array('id' => $model->id)); } }
/** * Saves an issue to the database * * @param array|Issue $params */ public function saveIssue($params, $doNotify = true) { $issue = null; $sendNotification = false; if (is_array($params)) { $existingId = ifset($params, 'id'); } else { $existingId = $params->id; } if (!$existingId) { $sendNotification = true; } $oldIssue = null; // If there's an existing one, save it in the history if ($existingId) { $oldIssue = $this->getIssue($existingId); $this->versioningService->createVersion($oldIssue); } // If saving a new one, we want to $issue = $this->dbService->saveObject($params, 'Issue'); // Okay, now check if it's on a project or not $project = null; if (!$issue->projectid) { // Get the project $client = $this->clientService->getClient($issue->clientid); if (!$client) { throw new Exception("No client exists with ID {$issue->clientid}"); } $project = $this->clientService->getClientSupportProject($client); if (!$project) { throw new Exception("Missing client details for request {$issue->title}"); } $issue->projectid = $project->id; $this->dbService->updateObject($issue); } else { $project = $this->projectService->getProject($issue->projectid); } // make sure it's assigned to someone if (!mb_strlen($issue->userid)) { if (!$project) { $project = $this->projectService->getProject($issue->projectid); } $issue->userid = $project->manager; $this->dbService->updateObject($issue); } // Check to see if the assignee has a watch, if not, add one $assignedTo = $this->userService->getByName($issue->userid); if ($assignedTo) { $existing = $this->notificationService->getWatch($assignedTo, $issue->id, 'Issue'); if (!$existing) { $this->notificationService->createWatch($assignedTo, $issue->id, 'Issue'); } } $this->log->debug("Saving request, notify {$issue->userid} = " . $sendNotification); $this->trackerService->track('create-issue', $issue->id); // now send a notification to those users in the // group assigned to the project the issue was just saved against. if ($sendNotification && $doNotify) { // create and assign a task to whoever was assigned to the issue // by default if ($assignedTo && false) { // Create the task $task = new Task(); $task->projectid = $issue->projectid; $task->userid = array($assignedTo->username); $task->title = 'Respond to request "' . $issue->title . '"'; $task->description = "Please investigate this request:\r\n\r\n" . $issue->description; $task->category = 'Support'; $task->due = date('Y-m-d H:i:s', strtotime('+2 days')); // $task = $this->projectService->saveTask($task, false, true); // $this->itemLinkService->linkItems($issue, $task); } $this->log->debug("Notifying users about new request {$issue->title}"); $this->notifyOfNewIssue($issue); // Add a watch for the current user. Note that it might be null if // this issue is created from an email $user = za()->getUser(); if ($user) { $this->notificationService->createWatch($user, $issue->id, 'Issue'); } } if ($issue->status == Issue::STATUS_CLOSED) { // remove notifications $subscribers = $this->notificationService->getSubscribers($issue); foreach ($subscribers as $username => $item) { $user = $this->userService->getUserByField('username', $username); if ($user) { $this->notificationService->removeWatch($user, $issue->id, 'Issue'); } } } // See if the status has changed and notify the creator if ($oldIssue != null && $oldIssue->status != $issue->status && $doNotify) { try { $this->notifyOfUpdatedIssue($oldIssue, $issue); } catch (Exception $e) { $this->log->warn("Failed to notify of request update"); } } return $issue; }
/** * Save a task. * * Saves the task object, then updates any task assignments that need * attention. * * @param Task $taskToSave The task to save * @param boolean $updateGroups Whether to update group membership on save. Defaults * to false to prevent too much db access * @param boolean $updateAssignees Whether the assignees should be updated. * make this false if you know the assigned users haven't changed */ public function saveTask($taskToSave, $updateGroups = false, $updateAssignees = true) { $task = null; try { $this->dbService->beginTransaction(); $oldId = null; $projectid = 0; $title = ''; if (is_array($taskToSave)) { $title = ifset($taskToSave, 'title', 'Untitled Task'); if (ifset($taskToSave, 'complete', false)) { $taskToSave['completedate'] = date('Y-m-d H:i:s'); } if (isset($taskToSave['id'])) { $oldId = $taskToSave['id']; } } else { $title = $taskToSave->title; if ($taskToSave->complete) { $taskToSave->completedate = date('Y-m-d H:i:s'); } if ($taskToSave->id) { $oldId = $taskToSave->id; } } // if there's an OLD ID, get that task so we know what dependencies // will need to be updated after saving $dependency = null; $oldState = null; if ($oldId) { $oldState = $this->getTask($oldId); $dependency = $oldState->getDependencyId(); } else { // no previous id, so must be creating from scratch $this->trackerService->track('create-task', $title); } $task = $this->dbService->saveObject($taskToSave, 'Task'); if ($task == null) { throw new Exception("Failed creating task for parameters " . print_r($taskToSave, true)); } $projectid = $task->projectid ? $task->projectid : 0; if (!$projectid) { $unassignedProject = $this->getUnassignedTaskProject(); $task->projectid = $unassignedProject->id; $this->dbService->saveObject($task); } // If the task's dependency is different, or its dates have changed, // update all dependants if ($oldState != null) { if (date('Y-m-d', strtotime($oldState->due)) != date('Y-m-d', strtotime($task->due)) || $dependency != $task->getDependencyId()) { // go and update the dependency $this->updateTaskDependants($task, $dependency); } } // Get the project because we'll be adding users // to the project in a moment $project = $this->getProject($task->projectid); if (!is_array($task->userid)) { $task->userid = array(); } if ($updateAssignees) { // Delete all the old user/task assignments $this->dbService->delete('usertaskassignment', 'taskid=' . $task->id); foreach ($task->userid as $username) { // create a new assignment $params = array('taskid' => $task->id, 'userid' => $username); $user = $this->userService->getByName($username); if ($user && $updateGroups) { $groups = $this->groupService->getGroupsForUser($user, false); // Note here that ownerid == the group that owns this project if ($project->ownerid && !isset($groups[$project->ownerid])) { $group = $this->groupService->getGroup($project->ownerid); if ($group) { // Add the user to this group $this->groupService->addToGroup($group, $user); $this->log->debug(__CLASS__ . ':' . __LINE__ . ": User {$user->username} added to {$group->title}"); } else { $this->log->warn(__CLASS__ . ':' . __LINE__ . ": Group not found for {$project->ownerid}"); } } else { if ($project->ownerid) { $this->log->debug(__CLASS__ . ':' . __LINE__ . ": User {$user->username} is already in group " . $groups[$project->ownerid]->title); } else { $this->log->debug(__CLASS__ . ':' . __LINE__ . ": Project does not have an owner for assigning a group"); } } } $this->dbService->saveObject($params, 'UserTaskAssignment'); } } $this->updateAffectedLinkedItems($task); $this->dbService->commit(); } catch (InvalidModelException $ime) { $this->log->err("Failed saving task because of invalid data: " . print_r($ime->getMessages(), true)); $this->log->err($ime->getTraceAsString()); $this->dbService->rollback(); throw $ime; } catch (Exception $e) { $this->log->err("Failed saving task " . $e->getMessage()); $this->log->err($e->getTraceAsString()); $this->dbService->rollback(); throw $e; } return $task; }