229 lines
7.1 KiB
PHP
229 lines
7.1 KiB
PHP
<?php
|
||
declare(strict_types=1);
|
||
/**
|
||
* The control file of git module of ZenTaoPMS.
|
||
*
|
||
* @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
|
||
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
|
||
* @author Yanyi Cao <caoyanyi@easycorp.com>
|
||
* @package git
|
||
* @link https://www.zentao.net
|
||
*/
|
||
class git extends control
|
||
{
|
||
/**
|
||
* 定时任务:同步git。
|
||
* Sync git.
|
||
*
|
||
* @access public
|
||
* @return void
|
||
*/
|
||
public function run()
|
||
{
|
||
$this->git->run();
|
||
}
|
||
|
||
/**
|
||
* Git对比文件。
|
||
* Diff a file.
|
||
*
|
||
* @param string $path
|
||
* @param int $revision
|
||
* @access public
|
||
* @return void
|
||
*/
|
||
public function diff(string $path, string $revision)
|
||
{
|
||
if(isset($_GET['repoUrl'])) $path = $this->get->repoUrl;
|
||
|
||
$this->loadModel('repo');
|
||
$path = helper::safe64Decode($path);
|
||
$repos = $this->repo->getListBySCM(implode(',', $this->config->repo->gitTypeList), 'haspriv');
|
||
$currentRepo = null;
|
||
foreach($repos as $repo)
|
||
{
|
||
if(!empty($repo->path) && strpos($path, $repo->path) === 0) $currentRepo = $repo;
|
||
if(!empty($repo->apiPath) && strpos($path, $repo->apiPath) === 0) $currentRepo = $repo;
|
||
}
|
||
|
||
if($currentRepo && common::hasPriv('repo', 'diff'))
|
||
{
|
||
$entry = $this->repo->encodePath(str_replace(array($currentRepo->path, $currentRepo->apiPath), '', $path));
|
||
$oldRevision = "$revision^";
|
||
return print($this->fetch('repo', 'diff', "repoID=$currentRepo->id&objectID=0&entry=$entry&oldRevision=$oldRevision&revision=$revision"));
|
||
}
|
||
|
||
if($currentRepo)
|
||
{
|
||
$scm = $this->app->loadClass('scm');
|
||
$scm->setEngine($currentRepo);
|
||
}
|
||
|
||
$this->view->path = $path;
|
||
$this->view->revision = $revision;
|
||
$this->view->diff = $currentRepo ? $scm->diff($path, $revision) : '';
|
||
$this->display();
|
||
}
|
||
|
||
/**
|
||
* Git查看文件。
|
||
* Cat a file.
|
||
*
|
||
* @param string $path
|
||
* @param int $revision
|
||
* @access public
|
||
* @return void
|
||
*/
|
||
public function cat(string $path, string $revision)
|
||
{
|
||
if(isset($_GET['repoUrl'])) $path = $this->get->repoUrl;
|
||
|
||
$this->loadModel('repo');
|
||
$path = helper::safe64Decode($path);
|
||
$repos = $this->repo->getListBySCM(implode(',', $this->config->repo->gitTypeList), 'haspriv');
|
||
$currentRepo = null;
|
||
foreach($repos as $repo)
|
||
{
|
||
if(!empty($repo->path) && strpos($path, $repo->path) === 0) $currentRepo = $repo;
|
||
if(!empty($repo->apiPath) && strpos($path, $repo->apiPath) === 0) $currentRepo = $repo;
|
||
}
|
||
|
||
if($currentRepo && common::hasPriv('repo', 'view'))
|
||
{
|
||
$entry = $this->repo->encodePath(str_replace(array($currentRepo->path, $repo->apiPath), '', $path));
|
||
return print($this->fetch('repo', 'view', "repoID=$currentRepo->id&objectID=0&entry=$entry&revision=$revision"));
|
||
}
|
||
|
||
if($currentRepo)
|
||
{
|
||
$scm = $this->app->loadClass('scm');
|
||
$scm->setEngine($currentRepo);
|
||
}
|
||
$this->view->path = $path;
|
||
$this->view->revision = $revision;
|
||
$this->view->code = $currentRepo ? $scm->cat($path, $revision) : '';
|
||
|
||
$this->display();
|
||
}
|
||
|
||
/**
|
||
* 通过api同步提交信息。
|
||
* Sync from the syncer by api.
|
||
*
|
||
* @access public
|
||
* @return void
|
||
*/
|
||
public function apiSync()
|
||
{
|
||
if($this->post->logs) return;
|
||
|
||
$repoRoot = $this->post->repoRoot;
|
||
$list = json_decode($this->post->logs);
|
||
|
||
$logs = array();
|
||
$i = 0;
|
||
foreach($list as $line)
|
||
{
|
||
if(!$line)
|
||
{
|
||
$i++;
|
||
continue;
|
||
}
|
||
$logs[$i][] = $line;
|
||
}
|
||
|
||
foreach($logs as $log)
|
||
{
|
||
$log = $this->git->convertLog($log);
|
||
if($log) $parsedLogs[] = $log;
|
||
}
|
||
|
||
$this->loadModel('repo');
|
||
$parsedObjects = array('stories' => array(), 'tasks' => array(), 'bugs' => array());
|
||
foreach($parsedLogs as $log)
|
||
{
|
||
$objects = $this->repo->parseComment($log->msg);
|
||
|
||
if($objects)
|
||
{
|
||
$this->git->saveAction2PMS($objects, $log, $repoRoot);
|
||
if($objects['stories']) $parsedObjects['stories'] = array_merge($parsedObjects['stories'], $objects['stories']);
|
||
if($objects['tasks']) $parsedObjects['tasks' ] = array_merge($parsedObjects['tasks'], $objects['tasks']);
|
||
if($objects['bugs']) $parsedObjects['bugs'] = array_merge($parsedObjects['bugs'], $objects['bugs']);
|
||
}
|
||
}
|
||
$parsedObjects['stories'] = array_unique($parsedObjects['stories']);
|
||
$parsedObjects['tasks'] = array_unique($parsedObjects['tasks']);
|
||
$parsedObjects['bugs'] = array_unique($parsedObjects['bugs']);
|
||
$this->view->parsedObjects = $parsedObjects;
|
||
return $this->display();
|
||
}
|
||
|
||
/**
|
||
* 保存git提交日志。
|
||
* Ajax save log.
|
||
*
|
||
* @access public
|
||
* @return void
|
||
*/
|
||
public function ajaxSaveLog()
|
||
{
|
||
$repoUrl = trim($this->post->repoUrl);
|
||
$message = trim($this->post->message);
|
||
$revision = trim($this->post->revision);
|
||
$files = $this->post->files;
|
||
if(empty($repoUrl)) return;
|
||
|
||
$repoUrl = rtrim($repoUrl, '/') . '/';
|
||
$parsedFiles = array();
|
||
$repoDirs = explode('/', trim($repoUrl, '/'));
|
||
foreach($files as $file)
|
||
{
|
||
$file = trim($file);
|
||
if(empty($file)) continue;
|
||
|
||
$action = '';
|
||
if(preg_match('/^[\w][ \t]/', $file))
|
||
{
|
||
$action = $file[0];
|
||
$file = trim(substr($file, 2));
|
||
}
|
||
$fileDirs = explode('/', trim($file, '/'));
|
||
$diffDirs = array_diff($fileDirs, $repoDirs);
|
||
|
||
foreach($fileDirs as $i => $dir)
|
||
{
|
||
if(isset($diffDirs[$i])) break;
|
||
if(!isset($diffDirs[$i])) unset($fileDirs[$i]);
|
||
}
|
||
$path = '/' . join('/', $fileDirs);
|
||
$parsedFiles[$action][] = ltrim($path, '/');
|
||
}
|
||
|
||
$objects = $this->loadModel('repo')->parseComment($message);
|
||
if($objects)
|
||
{
|
||
$log = new stdclass();
|
||
$log->author = $this->app->user->account;
|
||
$log->date = helper::now();
|
||
$log->msg = $message;
|
||
$log->revision = $revision;
|
||
$log->files = $parsedFiles;
|
||
$this->git->saveAction2PMS($objects, $log, $repoUrl);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取代码库列表。
|
||
* Ajax get repos.
|
||
*
|
||
* @access public
|
||
* @return void
|
||
*/
|
||
public function ajaxGetRepos()
|
||
{
|
||
$repos = $this->git->getRepos();
|
||
echo json_encode($repos);
|
||
}
|
||
}
|