do not add files that are empty and have no name
[phorkie.git] / src / Phorkie / Repository / Post.php
1 <?php
2 namespace Phorkie;
3
4 class Repository_Post
5 {
6     public $repo;
7
8     public function __construct(Repository $repo = null)
9     {
10         $this->repo = $repo;
11     }
12
13     /**
14      * Processes the POST data, changes description and files
15      *
16      * @return boolean True if the post was successful
17      */
18     public function process($postData)
19     {
20         if (!isset($postData['files'])) {
21             return false;
22         }
23
24         if (!$this->repo) {
25             $this->repo = $this->createRepo();
26         }
27
28         $vc = $this->repo->getVc();
29         $this->repo->setDescription($postData['description']);
30
31         $bChanged = false;
32         foreach ($postData['files'] as $arFile) {
33             if ($arFile['content'] == '' && $arFile['name'] == '') {
34                 //empty (new) file
35                 continue;
36             }
37
38             $orignalName = $this->sanitizeFilename($arFile['original_name']);
39             $name        = $this->sanitizeFilename($arFile['name']);
40
41             if ($name == '') {
42                 $name = $this->getNextNumberedFile('phork')
43                     . '.' . $arFile['type'];
44             }
45
46             $bNew = false;
47             if (!isset($orignalName) || $orignalName == '') {
48                 //new file
49                 $bNew = true;
50             } else if (!$this->repo->hasFile($orignalName)) {
51                 //unknown file
52                 //FIXME: Show error message
53                 continue;
54             } else if ($orignalName != $name) {
55                 //FIXME: what to do with overwrites?
56                 $vc->getCommand('mv')
57                     ->addArgument($orignalName)
58                     ->addArgument($name)
59                     ->execute();
60                 $bChanged = true;
61             }
62
63             $file = $this->repo->getFileByName($name, false);
64             if ($bNew || $file->getContent() != $arFile['content']) {
65                 file_put_contents($file->getPath(), $arFile['content']);
66                 $command = $vc->getCommand('add')
67                     ->addArgument($file->getFilename())
68                     ->execute();
69                 $bChanged = true;
70             }
71         }
72
73         if ($bChanged) {
74             $vc->getCommand('commit')
75                 ->setOption('message', '')
76                 ->setOption('allow-empty-message')
77                 ->setOption('author', 'Anonymous <anonymous@phorkie>')
78                 ->execute();
79         }
80
81         return true;
82     }
83
84     public function createRepo()
85     {
86         $rs = new Repositories();
87         $repo = $rs->createNew();
88         $vc = $repo->getVc();
89         $vc->initRepository();
90         foreach (glob($repo->repoDir . '/.git/hooks/*') as $hookfile) {
91             unlink($hookfile);
92         }
93         return $repo;
94     }
95
96     public function getNextNumberedFile($prefix)
97     {
98         $num = -1;
99         do {
100             ++$num;
101             $files = glob($this->repo->repoDir . '/' . $prefix . $num . '.*');
102         } while (count($files));
103
104         return $prefix . $num;
105     }
106
107     /**
108      * Removes malicious parts from a file name
109      *
110      * @param string $file File name from the user
111      *
112      * @return string Fixed and probably secure filename
113      */
114     public function sanitizeFilename($file)
115     {
116         $file = trim($file);
117         $file = str_replace(array('\\', '//'), '/', $file);
118         $file = str_replace('/../', '/', $file);
119         if (substr($file, 0, 3) == '../') {
120             $file = substr($file, 3);
121         }
122         if (substr($file, 0, 1) == '../') {
123             $file = substr($file, 1);
124         }
125
126         return $file;
127     }
128 }
129
130 ?>