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:  * VFS implementation for a filesystem.
  4:  *
  5:  * Copyright 2002-2012 Horde LLC (http://www.horde.org/)
  6:  *
  7:  * See the enclosed file COPYING for license information (LGPL). If you
  8:  * did not receive this file, see http://www.horde.org/licenses/lgpl21.
  9:  *
 10:  * @author  Chuck Hagenbuch
 11:  * @package Vfs
 12:  */
 13: class Horde_Vfs_File extends Horde_Vfs_Base
 14: {
 15:     /**
 16:      * List of permissions and if they can be changed in this VFS backend.
 17:      *
 18:      * @var array
 19:      */
 20:     protected $_permissions = array(
 21:         'owner' => array(
 22:             'read' => true,
 23:             'write' => true,
 24:             'execute' => true
 25:         ),
 26:         'group' => array(
 27:             'read' => true,
 28:             'write' => true,
 29:             'execute' => true
 30:         ),
 31:         'all' => array(
 32:             'read' => true,
 33:             'write' => true,
 34:             'execute' => true
 35:         )
 36:     );
 37: 
 38:     /**
 39:      * Constructs a new Filesystem based VFS object.
 40:      *
 41:      * @param array $params  A hash containing connection parameters. REQUIRED
 42:      *                       parameters:
 43:      *   - vfsroot: (string) The root path.
 44:      *              Note: The user that your webserver runs as MUST have
 45:      *              read/write permission to this directory.
 46:      */
 47:     public function __construct($params = array())
 48:     {
 49:         parent::__construct($params);
 50: 
 51:         if (!empty($this->_params['vfsroot']) &&
 52:             ((substr($this->_params['vfsroot'], -1) == '/') ||
 53:              (substr($this->_params['vfsroot'], -1) == '\\'))) {
 54:             $this->_params['vfsroot'] = substr($this->_params['vfsroot'], 0, strlen($this->_params['vfsroot']) - 1);
 55:         }
 56:     }
 57: 
 58:     /**
 59:      * Retrieves the filesize from the VFS.
 60:      *
 61:      * @param string $path  The pathname to the file.
 62:      * @param string $name  The filename to retrieve.
 63:      *
 64:      * @return integer  The file size.
 65:      * @throws Horde_Vfs_Exception
 66:      */
 67:     public function size($path, $name)
 68:     {
 69:         if (($size = @filesize($this->_getNativePath($path, $name))) === false) {
 70:             throw new Horde_Vfs_Exception(sprintf('Unable to check file size of "%s/%s".'), $path, $name);
 71:         }
 72: 
 73:         return $size;
 74:     }
 75: 
 76:     /**
 77:      * Retrieve a file from the VFS.
 78:      *
 79:      * @param string $path  The pathname to the file.
 80:      * @param string $name  The filename to retrieve.
 81:      *
 82:      * @return string  The file data.
 83:      * @throws Horde_Vfs_Exception
 84:      */
 85:     public function read($path, $name)
 86:     {
 87:         if (($data = @file_get_contents($this->_getNativePath($path, $name))) === false) {
 88:             throw new Horde_Vfs_Exception('Unable to open VFS file.');
 89:         }
 90: 
 91:         return $data;
 92:     }
 93: 
 94:     /**
 95:      * Retrieves a file from the VFS as an on-disk local file.
 96:      *
 97:      * This function provides a file on local disk with the data of a VFS file
 98:      * in it. This file <em>cannot</em> be modified! The behavior if you do
 99:      * modify it is undefined. It will be removed at the end of the request.
100:      *
101:      * @param string $path  The pathname to the file.
102:      * @param string $name  The filename to retrieve.
103:      *
104:      * @return string A local filename.
105:      */
106:     public function readFile($path, $name)
107:     {
108:         return $this->_getNativePath($path, $name);
109:     }
110: 
111:     /**
112:      * Open a read-only stream to a file in the VFS.
113:      *
114:      * @param string $path  The pathname to the file.
115:      * @param string $name  The filename to retrieve.
116:      *
117:      * @return resource  The stream.
118:      * @throws Horde_Vfs_Exception
119:      */
120:     public function readStream($path, $name)
121:     {
122:         $mode = OS_WINDOWS ? 'rb' : 'r';
123:         $stream = @fopen($this->_getNativePath($path, $name), $mode);
124:         if (!is_resource($stream)) {
125:             throw new Horde_Vfs_Exception('Unable to open VFS file.');
126:         }
127: 
128:         return $stream;
129:     }
130: 
131:     /**
132:      * Retrieves a part of a file from the VFS. Particularly useful when
133:      * reading large files which would exceed the PHP memory limits if they
134:      * were stored in a string.
135:      *
136:      * @param string  $path       The pathname to the file.
137:      * @param string  $name       The filename to retrieve.
138:      * @param integer $offset     The offset of the part. (The new offset will
139:      *                            be stored in here).
140:      * @param integer $length     The length of the part. If the length = -1,
141:      *                            the whole part after the offset is retrieved.
142:      *                            If more bytes are given as exists after the
143:      *                            given offset. Only the available bytes are
144:      *                            read.
145:      * @param integer $remaining  The bytes that are left, after the part that
146:      *                            is retrieved.
147:      *
148:      * @return string  The file data.
149:      * @throws Horde_Vfs_Exception
150:      */
151:     public function readByteRange($path, $name, &$offset, $length, &$remaining)
152:     {
153:         if ($offset < 0) {
154:             throw new Horde_Vfs_Exception(sprintf('Wrong offset %d while reading a VFS file.', $offset));
155:         }
156: 
157:         // Calculate how many bytes MUST be read, so the remainging
158:         // bytes and the new offset can be calculated correctly.
159:         $file = $this->_getNativePath($path, $name);
160:         $size = filesize ($file);
161:         if (($length == -1) || (($length + $offset) > $size)) {
162:             $length = $size - $offset;
163:         }
164:         if ($remaining < 0) {
165:             $remaining = 0;
166:         }
167: 
168:         $fp = @fopen($file, 'rb');
169:         if (!$fp) {
170:             throw new Horde_Vfs_Exception('Unable to open VFS file.');
171:         }
172:         fseek($fp, $offset);
173:         $data = fread($fp, $length);
174:         $offset = ftell($fp);
175:         $remaining = $size - $offset;
176: 
177:         fclose($fp);
178: 
179:         return $data;
180:     }
181: 
182:     /**
183:      * Store a file in the VFS, with the data copied from a temporary
184:      * file.
185:      *
186:      * @param string $path         The path to store the file in.
187:      * @param string $name         The filename to use.
188:      * @param string $tmpFile      The temporary file containing the data to be
189:      *                             stored.
190:      * @param boolean $autocreate  Automatically create directories?
191:      *
192:      * @throws Horde_Vfs_Exception
193:      */
194:     public function write($path, $name, $tmpFile, $autocreate = false)
195:     {
196:         if (!@is_dir($this->_getNativePath($path))) {
197:             if ($autocreate) {
198:                 $this->autocreatePath($path);
199:             } else {
200:                 throw new Horde_Vfs_Exception('VFS directory does not exist.');
201:             }
202:         }
203: 
204:         $this->_checkQuotaWrite('file', $tmpFile);
205: 
206:         // Since we already have the data in a file, don't read it
207:         // into PHP's memory at all - just copy() it to the new
208:         // location. We leave it to the caller to clean up the
209:         // temporary file, so we don't use rename().
210:         if (!@copy($tmpFile, $this->_getNativePath($path, $name))) {
211:             throw new Horde_Vfs_Exception('Unable to write VFS file (copy() failed).');
212:         }
213:     }
214: 
215:     /**
216:      * Moves a file in the database and the file system.
217:      *
218:      * @param string $path         The path to store the file in.
219:      * @param string $name         The filename to use.
220:      * @param string $dest         The destination of the file.
221:      * @param boolean $autocreate  Automatically create directories?
222:      *
223:      * @throws Horde_Vfs_Exception
224:      */
225:     public function move($path, $name, $dest, $autocreate = false)
226:     {
227:         $orig = $this->_getNativePath($path, $name);
228:         if (preg_match('|^' . preg_quote($orig) . '/?$|', $dest)) {
229:             throw new Horde_Vfs_Exception('Cannot move file(s) - destination is within source.');
230:         }
231: 
232:         if ($autocreate) {
233:             $this->autocreatePath($dest);
234:         }
235: 
236:         foreach ($this->listFolder($dest, false) as $file) {
237:             if ($file['name'] == $name) {
238:                 throw new Horde_Vfs_Exception('Unable to move VFS file.');
239:             }
240:         }
241: 
242:         if (!@rename($orig, $this->_getNativePath($dest, $name))) {
243:             throw new Horde_Vfs_Exception('Unable to move VFS file.');
244:         }
245:     }
246: 
247:     /**
248:      * Copies a file through the backend.
249:      *
250:      * @param string $path         The path to store the file in.
251:      * @param string $name         The filename to use.
252:      * @param string $dest         The destination of the file.
253:      * @param boolean $autocreate  Automatically create directories?
254:      *
255:      * @throws Horde_Vfs_Exception
256:      */
257:     public function copy($path, $name, $dest, $autocreate = false)
258:     {
259:         $orig = $this->_getNativePath($path, $name);
260:         if (preg_match('|^' . preg_quote($orig) . '/?$|', $dest)) {
261:             throw new Horde_Vfs_Exception('Cannot copy file(s) - source and destination are the same.');
262:         }
263: 
264:         if ($autocreate) {
265:             $this->autocreatePath($dest);
266:         }
267: 
268:         foreach ($this->listFolder($dest, false) as $file) {
269:             if ($file['name'] == $name) {
270:                 throw new Horde_Vfs_Exception('Unable to copy VFS file.');
271:             }
272:         }
273: 
274:         $this->_checkQuotaWrite('file', $orig);
275: 
276:         if (!@copy($orig, $this->_getNativePath($dest, $name))) {
277:             throw new Horde_Vfs_Exception('Unable to copy VFS file.');
278:         }
279:     }
280: 
281:     /**
282:      * Store a file in the VFS from raw data.
283:      *
284:      * @param string $path         The path to store the file in.
285:      * @param string $name         The filename to use.
286:      * @param string $data         The file data.
287:      * @param boolean $autocreate  Automatically create directories?
288:      *
289:      * @throws Horde_Vfs_Exception
290:      */
291:     public function writeData($path, $name, $data, $autocreate = false)
292:     {
293:         if (!@is_dir($this->_getNativePath($path))) {
294:             if ($autocreate) {
295:                 $this->autocreatePath($path);
296:             } else {
297:                 throw new Horde_Vfs_Exception(sprintf('VFS directory %s does not exist.', $path));
298:             }
299:         }
300: 
301:         // Treat an attempt to write an empty file as a touch() call,
302:         // since otherwise the file will not be created at all.
303:         if (!strlen($data)) {
304:             if (@touch($this->_getNativePath($path, $name))) {
305:                 return;
306:             }
307:             throw new Horde_Vfs_Exception('Unable to create empty VFS file.');
308:         }
309: 
310:         $this->_checkQuotaWrite('string', $data);
311: 
312:         // Otherwise we go ahead and try to write out the file.
313:         if (!@file_put_contents($this->_getNativePath($path, $name), $data)) {
314:             throw new Horde_Vfs_Exception('Unable to write VFS file data.');
315:         }
316:     }
317: 
318:     /**
319:      * Delete a file from the VFS.
320:      *
321:      * @param string $path  The path to store the file in.
322:      * @param string $name  The filename to use.
323:      *
324:      * @throws Horde_Vfs_Exception
325:      */
326:     public function deleteFile($path, $name)
327:     {
328:         $this->_checkQuotaDelete($path, $name);
329: 
330:         if (!@unlink($this->_getNativePath($path, $name))) {
331:             throw new Horde_Vfs_Exception('Unable to delete VFS file.');
332:         }
333:     }
334: 
335:     /**
336:      * Delete a folder from the VFS.
337:      *
338:      * @param string $path        The path to delete the folder from.
339:      * @param string $name        The foldername to use.
340:      * @param boolean $recursive  Force a recursive delete?
341:      *
342:      * @throws Horde_Vfs_Exception
343:      */
344:     public function deleteFolder($path, $name, $recursive = false)
345:     {
346:         if ($recursive) {
347:             $this->emptyFolder($path . '/' . $name);
348:         } else {
349:             $list = $this->listFolder($path . '/' . $name);
350:             if (count($list)) {
351:                 throw new Horde_Vfs_Exception(sprintf('Unable to delete %s, the directory is not empty', $path . '/' . $name));
352:             }
353:         }
354: 
355:         if (!@rmdir($this->_getNativePath($path, $name))) {
356:             throw new Horde_Vfs_Exception('Unable to delete VFS directory.');
357:         }
358:     }
359: 
360:     /**
361:      * Creates a folder on the VFS.
362:      *
363:      * @param string $path  The path to create the folder in.
364:      * @param string $name  The foldername to use.
365:      *
366:      * @throws Horde_Vfs_Exception
367:      */
368:     public function createFolder($path, $name)
369:     {
370:         if (!@mkdir($this->_getNativePath($path, $name))) {
371:             throw new Horde_Vfs_Exception('Unable to create VFS directory.');
372:         }
373:     }
374: 
375:     /**
376:      * Check if a given pathname is a folder.
377:      *
378:      * @param string $path  The path to the folder.
379:      * @param string $name  The file/folder name.
380:      *
381:      * @return boolean  True if it is a folder, false otherwise.
382:      */
383:     public function isFolder($path, $name)
384:     {
385:         return @is_dir($this->_getNativePath($path, $name));
386:     }
387: 
388:     /**
389:      * Changes permissions for an item in the VFS.
390:      *
391:      * @param string $path        The path of directory of the item.
392:      * @param string $name        The name of the item.
393:      * @param string $permission  The permission to set in octal notation.
394:      *
395:      * @throws Horde_Vfs_Exception
396:      */
397:     public function changePermissions($path, $name, $permission)
398:     {
399:         if (!@chmod($this->_getNativePath($path, $name), base_convert($permission, 8, 10))) {
400:             throw new Horde_Vfs_Exception(sprintf('Unable to change permission for VFS file %s/%s.', $path, $name));
401:         }
402:     }
403: 
404:     /**
405:      * Return a list of the contents of a folder.
406:      *
407:      * @param string $path       The path of the directory.
408:      * @param mixed $filter      String/hash to filter file/dirname on.
409:      * @param boolean $dotfiles  Show dotfiles?
410:      * @param boolean $dironly   Show only directories?
411:      *
412:      * @return array  File list.
413:      * @throws Horde_Vfs_Exception
414:      */
415:     protected function _listFolder($path, $filter = null, $dotfiles = true,
416:                                    $dironly = false)
417:     {
418:         $files = array();
419:         $path = $this->_getNativePath(isset($path) ? $path : '');
420: 
421:         if (!@is_dir($path)) {
422:             throw new Horde_Vfs_Exception('Not a directory');
423:         }
424: 
425:         if (!@chdir($path)) {
426:             throw new Horde_Vfs_Exception('Unable to access VFS directory.');
427:         }
428: 
429:         $d = dir($path);
430:         while (($entry = $d->read()) !== false) {
431:             // Filter out '.' and '..' entries.
432:             if ($entry == '.' || $entry == '..') {
433:                 continue;
434:             }
435: 
436:             // Filter out dotfiles if they aren't wanted.
437:             if (!$dotfiles && substr($entry, 0, 1) == '.') {
438:                 continue;
439:             }
440: 
441:             // File name
442:             $file['name'] = $entry;
443: 
444:             // Unix style file permissions
445:             $file['perms'] = $this->_getUnixPerms(fileperms($entry));
446: 
447:             // Owner
448:             $file['owner'] = fileowner($entry);
449:             if (function_exists('posix_getpwuid')) {
450:                 $owner = posix_getpwuid($file['owner']);
451:                 $file['owner'] = $owner['name'];
452:             }
453: 
454:             // Group
455:             $file['group'] = filegroup($entry);
456:             if (function_exists('posix_getgrgid') && (PHP_VERSION != '5.2.1')) {
457:                 $group = posix_getgrgid($file['group']);
458:                 $file['group'] = $group['name'];
459:             }
460: 
461:             // Size
462:             $file['size'] = filesize($entry);
463: 
464:             // Date
465:             $file['date'] = filemtime($entry);
466: 
467:             // Type
468:             if (@is_dir($entry) && !is_link($entry)) {
469:                 $file['perms'] = 'd' . $file['perms'];
470:                 $file['type'] = '**dir';
471:                 $file['size'] = -1;
472:             } elseif (is_link($entry)) {
473:                 $file['perms'] = 'l' . $file['perms'];
474:                 $file['type'] = '**sym';
475:                 $file['link'] = readlink($entry);
476:                 $file['linktype'] = '**none';
477:                 if (file_exists($file['link'])) {
478:                     if (is_dir($file['link'])) {
479:                         $file['linktype'] = '**dir';
480:                     } elseif (is_link($file['link'])) {
481:                         $file['linktype'] = '**sym';
482:                     } elseif (is_file($file['link'])) {
483:                         $ext = explode('.', $file['link']);
484:                         if (!(count($ext) == 1 || ($ext[0] === '' && count($ext) == 2))) {
485:                             $file['linktype'] = Horde_String::lower($ext[count($ext) - 1]);
486:                         }
487:                     }
488:                 } else {
489:                     $file['linktype'] = '**broken';
490:                 }
491:             } elseif (is_file($entry)) {
492:                 $file['perms'] = '-' . $file['perms'];
493:                 $ext = explode('.', $entry);
494: 
495:                 if (count($ext) == 1 || (substr($file['name'], 0, 1) === '.' && count($ext) == 2)) {
496:                     $file['type'] = '**none';
497:                 } else {
498:                     $file['type'] = Horde_String::lower($ext[count($ext) - 1]);
499:                 }
500:             } else {
501:                 $file['type'] = '**none';
502:                 if ((fileperms($entry) & 0xC000) == 0xC000) {
503:                     $file['perms'] = 's' . $file['perms'];
504:                 } elseif ((fileperms($entry) & 0x6000) == 0x6000) {
505:                     $file['perms'] = 'b' . $file['perms'];
506:                 } elseif ((fileperms($entry) & 0x2000) == 0x2000) {
507:                     $file['perms'] = 'c' . $file['perms'];
508:                 } elseif ((fileperms($entry) & 0x1000) == 0x1000) {
509:                     $file['perms'] = 'p' . $file['perms'];
510:                 } else {
511:                     $file['perms'] = '?' . $file['perms'];
512:                 }
513:             }
514: 
515:             // Filtering.
516:             if ($this->_filterMatch($filter, $file['name'])) {
517:                 unset($file);
518:                 continue;
519:             }
520:             if ($dironly && $file['type'] !== '**dir') {
521:                 unset($file);
522:                 continue;
523:             }
524: 
525:             $files[$file['name']] = $file;
526:             unset($file);
527:         }
528: 
529:         $d->close();
530: 
531:         return $files;
532:     }
533: 
534:     /**
535:      * Returns a sorted list of folders in specified directory.
536:      *
537:      * @param string $path         The path of the directory to get the
538:      *                             directory list for.
539:      * @param mixed $filter        Hash of items to filter based on folderlist.
540:      * @param boolean $dotfolders  Include dotfolders?
541:      *
542:      * @return array  Folder list.
543:      * @throws Horde_Vfs_Exception
544:      */
545:     public function listFolders($path = '', $filter = null, $dotfolders = true)
546:     {
547:         $this->_connect();
548: 
549:         $folders = array();
550:         $folders[dirname($path)] = array(
551:             'val' => dirname($path),
552:             'abbrev' => '..',
553:             'label' => '..'
554:         );
555: 
556:         $folderList = $this->listFolder($path, null, $dotfolders, true);
557:         foreach ($folderList as $name => $files) {
558:             $folders[$name] = array(
559:                 'val' => $path . '/' . $files['name'],
560:                 'abbrev' => $files['name'],
561:                 'label' => $path . '/' . $files['name']
562:             );
563:         }
564: 
565:         ksort($folders);
566: 
567:         return $folders;
568:     }
569: 
570:     /**
571:      * Return Unix style perms.
572:      *
573:      * @param integer $perms  The permissions to set.
574:      *
575:      * @return string  Unix style perms.
576:      */
577:     protected function _getUnixPerms($perms)
578:     {
579:         // Determine permissions
580:         $owner['read']    = ($perms & 00400) ? 'r' : '-';
581:         $owner['write']   = ($perms & 00200) ? 'w' : '-';
582:         $owner['execute'] = ($perms & 00100) ? 'x' : '-';
583:         $group['read']    = ($perms & 00040) ? 'r' : '-';
584:         $group['write']   = ($perms & 00020) ? 'w' : '-';
585:         $group['execute'] = ($perms & 00010) ? 'x' : '-';
586:         $world['read']    = ($perms & 00004) ? 'r' : '-';
587:         $world['write']   = ($perms & 00002) ? 'w' : '-';
588:         $world['execute'] = ($perms & 00001) ? 'x' : '-';
589: 
590:         // Adjust for SUID, SGID and sticky bit
591:         if ($perms & 0x800) {
592:             $owner['execute'] = ($owner['execute'] == 'x') ? 's' : 'S';
593:         }
594:         if ($perms & 0x400) {
595:             $group['execute'] = ($group['execute'] == 'x') ? 's' : 'S';
596:         }
597:         if ($perms & 0x200) {
598:             $world['execute'] = ($world['execute'] == 'x') ? 't' : 'T';
599:         }
600: 
601:         return $owner['read'] . $owner['write'] . $owner['execute'] .
602:                $group['read'] . $group['write'] . $group['execute'] .
603:                $world['read'] . $world['write'] . $world['execute'];
604:     }
605: 
606:     /**
607:      * Rename a file or folder in the VFS.
608:      *
609:      * @param string $oldpath  The old path to the file.
610:      * @param string $oldname  The old filename.
611:      * @param string $newpath  The new path of the file.
612:      * @param string $newname  The new filename.
613:      *
614:      * @throws Horde_Vfs_Exception
615:      */
616:     public function rename($oldpath, $oldname, $newpath, $newname)
617:     {
618:         if (!@is_dir($this->_getNativePath($newpath))) {
619:             $this->autocreatePath($newpath);
620:         }
621: 
622:         if (!@rename($this->_getNativePath($oldpath, $oldname),
623:                      $this->_getNativePath($newpath, $newname))) {
624:             throw new Horde_Vfs_Exception(sprintf('Unable to rename VFS file %s/%s.', $oldpath, $oldname));
625:         }
626:     }
627: 
628:     /**
629:      * Returns if a given file or folder exists in a folder.
630:      *
631:      * @param string $path  The path to the folder.
632:      * @param string $name  The file or folder name.
633:      *
634:      * @return boolean  True if it exists, false otherwise.
635:      */
636:     public function exists($path, $name)
637:     {
638:         return file_exists($this->_getNativePath($path, $name));
639:     }
640: 
641:     /**
642:      * Return a full filename on the native filesystem, from a VFS
643:      * path and name.
644:      *
645:      * @param string $path  The VFS file path.
646:      * @param string $name  The VFS filename.
647:      *
648:      * @return string  The full native filename.
649:      */
650:     protected function _getNativePath($path = '', $name = '')
651:     {
652:         $name = basename($name);
653:         if (strlen($name)) {
654:             if ($name == '..') {
655:                 $name = '';
656:             }
657:             if (substr($name, 0, 1) != '/') {
658:                 $name = '/' . $name;
659:             }
660:         }
661: 
662:         if (strlen($path)) {
663:             if (isset($this->_params['home']) &&
664:                 preg_match('|^~/?(.*)$|', $path, $matches)) {
665:                 $path = $this->_params['home'] . '/' . $matches[1];
666:             }
667: 
668:             $path = str_replace('..', '', $path);
669:             if (substr($path, 0, 1) == '/') {
670:                 return $this->_params['vfsroot'] . $path . $name;
671:             } else {
672:                 return $this->_params['vfsroot'] . '/' . $path . $name;
673:             }
674:         }
675: 
676:         return $this->_params['vfsroot'] . $name;
677:     }
678: 
679:     /**
680:      * Make sure that the vfsroot is readable.
681:      *
682:      * @throws Horde_Vfs_Exception
683:      */
684:     protected function _connect()
685:     {
686:         if (!@is_dir($this->_params['vfsroot'])) {
687:             @mkdir($this->_params['vfsroot']);
688:         }
689: 
690:         if (!is_readable($this->_params['vfsroot'])) {
691:             throw new Horde_Vfs_Exception('Unable to read the vfsroot directory.');
692:         }
693:     }
694: 
695: }
696: 
API documentation generated by ApiGen