Наследование: extends Traq\Models\Model
Пример #1
0
function createMilestone($project = null)
{
    if (!$project) {
        $project = createProject();
    }
    $milestone = new Milestone(['name' => 'milestone-' . mkRandomHash(5) . '-name', 'slug' => 'milestone-' . mkRandomHash(5) . '-slug', 'project_id' => $project['id']]);
    $milestone->save();
    return $milestone;
}
Пример #2
0
 /**
  * Handles the changelog page.
  */
 public function changelogAction()
 {
     $this->title($this->translate('changelog'));
     // Fetch issues
     $issues = [];
     $query = Ticket::select('t.summary', 't.ticket_id', 't.milestone_id', 't.type_id')->leftJoin('t', PREFIX . 'types', 'type', 'type.id = t.type_id')->leftJoin('t', PREFIX . 'statuses', 'status', 'status.id = t.status_id')->where('t.project_id = ?')->andWhere('type.show_on_changelog = 1')->andWhere('status.show_on_changelog = 1')->orderBy('t.type_id', 'ASC')->setParameter(0, $this->currentProject['id'])->execute();
     // Index issues by milestone ID
     foreach ($query->fetchAll() as $row) {
         $issues[$row['milestone_id']][] = $row;
     }
     // Fetch complete milestones
     $milestones = Milestone::select('m.id', 'm.name', 'm.slug')->where('m.project_id = ?')->andWhere('m.status = 2')->orderBy('m.display_order', 'DESC')->setParameter(0, $this->currentProject['id'])->execute()->fetchAll();
     // Combine issues and milestones into a single array
     foreach ($milestones as $index => $milestone) {
         $milestones[$index]['changes'] = isset($issues[$milestone['id']]) ? $issues[$milestone['id']] : [];
     }
     // Fetch ticket types
     $types = [];
     $query = queryBuilder()->select('id', 'bullet')->from(PREFIX . 'types')->execute();
     foreach ($query->fetchAll() as $row) {
         $types[$row['id']] = $row['bullet'];
     }
     return $this->respondTo(function ($format) use($milestones, $types) {
         if ($format == 'html') {
             return $this->render('projects/changelog.phtml', ['milestones' => $milestones, 'types' => $types]);
         } elseif ($format == 'txt') {
             $resp = $this->render('projects/changelog.txt.php', ['_layout' => false, 'milestones' => $milestones]);
             $resp->contentType = 'text/plain';
             return $resp;
         }
     });
 }
Пример #3
0
 /**
  * @return array[]
  */
 public function milestoneSelectOptions($valueField = 'id', $status = null, $sort = 'ASC')
 {
     $options = [];
     $milestones = Milestone::where('project_id = ?')->setParameter(0, $this->id)->orderBy('display_order', $sort);
     if ($status !== null) {
         $milestones->andWhere('status = ?')->setParameter(1, $status);
     }
     foreach ($milestones->execute()->fetchAll() as $milestone) {
         $options[] = ['label' => $milestone['name'], 'value' => $milestone[$valueField]];
     }
     return $options;
 }
Пример #4
0
 /**
  * Show milestone.
  *
  * @param string $slug
  */
 public function showAction($slug)
 {
     list($openQuery, $startedQuery, $closedQuery) = $this->getTicketCountQueries();
     $milestone = Milestone::where('project_id = :project_id')->andWhere('slug = :slug')->addSelect("({$openQuery}) AS open_tickets")->addSelect("({$startedQuery}) AS started_tickets")->addSelect("({$closedQuery}) AS closed_tickets")->setParameter('project_id', $this->currentProject['id'])->setParameter('slug', $slug)->setParameter('open_count_is_closed', false, 'boolean')->setParameter('closed_count_is_closed', false, 'boolean')->fetch();
     $this->addCrumb($milestone['name'], $this->generateUrl('milestone', ['slug' => $milestone['slug']]));
     return $this->respondTo(function ($format) use($milestone) {
         if ($format == 'html') {
             return $this->render('roadmap/show.phtml', ['milestone' => $milestone]);
         } elseif ($format == 'json') {
             return $this->jsonResponse($milestone);
         }
     });
 }
Пример #5
0
 /**
  * Toggles the subscription.
  *
  * @param string  $type Subscription type (Project, Milestone, Ticket)
  * @param integer $id   Subscribed object ID
  */
 public function action_toggle($type, $id)
 {
     switch ($type) {
         // Project
         case 'project':
             // Delete subscription
             if (is_subscribed($this->user, $this->project)) {
                 $sub = Subscription::select()->where(array(array('project_id', $this->project->id), array('user_id', $this->user->id), array('type', 'project')))->exec()->fetch();
                 $sub->delete();
             } else {
                 $sub = new Subscription(array('type' => "project", 'project_id' => $this->project->id, 'user_id' => $this->user->id, 'object_id' => $this->project->id));
                 $sub->save();
             }
             Request::redirectTo($this->project->href());
             break;
             // Milestone
         // Milestone
         case 'milestone':
             // Get milestone
             $milestone = Milestone::select()->where(array(array('project_id', $this->project->id), array('slug', $id)))->exec()->fetch();
             // Delete subscription
             if (is_subscribed($this->user, $milestone)) {
                 $sub = Subscription::select()->where(array(array('project_id', $this->project->id), array('user_id', $this->user->id), array('type', 'milestone'), array('object_id', $milestone->id)))->exec()->fetch();
                 $sub->delete();
             } else {
                 $sub = new Subscription(array('type' => "milestone", 'project_id' => $this->project->id, 'user_id' => $this->user->id, 'object_id' => $milestone->id));
                 $sub->save();
             }
             Request::redirectTo($milestone->href());
             break;
             // Milestone
         // Milestone
         case 'ticket':
             // Get ticket
             $ticket = Ticket::select()->where(array(array('project_id', $this->project->id), array('ticket_id', $id)))->exec()->fetch();
             // Delete subscription
             if (is_subscribed($this->user, $ticket)) {
                 $sub = Subscription::select()->where(array(array('project_id', $this->project->id), array('user_id', $this->user->id), array('type', 'ticket'), array('object_id', $ticket->id)))->exec()->fetch();
                 $sub->delete();
             } else {
                 $sub = new Subscription(array('type' => "ticket", 'project_id' => $this->project->id, 'user_id' => $this->user->id, 'object_id' => $ticket->id));
                 $sub->save();
             }
             Request::redirectTo($ticket->href());
             break;
     }
 }
