1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29:
30: class Horde_Vfs_Musql extends Horde_Vfs_Sql
31: {
32:
33: const FLAG_READ = 1;
34:
35:
36: const FLAG_WRITE = 2;
37:
38: 39: 40: 41: 42:
43: protected $_permissions = array(
44: 'owner' => array(
45: 'read' => false,
46: 'write' => false,
47: 'execute' => false
48: ),
49: 'group' => array(
50: 'read' => false,
51: 'write' => false,
52: 'execute' => false
53: ),
54: 'all' => array(
55: 'read' => true,
56: 'write' => true,
57: 'execute' => false
58: )
59: );
60:
61: 62: 63: 64: 65: 66: 67: 68: 69: 70:
71: public function writeData($path, $name, $data, $autocreate = false)
72: {
73:
74: if ($path != '') {
75: $paths = explode('/', $path);
76: $path_name = array_pop($paths);
77: if (!$this->isFolder(implode('/', $paths), $path_name)) {
78: if (!$autocreate) {
79: throw new Horde_Vfs_Exception(sprintf('Folder "%s" does not exist'), $path);
80: } else {
81: $this->autocreatePath($path);
82: }
83: }
84: $paths[] = $path_name;
85: $previous = '';
86:
87: foreach ($paths as $thispath) {
88: $sql = sprintf('SELECT vfs_owner, vfs_perms FROM %s
89: WHERE vfs_path = ? AND vfs_name= ?',
90: $this->_params['table']);
91: try {
92: $results = $this->_db->selectAll($sql, array($previous, $thispath));
93: } catch (Horde_Db_Exception $e) {
94: throw new Horde_Vfs_Exception($e);
95: }
96: if (!is_array($results) || count($results) < 1) {
97: throw new Horde_Vfs_Exception('Unable to create VFS file.');
98: }
99:
100: $allowed = false;
101: foreach ($results as $result) {
102: if ($result['vfs_owner'] == $this->_params['user'] ||
103: $result['vfs_perm'] & self::FLAG_WRITE) {
104: $allowed = true;
105: break;
106: }
107: }
108:
109: if (!$allowed) {
110: throw new Horde_Vfs_Exception('Access denied creating VFS file.');
111: }
112:
113: $previous = $thispath;
114: }
115: }
116:
117: return parent::writeData($path, $name, $data, $autocreate);
118: }
119:
120: 121: 122: 123: 124: 125: 126: 127:
128: public function deleteFile($path, $name)
129: {
130: $sql = sprintf('SELECT vfs_id, vfs_owner, vfs_perms FROM %s
131: WHERE vfs_path = ? AND vfs_name= ? AND vfs_type = ?',
132: $this->_params['table']);
133: try {
134: $fileList = $this->_db->selectAll($sql, array($path, $name, self::FILE));
135: } catch (Horde_Db_Exception $e) {
136: throw new Horde_Vfs_Exception($e);
137: }
138: if (!is_array($fileList) || count($fileList) < 1) {
139: throw new Horde_Vfs_Exception('Unable to delete VFS file.');
140: }
141:
142: 143: 144:
145: foreach ($fileList as $file) {
146: if ($file['vfs_owner'] == $this->_params['user'] ||
147: $file['vfs_perms'] & self::FLAG_WRITE) {
148: $sql = sprintf('DELETE FROM %s WHERE vfs_id = ?',
149: $this->_params['table']);
150: try {
151: $result = $this->_db->delete($sql, array($file['vfs_id']));
152: } catch (Horde_Db_Exception $e) {
153: throw new Horde_Vfs_Exception($e);
154: }
155: if ($result == 0) {
156: throw new Horde_Vfs_Exception('Unable to delete VFS file.');
157: }
158: return $result;
159: }
160: }
161:
162:
163: throw new Horde_Vfs_Exception('Unable to delete VFS file.');
164: }
165:
166: 167: 168: 169: 170: 171: 172: 173: 174: 175:
176: public function rename($oldpath, $oldname, $newpath, $newname)
177: {
178: $sql = sprintf('SELECT vfs_id, vfs_owner, vfs_perms FROM %s
179: WHERE vfs_path = ? AND vfs_name= ?',
180: $this->_params['table']);
181: try {
182: $fileList = $this->_db->selectAll($sql, array($oldpath, $oldname));
183:
184: } catch (Horde_Db_Exception $e) {
185: throw new Horde_Vfs_Exception($e);
186: }
187: if (!is_array($fileList) || count($fileList) < 1) {
188: throw new Horde_Vfs_Exception('Unable to rename VFS file.');
189: }
190:
191: if (strpos($newpath, '/') === false) {
192: $parent = '';
193: $path = $newpath;
194: } else {
195: list($parent, $path) = explode('/', $newpath, 2);
196: }
197: if (!$this->isFolder($parent, $path)) {
198: $this->autocreatePath($newpath);
199: }
200:
201: 202: 203:
204: foreach ($fileList as $file) {
205: if ($file['vfs_owner'] == $this->_params['user'] ||
206: $file['vfs_perms'] & self::FLAG_WRITE) {
207: $sql = sprintf('UPDATE %s SET vfs_path = ?, vfs_name = ?, vfs_modified = ?
208: WHERE vfs_id = ?',
209: $this->_params['table']);
210: try {
211: $this->_db->update(
212: $sql,
213: array($newpath, $newname, time(), $file['vfs_id']));
214: } catch (Horde_Db_Exception $e) {
215: throw new Horde_Vfs_Exception($e);
216: }
217: }
218: }
219:
220: throw new Horde_Vfs_Exception(sprintf('Unable to rename VFS file %s/%s.', $oldpath, $oldname));
221: }
222:
223: 224: 225: 226: 227: 228: 229: 230:
231: public function createFolder($path, $name)
232: {
233:
234: if (strlen($path)) {
235: $paths = explode('/', $path);
236: $previous = '';
237:
238: foreach ($paths as $thispath) {
239: $sql = sprintf('SELECT vfs_owner, vfs_perms FROM %s
240: WHERE vfs_path = ? AND vfs_name= ?',
241: $this->_params['table']);
242: try {
243: $results = $this->_db->selectAll($sql, array($previous, $thispath));
244: } catch (Horde_Db_Exception $e) {
245: throw new Horde_Vfs_Exception($e);
246: }
247: if (!is_array($results) || count($results) < 1) {
248: throw new Horde_Vfs_Exception('Unable to create VFS directory.');
249: }
250:
251: $allowed = false;
252: foreach ($results as $result) {
253: if ($result['vfs_owner'] == $this->_params['user'] ||
254: $result['vfs_perms'] & self::FLAG_WRITE) {
255: $allowed = true;
256: break;
257: }
258: }
259:
260: if (!$allowed) {
261: throw new Horde_Vfs_Exception('Access denied creating VFS directory.');
262: }
263:
264: $previous = $thispath;
265: }
266: }
267:
268: $sql = sprintf('INSERT INTO %s
269: (vfs_type, vfs_path, vfs_name, vfs_modified, vfs_owner, vfs_perms)
270: VALUES (?, ?, ?, ?, ?, ?)',
271: $this->_params['table']);
272: try {
273: $this->_db->insert(
274: $sql,
275: array(self::FOLDER, $path, $name, time(), $this->_params['user'], 0));
276: } catch (Horde_Db_Exception $e) {
277: throw new Horde_Vfs_Exception($e);
278: }
279: }
280:
281: 282: 283: 284: 285: 286: 287: 288: 289:
290: public function deleteFolder($path, $name, $recursive = false)
291: {
292: if ($recursive) {
293: $this->emptyFolder($path . '/' . $name);
294: } else {
295: $list = $this->listFolder($path . '/' . $name);
296: if (count($list)) {
297: throw new Horde_Vfs_Exception(sprintf('Unable to delete %s, the directory is not empty', $path . '/' . $name));
298: }
299: }
300:
301: $sql = sprintf('SELECT vfs_id, vfs_owner, vfs_perms FROM %s
302: WHERE vfs_path = ? AND vfs_name= ? AND vfs_type = ?',
303: $this->_params['table']);
304: try {
305: $fileList = $this->_db->selectAll($sql, array($path, $name, self::FOLDER));
306: } catch (Horde_Db_Exception $e) {
307: throw new Horde_Vfs_Exception($e);
308: }
309: if (!is_array($fileList) || count($fileList) < 1) {
310: throw new Horde_Vfs_Exception('Unable to delete VFS directory.');
311: }
312:
313: 314: 315:
316: foreach ($fileList as $file) {
317: if ($file['vfs_owner'] == $this->_params['user'] ||
318: $file['vfs_perms'] & self::FLAG_WRITE) {
319: $sql = sprintf('DELETE FROM %s WHERE vfs_id = ?',
320: $this->_params['table']);
321: try {
322: $result = $this->_db->delete($sql, array($file['vfs_id']));
323: } catch (Horde_Db_Exception $e) {
324: throw new Horde_Vfs_Exception($e);
325: }
326: if ($result == 0) {
327: throw new Horde_Vfs_Exception('Unable to delete VFS directory.');
328: }
329:
330: return $result;
331: }
332: }
333:
334:
335: throw new Horde_Vfs_Exception('Unable to delete VFS directory.');
336: }
337:
338: 339: 340: 341: 342: 343: 344: 345: 346: 347: 348:
349: protected function _listFolder($path, $filter = null, $dotfiles = true,
350: $dironly = false)
351: {
352: $length_op = $this->_getFileSizeOp();
353: $sql = sprintf('SELECT vfs_name, vfs_type, vfs_modified, vfs_owner, vfs_perms, %s(vfs_data) length FROM %s
354: WHERE vfs_path = ? AND (vfs_owner = ? OR vfs_perms \&\& ?)',
355: $length_op, $this->_params['table']);
356: try {
357: $fileList = $this->_db->selectAll(
358: $sql,
359: array($path, $this->_params['user'], self::FLAG_READ));
360: } catch (Horde_Db_Exception $e) {
361: throw new Horde_Vfs_Exception($e);
362: }
363:
364: $files = array();
365: foreach ($fileList as $line) {
366:
367: if (!$dotfiles && substr($line['vfs_name'], 0, 1) == '.') {
368: continue;
369: }
370:
371: $file['name'] = stripslashes($line['vfs_name']);
372:
373: if ($line['vfs_type'] == self::FILE) {
374: $name = explode('.', $line['vfs_name']);
375:
376: if (count($name) == 1) {
377: $file['type'] = '**none';
378: } else {
379: $file['type'] = Horde_String::lower($name[count($name) - 1]);
380: }
381:
382: $file['size'] = $line['length'];
383: } elseif ($line['vfs_type'] == self::FOLDER) {
384: $file['type'] = '**dir';
385: $file['size'] = -1;
386: }
387:
388: $file['date'] = $line['vfs_modified'];
389: $file['owner'] = $line['vfs_owner'];
390:
391: $line['vfs_perms'] = intval($line['vfs_perms']);
392: $file['perms'] = ($line['vfs_type'] == self::FOLDER) ? 'd' : '-';
393: $file['perms'] .= 'rw-';
394: $file['perms'] .= ($line['vfs_perms'] & self::FLAG_READ) ? 'r' : '-';
395: $file['perms'] .= ($line['vfs_perms'] & self::FLAG_WRITE) ? 'w' : '-';
396: $file['perms'] .= '-';
397: $file['group'] = '';
398:
399:
400: if ($this->_filterMatch($filter, $file['name'])) {
401: unset($file);
402: continue;
403: }
404: if ($dironly && $file['type'] !== '**dir') {
405: unset($file);
406: continue;
407: }
408:
409: $files[$file['name']] = $file;
410: unset($file);
411: }
412:
413: return $files;
414: }
415:
416: 417: 418: 419: 420: 421: 422: 423: 424:
425: public function changePermissions($path, $name, $permission)
426: {
427: $val = intval(substr($permission, -1));
428: $perm = 0;
429: $perm |= ($val & 4) ? self::FLAG_READ : 0;
430: $perm |= ($val & 2) ? self::FLAG_WRITE : 0;
431:
432: $sql = sprintf('SELECT vfs_id, vfs_owner, vfs_perms FROM %s
433: WHERE vfs_path = ? AND vfs_name= ?',
434: $this->_params['table']);
435: try {
436: $fileList = $this->_db->selectAll($sql, array($path, $name));
437: } catch (Horde_Db_Exception $e) {
438: throw new Horde_Vfs_Exception($e);
439: }
440: if (!is_array($fileList) || count($fileList) < 1) {
441: throw new Horde_Vfs_Exception('Unable to rename VFS file.');
442: }
443:
444: 445: 446:
447: foreach ($fileList as $file) {
448: if ($file['vfs_owner'] == $this->_params['user'] ||
449: $file['vfs_perms'] & self::FLAG_WRITE) {
450: $sql = sprintf('UPDATE %s SET vfs_perms = ?
451: WHERE vfs_id = ?',
452: $this->_params['table']);
453: try {
454: $result = $this->_db->update($sql, array($perm, $file['vfs_id']));
455: } catch (Horde_Db_Exception $e) {
456: throw new Horde_Vfs_Exception($e);
457: }
458: }
459: }
460:
461: throw new Horde_Vfs_Exception(sprintf('Unable to change permission for VFS file %s/%s.', $path, $name));
462: }
463:
464: }
465: