Adding project groups

This commit is contained in:
Dan Cryer 2015-10-08 16:33:01 +01:00
parent e186874eba
commit 74d313862c
18 changed files with 695 additions and 72 deletions

View file

@ -135,15 +135,17 @@ class Application extends b8\Application
*/
protected function setLayoutVariables(View &$layout)
{
/** @var \PHPCI\Store\ProjectStore $projectStore */
$projectStore = b8\Store\Factory::getStore('Project');
$layout->projects = $projectStore->getWhere(
array('archived' => (int)isset($_GET['archived'])),
50,
0,
array(),
array('title' => 'ASC')
);
$groups = array();
$groupList = b8\Store\Factory::getStore('ProjectGroup')->getWhere(array(), 100, 0, array(), array('title' => 'ASC'));
foreach ($groupList['items'] as $group) {
$thisGroup = array('title' => $group->getTitle());
$projects = b8\Store\Factory::getStore('Project')->getByGroupId($group->getId());
$thisGroup['projects'] = $projects['items'];
$groups[] = $thisGroup;
}
$layout->groups = $groups;
}
/**

View file

@ -0,0 +1,104 @@
<?php
/**
* PHPCI - Continuous Integration for PHP
*
* @copyright Copyright 2015, Block 8 Limited.
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
* @link https://www.phptesting.org/
*/
namespace PHPCI\Controller;
use b8;
use b8\Form;
use b8\Store;
use PHPCI\Controller;
use PHPCI\Model\ProjectGroup;
/**
* Project Controller - Allows users to create, edit and view projects.
* @author Dan Cryer <dan@block8.co.uk>
* @package PHPCI
* @subpackage Web
*/
class GroupController extends Controller
{
/**
* @var \PHPCI\Store\ProjectGroupStore
*/
protected $groupStore;
public function init()
{
$this->groupStore = b8\Store\Factory::getStore('ProjectGroup');
}
public function index()
{
$this->requireAdmin();
$groups = array();
$groupList = $this->groupStore->getWhere(array(), 100, 0, array(), array('title' => 'ASC'));
foreach ($groupList['items'] as $group) {
$thisGroup = array(
'title' => $group->getTitle(),
'id' => $group->getId(),
);
$projects = b8\Store\Factory::getStore('Project')->getByGroupId($group->getId());
$thisGroup['projects'] = $projects['items'];
$groups[] = $thisGroup;
}
$this->view->groups = $groups;
}
public function edit($id = null)
{
$this->requireAdmin();
if (!is_null($id)) {
$group = $this->groupStore->getById($id);
} else {
$group = new ProjectGroup();
}
if ($this->request->getMethod() == 'POST') {
$group->setTitle($this->getParam('title'));
$this->groupStore->save($group);
$response = new b8\Http\Response\RedirectResponse();
$response->setHeader('Location', PHPCI_URL.'group');
return $response;
}
$form = new Form();
$form->setMethod('POST');
$form->setAction(PHPCI_URL . 'group/edit' . (!is_null($id) ? '/' . $id : ''));
$title = new Form\Element\Text('title');
$title->setContainerClass('form-group');
$title->setClass('form-control');
$title->setLabel('Group Title');
$title->setValue($group->getTitle());
$submit = new Form\Element\Submit();
$submit->setValue('Save Group');
$form->addField($title);
$form->addField($submit);
$this->view->form = $form;
}
public function delete($id)
{
$this->requireAdmin();
$group = $this->groupStore->getById($id);
$this->groupStore->delete($group);
$response = new b8\Http\Response\RedirectResponse();
$response->setHeader('Location', PHPCI_URL.'group');
return $response;
}
}

View file

