public static function transcript($params)
 {
     $db = Settings::getProtected('db');
     // Parse parameters
     $format = Utils::getFormat($params['args'], 1, 3);
     $projectType = Utils::getProjectType($params['args']);
     $projectSlugIndex = $projectType == 'system' ? 0 : 2;
     $projectSlug = $params['args'][$projectSlugIndex];
     $project = new Project($projectSlug);
     $user = User::getAuthenticatedUser();
     // Make sure the user has access to download this
     RoleController::forceClearance(array('project.admin', 'project.owner', 'system.admin'), $user, array('project' => $project));
     switch ($params['method']) {
         // GET: download project transcript
         case 'GET':
             // Load project
             $project->getItems();
             $finalText = "";
             // Go through each item and get the relevant transcript
             foreach ($project->items as $item) {
                 $proofTranscripts = $db->loadItemTranscripts($item['project_id'], $item['id'], "proof");
                 $reviewTranscripts = $db->loadItemTranscripts($item['project_id'], $item['id'], "review");
                 // If there are reviewed transcripts, get the diff of those
                 $fieldTranscripts = array();
                 if (count($reviewTranscripts) > 0) {
                     if (count($reviewTranscripts) > 1) {
                         $text = Transcript::diff($reviewTranscripts);
                         foreach ($reviewTranscripts as $transcript) {
                             $fieldTranscripts[] = $transcript['fields'];
                         }
                     } else {
                         $text = $reviewTranscripts[0]['transcript'];
                         $fieldTranscripts[] = $reviewTranscripts[0]['fields'];
                     }
                 } else {
                     if (count($proofTranscripts) > 0) {
                         // If there are proofed transcripts, get the diff of those
                         if (count($proofTranscripts) > 1) {
                             $text = Transcript::diff($proofTranscripts);
                             foreach ($proofTranscripts as $transcript) {
                                 $fieldTranscripts[] = $transcript['fields'];
                             }
                         } else {
                             $text = $proofTranscripts[0]['transcript'];
                             $fieldTranscripts[] = $proofTranscripts[0]['fields'];
                         }
                     } else {
                         // Otherwise just get the item's original transcript
                         $text = $item['transcript'];
                     }
                 }
                 // Get the unique values for each of the item fields (if there are any)
                 $fields = array();
                 foreach ($fieldTranscripts as $transcript) {
                     // Convert from JSON string to object
                     $field = json_decode($transcript);
                     // Loop through the field transcript's properties
                     foreach ($field as $key => $value) {
                         // If the key isn't in the array, add it as an empty array
                         if (!array_key_exists($key, $fields)) {
                             $fields[$key] = array();
                         }
                         // If the value isn't in the array for that key, add it
                         if (!in_array($value, $fields[$key])) {
                             $fields[$key][] = $value;
                         }
                     }
                 }
                 // And serialize the fields to strings
                 $fieldStrings = array();
                 foreach ($fields as $field => $values) {
                     // If more than one, put in {a|b|c} format, otherwise just put the value
                     if (count($values) > 1) {
                         $str = "{" . join("|", $values) . "}";
                     } else {
                         $str = $values[0];
                     }
                     $fieldStrings[$field] = $str;
                 }
                 // Get the list of proofers/reviewers as comma-separated usernames
                 $stats = $db->getStatsForItem($item['id']);
                 $proofers = array();
                 $reviewers = array();
                 foreach ($stats['proofs'] as $stat) {
                     array_push($proofers, $stat['user']);
                 }
                 foreach ($stats['reviews'] as $stat) {
                     array_push($reviewers, $stat['user']);
                 }
                 $proofers = join(',', $proofers);
                 $reviewers = join(',', $reviewers);
                 // If there's a project template, use it, otherwise use default from config
                 $defaultTemplate = Settings::getProtected("download_template");
                 $template = $project->downloadTemplate != '' ? $project->downloadTemplate : $defaultTemplate;
                 // Apply the download template
                 $finalText .= TranscriptController::replaceVariables($template, array('transcript' => $text, 'project' => $project, 'item' => $item, 'proofers' => $proofers, 'reviewers' => $reviewers, 'fields' => $fieldStrings));
             }
             switch ($format) {
                 case 'json':
                     echo json_encode(array('transcript' => htmlentities($finalText)));
                     break;
                 case 'html':
                     $filename = "{$project->slug}.txt";
                     header("Content-Type: text/html");
                     header("Content-Disposition: attachment; filename={$filename}");
                     echo trim(str_replace('\\n', "\n", $finalText));
                     break;
             }
             break;
     }
 }
 public static function getNextAvailableItem($params)
 {
     $username = $params['username'];
     $projectSlug = $params['projectSlug'];
     $type = $params['type'];
     $role = $type . "er";
     $success = false;
     $errorCode = '';
     $db = Settings::getProtected('db');
     $auth = Settings::getProtected('auth');
     // Make sure we're authenticated as the user we say we are
     $auth->forceAuthentication();
     $loggedInUsername = $auth->getUsername();
     if ($username != $loggedInUsername) {
         $code = "not-authenticated-as-correct-user";
     }
     // Load user
     $user = new User($username);
     // Does this user belong to the project?
     if (!$user->isMember($projectSlug, $role)) {
         $code = "not-a-member";
     }
     // Does this user already have an item from this project?
     if ($user->hasProjectItem($projectSlug)) {
         $code = "has-unfinished-item";
     }
     // Load the user's queue
     $userQueue = new Queue("user.{$type}:{$username}", false, array('include-removed' => true));
     $userQueueItems = $userQueue->getItems();
     // Load the project's queue
     $queue = new Queue("project.{$type}:{$projectSlug}");
     $queueItems = $queue->getItems();
     // Go through the project queue and get the first item the user hasn't yet done
     foreach ($queueItems as $item) {
         if (!in_array($item, $userQueueItems)) {
             $nextItem = $item;
             break;
         }
     }
     if (isset($nextItem) && $nextItem->item_id != -1) {
         // Concatenate proofed transcripts
         if ($type == 'review') {
             // Get proofed transcripts for the new item
             $transcripts = $db->loadItemTranscripts($nextItem->project_id, $nextItem->item_id, 'proof');
             // Only diff them if there's more than one
             if (count($transcripts) > 1) {
                 $transcriptText = Transcript::diff($transcripts);
             } else {
                 $transcriptText = $transcripts[0]['transcript'];
             }
             // Only get the fields for the first transcript
             $transcriptFields = $transcripts[0]['fields'];
             // Create transcript and add to the database
             $transcript = new Transcript();
             $transcript->setText($transcriptText);
             $transcript->setFields($transcriptFields);
             $transcript->save(array('item' => $nextItem, 'status' => 'draft', 'type' => 'review'));
         }
         // Reload the user's queue, this time ignoring items they've already done
         // Add it to the user's queue
         $userQueue = new Queue("user.{$type}:{$username}", false);
         $userQueue->add($nextItem);
         $userQueue->save();
         // Remove it from the project queue
         $queue->remove($nextItem);
         $queue->save();
         $success = true;
         $code = $nextItem->item_id;
     } else {
         $code = "no-item-available";
     }
     return array('status' => $success, 'code' => $code);
 }