/** * Update tickets from built plan * * @param $planId * @param $ticketsData * @return bool */ public function updateBuiltTickets($planId, $ticketsData) { $redirect = false; $errorMsg = ''; // Start transaction DB::beginTransaction(); // Start tickets update try { $ticket = $this->model->where('plan_id', '=', $planId); $ticket->update(['tickets' => serialize($ticketsData)]); } catch (\Exception $e) { $errorMsg = $e->getMessage(); $redirect = true; } catch (QueryException $e) { $errorMsg = $e->getErrors(); $redirect = true; } catch (ModelNotFoundException $e) { $errorMsg = $e->getErrors(); $redirect = true; } // Redirect if errors if ($redirect) { // Rollback DB::rollback(); // Log to system Tools::log($errorMsg, $ticketsData); return false; } // Commit all changes DB::commit(); return true; }
/** * Save comment in activity stream * * @param Request $request * @return \Illuminate\Http\JsonResponse */ public function save(Request $request) { $asId = $request->get('as_id'); $userId = Auth::user()->id; $comment = $request->get('comment'); $results = $this->streamApi->saveActivityComment($asId, $userId, $comment); return response()->json(["status" => "success", "commentator" => Tools::getUserFirstName(Auth::user()->id), "comment" => $results->comment, "created_at" => Tools::dateConverter($results->created_at)]); }
/** * Save activity stream * * @param $plan * @return bool */ public function saveActivityStream($plan) { try { $assigneeName = Tools::getUserFirstName($plan['creator_id']); $userId = $plan['creator_id']; $type = $plan['type']; $status = $plan['status']; if ($type != 'plan') { $assigneeName = $plan['assignee']; $userId = $plan['tester_id']; $status = $plan['tickets_overall_status']; } $this->model->create(['plan_id' => $plan['plan_id'], 'user_id' => $userId, 'activity' => $assigneeName . ' ' . Tools::getStatusText('activity', $type, $status) . ' ' . $plan['description']]); } catch (\Exception $e) { Tools::log($e->getMessage() . ' activity stream', $plan); Session::flash('flash_error', config('testplanner.messages.plan.system.activity_stream_error')); return true; } return true; }
/** * Send email * * @param $type * @param $data * @return mixed */ public static function sendEmail($type, $data) { try { // Subject and email type selector switch ($type) { case 'plan_created': case 'plan_updated': $emailSubject = $data['description'] . ' - ' . config('testplanner.mail.subjects.' . $type); foreach ($data['testers'] as $tester) { $type = 'emails.' . $type; $tester['browsers'] = Tools::translateBrowserName($tester['browsers']); if ($type = 'plan_updated' && $tester['update_status'] != 0) { $type = 'emails.plan_browser_updated'; } Mail::send($type, array_merge($data, $tester), function ($message) use($tester, $emailSubject) { $message->to($tester['email'], $tester['first_name'])->subject($emailSubject); }); } break; case 'ticket_response': $emailSubject = $data['description'] . ' - ' . config('testplanner.mail.subjects.' . $type) . ' ' . $data['assignee']; $data += ['tester_email' => Tools::getUserEmail($data['tester_id']), 'creator_email' => Tools::getUserEmail($data['creator_id'])]; if ($data['creator_email'] != $data['tester_email']) { Mail::send('emails.' . $type, $data, function ($message) use($data, $emailSubject) { $message->from($data['tester_email'], $data['assignee']); $message->to($data['creator_email'], $data['reporter'])->subject($emailSubject); }); } break; } } catch (\Exception $e) { Tools::log($e->getMessage() . ' email sending', $data); Session::flash('flash_error', config('testplanner.messages.plan.system.email_error')); } return true; }
/** * Retrieve custom accessor * * @return mixed */ public function getUserFirstNameAttribute() { return Tools::getUserFirstName($this->user_id); }
/** * Update tester from built plan * * @param $planId * @param $testersData * @return array|bool */ public function updateBuiltTesters($planId, $testersData, $origData) { $redirect = false; $errorMsg = ''; // Start transaction DB::beginTransaction(); // Start testers update try { $query = $this->model->where('plan_id', '=', $planId)->delete(); foreach ($testersData as $tester) { $testerId = $tester['id']; $browsers = $tester['browsers']; $newCount = isset($browsers) ? count(explode(',', $browsers)) : 0; // Formerly selected browsers $oldCount = isset($origData[$testerId]) ? count(explode(',', $origData[$testerId])) : 0; if ($oldCount == $newCount) { $updateStatus = 0; } elseif ($newCount > $oldCount) { $updateStatus = 1; } elseif ($oldCount < $newCount || $oldCount > $newCount) { $updateStatus = -1; } $tester += ['update_status' => $updateStatus, 'update_status_text' => Tools::planTesterChanges($updateStatus)]; $results[] = $tester; // Create new or update if (count($tester['input-ids']) > 0 && !empty($browsers)) { $this->model->create(['plan_id' => $planId, 'user_id' => $testerId, 'browsers' => $browsers]); } } } catch (\Exception $e) { $errorMsg = $e->getMessage(); $redirect = true; } catch (QueryException $e) { $errorMsg = $e->getErrors(); $redirect = true; } catch (ModelNotFoundException $e) { $errorMsg = $e->getErrors(); $redirect = true; } // Redirect if errors if ($redirect) { // Rollback DB::rollback(); // Log to system Tools::log($errorMsg, $testersData); return false; } // Commit all changes DB::commit(); return $results; }
/** * Store a newly created resource in storage * * @param TicketsFormRequest $request * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|void */ public function store(TicketsFormRequest $request) { // Save data to session $tickets = json_decode($request->get('tickets_obj'), true); foreach ($tickets as $ticket) { $ticket['desc'] = Tools::convertDoubleQuotes($ticket['desc']); $results[] = $ticket; } Session::put('mophie_testplanner.tickets', $results); return redirect('tester/build'); }
/** * Handle a registration request for the application. * * @param RegisterFormRequest $request * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|void */ public function postRegister(RegisterFormRequest $request, UserRoleApi $userRoleApi) { $redirect = false; $errorMsg = ''; // Start transaction DB::beginTransaction(); // Register new user try { $user = $this->user->where('email', '=', $request->email)->first(); $userId = isset($user->id) ? $user->id : false; // Save user if (!$userId) { $this->user->first_name = $request->first_name; $this->user->last_name = $request->last_name; $this->user->email = $request->email; $this->user->password = bcrypt($request->password); $this->user->active = 1; $this->user->save(); $userId = $this->user->id; } // Roles that were selected to be registered $selectedRoles = explode(',', $request->get('role')); // Find all roles for this user $userRoles = $this->user->findOrNew($userId)->roles(); $existingRoles = []; foreach ($userRoles->get() as $user) { $existingRoles[] = $user->role_id; } // Identical user with all the roles, throw error if (isset($userId) && $userRoles->count() == 3) { throw new Exception(config('testplanner.messages.users.identical_user')); } // Throw error if role already exists if (count(array_diff($selectedRoles, $existingRoles)) == 0) { throw new Exception(config('testplanner.messages.users.identical_role')); } // Add user's role $userRoleApi->addRoles($userId, $selectedRoles); } catch (\Exception $e) { $errorMsg = $e->getMessage(); $redirect = true; } catch (QueryException $e) { $errorMsg = $e->getErrors(); $redirect = true; } catch (ModelNotFoundException $e) { $errorMsg = $e->getErrors(); $redirect = true; } // Redirect if errors if ($redirect) { // Rollback DB::rollback(); // Log specific technical message Tools::log($errorMsg, array_except($request->all(), ['_token', 'created_from', 'created_to', 'password', 'password_confirmation'])); // Return JSON error response return response()->json(['type' => 'error', 'msg' => config('testplanner.messages.users.new_error')]); } // Commit all changes DB::commit(); // Flash message so it could be shown once redirected by AJAX call Session::flash('flash_success', config('testplanner.messages.users.new')); // Return JSON success message and redirect url return response()->json(['type' => 'success', 'redirect_url' => url('user/all')]); }
/** * Get overall ticket status for each tester * * @param $plan * @param $testers * @param null $model * @return mixed */ public function getTestersTicketsStatus($plan, $testers, $model = null) { $totalBrowsers = 0; $allStatus = []; foreach ($testers as $eachTester) { // Total of assigned browsers $totalBrowsersToTest = count(explode(',', $eachTester->browsers)); // Overall count of all browsers for each tester $totalBrowsers += $totalBrowsersToTest; // Responses and total $responses = $eachTester->tickets()->where('plan_id', '=', $plan->id)->get(); $totalResponses = count($responses); // If total responses already doesn't match, no need to continue further, // status is still new if ($totalResponses != $totalBrowsersToTest) { $allStatus[] = 'new'; continue; } // Don't need to check each status, just get the last outcome foreach ($responses as $ticket) { $allStatus[] = $ticket->status; } } $overallStatus = Tools::getOverallStatus($allStatus, $totalBrowsers); $plan->update(['status' => $overallStatus]); if ($model == 'single') { $results['status'] = $overallStatus; } else { $results = $plan->description; } return $results; }
/** * Get all issues, also specific issues by build version ID * * @param $buildVersionId * @return array */ public function jiraIssuesByVersion($buildVersionId) { try { // Get JIRA issues from cache, if it doesn't exist, // pull items from Jira API if (Cache::has('jira_issues')) { $data = Cache::get('jira_issues'); } else { $options['query_url'] = $this->_issueQueryUrl; $data = $this->_connect($options); Cache::put('jira_issues', $data, config('testplanner.jira.cache.issues_lifetime')); } // Grab only specific issues to be auto filled if (isset($data)) { $allIssues = []; $specificIssues = []; foreach ($data->issues as $issue) { $issueId = $issue->id; $key = $issue->key; $fixVersions = $issue->fields->fixVersions; $summary = $issue->fields->summary; foreach ($fixVersions as $fixVersion) { if ($fixVersion->id == $buildVersionId) { $specificIssues[$issueId] = $key . ': ' . $summary; } } // Grab all issues to be shown as dropdown $allIssues[] = $issue->key . ': ' . $issue->fields->summary; } ksort($allIssues); } } catch (\Exception $e) { Tools::log('cURL errors: ' . $e->getErrors(), $data); } // Set default array, therefore it shows blank ticket block if (count($specificIssues) == 0) { $specificIssues[0] = ''; } $results = ['allIssues' => $allIssues, 'specificIssues' => $specificIssues]; return $results; }
/** * Setup additional keys/values when searching all created * * @param $searchTerms * @param $roles * @param $adminId * @return array|mixed */ public function prepareSearchAllCreated($searchTerms, $roles, $adminId) { // If user has root privileges, get all the plans that were created. // Otherwise just get the plans created with administrator privilege. $adminList = []; $roleName = ''; if (in_array('root', $roles)) { $userId = 0; $roleName = 'root'; } // Display selected creator of the plan if (isset($adminId)) { $userId = $adminId; } // Administrators who created plans $admins = $this->userApi->getAllUsersByRole(['root', 'administrator']); // Set up dropdown list of all admins $adminsList = Tools::getUsersDropdrownOptions($admins, 'admin'); $columns = ['description', 'first_name', 'last_name', 'status', 'created_at', 'updated_at', 'edit']; $results = $this->tablesApi->searchPlans($searchTerms, $columns); $results += ['userId' => $userId, 'role' => $roleName, 'adminsList' => $adminsList]; return $results; }
/** * Save tester's ticket responses * * @param $planData * @return string */ public function saveResponse($planData) { $totalTickets = count($planData['tickets_responses']); $allStatus = []; $redirect = false; $errorMsg = ''; DB::beginTransaction(); try { // Determine ticket status foreach ($planData['tickets_responses'] as $browser => $rows) { $totalRows = count($rows['tickets']); $completed = 0; $incomplete = 0; foreach ($rows['tickets'] as $ticket) { if (!isset($ticket['test_status'])) { $incomplete += 1; } else { $completed += 1; } } if ($incomplete == $totalRows) { $ticketStatus = 'new'; } elseif ($completed == $totalRows) { if ($rows['ticket_status'] == 'complete' && $ticket['original_data'] == 'modified') { $ticketStatus = 'update'; } else { $ticketStatus = 'complete'; } } else { $ticketStatus = 'progress'; } // Collect status for every tickets $allStatus[] = $ticketStatus; // Create or update ticket response $this->model->updateOrCreate(['id' => $rows['ticket_resp_id']], ['plan_id' => $planData['plan_id'], 'tester_id' => $planData['tester_id'], 'browser' => $browser, 'responses' => serialize($rows['tickets']), 'status' => $ticketStatus]); } } catch (\Exception $e) { $errorMsg = $e->getMessage(); $redirect = true; } catch (ValidationException $e) { $errorMsg = $e->getErrors(); $redirect = true; } catch (QueryException $e) { $errorMsg = $e->getErrors(); $redirect = true; } catch (ModelNotFoundException $e) { $errorMsg = $e->getErrors(); $redirect = true; } // Redirect if errors if ($redirect) { // Rollback DB::rollback(); // Log to system Tools::log($errorMsg, $planData); return false; } // Commit all changes DB::commit(); $results = Tools::getOverallStatus($allStatus, $totalTickets); return $results; }
/** * Calculate and convert to a human readable format * * @param $value * @return mixed */ public function getCreatedAtAttribute($value) { return Tools::timeDifference($value); }
/** * Update user account information * * @param $request * @return bool */ public function updateUser($request) { $redirect = false; $errorMsg = ''; // Start transaction DB::beginTransaction(); // Create new user try { $userId = $request->get('user_id'); // Update user info $user = $this->model->find($userId); $update = $user->update(['first_name' => $request->get('first_name'), 'last_name' => $request->get('last_name'), 'email' => $request->get('email'), 'active' => $request->get('active'), 'password' => bcrypt($request->get('password'))]); // Remove all existing roles for user if (isset($user->id)) { $user->roles()->delete(); } // Update user roles $newRoles = explode(',', $request->get('role')); if (count($newRoles) > 0) { foreach ($newRoles as $key => $value) { $this->userRoleModel->create(['user_id' => $userId, 'role_id' => $value]); } } } catch (\Exception $e) { $errorMsg = $e->getMessage(); $redirect = true; } catch (QueryException $e) { $errorMsg = $e->getErrors(); $redirect = true; } catch (ModelNotFoundException $e) { $errorMsg = $e->getErrors(); $redirect = true; } // Redirect if errors if ($redirect) { // Rollback DB::rollback(); // Log specific technical message Tools::log($errorMsg, array_except($request->all(), ['_token', 'created_from', 'created_to', 'password', 'password_confirmation'])); return false; } // Commit all changes DB::commit(); return true; }
public function searchActivities($searchTerms) { // Remove certain keys when querying $filters = array_except($searchTerms, ['created_from', 'created_to', 'sortBy', 'order', 'page']); $perPage = config('testplanner.tables.pagination.lists'); $page = isset($searchTerms['page']) ? $searchTerms['page'] : 1; $url = parse_url(Request::url()); // Default sort and order $sortBy = empty($searchTerms['sortBy']) ? 'created_at' : $searchTerms['sortBy']; $order = empty($searchTerms['order']) ? 'DESC' : $searchTerms['order']; $from = !empty($searchTerms['created_from']) ? Tools::dbDateConverter($searchTerms['created_from'], '00:00:00') : null; $to = !empty($searchTerms['created_to']) ? Tools::dbDateConverter($searchTerms['created_to'], '23:59:59') : null; $query = DB::table('streams'); // Remaining where conditions foreach ($filters as $key => $value) { if (!empty($value)) { $query->where($key, 'LIKE', '%' . $value . '%'); } } if (isset($from) && isset($to)) { $query->whereBetween('created_at', [$from, $to]); } $totalCount = $query->count(); $query->orderBy($sortBy, $order)->take($perPage)->offset(($page - 1) * $perPage); // Manual paginator if (isset($searchTerms['page'])) { $list = new LengthAwarePaginator($query->get(), $totalCount, $perPage, $page, ["path" => $url['path']]); } else { $list = $query->paginate($perPage); } // Columns $columns = ['activity', 'created_at']; // Prepare columns to be shown $table = $this->prepare('order', $columns, 'ActivityStreamController@index'); $results = ['activities' => $list, 'totalCount' => $totalCount, 'order' => $order, 'link' => $searchTerms, 'columns' => $table['columns'], 'columnsLink' => $table['columns_link']]; return $results; }