@ -23,15 +23,20 @@ use PHPCI\Model\Build;
class HomeController extends \PHPCI\Controller
{
/**
* @var \b8\Store\BuildStore
* @var \PHPCI\Store\BuildStore
*/
protected $buildStore;
/**
* @var \b8\Store\ProjectStore
* @var \PHPCI\Store\ProjectStore
*/
protected $projectStore;
/**
* @var \PHPCI\Store\ProjectGroupStore
*/
protected $groupStore;
/**
* Initialise the controller, set up stores and services.
*/
@ -39,6 +44,7 @@ class HomeController extends \PHPCI\Controller
{
$this->buildStore = b8\Store\Factory::getStore('Build');
$this->projectStore = b8\Store\Factory::getStore('Project');
$this->groupStore = b8\Store\Factory::getStore('ProjectGroup');
}
/**
@ -47,15 +53,6 @@ class HomeController extends \PHPCI\Controller
public function index()
{
$this->layout->title = Lang::get('dashboard');
$projects = $this->projectStore->getWhere(
array('archived' => (int)isset($_GET['archived'])),
50,
0,
array(),
array('title' => 'ASC')
);
$builds = $this->buildStore->getLatestBuilds(null, 10);
foreach ($builds as &$build) {
@ -63,8 +60,7 @@ class HomeController extends \PHPCI\Controller
}
$this->view->builds = $builds;
$this->view->projects = $projects['items'];
$this->view->summary = $this->getSummaryHtml($projects);
$this->view->groups = $this->getGroupInfo();
return $this->view->render();
}
@ -102,7 +98,7 @@ class HomeController extends \PHPCI\Controller
$failures = array();
$counts = array();
foreach ($projects['items'] as $project) {
foreach ($projects as $project) {
$summaryBuilds[$project->getId()] = $this->buildStore->getLatestBuilds($project->getId());
$count = $this->buildStore->getWhere(
@ -122,7 +118,7 @@ class HomeController extends \PHPCI\Controller
}
$summaryView = new b8\View('SummaryTable');
$summaryView->projects = $projects['items'];
$summaryView->projects = $projects;
$summaryView->builds = $summaryBuilds;
$summaryView->successful = $successes;
$summaryView->failed = $failures;
@ -147,4 +143,21 @@ class HomeController extends \PHPCI\Controller
return $view->render();
}
protected function getGroupInfo()
{
$rtn = array();
$groups = $this->groupStore->getWhere(array(), 100, 0, array(), array('title' => 'ASC'));
foreach ($groups['items'] as $group) {
$thisGroup = array('title' => $group->getTitle());
$projects = $this->projectStore->getByGroupId($group->getId());
$thisGroup['projects'] = $projects['items'];
$thisGroup['summary'] = $this->getSummaryHtml($thisGroup['projects']);
$rtn[] = $thisGroup;
}
return $rtn;
}
}

View file

@ -220,6 +220,7 @@ class ProjectController extends PHPCI\Controller
'build_config' => $this->getParam('build_config', null),
'allow_public_status' => $this->getParam('allow_public_status', 0),
'branch' => $this->getParam('branch', null),
'group' => $this->getParam('group_id', null),
);
$project = $this->projectService->createProject($title, $type, $reference, $options);
@ -284,6 +285,7 @@ class ProjectController extends PHPCI\Controller
'allow_public_status' => $this->getParam('allow_public_status', 0),
'archived' => $this->getParam('archived', 0),
'branch' => $this->getParam('branch', null),
'group' => $this->getParam('group_id', null),
);
$project = $this->projectService->updateProject($project, $title, $type, $reference, $options);
@ -352,6 +354,20 @@ class ProjectController extends PHPCI\Controller
$field->setClass('form-control')->setContainerClass('form-group')->setValue('master');
$form->addField($field);
$field = Form\Element\Select::create('group_id', 'Project Group', true);
$field->setClass('form-control')->setContainerClass('form-group')->setValue(1);
$groups = array();
$groupStore = b8\Store\Factory::getStore('ProjectGroup');
$groupList = $groupStore->getWhere(array(), 100, 0, array(), array('title' => 'ASC'));
foreach ($groupList['items'] as $group) {
$groups[$group->getId()] = $group->getTitle();
}
$field->setOptions($groups);
$form->addField($field);
$field = Form\Element\Checkbox::create('allow_public_status', Lang::get('allow_public_status'), false);
$field->setContainerClass('form-group');
$field->setCheckedValue(1);

View file

@ -0,0 +1,29 @@
<?php
use Phinx\Migration\AbstractMigration;
class AddProjectGroups extends AbstractMigration
{
public function change()
{
$table = $this->table('project_group');
$table->addColumn('title', 'string', array('limit' => 100, 'null' => false));
$table->save();
$group = new \PHPCI\Model\ProjectGroup();
$group->setTitle('Projects');
/** @var \PHPCI\Model\ProjectGroup $group */
$group = \b8\Store\Factory::getStore('ProjectGroup')->save($group);
$table = $this->table('project');
$table->addColumn('group_id', 'integer', array(
'signed' => true,
'null' => false,
'default' => $group->getId(),
));
$table->addForeignKey('group_id', 'project_group', 'id', array('delete'=> 'RESTRICT', 'update' => 'CASCADE'));
$table->save();
}
}

