public static function transcript($params)
 {
     $format = Utils::getFormat($params['args'], 0, 2);
     $projectType = Utils::getProjectType($params['args']);
     $projectSlugIndex = $projectType == 'system' ? 0 : 2;
     $projectSlug = $params['args'][$projectSlugIndex];
     $itemIndex = $projectType == 'system' ? 1 : 3;
     $itemId = $params['args'][$itemIndex];
     $owner = $projectType == 'user' ? $params['args'][1] : '';
     $user = User::getAuthenticatedUser();
     switch ($params['method']) {
         // POST: Post transcript for item
         case 'POST':
             $proofType = Utils::POST('proofType');
             $proofUser = Utils::POST('proofUser');
             $transcriptText = Utils::POST('transcript');
             $transcriptStatus = Utils::POST('status');
             // draft, completed, reviewed
             $fields = Utils::POST('fields');
             $role = $proofType . "er";
             // Make sure they have access to the item
             if ($proofType == 'edit' || $proofUser != '') {
                 // For editing an item or a specific proof/review, user must be project admin or site admin
                 RoleController::forceClearance(array('project.admin', 'project.owner', 'system.admin'), $user, array('project' => $project));
             } else {
                 // User has to be a member of the project
                 if (!$user->isMember($projectSlug, $role, $owner)) {
                     Utils::redirectToDashboard("", $i18n->t("error.not_a_member"));
                     return;
                 }
             }
             // If we're looking at an existing proof/review, load it for that user
             // Otherwise load it for the existing user
             $username = $proofUser != '' ? $proofUser : $user->username;
             // Load the item
             $itemObj = new Item($itemId, $projectSlug, $username, $proofType);
             // Make sure item exists (if it fails, it'll return a boolean)
             if ($itemObj->item_id == -1) {
                 Utils::redirectToDashboard("", $i18n->t("error.nonexistent_item"));
                 return;
             }
             // Make sure the user has this item in their queue
             // TODO: Finish
             if ($proofType == 'edit') {
                 // Set the transcript and save the item
                 $itemObj->transcript = $transcriptText;
                 $itemObj->save();
             } else {
                 // Save transcript to database
                 $transcript = new Transcript();
                 $transcript->load(array('item' => $itemObj, 'type' => $proofType));
                 $transcript->setText($transcriptText);
                 $transcript->setFields($fields);
                 $transcript->save(array('item' => $itemObj, 'status' => $transcriptStatus, 'type' => $proofType));
                 // If we're looking at a user's proof or review, or if the transcript has already been
                 // completed/reviewed, then we don't want to update scoring and move the item through
                 // the workflow index
                 if ($proofUser == '' && $transcriptStatus != 'draft') {
                     $scoring = Settings::getProtected('scoring');
                     // Notifications
                     if ($transcriptStatus == 'reviewed') {
                         // Bump user's score up if they haven't already reviewed this item
                         $user->updateScoreForItem($itemObj->item_id, $itemObj->project_id, $scoring['review'], 'review');
                         // Notify project owner that review is complete
                     } else {
                         if ($transcriptStatus == 'completed') {
                             // Bump user's score up if they haven't already proofed this item
                             $user->updateScoreForItem($itemObj->item_id, $itemObj->project_id, $scoring['proof'], 'proof');
                         }
                     }
                     // Remove from user's queue
                     $userQueue = new Queue("user.{$proofType}:{$user->username}");
                     $userQueue->remove($itemObj);
                     $userQueue->save();
                     // Increase item's workflow index
                     $itemObj->workflow_index += 1;
                     // And save it
                     $itemObj->save();
                     // Load the project
                     $project = new Project($itemObj->project_slug);
                     // Get next workflow step
                     $workflow = new Workflow($project->workflow);
                     $workflow->setIndex($itemObj->workflow_index);
                     $workflowQueue = $workflow->getWorkflow();
                     if ($itemObj->workflow_index < count($workflowQueue)) {
                         // Process next step
                         $workflow->next($itemObj);
                     } else {
                         // The item is complete
                         $itemObj->setStatus("completed");
                     }
                 }
             }
             echo json_encode(array("statuscode" => "success"));
             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);
 }