Example #1
0
 public function projects()
 {
     $projects = Project::getProjects();
     $ret = array();
     $default = isset($_REQUEST['project_id']) ? $_REQUEST['project_id'] : null;
     $ret[] = array('project_id' => 'ALL', 'name' => 'ALL');
     foreach ($projects as $project) {
         $ret[] = array_merge($project, array('selected' => $project['project_id'] === $default));
     }
     return $ret;
 }
Example #2
0
 public function projects()
 {
     $projects = Project::getProjects();
     $default = $this->read('projectFilter');
     $ret = array();
     $ret[] = array('project_id' => '0', 'name' => 'All projects', 'selected' => !$default);
     foreach ($projects as $project) {
         $ret[] = array_merge($project, array('selected' => $project['project_id'] == $default));
     }
     return $ret;
 }
Example #3
0
 public function projects()
 {
     $user = $this->currentUser;
     $current = empty($this->workItem) ? 'hifi' : $this->workItem()->getProjectName();
     $activeOnly = !($user['is_runner'] || $user['is_admin'] || $user['is_payer']);
     $projects = Project::getProjects($activeOnly);
     $ret = array();
     foreach ($projects as $project) {
         $ret[] = array('id' => $project['project_id'], 'name' => $project['name'], 'current' => $project['name'] == $current ? true : false);
     }
     return $ret;
 }
Example #4
0
 public function action_index()
 {
     $studentsPerProject = 5;
     $showCreateProject = false;
     //$args = array();
     $session = Session::instance();
     if ($session->get('userType') == 'company') {
         $showCreateProject = true;
     }
     if ($this->request->query('p')) {
         $projects = Project::getProjects($this->request->query('p'));
     } else {
         $projects = Project::getProjects('all');
     }
     //array_push($args,$projects);
     //print_r($args);
     $this->response->body(View::factory('header') . View::factory('project')->set('showCreateProject', $showCreateProject)->set('projects', $projects)->bind('studentsPerProject', $studentsPerProject));
 }
Example #5
0
 /**
  * get all existing projects, except ExternalTasksProject & SideTasksProjects
  * @return string[int] : name[id]
  */
 private function getProjectList()
 {
     $projects = Project::getProjects();
     if ($projects != NULL) {
         $extproj_id = Config::getInstance()->getValue(Config::id_externalTasksProject);
         $smartyProjects = array();
         foreach ($projects as $id => $name) {
             if ($extproj_id != $id) {
                 try {
                     $p = ProjectCache::getInstance()->getProject($id);
                     if (!$p->isSideTasksProject()) {
                         $smartyProjects[$id] = $name;
                     } else {
                         // exclude SideTasksProjects
                         if (self::$logger->isDebugEnabled()) {
                             self::$logger->debug("project {$id}: sideTaskProjects are excluded");
                         }
                     }
                 } catch (Exception $e) {
                     // could not determinate, so the project should be included in the list
                     if (self::$logger->isDebugEnabled()) {
                         self::$logger->debug("project {$id}: Unknown type, project included anyway.");
                     }
                     // nothing to do.
                 }
             } else {
                 // exclude ExternalTasksProject
                 if (self::$logger->isDebugEnabled()) {
                     self::$logger->debug("project {$id}: ExternalTasksProject is excluded");
                 }
             }
         }
         return $smartyProjects;
     } else {
         return NULL;
     }
 }
function renderProjects($organisation_selection = '', $projects = '', $target = '', $inline = FALSE, $reload_data = TRUE, $owner_only = FALSE)
{
    if (!$projects && $reload_data) {
        $projects = Project::getProjects('', $owner_only ? $GLOBALS['user']->uid : null, $organisation_selection);
    }
    $target_set = !empty($target);
    if ($projects) {
        $s = "<ol class='projectlist'>";
        foreach ($projects as $project) {
            $project = objectToArray($project);
            $s .= "<li>";
            if (!$target_set || $inline) {
                $target = "show_{$project['pid']}";
            }
            $inline = $inline ? 1 : 0;
            $s .= "<a href='javascript: void(0);' onclick='" . "ajaxCall(\"project\", \"view\", {id:{$project['pid']},type:\"project\", target:\"{$target}\", inline:{$inline}}, \"{$target}\");'>{$project['title']}</a>";
            if (!$target_set || $inline) {
                $s .= "<div id='{$target}' ></div>";
            }
            $s .= "</li>";
        }
        $s .= "</ol>";
        return $s;
    } else {
        return t('You have no projects yet');
    }
}
Example #7
0
 protected function display()
 {
     if (Tools::isConnectedUser()) {
         // Admins only
         $session_user = UserCache::getInstance()->getUser($_SESSION['userid']);
         if ($session_user->isTeamMember(Config::getInstance()->getValue(Config::id_adminTeamId))) {
             $this->smartyHelper->assign('jobType', Job::$typeNames);
             $action = Tools::getSecurePOSTStringValue('action', 'none');
             if ('addJob' == $action) {
                 $job_name = Tools::getSecurePOSTStringValue('job_name');
                 $job_type = Tools::getSecurePOSTStringValue('job_type');
                 $job_color = Tools::getSecurePOSTStringValue('job_color');
                 // TODO check if not already in table !
                 // save to DB
                 Jobs::create($job_name, $job_type, $job_color);
             } elseif ('addAssociationProject' == $action) {
                 // Add Job to selected projects
                 $job_id = Tools::getSecurePOSTIntValue('job_id');
                 $proj = explode(",", Tools::getSecurePOSTStringValue('formattedProjects'));
                 foreach ($proj as $project_id) {
                     // TODO check if not already in table !
                     // save to DB
                     $query = "INSERT INTO `codev_project_job_table`  (`project_id`, `job_id`) VALUES ('" . $project_id . "','" . $job_id . "');";
                     $result = SqlWrapper::getInstance()->sql_query($query);
                     if (!$result) {
                         $this->smartyHelper->assign('error', T_("Couldn't add the job association"));
                     }
                 }
             } elseif ('deleteJob' == $action) {
                 $job_id = Tools::getSecurePOSTIntValue('job_id');
                 if (Jobs::JOB_NA == $job_id || Jobs::JOB_SUPPORT == $job_id) {
                     $this->smartyHelper->assign('error', T_("This job must not be deleted."));
                 } else {
                     $query = "DELETE FROM `codev_project_job_table` WHERE job_id = " . $job_id . ';';
                     $result = SqlWrapper::getInstance()->sql_query($query);
                     if (!$result) {
                         $this->smartyHelper->assign('error', T_("Couldn't remove the job association"));
                     }
                     $query = "DELETE FROM `codev_job_table` WHERE id = {$job_id};";
                     $result = SqlWrapper::getInstance()->sql_query($query);
                     if (!$result) {
                         $this->smartyHelper->assign('error', T_("Couldn't delete the job"));
                     }
                 }
             } elseif ('deleteJobProjectAssociation' == $action) {
                 $asso_id = Tools::getSecurePOSTIntValue('asso_id');
                 $query = "DELETE FROM `codev_project_job_table` WHERE id = " . $asso_id . ';';
                 $result = SqlWrapper::getInstance()->sql_query($query);
                 if (!$result) {
                     $this->smartyHelper->assign('error', T_("Couldn't remove the job association"));
                 }
             }
             $jobs = $this->getJobs();
             $this->smartyHelper->assign('jobs', $jobs);
             //$this->smartyHelper->assign('assignedJobs', $this->getAssignedJobs($jobs));
             $this->smartyHelper->assign('assignedJobs', $jobs);
             $projects = Project::getProjects();
             $this->smartyHelper->assign('projects', $projects);
             $this->smartyHelper->assign('tuples', $this->getAssignedJobTuples($projects));
         }
     }
 }