View file

@ -45,6 +45,7 @@ class ProjectBase extends Model
'ssh_public_key' => null,
'allow_public_status' => null,
'archived' => null,
'group_id' => null,
);
/**
@ -64,8 +65,10 @@ class ProjectBase extends Model
'ssh_public_key' => 'getSshPublicKey',
'allow_public_status' => 'getAllowPublicStatus',
'archived' => 'getArchived',
'group_id' => 'getGroupId',
// Foreign key getters:
'Group' => 'getGroup',
);
/**
@ -85,8 +88,10 @@ class ProjectBase extends Model
'ssh_public_key' => 'setSshPublicKey',
'allow_public_status' => 'setAllowPublicStatus',
'archived' => 'setArchived',
'group_id' => 'setGroupId',
// Foreign key setters:
'Group' => 'setGroup',
);
/**
@ -153,10 +158,14 @@ class ProjectBase extends Model
),
'archived' => array(
'type' => 'tinyint',
'length' => 4,
'nullable' => true,
'length' => 1,
'default' => null,
),
'group_id' => array(
'type' => 'int',
'length' => 11,
'default' => 1,
),
);
/**
@ -165,12 +174,20 @@ class ProjectBase extends Model
public $indexes = array(
'PRIMARY' => array('unique' => true, 'columns' => 'id'),
'idx_project_title' => array('columns' => 'title'),
'group_id' => array('columns' => 'group_id'),
);
/**
* @var array
*/
public $foreignKeys = array(
'project_ibfk_1' => array(
'local_col' => 'group_id',
'update' => 'CASCADE',
'delete' => '',
'table' => 'project_group',
'col' => 'id'
),
);
/**
@ -317,6 +334,18 @@ class ProjectBase extends Model
return $rtn;
}
/**
* Get the value of GroupId / group_id.
*
* @return int
*/
public function getGroupId()
{
$rtn = $this->data['group_id'];
return $rtn;
}
/**
* Set the value of Id / id.
*
@ -530,10 +559,12 @@ class ProjectBase extends Model
/**
* Set the value of Archived / archived.
*
* Must not be null.
* @param $value int
*/
public function setArchived($value)
{
$this->_validateNotNull('Archived', $value);
$this->_validateInt('Archived', $value);
if ($this->data['archived'] === $value) {
@ -545,6 +576,83 @@ class ProjectBase extends Model
$this->_setModified('archived');
}
/**
* Set the value of GroupId / group_id.
*
* Must not be null.
* @param $value int
*/
public function setGroupId($value)
{
$this->_validateNotNull('GroupId', $value);
$this->_validateInt('GroupId', $value);
if ($this->data['group_id'] === $value) {
return;
}
$this->data['group_id'] = $value;
$this->_setModified('group_id');
}
/**
* Get the ProjectGroup model for this Project by Id.
*
* @uses \PHPCI\Store\ProjectGroupStore::getById()
* @uses \PHPCI\Model\ProjectGroup
* @return \PHPCI\Model\ProjectGroup
*/
public function getGroup()
{
$key = $this->getGroupId();
if (empty($key)) {
return null;
}
$cacheKey = 'Cache.ProjectGroup.' . $key;
$rtn = $this->cache->get($cacheKey, null);
if (empty($rtn)) {
$rtn = Factory::getStore('ProjectGroup', 'PHPCI')->getById($key);
$this->cache->set($cacheKey, $rtn);
}
return $rtn;
}
/**
* Set Group - Accepts an ID, an array representing a ProjectGroup or a ProjectGroup model.
*
* @param $value mixed
*/
public function setGroup($value)
{
// Is this an instance of ProjectGroup?
if ($value instanceof \PHPCI\Model\ProjectGroup) {
return $this->setGroupObject($value);
}
// Is this an array representing a ProjectGroup item?
if (is_array($value) && !empty($value['id'])) {
return $this->setGroupId($value['id']);
}
// Is this a scalar value representing the ID of this foreign key?
return $this->setGroupId($value);
}
/**
* Set Group - Accepts a ProjectGroup model.
*
* @param $value \PHPCI\Model\ProjectGroup
*/
public function setGroupObject(\PHPCI\Model\ProjectGroup $value)
{
return $this->setGroupId($value->getId());
}
/**
* Get Build models by ProjectId for this Project.
*

View file

@ -0,0 +1,168 @@
<?php
/**
* ProjectGroup base model for table: project_group
*/
namespace PHPCI\Model\Base;
use PHPCI\Model;
use b8\Store\Factory;
/**
* ProjectGroup Base Model
*/
class ProjectGroupBase extends Model
{
/**
* @var array
*/
public static $sleepable = array();
/**
* @var string
*/
protected $tableName = 'project_group';
/**
* @var string
*/
protected $modelName = 'ProjectGroup';
/**
* @var array
*/
protected $data = array(
'id' => null,
'title' => null,
);
/**
* @var array
*/
protected $getters = array(
// Direct property getters:
'id' => 'getId',
'title' => 'getTitle',
// Foreign key getters:
);
/**
* @var array
*/
protected $setters = array(
// Direct property setters:
'id' => 'setId',
'title' => 'setTitle',
// Foreign key setters:
);
/**
* @var array
*/
public $columns = array(
'id' => array(
'type' => 'int',
'length' => 11,
'primary_key' => true,
'auto_increment' => true,
'default' => null,
),
'title' => array(
'type' => 'varchar',
'length' => 100,
'default' => null,
),
);
/**
* @var array
*/
public $indexes = array(
'PRIMARY' => array('unique' => true, 'columns' => 'id'),
);
/**
* @var array
*/
public $foreignKeys = array(
);
/**
* Get the value of Id / id.
*
* @return int
*/
public function getId()
{
$rtn = $this->data['id'];
return $rtn;
}
/**
* Get the value of Title / title.
*
* @return string
*/
public function getTitle()
{
$rtn = $this->data['title'];
return $rtn;
}
/**
* Set the value of Id / id.
*
* Must not be null.
* @param $value int
*/
public function setId($value)
{
$this->_validateNotNull('Id', $value);
$this->_validateInt('Id', $value);
if ($this->data['id'] === $value) {
return;
}
$this->data['id'] = $value;
$this->_setModified('id');
}
/**
* Set the value of Title / title.
*
* Must not be null.
* @param $value string
*/
public function setTitle($value)
{
$this->_validateNotNull('Title', $value);
$this->_validateString('Title', $value);
if ($this->data['title'] === $value) {
return;
}
$this->data['title'] = $value;
$this->_setModified('title');
}
/**
* Get Project models by GroupId for this ProjectGroup.
*
* @uses \PHPCI\Store\ProjectStore::getByGroupId()
* @uses \PHPCI\Model\Project
* @return \PHPCI\Model\Project[]
*/
public function getGroupProjects()
{
return Factory::getStore('Project', 'PHPCI')->getByGroupId($this->getId());
}
}

View file

@ -0,0 +1,18 @@
<?php
/**
* ProjectGroup model for table: project_group
*/
namespace PHPCI\Model;
use PHPCI\Model\Base\ProjectGroupBase;
/**
* ProjectGroup Model
* @uses PHPCI\Model\Base\ProjectGroupBase
*/
class ProjectGroup extends ProjectGroupBase
{
// This class has been left blank so that you can modify it - changes in this file will not be overwritten.
}

View file

@ -89,6 +89,10 @@ class ProjectService
$project->setBranch($options['branch']);
}
if (array_key_exists('group', $options)) {
$project->setGroup($options['group']);
}
// Allow certain project types to set access information:
$this->processAccessInformation($project);

