added basic functions to GITManagedWebpage.class.php
authorpk910 <philipp@zoelle1.de>
Sat, 5 Oct 2013 23:12:28 +0000 (01:12 +0200)
committerpk910 <philipp@zoelle1.de>
Sat, 5 Oct 2013 23:12:28 +0000 (01:12 +0200)
GITManagedWebpage.class.php

index 9093b8a4e2c0795848076be94474529ae703db01..305530b1ba1195254bd2cd8c266a25ec3ce5ccfe 100644 (file)
 
 class GITManagedWebpage {
     const ERROR_CRITICAL = 1;
 
 class GITManagedWebpage {
     const ERROR_CRITICAL = 1;
-    
+    const SESSION_PREFIX = "GITManagedWebpage_";
 
     private $giturl;
 
     private $giturl;
-    private $workdir;
+    private $workdir, $localdir;
+    private $ready = false;
+    private $loopedcall = false;
+    private $config = null;
+    private $config_changed = true;
     
     
-    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($workdir === null) {
             $workdir = dirname(__FILE__);
-            if(!substr($workdir, -1) == "/")
+            if(substr($workdir, -1) != "/")
                 $workdir .= "/";
             $workdir .= ".gitmanaged/";
         }
                 $workdir .= "/";
             $workdir .= ".gitmanaged/";
         }
-        else if(!substr($workdir, -1) == "/")
+        else if(substr($workdir, -1) != "/")
             $workdir .= "/";
         
             $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->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();
             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(...)
     }
     
     /* private function gitcmd(...)
@@ -66,11 +89,48 @@ class GITManagedWebpage {
             } else
                 $argstr .= " ".escapeshellarg($arg);
         }
             } else
                 $argstr .= " ".escapeshellarg($arg);
         }
-        $gitcmd = 'git '.escapeshellarg('--git-dir='.$this->workdir.'/repository').$argstr;
+        $gitcmd = 'git '.escapeshellarg('--git-dir='.$this->workdir.'repository/.git').$argstr;
         $output = shell_exec($gitcmd);
         return $output;
     }
     
         $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 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);
+            } 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
     */
     /* private function setupWorkdir()
     * Setup local GITManagedWebpage Work directory with git repository
     */
@@ -83,24 +143,172 @@ class GITManagedWebpage {
         }
         
         mkdir($this->workdir);
         }
         
         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)) {
         $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;
         }
             rmdir($this->workdir);
             $this->error(self::ERROR_CRITICAL, "error cloning git repository.");
             return;
         }
+        $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_'.$branch.'/';
+        if(file_exists($dir))
+            return $dir;
+        else if($create) {
+            mkdir($dir);
+            return $dir;
+        } else 
+            return false;
+    }
+    
+    private function updateBranch($branch, $path) {
+        if(substr($path, -1) != '/')
+            $path .= '/';
+        $current_branch = str_replace(array("\r", "\n"), array("", ""), $this->gitcmd("rev-parse", "--abbrev-ref", "HEAD"));
+        if($current_branch != $branch)
+            $this->gitcmd("checkout", $branch);
+        $this->gitcmd("pull");
+        $gitret = $this->gitcmd("rev-list", "--max-count=1", $branch);
+        preg_match("#([a-z0-9]{40})#", $gitret, $match);
+        $newest_version = $match[1];
+        
+        if(($current_version = $this->getConfig('version_'.$branch))) {
+            if($current_version == $newest_version)
+                return;
+            else {
+                //applying patch
+                $difftxt = $this->gitcmd("diff", $current_version, $newest_version);
+                echo $difftxt;
+            }
+        } 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));
+        }
+        $this->setConfig('version_'.$branch, $newest_version);
+        //$this->saveConfig();
     }
     
     /* public function update()
     }
     
     /* 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() {
     */
     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))
+            return false;
+        $this->setActiveBranch($branch, $remember);
+        
+        if(!$this->localBranchPath($branch)) {
+            $dir = $this->localBranchPath($branch, true);
+            $this->updateBranch($branch, $dir);
+        }
+    }
     
     
+    public function execute($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($branch))) {
+                $dir = $this->localBranchPath($active_branch, true);
+                $this->updateBranch($active_branch, $dir);
+            }
+            include_once($dir.$file);
+        } else {
+            include_once($this->localdir.$file);
+        }
     }
     
 }
     }
     
 }