public static function load($name, $options = array()) { $db = Settings::getProtected('db'); $auth = Settings::getProtected('auth'); $auth->forceAuthentication(); $username = $auth->getUsername(); if (array_key_exists('include-removed', $options) && $options['include-removed'] == true) { $includeRemoved = true; } else { $includeRemoved = false; } $items = array(); $results = $db->loadQueue($name, $includeRemoved); if (strpos($name, 'proof') != false) { $type = 'proof'; } else { if (strpos($name, 'review') != false) { $type = 'review'; } } foreach ($results as $result) { $itemID = $result['item_id']; $projectID = $result['project_id']; $item = new Item($db); $item->loadWithProjectID($itemID, $projectID, $username, $type); array_push($items, $item); } return $items; }
public function Item($itemId = '', $projectSlug = '', $username = '', $type = 'proof') { $this->db = Settings::getProtected('db'); if ($itemId && $projectSlug) { $this->load($itemId, $projectSlug, $username, $type); } }
public static function sendMessage($to, $subject, $message) { $admin_email = Settings::getProtected('admin_email'); $headers = "From: {$admin_email}" . "\r\n"; $headers .= "Reply-To: {$admin_email}" . "\r\n"; $headers .= "X-Mailer: PHP/" . phpversion(); return mail($to, $subject, $message, $headers); }
public static function forceClearance($roles, $user, $params = array(), $error = 'error.insufficient_rights') { $app_url = Settings::getProtected('app_url'); $i18n = new I18n("../translations", Settings::getProtected('language')); if (!self::verify($roles, $user, $params)) { Utils::redirectToDashboard('', $i18n->t($error)); return false; } return true; }
public function ItemTypeUploader($projectSlug) { $this->itemData = array(); $this->items = array(); $this->files = array(); $this->projectSlug = $projectSlug; $sysPath = Settings::getProtected('sys_path'); $this->tempDir = "{$sysPath}/htdocs/media/temp/{$this->projectSlug}"; $project = new Project($projectSlug); $this->projectId = $project->project_id; }
public static function redirectToDashboard($message, $error) { $app_url = Settings::getProtected('app_url'); if ($message != '') { $_SESSION['ub_message'] = trim($message); } if ($error != '') { $_SESSION['ub_error'] = trim($error); } header("Location: {$app_url}"); }
public static function load($params) { $item = $params['item']; $type = $params['type']; $auth = Settings::getProtected('auth'); $auth->forceAuthentication(); $username = $auth->getUsername(); $user = new User($username); // Make sure user has access (member of project, item is in queue) // TODO: Finish return $user->loadTranscript($item, $type); }
public static function admin($params) { $format = Utils::getFormat($params['args'], 0, 2); $app_url = Settings::getProtected('app_url'); $db = Settings::getProtected('db'); $user = User::getAuthenticatedUser(); // Make sure the user is at least creator or admin RoleController::forceClearance(array('system.creator', 'system.admin'), $user); // Get latest work for the user's projects $latestWorkList = $db->getAdminProjectsLatestWork($user->username, 5); $latestWork = array(); foreach ($latestWorkList as $work) { $qn = $work['queue_name']; $type = substr($qn, strpos($qn, '.') + 1, strpos($qn, ':') - strpos($qn, '.') - 1); $username = substr($qn, strpos($qn, ':') + 1); $item = new Item($work['item_id'], $work['project_slug']); $project = new Project($work['project_slug']); if ($item->project_type == 'system') { $transcriptURL = "{$app_url}/projects/" . $item->project_slug . "/items/" . $item->item_id . "/{$type}/{$username}"; $editURL = "{$app_url}/projects/" . $item->project_slug . "/items/" . $item->item_id . "/edit"; } else { $transcriptURL = "{$app_url}/" . $item->project_owner . "/projects/" . $item->project_slug . "/items/" . $item->item_id . "/{$type}/{$username}"; $editURL = "{$app_url}/" . $item->project_owner . "/projects/" . $item->project_slug . "/items/" . $item->item_id . "/edit"; } array_push($latestWork, array('item' => $item->getResponse(), 'project' => $project->getResponse(), 'type' => $type, 'username' => $username, 'date_completed' => $work['date_completed'], 'transcript_url' => $transcriptURL, 'edit_url' => $editURL)); } $newestMembers = $db->getNewestProjectMembers($user->username, 5); // Only get list of users if they're a site admin $users = array(); if ($user->role == 'admin') { $usernameList = $db->getUsers(); foreach ($usernameList as $username) { $tempUser = new User($username['username']); $tempUserArray = $tempUser->getResponse(); // Get list of projects they're working on $projects = $db->getUserProjectsWithStats($username['username']); $tempUserArray['projects'] = $projects; array_push($users, $tempUserArray); } } $response = array('page_title' => 'Admin Dashboard', 'user' => $user->getResponse(), 'latest_work' => $latestWork, 'newest_members' => $newestMembers, 'users' => $users); switch ($format) { case 'json': echo json_encode($response); break; case 'html': Template::render('admin_dashboard', $response); break; } }
public static function render($page, $options, $theme = 'core') { $cached = Settings::getProtected('theme_cached'); // If there's a system-wide theme in config.yaml, use it as the default instead $settingsTheme = Settings::getProtected('theme'); if ($settingsTheme != 'core' && $theme == 'core') { $theme = $settingsTheme; } if ($cached) { $twig_opts = array('cache' => '../templates/cache'); } else { $twig_opts = array(); } $loader = new Twig_Loader_Filesystem(array("../templates/{$theme}", "../templates/core")); $twig = new Twig_Environment($loader, $twig_opts); $options['title'] = Settings::getProtected('title'); $options['app_url'] = Settings::getProtected('app_url'); $options['google_analytics'] = Settings::getProtected('google_analytics'); $options['theme_root'] = $options['app_url'] . "/themes/{$theme}"; $options['i18n'] = new I18n("../translations", Settings::getProtected('language')); $options['message'] = Utils::SESSION('ub_message'); $options['error'] = Utils::SESSION('ub_error'); $auth = Settings::getProtected('auth'); if ($auth->authenticated()) { $username = $auth->getUsername(); if (isset($username)) { $options['username'] = $auth->getUsername(); } } // Prepare the methods they want if (array_key_exists('registered_methods', $options)) { // TODO: get user token $userToken = 'foo'; $appName = 'unbindery'; $privateKey = Settings::getProtected('private_key'); $devKeys = Settings::getProtected('devkeys'); $devKey = $devKeys['unbindery']; $options['methods'] = array(); foreach ($options['registered_methods'] as $method) { // Create the signature hash for each method we'll use on the page in Javascript $options['methods'][$method] = array("name" => $method, "value" => md5($method . $userToken . $appName . $privateKey . $devKey)); } } echo $twig->render("{$page}.html", $options); // Now that we've displayed it, get rid of it unset($_SESSION['ub_message']); unset($_SESSION['ub_error']); }
public function preprocess($filenames) { // Get settings $sysPath = Settings::getProtected('sys_path'); $uploaders = Settings::getProtected('uploaders'); $chunkSize = $uploaders['Audio']['chunksize']; $chunkOverlap = $uploaders['Audio']['chunkoverlap']; $ffmpegPath = $uploaders['Audio']['ffmpeg']; // Chunk each MP3 into smaller segments foreach ($filenames as $file) { $path = "{$this->tempDir}/{$file}"; // These four lines from http://stackoverflow.com/questions/3069574/get-the-length-of-an-audio-file-php $execStr = $ffmpegPath . " -i {$path} 2>&1 | grep 'Duration' | cut -d ' ' -f 4 | sed s/,//"; $time = exec($execStr); list($hms, $milli) = explode('.', $time); list($hours, $minutes, $seconds) = explode(':', $hms); $totalSeconds = $hours * 3600 + $minutes * 60 + $seconds; $count = 1; // If the MP3 is longer than the chunk size, split it if ($totalSeconds > $chunkSize) { $start = 0; // Get the filename and extension $filename = pathinfo($file, PATHINFO_FILENAME); $ext = pathinfo($file, PATHINFO_EXTENSION); // Get the size of the chunks, including the overlap $chunkSeconds = $chunkSize + $chunkOverlap; for ($start = 0; $start < $totalSeconds; $start += $chunkSize) { // Prep output filename $outputFilename = sprintf("{$filename}-%03d.{$ext}", $count); $outputPath = "{$this->tempDir}/{$outputFilename}"; // And chunk the file $execStr = $ffmpegPath . " -ss {$start} -i {$path} -t {$chunkSeconds} -acodec copy {$outputPath}"; exec($execStr); // Add to files array array_push($this->files, $outputFilename); $count++; } } } // And create the item info array foreach ($this->files as $file) { // Strip off the extension for the title $title = pathinfo($file, PATHINFO_FILENAME); $item = array("title" => $title, "project_id" => $this->projectId, "transcript" => "", "type" => "audio", "href" => $file); array_push($this->itemData, $item); } }
public static function parse($item, $action) { $auth = Settings::getProtected('auth'); $auth->forceAuthentication(); $username = $auth->getUsername(); $user = new User($username); // Parse the action switch (trim($action)) { case '@proofer': $destinationQueue = "project.proof:" . $item->project_slug; break; case '@reviewer': $destinationQueue = "project.review:" . $item->project_slug; break; default: // username (defaults to proof, TODO: allow review as well) $destinationQueue = "user.proof:" . $action; break; } $queue = new Queue($destinationQueue); $queue->add($item); $queue->save(); }
public function createAccount($user) { $app_url = Settings::getProtected('app_url'); $email_subject = Settings::getProtected('email_subject'); $admin_email = Settings::getProtected('admin_email'); $i18n = new I18n("../translations", Settings::getProtected('language')); // Add username/email here if they're not already in Unbindery (unnecessary for Alibaba) // Example: // $user->username = $this->getUsername(); // $user->email = $this->getEmail(); // Generate hash $user->hash = md5($user->email . $user->username . time()); // Add user to the database or update if they're already there $user->save(); // Send confirmation link to user via email $message = $i18n->t('signup.confirmation_email', array("url" => "{$app_url}/signup/activate/{$user->hash}")); $status = Mail::sendMessage($user->email, "{$email_subject} " . $i18n->t('signup.confirmation_link'), $message); if ($status == 1) { $status = "done"; } else { $status = "error mailing"; } $status = Mail::sendMessage($admin_email, "{$email_subject} " . $i18n->t('signup.new_signup'), $i18n->t('signup.new_user') . " {$user->username} <{$user->email}>"); }
public static function sendNotification($to, $notification, $params) { $i18n = new I18n("../translations", Settings::getProtected('language')); error_log("Sending {$notification}.subject / {$notification}.message"); $subject = self::replaceVariables($i18n->t("{$notification}.subject"), $params); $email_subject = Settings::getProtected('email_subject'); if ($email_subject) { $subject = "{$email_subject} {$subject}"; } $message = self::replaceVariables($i18n->t("{$notification}.message"), $params); Mail::sendMessage($to, $subject, $message); }
public static function getAuthenticatedUser() { $auth = Settings::getProtected('auth'); $auth->forceAuthentication(); return new User($auth->getUsername()); }
public static function removeFileForItem($item) { $sysPath = Settings::getProtected('sys_path'); // Load the project $project = new Project($item->project_slug); // Set up the target dir if ($project->type == 'system') { $projectDir = "{$sysPath}/htdocs/media/projects/{$project->slug}"; } else { if ($project->type == 'user') { $projectDir = "{$sysPath}/htdocs/media/users/{$project->owner}/{$project->slug}"; } } // File path $filePath = "{$projectDir}/{$item->href}"; // Remove the file if ($projectDir != '' && file_exists($filePath)) { return unlink($filePath); } return false; }
public static function getPublicCompletedProjects($user = '', $limit = true) { $app_url = Settings::getProtected('app_url'); $db = Settings::getProtected('db'); $projects = $db->getPublicCompletedProjects($user, $limit); foreach ($projects as &$project) { $project["title"] = stripslashes($project["title"]); if ($project["type"] == "system") { $project["link"] = "{$app_url}/projects/{$project["slug"]}"; } else { if ($project["type"] == "user") { $project["link"] = "{$app_url}/users/{$project["owner"]}/projects/{$project["slug"]}"; } } } return $projects; }
public static function import($params) { $appUrl = Settings::getProtected('app_url'); $themeRoot = Settings::getProtected('theme_root'); $format = Utils::getFormat($params['args'], 1, 3); $projectType = Utils::getProjectType($params['args']); $projectSlug = $projectType == 'system' ? $params['args'][0] : $params['args'][2]; $user = User::getAuthenticatedUser(); // Load the project $project = new Project($projectSlug); RoleController::forceClearance(array('project.admin', 'project.owner', 'system.admin'), $user, array('project' => $project)); if ($project->title == '') { Utils::redirectToDashboard('', 'Error loading project.'); } if ($project->type == 'system') { $projectUrl = "projects/" . $project->slug; } else { if ($project->type == 'user') { $projectUrl = "users/" . $project->owner . "/projects/" . $project->slug; } } $project->getItems(); $projectArray = $project->getResponse(); $projectArray['items'] = $project->items; $projectArray['url'] = "{$appUrl}/{$projectUrl}"; switch ($params['method']) { // GET: Get transcript import page case 'GET': $response = array('page_title' => 'Import Transcript', 'user' => $user->getResponse(), 'project' => $projectArray); switch ($format) { case 'json': echo json_encode(array('status' => 'success', 'response' => $response)); break; case 'html': Template::render('import', $response); break; } break; // POST: Update transcripts for items // POST: Update transcripts for items case 'POST': $template = Utils::POST('template'); $transcript = Utils::POST('transcript'); $items = Utils::POST('items'); $projectSlug = Utils::POST('projectSlug'); $status = 'success'; // Split the transcript $splitTranscripts = TranscriptController::splitTranscript($transcript, $template); // Make sure the number of items still matches, otherwise return error if (count($splitTranscripts) != count($items)) { $status = 'error'; } // Update each item's transcript for ($i = 0; $i < count($items); $i++) { $item = new Item($items[$i], $projectSlug); $item->transcript = $splitTranscripts[$i]; if (!$item->save()) { $status = 'error'; break; } } echo json_encode(array('status' => $status)); break; } }
// Initialize event manager // -------------------------------------------------- $eventManager = new EventManager(); Settings::setProtected('eventManager', $eventManager); // Initialize transcript controller // -------------------------------------------------- Transcript::setEventManager($eventManager); Transcript::register('load', array('TranscriptController', 'load')); Transcript::register('save', array('TranscriptController', 'save')); Transcript::register('diff', array('TranscriptController', 'diff')); // Initialize workflow controller // -------------------------------------------------- Workflow::register('callback', array('WorkflowController', 'parse')); // Initialize notifications controller // -------------------------------------------------- $notifications = Settings::getProtected('notifications'); $notificationsList = array(); foreach ($notifications as $key => $value) { // Get an array of just the keys array_push($notificationsList, $key); } $notify = new NotificationManager(); $notify->setEventManager($eventManager); $notify->registerNotifications($notificationsList, array('NotificationController', 'send')); Settings::setProtected('notify', $notify); // Parse the routes // -------------------------------------------------- // The \.?([^/]*)?/? at the end allows us to add .json, etc. for other formats // Create the routes we want to use $routes = array('#^/?$#' => 'SystemPageController::index', '#^/login/?$#' => 'SystemPageController::login', '#^/logout/?$#' => 'SystemPageController::logout', '#^/signup(\\.[^/]+)?/?$#' => 'SystemPageController::signup', '#^/signup/activate/(.*)(\\.[^/]+)?/?$#' => 'SystemPageController::activate', '#^/messages/?$#' => 'SystemPageController::message', '#^/install/?$#' => 'SystemPageController::install', '#^/test/(.*)/?$#' => 'SystemPageController::test', '#^/(users)/([^/]+)/projects/([^/]+)/items/get(\\.[^/]+)?/?#' => 'ItemPageController::getNewItem', '#^/(users)/([^/]+)/projects/([^/]+)/items/([^/.]+)/transcript(\\.[^/]+)?/?#' => 'ItemPageController::transcript', '#^/(users)/([^/]+)/projects/([^/]+)/items/([^/.]+)/delete(\\.[^/]+)?/?#' => 'ItemPageController::deleteItem', '#^/(users)/([^/]+)/projects/([^/]+)/items/([^/.]+)/(proof|review)(\\.[^/]+)?/?#' => 'ItemPageController::itemProof', '#^/(users)/([^/]+)/projects/([^/]+)/items/([^/.]+)/(proof|review|edit)(\\.[^/]+)?/?#' => 'ItemPageController::itemProof', '#^/(users)/([^/]+)/projects/([^/]+)/items/([^/.]+)(\\.[^/]+)?/?#' => 'ItemPageController::item', '#^/(users)/([^/]+)/projects/([^/]+)/items(\\.[^/]+)?/?#' => 'ItemPageController::items', '#^/(users)/([^/]+)/projects/([^/]+)/transcript/split(\\.[^/]+)?/?#' => 'ProjectPageController::splitTranscript', '#^/(users)/([^/]+)/projects/([^/]+)/transcript(\\.[^/]+)?/?#' => 'ProjectPageController::transcript', '#^/(users)/([^/]+)/projects/([^/]+)/membership/leave(\\.[^/]+)?/?#' => 'ProjectPageController::membershipLeave', '#^/(users)/([^/]+)/projects/([^/]+)/membership(\\.[^/]+)?/?#' => 'ProjectPageController::membership', '#^/(users)/([^/]+)/projects/([^/]+)/admin(\\.[^/]+)?/?#' => 'ProjectPageController::admin', '#^/(users)/([^/]+)/projects/([^/]+)/upload(\\.[^/]+)?/?#' => 'ProjectPageController::upload', '#^/(users)/([^/]+)/projects/([^/]+)/import(\\.[^/]+)?/?#' => 'ProjectPageController::import', '#^/(users)/([^/]+)/projects/new-project(\\.[^/]+)?/?#' => 'ProjectPageController::newProject', '#^/(users)/([^/]+)/projects/([^/.]+)(\\.[^/]+)?/?#' => 'ProjectPageController::projectPage', '#^/(users)/([^/]+)/projects(\\.[^/]+)?/?#' => 'ProjectPageController::projects', '#^/users/([^/]+)/dashboard(\\.[^/]+)?/?#' => 'UserPageController::userDashboard', '#^/users/([^/]+)/settings(\\.[^/]+)?/?#' => 'UserPageController::userSettings', '#^/users/([^/.]+)(\\.[^/]+)?/?#' => 'UserPageController::userPage', '#^/users(\\.[^/]+)?/?#' => 'UserPageController::users', '#^/projects/([^/]+)/items/get(\\.[^/]+)?/?#' => 'ItemPageController::getNewItem', '#^/projects/([^/]+)/items/([^/.]+)/transcript(\\.[^/]+)?/?#' => 'ItemPageController::transcript', '#^/projects/([^/]+)/items/([^/.]+)/delete(\\.[^/]+)?/?#' => 'ItemPageController::deleteItem', '#^/projects/([^/]+)/items/([^/.]+)/(proof|review)/(\\.[^/]+)/?#' => 'ItemPageController::itemProof', '#^/projects/([^/]+)/items/([^/.]+)/(proof|review|edit)(\\.[^/]+)?/?#' => 'ItemPageController::itemProof', '#^/projects/([^/]+)/items/([^/.]+)(\\.[^/]+)?/?#' => 'ItemPageController::item', '#^/projects/([^/]+)/items(\\.[^/]+)?/?#' => 'ItemPageController::items', '#^/projects/([^/]+)/transcript/split(\\.[^/]+)?/?#' => 'ProjectPageController::splitTranscript', '#^/projects/([^/]+)/transcript(\\.[^/]+)?/?#' => 'ProjectPageController::transcript', '#^/projects/([^/]+)/membership/leave(\\.[^/]+)?/?#' => 'ProjectPageController::membershipLeave', '#^/projects/([^/]+)/membership(\\.[^/]+)?/?#' => 'ProjectPageController::membership', '#^/projects/([^/]+)/admin(\\.[^/]+)?/?#' => 'ProjectPageController::admin', '#^/projects/([^/]+)/upload(\\.[^/]+)?/?#' => 'ProjectPageController::upload', '#^/projects/([^/]+)/import(\\.[^/]+)?/?#' => 'ProjectPageController::import', '#^/projects/new-project(\\.[^/]+)?/?#' => 'ProjectPageController::newProject', '#^/projects/([^/.]+)(\\.[^/]+)?/?#' => 'ProjectPageController::projectPage', '#^/projects(\\.[^/]+)?/?#' => 'ProjectPageController::projects', '#^/admin(\\.[^/]+)?/?$#' => 'AdminPageController::admin'); $router = new Router('SystemPageController::fileNotFound');
public static function install($params) { // Load database $db = Settings::getProtected('db'); $installed = $db->installed(); // Make sure we haven't already installed if ($installed) { // Already installed Utils::redirectToDashboard('error.already_installed', ''); } else { // We haven't, so install switch ($params['method']) { // GET: Show install form case 'GET': Template::render('install', array('external_login' => Settings::getProtected('external_login'))); break; // POST: Run install script // POST: Run install script case 'POST': // And install if ($db->install()) { // Sleep two seconds to make sure the tables are all created sleep(2); // Add admin user $user = new User(); $user->username = Utils::POST('username'); if (Utils::POST('password')) { $user->password = md5(Utils::POST('password')); // TODO: make this better } else { $user->password = ''; } $user->role = "admin"; $user->status = "active"; $user->hash = "adminadminadmin"; // doesn't really matter since we don't need to confirm $user->in_db = false; $user->save(); // Redirect to admin login page $auth = Settings::getProtected('auth'); $auth->redirectToLogin(); } else { Template::render('install', array('status' => 'failed')); } break; } } }
public static function items($params) { $format = Utils::getFormat($params['args'], 0, 2); $projectType = Utils::getProjectType($params['args']); $projectSlugIndex = $projectType == 'system' ? 0 : 2; $projectSlug = $params['args'][$projectSlugIndex]; switch ($params['method']) { // POST: Run uploaded files through item type uploader modules case 'POST': $fileList = Utils::POST('fileList'); $items = array(); foreach ($fileList as $file) { // Get extension $ext = pathinfo($file, PATHINFO_EXTENSION); // Default uploader type $uploaderType = "Page"; // Get the uploader type from the settings $uploaders = Settings::getProtected('uploaders'); foreach ($uploaders as $type => $data) { if (in_array($ext, $data['extensions'])) { $uploaderType = $type; break; } } // Load the appropriate class require_once "../modules/uploaders/{$uploaderType}Uploader.class.php"; $uploaderClass = "{$uploaderType}Uploader"; $uploader = new $uploaderClass($projectSlug); // Call the uploader (it takes an array) $returnedItems = $uploader->upload(array($file)); // Merge the arrays $items = array_merge($items, $returnedItems); } // Create a JSON-ready version $finalItems = array(); foreach ($items as $item) { $newItem = array("id" => $item->item_id, "title" => $item->title, "project_id" => $item->project_id, "transcript" => $item->transcript, "type" => $item->type, "href" => $item->href); array_push($finalItems, $newItem); } $uploader = new ItemTypeUploader($projectSlug); $uploader->cleanup(); echo json_encode(array('status' => 'success', 'items' => $finalItems)); break; } }
public static function userDashboard($params) { $format = $params['args'][1] != '' ? $params['args'][1] : 'html'; $app_url = Settings::getProtected('app_url'); $user = User::getAuthenticatedUser(); // Put it in the settings cache Settings::setProtected('username', $user->username); // Set up proofing and reviewing objects $proofing = array(); $reviewing = array(); // Load the user's proofing queue $proofQueue = new Queue("user.proof:{$user->username}"); $proofing['items'] = array(); foreach ($proofQueue->getItems() as $item) { array_push($proofing['items'], array('title' => $item->title, 'status' => $item->status, 'project_slug' => $item->project_slug, 'project_type' => $item->project_type, 'project_owner' => $item->project_owner, 'item_id' => $item->item_id, 'type' => $item->type)); } // Load the user's reviewing queue $reviewQueue = new Queue("user.review:{$user->username}"); $reviewing['items'] = array(); foreach ($reviewQueue->getItems() as $item) { array_push($reviewing['items'], array('title' => $item->title, 'status' => $item->status, 'project_slug' => $item->project_slug, 'project_type' => $item->project_type, 'project_owner' => $item->project_owner, 'item_id' => $item->item_id, 'type' => $item->type)); } // Add extra info (edit link and slug) to each item $prooflist = array(); foreach ($proofing['items'] as &$item) { if ($item['project_type'] == 'system') { $item['editlink'] = $app_url . '/projects/' . $item['project_slug'] . '/items/' . $item['item_id'] . '/proof'; } else { if ($item['project_type'] == 'user') { $item['editlink'] = $app_url . '/users/' . $item['project_owner'] . '/projects/' . $item['project_slug'] . '/items/' . $item['item_id'] . '/proof'; } } if (!in_array($item['project_slug'], $prooflist)) { $prooflist[] = $item['project_slug']; } } $reviewlist = array(); foreach ($reviewing['items'] as &$item) { if ($item['project_type'] == 'system') { $item['editlink'] = $app_url . '/projects/' . $item['project_slug'] . '/items/' . $item['item_id'] . '/review'; } else { if ($item['project_type'] == 'user') { $item['editlink'] = $app_url . '/users/' . $item['project_owner'] . '/projects/' . $item['project_slug'] . '/items/' . $item['item_id'] . '/review'; } } if (!in_array($item['project_slug'], $reviewlist)) { $reviewlist[] = $item["project_slug"]; } } // Add link and percentages to each project $projects = $user->getProjectSummaries(); $projectInfo = array(); $proofing['projects'] = array(); $reviewing['projects'] = array(); foreach ($projects as &$project) { $roles = $user->getRolesForProject($project['slug']); // If the project is available for proofing or reviewing (with no items already claimed), // then add it to the appropriate list if (!in_array($project["slug"], $prooflist) && $project["available_to_proof"] > 0 && in_array('proofer', $roles)) { array_push($proofing['projects'], $project['slug']); } if (!in_array($project["slug"], $reviewlist) && $project["available_to_review"] > 0 && in_array('reviewer', $roles)) { array_push($reviewing['projects'], $project['slug']); } // Set up percentage bars if ($project['num_items'] == 0) { $project['percent_proofed'] = 0; $project['percent_reviewed'] = 0; } else { $project['percent_proofed'] = round($project['num_proofed'] / $project['num_items'] * 100, 0); $project['percent_reviewed'] = round($project['num_reviewed'] / $project['num_items'] * 100, 0); } // And the project link if ($project['type'] == 'system') { $project['link'] = $app_url . '/projects/' . $project['slug']; } else { if ($project['type'] == 'user') { $project['link'] = $app_url . '/users/' . $project['owner'] . '/projects/' . $project['slug']; } } $projectInfo[$project['slug']] = $project; } // Blank slate condition if there are no items and no projects $proofing['blankslate'] = count($proofing['items']) == 0 && count($proofing['projects']) == 0 ? true : false; $reviewing['blankslate'] = count($reviewing['items']) == 0 && count($reviewing['projects']) == 0 ? true : false; // Get the user's history and the top proofers information $history = $user->getHistory(); $topusers = User::getTopUsers(); // Prepare user history foreach ($history as &$event) { if ($event['project_type'] == 'system') { $event['editlink'] = "{$app_url}/projects/" . $event['project_slug'] . '/items/' . $event['item_id'] . '/proof'; } else { if ($project['type'] == 'user') { $event['editlink'] = "{$app_url}/users/" . $event['project_owner'] . '/projects/' . $event['project_slug'] . '/items/' . $event['item_id'] . '/proof'; } } $event['title'] = $event['item_title']; } $response = array('page_title' => 'Dashboard', 'user' => $user->getResponse(), 'projects' => $projectInfo, 'proofing' => array('items' => $proofing['items'], 'projects' => $proofing['projects'], 'blankslate' => $proofing['blankslate']), 'reviewing' => array('items' => $reviewing['items'], 'projects' => $reviewing['projects'], 'blankslate' => $reviewing['blankslate']), 'history' => $history, 'history_count' => count($history), 'registered_methods' => array('/users/' . $user->username), 'topusers' => $topusers); switch ($params['method']) { // GET: Get user dashboard case 'GET': switch ($format) { case 'json': echo json_encode($response); break; case 'html': Template::render('dashboard', $response); 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); }