View file

@ -0,0 +1,46 @@
<?php
/**
* ProjectGroup base store for table: project_group
*/
namespace PHPCI\Store\Base;
use b8\Database;
use b8\Exception\HttpException;
use PHPCI\Store;
use PHPCI\Model\ProjectGroup;
/**
* ProjectGroup Base Store
*/
class ProjectGroupStoreBase extends Store
{
protected $tableName = 'project_group';
protected $modelName = '\PHPCI\Model\ProjectGroup';
protected $primaryKey = 'id';
public function getByPrimaryKey($value, $useConnection = 'read')
{
return $this->getById($value, $useConnection);
}
public function getById($value, $useConnection = 'read')
{
if (is_null($value)) {
throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.');
}
$query = 'SELECT * FROM `project_group` WHERE `id` = :id LIMIT 1';
$stmt = Database::getConnection($useConnection)->prepare($query);
$stmt->bindValue(':id', $value);
if ($stmt->execute()) {
if ($data = $stmt->fetch(\PDO::FETCH_ASSOC)) {
return new ProjectGroup($data);
}
}
return null;
}
}

View file

@ -20,24 +20,11 @@ class ProjectStoreBase extends Store
protected $modelName = '\PHPCI\Model\Project';
protected $primaryKey = 'id';
/**
* Returns a Project model by primary key.
* @param mixed $value
* @param string $useConnection
* @return \@appNamespace\Model\Project|null
*/
public function getByPrimaryKey($value, $useConnection = 'read')
{
return $this->getById($value, $useConnection);
}
/**
* Returns a Project model by Id.
* @param mixed $value
* @param string $useConnection
* @throws HttpException
* @return \@appNamespace\Model\Project|null
*/
public function getById($value, $useConnection = 'read')
{
if (is_null($value)) {
@ -57,14 +44,6 @@ class ProjectStoreBase extends Store
return null;
}
/**
* Returns an array of Project models by Title.
* @param mixed $value
* @param int $limit
* @param string $useConnection
* @throws HttpException
* @return array
*/
public function getByTitle($value, $limit = 1000, $useConnection = 'read')
{
if (is_null($value)) {
@ -92,4 +71,32 @@ class ProjectStoreBase extends Store
return array('items' => array(), 'count' => 0);
}
}
public function getByGroupId($value, $limit = 1000, $useConnection = 'read')
{
if (is_null($value)) {
throw new HttpException('Value passed to ' . __FUNCTION__ . ' cannot be null.');
}
$query = 'SELECT * FROM `project` WHERE `group_id` = :group_id LIMIT :limit';
$stmt = Database::getConnection($useConnection)->prepare($query);
$stmt->bindValue(':group_id', $value);
$stmt->bindValue(':limit', (int)$limit, \PDO::PARAM_INT);
if ($stmt->execute()) {
$res = $stmt->fetchAll(\PDO::FETCH_ASSOC);
$map = function ($item) {
return new Project($item);
};
$rtn = array_map($map, $res);
$count = count($rtn);
return array('items' => $rtn, 'count' => $count);
} else {
return array('items' => array(), 'count' => 0);
}
}
}

