public static function exportCommentsForText($projectId, $textId, $params) { $project = new ProjectModel($projectId); $text = new TextModel($project, $textId); $usxHelper = new UsxHelper($text->content); $textInfo = $usxHelper->getMetadata(); $questionlist = new QuestionAnswersListModel($project, $textId); $questionlist->read(); $dl = array('complete' => true, 'inprogress' => false, 'answerCount' => 0, 'commentCount' => 0, 'totalCount' => 0, 'xml' => "<CommentList>\n"); foreach ($questionlist->entries as $question) { if (!array_key_exists('isArchived', $question) || !$question['isArchived']) { foreach ($question['answers'] as $answerId => $answer) { if (!$params['exportFlagged'] || array_key_exists('isToBeExported', $answer) && $answer['isToBeExported']) { // if the answer is tagged with an export tag $dl['answerCount']++; $dl['xml'] .= self::makeCommentXml($answer['tags'], $answer['score'], $textInfo, $answerId, $answer); if ($params['exportComments']) { foreach ($answer['comments'] as $commentId => $comment) { $dl['xml'] .= self::makeCommentXml(array(), 0, $textInfo, $commentId, $comment); $dl['commentCount']++; } } } } } } $dl['totalCount'] = $dl['answerCount'] + $dl['commentCount']; $dl['xml'] .= "</CommentList>"; $dl['filename'] = 'Comments_sf_' . date('Ymd_Gi') . '.xml'; //$dl['filename'] = preg_replace("([^\w\d\-]|[\.]{2,})", '_', $filename) . '.xml'; return $dl; }
/** * @param string $projectId * @param string $textId * @param string $userId * @returns array - the DTO array */ public static function encode($projectId, $textId, $userId) { $user = new UserModel($userId); $project = new SfchecksProjectModel($projectId); $text = new TextModel($project, $textId); $questionList = new QuestionAnswersListModel($project, $textId); $questionList->read(); $data = array(); $data['text'] = JsonEncoder::encode($text); $data['archivedQuestions'] = array(); foreach ($questionList->entries as $questionData) { $question = new QuestionModel($project, $questionData['id']); if ($question->isArchived) { // Just want answer count, not whole list $questionData['answerCount'] = count($questionData['answers']); $responseCount = 0; // "Reponses" = answers + comments foreach ($questionData['answers'] as $a) { $commentCount = count($a['comments']); $responseCount += $commentCount + 1; // +1 for this answer } $questionData['responseCount'] = $responseCount; unset($questionData['answers']); $questionData['dateModified'] = $question->dateModified->asDateTimeInterface()->format(\DateTime::RFC2822); $data['archivedQuestions'][] = $questionData; } } $data['rights'] = RightsHelper::encode($user, $project); $data['bcs'] = BreadCrumbHelper::encode('settings', $project, $text, null); return $data; }
/** * @param string $projectId * @param string $textId * @param string $userId * @return array - the DTO array * @throws ResourceNotAvailableException */ public static function encode($projectId, $textId, $userId) { $project = new SfchecksProjectModel($projectId); $text = new TextModel($project, $textId); $user = new UserModel($userId); if (($project->isArchived || $text->isArchived) && $project->users[$userId]->role != ProjectRoles::MANAGER) { throw new ResourceNotAvailableException("This Text is no longer available. If this is incorrect contact your project manager."); } $questionList = new QuestionAnswersListModel($project, $textId); $questionList->read(); $data = array(); $data['rights'] = RightsHelper::encode($user, $project); $data['entries'] = array(); $data['project'] = array('id' => $projectId, 'name' => $project->projectName, 'slug' => $project->databaseName(), 'allowAudioDownload' => $project->allowAudioDownload); $data['text'] = JsonEncoder::encode($text); $usxHelper = new UsxHelper($text->content); $data['text']['content'] = $usxHelper->toHtml(); foreach ($questionList->entries as $questionData) { $question = new QuestionModel($project, $questionData['id']); if (!$question->isArchived) { // Just want answer count, not whole list $questionData['answerCount'] = count($questionData['answers']); $responseCount = 0; // "Reponses" = answers + comments foreach ($questionData['answers'] as $a) { $commentCount = count($a['comments']); $responseCount += $commentCount + 1; // +1 for this answer } $questionData['responseCount'] = $responseCount; unset($questionData['answers']); $questionData['dateCreated'] = $question->dateCreated->asDateTimeInterface()->format(\DateTime::RFC2822); $data['entries'][] = $questionData; } } // sort Questions with newest at the top usort($data['entries'], function ($a, $b) { $sortOn = 'dateCreated'; if (array_key_exists($sortOn, $a) && array_key_exists($sortOn, $b)) { return strtotime($a[$sortOn]) < strtotime($b[$sortOn]) ? 1 : -1; } else { return 0; } }); $data['count'] = count($data['entries']); return $data; }
public static function UserEngagementReport($projectId) { $project = ProjectModel::getById($projectId); $output = str_pad('**** User Engagement Report ****', 120, " ", STR_PAD_BOTH) . "\n"; $output .= str_pad(date(DATE_RFC2822), 120, " ", STR_PAD_BOTH) . "\n\n"; $data = array(); $activeUsers = array(); $managerUsers = array(); $inactiveUsers = array(); $invalidUsers = array(); $listModel = new UserListProjectModel($projectId); $listModel->read(); if ($listModel->count > 0) { $textListModel = new TextListModel($project); $textListModel->read(); $questions = array(); foreach ($textListModel->entries as $text) { $questionListModel = new QuestionAnswersListModel($project, $text['id']); $questionListModel->read(); $questions = array_merge($questions, array_map(function ($q) use($text) { $q['textRef'] = $text['id']; return $q; }, $questionListModel->entries)); } $answerCtr = 0; $commentCtr = 0; foreach ($listModel->entries as $user) { $userModel = new UserModel($user['id']); $user['isActive'] = $userModel->active; $user['questions'] = 0; $user['texts'] = 0; $user['answers'] = 0; $user['comments'] = 0; $user['responses'] = 0; $user['textIds'] = array(); if (!$user['isActive']) { if (!$user['email']) { $user['email'] = $userModel->emailPending; } array_push($invalidUsers, $user); continue; } if ($project->users->offsetExists($user['id'])) { $user['role'] = $project->users[$user['id']]->role; } else { $user['role'] = ProjectRoles::NONE; } $answerCtr = 0; $commentCtr = 0; foreach ($questions as $question) { $responses = 0; foreach ($question['answers'] as $answer) { if (!$answer['content']) { continue; } $answerCtr++; foreach ($answer['comments'] as $comment) { if (!$comment['content']) { continue; } $commentCtr++; if ($comment['userRef'] && strval($comment['userRef']) == $user['id']) { $user['comments']++; $user['responses']++; array_push($user['textIds'], $question['textRef']); $responses++; } } if ($answer['userRef'] && strval($answer['userRef']) == $user['id']) { $user['answers']++; $user['responses']++; array_push($user['textIds'], $question['textRef']); $responses++; } } if ($responses > 0) { $user['questions']++; } } $user['texts'] = count(array_unique($user['textIds'])); if ($user['role'] == ProjectRoles::MANAGER) { array_push($managerUsers, $user); } elseif ($user['responses'] > 0) { array_push($activeUsers, $user); } else { array_push($inactiveUsers, $user); } } $output .= $project->projectName . " Project\n"; $output .= "Texts (T's) in Project: " . $textListModel->count . "\n"; $output .= "Questions (Q's) in Project: " . count($questions) . "\n"; $output .= "Responses (R's) in Project (Answers + Comments): " . ($answerCtr + $commentCtr) . "\n"; $output .= "Answers (A's) in Project: " . $answerCtr . "\n"; $output .= "Comments (C's) in Project: " . $commentCtr . "\n"; } else { $output .= "This project has no users\n\n"; } $sortByResponses = function ($a, $b) { if ($a['responses'] > $b['responses']) { return -1; } elseif ($a['responses'] < $b['responses']) { return 1; } else { if ($a['answers'] > $b['answers']) { return -1; } elseif ($a['answers'] < $b['answers']) { return 1; } else { if ($a['comments'] > $b['comments']) { return -1; } elseif ($a['comments'] < $b['comments']) { return 1; } else { return strcmp($a['username'], $b['username']); } } } }; $sortByName = function ($a, $b) { return strcasecmp($a['name'], $b['name']); }; usort($activeUsers, $sortByResponses); usort($managerUsers, $sortByResponses); usort($inactiveUsers, $sortByName); usort($invalidUsers, $sortByName); $output .= "\n\nManagers: " . count($managerUsers) . "\n" . str_pad("Name", 30) . str_pad("Email", 35) . str_pad("Username", 25) . str_pad("R's", 5) . str_pad("A's", 5) . str_pad("C's", 5) . str_pad("Q's", 5) . str_pad("T's", 5) . "\n\n"; foreach ($managerUsers as $user) { $output .= str_pad($user['name'], 30) . str_pad($user['email'], 35) . str_pad($user['username'], 25) . str_pad($user['responses'], 5) . str_pad($user['answers'], 5) . str_pad($user['comments'], 5) . str_pad($user['questions'], 5) . str_pad($user['texts'], 5) . "\n"; } $output .= "\n\nActive Users: " . count($activeUsers) . "\n" . str_pad("Name", 30) . str_pad("Email", 35) . str_pad("Username", 25) . str_pad("R's", 5) . str_pad("A's", 5) . str_pad("C's", 5) . str_pad("Q's", 5) . str_pad("T's", 5) . "\n\n"; foreach ($activeUsers as $user) { $output .= str_pad($user['name'], 30) . str_pad($user['email'], 35) . str_pad($user['username'], 25) . str_pad($user['responses'], 5) . str_pad($user['answers'], 5) . str_pad($user['comments'], 5) . str_pad($user['questions'], 5) . str_pad($user['texts'], 5) . "\n"; } $output .= "\n\nInactive Users (never engaged): " . count($inactiveUsers) . "\n" . str_pad("Name", 30) . str_pad("Email", 35) . str_pad("Username", 25) . "\n\n"; foreach ($inactiveUsers as $user) { $output .= str_pad($user['name'], 30) . str_pad($user['email'], 35) . str_pad($user['username'], 25) . "\n"; } $output .= "\n\nInvited Users (but never validated or logged in): " . count($invalidUsers) . "\n" . str_pad("Name", 30) . str_pad("Email", 35) . str_pad("Username", 25) . "\n\n"; foreach ($invalidUsers as $user) { $output .= str_pad($user['name'], 30) . str_pad($user['email'], 35) . str_pad($user['username'], 25) . "\n"; } $data['output'] = $output; $data['result'] = array('managerUsers' => $managerUsers, 'activeUsers' => $activeUsers, 'inactiveUsers' => $inactiveUsers, 'invitedUsers' => $invalidUsers); return $data; }
public function listQuestionsWithAnswers() { $questionList = new QuestionAnswersListModel($this->_projectModel, $this->id->asString()); $questionList->read(); return $questionList; }