merge paste creation and paste edit code
authorChristian Weiske <cweiske@cweiske.de>
Thu, 29 Mar 2012 21:17:34 +0000 (23:17 +0200)
committerChristian Weiske <cweiske@cweiske.de>
Thu, 29 Mar 2012 21:17:34 +0000 (23:17 +0200)
src/Phorkie/Repository.php
src/Phorkie/Repository/Post.php [new file with mode: 0644]
www/edit.php
www/index.php

index 5273b60..d9fc234 100644 (file)
@@ -76,7 +76,7 @@ class Repository
         return $arFiles;
     }
 
-    public function getFileByName($name)
+    public function getFileByName($name, $bHasToExist = true)
     {
         $base = basename($name);
         if ($base != $name) {
@@ -86,7 +86,7 @@ class Repository
             throw new Exception_Input('Empty file name given');
         }
         $path = $this->repoDir . '/' . $base;
-        if (!is_readable($path)) {
+        if ($bHasToExist && !is_readable($path)) {
             throw new Exception_Input('File does not exist');
         }
         return new File($path, $this);
diff --git a/src/Phorkie/Repository/Post.php b/src/Phorkie/Repository/Post.php
new file mode 100644 (file)
index 0000000..632f321
--- /dev/null
@@ -0,0 +1,125 @@
+<?php
+namespace Phorkie;
+
+class Repository_Post
+{
+    public $repo;
+
+    public function __construct(Repository $repo = null)
+    {
+        $this->repo = $repo;
+    }
+
+    /**
+     * Processes the POST data, changes description and files
+     *
+     * @return boolean True if the post was successful
+     */
+    public function process($postData)
+    {
+        if (!isset($postData['files'])) {
+            return false;
+        }
+
+        if (!$this->repo) {
+            $this->repo = $this->createRepo();
+        }
+
+        $vc = $this->repo->getVc();
+        $this->repo->setDescription($postData['description']);
+
+        $bChanged = false;
+        foreach ($postData['files'] as $num => $arFile) {
+            $orignalName = $this->sanitizeFilename($arFile['original_name']);
+            $name        = $this->sanitizeFilename($arFile['name']);
+
+            if ($name == '') {
+                $name = $this->getNextNumberedFile('phork')
+                    . '.' . $arFile['type'];
+            }
+
+            $bNew = false;
+            if (!isset($orignalName) || $orignalName == '') {
+                //new file
+                $bNew = true;
+            } else if (!$this->repo->hasFile($orignalName)) {
+                //unknown file
+                //FIXME: Show error message
+                continue;
+            } else if ($orignalName != $name) {
+                //FIXME: what to do with overwrites?
+                $vc->getCommand('mv')
+                    ->addArgument($orignalName)
+                    ->addArgument($name)
+                    ->execute();
+                $bChanged = true;
+            }
+
+            $file = $this->repo->getFileByName($name, false);
+            if ($bNew || $file->getContent() != $arFile['content']) {
+                file_put_contents($file->getPath(), $arFile['content']);
+                $command = $vc->getCommand('add')
+                    ->addArgument($file->getFilename())
+                    ->execute();
+                $bChanged = true;
+            }
+        }
+
+        if ($bChanged) {
+            $vc->getCommand('commit')
+                ->setOption('message', '')
+                ->setOption('allow-empty-message')
+                ->setOption('author', 'Anonymous <anonymous@phorkie>')
+                ->execute();
+        }
+
+        return true;
+    }
+
+    public function createRepo()
+    {
+        $rs = new Repositories();
+        $repo = $rs->createNew();
+        $vc = $repo->getVc();
+        $vc->initRepository();
+        foreach (glob($repo->repoDir . '/.git/hooks/*') as $hookfile) {
+            unlink($hookfile);
+        }
+        return $repo;
+    }
+
+    public function getNextNumberedFile($prefix)
+    {
+        $num = -1;
+        do {
+            ++$num;
+            $files = glob($this->repo->repoDir . '/' . $prefix . $num . '.*');
+        } while (count($files));
+
+        return $prefix . $num;
+    }
+
+    /**
+     * Removes malicious parts from a file name
+     *
+     * @param string $file File name from the user
+     *
+     * @return string Fixed and probably secure filename
+     */
+    public function sanitizeFilename($file)
+    {
+        $file = trim($file);
+        $file = str_replace(array('\\', '//'), '/', $file);
+        $file = str_replace('/../', '/', $file);
+        if (substr($file, 0, 3) == '../') {
+            $file = substr($file, 3);
+        }
+        if (substr($file, 0, 1) == '../') {
+            $file = substr($file, 1);
+        }
+
+        return $file;
+    }
+}
+
+?>
index 3bcec6e..9acc1d6 100644 (file)
@@ -8,45 +8,8 @@ require_once 'www-header.php';
 $repo = new Repository();
 $repo->loadFromRequest();
 
-if (isset($_POST['files'])) {
-    $vc = $repo->getVc();
-    $repo->setDescription($_POST['description']);
-
-    $bChanged = false;
-    foreach ($_POST['files'] as $num => $arFile) {
-        if (!isset($arFile['original_name'])
-            || !$repo->hasFile($arFile['original_name'])
-        ) {
-            //FIXME: Show error message
-            continue;
-        }
-        //FIXME: fix file names from .. and ./
-        if ($arFile['original_name'] != $arFile['name']) {
-            //FIXME: what to do with overwrites?
-            $vc->getCommand('mv')
-                ->addArgument($arFile['original_name'])
-                ->addArgument($arFile['name'])
-                ->execute();
-            $bChanged = true;
-        }
-        $file = $repo->getFileByName($arFile['name']);
-        if ($file->getContent() != $arFile['content']) {
-            file_put_contents($file->getPath(), $arFile['content']);
-            $command = $vc->getCommand('add')
-                ->addArgument($file->getFilename())
-                ->execute();
-            $bChanged = true;
-        }
-    }
-
-    if ($bChanged) {
-        $vc->getCommand('commit')
-            ->setOption('message', '')
-            ->setOption('allow-empty-message')
-            ->setOption('author', 'Anonymous <anonymous@phorkie>')
-            ->execute();
-    }
-
+$repopo = new Repository_Post($repo);
+if ($repopo->process($_POST)) {
     redirect($repo->getLink('display'));
 }
 
index db3fd7b..d33604d 100644 (file)
@@ -12,37 +12,9 @@ namespace Phorkie;
  */
 require_once 'www-header.php';
 
-if (isset($_POST['files'])) {
-    //save
-    $rs = new Repositories();
-    $repo = $rs->createNew();
-    $vc = $repo->getVc();
-    $vc->initRepository();
-    foreach (glob($repo->repoDir . '/.git/hooks/*') as $hookfile) {
-        unlink($hookfile);
-    }
-    $repo->setDescription($_POST['description']);
-
-    foreach ($_POST['files'] as $num => $arFile) {
-        if ($arFile['name'] != '') {
-            //FIXME: fix file name from ..
-            $fname = $arFile['name'];
-        } else {
-            $fname = 'phork' . $num . '.' . $arFile['type'];
-        }
-        $fpath = $repo->repoDir . $fname;
-        file_put_contents($fpath, $arFile['content']);
-        //fixme: let the class do that when it is able to
-        $command = $vc->getCommand('add')
-            ->addArgument($fname)
-            ->execute();
-    }
-    $command = $vc->getCommand('commit')
-        ->setOption('message', 'initial paste')
-        ->setOption('author', 'Anonymous <anonymous@phorkie>')
-        ->execute();
-    //redirect to phork
-    redirect($repo->getLink('display'));
+$repopo = new Repository_Post();
+if ($repopo->process($_POST)) {
+    redirect($repopo->repo->getLink('display'));
 }
 
 $phork = array(