Example #8
0
                echo $iPro['ProjectName'];
                ?>
</label>
                                         </li>
                                         <?php 
            }
            ?>
                                    </ol>
                            <input type='submit' class='btn btn-default' name='submit-approveproject' value='Approve Projects' />
                        </fieldset>
                    </form>
                    
                    <?php 
        } elseif ($_GET['p'] == 'finishproject') {
            $projectObj = new Project();
            $Projects = $projectObj->getProjects("all");
            ?>
                    
                    <form id='approveproject' role='form' action='admin.php' method = 'POST'>
                        <fieldset>
                            <legend>Approve Companies</legend>
                                    <ol style="aligh:left;">
                                    <?php 
            foreach ($Projects as $Pro) {
                //print_r($Pro);
                if ($Pro['completed'] == '0') {
                    ?>
                                         <li>
                                            <label><input type='checkbox' class='form-control' name='iPro[]' value="<?php 
                    echo $Pro['id_pk'];
                    ?>
Example #9
0
function getProjects($public_only = true)
{
    // Create project object
    $projectHandler = new Project();
    // page 1 is "all active projects"
    $page = isset($_REQUEST['page']) ? (int) $_REQUEST['page'] : 1;
    // for subsequent pages, which will be inactive projects, return 10 at a time
    if ($page > 1) {
        // Define values for sorting a display
        $limit = 10;
        // Get listing of all inactive projects
        $projectListing = $projectHandler->getProjects(false, array(), true, false, $public_only);
        // Create content for each page
        // Select projects that match the letter chosen and construct the array for
        // the selected page
        $pageFinish = $page * $limit;
        $pageStart = $pageFinish - ($limit - 1);
        // leaving 'letter' filter in place for the time being although the UI is not supporting it
        $letter = isset($_REQUEST["letter"]) ? trim($_REQUEST["letter"]) : "all";
        if ($letter == "all") {
            $letter = ".*";
        } else {
            if ($letter == "_") {
                //numbers
                $letter = "[^A-Za-z]";
            }
        }
        // Count total number of active projects
        $activeProjectsCount = count($projectListing);
        if ($projectListing != null) {
            foreach ($projectListing as $key => $value) {
                if (preg_match("/^{$letter}/i", $value["name"])) {
                    $selectedProjects[] = $value;
                }
            }
            // Count number of projects to display
            $projectsToDisplay = count($selectedProjects);
            // Determine total number of pages
            $displayPages = ceil($projectsToDisplay / $limit);
            // Construct json for pagination
            // $projectsOnPage = array(array($projectsToDisplay, $page, $displayPages));
            $projectsOnPage = array();
            // Select projects for current page
            $i = $pageStart - 1;
            while ($i < $pageFinish) {
                if (isset($selectedProjects[$i])) {
                    $projectsOnPage[] = $selectedProjects[$i];
                }
                $i++;
            }
        }
    } else {
        // Get listing of active projects
        $projectsOnPage = $projectHandler->getProjects(true, array(), false, false, $public_only);
    }
    // Prepare data for printing in projects
    $json = json_encode($projectsOnPage);
    echo $json;
}
Example #10
0
    if ($r) {
        echo "Signed up successfully!";
    } else {
        echo "Signup failed!";
    }
} else {
    //if not signing up execute this
    ?>


   <div class="col-md-8">
    <?php 
    $projectObj = new Project();
    $projects;
    if (isset($_GET['p'])) {
        $projects = $projectObj->getProjects($_GET['p']);
    } else {
        $projects = $projectObj->getProjects('all');
    }
    ?>
    
        <div class="well">
        <?php 
    $p = 1;
    for ($i = 0; $i < count($projects) / 3; $i++) {
        echo "<div class='row'>";
        for ($q = 0; $q < 3; $q++) {
            if ($p > count($projects)) {
                continue;
            }
            ?>
Example #11
0
function showInstituteOverviewPage($institute)
{
    include_once _VALS_SOC_ROOT . '/includes/classes/Proposal.php';
    include_once _VALS_SOC_ROOT . '/includes/classes/Organisations.php';
    include_once _VALS_SOC_ROOT . '/includes/classes/Project.php';
    echo "<h2>" . t('Overview of your institute activity') . "</h2>";
    $inst_id = $institute->inst_id;
    $nr_proposals_draft = count(Proposal::getProposalsPerOrganisation('', $inst_id));
    $nr_proposals_final = count(Proposal::getProposalsPerOrganisation('', $inst_id, 'published'));
    $nr_students = Users::getUsers(_STUDENT_TYPE, _INSTITUTE_GROUP, $inst_id)->rowCount();
    $nr_groups = Groups::getGroups(_STUDENT_GROUP, 'all', $inst_id)->rowCount();
    $nr_tutors = Users::getUsers(_SUPERVISOR_TYPE, _INSTITUTE_GROUP, $inst_id)->rowCount() + Users::getUsers(_INSTADMIN_TYPE, _INSTITUTE_GROUP, $inst_id)->rowCount();
    $nr_orgs = count(Organisations::getInstance()->getOrganisations());
    $nr_projects = count(Project::getProjects());
    echo "<b>" . t("Proposals in draft:") . "</b>&nbsp; {$nr_proposals_draft}<br>";
    echo "<b>" . t("Proposals submitted:") . "</b>&nbsp; {$nr_proposals_final}<br>";
    echo "<b>" . t("Number of students subscribed:") . "</b>&nbsp; {$nr_students}<br>";
    echo "<b>" . t("Number of groups available:") . "</b>&nbsp; {$nr_groups}<br>";
    echo "<b>" . t("Number of supervisors subscribed:") . "</b>&nbsp; {$nr_tutors}<br>";
    echo "<b>" . t("Number of organisations:") . "</b>&nbsp; {$nr_orgs}<br>";
    echo "<b>" . t("Number of projects:") . "</b>&nbsp; {$nr_projects}<br>";
}
Example #12
0
/**
 * get all existing projects, except ExternalTasksProject & SideTasksProjects
 * @return string[] : name[id]
 */
function getProjectList()
{
    global $logger;
    $projects = Project::getProjects();
    if ($projects != NULL) {
        $extproj_id = Config::getInstance()->getValue(Config::id_externalTasksProject);
        $smartyProjects = array();
        foreach ($projects as $id => $name) {
            // exclude ExternalTasksProject
            if ($extproj_id == $id) {
                echo "<script type=\"text/javascript\">console.log(\"   getProjectList - project {$id}: ExternalTasksProject is excluded\");</script>";
                continue;
            }
            // exclude SideTasksProjects
            try {
                $p = ProjectCache::getInstance()->getProject($id);
                if ($p->isSideTasksProject()) {
                    echo "<script type=\"text/javascript\">console.log(\"   getProjectList - project {$id}: sideTaskProjects are excluded\");</script>";
                    continue;
                }
            } catch (Exception $e) {
                // could not determinate, so the project should be included in the list
                echo "<script type=\"text/javascript\">console.log(\"   getProjectList - project {$id}: Unknown type, project included anyway\");</script>";
                // nothing to do.
            }
            $smartyProjects[$id] = $name;
        }
        return $smartyProjects;
    } else {
        return NULL;
    }
}
Example #13
0
 function listClosureReports()
 {
     $p = new Project();
     $this->engine->assign('p_uuid', $_SESSION['user_id']);
     $this->engine->assign('projects', $p->getProjects(null, false, false, true));
     $this->engine->display('project/list_closure.tpl.php');
 }
Example #14
0
 public function view($job_id)
 {
     $this->write('statusListRunner', array("Draft", "Suggestion", "Bidding", "In Progress", "QA Ready", "Code Review", "Merged", "Done", "Pass"));
     $statusListMechanic = array("In Progress", "QA Ready", "Code Review", "Merged", "Pass");
     $this->write('statusListMechanic', $statusListMechanic);
     $this->write('statusListCreator', array("Suggestion", "Pass"));
     if (!defined("WORKITEM_URL")) {
         define("WORKITEM_URL", SERVER_URL);
     }
     if (!defined("WORKLIST_REDIRECT_URL")) {
         define("WORKLIST_REDIRECT_URL", SERVER_URL);
     }
     $worklist_id = intval($job_id);
     $is_runner = isset($_SESSION['is_runner']) ? $_SESSION['is_runner'] : 0;
     $currentUsername = isset($_SESSION['username']) ? $_SESSION['username'] : '';
     //initialize user accessing the page
     $userId = Session::uid();
     $user = new User();
     if ($userId > 0) {
         $user->findUserById($userId);
     } else {
         $user->setId(0);
     }
     $this->write('user', $user);
     // TODO: Would be good to take out all the checks for isset($_SESSION['userid'] etc. and have them use $user instead, check $user->getId() > 0.
     if (empty($worklist_id)) {
         $this->view = null;
         return;
     }
     //Set an empty variable for $journal_message to avoid errors/warnings with .=
     $journal_message = null;
     //initialize the workitem class
     $workitem = new WorkItem();
     try {
         $workitem->loadById($worklist_id);
     } catch (Exception $e) {
         $error = $e->getMessage();
         $this->view = null;
         die($error);
     }
     if ($workitem->isInternal() && !$user->isInternal()) {
         $this->write('msg', 'You don\'t have permissions to view this job.');
         $this->write('link', WORKLIST_URL);
         $this->view = new ErrorView();
         parent::run();
         exit;
     }
     if ($workitem->getStatus() == 'Draft' && $workitem->getCreatorId() != $_SESSION['userid']) {
         $this->write('msg', 'You don\'t have permissions to view this job.');
         $this->write('link', WORKLIST_URL);
         $this->view = new ErrorView();
         parent::run();
         exit;
     }
     $this->write('workitem', $workitem);
     // we need to be able to grant runner rights to a project founder for all jobs for their project
     $workitem_project = Project::getById($workitem->getProjectId());
     $is_project_founder = false;
     if ($workitem_project->getOwnerId() == $_SESSION['userid']) {
         $is_project_founder = true;
     }
     $this->write('workitem_project', $workitem_project);
     $this->write('is_project_founder', $is_project_founder);
     $this->write('isGitHubConnected', $user->isGithub_connected($workitem_project->getGithubId()));
     //used for is_project_runner rights
     $is_project_runner = false;
     if ($workitem->getIsRelRunner() == 1) {
         $is_project_runner = true;
     }
     $this->write('is_project_runner', $is_project_runner);
     $redirectToDefaultView = false;
     $promptForReviewUrl = true;
     $runner_budget = $user->getBudget();
     $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : 'view';
     if ($workitem->getStatus() == 'Done' && $action == 'edit') {
         $action = 'view';
     }
     $view_bid_id = 0;
     if (isset($_REQUEST['withdraw_bid'])) {
         $action = "withdraw_bid";
     } else {
         if (isset($_REQUEST['decline_bid'])) {
             $action = "decline_bid";
         } else {
             if (isset($_REQUEST['save_workitem'])) {
                 $action = "save_workitem";
             } else {
                 if (isset($_REQUEST['place_bid'])) {
                     $action = "place_bid";
                 } else {
                     if (isset($_REQUEST['swb'])) {
                         $action = "swb";
                     } else {
                         if (isset($_REQUEST['edit_bid'])) {
                             $action = "edit_bid";
                         } else {
                             if (isset($_REQUEST['add_fee'])) {
                                 $action = "add_fee";
                             } else {
                                 if (isset($_REQUEST['add_tip'])) {
                                     $action = "add_tip";
                                 } else {
                                     if (isset($_REQUEST['accept_bid'])) {
                                         $action = "accept_bid";
                                     } else {
                                         if (isset($_REQUEST['accept_multiple_bid'])) {
                                             $action = "accept_multiple_bid";
                                         } else {
                                             if (isset($_REQUEST['status-switch'])) {
                                                 $action = "status-switch";
                                             } else {
                                                 if (isset($_REQUEST['newcomment'])) {
                                                     $action = 'new-comment';
                                                 }
                                             }
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     if ($action == 'view_bid') {
         $action = "view";
         $this->write('view_bid_id', isset($_REQUEST['bid_id']) ? $_REQUEST['bid_id'] : 0);
     }
     // for any other action user has to be logged in
     if ($action != 'view') {
         Utils::checkLogin();
         $action_error = '';
         $action = $workitem->validateAction($action, $action_error);
     }
     $this->write('action', $action);
     // Save WorkItem was requested. We only support Update here
     $notifyEmpty = true;
     $job_changes = array();
     $status_change = '';
     if ($action == 'save_workitem') {
         $this->edit($worklist_id);
     }
     if ($action == 'new-comment') {
         if (isset($_REQUEST['worklist_id']) && !empty($_REQUEST['worklist_id']) && (isset($_REQUEST['user_id']) && !empty($_REQUEST['user_id'])) && (isset($_REQUEST['comment']) && !empty($_REQUEST['comment']))) {
             if (isset($_REQUEST['comment_id']) && !empty($_REQUEST['comment_id'])) {
                 $parent_comment = (int) $_REQUEST['comment_id'];
             } else {
                 $parent_comment = NULL;
             }
             $worklist_id = (int) $_REQUEST['worklist_id'];
             $user_id = (int) $_REQUEST['user_id'];
             $comment = $_REQUEST['comment'];
             $rt = $this->addComment($worklist_id, $user_id, $comment, $parent_comment);
             // Send journal notification
             if ($workitem->getStatus() != 'Draft') {
                 $related = $this->getRelated($comment);
                 $journal_message .= '@' . $_SESSION['nickname'] . ' posted a comment on #' . $worklist_id . $related;
                 $options = array('type' => 'comment', 'workitem' => $workitem, 'recipients' => array('creator', 'runner', 'mechanic', 'followers'), 'emails' => $rt['correspondent']);
                 $data = array('who' => $_SESSION['nickname'], 'comment' => $comment, 'related' => $related, 'comment-id' => $rt['id']);
                 Notification::workitemNotify($options, $data, false);
                 Notification::workitemNotifyHipchat($options, $data);
                 // workitem mentions
                 $matches = array();
                 if (preg_match_all('/@(\\w+)/', $comment, $matches, PREG_SET_ORDER)) {
                     foreach ($matches as $mention) {
                         // validate the username actually exists
                         if ($recipient = User::find($mention[1])) {
                             // exclude creator, designer, developer and followers
                             if ($recipient->getId() != $workitem->getRunnerId() && $recipient->getId() != $workitem->getMechanicId() && $recipient->getId() != $workitem->getCreatorId() && !$workitem->isUserFollowing($recipient->getId())) {
                                 $emailTemplate = 'workitem-mention';
                                 $comment_url = WORKLIST_URL . $workitem->getId() . '#comment-' . $rt['id'];
                                 $data = array('job_id' => $workitem->getId(), 'summary' => $workitem->getSummary(), 'author' => $_SESSION['nickname'], 'text' => $comment, 'link' => '<a href="' . $comment_url . '">See the comment</a>');
                                 $senderEmail = 'Worklist - ' . $_SESSION['nickname'] . ' <*****@*****.**> ';
                                 Utils::sendTemplateEmail($recipient->getUsername(), $emailTemplate, $data, $senderEmail);
                             }
                         }
                     }
                 }
             }
             Utils::systemNotification($journal_message);
             $comment = new Comment();
             $comment->findCommentById((int) $rt['id']);
             $result = array('success' => true, 'id' => $rt['id'], 'comment' => str_replace(array('\\n\\r', '\\r\\n', '\\n', '\\r'), '<br/>', Utils::linkify($comment->getComment())), 'avatar' => $comment->getUser()->getAvatar(), 'nickname' => $comment->getUser()->getNickname(), 'userid' => $comment->getUser()->getId(), 'date' => Utils::relativeTime(strtotime($comment->getDate()) - strtotime(Model::now())));
             ob_start();
             $json = json_encode($result);
         } else {
             $json = json_encode(array('success' => false));
         }
         $this->view = null;
         echo $json;
         ob_end_flush();
         exit;
     }
     if ($action == 'status-switch') {
         $status = $_REQUEST['quick-status'];
         $status_error = '';
         if ($status == 'Done' && $workitem->getProjectId() == 0) {
             $status_error = "No project associated with workitem. Could not set to DONE.";
         } else {
             if ($this->changeStatus($workitem, $status, $user)) {
                 if ($workitem->save() == false) {
                     $status_error = "Error in save workitem process. Could not change the status.";
                 } else {
                     if ($status == 'Merged') {
                         $workitem->addFeesToCompletedJob();
                     }
                     if ($status != 'Draft') {
                         $new_update_message = "Status set to *{$status}*. ";
                         $notifyEmpty = false;
                         $status_change = '-' . ucfirst(strtolower($status));
                         if ($status == 'QA Ready') {
                             Notification::workitemNotify(array('type' => 'new_qa', 'workitem' => $workitem, 'status_change' => $status_change, 'job_changes' => $job_changes, 'recipients' => array($workitem->getRunnerId(), 'creator', 'mechanic', 'followers')), array('changes' => $new_update_message));
                             $notifyEmpty = true;
                         }
                         if ($status == 'Code Review') {
                             Notification::workitemNotify(array('type' => 'new_review', 'workitem' => $workitem, 'status_change' => $status_change, 'job_changes' => $job_changes, 'recipients' => array($workitem->getRunnerId(), 'creator', 'mechanic', 'followers', 'reviewNotifs')), array('changes' => $new_update_message));
                             $notifyEmpty = true;
                         }
                         $journal_message = '\\#' . $worklist_id . ' updated by @' . $_SESSION['nickname'] . ' ' . $new_update_message;
                     }
                 }
             } else {
                 $message = '';
                 if ($status & 4) {
                     //sandbox not updated
                     $message .= " - Sandbox is not up-to-date\n";
                 }
                 if ($status & 8) {
                     //sandbox has conflicts
                     $message .= " - Sandbox contains conflicted files\n";
                 }
                 if ($status & 16) {
                     //sandbox has not-included files
                     $message .= " - Sandbox contains 'not-included' files\n";
                 }
                 $status_error = "Sandbox verification failed. " . $message;
             }
         }
     }
     if (!$notifyEmpty) {
         $options = array('type' => 'modified', 'workitem' => $workitem, 'status_change' => $status_change, 'job_changes' => $job_changes, 'recipients' => array('runner', 'creator', 'mechanic', 'followers'));
         $data = array('changes' => $new_update_message);
         Notification::workitemNotify($options, $data);
     }
     if ($action == "place_bid") {
         //Escaping $notes with mysql_real_escape_string is generating \n\r instead of <br>
         //a new variable is used to send the unenscaped notes in email alert.
         //so it can parse the new line as <BR>   12-Mar-2011 <webdev>
         $args = array('bid_amount', 'done_in', 'bid_expires', 'notes', 'mechanic_id');
         foreach ($args as $arg) {
             ${$arg} = mysql_real_escape_string($_REQUEST[$arg]);
         }
         $bid_amount = (double) $bid_amount;
         $mechanic_id = (int) $mechanic_id;
         if ($_SESSION['timezone'] == '0000') {
             $_SESSION['timezone'] = '+0000';
         }
         $summary = $workitem->getSummary();
         if ($mechanic_id != Session::uid()) {
             $row = $workitem->getUserDetails($mechanic_id);
             if (!empty($row)) {
                 $nickname = $row['nickname'];
                 $username = $row['username'];
             } else {
                 $username = "******";
                 $nickname = "unknown-{$mechanic_id}";
             }
         } else {
             $mechanic_id = $_SESSION['userid'];
             $username = $_SESSION['username'];
             $nickname = $_SESSION['nickname'];
         }
         if ($user->isEligible()) {
             $bid_id = $workitem->placeBid($mechanic_id, $username, $worklist_id, $bid_amount, $done_in, $bid_expires, $notes);
             //sending email to the runner of worklist item or all runners if not assigned
             $row = $workitem->getRunnerSummary($worklist_id);
             if (!empty($row)) {
                 $id = $row['id'];
                 $summary = $row['summary'];
                 $username = $row['username'];
             }
             $options = array('type' => 'bid_placed', 'workitem' => $workitem, 'recipients' => array($workitem->getRunnerId() == '' ? 'projectRunners' : 'runner'), 'jobsInfo' => $user->jobsForProject('Done', $workitem->getProjectId(), 1, 3), 'totalJobs' => $user->jobsCount(array('In Progress', 'QA Ready', 'Review', 'Merged', 'Done')), 'activeJobs' => $user->jobsCount(array('In Progress', 'QA Ready', 'Review')));
             $journal_message = 'A bid was placed on #' . $worklist_id;
             $data = array('done_in' => $done_in, 'bid_expires' => $bid_expires, 'bid_amount' => $bid_amount, 'notes' => str_replace(array('\\n\\r', '\\r\\n', '\\n', '\\r'), '<br/>', $notes), 'bid_id' => $bid_id);
             // notify runner of new bid
             Notification::workitemNotify($options, $data);
             $status = $workitem->loadStatusByBidId($bid_id);
             $data['new_update_message'] = $new_update_message;
             Notification::workitemNotifyHipchat($options, $data);
         } else {
             error_log("Input forgery detected for user {$userId}: attempting to {$action}.");
         }
         $redirectToDefaultView = true;
     }
     // Edit Bid
     if ($action == "edit_bid") {
         if (!$user->isEligible()) {
             error_log("Input forgery detected for user {$userId}: attempting to {$action} (isEligible in job)");
         } else {
             //Escaping $notes with mysql_real_escape_string is generating \n\r instead of <br>
             //a new variable is used to send the unenscaped notes in email alert.
             //so it can parse the new line as <BR>   12-Mar-2011 <webdev>
             $args = array('bid_id', 'bid_amount', 'done_in', 'bid_expires', 'notes');
             foreach ($args as $arg) {
                 ${$arg} = mysql_real_escape_string($_REQUEST[$arg]);
             }
             $bid_amount = (double) $bid_amount;
             $mechanic_id = (int) $mechanic_id;
             if ($_SESSION['timezone'] == '0000') {
                 $_SESSION['timezone'] = '+0000';
             }
             $summary = $workitem->getSummary();
             $bid_id = $workitem->updateBid($bid_id, $bid_amount, $done_in, $bid_expires, $_SESSION['timezone'], $notes);
             // Journal notification
             $journal_message = 'Bid updated on #' . $worklist_id;
             //sending email to the runner of worklist item
             $row = $workitem->getRunnerSummary($worklist_id);
             if (!empty($row)) {
                 $id = $row['id'];
                 $summary = $row['summary'];
                 $username = $row['username'];
             }
             $options = array('type' => 'bid_updated', 'workitem' => $workitem, 'recipients' => array('runner'), 'jobsInfo' => $user->jobsForProject('Done', $workitem->getProjectId(), 1, 3), 'totalJobs' => $user->jobsCount(array('In Progress', 'QA Ready', 'Review', 'Merged', 'Done')), 'activeJobs' => $user->jobsCount(array('In Progress', 'QA Ready', 'Review')));
             $data = array('done_in' => $done_in, 'bid_expires' => $bid_expires, 'bid_amount' => $bid_amount, 'notes' => str_replace(array('\\n\\r', '\\r\\n', '\\n', '\\r'), '<br/>', $notes), 'bid_id' => $bid_id);
             // notify runner of new bid
             Notification::workitemNotify($options, $data);
             Notification::workitemNotifyHipchat($options, $data);
         }
         $redirectToDefaultView = true;
     }
     // Request submitted from Add Fee popup
     if ($action == "add_fee") {
         if (!$user->isEligible()) {
             error_log("Input forgery detected for user {$userId}: attempting to {$action}.");
         } else {
             $args = array('itemid', 'fee_amount', 'fee_desc', 'mechanic_id', 'is_expense', 'is_rewarder');
             foreach ($args as $arg) {
                 if (isset($_REQUEST[$arg])) {
                     ${$arg} = mysql_real_escape_string($_REQUEST[$arg]);
                 } else {
                     ${$arg} = '';
                 }
             }
             $itemid = (int) $itemid;
             $fee_amount = (double) $fee_amount;
             $mechanic_id = (int) $mechanic_id;
             $journal_message = Fee::add($itemid, $fee_amount, '', $fee_desc, $mechanic_id, '', '');
             if ($workitem->getStatus() != 'Draft') {
                 $options = array('type' => 'fee_added', 'workitem' => $workitem, 'recipients' => array('runner'));
                 $data = array('fee_adder' => $user->getNickname(), 'fee_amount' => $fee_amount, 'fee_desc' => $fee_desc, 'mechanic_id' => $mechanic_id);
                 Notification::workitemNotify($options, $data);
                 $data['nick'] = $_SESSION['nickname'];
                 Notification::workitemNotifyHipchat($options, $data);
                 // update budget
                 $runner = new User();
                 $runner->findUserById($workitem->getRunnerId());
                 $runner->updateBudget(-$fee_amount, $workitem->getBudget_id());
             }
             $redirectToDefaultView = true;
         }
     }
     // Accept a bid
     if ($action == 'accept_bid') {
         if (!isset($_REQUEST['bid_id']) || !isset($_REQUEST['budget_id'])) {
             $_SESSION['workitem_error'] = "Missing parameter to accept a bid!";
         } else {
             $bid_id = intval($_REQUEST['bid_id']);
             $budget_id = intval($_REQUEST['budget_id']);
             $budget = new Budget();
             if (!$budget->loadById($budget_id)) {
                 $_SESSION['workitem_error'] = "Invalid budget!";
             }
             $is_job_runner = $workitem->getRunnerId() == Session::uid();
             $is_assigned = $workitem->getAssigned_id() == Session::uid();
             // only runners can accept bids
             if ($is_project_runner || $is_job_runner || $is_assigned || $user->getIs_admin() == 1 && $is_runner && !$workitem->hasAcceptedBids() && $workitem->getStatus() == "Bidding") {
                 // query to get a list of bids (to use the current class rather than breaking uniformity)
                 // I could have done this quite easier with just 1 query and an if statement..
                 $bids = (array) $workitem->getBids($workitem->getId());
                 $exists = false;
                 foreach ($bids as $array) {
                     if ($array['id'] == $bid_id) {
                         $exists = true;
                         $bid_amount = $array["bid_amount"];
                         break;
                     }
                 }
                 if ($exists) {
                     $remainingFunds = $budget->getRemainingFunds();
                     if ($bid_amount <= $remainingFunds) {
                         $bid_info = $workitem->acceptBid($bid_id, $budget_id);
                         $budget->recalculateBudgetRemaining();
                         // Journal notification
                         $journal_message .= '@' . $_SESSION['nickname'] . " accepted {$bid_info['bid_amount']} from " . $bid_info['nickname'] . " on #" . $bid_info['worklist_id'] . " Status set to *In Progress*.";
                         $options = array('type' => 'bid_accepted', 'workitem' => $workitem, 'recipients' => array('mechanic', 'followers'));
                         // mail notification - including any data returned from acceptBid
                         Notification::workitemNotify($options, $bid_info);
                         $data = $bid_info;
                         $data['nick'] = $_SESSION['nickname'];
                         Notification::workitemNotifyHipchat($options, $data);
                         $bidder = new User();
                         $bidder->findUserById($bid_info['bidder_id']);
                         // Update Budget
                         $runner = new User();
                         $runner->findUserById($workitem->getRunnerId());
                         $runner->updateBudget(-$bid_amount, $workitem->getBudget_id());
                         // Send email to not accepted bidders
                         $this->sendMailToDiscardedBids($worklist_id);
                     } else {
                         $overBudget = money_format('%i', $bid_amount - $remainingFunds);
                         $_SESSION['workitem_error'] = "Failed to accept bid. Accepting this bid would make you " . $overBudget . " over your budget!";
                     }
                 } else {
                     $_SESSION['workitem_error'] = "Failed to accept bid, bid has been deleted!";
                 }
             } else {
                 if ($workitem->getIsRelRunner() || $workitem->getRunnerId() == $_SESSION['userid']) {
                     if ($workitem->hasAcceptedBids()) {
                         $_SESSION['workitem_error'] = "Failed to accept bid on task with an accepted bid!";
                     } else {
                         $_SESSION['workitem_error'] = "Accept Bid Failed, unknown task state!";
                     }
                 }
             }
         }
         $redirectToDefaultView = true;
     }
     // Accept Multiple  bid
     if ($action == 'accept_multiple_bid') {
         if (!isset($_REQUEST['budget_id'])) {
             $_SESSION['workitem_error'] = "Missing budget to accept a bid!";
         } else {
             $bid_id = $_REQUEST['chkMultipleBid'];
             $mechanic_id = $_REQUEST['mechanic'];
             $budget_id = intval($_REQUEST['budget_id']);
             $budget = new Budget();
             if (!$budget->loadById($budget_id)) {
                 $_SESSION['workitem_error'] = "Invalid budget!";
             }
             if (count($bid_id) > 0) {
                 //only runners can accept bids
                 if (($is_project_runner || $workitem->getRunnerId() == Session::uid() || $user->getIs_admin() == 1 && $is_runner) && !$workitem->hasAcceptedBids() && $workitem->getStatus() == "Bidding") {
                     $total = 0;
                     foreach ($bid_id as $bid) {
                         $currentBid = new Bid();
                         $currentBid->findBidById($bid);
                         $total = $total + $currentBid->getBid_amount();
                     }
                     $remainingFunds = $budget->getRemainingFunds();
                     if ($total <= $remainingFunds) {
                         foreach ($bid_id as $bid) {
                             $bids = (array) $workitem->getBids($workitem->getId());
                             $exists = false;
                             foreach ($bids as $array) {
                                 if ($array['id'] == $bid) {
                                     if ($array['bidder_id'] == $mechanic_id) {
                                         $is_mechanic = true;
                                     } else {
                                         $is_mechanic = false;
                                     }
                                     $exists = true;
                                     break;
                                 }
                             }
                             if ($exists) {
                                 $bid_info = $workitem->acceptBid($bid, $budget_id, $is_mechanic);
                                 // Journal notification
                                 $journal_message .= '@' . $_SESSION['nickname'] . " accepted {$bid_info['bid_amount']} from " . $bid_info['nickname'] . " " . ($is_mechanic ? ' as Developer ' : '') . "on #" . $bid_info['worklist_id'] . " Status set to *In Progress*.";
                                 // mail notification
                                 Notification::workitemNotify(array('type' => 'bid_accepted', 'workitem' => $workitem, 'recipients' => array('mechanic', 'followers')));
                             } else {
                                 $_SESSION['workitem_error'] = "Failed to accept bid, bid has been deleted!";
                             }
                         }
                         // Send email to not accepted bidders
                         $this->sendMailToDiscardedBids($worklist_id);
                         $runner = new User();
                         $runner->findUserById($workitem->getRunnerId());
                         $runner->updateBudget(-$total, $workitem->getBudget_id());
                     } else {
                         $overBudget = money_format('%i', $total - $remainingFunds);
                         $_SESSION['workitem_error'] = "Failed to accept bids. Accepting this bids would make you " . $overBudget . " over your budget!";
                     }
                 }
             }
         }
         $redirectToDefaultView = true;
     }
     //Withdraw a bid
     if ($action == "withdraw_bid") {
         if (isset($_REQUEST['bid_id'])) {
             $this->withdrawBid(intval($_REQUEST['bid_id']), $_REQUEST['withdraw_bid_reason']);
         } else {
             $fee_id = intval($_REQUEST['fee_id']);
             $res = mysql_query('SELECT f.bid_id, f.amount, w.runner_id FROM `' . FEES . '` AS f, ' . WORKLIST . ' AS w WHERE f.`id`=' . $fee_id . ' AND f.worklist_id = w.id');
             $fee = mysql_fetch_object($res);
             if ((int) $fee->bid_id !== 0) {
                 $this->withdrawBid($fee->bid_id, $_REQUEST['withdraw_bid_reason']);
             } else {
                 $this->deleteFee($fee_id);
             }
             // Update Runner's Budget
             $runner = new User();
             $runner->findUserById($fee->runner_id);
             $runner->updateBudget($fee->amount, $workitem->getBudget_id());
         }
         $redirectToDefaultView = true;
     }
     //Decline a bid
     if ($action == "decline_bid") {
         if (isset($_REQUEST['bid_id'])) {
             $this->withdrawBid(intval($_REQUEST['bid_id']), $_REQUEST['decline_bid_reason']);
         } else {
             $fee_id = intval($_REQUEST['fee_id']);
             $res = mysql_query('SELECT f.bid_id, f.amount, w.runner_id FROM `' . FEES . '` AS f, ' . WORKLIST . ' AS w WHERE f.`id`=' . $fee_id . ' AND f.worklist_id = w.id');
             $fee = mysql_fetch_object($res);
             if ((int) $fee->bid_id !== 0) {
                 $this->withdrawBid($fee->bid_id, $_REQUEST['decline_bid_reason']);
             } else {
                 $this->deleteFee($fee_id);
             }
             // Update Runner's Budget
             $runner = new User();
             $runner->findUserById($fee->runner_id);
             $runner->updateBudget($fee->amount, $workitem->getBudget_id());
         }
         $redirectToDefaultView = true;
     }
     // we have a Journal message, send it to Journal - except for DRAFTS
     if (isset($journal_message) && $workitem->getStatus() != 'Draft') {
         Utils::systemNotification($journal_message);
         //$postProcessUrl = WORKITEM_URL . $worklist_id . "?msg=" . $journal_message;
     }
     if ($redirectToDefaultView) {
         $this->redirect('./' . $worklist_id);
     }
     // handle the makeshift error I made..
     $erroneous = false;
     if (isset($_SESSION['workitem_error'])) {
         $erroneous = true;
         $the_errors = $_SESSION['workitem_error'];
         unset($_SESSION['workitem_error']);
         $this->write('erroneous', $erroneous);
         $this->write('the_errors', $the_errors);
     }
     // Process the request normally and display the page.
     //get workitem from db
     $worklist = $workitem->getWorkItem($worklist_id);
     $this->write('worklist', $worklist);
     //get bids
     $bids = $workitem->getBids($worklist_id);
     // get only those bids that have not expired, used to determine whether
     // runner can edit the job notes
     $this->write('activeBids', (array) $workitem->getBids($workitem->getId(), false));
     //Findout if the current user already has any bids.
     // Yes, it's a String instead of boolean to make it easy to use in JS.
     // Suppress names if not is_runner, or creator of Item. Still show if it's user's bid.
     $currentUserHasBid = "false";
     if (!empty($bids) && is_array($bids)) {
         foreach ($bids as &$bid) {
             if ($bid['email'] == $currentUsername) {
                 $currentUserHasBid = "true";
                 //break;
             }
             if (!($user->getId() == $bid['bidder_id'] || $user->isRunnerOfWorkitem($workitem) || $workitem->getIsRelRunner() && !$worklist['runner_id'])) {
                 if ($user->getIs_admin() == 0) {
                     $bid['nickname'] = '*name hidden*';
                     $bid['bid_amount'] = '***';
                     $bid['email'] = '********';
                     $bid['notes'] = '********';
                 }
             }
             $bid['bid_created'] = $this->convertTimezone($bid['unix_bid_created']);
             if ($bid['unix_bid_accepted'] > 0) {
                 $bid['bid_accepted'] = $this->convertTimezone($bid['unix_bid_accepted']);
             } else {
                 $bid['bid_accepted'] = '';
             }
             if ($bid['unix_done_full'] > 0 && !empty($bid['unix_done_full'])) {
                 $bid['unix_done_full'] = $this->convertTimezone($bid['unix_done_full']);
             } else {
                 $bid['unix_done_full'] = '';
             }
             // calculate Total Time to Complete
             if (isset($bid['unix_done_by']) && $bid['unix_done_by'] != 0) {
                 $timeToComplete = (int) $bid['unix_done_by'] - (int) $bid['unix_bid_created'];
                 if ($bid['unix_bid_accepted'] > 0) {
                     $timeElapsed = (int) $bid['unix_now'] - (int) $bid['unix_bid_accepted'];
                     $timeToComplete -= $timeElapsed;
                 }
                 $fullDays = floor($timeToComplete / (60 * 60 * 24));
                 $fullHours = floor(($timeToComplete - $fullDays * 60 * 60 * 24) / (60 * 60));
                 $fullMinutes = floor(($timeToComplete - $fullDays * 60 * 60 * 24 - $fullHours * 60 * 60) / 60);
                 $bid['time_to_complete'] = $fullDays . ($fullDays == 1 ? " day, " : " days, ") . $fullHours . ($fullHours == 1 ? " hour and " : " hours and ") . $fullMinutes . ($fullMinutes == 1 ? " minute." : " minutes.");
             } else {
                 $bid['time_to_complete'] = null;
             }
         }
     }
     // break reference to $bid
     unset($bid);
     //get fees
     $fees = $workitem->getFees($worklist_id);
     $this->write('fees', $fees);
     $user_id = isset($_SESSION['userid']) ? $_SESSION['userid'] : "";
     $is_runner = isset($_SESSION['is_runner']) ? $_SESSION['is_runner'] : 0;
     $is_admin = isset($_SESSION['is_admin']) ? $_SESSION['is_admin'] : 0;
     $is_payer = isset($_SESSION['is_payer']) ? $_SESSION['is_payer'] : 0;
     $creator_id = isset($worklist['creator_id']) ? $worklist['creator_id'] : 0;
     $mechanic_id = isset($worklist['mechanic_id']) ? $worklist['mechanic_id'] : 0;
     $runner_id = isset($worklist['runner_id']) ? $worklist['runner_id'] : 0;
     $status_error = '';
     $has_budget = 0;
     if (!empty($user_id)) {
         $user = new User();
         $user->findUserById($user_id);
         if ($user->getBudget() > 0) {
             $has_budget = 1;
         }
         // fee defaults to 0 for internal users
         $crFee = 0;
         if (!$user->isInternal()) {
             // otherwise, lookup reviewer fee on the Project
             $crFee = $this->getCRFee($workitem);
         }
         $this->write('crFee', $crFee);
     }
     $workitem = WorkItem::getById($worklist['id']);
     if ($worklist['project_id']) {
         $workitem_project = new Project($worklist['project_id']);
     }
     $projects = Project::getProjects();
     $allowEdit = false;
     $classEditable = "";
     if ($workitem->getIsRelRunner() && is_null($worklist['runner_id']) || $user->getIs_admin() == 1 && $is_runner || $creator_id == $user_id && $worklist['status'] == 'Suggestion' && is_null($worklist['runner_id']) || $runner_id == $user_id) {
         $allowEdit = true;
         if ($action != "edit") {
             $classEditable = " editable";
         }
     }
     $this->write('classEditable', $classEditable);
     $this->write('allowEdit', $allowEdit);
     $hideFees = false;
     if ($worklist['status'] == 'Bidding' || $worklist['status'] == 'Suggestion') {
         $hideFees = true;
     }
     $this->write('hideFees', $hideFees);
     $this->write('bids', $bids);
     $this->write('userHasCodeReviewRights', $this->hasCodeReviewRights($user_id, $workitem));
     $this->write('mechanic', $workitem->getUserDetails($worklist['mechanic_id']));
     $reviewer = new User();
     $reviewer->findUserById($workitem->getCReviewerId());
     $this->write('reviewer', $reviewer);
     $this->write('action_error', isset($action_error) ? $action_error : '');
     $this->write('comments', Comment::findCommentsForWorkitem($worklist['id']));
     $this->write('entries', $this->getTaskPosts($worklist['id']));
     $this->write('message', isset($message) ? $message : '');
     $this->write('currentUserHasBid', $currentUserHasBid);
     $this->write('has_budget', $has_budget);
     $this->write('promptForReviewUrl', $promptForReviewUrl);
     $this->write('status_error', $status_error);
     $this->write('{{userinfotoshow}}', isset($_REQUEST['userinfotoshow']) && isset($_SESSION['userid']) ? $_REQUEST['userinfotoshow'] : 0);
     $job_analytics = VisitQueryTools::visitQuery($worklist_id);
     $this->write('viewCount', $job_analytics['views']);
     $job_views = $job_analytics['views'] > 1 ? " views" : " view";
     $this->write('views', $job_views);
     parent::run();
 }