1 <?php
2
3 4 5 6 7 8 9 10
11
12 namespace Icybee\Modules\Files;
13
14 use ICanBoogie\Exception;
15 use ICanBoogie\Uploaded;
16
17 class Model extends \Icybee\Modules\Nodes\Model
18 {
19 const ACCEPT = '#files-accept';
20 const UPLOADED = '#files-uploaded';
21
22 public function save(array $properties, $key=null, array $options=array())
23 {
24
25
26
27
28
29
30 $delete = null;
31
32
33
34
35
36
37
38
39
40 $previous_title = null;
41 $previous_path = null;
42
43
44
45
46
47
48 if ($key)
49 {
50
51
52
53
54 $previous = $this->select('title, path, mime')->filter_by_nid($key)->one;
55
56
57
58
59
60 extract($previous, EXTR_PREFIX_ALL, 'previous');
61
62 $properties[File::MIME] = $previous_mime;
63 }
64
65 if (isset($properties[File::HTTP_FILE]))
66 {
67
68
69 $file = $properties[File::HTTP_FILE];
70
71 $delete = $previous_path;
72 $path = \ICanBoogie\strip_root($file->pathname);
73 $previous_path = $path;
74 $previous_title = null;
75
76 $properties[File::MIME] = $file->type;
77 $properties[File::SIZE] = $file->size;
78
79 if (empty($properties[File::TITLE]))
80 {
81 $properties[File::TITLE] = $file->unsuffixed_name;
82 }
83
84 $properties[File::PATH] = $path;
85 }
86
87 $title = null;
88
89 if (isset($properties[File::TITLE]))
90 {
91 $title = $properties[File::TITLE];
92 }
93
94 $mime = $properties[File::MIME];
95
96
97
98
99
100 $path = self::make_path($key, $title, $previous_path, $mime);
101
102 $root = \ICanBoogie\DOCUMENT_ROOT;
103 $parent = dirname($path);
104
105 if (!is_dir($root . $parent))
106 {
107 mkdir($root . $parent, 0705, true);
108 }
109
110 $key = parent::save($properties, $key, $options);
111
112 if (!$key)
113 {
114 return $key;
115 }
116
117
118
119
120
121 if (($path != $previous_path) || (!$previous_title || ($previous_title != $title)))
122 {
123 $path = self::make_path($key, $title, $previous_path, $mime);
124
125 if ($delete && is_file($root . $delete))
126 {
127 unlink($root . $delete);
128 }
129
130 $ok = rename($root . $previous_path, $root . $path);
131
132 if (!$ok)
133 {
134 throw new \Exception(\ICanBoogie\format('Unable to rename %previous to %path', [
135
136 'previous' => $previous_path,
137 'path' => $path
138
139 ]));
140 }
141
142 $this->update([ File::PATH => $path ], $key);
143 }
144
145 return $key;
146 }
147
148 public function delete($key)
149 {
150 $path = $this->select('path')->filter_by_nid($key)->rc;
151
152 $rc = parent::delete($key);
153
154 if ($rc && $path)
155 {
156 $root = \ICanBoogie\DOCUMENT_ROOT;
157
158 if (is_file($root . $path))
159 {
160 unlink($root . $path);
161 }
162 }
163
164 return $rc;
165 }
166
167 static protected function make_path($key, $title, $path, $mime)
168 {
169 $base = dirname($mime);
170
171 if ($base == 'application')
172 {
173 $base = basename($mime);
174 }
175
176 if (!in_array($base, [ 'image', 'audio', 'pdf', 'zip' ]))
177 {
178 $base = 'bin';
179 }
180
181 $rc = \ICanBoogie\strip_root(\ICanBoogie\REPOSITORY . 'files')
182 . '/' . $base . '/' . ($key ?: uniqid()) . '-' . \ICanBoogie\normalize($title);
183
184
185
186
187
188 $extension = pathinfo($path, PATHINFO_EXTENSION) ?: 'file';
189
190 return $rc . '.' . $extension;
191 }
192 }