View file

@ -0,0 +1,18 @@
<?php
/**
* ProjectGroup store for table: project_group
*/
namespace PHPCI\Store;
use PHPCI\Store\Base\ProjectGroupStoreBase;
/**
* ProjectGroup Store
* @uses PHPCI\Store\Base\ProjectGroupStoreBase
*/
class ProjectGroupStore extends ProjectGroupStoreBase
{
// This class has been left blank so that you can modify it - changes in this file will not be overwritten.
}

View file

@ -0,0 +1,9 @@
<div class="box box-primary">
<div class="box-header">
<h3 class="box-title">Add / Edit Group</h3>
</div>
<div class="box-body">
<?php print $form; ?>
</div>
</div>

View file

@ -0,0 +1,41 @@
<div class="clearfix" style="margin-bottom: 20px;">
<a class="btn btn-success pull-right" href="<?php print PHPCI_URL . 'group/edit'; ?>">
Add Group
</a>
</div>
<div class="box box-primary">
<div class="box-header">
<h3 class="box-title">Project Groups</h3>
</div>
<table class="table">
<thead>
<tr>
<th>Title</th>
<th style="width: 100px;">Projects</th>
<th style="width: 150px"></th>
</tr>
</thead>
<tbody>
<?php foreach($groups as $group): ?>
<tr>
<td><?php print $group['title']; ?></td>
<td><?php print count($group['projects']); ?></td>
<td>
<a class="btn btn-sm btn-default" href="<?php print PHPCI_URL . 'group/edit/' . $group['id']; ?>">
Edit
</a>
<?php if (!count($group['projects'])): ?>
<a class="btn btn-sm btn-danger delete-group" href="<?php print PHPCI_URL . 'group/delete/' . $group['id']; ?>">
Delete
</a>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>

View file

@ -2,7 +2,17 @@
<div class="row">
<div class="col-sm-5">
<?php print $summary; ?>
<?php foreach ($groups as $group): ?>
<div class="box box-primary">
<div class="box-header">
<h3 class="box-title"><?php print $group['title']; ?></h3>
</div>
<div class="box-body">
<?php print $group['summary']; ?>
</div>
</div>
<?php endforeach; ?>
</div>
<div class="col-sm-7 pull-left">

View file

