Overview

Packages

  • Vfs

Classes

  • Horde_Vfs
  • Horde_Vfs_Base
  • Horde_Vfs_Browser
  • Horde_Vfs_Exception
  • Horde_Vfs_File
  • Horde_Vfs_Ftp
  • Horde_Vfs_Gc
  • Horde_Vfs_Horde
  • Horde_Vfs_Kolab
  • Horde_Vfs_ListItem
  • Horde_Vfs_Musql
  • Horde_Vfs_Object
  • Horde_Vfs_Smb
  • Horde_Vfs_Sql
  • Horde_Vfs_SqlFile
  • Horde_Vfs_Ssh2
  • Horde_Vfs_Translation
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * Horde_Vfs:: implementation using PHP's PEAR database abstraction
  4:  * layer and local file system for file storage.
  5:  *
  6:  * Required values for $params:<pre>
  7:  * db - (DB) The DB object.
  8:  * vfsroot - (string) The root directory of where the files should be
  9:  *           actually stored.</pre>
 10:  *
 11:  * Optional values:<pre>
 12:  * table - (string) The name of the vfs table in 'database'. Defaults to
 13:  *         'horde_vfs'.</pre>
 14:  *
 15:  * The table structure for the VFS can be found in data/vfs.sql.
 16:  *
 17:  * @author   Michael Varghese <mike.varghese@ascellatech.com>
 18:  * @category Horde
 19:  * @package  VFS
 20:  */
 21: class Horde_Vfs_SqlFile extends Horde_Vfs_File
 22: {
 23:     /* File value for vfs_type column. */
 24:     const FILE = 1;
 25: 
 26:     /* Folder value for vfs_type column. */
 27:     const FOLDER = 2;
 28: 
 29:     /**
 30:      * Handle for the current database connection.
 31:      *
 32:      * @var DB
 33:      */
 34:     protected $_db = false;
 35: 
 36:     /**
 37:      * Constructor.
 38:      *
 39:      * @param array $params  A hash containing connection parameters.
 40:      */
 41:     public function __construct($params = array())
 42:     {
 43:         throw new Horde_Vfs_Exception('The SqlFile VFS driver needs to be refactored to a real composite driver.');
 44:     }
 45: 
 46:     /**
 47:      * Store a file in the VFS, with the data copied from a temporary
 48:      * file.
 49:      *
 50:      * @param string $path         The path to store the file in.
 51:      * @param string $name         The filename to use.
 52:      * @param string $tmpFile      The temporary file containing the data to be
 53:      *                             stored.
 54:      * @param boolean $autocreate  Automatically create directories?
 55:      *
 56:      * @throws Horde_Vfs_Exception
 57:      */
 58:     public function write($path, $name, $tmpFile, $autocreate = false)
 59:     {
 60:         /* No need to check quota here as we will check it when we call
 61:          * writeData(). */
 62:         $data = file_get_contents($tmpFile);
 63:         return $this->writeData($path, $name, $data, $autocreate);
 64:     }
 65: 
 66:     /**
 67:      * Store a file in the VFS from raw data.
 68:      *
 69:      * @param string $path         The path to store the file in.
 70:      * @param string $name         The filename to use.
 71:      * @param string $data         The file data.
 72:      * @param boolean $autocreate  Automatically create directories?
 73:      *
 74:      * @throws Horde_Vfs_Exception
 75:      */
 76:     public function writeData($path, $name, $data, $autocreate = false)
 77:     {
 78:         $this->_checkQuotaWrite('string', $data);
 79: 
 80:         $fp = @fopen($this->_getNativePath($path, $name), 'w');
 81:         if (!$fp) {
 82:             if ($autocreate) {
 83:                 $this->autocreatePath($path);
 84:                 $fp = @fopen($this->_getNativePath($path, $name), 'w');
 85:                 if (!$fp) {
 86:                     throw new Horde_Vfs_Exception('Unable to open VFS file for writing.');
 87:                 }
 88:             } else {
 89:                 throw new Horde_Vfs_Exception('Unable to open VFS file for writing.');
 90:             }
 91:         }
 92: 
 93:         if (!@fwrite($fp, $data)) {
 94:             throw new Horde_Vfs_Exception('Unable to write VFS file data.');
 95:         }
 96: 
 97:         if ($this->_writeSQLData($path, $name, $autocreate) instanceof PEAR_Error) {
 98:             @unlink($this->_getNativePath($path, $name));
 99:             throw new Horde_Vfs_Exception('Unable to write VFS file data.');
100:         }
101:     }
102: 
103:     /**
104:      * Moves a file in the database and the file system.
105:      *
106:      * @param string $path         The path to store the file in.
107:      * @param string $name         The old filename.
108:      * @param string $dest         The new filename.
109:      * @param boolean $autocreate  Automatically create directories?
110:      *
111:      * @throws Horde_Vfs_Exception
112:      */
113:     public function move($path, $name, $dest, $autocreate = false)
114:     {
115:         $orig = $this->_getNativePath($path, $name);
116:         if (preg_match('|^' . preg_quote($orig) . '/?$|', $dest)) {
117:             throw new Horde_Vfs_Exception('Cannot move file(s) - destination is within source.');
118:         }
119: 
120:         if ($autocreate) {
121:             $this->autocreatePath($dest);
122:         }
123: 
124:         foreach ($this->listFolder($dest, null, false) as $file) {
125:             if ($file['name'] == $name) {
126:                 throw new Horde_Vfs_Exception('Unable to move VFS file.');
127:             }
128:         }
129: 
130:         if (strpos($dest, $this->_getSQLNativePath($path, $name)) !== false) {
131:             throw new Horde_Vfs_Exception('Unable to move VFS file.');
132:         }
133: 
134:         $this->rename($path, $name, $dest, $name);
135:     }
136: 
137:     /**
138:      * Copies a file through the backend.
139:      *
140:      * @param string $path         The path to store the file in.
141:      * @param string $name         The filename to use.
142:      * @param string $dest         The destination of the file.
143:      * @param boolean $autocreate  Automatically create directories?
144:      *
145:      * @throws Horde_Vfs_Exception
146:      */
147:     public function copy($path, $name, $dest, $autocreate = false)
148:     {
149:         $orig = $this->_getNativePath($path, $name);
150:         if (preg_match('|^' . preg_quote($orig) . '/?$|', $dest)) {
151:             throw new Horde_Vfs_Exception('Cannot copy file(s) - source and destination are the same.');
152:         }
153: 
154:         $this->_connect();
155: 
156:         if ($autocreate) {
157:             $this->autocreatePath($dest);
158:         }
159: 
160:         foreach ($this->listFolder($dest, null, false) as $file) {
161:             if ($file['name'] == $name) {
162:                 throw new Horde_Vfs_Exception('Unable to copy VFS file.');
163:             }
164:         }
165: 
166:         if (strpos($dest, $this->_getSQLNativePath($path, $name)) !== false) {
167:             throw new Horde_Vfs_Exception('Unable to copy VFS file.');
168:         }
169: 
170:         if (is_dir($orig)) {
171:             return $this->_recursiveCopy($path, $name, $dest);
172:         }
173: 
174:         $this->_checkQuotaWrite('file', $orig);
175: 
176:         if (!@copy($orig, $this->_getNativePath($dest, $name))) {
177:             throw new Horde_Vfs_Exception('Unable to copy VFS file.');
178:         }
179: 
180:         $id = $this->_db->nextId($this->_params['table']);
181: 
182:         $query = sprintf('INSERT INTO %s (vfs_id, vfs_type, vfs_path, vfs_name, vfs_modified, vfs_owner) VALUES (?, ?, ?, ?, ?, ?)',
183:                          $this->_params['table']);
184:         $values = array($id, self::FILE, $dest, $name, time(), $this->_params['user']);
185: 
186:         $result = $this->_db->query($query, $values);
187: 
188:         if ($result instanceof PEAR_Error) {
189:             unlink($this->_getNativePath($dest, $name));
190:             throw new Horde_Vfs_Exception($result->getMessage());
191:         }
192:     }
193: 
194:     /**
195:      * Creates a folder on the VFS.
196:      *
197:      * @param string $path  Holds the path of directory to create folder.
198:      * @param string $name  Holds the name of the new folder.
199:      *
200:      * @throws Horde_Vfs_Exception
201:      */
202:     public function createFolder($path, $name)
203:     {
204:         $this->_connect();
205: 
206:         $id = $this->_db->nextId($this->_params['table']);
207:         $result = $this->_db->query(sprintf('INSERT INTO %s (vfs_id, vfs_type, vfs_path, vfs_name, vfs_modified, vfs_owner)
208:                                             VALUES (?, ?, ?, ?, ?, ?)',
209:                                             $this->_params['table']),
210:                                     array($id, self::FOLDER, $path, $name, time(), $this->_params['user']));
211:         if ($result instanceof PEAR_Error) {
212:             throw new Horde_Vfs_Exception($result->getMessage());
213:         }
214: 
215:         if (!@mkdir($this->_getNativePath($path, $name))) {
216:             $result = $this->_db->query(sprintf('DELETE FROM %s WHERE vfs_id = ?',
217:                                                 $this->_params['table']),
218:                                         array($id));
219:             throw new Horde_Vfs_Exception('Unable to create VFS directory.');
220:         }
221:     }
222: 
223:     /**
224:      * Rename a file or folder in the VFS.
225:      *
226:      * @param string $oldpath  The old path to the file.
227:      * @param string $oldname  The old filename.
228:      * @param string $newpath  The new path of the file.
229:      * @param string $newname  The new filename.
230:      *
231:      * @throws Horde_Vfs_Exception
232:      */
233:     public function rename($oldpath, $oldname, $newpath, $newname)
234:     {
235:         $this->_connect();
236: 
237:         if (strpos($newpath, '/') === false) {
238:             $parent = '';
239:             $path = $newpath;
240:         } else {
241:             list($parent, $path) = explode('/', $newpath, 2);
242:         }
243: 
244:         if (!$this->isFolder($parent, $path)) {
245:             $this->autocreatePath($newpath);
246:         }
247: 
248:         $this->_db->query(sprintf('UPDATE %s SET vfs_path = ?, vfs_name = ?, vfs_modified = ? WHERE vfs_path = ? AND vfs_name = ?', $this->_params['table']), array($newpath, $newname, time(), $oldpath, $oldname));
249: 
250:         if ($this->_db->affectedRows() == 0) {
251:             throw new Horde_Vfs_Exception('Unable to rename VFS file.');
252:         }
253: 
254:         if (is_a($this->_recursiveSQLRename($oldpath, $oldname, $newpath, $newname), 'PEAR_Error')) {
255:             $this->_db->query(sprintf('UPDATE %s SET vfs_path = ?, vfs_name = ?  WHERE vfs_path = ? AND vfs_name = ?', $this->_params['table']), array($oldpath, $oldname, $newpath, $newname));
256:             throw new Horde_Vfs_Exception('Unable to rename VFS directory.');
257:         }
258: 
259:         if (!@is_dir($this->_getNativePath($newpath))) {
260:             $this->autocreatePath($newpath);
261:         }
262: 
263:         if (!@rename($this->_getNativePath($oldpath, $oldname), $this->_getNativePath($newpath, $newname))) {
264:             $this->_db->query(sprintf('UPDATE %s SET vfs_path = ?, vfs_name = ? WHERE vfs_path = ? AND vfs_name = ?', $this->_params['table']), array($oldpath, $oldname, $newpath, $newname));
265:             return PEAR::raiseError(Horde_Vfs_Translation::t("Unable to rename VFS file."));
266:         }
267:     }
268: 
269:     /**
270:      * Delete a folder from the VFS.
271:      *
272:      * @param string $path        The path to delete the folder from.
273:      * @param string $name        The foldername to use.
274:      * @param boolean $recursive  Force a recursive delete?
275:      *
276:      * @throws Horde_Vfs_Exception
277:      */
278:     public function deleteFolder($path, $name, $recursive = false)
279:     {
280:         $this->_connect();
281: 
282:         if ($recursive) {
283:             $this->emptyFolder($path . '/' . $name);
284:         } else {
285:             $list = $this->listFolder($path . '/' . $name);
286:             if (count($list)) {
287:                 throw new Horde_Vfs_Exception(sprintf('Unable to delete %s, the directory is not empty', $path . '/' . $name));
288:             }
289:         }
290: 
291:         $result = $this->_db->query(sprintf('DELETE FROM %s WHERE vfs_type = ? AND vfs_path = ? AND vfs_name = ?', $this->_params['table']), array(self::FOLDER, $path, $name));
292: 
293:         if ($this->_db->affectedRows() == 0 || ($result instanceof PEAR_Error)) {
294:             throw new Horde_Vfs_Exception('Unable to delete VFS directory.');
295:         }
296: 
297:         if ($this->_recursiveSQLDelete($path, $name) instanceof PEAR_Error ||
298:             $this->_recursiveLFSDelete($path, $name) instanceof PEAR_Error) {
299:             throw new Horde_Vfs_Exception('Unable to delete VFS directory recursively.');
300:         }
301:     }
302: 
303:     /**
304:      * Delete a file from the VFS.
305:      *
306:      * @param string $path  The path to store the file in.
307:      * @param string $name  The filename to use.
308:      *
309:      * @throws Horde_Vfs_Exception
310:      */
311:     public function deleteFile($path, $name)
312:     {
313:         $this->_checkQuotaDelete($path, $name);
314:         $this->_connect();
315: 
316:         $result = $this->_db->query(sprintf('DELETE FROM %s WHERE vfs_type = ? AND vfs_path = ? AND vfs_name = ?',
317:                                             $this->_params['table']),
318:                                     array(self::FILE, $path, $name));
319: 
320:         if ($this->_db->affectedRows() == 0) {
321:             throw new Horde_Vfs_Exception('Unable to delete VFS file.');
322:         }
323: 
324:         if ($result instanceof PEAR_Error) {
325:             throw new Horde_Vfs_Exception($result->getMessage());
326:         }
327: 
328:         if (!@unlink($this->_getNativePath($path, $name))) {
329:             throw new Horde_Vfs_Exception('Unable to delete VFS file.');
330:         }
331:     }
332: 
333:     /**
334:      * Return a list of the contents of a folder.
335:      *
336:      * @param string $path       The directory path.
337:      * @param mixed $filter      String/hash of items to filter based on
338:      *                           filename.
339:      * @param boolean $dotfiles  Show dotfiles?
340:      * @param boolean $dironly   Show directories only?
341:      *
342:      * @return array  File list.
343:      * @throws Horde_Vfs_Exception
344:      */
345:     protected function _listFolder($path, $filter = null, $dotfiles = true,
346:                                    $dironly = false)
347:     {
348:         $this->_connect();
349: 
350:         $files = array();
351: 
352:         $fileList = $this->_db->getAll(sprintf('SELECT vfs_name, vfs_type, vfs_modified, vfs_owner FROM %s
353:                                                WHERE vfs_path = ?',
354:                                                $this->_params['table']),
355:                                        array($path));
356:         if ($fileList instanceof PEAR_Error) {
357:             throw new Horde_Vfs_Exception($fileList->getMessage());
358:         }
359: 
360:         foreach ($fileList as $line) {
361:             // Filter out dotfiles if they aren't wanted.
362:             if (!$dotfiles && substr($line[0], 0, 1) == '.') {
363:                 continue;
364:             }
365: 
366:             $file['name'] = $line[0];
367: 
368:             if ($line[1] == self::FILE) {
369:                 $name = explode('.', $line[0]);
370: 
371:                 if (count($name) == 1) {
372:                     $file['type'] = '**none';
373:                 } else {
374:                     $file['type'] = Horde_String::lower($name[count($name) - 1]);
375:                 }
376: 
377:                 $file['size'] = filesize($this->_getNativePath($path, $line[0]));
378:             } elseif ($line[1] == self::FOLDER) {
379:                 $file['type'] = '**dir';
380:                 $file['size'] = -1;
381:             }
382: 
383:             $file['date'] = $line[2];
384:             $file['owner'] = $line[3];
385:             $file['perms'] = '';
386:             $file['group'] = '';
387: 
388:             // Filtering.
389:             if ($this->_filterMatch($filter, $file['name'])) {
390:                 unset($file);
391:                 continue;
392:             }
393:             if ($dironly && $file['type'] !== '**dir') {
394:                 unset($file);
395:                 continue;
396:             }
397: 
398:             $files[$file['name']] = $file;
399:             unset($file);
400:         }
401: 
402:         return $files;
403:     }
404: 
405:     /**
406:      * Returns a sorted list of folders in specified directory.
407:      *
408:      * @param string $path         The path of the directory to get the
409:      *                             directory list for.
410:      * @param mixed $filter        String/hash of items to filter based on
411:      *                             folderlist.
412:      * @param boolean $dotfolders  Include dotfolders?
413:      *
414:      * @return array  Folder list.
415:      * @throws Horde_Vfs_Exception
416:      */
417:     public function listFolders($path = '', $filter = array(),
418:                                 $dotfolders = true)
419:     {
420:         $this->_connect();
421: 
422:         $sql = sprintf('SELECT vfs_name, vfs_path FROM %s WHERE vfs_path = ? AND vfs_type = ?',
423:                        $this->_params['table']);
424: 
425:         $folderList = $this->_db->getAll($sql, array($path, self::FOLDER));
426:         if ($folderList instanceof PEAR_Error) {
427:             throw new Horde_Vfs_Exception($folderList->getMessage());
428:         }
429: 
430:         $folders = array();
431:         foreach ($folderList as $line) {
432:             $folder['val'] = $this->_getNativePath($line[1], $line[0]);
433:             $folder['abbrev'] = '';
434:             $folder['label'] = '';
435: 
436:             $count = substr_count($folder['val'], '/');
437: 
438:             $x = 0;
439:             while ($x < $count) {
440:                 $folder['abbrev'] .= '    ';
441:                 $folder['label'] .= '    ';
442:                 $x++;
443:             }
444: 
445:             $folder['abbrev'] .= $line[0];
446:             $folder['label'] .= $line[0];
447: 
448:             $strlen = Horde_String::length($folder['label']);
449:             if ($strlen > 26) {
450:                 $folder['abbrev'] = substr($folder['label'], 0, ($count * 4));
451:                 $length = (29 - ($count * 4)) / 2;
452:                 $folder['abbrev'] .= substr($folder['label'], ($count * 4), $length);
453:                 $folder['abbrev'] .= '...';
454:                 $folder['abbrev'] .= substr($folder['label'], -1 * $length, $length);
455:             }
456: 
457:             $found = false;
458:             foreach ($filter as $fltr) {
459:                 if ($folder['val'] == $fltr) {
460:                     $found = true;
461:                 }
462:             }
463: 
464:             if (!$found) {
465:                 $folders[$folder['val']] = $folder;
466:             }
467:         }
468: 
469:         ksort($folders);
470:         return $folders;
471:     }
472: 
473:     /**
474:      * Recursively copies the contents of a folder to a destination.
475:      *
476:      * @param string $path  The path to store the directory in.
477:      * @param string $name  The name of the directory.
478:      * @param string $dest  The destination of the directory.
479:      *
480:      * @throws Horde_Vfs_Exception
481:      */
482:     protected function _recursiveCopy($path, $name, $dest)
483:     {
484:         $this->createFolder($dest, $name);
485: 
486:         $file_list = $this->listFolder($this->_getSQLNativePath($path, $name));
487:         foreach ($file_list as $file) {
488:             $this->copy($this->_getSQLNativePath($path, $name), $file['name'], $this->_getSQLNativePath($dest, $name));
489:         }
490:     }
491: 
492:     /**
493:      * Store a files information within the database.
494:      *
495:      * @param string $path         The path to store the file in.
496:      * @param string $name         The filename to use.
497:      * @param boolean $autocreate  Automatically create directories?
498:      *
499:      * @throws Horde_Vfs_Exception
500:      */
501:     protected function _writeSQLData($path, $name, $autocreate = false)
502:     {
503:         $this->_connect();
504: 
505:         // File already exists in database
506:         if ($this->exists($path, $name)) {
507:             $query = 'UPDATE ' . $this->_params['table'] .
508:                      ' SET vfs_modified = ?' .
509:                      ' WHERE vfs_path = ? AND vfs_name = ?';
510:             $values = array(time(), $path, $name);
511:         } else {
512:             $id = $this->_db->nextId($this->_params['table']);
513: 
514:             $query = 'INSERT INTO ' . $this->_params['table'] .
515:                      ' (vfs_id, vfs_type, vfs_path, vfs_name, vfs_modified,' .
516:                      ' vfs_owner) VALUES (?, ?, ?, ?, ?, ?)';
517:             $values = array($id, self::FILE, $path, $name, time(),
518:                             $this->_params['user']);
519:         }
520:         return $this->_db->query($query, $values);
521:     }
522: 
523:     /**
524:      * Renames all child paths.
525:      *
526:      * @param string $oldpath  The old path of the folder to rename.
527:      * @param string $oldname  The old name.
528:      * @param string $newpath  The new path of the folder to rename.
529:      * @param string $newname  The new name.
530:      *
531:      * @throws Horde_Vfs_Exception
532:      */
533:     protected function _recursiveSQLRename($oldpath, $oldname, $newpath,
534:                                            $newname)
535:     {
536:         $folderList = $this->_db->getCol(sprintf('SELECT vfs_name FROM %s WHERE vfs_type = ? AND vfs_path = ?',
537:                                                  $this->_params['table']),
538:                                          0,
539:                                          array(self::FOLDER, $this->_getSQLNativePath($oldpath, $oldname)));
540: 
541:         foreach ($folderList as $folder) {
542:             $this->_recursiveSQLRename($this->_getSQLNativePath($oldpath, $oldname), $folder, $this->_getSQLNativePath($newpath, $newname), $folder);
543:         }
544: 
545:         $result = $this->_db->query(sprintf('UPDATE %s SET vfs_path = ? WHERE vfs_path = ?',
546:                                             $this->_params['table']),
547:                                     array($this->_getSQLNativePath($newpath, $newname),
548:                                           $this->_getSQLNativePath($oldpath, $oldname)));
549: 
550:         if ($result instanceof PEAR_Error) {
551:             throw new Horde_Vfs_Exception($result->getMessage());
552:         }
553:     }
554: 
555:     /**
556:      * Delete a folders contents from the VFS in the SQL database,
557:      * recursively.
558:      *
559:      * @param string $path  The path of the folder.
560:      * @param string $name  The foldername to use.
561:      *
562:      * @throws Horde_Vfs_Exception
563:      */
564:     protected function _recursiveSQLDelete($path, $name)
565:     {
566:         $result = $this->_db->query(sprintf('DELETE FROM %s WHERE vfs_type = ? AND vfs_path = ?', $this->_params['table']), array(self::FILE, $this->_getSQLNativePath($path, $name)));
567:         if ($result instanceof PEAR_Error) {
568:             throw new Horde_Vfs_Exception($result->getMessage());
569:         }
570: 
571:         $folderList = $this->_db->getCol(sprintf('SELECT vfs_name FROM %s WHERE vfs_type = ? AND vfs_path = ?', $this->_params['table']), 0, array(self::FOLDER, $this->_getSQLNativePath($path, $name)));
572: 
573:         foreach ($folderList as $folder) {
574:             $this->_recursiveSQLDelete($this->_getSQLNativePath($path, $name), $folder);
575:         }
576: 
577:         $this->_db->query(sprintf('DELETE FROM %s WHERE vfs_type = ? AND vfs_name = ? AND vfs_path = ?', $this->_params['table']), array(self::FOLDER, $name, $path));
578:     }
579: 
580:     /**
581:      * Delete a folders contents from the VFS, recursively.
582:      *
583:      * @param string $path  The path of the folder.
584:      * @param string $name  The foldername to use.
585:      *
586:      * @throws Horde_Vfs_Exception
587:      */
588:     protected function _recursiveLFSDelete($path, $name)
589:     {
590:         $dir = $this->_getNativePath($path, $name);
591:         $dh = @opendir($dir);
592: 
593:         while (false !== ($file = readdir($dh))) {
594:             if ($file != '.' && $file != '..') {
595:                 if (is_dir($dir . '/' . $file)) {
596:                     $this->_recursiveLFSDelete(!strlen($path) ? $name : $path . '/' . $name, $file);
597:                 } else {
598:                     @unlink($dir . '/' . $file);
599:                 }
600:             }
601:         }
602:         @closedir($dh);
603: 
604:         rmdir($dir);
605:     }
606: 
607:     /**
608:      * Attempts to open a persistent connection to the SQL server.
609:      *
610:      * @throws Horde_Vfs_Exception
611:      */
612:     protected function _connect()
613:     {
614:         if ($this->_db !== false) {
615:             return;
616:         }
617: 
618:         $required = array('db', 'vfsroot');
619:         foreach ($required as $val) {
620:             if (!isset($this->_params[$val])) {
621:                 throw new Horde_Vfs_Exception(sprintf('Required "%s" not specified in VFS configuration.', $val));
622:             }
623:         }
624: 
625:         $this->_params = array_merge(array(
626:             'table' => 'horde_vfs',
627:         ), $this->_params);
628: 
629:         $this->_db = $this->_params['db'];
630:     }
631: 
632:     /**
633:      * Return a full filename on the native filesystem, from a VFS
634:      * path and name.
635:      *
636:      * @param string $path  The VFS file path.
637:      * @param string $name  The VFS filename.
638:      *
639:      * @return string  The full native filename.
640:      */
641:     protected function _getNativePath($path, $name)
642:     {
643:         if (strlen($name)) {
644:             $name = '/' . $name;
645:         }
646: 
647:         if (strlen($path)) {
648:             if (isset($this->_params['home']) &&
649:                 preg_match('|^~/?(.*)$|', $path, $matches)) {
650:                 $path = $this->_params['home']  . '/' . $matches[1];
651:             }
652: 
653:             return $this->_params['vfsroot'] . '/' . $path . $name;
654:         }
655: 
656:         return $this->_params['vfsroot'] . $name;
657:     }
658: 
659:     /**
660:      * Return a full SQL filename on the native filesystem, from a VFS
661:      * path and name.
662:      *
663:      * @param string $path  The VFS file path.
664:      * @param string $name  The VFS filename.
665:      *
666:      * @return string  The full native filename.
667:      */
668:     protected function _getSQLNativePath($path, $name)
669:     {
670:         return strlen($path)
671:             ? $path . '/' . $name
672:             : $name;
673:     }
674: 
675: }
676: 
API documentation generated by ApiGen