Overview

Packages

  • Gollem
  • None

Classes

  • Gollem
  • Gollem_Ajax_Application
  • Gollem_Api
  • Gollem_Auth
  • Gollem_Exception
  • Gollem_Factory_Vfs
  • Gollem_Factory_VfsDefault
  • Gollem_LoginTasks_SystemTask_Upgrade
  • Gollem_Test
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * Gollem base library.
  4:  *
  5:  * Copyright 1999-2012 Horde LLC (http://www.horde.org/)
  6:  *
  7:  * See the enclosed file COPYING for license information (GPL). If you
  8:  * did not receive this file, see http://www.horde.org/licenses/gpl.
  9:  *
 10:  * @author   Max Kalika <max@horde.org>
 11:  * @author   Chuck Hagenbuch <chuck@horde.org>
 12:  * @author   Michael Slusarz <slusarz@horde.org>
 13:  * @category Horde
 14:  * @license  http://www.horde.org/licenses/gpl GPL
 15:  * @package  Gollem
 16:  */
 17: class Gollem
 18: {
 19:     /* Sort constants. */
 20:     const SORT_TYPE = 0;
 21:     const SORT_NAME = 1;
 22:     const SORT_DATE = 2;
 23:     const SORT_SIZE = 3;
 24: 
 25:     const SORT_ASCEND = 0;
 26:     const SORT_DESCEND = 1;
 27: 
 28:     /**
 29:      * Configuration hash for the current backend.
 30:      *
 31:      * @var array
 32:      */
 33:     static public $backend;
 34: 
 35:     /**
 36:      * Changes the current directory of the Gollem session to the supplied
 37:      * value.
 38:      *
 39:      * @param string $dir  Directory name.
 40:      *
 41:      * @throws Gollem_Exception
 42:      */
 43:     static public function setDir($dir)
 44:     {
 45:         $dir = Horde_Util::realPath($dir);
 46: 
 47:         if (!self::verifyDir($dir)) {
 48:             throw new Gollem_Exception(sprintf(_("Access denied to folder \"%s\"."), $dir));
 49:         }
 50:         self::$backend['dir'] = $dir;
 51: 
 52:         self::_setLabel();
 53:     }
 54: 
 55:     /**
 56:      * Changes the current directory of the Gollem session based on the
 57:      * 'dir' form field.
 58:      *
 59:      * @throws Gollem_Exception
 60:      */
 61:     static public function changeDir()
 62:     {
 63:         $dir = Horde_Util::getFormData('dir');
 64:         if (is_null($dir)) {
 65:             self::_setLabel();
 66:         } else {
 67:             if (strpos($dir, '/') !== 0) {
 68:                 $dir = self::$backend['dir'] . '/' . $dir;
 69:             }
 70:             self::setDir($dir);
 71:         }
 72:     }
 73: 
 74:     /**
 75:      * Set the lable to use for the current page.
 76:      */
 77:     static protected function _setLabel()
 78:     {
 79:         self::$backend['label'] = self::getDisplayPath(self::$backend['dir']);
 80:         if (empty(self::$backend['label'])) {
 81:             self::$backend['label'] = '/';
 82:         }
 83:     }
 84: 
 85:     /**
 86:      * Internal helper to sort directories first if pref set.
 87:      */
 88:     static protected function _sortDirs($a, $b)
 89:     {
 90:         /* Sort symlinks to dirs as dirs */
 91:         $dira = ($a['type'] === '**dir') ||
 92:             (($a['type'] === '**sym') && ($a['linktype'] === '**dir'));
 93:         $dirb = ($b['type'] === '**dir') ||
 94:             (($b['type'] === '**sym') && ($b['linktype'] === '**dir'));
 95: 
 96:         if ($GLOBALS['prefs']->getValue('sortdirsfirst')) {
 97:             if ($dira && !$dirb) {
 98:                 return -1;
 99:             } elseif (!$dira && $dirb) {
100:                 return 1;
101:             }
102:         }
103:         return 0;
104:     }
105: 
106:     /**
107:      * Internal sorting function for 'date'.
108:      */
109:     static public function sortDate($a, $b)
110:     {
111:         $dirs = self::_sortDirs($a, $b);
112:         if ($dirs) {
113:             return $dirs;
114:         }
115: 
116:         if ($a['date'] > $b['date']) {
117:             return $GLOBALS['prefs']->getValue('sortdir') ? -1 : 1;
118:         } elseif ($a['date'] === $b['date']) {
119:             return self::sortName($a, $b);
120:         } else {
121:             return $GLOBALS['prefs']->getValue('sortdir') ? 1 : -1;
122:         }
123:     }
124: 
125:     /**
126:      * Internal sorting function for 'size'.
127:      */
128:     static public function sortSize($a, $b)
129:     {
130:         $dirs = self::_sortDirs($a, $b);
131:         if ($dirs) {
132:             return $dirs;
133:         }
134: 
135:         if ($a['size'] > $b['size']) {
136:             return $GLOBALS['prefs']->getValue('sortdir') ? -1 : 1;
137:         } elseif ($a['size'] === $b['size']) {
138:             return 0;
139:         } else {
140:             return $GLOBALS['prefs']->getValue('sortdir') ? 1 : -1;
141:         }
142:     }
143: 
144:     /**
145:      * Internal sorting function for 'type'.
146:      */
147:     static public function sortType($a, $b)
148:     {
149:         $dirs = self::_sortDirs($a, $b);
150:         if ($dirs) {
151:             return $dirs;
152:         }
153: 
154:         if ($a['type'] === $b['type']) {
155:             return self::sortName($a, $b);
156:         } elseif ($a['type'] === '**dir') {
157:             return $GLOBALS['prefs']->getValue('sortdir') ? 1 : -1;
158:         } elseif ($b['type'] === '**dir') {
159:             return $GLOBALS['prefs']->getValue('sortdir') ? -1 : 1;
160:         } else {
161:             $res = strcasecmp($a['type'], $b['type']);
162:             return $GLOBALS['prefs']->getValue('sortdir') ? ($res * -1) : $res;
163:         }
164:     }
165: 
166:     /**
167:      * Internal sorting function for 'name'.
168:      */
169:     static public function sortName($a, $b)
170:     {
171:         $dirs = self::_sortDirs($a, $b);
172:         if ($dirs) {
173:             return $dirs;
174:         }
175: 
176:         $res = strcasecmp($a['name'], $b['name']);
177:         return $GLOBALS['prefs']->getValue('sortdir') ? ($res * -1) : $res;
178:     }
179: 
180:     /**
181:      * List the current folder.
182:      *
183:      * @param string $dir  The directory name.
184:      *
185:      * @return array  The sorted list of files.
186:      * @throws Gollem_Exception
187:      */
188:     static public function listFolder($dir)
189:     {
190:         global $conf;
191: 
192:         if (!empty($conf['foldercache']['use_cache']) &&
193:             !empty($conf['cache']['driver']) &&
194:             ($conf['cache']['driver'] != 'none')) {
195:             $key = self::_getCacheID($dir);
196: 
197:             $cache = $GLOBALS['injector']->getInstance('Horde_Cache');
198:             $res = $cache->get($key, $conf['foldercache']['lifetime']);
199:             if ($res !== false) {
200:                 $res = Horde_Serialize::unserialize($res, Horde_Serialize::BASIC);
201:                 if (is_array($res)) {
202:                     return $res;
203:                 }
204:             }
205:         }
206: 
207:         try {
208:             $files = $GLOBALS['injector']
209:                 ->getInstance('Gollem_Vfs')
210:                 ->listFolder($dir,
211:                              isset(self::$backend['filter']) ? self::$backend['filter'] : null,
212:                              $GLOBALS['prefs']->getValue('show_dotfiles'));
213:         } catch (Horde_Vfs_Exception $e) {
214:             throw new Gollem_Exception($e);
215:         }
216:         $sortcols = array(
217:             self::SORT_TYPE => 'sortType',
218:             self::SORT_NAME => 'sortName',
219:             self::SORT_DATE => 'sortDate',
220:             self::SORT_SIZE => 'sortSize',
221:         );
222:         usort($files, array('Gollem', $sortcols[$GLOBALS['prefs']->getValue('sortby')]));
223: 
224:         if (isset($cache)) {
225:             $cache->set($key, Horde_Serialize::serialize($files, Horde_Serialize::BASIC), $conf['foldercache']['lifetime']);
226:         }
227: 
228:         return $files;
229:     }
230: 
231:     /**
232:      * Generate the Cache ID for a directory.
233:      *
234:      * @param string $dir  The directory name.
235:      */
236:     static protected function _getCacheID($dir)
237:     {
238:         return implode('|', array($GLOBALS['registry']->getAuth(),
239:                                   $GLOBALS['session']->get('gollem', 'backend_key'),
240:                                   $GLOBALS['prefs']->getValue('show_dotfiles'),
241:                                   $GLOBALS['prefs']->getValue('sortdirsfirst'),
242:                                   $GLOBALS['prefs']->getValue('sortby'),
243:                                   $GLOBALS['prefs']->getValue('sortdir'),
244:                                   $dir));
245:     }
246: 
247:     /**
248:      * Expire a folder cache entry.
249:      *
250:      * @param string $dir  The directory name.
251:      */
252:     static public function expireCache($dir)
253:     {
254:         global $conf;
255: 
256:         if (!empty($conf['foldercache']['use_cache']) &&
257:             !empty($conf['cache']['driver']) &&
258:             ($conf['cache']['driver'] != 'none')) {
259:             $cache = $GLOBALS['injector']->getInstance('Horde_Cache');
260:             $cache->expire(self::_getCacheID($dir));
261:         }
262:     }
263: 
264:     /**
265:      * Generate correct subdirectory links.
266:      *
267:      * @param string $base  The base directory.
268:      * @param string $dir   The directory string.
269:      *
270:      * @return string  The correct subdirectoy string.
271:      */
272:     static public function subdirectory($base, $dir)
273:     {
274:         if (empty($base)) {
275:             return $dir;
276:         }
277: 
278:         if (substr($base, -1) == '/') {
279:             return $base . $dir;
280:         }
281: 
282:         return $base . '/' . $dir;
283:     }
284: 
285:     /**
286:      * Create a folder using the current Gollem session settings.
287:      *
288:      * @param string $dir                 The directory path.
289:      * @param string $name                The folder to create.
290:      * @param Horde_Vfs_Base $gollem_vfs  A VFS instance to use.
291:      *
292:      * @throws Gollem_Exception
293:      * @throws Horde_Vfs_Exception
294:      */
295:     static public function createFolder($dir, $name, $gollem_vfs = null)
296:     {
297:         $totalpath = Horde_Util::realPath($dir . '/' . $name);
298:         if (!self::verifyDir($totalpath)) {
299:             throw new Gollem_Exception(sprintf(_("Access denied to folder \"%s\"."), $totalpath));
300:         }
301: 
302:         /* The $name parameter may contain additional directories so we
303:          * need to pass autocreatePath everything but the base filename. */
304:         $pos = strrpos($totalpath, '/');
305:         $dir = substr($totalpath, 0, $pos);
306:         $name = substr($totalpath, $pos + 1);
307: 
308:         if (!$gollem_vfs) {
309:             $gollem_vfs = $GLOBALS['injector']->getInstance('Gollem_Vfs');
310:         }
311:         $gollem_vfs->autocreatePath($dir);
312:         $gollem_vfs->createFolder($dir, $name);
313: 
314:         if (!empty(self::$backend['params']['permissions'])) {
315:             $gollem_vfs->changePermissions($dir, $name, self::$backend['params']['permissions']);
316:         }
317:     }
318: 
319:     /**
320:      * Rename files using the current Gollem session settings.
321:      *
322:      * @param string $oldDir  Old directory name.
323:      * @param string $old     Old file name.
324:      * @param string $newDir  New directory name.
325:      * @param string $old     New file name.
326:      *
327:      * @throws Horde_Vfs_Exception
328:      */
329:     static public function renameItem($oldDir, $old, $newDir, $new)
330:     {
331:         $GLOBALS['injector']
332:             ->getInstance('Gollem_Vfs')
333:             ->rename($oldDir, $old, $newDir, $new);
334:     }
335: 
336:     /**
337:      * Delete a folder using the current Gollem session settings.
338:      *
339:      * @param string $dir   The subdirectory name.
340:      * @param string $name  The folder name to delete.
341:      *
342:      * @throws Gollem_Exception
343:      * @throws Horde_Vfs_Exception
344:      */
345:     static public function deleteFolder($dir, $name)
346:     {
347:         if (!self::verifyDir($dir)) {
348:             throw new Gollem_Exception(sprintf(_("Access denied to folder \"%s\"."), $dir));
349:         }
350: 
351:         $GLOBALS['injector']
352:             ->getInstance('Gollem_Vfs')
353:             ->deleteFolder($dir,
354:                            $name,
355:                            $GLOBALS['prefs']->getValue('recursive_deletes') != 'disabled');
356:     }
357: 
358:     /**
359:      * Delete a file using the current Gollem session settings.
360:      *
361:      * @param string $dir   The directory name.
362:      * @param string $name  The filename to delete.
363:      *
364:      * @throws Gollem_Exception
365:      * @throws Horde_Vfs_Exception
366:      */
367:     static public function deleteFile($dir, $name)
368:     {
369:         if (!self::verifyDir($dir)) {
370:             throw new Gollem_Exception(sprintf(_("Access denied to folder \"%s\"."), $dir));
371:         }
372:         $GLOBALS['injector']
373:             ->getInstance('Gollem_Vfs')
374:             ->deleteFile($dir, $name);
375:     }
376: 
377:     /**
378:      * Change permissions on files using the current Gollem session settings.
379:      *
380:      * @param string $dir         The directory name.
381:      * @param string $name        The filename to change permissions on.
382:      * @param string $permission  The permission mode to set.
383:      *
384:      * @throws Gollem_Exception
385:      * @throws Horde_Vfs_Exception
386:      */
387:     static public function changePermissions($dir, $name, $permission)
388:     {
389:         if (!self::verifyDir($dir)) {
390:             throw new Gollem_Exception(sprintf(_("Access denied to folder \"%s\"."), $dir));
391:         }
392:         $GLOBALS['injector']
393:             ->getInstance('Gollem_Vfs')
394:             ->changePermissions($dir, $name, $permission);
395:     }
396: 
397:     /**
398:      * Write an uploaded file to the VFS backend.
399:      *
400:      * @param string $dir       The directory name.
401:      * @param string $name      The filename to create.
402:      * @param string $filename  The local file containing the file data.
403:      *
404:      * @thows Horde_Vfs_Exception
405:      */
406:     static public function writeFile($dir, $name, $filename)
407:     {
408:         $gollem_vfs = $GLOBALS['injector']->getInstance('Gollem_Vfs');
409:         $gollem_vfs->write($dir, $name, $filename, true);
410:         if (!empty(self::$backend['params']['permissions'])) {
411:             $gollem_vfs->changePermissions($dir, $name, self::$backend['params']['permissions']);
412:         }
413:     }
414: 
415:     /**
416:      * Moves a file using the current Gollem session settings.
417:      *
418:      * @param string $backend_f The backend to move the file from.
419:      * @param string $dir       The directory name of the original file.
420:      * @param string $name      The original filename.
421:      * @param string $backend_t The backend to move the file to.
422:      * @param string $newdir    The directory to move the file to.
423:      *
424:      * @throws Horde_Vfs_Exception
425:      */
426:     static public function moveFile($backend_f, $dir, $name, $backend_t,
427:                                     $newdir)
428:     {
429:         self::_copyFile('move', $backend_f, $dir, $name, $backend_t, $newdir);
430:     }
431: 
432:     /**
433:      * Copies a file using the current Gollem session settings.
434:      *
435:      * @param string $backend_f The backend to copy the file from.
436:      * @param string $dir       The directory name of the original file.
437:      * @param string $name      The original filename.
438:      * @param string $backend_t The backend to copy the file to.
439:      * @param string $newdir    The directory to copy the file to.
440:      *
441:      * @throws Horde_Vfs_Exception
442:      */
443:     static public function copyFile($backend_f, $dir, $name, $backend_t,
444:                                     $newdir)
445:     {
446:         self::_copyFile('copy', $backend_f, $dir, $name, $backend_t, $newdir);
447:     }
448: 
449:     /**
450:      * Private function that copies/moves files.
451:      *
452:      * @throws Horde_Vfs_Exception
453:      */
454:     static protected function _copyFile($mode, $backend_f, $dir, $name,
455:                                         $backend_t, $newdir)
456:     {
457:         $backend_key = $GLOBALS['session']->get('gollem', 'backend_key');
458: 
459:         /* If the from/to backends are the same, we can just use the built-in
460:          * VFS functions. */
461:         if ($backend_f == $backend_t) {
462:             $ob = $GLOBALS['injector']->getInstance('Gollem_Factory_Vfs')->create($backend_f);
463:             if ($backend_f != $backend_key) {
464:                 $ob->checkCredentials();
465:             }
466:             return $mode == 'copy'
467:                 ? $ob->copy($dir, $name, $newdir)
468:                 : $ob->move($dir, $name, $newdir);
469:         }
470: 
471:         /* Else, get the two VFS objects and copy/move the files. */
472:         $from_be = $GLOBALS['injector']->getInstance('Gollem_Factory_Vfs')->create($backend_f);
473:         if ($backend_f != $backend_key) {
474:             $from_be->checkCredentials();
475:         }
476: 
477:         $to_be = $GLOBALS['injector']->getInstance('Gollem_Factory_Vfs')->create($backend_t);
478:         if ($backend_t != $backend_key) {
479:             $to_be->checkCredentials();
480:         }
481: 
482:         /* Read the source data. */
483:         $data = $from_be->read($dir, $name);
484: 
485:         /* Write the target data. */
486:         $to_be->writeData($newdir, $name, $data);
487: 
488:         /* If moving, delete the source data. */
489:         if ($mode == 'move') {
490:             $from_be->deleteFile($dir, $name);
491:         }
492:     }
493: 
494:     /**
495:      * This function verifies whether a given directory is below the root.
496:      *
497:      * @param string $dir  The directory to check.
498:      *
499:      * @return boolean  True if the directory is below the root.
500:      */
501:     static public function verifyDir($dir)
502:     {
503:         return Horde_String::substr(Horde_Util::realPath($dir), 0, Horde_String::length(self::$backend['root'])) == self::$backend['root'];
504:     }
505: 
506:     /**
507:      * Checks if a user has the specified permissions on the selected backend.
508:      *
509:      * @param string $filter       What are we checking for.
510:      * @param integer $permission  What permission to check for.
511:      * @param string $backend      The backend to check.  If empty, check
512:      *                             the current backend.
513:      *
514:      * @return boolean  Returns true if the user has permission, false if
515:      *                  they do not.
516:      */
517:     static public function checkPermissions($filter,
518:                                             $permission = Horde_Perms::READ,
519:                                             $backend = null)
520:     {
521:         $userID = $GLOBALS['registry']->getAuth();
522:         if (is_null($backend)) {
523:             $backend = $GLOBALS['session']->get('gollem', 'backend_key');
524:         }
525: 
526:         switch ($filter) {
527:         case 'backend':
528:             $backendTag = 'gollem:backends:' . $backend;
529:             return (!$GLOBALS['injector']->getInstance('Horde_Perms')->exists($backendTag) ||
530:                     $GLOBALS['injector']->getInstance('Horde_Perms')->hasPermission($backendTag, $userID, $permission));
531:         }
532: 
533:         return false;
534:     }
535: 
536:     /**
537:      * Produces a directory link used for navigation.
538:      *
539:      * @param string $currdir  The current directory string.
540:      * @param string $url      The URL to link to.
541:      *
542:      * @return string  The directory navigation string.
543:      */
544:     static public function directoryNavLink($currdir, $url)
545:     {
546:         $label = array();
547:         $root_dir_name = self::$backend['name'];
548: 
549:         if ($currdir == $root_dir_name) {
550:             $label[] = '[' . $root_dir_name . ']';
551:         } else {
552:             $parts = explode('/', $currdir);
553:             $parts_count = count($parts);
554: 
555:             $url = new Horde_Url($url);
556:             $label[] = Horde::link($url->add('dir', self::$backend['root']), sprintf(_("Up to %s"), $root_dir_name)) . '[' . $root_dir_name . ']</a>';
557: 
558:             for ($i = 1; $i <= $parts_count; ++$i) {
559:                 $part = array_slice($parts, 0, $i);
560:                 $dir = implode('/', $part);
561:                 if ((strstr($dir, self::$backend['root']) !== false) &&
562:                     (self::$backend['root'] != $dir)) {
563:                     if ($i == $parts_count) {
564:                         $label[] = $parts[($i - 1)];
565:                     } else {
566:                         $label[] = Horde::link($url->add('dir', $dir), sprintf(_("Up to %s"), $dir)) . $parts[($i - 1)] . '</a>';
567:                     }
568:                 }
569:             }
570:         }
571: 
572:         return implode('/', $label);
573:     }
574: 
575:     /**
576:      * Build Gollem's menu.
577:      *
578:      * @return string  Menu.
579:      */
580:     static public function menu()
581:     {
582:         $t = $GLOBALS['injector']->createInstance('Horde_Template');
583: 
584:         $t->set('login_url', Horde::getServiceLink('login', 'horde'));
585:         $t->set('forminput', Horde_Util::formInput());
586:         $t->set('hidden', array(array('key' => 'url', 'value' => (string)Horde::url('manager.php', true)),
587:                                 array('key' => 'app', 'value' => 'gollem')));
588:         $t->set('be_select', self::backendSelect(), true);
589:         if ($t->get('be_select')) {
590:             $t->set('accesskey', $GLOBALS['prefs']->getValue('widget_accesskey') ? Horde::getAccessKey(_("_Change Server")) : '');
591:             $menu_view = $GLOBALS['prefs']->getValue('menu_view');
592:             $link = Horde::link('#', _("Change Server"), '', '', 'serverSubmit(true);return false;');
593:             $t->set('slink', sprintf('<ul><li>%s%s<br />%s</a></li></ul>', $link, ($menu_view != 'text') ? Horde::img('gollem.png') : '', ($menu_view != 'icon') ? Horde::highlightAccessKey(_("_Change Server"), $t->get('accesskey')) : ''));
594:         }
595:         $t->set('menu_string', Horde::menu(array('menu_ob' => true))->render());
596: 
597:         $menu = $t->fetch(GOLLEM_TEMPLATES . '/menu.html');
598: 
599:         /* Need to buffer sidebar output here, because it may add things like
600:          * cookies which need to be sent before output begins. */
601:         Horde::startBuffer();
602:         require HORDE_BASE . '/services/sidebar.php';
603:         return $menu .= Horde::endBuffer();
604:     }
605: 
606:     /**
607:      * Outputs Gollem's status/notification bar.
608:      */
609:     static public function status()
610:     {
611:         $GLOBALS['notification']->notify(array('listeners' => 'status'));
612:     }
613: 
614:     /**
615:      * Generate the backend selection list for use in the menu.
616:      *
617:      * @return string  The backend selection list.
618:      */
619:     static public function backendSelect()
620:     {
621:         $backends = Gollem_Auth::getBackend();
622:         $backend = Gollem_Auth::getPreferredBackend();
623:         $text = '';
624: 
625:         if ($GLOBALS['conf']['backend']['backend_list'] == 'shown' &&
626:             count($backends) > 1) {
627:             foreach ($backends as $key => $val) {
628:                 $sel = ($backend == $key) ? ' selected="selected"' : '';
629:                 $text .= sprintf('<option value="%s"%s>%s</option>%s',
630:                                  empty($sel) ? $key : '',
631:                                  $sel,
632:                                  $val['name'],
633:                                  "\n");
634:             }
635:         }
636: 
637:         return $text;
638:     }
639: 
640:     /**
641:      * Generate the display path (the path with any root information stripped
642:      * out).
643:      *
644:      * @param string $path  The path to display.
645:      *
646:      * @return string  The display path.
647:      */
648:     static public function getDisplayPath($path)
649:     {
650:         $path = Horde_Util::realPath($path);
651:         if (self::$backend['root'] != '/' &&
652:             strpos($path, self::$backend['root']) === 0) {
653:             $path = substr($path, Horde_String::length(self::$backend['root']));
654:         }
655:         return $path;
656:     }
657: 
658:     /**
659:      * Cleans a path presented to Gollem's browse API call.
660:      *
661:      * This will remove:
662:      * - leading '/'
663:      * - leading 'gollem'
664:      * - trailing '/'
665:      * The desired end result is the path including VFS backend.
666:      *
667:      * @param string $path  Path as presented to Gollem API.
668:      *
669:      * @return string  Cleaned path as described above.
670:      */
671:     static public function stripAPIPath($path)
672:     {
673:         // Strip leading '/'
674:         if (substr($path, 0, 1) == '/') {
675:             $path = substr($path, 1);
676:         }
677:         // Remove 'gollem' from path
678:         if (substr($path, 0, 6) == 'gollem') {
679:             $path = substr($path, 6);
680:         }
681:         // Remove leading '/'
682:         if (substr($path, 0, 1) == '/') {
683:             $path = substr($path, 1);
684:         }
685:         // Remove trailing '/'
686:         if (substr($path, -1) == '/') {
687:             $path = substr($path, 0, -1);
688:         }
689:         return $path;
690:     }
691: 
692:     /**
693:      * Convert a Gollem path into a URL encoded string, but keep '/'.
694:      * This allows for proper PATH_INFO path parsing.
695:      * Special care is taken to handle "+" and " ".
696:      *
697:      * @param string $path  Path to be urlencode()d.
698:      *
699:      * @return string  URL-encoded string with '/' preserved.
700:      */
701:     static public function pathEncode($path)
702:     {
703:         return str_ireplace(array('%2F', '%2f'), '/', rawurlencode($path));
704:     }
705: 
706:     /**
707:      * Take a fully qualified and break off the file or directory name.
708:      * This pair is used for the input to many VFS library functions.
709:      *
710:      * @param string $fullpath   Path to be split.
711:      *
712:      * @return array  Array of ($path, $name)
713:      */
714:     static public function getVFSPath($fullpath)
715:     {
716:         // Convert the path into VFS's ($path, $name) convention
717:         $i = strrpos($fullpath, '/');
718:         if ($i !== false) {
719:             $path = substr($fullpath, 0, $i);
720:             $name = substr($fullpath, $i + 1);
721:         } else {
722:             $name = $fullpath;
723:             $path = '';
724:         }
725:         return array($name, $path);
726:     }
727: }
728: 
API documentation generated by ApiGen