@ -5,8 +5,16 @@
</script>
<div class="clearfix" style="margin-bottom: 20px;">
<a class="btn btn-default" href="<?php print PHPCI_URL . 'project/edit/' . $project->getId(); ?>">
<?php Lang::out('edit_project'); ?>
</a>
<a class="btn btn-danger" href="javascript:confirmDelete('<?php print PHPCI_URL . 'project/delete/' . $project->getId(); ?>', '<?php print Lang::out('project'); ?>', true">
<?php Lang::out('delete_project'); ?>
</a>
<div class="pull-right btn-group">
<a class="btn btn-success" href="<?php print PHPCI_URL . 'project/build/' . $project->getId(); ?>/<?php echo urlencode($branch) ?>">
<a class="btn btn-success" href="<?php print PHPCI_URL . 'project/build/' . $project->getId(); ?><?php echo !empty($branch) ? '/' . urlencode($branch) : '' ?>">
<?php Lang::out('build_now'); ?>
</a>

View file

@ -83,7 +83,7 @@ foreach($projects as $project):
?>
<?php
if (count($projects) > 10) {
if (count($projects) > 5) {
$containerClass = 'small-box-minimal';
} else {
$containerClass = 'small-box-full';
@ -92,7 +92,7 @@ foreach($projects as $project):
<div class="small-box <?php print $containerClass; ?> bg-<?php print $subcls; ?>">
<?php if (count($projects) > 10): ?>
<?php if (count($projects) > 5): ?>
<div class="inner">
<h4>

View file

@ -159,6 +159,12 @@
</a>
</li>
<li>
<a href="<?php print PHPCI_URL; ?>group">
<i class="fa fa-angle-double-right"></i> Project Groups
</a>
</li>
<li>
<a href="<?php print PHPCI_URL; ?>settings">
<i class="fa fa-angle-double-right"></i> <?php Lang::out('settings'); ?>
@ -180,41 +186,57 @@
</li>
<?php endif; ?>
<?php foreach ($projects['items'] as $project): ?>
<?php foreach ($groups as $group): ?>
<li class="treeview">
<a href="#">
<i class="fa fa-<?php print $project->getIcon(); ?>"></i>
<span><?php print $project->getTitle(); ?></span>
<i class="fa fa-folder"></i>
<span><?php print $group['title']; ?></span>
<i class="fa fa-angle-left pull-right"></i>
</a>
<?php if (count($group['projects'])): ?>
<ul class="treeview-menu">
<?php foreach($group['projects'] as $project): ?>
<li>
<a href="<?php print PHPCI_URL; ?>project/view/<?php print $project->getId(); ?>">
<i class="fa fa-angle-double-right"></i> <?php Lang::out('view'); ?>
<i class="fa fa-<?php print $project->getIcon(); ?>"></i>
<span><?php print $project->getTitle(); ?></span>
</a>
</li>
<li>
<a href="<?php print PHPCI_URL; ?>project/build/<?php print $project->getId(); ?>">
<i class="fa fa-angle-double-right"></i> <?php Lang::out('build_now'); ?>
</a>
</li>
<?php /* <ul class="treeview-menu">
<?php if ($this->User()->getIsAdmin()): ?>
<li>
<a href="<?php print PHPCI_URL; ?>project/edit/<?php print $project->getId(); ?>">
<i class="fa fa-angle-double-right"></i> <?php Lang::out('edit_project'); ?>
</a>
</li>
<li>
<a href="<?php print PHPCI_URL; ?>project/view/<?php print $project->getId(); ?>">
<i class="fa fa-angle-double-right"></i> <?php Lang::out('view'); ?>
</a>
</li>
<li>
<a href="<?php print PHPCI_URL; ?>project/delete/<?php print $project->getId(); ?>">
<i class="fa fa-angle-double-right"></i> <?php Lang::out('delete_project'); ?>
</a>
<li>
<a href="<?php print PHPCI_URL; ?>project/build/<?php print $project->getId(); ?>">
<i class="fa fa-angle-double-right"></i> <?php Lang::out('build_now'); ?>
</a>
</li>
<?php if ($this->User()->getIsAdmin()): ?>
<li>
<a href="<?php print PHPCI_URL; ?>project/edit/<?php print $project->getId(); ?>">
<i class="fa fa-angle-double-right"></i> <?php Lang::out('edit_project'); ?>
</a>
</li>
<li>
<a href="<?php print PHPCI_URL; ?>project/delete/<?php print $project->getId(); ?>">
<i class="fa fa-angle-double-right"></i> <?php Lang::out('delete_project'); ?>
</a>
</li>
<?php endif; ?>
</ul>
*/ ?>
</li>
<?php endif; ?>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</li>
<?php endforeach; ?>