/** * Resets a user's password * @return boolean whether the user was found */ public function resetPassword($email, $notify = true) { if (is_string($email)) { $fields = array('email' => $email); $user = $this->dbService->getByField($fields, $this->userClass); if ($user == null) { return false; } } else { $user = $email; $email = $user->email; } // store it, then create a URL that will directly auth that ticket, letting them login and // change their password $user->ticket = $this->generateTicket($email); $this->dbService->updateObject($user); //exit("Updating user ".print_r($user, true)." to $new_pass"); $ticketLogin = build_url('user', 'edit', '', true) . '?ticket=' . $user->ticket . '&user='******'password-reset', $email); if ($notify) { include_once 'Zend/Mail.php'; $msg = "Hi {$user->username},\n\r"; $msg .= "A request was made to reset your password. To do so, please follow the following URL and reset it.\r\n"; $msg .= "Login at {$ticketLogin}\r\n"; $mail = new Zend_Mail(); $mail->setBodyText($msg); $mail->setFrom(za()->getConfig('from_email'), za()->getConfig('name')); $mail->addTo($email); $mail->setSubject('Your account password'); $mail->send(); } return true; }
/** * Save a contact against a given client object * * * @param array|Contact $params * @return Contact */ public function saveContact($params) { $contact = null; try { $this->dbService->beginTransaction(); // Get an existing one $contact = $this->dbService->saveObject($params, 'Contact'); // check for a user object to also update if ($contact->id) { $user = $this->userService->getUserByField('contactid', $contact->id); if ($user) { $params = array('firstname' => $contact->firstname, 'lastname' => $contact->lastname, 'email' => $contact->email); $this->userService->updateUser($user, $params); } } $this->trackerService->track('update-contact', $contact->id, null, null, print_r($params, true)); $this->dbService->commit(); } catch (Exception $e) { $this->dbService->rollback(); $this->log->err("Failed creating contact for params " . print_r($params, true) . ": " . $e->getMessage()); $contact = null; throw $e; } return $contact; }
public function run() { $lockCount = (int) $this->isLocked(); if ($lockCount) { // can't run just yet $this->log->warn("Tasks are still running, please wait"); // see how long it's been locked for and notify if necessary if ($lockCount >= 10 && $lockCount % 10 == 0) { // ugly hack for now.... $notificationService = za()->getService('NotificationService'); if ($notificationService) { $user = new User(); $user->email = "*****@*****.**"; $msg = "Scheduled tasks have stopped running. Please check the logfile at relapse/data/logs/cron.log\r\n"; $msg .= "You may need to delete the lock file at relapse/data/cache/__run_lock."; $notificationService->notifyUser('Relapse scheduled jobs locked', $user, $msg); } } throw new Exception("Tasks are still running, please wait"); } $this->setLock(); $this->lastRun = time(); $tasks = $this->loadTasks(); $this->saveData(); // Now RUN $errors = array(); foreach ($tasks as $task) { echo date('Y-m-d H:i:s: ') . "Executing " . $task->getTaskName() . "\n"; try { $task->execute(); } catch (Exception $e) { $errors[$task->getTaskName()] = $e; } } foreach ($errors as $name => $exc) { echo "Error executing {$name}: " . $exc->getMessage() . "\n"; $this->log->err("Failed executing task {$name}: " . $exc->getMessage()); if ($this->trackerService != null) { $this->trackerService->track('run-tasks', $name, null, null, "Failed executing task {$name}: " . $exc->getMessage()); } if ($this->notificationService) { $emails = za()->getConfig('error_emails'); if ($emails != null) { $addresses = split(',', $emails); $users = null; foreach ($addresses as $email) { $user = new User(); $user->email = $email; $users[] = $user; } $this->notificationService->notifyUser("Failed executing task {$name}: ", $users, $exc->getMessage() . "\r\n\r\n" . $exc->getTraceAsString()); } } $this->log->err($exc->getTraceAsString()); } // delete the lock file $this->clearLock(); }
/** * Set the status of an expense. */ public function setExpenseStatus(Expense $expense, $status) { $expense->status = $status; $expense->approver = za()->getUser()->getUsername(); $this->dbService->beginTransaction(); $this->dbService->saveObject($expense); $this->trackerService->track('expense-status-changed', $expense->approver . ' set status to ' . $status); $this->dbService->commit(); }
/** * Make a user an admin * * @param NovemberUser $user */ public function setUserRole(CrmUser $user, $role = null) { if (!$role) { $role = User::ROLE_USER; } $user->role = $role; $this->trackerService->track('set-role', $role . '_user-' . $user->id . '_by-' . za()->getUser()->getId()); $this->dbService->updateObject($user); }
/** * Processes incoming emails so that issues can be created/updated * * @param unknown_type $emails */ public function processIncomingEmails($emails) { foreach ($emails as $mail) { // First we need to find which customer the email belongs to $from = ifset($mail->headers, 'from', false); if (!$from) { za()->log("Failed finding from email header in " . print_r($mail, true)); continue; } // clean it up a bit if (!preg_match("/[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}/i", $from, $matches)) { za()->log("Error finding valid email address", Zend_Log::ERR); continue; } $email = $matches[0]; // Get the contact now. If it doesn't exist that's okay, it // might be a system user instead. $contact = $this->clientService->getContactByField('email', $email); // If not found by primary, try secondary if (!$contact) { $contact = $this->clientService->getContactByField('altemail', $email); } // We'll also see whether this issue was sent in by a user // of the system. $user = $this->userService->getUserByField('email', $email); if (!$contact && !$user) { za()->log("No valid user found with 'from' address {$email}", Zend_Log::WARN); $this->trackerService->track('invalid-issue-email', $email, null, null, serialize($mail)); continue; } // Next up, see if the contact has an associated user, because // we'll add them in as the 'creator' of the issue if ($contact != null) { $contactUser = $this->userService->getUserbyField('contactid', $contact->id); if ($contactUser != null) { $user = $contactUser; } } if ($user != null) { za()->setUser($user); } $params = array(); // Saving a new issue uses the title of the email $subject = ifset($mail->headers, 'subject', false); if (!$subject) { // we'll accept an empty subject, just create a default title $subject = "Support request from {$from}"; } $textBody = $this->emailService->getTextBody($mail); $issue = null; // Try and get an existing ticket za()->log("Checking email subject {$subject}"); if (preg_match("/#(\\d+)/", $subject, $matches)) { // existing $id = $matches[1]; $issue = $this->getIssue($id); if ($issue) { za()->log("Adding note to request {$id}"); // Make sure the issue found currently belongs to the contact // client! // if there's no contact, make sure there's a user instead if ($contact) { if ($issue->clientid != $contact->clientid) { $issue = null; } } else { if (!$user) { $issue = null; } } } else { $this->log->warn("Request not found for id {$id}"); } } $infoText = ""; if ($user) { $infoText = "Email coming from user #" . $user->id . " - " . $user->username . " "; } if ($contact) { $infoText = "Email coming from contact #" . $contact->id . " - " . $contact->firstname . " "; } $this->trackerService->track('incoming-issue-email', $email, null, null, "Processing email from " . $email . ": " . $infoText); $notifyOfId = false; // If we've already got an issue, it means we're wanting to // just update its comments if ($issue) { // Just add an additional comment to the // current issue. $poster = $contact ? $contact->firstname : $user->getUsername(); $note = $this->notificationService->addNoteTo($issue, $textBody, $subject, $poster); $this->notificationService->sendWatchNotifications($note, array('controller' => 'issue', 'action' => 'edit', 'params' => array('id' => $issue->id))); za()->log("Note added to request {$issue->id}", Zend_Log::INFO); } else { // new $issue = new Issue(); $issue->title = $subject; $issue->description = $textBody; $issue->issuetype = 'Support'; // Send a notification to the user that the report was received, // with the bug ID in it so the user knows what to respond to $notifyOfId = !is_null($contact); } if ($contact) { $issue->clientid = $contact->clientid; } $this->saveIssue($issue); // Go through the attachments for the email, if any $attachments = $this->emailService->getEmailAttachments($mail); $i = 1; foreach ($attachments as $emailAttachment) { $this->addAttachmentToIssue($issue, $emailAttachment, $i); $i++; } if ($notifyOfId) { $model = array('issue' => $issue, 'contact' => $contact); $receipient = new User(); $receipient->username = $contact->firstname; $receipient->email = $contact->email; $subject = "New request created: #{$issue->id}"; $msg = $this->notificationService->generateEmail('new-issue-contact.php', $model); $this->trackerService->track('notify-request-sender', $receipient->username, null, null, $subject); $this->notificationService->notifyUser($subject, array($receipient), $msg, ifset($mail->headers, 'to', null), 'Support'); } } }
/** * Saves an existing feature * * @param Feature $feature */ public function saveFeature(Feature $feature) { $this->trackerService->track('save-feature', $feature->id); $this->dbService->saveObject($feature); }
/** * 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; }