Single file editing
[phorkie.git] / src / phorkie / Repository.php
index ed07fb50a771eb0db00e6d96a8829108601d3042..467456b96821e81cd919927c734f098e2212bdb0 100644 (file)
@@ -65,6 +65,16 @@ class Repository
         $this->loadMessage();
     }
 
+    public function loadById($id)
+    {
+        if (!is_numeric($id)) {
+            throw new Exception_Input('Paste ID not numeric');
+        }
+        $this->id = (int)$id;
+        $this->loadDirs();
+        $this->loadHash();
+    }
+
     protected function loadDirs()
     {
         $gitDir = $GLOBALS['phorkie']['cfg']['gitdir'] . '/' . $this->id . '.git';
@@ -104,7 +114,7 @@ class Repository
         $this->hash = $output;
     }
 
-       /**
+    /**
      * Populates $this->message
      *
      * @return void
@@ -126,16 +136,6 @@ class Repository
         }
     }
 
-    public function loadById($id)
-    {
-        if (!is_numeric($id)) {
-            throw new Exception_Input('Paste ID not numeric');
-        }
-        $this->id = (int)$id;
-        $this->loadDirs();
-        $this->loadHash();
-    }
-
     public function getVc()
     {
         return new \VersionControl_Git($this->gitDir);
@@ -144,7 +144,7 @@ class Repository
     /**
      * Loads the list of files in this repository
      *
-     * @return File[] Array of files
+     * @return File[] Array of file objects
      */
     public function getFiles()
     {
@@ -156,6 +156,41 @@ class Repository
         return $arFiles;
     }
 
+    /**
+     * Decodes unicode characters in git filenames
+     * They begin and end with double quote characters, and may contain
+     * backslash + 3 letter octal code numbers representing the character.
+     *
+     * For example,
+     * > "t\303\244st.txt"
+     * means
+     * > täst.txt
+     *
+     * On the shell, you can pipe them into "printf" and have them decoded.
+     *
+     * @param string Encoded git file name
+     *
+     * @return string Decoded file name
+     */
+    protected function decodeFileName($name)
+    {
+        $name = substr($name, 1, -1);
+        $name = str_replace('\"', '"', $name);
+        $name = preg_replace_callback(
+            '#\\\\[0-7]{3}#',
+            function ($ar) {
+                return chr(octdec(substr($ar[0], 1)));
+            },
+            $name
+        );
+        return $name;
+    }
+
+    /**
+     * Return array with all file paths in this repository
+     *
+     * @return array
+     */
     protected function getFilePaths()
     {
         if ($this->hash === null) {
@@ -168,7 +203,13 @@ class Repository
             ->setOption('name-only')
             ->addArgument($hash)
             ->execute();
-        return explode("\n", trim($output));
+        $files = explode("\n", trim($output));
+        foreach ($files as &$file) {
+            if ($file{0} == '"') {
+                $file = $this->decodeFileName($file);
+            }
+        }
+        return $files;
     }
 
     public function getFileByName($name, $bHasToExist = true)
@@ -208,8 +249,13 @@ class Repository
         $db = new Database();
         $db->getIndexer()->deleteRepo($this);
 
-        return Tools::recursiveDelete($this->workDir)
+        $bOk = Tools::recursiveDelete($this->workDir)
             && Tools::recursiveDelete($this->gitDir);
+
+        $not = new Notificator();
+        $not->delete($this);
+
+        return $bOk;
     }
 
     public function getTitle()
@@ -235,38 +281,73 @@ class Repository
         file_put_contents($this->gitDir . '/description', $description);
     }
 
+    /**
+     * @return array Array with keys "email" and "name"
+     */
+    public function getOwner()
+    {
+        try {
+            $name = $this->getVc()->getCommand('config')
+                ->addArgument('owner.name')->execute();
+        } catch (\VersionControl_Git_Exception $e) {
+            $name = $GLOBALS['phorkie']['auth']['anonymousName'];
+        }
+        try {
+            $email = $this->getVc()->getCommand('config')
+                ->addArgument('owner.email')->execute();
+        } catch (\VersionControl_Git_Exception $e) {
+            $email = $GLOBALS['phorkie']['auth']['anonymousEmail'];
+        }
+
+        return array('name' => trim($name), 'email' => trim($email));
+    }
+
     /**
      * Get a link to the repository
      *
-     * @param string $type Link type. Supported are:
-     *                     - "edit"
-     *                     - "delete"
-     *                     - "delete-confirm"
-     *                     - "display"
-     *                     - "fork"
-     *                     - "revision"
-     * @param string $option
+     * @param string  $type   Link type. Supported are:
+     *                        - "edit"
+     *                        - "delete"
+     *                        - "delete-confirm"
+     *                        - "display"
+     *                        - "fork"
+     *                        - "revision"
+     * @param string  $option Additional link option, e.g. revision number
+     * @param boolean $full   Return full URL or normal relative
      *
      * @return string
      */
-    public function getLink($type, $option = null)
+    public function getLink($type, $option = null, $full = false)
     {
         if ($type == 'edit') {
-            return '/' . $this->id . '/edit';
+            $link = $this->id . '/edit';
+            if ($option !== null) {
+                $link .= '/' . urlencode($option);
+            }
         } else if ($type == 'display') {
-            return '/' . $this->id;
+            $link = $this->id;
         } else if ($type == 'fork') {
-            return '/' . $this->id . '/fork';
+            $link = $this->id . '/fork';
         } else if ($type == 'doap') {
-            return '/' . $this->id . '/doap';
+            $link = $this->id . '/doap';
         } else if ($type == 'delete') {
-            return '/' . $this->id . '/delete';
+            $link = $this->id . '/delete';
         } else if ($type == 'delete-confirm') {
-            return '/' . $this->id . '/delete/confirm';
+            $link = $this->id . '/delete/confirm';
+        } else if ($type == 'remotefork') {
+            return 'web+fork:' . $this->getLink('display', null, true);
         } else if ($type == 'revision') {
-            return '/' . $this->id . '/rev/' . $option;
+            $link = $this->id . '/rev/' . $option;
+        } else if ($type == 'linkback') {
+            $link = $this->id . '/linkback';
+        } else {
+            throw new Exception('Unknown link type');
         }
-        throw new Exception('Unknown link type');
+
+        if ($full) {
+            $link = Tools::fullUrl($link);
+        }
+        return $link;
     }
 
     public function getCloneURL($public = true)
@@ -331,6 +412,14 @@ class Repository
 
         return $arCommits;
     }
+
+    /**
+     * @return Repository_ConnectionInfo
+     */
+    public function getConnectionInfo()
+    {
+        return new Repository_ConnectionInfo($this);
+    }
 }
 
 ?>