class GITManagedWebpage {
const ERROR_CRITICAL = 1;
-
+ const SESSION_PREFIX = "GITManagedWebpage_";
private $giturl;
- private $workdir;
+ private $workdir, $localdir;
+ private $ready = false;
+ private $loopedcall = false;
+ private $config = null;
+ private $config_changed = true;
+ private $activeSession = null;
- public function __construct($giturl, $workdir = null) {
+ public function __construct($giturl, $workdir = null, $localdir = null) {
+ if(session_status() != PHP_SESSION_ACTIVE) {
+ session_start();
+ }
+
+ if(defined("GITMANAGED_EXECUTED")) {
+ $this->loopedcall = true;
+ return;
+ }
+
if($workdir === null) {
$workdir = dirname(__FILE__);
- if(!substr($workdir, -1) == "/")
+ if(substr($workdir, -1) != "/")
$workdir .= "/";
$workdir .= ".gitmanaged/";
}
- else if(!substr($workdir, -1) == "/")
+ else if(substr($workdir, -1) != "/")
$workdir .= "/";
+ if($localdir === null) {
+ $localdir = dirname(__FILE__);
+ if(substr($localdir, -1) != "/")
+ $localdir .= "/";
+ }
+ else if(substr($localdir, -1) != "/")
+ $localdir .= "/";
+
$this->giturl = $giturl;
$this->workdir = $workdir;
+ $this->localdir = $localdir;
- //if(!file_exists($this->workdir) || !is_dir($this->workdir)) {
+ if(!file_exists($this->workdir) || !is_dir($this->workdir)) {
if(file_exists($this->workdir) && !is_dir($this->workdir)) {
$this->error(self::ERROR_CRITICAL, "local workdir (".htmlspecialchars($this->workdir).") is not a directory.");
return;
}
$this->setupWorkdir();
- //}
+ }
+ $this->ready = true;
}
/* private function gitcmd(...)
} else
$argstr .= " ".escapeshellarg($arg);
}
- $gitcmd = 'git '.escapeshellarg('--git-dir='.$this->workdir.'/repository').$argstr;
+ $gitcmd = 'git '.escapeshellarg('--git-dir='.$this->workdir.'repository/.git').' '.escapeshellarg('--work-tree='.$this->workdir.'repository').$argstr;
$output = shell_exec($gitcmd);
return $output;
}
+ /* private function setConfig($name, $value)
+ * store a option in the configuration
+ */
+ private function setConfig($name, $value) {
+ $this->config[strtolower($name)] = $value;
+ $this->config_changed = true;
+ }
+
+ private function checkConfigIntegrity() {
+ foreach($this->config as $key => $value) {
+ if(substr($key, 0, strlen('branch_')) == 'branch_') {
+ if(!file_exists($this->workdir.$key)) {
+ unset($this->config['key']);
+ }
+ }
+ }
+ }
+
+ /* private function getConfig($name)
+ * get an option from the configuration
+ */
+ private function getConfig($name) {
+ if($this->config == null) {
+ if(!$this->ready)
+ return null;
+ if(file_exists($this->workdir."config.txt")) {
+ $config_txt = @file_get_contents($this->workdir."config.txt");
+ $this->config = unserialize($config_txt);
+ $this->checkConfigIntegrity();
+ } else {
+ $this->config = array();
+ return null;
+ }
+ }
+ if(array_key_exists(strtolower($name), $this->config))
+ return $this->config[strtolower($name)];
+ else
+ return null;
+ }
+
+ private function saveConfig() {
+ if($this->config_changed && $this->ready) {
+ $fp = fopen($this->workdir."config.txt", "w");
+ fwrite($fp, serialize($this->config));
+ fclose($fp);
+ }
+ }
+
/* private function setupWorkdir()
* Setup local GITManagedWebpage Work directory with git repository
*/
}
mkdir($this->workdir);
- mkdir($this->workdir.'/repository');
- shell_exec('git clone '.escapeshellarg($this->giturl).' '.escapeshellarg($this->workdir.'/repository'));
+ mkdir($this->workdir.'repository');
+ shell_exec('git clone '.escapeshellarg($this->giturl).' '.escapeshellarg($this->workdir.'repository'));
$gitok = $this->gitcmd("status");
if(preg_match("#Not a git repository#", $gitok)) {
- rmdir($this->workdir.'/repository');
+ rmdir($this->workdir.'repository');
rmdir($this->workdir);
$this->error(self::ERROR_CRITICAL, "error cloning git repository.");
return;
}
+ $fp = fopen($this->workdir.'.htaccess');
+ fwrite($fp, '
+Order deny,allow
+Deny from all
+');
+ fclose($fp);
+
+ $this->ready = true;
+ $default_branch = str_replace(array("\r", "\n"), array("", ""), $this->gitcmd("rev-parse", "--abbrev-ref", "HEAD"));
+ $this->setConfig("defaultbranch", $default_branch);
+ $this->saveConfig();
+ }
+
+ private function getActiveBranch() {
+ if($this->activeSession)
+ return $this->activeSession;
+ else if(isset($_SESSION[self::SESSION_PREFIX.'branch']))
+ return $_SESSION[self::SESSION_PREFIX.'branch'];
+ else
+ return $this->getConfig("defaultbranch");
+ }
+
+ private function setActiveBranch($branch, $remember) {
+ $this->activeSession = $branch;
+ if($remember)
+ $_SESSION[self::SESSION_PREFIX.'branch'] = $branch;
+ }
+
+ private function getLocalUntrackedFiles() {
+ $default_branch = $this->getConfig("defaultbranch");
+ $tracked_files = $this->gitcmd("ls-tree", $default_branch, "--full-name", "--name-only");
+ $local_files = shell_exec("find ".escapeshellarg($this->localdir));
+ $untracked_files = array();
+
+ $tracked_files = explode("\n", str_replace(array("\r"), array(""), $tracked_files));
+ $local_files = explode("\n", str_replace(array("\r"), array(""), $local_files));
+
+ foreach($local_files as $local_file) {
+ if(!$local_file)
+ continue;
+ if($strip_local || (($strip_local = strlen($this->localdir)) && substr($local_file, 0, $strip_local) == $this->localdir)) {
+ $local_file = substr($local_file, $strip_local);
+ }
+ $tracked = false;
+ foreach($tracked_files as $tracked_file) {
+ if($tracked_file == $local_file) {
+ $tracked = true;
+ break;
+ }
+ }
+ if(!$tracked) {
+ $untracked_files[] = $local_file;
+ }
+ }
+ return $untracked_files;
+ }
+
+ private function branchExists($branch) {
+ //check if branch exists
+ $gitret = $this->gitcmd("rev-list", "--max-count=1", $branch);
+ if(!preg_match("#([a-z0-9]{40})#", $gitret, $match))
+ return false;
+ else
+ return $match[1];
+ }
+
+ private function localBranchPath($branch, $create = false) {
+ $default_branch = $this->getConfig("defaultbranch");
+ if($branch == $default_branch)
+ $dir = $this->localdir;
+ else
+ $dir = $this->workdir.'branch_'.str_replace(array('/'), array('_'), $branch).'/';
+ if(file_exists($dir))
+ return $dir;
+ else if($create) {
+ mkdir($dir);
+ return $dir;
+ } else
+ return false;
+ }
+
+ private function updateBranch($branch, $path, $force = false) {
+ if(substr($path, -1) != '/')
+ $path .= '/';
+ $current_branch = str_replace(array("\r", "\n"), array("", ""), $this->gitcmd("rev-parse", "--abbrev-ref", "HEAD"));
+ $this->gitcmd("fetch");
+ $this->gitcmd("reset", "--hard", "origin/".$branch);
+ $gitret = $this->gitcmd("rev-list", "--max-count=1", $branch);
+ preg_match("#([a-z0-9]{40})#", $gitret, $match);
+ $newest_version = $match[1];
+
+ $deleted_files = array();
+ if(($current_version = $this->getConfig('version_'.$branch))) {
+ if($current_version == $newest_version && !$force)
+ return;
+ else {
+ $override_all = true;
+ $delfiles = $this->gitcmd("diff", "--diff-filter=D", "--name-only", $current_version, $newest_version);
+ $delfiles = explode("\n", str_replace(array("\r"), array(""), $delfiles));
+ foreach($delfiles as $file) {
+ if(!$file)
+ continue;
+ $deleted_files[] = $file;
+ }
+ }
+ } else
+ $override_all = true;
+ if($override_all) {
+ $rsync_present = preg_match("#rsync#", `which rsync`);
+ if($rsync_present)
+ shell_exec('rsync -avz --exclude ".git" '.escapeshellarg($this->workdir."repository/").' '.escapeshellarg($path));
+ else
+ shell_exec('tar -c --exclude ".git" -C '.escapeshellarg($this->workdir."repository").' . | tar -x -C '.escapeshellarg($path));
+
+ // remove deleted files
+ foreach($deleted_files as $file) {
+ unlink($path.$file);
+ }
+ }
+ $this->setConfig('version_'.$branch, $newest_version);
+ $this->saveConfig();
}
/* public function update()
- * Pulls latest commit of active branch and overwrites local files
+ * Pulls latest commit of active branch and overwrites files in branch folder
*/
public function update() {
+ if($this->loopedcall)
+ return;
+
+ $active_branch = $this->getActiveBranch();
+
+ if(!$this->branchExists($active_branch))
+ return false;
+ $dir = $this->localBranchPath($active_branch, true);
+ $this->updateBranch($active_branch, $dir);
+ }
+
+ public function setBranch($branch, $remember = false) {
+ if($this->loopedcall)
+ return;
+
+ if(!$this->branchExists($branch)) {
+ $this->gitcmd("fetch");
+ if(!$this->branchExists('origin/'.$branch))
+ return false;
+ }
+ $this->setActiveBranch($branch, $remember);
+
+ if(!$this->localBranchPath($branch)) {
+ $dir = $this->localBranchPath($branch, true);
+ $this->updateBranch($branch, $dir, true);
+ }
+ }
+ public function getExecFile($file = null) {
+ if($this->loopedcall)
+ return;
+ define("GITMANAGED_EXECUTED", true);
+
+ if(!$file)
+ $file = $_SERVER['PHP_SELF'];
+ if($file[0] == '/')
+ $file = substr($file, 1);
+
+ $default_branch = $this->getConfig("defaultbranch");
+ $active_branch = $this->getActiveBranch();
+ if($active_branch != $default_branch) {
+ if(!($dir = $this->localBranchPath($active_branch))) {
+ $dir = $this->localBranchPath($active_branch, true);
+ $this->updateBranch($active_branch, $dir, true);
+ }
+ chdir($dir);
+ return $dir.$file;
+ } else {
+ return $file;
+ }
+ }
+
+ public function showMngrWindow() {
+ $html = '<script type="text/javascript" src="http://lib.pk910.de/jquery.min.js"></script>';
+ $html .= '<script type="text/javascript" src="http://lib.pk910.de/jquery-ui/jquery-ui.min.js"></script>';
+ $html .= '<script type="text/javascript" src="http://lib.pk910.de/jquery-migrate.min.js"></script>';
+ $html .= '<script type="text/javascript" src="http://lib.pk910.de/jquery.window/jquery.window.js"></script>';
+ $html .= '<script type="text/javascript" src="http://lib.pk910.de/jquery.cookie/jquery.cookie.js"></script>';
+ $html .= '<link type="text/css" href="http://lib.pk910.de/jquery-ui/jquery-ui.min.css" rel="stylesheet" />';
+ $html .= '<link type="text/css" href="http://lib.pk910.de/jquery.window/css/jquery.window.css" rel="stylesheet" />';
+
+ $current_branch = $this->getActiveBranch();
+ $current_version = substr($this->getConfig('version_'.$current_branch), 0, 7);
+ $html .= <<<HTML_END
+<div id="gitmanagedwindow" style="display:none;">
+ <table width="100%" class="gitmanaged">
+ <tr>
+ <td colspan="2" align="center">
+ <h2>GITManagedWebpage</h2>
+ </td>
+ </tr>
+ <tr>
+ <td width="150px">current branch:</td>
+ <td>{$current_branch}</td>
+ </tr>
+ <tr>
+ <td>current version:</td>
+ <td>{$current_version}</td>
+ </tr>
+ <tr>
+ <td colspan="2" align="center"><input type="button" value="update branch" class="update"></td>
+ </tr>
+ </table>
+</div>
+
+<script type="text/javascript">
+$.window.prepare({
+ dock: 'right',
+ animationSpeed: 200,
+ minWinLong: 65
+});
+
+var cookie_prefix = 'gitmanaged_';
+var win = $.window({
+ icon: 'http://lib.pk910.de/_ico/git.ico',
+ title: "GIT Managed Webpage",
+ content: $('#gitmanagedwindow').html(),
+ checkBoundary: true,
+ withinBrowserWindow: true,
+
+ maximizable: false,
+ closable: false,
+
+ width: 200,
+ height: 150,
+
+ onMinimize: function(wnd) {
+ $.cookie(cookie_prefix+'minimized', '1');
+ },
+ onCascade: function(wnd) {
+ $.removeCookie(cookie_prefix+'minimized');
+ },
+ afterDrag: function(wnd) {
+ var pos = wnd.getContainer().position();
+ $.cookie(cookie_prefix+'pos', pos.left + ';' + pos.top)
+ },
+});
+
+function updateURLParameter(url, param, paramVal) {
+ var TheAnchor = null;
+ var newAdditionalURL = "";
+ var tempArray = url.split("?");
+ var baseURL = tempArray[0];
+ var additionalURL = tempArray[1];
+ var temp = "";
+ if (additionalURL) {
+ var tmpAnchor = additionalURL.split("#");
+ var TheParams = tmpAnchor[0];
+ TheAnchor = tmpAnchor[1];
+ if(TheAnchor)
+ additionalURL = TheParams;
+ tempArray = additionalURL.split("&");
+ for (i=0; i<tempArray.length; i++) {
+ if(tempArray[i].split('=')[0] != param) {
+ newAdditionalURL += temp + tempArray[i];
+ temp = "&";
+ }
+ }
+ } else {
+ var tmpAnchor = baseURL.split("#");
+ var TheParams = tmpAnchor[0];
+ TheAnchor = tmpAnchor[1];
+ if(TheParams)
+ baseURL = TheParams;
+ }
+ if(TheAnchor)
+ paramVal += "#" + TheAnchor;
+ var rows_txt = temp + "" + param + "=" + paramVal;
+ return baseURL + "?" + newAdditionalURL + rows_txt;
+}
+
+var container = win.getContainer();
+container.find('.update').on('click', function() {
+ var url = updateURLParameter(window.location.href, "update", "1");
+ window.location.href = url;
+});
+
+if($.cookie(cookie_prefix+'pos')) {
+ var pos = $.cookie(cookie_prefix+'pos').split(';');
+ container.css("left", pos[0]);
+ container.css("top", pos[1]);
+}
+if($.cookie(cookie_prefix+'minimized'))
+ win.minimize();
+
+</script>
+HTML_END;
+ return $html;
}
}