Merge branch 'zentaopms_239'
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
$config->program = new stdclass();
|
||||
$config->program->showAllProjects = 0;
|
||||
|
||||
$config->program->editor = new stdclass();
|
||||
$config->program->editor->create = array('id' => 'desc', 'tools' => 'simpleTools');
|
||||
|
||||
@@ -10,6 +10,14 @@
|
||||
*/
|
||||
class program extends control
|
||||
{
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param string $moduleName
|
||||
* @param string $methodName
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($moduleName = '', $methodName = '')
|
||||
{
|
||||
parent::__construct($moduleName, $methodName);
|
||||
@@ -757,4 +765,16 @@ class program extends control
|
||||
|
||||
echo $this->fetch('program', 'product', "programID=$programID");
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax set show setting.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function ajaxSetShowSetting()
|
||||
{
|
||||
$data = fixer::input('post')->get();
|
||||
$this->loadModel('setting')->updateItem("{$this->app->user->account}.program.showAllProjects", $data->showAllProjects);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,3 +26,6 @@
|
||||
|
||||
.scroll {overflow-x: hidden; overflow-y: auto;}
|
||||
.fix-table-copy-wrapper thead > tr > th:first-child {background: none!important;}
|
||||
|
||||
#showSettingsBox {text-align:right; margin-top:-15px; margin-right:4px;}
|
||||
#showSettingsBox .checkbox-primary {display:inline-block;}
|
||||
|
||||
@@ -131,9 +131,14 @@ function calcColHeight(col, lane, colCards, colHeight)
|
||||
return colCards.length * 62;
|
||||
}
|
||||
|
||||
$(function()
|
||||
/**
|
||||
* Init kanban.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function initKanban()
|
||||
{
|
||||
/* Init all kanbans */
|
||||
$.each(kanbanGroup, function(key, programsData)
|
||||
{
|
||||
var $kanban = $('#kanban-' + key);
|
||||
@@ -146,4 +151,23 @@ $(function()
|
||||
calcColHeight: calcColHeight
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
$(function()
|
||||
{
|
||||
/* Init all kanbans */
|
||||
initKanban();
|
||||
|
||||
$('#showAllProjects').click(function()
|
||||
{
|
||||
var showAllProjects = $(this).prop('checked') ? 1 : 0;
|
||||
$.post(createLink('program', 'ajaxSetShowSetting'), {"showAllProjects": showAllProjects}, function()
|
||||
{
|
||||
$.get(createLink('program', 'kanban'), function(data)
|
||||
{
|
||||
$('#kanbanList').html($(data).find('#kanbanList').html());
|
||||
initKanban();
|
||||
});
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
@@ -82,6 +82,7 @@ $lang->program->manageMembers = 'Program Team';
|
||||
$lang->program->confirmChangePRJUint = 'Synchronize the budget unit of the subprograms and the projects of the program? If yes, please the current exchange rate.';
|
||||
$lang->program->exRateNotNegative = 'The『exchange rate』should not be negative.';
|
||||
$lang->program->changePRJUnit = 'Update the budget unit of the project';
|
||||
$lang->program->showNotCurrentProjects = 'Display project information of non current program';
|
||||
|
||||
$lang->program->progress = 'Progress';
|
||||
$lang->program->children = 'Child';
|
||||
@@ -163,3 +164,5 @@ $lang->program->kanban->doingExecutions = 'Ongoing Executions';
|
||||
$lang->program->kanban->normalReleases = 'Normal Releases';
|
||||
|
||||
$lang->program->kanban->laneColorList = array('#32C5FF', '#006AF1', '#9D28B2', '#FF8F26', '#FFC20E', '#00A78E', '#7FBB00', '#424BAC', '#C0E9FF', '#EC2761');
|
||||
|
||||
$lang->program->defaultProgram = 'Default program';
|
||||
|
||||
@@ -82,6 +82,7 @@ $lang->program->manageMembers = 'Program Team';
|
||||
$lang->program->confirmChangePRJUint = 'Synchronize the budget unit of the subprograms and the projects of the program? If yes, please the current exchange rate.';
|
||||
$lang->program->exRateNotNegative = 'The『exchange rate』should not be negative.';
|
||||
$lang->program->changePRJUnit = 'Update the budget unit of the project';
|
||||
$lang->program->showNotCurrentProjects = 'Display project information of non current program';
|
||||
|
||||
$lang->program->progress = 'Progress';
|
||||
$lang->program->children = 'Add Child';
|
||||
@@ -163,3 +164,5 @@ $lang->program->kanban->doingExecutions = 'Ongoing Executions';
|
||||
$lang->program->kanban->normalReleases = 'Normal Releases';
|
||||
|
||||
$lang->program->kanban->laneColorList = array('#32C5FF', '#006AF1', '#9D28B2', '#FF8F26', '#FFC20E', '#00A78E', '#7FBB00', '#424BAC', '#C0E9FF', '#EC2761');
|
||||
|
||||
$lang->program->defaultProgram = 'Default program';
|
||||
|
||||
@@ -82,6 +82,7 @@ $lang->program->manageMembers = 'Program Team';
|
||||
$lang->program->confirmChangePRJUint = 'Synchronize the budget unit of the subprograms and the projects of the program? If yes, please the current exchange rate.';
|
||||
$lang->program->exRateNotNegative = 'The『exchange rate』should not be negative.';
|
||||
$lang->program->changePRJUnit = 'Update the budget unit of the project';
|
||||
$lang->program->showNotCurrentProjects = 'Display project information of non current program';
|
||||
|
||||
$lang->program->progress = 'Progress';
|
||||
$lang->program->children = 'Child';
|
||||
@@ -163,3 +164,5 @@ $lang->program->kanban->doingExecutions = 'Ongoing Executions';
|
||||
$lang->program->kanban->normalReleases = 'Normal Releases';
|
||||
|
||||
$lang->program->kanban->laneColorList = array('#32C5FF', '#006AF1', '#9D28B2', '#FF8F26', '#FFC20E', '#00A78E', '#7FBB00', '#424BAC', '#C0E9FF', '#EC2761');
|
||||
|
||||
$lang->program->defaultProgram = 'Default program';
|
||||
|
||||
@@ -82,6 +82,7 @@ $lang->program->manageMembers = '项目集团队';
|
||||
$lang->program->confirmChangePRJUint = '是否同步更新该项目集下子项目集和项目的预算的单位?若确认更新,请填写今日汇率。';
|
||||
$lang->program->exRateNotNegative = '『汇率』不能是负数。';
|
||||
$lang->program->changePRJUnit = '更新项目预算单位';
|
||||
$lang->program->showNotCurrentProjects = '显示非当前项目集的项目信息';
|
||||
|
||||
$lang->program->progress = '项目进度';
|
||||
$lang->program->children = '添加子项目集';
|
||||
@@ -163,3 +164,5 @@ $lang->program->kanban->doingExecutions = '进行中的执行';
|
||||
$lang->program->kanban->normalReleases = '正常的发布';
|
||||
|
||||
$lang->program->kanban->laneColorList = array('#32C5FF', '#006AF1', '#9D28B2', '#FF8F26', '#FFC20E', '#00A78E', '#7FBB00', '#424BAC', '#C0E9FF', '#EC2761');
|
||||
|
||||
$lang->program->defaultProgram = '默认项目集';
|
||||
|
||||
+122
-15
@@ -66,34 +66,90 @@ class programModel extends model
|
||||
* @param string $mode all|assign
|
||||
* @param string $status all|noclosed
|
||||
* @param string|array $append
|
||||
* @param string|int $shadow all | 0 | 1
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getProductPairs($programID = 0, $mode = 'assign', $status = 'all', $append = '')
|
||||
public function getProductPairs($programID = 0, $mode = 'assign', $status = 'all', $append = '', $shadow = 0)
|
||||
{
|
||||
/* Get the top programID. */
|
||||
if($programID)
|
||||
{
|
||||
$program = $this->getByID($programID);
|
||||
$path = explode(',', $program->path);
|
||||
$path = array_filter($path);
|
||||
$path = array_filter(explode(',', $program->path));
|
||||
$programID = current($path);
|
||||
}
|
||||
|
||||
/* When mode equals assign and programID equals 0, you can query the standalone product. */
|
||||
if(!empty($append) and is_array($append)) $append = implode(',', $append);
|
||||
$views = empty($append) ? $this->app->user->view->products : $this->app->user->view->products . ",$append";
|
||||
|
||||
$views = empty($append) ? $this->app->user->view->products : $this->app->user->view->products . ",$append";
|
||||
$products = $this->dao->select('*')->from(TABLE_PRODUCT)
|
||||
return $this->dao->select('*')->from(TABLE_PRODUCT)
|
||||
->where('deleted')->eq(0)
|
||||
->andWhere('vision')->eq($this->config->vision)
|
||||
->beginIF($shadow !== 'all')->andWhere('shadow')->eq((int)$shadow)->fi()
|
||||
->beginIF($mode == 'assign')->andWhere('program')->eq($programID)->fi()
|
||||
->beginIF(strpos($status, 'noclosed') !== false)->andWhere('status')->ne('closed')->fi()
|
||||
->beginIF(!$this->app->user->admin)->andWhere('id')->in($views)->fi()
|
||||
->fetchPairs('id', 'name');
|
||||
return $products;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get product pairs which name with program.
|
||||
*
|
||||
* @param int $programID
|
||||
* @param string $mode
|
||||
* @param string $status
|
||||
* @param string $append
|
||||
* @param int $shadow
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getProductPairsWithProgram($programID = 0, $mode = 'assign', $status = 'all', $append = '', $shadow = 0)
|
||||
{
|
||||
/* Get the top programID. */
|
||||
if($programID)
|
||||
{
|
||||
$program = $this->getByID($programID);
|
||||
$path = array_filter(explode(',', $program->path));
|
||||
$programID = current($path);
|
||||
}
|
||||
|
||||
/* When mode equals assign and programID equals 0, you can query the standalone product. */
|
||||
if(!empty($append) and is_array($append)) $append = implode(',', $append);
|
||||
$views = empty($append) ? $this->app->user->view->products : $this->app->user->view->products . ",$append";
|
||||
|
||||
$products = $this->dao->select("t1.id, t1.program, CONCAT(IF(t2.name IS NOT NULL, t2.name, ''), '/', t1.name) AS name")->from(TABLE_PRODUCT)->alias('t1')
|
||||
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.program = t2.id')
|
||||
->where('t1.deleted')->eq('0')
|
||||
->andWhere('t1.vision')->eq($this->config->vision)
|
||||
->beginIF($shadow !== 'all')->andWhere('t1.shadow')->eq((int)$shadow)->fi()
|
||||
->beginIF($mode == 'assign')->andWhere('t1.program')->eq($programID)->fi()
|
||||
->beginIF(strpos($status, 'noclosed') !== false)->andWhere('t1.status')->ne('closed')->fi()
|
||||
->beginIF(!$this->app->user->admin)->andWhere('t1.id')->in($views)->fi()
|
||||
->orderBy('t1.program, t1.order_asc')
|
||||
->fetchGroup('program');
|
||||
|
||||
/* Put products of current program first.*/
|
||||
if($mode != 'assign' && $programID)
|
||||
{
|
||||
$currentProgramProducts = $products[$programID];
|
||||
|
||||
unset($products[$programID]);
|
||||
|
||||
array_unshift($products, $currentProgramProducts);
|
||||
}
|
||||
|
||||
$productPairs = array();
|
||||
foreach($products as $programProducts)
|
||||
{
|
||||
foreach($programProducts as $product) $productPairs[$product->id] = $product->name;
|
||||
}
|
||||
|
||||
return $productPairs;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get program by id.
|
||||
*
|
||||
@@ -271,9 +327,8 @@ class programModel extends model
|
||||
->fetchGroup('product');
|
||||
|
||||
/* Get all products linked projects. */
|
||||
$projectGroup = $this->dao->select('DISTINCT t1.product, t2.id, t2.name, t2.status, t2.end')->from(TABLE_PROJECTPRODUCT)->alias('t1')
|
||||
->leftJoin(TABLE_PROJECT)->alias('t2')
|
||||
->on('t1.project = t2.id')
|
||||
$projectGroup = $this->dao->select('t1.product,t2.id,t2.name,t2.status,t2.end,t2.parent,t2.path')->from(TABLE_PROJECTPRODUCT)->alias('t1')
|
||||
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id')
|
||||
->where('t2.deleted')->eq(0)
|
||||
->andWhere('t1.product')->in($productPairs)
|
||||
->andWhere('t2.type')->eq('project')
|
||||
@@ -296,6 +351,7 @@ class programModel extends model
|
||||
->where('type')->in('sprint,stage,kanban')
|
||||
->andWhere('status')->eq('doing')
|
||||
->andWhere('deleted')->eq(0)
|
||||
->andWhere('multiple')->ne(0)
|
||||
->beginIF(!$this->app->user->admin)->andWhere('id')->in($this->app->user->view->sprints)->fi()
|
||||
->orderBy('id_asc')
|
||||
->fetchAll('project');
|
||||
@@ -336,6 +392,7 @@ class programModel extends model
|
||||
foreach($projects as $project)
|
||||
{
|
||||
if(helper::diffDate(helper::today(), $project->end) > 0) $project->delay = 1;
|
||||
if($this->config->systemMode == 'ALM' and !$this->config->program->showAllProjects and $project->parent != $product->program and strpos($project->path, ",{$product->program},") !== 0) continue;
|
||||
|
||||
$status = $project->status == 'wait' ? 'wait' : 'doing';
|
||||
$execution = zget($doingExecutions, $project->id, array());
|
||||
@@ -569,9 +626,9 @@ class programModel extends model
|
||||
->leftJoin(TABLE_STAKEHOLDER)->alias('t3')->on('t1.id=t3.objectID')
|
||||
->where('t1.deleted')->eq('0')
|
||||
->andWhere('t1.vision')->eq($this->config->vision)
|
||||
->beginIF($browseType == 'bysearch')->andWhere($query)->fi()
|
||||
->beginIF($this->config->systemMode == 'new')->andWhere('t1.type')->eq('project')->fi()
|
||||
->beginIF($this->config->systemMode == 'new' and ($this->cookie->involved or $involved))->andWhere('t2.type')->eq('project')->fi()
|
||||
->beginIF($browseType == 'bysearch' and $query)->andWhere($query)->fi()
|
||||
->andWhere('t1.type')->eq('project')
|
||||
->beginIF($this->cookie->involved or $involved)->andWhere('t2.type')->eq('project')->fi()
|
||||
->beginIF(!in_array($browseType, array('all', 'undone', 'bysearch', 'review', 'unclosed'), true))->andWhere('t1.status')->eq($browseType)->fi()
|
||||
->beginIF($browseType == 'undone' or $browseType == 'unclosed')->andWhere('t1.status')->in('wait,doing')->fi()
|
||||
->beginIF($browseType == 'review')
|
||||
@@ -579,8 +636,7 @@ class programModel extends model
|
||||
->andWhere('t1.reviewStatus')->eq('doing')
|
||||
->fi()
|
||||
->beginIF($path)->andWhere('t1.path')->like($path . '%')->fi()
|
||||
->beginIF(!$queryAll and !$this->app->user->admin and $this->config->systemMode == 'new')->andWhere('t1.id')->in($this->app->user->view->projects)->fi()
|
||||
->beginIF(!$queryAll and !$this->app->user->admin and $this->config->systemMode == 'classic')->andWhere('t1.id')->in($this->app->user->view->sprints)->fi()
|
||||
->beginIF(!$queryAll and !$this->app->user->admin)->andWhere('t1.id')->in($this->app->user->view->projects)->fi()
|
||||
->beginIF($this->cookie->involved or $involved)
|
||||
->andWhere('t1.openedBy', true)->eq($this->app->user->account)
|
||||
->orWhere('t1.PM')->eq($this->app->user->account)
|
||||
@@ -594,7 +650,7 @@ class programModel extends model
|
||||
->fetchAll('id');
|
||||
|
||||
/* Determine how to display the name of the program. */
|
||||
if($programTitle and $this->config->systemMode == 'new')
|
||||
if($programTitle and $this->config->systemMode == 'ALM')
|
||||
{
|
||||
$programList = $this->getPairs();
|
||||
foreach($projectList as $id => $project)
|
||||
@@ -1593,4 +1649,55 @@ class programModel extends model
|
||||
}
|
||||
return $menu;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create default program.
|
||||
*
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
public function createDefaultProgram()
|
||||
{
|
||||
$defaultProgram = $this->loadModel('setting')->getItem('owner=system&module=common§ion=global&key=defaultProgram');
|
||||
if($defaultProgram)
|
||||
{
|
||||
$program = $this->dao->select('id')->from(TABLE_PROGRAM)->where('id')->eq($defaultProgram)->andWhere('deleted')->eq(0)->fetch();
|
||||
if($program) return $defaultProgram;
|
||||
}
|
||||
|
||||
$program = $this->dao->select('id')->from(TABLE_PROGRAM)->where('name')->eq($this->lang->program->defaultProgram)->andWhere('deleted')->eq(0)->fetch();
|
||||
if($program) return $program->id;
|
||||
|
||||
$account = isset($this->app->user->account) ? $this->app->user->account : '';
|
||||
$minBegin = $this->dao->select('min(begin) as min')->from(TABLE_PROJECT)->where('deleted')->eq(0)->fetch('min');
|
||||
|
||||
$program = new stdclass();
|
||||
$program->name = $this->lang->program->defaultProgram;
|
||||
$program->type = 'program';
|
||||
$program->budgetUnit = 'CNY';
|
||||
$program->status = 'doing';
|
||||
$program->auth = 'extend';
|
||||
$program->begin = !empty($minBegin) ? $minBegin : helper::today();
|
||||
$program->end = LONG_TIME;
|
||||
$program->openedBy = $account;
|
||||
$program->openedDate = helper::now();
|
||||
$program->openedVersion = $this->config->version;
|
||||
$program->acl = 'open';
|
||||
$program->grade = 1;
|
||||
$program->vision = 'rnd';
|
||||
|
||||
$this->app->loadLang('program');
|
||||
$this->app->loadLang('project');
|
||||
$this->lang->project->name = $this->lang->program->name;
|
||||
|
||||
$this->dao->insert(TABLE_PROGRAM)->data($program)->exec();
|
||||
if(dao::isError()) return false;
|
||||
|
||||
$programID = $this->dao->lastInsertId();
|
||||
|
||||
$this->dao->update(TABLE_PROGRAM)->set('path')->eq(",{$programID},")->set('`order`')->eq($programID * 5)->where('id')->eq($programID)->exec();
|
||||
$this->loadModel('action')->create('program', $programID, 'openedbysystem');
|
||||
|
||||
return $programID;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,12 +11,18 @@
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<?php include '../../common/view/kanban.html.php';?>
|
||||
<?php if(empty($kanbanGroup)):?>
|
||||
<div class="table-empty-tip cell">
|
||||
<p class="text-muted"><?php echo $lang->program->noProgram;?></p>
|
||||
<div id='showSettingsBox'>
|
||||
<div class="checkbox-primary checkbox">
|
||||
<input type="checkbox" value="1" id="showAllProjects" title="<?php echo $lang->program->showNotCurrentProjects;?>" <?php echo $config->program->showAllProjects ? 'checked' : '';?>>
|
||||
<label for="showAllProjects"><?php echo $lang->program->showNotCurrentProjects;?></label>
|
||||
</div>
|
||||
</div>
|
||||
<?php else:?>
|
||||
<div id='kanbanList'>
|
||||
<?php if(empty($kanbanGroup)):?>
|
||||
<div class="table-empty-tip cell">
|
||||
<p class="text-muted"><?php echo $lang->program->noProgram;?></p>
|
||||
</div>
|
||||
<?php else:?>
|
||||
<?php foreach($kanbanGroup as $type => $programs):?>
|
||||
<?php if(empty($programs)) continue;?>
|
||||
<div class='panel kanban-panel'>
|
||||
@@ -27,26 +33,26 @@
|
||||
<div id='kanban-<?php echo $type;?>' class='kanban'></div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php endforeach;?>
|
||||
<?php
|
||||
$kanbanColumns = array();
|
||||
$kanbanColumns['unclosedProduct'] = array('name' => $lang->program->kanban->openProducts, 'type' => 'unclosedProduct');
|
||||
$kanbanColumns['unexpiredPlan'] = array('name' => $lang->program->kanban->unexpiredPlans, 'type' => 'unexpiredPlan');
|
||||
$kanbanColumns['waitProject'] = array('name' => $lang->program->kanban->waitingProjects, 'type' => 'waitProject');
|
||||
$kanbanColumns['doingProject'] = array('name' => $lang->program->kanban->doingProjects, 'type' => 'doingProject');
|
||||
$kanbanColumns['doingExecution'] = array('name' => $lang->program->kanban->doingExecutions, 'type' => 'doingExecution');
|
||||
$kanbanColumns['normalRelease'] = array('name' => $lang->program->kanban->normalReleases, 'type' => 'normalRelease');
|
||||
$userPrivs = array();
|
||||
$userPrivs['product'] = common::hasPriv('product', 'browse');
|
||||
$userPrivs['productplan'] = common::hasPriv('productplan', 'view');
|
||||
$userPrivs['project'] = common::hasPriv('project', 'index');
|
||||
$userPrivs['execution'] = common::hasPriv('execution', 'task');
|
||||
$userPrivs['release'] = common::hasPriv('release', 'view');
|
||||
js::set('kanbanColumns', array_values($kanbanColumns));
|
||||
js::set('userPrivs', $userPrivs);
|
||||
js::set('kanbanGroup', $kanbanGroup);
|
||||
js::set('doingText', $lang->program->statusList['doing']);
|
||||
?>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
<?php
|
||||
$kanbanColumns = array();
|
||||
$kanbanColumns['unclosedProduct'] = array('name' => $lang->program->kanban->openProducts, 'type' => 'unclosedProduct');
|
||||
$kanbanColumns['unexpiredPlan'] = array('name' => $lang->program->kanban->unexpiredPlans, 'type' => 'unexpiredPlan');
|
||||
$kanbanColumns['waitProject'] = array('name' => $lang->program->kanban->waitingProjects, 'type' => 'waitProject');
|
||||
$kanbanColumns['doingProject'] = array('name' => $lang->program->kanban->doingProjects, 'type' => 'doingProject');
|
||||
$kanbanColumns['doingExecution'] = array('name' => $lang->program->kanban->doingExecutions, 'type' => 'doingExecution');
|
||||
$kanbanColumns['normalRelease'] = array('name' => $lang->program->kanban->normalReleases, 'type' => 'normalRelease');
|
||||
$userPrivs = array();
|
||||
$userPrivs['product'] = common::hasPriv('product', 'browse');
|
||||
$userPrivs['productplan'] = common::hasPriv('productplan', 'view');
|
||||
$userPrivs['project'] = common::hasPriv('project', 'index');
|
||||
$userPrivs['execution'] = common::hasPriv('execution', 'task');
|
||||
$userPrivs['release'] = common::hasPriv('release', 'view');
|
||||
js::set('kanbanColumns', array_values($kanbanColumns));
|
||||
js::set('userPrivs', $userPrivs);
|
||||
js::set('kanbanGroup', $kanbanGroup);
|
||||
js::set('doingText', $lang->program->statusList['doing']);
|
||||
?>
|
||||
<?php endif; ?>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
|
||||
Reference in New Issue
Block a user