Пример #6
0
 /**
  * Returns the subscribed object.
  *
  * @return object
  */
 public function object()
 {
     if ($this->object !== null) {
         return $this->object;
     }
     switch ($this->type) {
         case 'project':
             $this->object = Project::find($this->object_id);
             break;
         case 'milestone':
             $this->object = Milestone::find($this->object_id);
             break;
         case 'ticket':
             $this->object = Ticket::find($this->object_id);
             break;
     }
     return $this->object;
 }
Пример #7
0
 /**
  * Override to only get the relevant projects milestones.
  *
  * @return array
  */
 protected function getAllRows()
 {
     return Milestone::select('id', 'name', 'codename', 'status')->where('project_id = ?')->orderBy('display_order', 'ASC')->setParameter(0, $this->currentProject['id'])->execute()->fetchAll();
 }
Пример #8
0
<?php

/*!
 * Traq Lite
 * Copyright (c) 2009-2016 Jack P.
 * https://github.com/nirix/traq-lite
 *
 * Licensed under the BSD 3-Clause license.
 */
use Traq\Models\Milestone;
$milestone = new Milestone();
if (Request::$method == 'POST') {
    $milestone->set(['name' => Request::$post['name'], 'slug' => Request::$post['slug'], 'description' => Request::$post['description'], 'project_id' => Request::$post['project_id'], 'display_order' => Request::$post['display_order']]);
    if ($milestone->validate()) {
        db()->beginTransaction();
        $query = db()->prepare('
            INSERT INTO ' . PREFIX . 'milestones
            (name, slug, description, project_id, display_order, created_at)
            VALUES(:name, :slug, :description, :project_id, :display_order, NOW())
        ');
        $query->bindValue(':name', $milestone['name']);
        $query->bindValue(':slug', $milestone['slug']);
        $query->bindValue(':description', $milestone['description']);
        $query->bindValue(':project_id', $milestone['project_id'], PDO::PARAM_INT);
        $query->bindValue(':display_order', $milestone['display_order'], PDO::PARAM_INT);
        $query->execute();
        db()->commit();
        return redirect('/admin/milestones');
    }
}
return view('admin/milestones/new.phtml', ['milestone' => $milestone]);
Пример #9
0
        $resp = $t->visit('admin_new_project', ['cookie' => ['traq' => $admin['session_hash']]]);
        $t->assertEquals(200, $resp->status);
        $t->assertContains('<h1 class="page-header">New Project</h1>', $resp->body);
    });
    $g->test('Create project', function ($t) use($admin) {
        $resp = $t->visit('admin_create_project', ['method' => 'POST', 'post' => ['name' => 'My Project', 'slug' => 'my-project', 'info' => 'This is a test project.'], 'cookie' => ['traq' => $admin['session_hash']]]);
        $t->assertRedirectTo($t->generateUrl('admin_projects'), $resp);
    });
    $g->test('Slug in use', function ($t) use($admin) {
        $resp = $t->visit('admin_create_project', ['method' => 'POST', 'post' => ['slug' => 'my-project'], 'cookie' => ['traq' => $admin['session_hash']]]);
        $t->assertContains('Slug is already in use', $resp->body);
    });
    $g->test('Edit project form', function ($t) use($admin, $project) {
        $resp = $t->visit('admin_edit_project', ['routeTokens' => ['id' => $project['id']], 'cookie' => ['traq' => $admin['session_hash']]]);
        $t->assertContains('<h1 class="page-header">Edit Project</h1>', $resp->body);
    });
    $g->test('Update project', function ($t) use($admin, $project) {
        $resp = $t->visit('admin_save_project', ['method' => 'PATCH', 'routeTokens' => ['id' => $project['id']], 'post' => ['name' => 'Just Another Project'], 'cookie' => ['traq' => $admin['session_hash']]]);
        $t->assertRedirectTo($t->generateUrl('admin_projects'), $resp);
    });
    $g->test('Slug is required', function ($t) use($admin, $project) {
        $resp = $t->visit('admin_save_project', ['method' => 'PATCH', 'routeTokens' => ['id' => $project['id']], 'post' => ['slug' => ''], 'cookie' => ['traq' => $admin['session_hash']]]);
        $t->assertContains('Slug is required', $resp->body);
    });
    $g->test('Delete project', function ($t) use($admin, $project) {
        $milestone = createMilestone($project);
        $resp = $t->visit('admin_delete_project', ['method' => 'DELETE', 'routeTokens' => ['id' => $project['id']], 'cookie' => ['traq' => $admin['session_hash']]]);
        $t->assertRedirectTo($t->generateUrl('admin_projects'), $resp);
        $t->assertFalse(Milestone::find($milestone['id']));
    });
});