[ Index ]
 

Code source de eGroupWare 1.2.106-2

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/phpgwapi/inc/ -> class.vfs.inc.php (source)

   1  <?php
   2      /**************************************************************************\
   3      * eGroupWare API - VFS base class                                          *
   4      * This file written by Jason Wies (Zone) <zone@phpgroupware.org>           *
   5      * This class handles file/dir access for eGroupWare                        *
   6      * Copyright (C) 2001 Jason Wies                                     *
   7      * -------------------------------------------------------------------------*
   8      * This library is part of the eGroupWare API                               *
   9      * http://www.egroupware.org/api                                            * 
  10      * ------------------------------------------------------------------------ *
  11      * This library is free software; you can redistribute it and/or modify it  *
  12      * under the terms of the GNU Lesser General Public License as published by *
  13      * the Free Software Foundation; either version 2.1 of the License,         *
  14      * or any later version.                                                    *
  15      * This library is distributed in the hope that it will be useful, but      *
  16      * WITHOUT ANY WARRANTY; without even the implied warranty of               *
  17      * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                     *
  18      * See the GNU Lesser General Public License for more details.              *
  19      * You should have received a copy of the GNU Lesser General Public License *
  20      * along with this library; if not, write to the Free Software Foundation,  *
  21      * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA            *
  22      \**************************************************************************/
  23  
  24      /* $Id: class.vfs.inc.php 20295 2006-02-15 12:31:25Z  $ */
  25  
  26      if (empty ($GLOBALS['egw_info']['server']['file_repository']))
  27      {
  28          $GLOBALS['egw_info']['server']['file_repository'] = 'sql';
  29      }
  30  
  31      /* Relative defines.  Used mainly by getabsolutepath () */
  32      define ('RELATIVE_ROOT', 1);
  33      define ('RELATIVE_USER', 2);
  34      define ('RELATIVE_CURR_USER', 4);
  35      define ('RELATIVE_USER_APP', 8);
  36      define ('RELATIVE_PATH', 16);
  37      define ('RELATIVE_NONE', 32);
  38      define ('RELATIVE_CURRENT', 64);
  39      define ('VFS_REAL', 1024);
  40      define ('RELATIVE_ALL', RELATIVE_PATH);
  41  
  42      /* These are used in calls to add_journal (), and allow journal messages to be more standard */
  43      define ('VFS_OPERATION_CREATED', 1);
  44      define ('VFS_OPERATION_EDITED', 2);
  45      define ('VFS_OPERATION_EDITED_COMMENT', 4);
  46      define ('VFS_OPERATION_COPIED', 8);
  47      define ('VFS_OPERATION_MOVED', 16);
  48      define ('VFS_OPERATION_DELETED', 32);
  49  
  50      /**
  51       *  * helper class for path_parts
  52       *  *
  53        */
  54      class path_class
  55      {
  56          var $mask;
  57          var $outside;
  58          var $fake_full_path;
  59          var $fake_leading_dirs;
  60          var $fake_extra_path;
  61          var $fake_name;
  62          var $real_full_path;
  63          var $real_leading_dirs;
  64          var $real_extra_path;
  65          var $real_name;
  66          var $fake_full_path_clean;
  67          var $fake_leading_dirs_clean;
  68          var $fake_extra_path_clean;
  69          var $fake_name_clean;
  70          var $real_full_path_clean;
  71          var $real_leading_dirs_clean;
  72          var $real_extra_path_clean;
  73          var $real_name_clean;
  74      }
  75  
  76      /**
  77       *  * Base class for Virtual File System classes
  78       *  *
  79       *  * @author Zone
  80        */
  81      class vfs_shared
  82      {
  83          /*
  84           * All VFS classes must have some form of 'linked directories'.
  85           * Linked directories allow an otherwise disparate "real" directory
  86           * to be linked into the "virtual" filesystem.  See make_link().
  87           */
  88          var $linked_dirs = array ();
  89  
  90          /*
  91           * All VFS classes need to support the access control in some form
  92           * (see acl_check()).  There are times when applications will need
  93           * to explictly disable access checking, for example when creating a
  94           * user's home directory for the first time or when the admin is
  95           * performing maintanence.  When override_acl is set, any access
  96           * checks must return True.
  97           */
  98          var $override_acl = 0;
  99  
 100          /*
 101           * The current relativity.  See set_relative() and get_relative().
 102           */
 103          var $relative;
 104  
 105          /*
 106           * Implementation dependant 'base real directory'.  It is not required
 107           * that derived classes use $basedir, but some of the shared functions
 108           * below rely on it, so those functions will need to be overload if
 109           * basedir isn't appropriate for a particular backend.
 110           */
 111          var $basedir;
 112  
 113          /*
 114           * Fake base directory.  Only the administrator should change this.
 115           */
 116          var $fakebase = '/home';
 117  
 118          /*
 119           * All derived classes must store certain information about each
 120           * location.  The attributes in the 'attributes' array represent
 121           * the minimum attributes that must be stored.  Derived classes
 122           * should add to this array any custom attributes.
 123           *
 124           * Not all of the attributes below are appropriate for all backends.
 125           * Those that don't apply can be replaced by dummy values, ie. '' or 0.
 126           */
 127          var $attributes = array(
 128              'file_id',    /* Integer.  Unique to each location */
 129              'owner_id',    /* phpGW account_id of owner */
 130              'createdby_id', /* phpGW account_id of creator */
 131              'modifiedby_id',/* phpGW account_id of who last modified */
 132              'created',    /* Datetime created, in SQL format */
 133              'modified',    /* Datetime last modified, in SQL format */
 134              'size',        /* Size in bytes */
 135              'mime_type',    /* Mime type.  'Directory' for directories */
 136              'comment',    /* User-supplied comment.  Can be empty */
 137              'app',        /* Name of phpGW application responsible for location */
 138              'directory',    /* Directory location is in */
 139              'name',        /* Name of file/directory */
 140              'link_directory',    /* Directory location is linked to, if any */
 141              'link_name',        /* Name location is linked to, if any */
 142              'version',    /* Version of file.  May be 0 */
 143          );
 144  
 145          /**
 146           *  * constructor
 147           *  *
 148           *  * All derived classes should call this function in their
 149           *        constructor ($this->vfs_shared())
 150            */
 151  		function vfs_shared ()
 152          {
 153          }
 154  
 155          /*
 156           * Definitions for functions that every derived
 157           * class must have, and suggestions for private functions
 158           * to completement the public ones.  The prototypes for
 159           * the public functions need to be uniform for all
 160           * classes.  Of course, each derived class should overload these
 161           * functions with their own version.
 162           */
 163  
 164          /*
 165           * Journal functions.
 166           *
 167           * See also: VFS_OPERATION_* defines
 168           *
 169           * Overview:
 170           * Each action performed on a location
 171           * should be recorded, in both machine and human
 172           * readable format.
 173           *
 174           * PRIVATE functions (suggested examples only, not mandatory):
 175           *
 176           * add_journal - Add journal entry
 177           * flush_journal - Clear all journal entries for a location
 178           *
 179           * PUBLIC functions (mandatory):
 180           *
 181           * get_journal - Get journal entries for a location
 182           */
 183  
 184          /* Private, suggestions only */
 185  		function add_journal ($data) {}
 186  		function flush_journal ($data) {}
 187  
 188          /**
 189           *  * Get journal entries for a location
 190           *  *
 191           *  * string    Path to location
 192           *  * relatives    Relativity array (default: RELATIVE_CURRENT)
 193           *  * type    [0|1|2]
 194           *                0 = any journal entries
 195           *                1 = current journal entries
 196           *                2 = deleted journal entries
 197           *  * @return Array of arrays of journal entries
 198           *       The keys will vary depending on the implementation,
 199           *       with most attributes in this->attributes being valid,
 200           *       and these keys being mandatory:
 201           *        created - Datetime in SQL format that journal entry
 202           *              was entered
 203           *        comment - Human readable comment describing the action
 204           *        version - May be 0 if the derived class does not support
 205           *              versioning
 206            */
 207  		function get_journal ($data) { return array(array()); }
 208  
 209          /*
 210           * Access checking functions.
 211           *
 212           * Overview:
 213           * Each derived class should have some kind of
 214           * user and group access control.  This will
 215           * usually be based directly on the ACL class.
 216           *
 217           * If $this->override_acl is set, acl_check()
 218           * must always return True.
 219           *
 220           * PUBLIC functions (mandatory):
 221           *
 222           * acl_check() - Check access for a user to a given
 223           */
 224  
 225          /**
 226           *  * Check access for a user to a given location
 227           *  *
 228           *  * If $this->override_acl is set, always return True
 229           *  * string    Path to location
 230           *  * relatives    Relativity array (default: RELATIVE_CURRENT)
 231           *  * operation    Operation to check access for.  Any combination
 232           *            of the EGW_ACL_* defines, for example:
 233           *            EGW_ACL_READ
 234           *            EGW_ACL_READ|EGW_ACL_WRITE
 235           *  * owner_id    phpGW ID to check access for.
 236           *  *             Default: $GLOBALS['egw_info']['user']['account_id']
 237           *  * must_exist    If set, string must exist, and acl_check() must
 238           *            return False if it doesn't.  If must_exist isn't
 239           *            passed, and string doesn't exist, check the owner_id's
 240           *            access to the parent directory, if it exists.
 241           *  * @return Boolean.  True if access is ok, False otherwise.
 242            */
 243  		function acl_check ($data) { return True; }
 244  
 245          /*
 246           * Operations functions.
 247           *
 248           * Overview:
 249           * These functions perform basic file operations.
 250           *
 251           * PUBLIC functions (mandatory):
 252           *
 253           * read - Retreive file contents
 254           *
 255           * write - Store file contents
 256           *
 257           * touch - Create a file if it doesn't exist.
 258           *       Optionally, update the modified time and
 259           *       modified user if the file exists.
 260           *
 261           * cp - Copy location
 262           *
 263           * mv - Move location
 264           *
 265           * rm - Delete location
 266           *
 267           * mkdir - Create directory
 268           */
 269  
 270          /**
 271           *  * Retreive file contents
 272           *  *
 273           *  * string    Path to location
 274           *  * relatives    Relativity array (default: RELATIVE_CURRENT)
 275           *  * @return String.  Contents of 'string', or False on error.
 276            */
 277  		function read ($data) { return False; }
 278  
 279           /**
 280           * Views the specified file (does not return!)
 281           *
 282           * @param string filename
 283           * @param relatives Relativity array
 284           * @return None (doesnt return)
 285           * By default this function just reads the file and
 286           * outputs it too the browser, after setting the content-type header 
 287           * appropriately.  For some other VFS implementations though, there
 288           * may be some more sensible way of viewing the file.
 289           */
 290  		 function view($data)
 291           {
 292               
 293               $default_values = array
 294                   (
 295                      'relatives'    => array (RELATIVE_CURRENT)
 296                  );
 297              $data = array_merge ($this->default_values ($data, $default_values), $data);
 298   
 299              $GLOBALS['egw_info']['flags']['noheader'] = true;
 300              $GLOBALS['egw_info']['flags']['nonavbar'] = true;
 301              $GLOBALS['egw_info']['flags']['noappheader'] = true;
 302              $GLOBALS['egw_info']['flags']['noappfooter'] = true;
 303              $ls_array = $this->ls (array (
 304                      'string'    =>  $data['string'],
 305                      'relatives'    => $data['relatives'],
 306                      'checksubdirs'    => False,
 307                      'nofiles'    => True
 308                  )
 309              );
 310          
 311              if ($ls_array[0]['mime_type'])
 312              {
 313                  $mime_type = $ls_array[0]['mime_type'];
 314              }
 315              elseif ($GLOBALS['settings']['viewtextplain'])
 316              {
 317                  $mime_type = 'text/plain';
 318              }
 319          
 320              header('Content-type: ' . $mime_type);
 321              echo $this->read (array (
 322                      'string'    =>  $data['string'],
 323                      'relatives'    => $data['relatives'],
 324                  )
 325              );        
 326              exit(); 
 327           }
 328          
 329          /**
 330           *  * Store file contents
 331           *  *
 332           *  * string    Path to location
 333           *  * relatives    Relativity array (default: RELATIVE_CURRENT)
 334           *  * @return Boolean.  True on success, False otherwise.
 335            */
 336  		function write ($data) { return False; }
 337  
 338          /**
 339           *  * Create a file if it doesn't exist.
 340           *  *
 341           *         Optionally, update the modified time and
 342           *         modified user if the file exists.
 343           *  * string    Path to location
 344           *  * relatives    Relativity array (default: RELATIVE_CURRENT)
 345           *  * @return Boolean.  True on success, False otherwise.
 346            */
 347  		function touch ($data) { return False; }
 348  
 349          /**
 350           *  * Copy location
 351           *  *
 352           *  * from    Path to location to copy from
 353           *  * to        Path to location to copy to
 354           *  * relatives    Relativity array (default: RELATIVE_CURRENT, RELATIVE_CURRENT)
 355           *  * @return Boolean.  True on success, False otherwise.
 356            */
 357          function cp ($data) { return False; }
 358  
 359          /**
 360           *  * Move location
 361           *  *
 362           *  * from    Path to location to move from
 363           *  * to        Path to location to move to
 364           *  * relatives    Relativity array (default: RELATIVE_CURRENT, RELATIVE_CURRENT)
 365           *  * @return Boolean.  True on success, False otherwise.
 366            */
 367          function mv ($data) { return False; }
 368  
 369          /**
 370           *  * Delete location
 371           *  *
 372           *  * string    Path to location
 373           *  * relatives    Relativity array (default: RELATIVE_CURRENT)
 374           *  * @return Boolean.  True on success, False otherwise.
 375            */
 376          function rm ($data) { return False; }
 377  
 378          /**
 379           *  * Create directory
 380           *  *
 381           *  * string    Path to location
 382           *  * relatives    Relativity array (default: RELATIVE_CURRENT)
 383           *  * @return Boolean.  True on success, False otherwise.
 384            */
 385  		function mkdir ($data) { return False; }
 386  
 387          /*
 388           * Information functions.
 389           *
 390           * Overview:
 391           * These functions set or return information about locations.
 392           *
 393           * PUBLIC functions (mandatory):
 394           *
 395           * set_attributes - Set attributes for a location
 396           *
 397           * file_exists - Check if a location (file or directory) exists
 398           *
 399           * get_size - Determine size of location
 400           *
 401           * ls - Return detailed information for location(s)
 402           */
 403  
 404          /**
 405           *  * Set attributes for a location
 406           *  *
 407           *  * Valid attributes are listed in vfs->attributes,
 408           *           which may be extended by each derived class
 409           *  * string    Path to location
 410           *  * relatives    Relativity array (default: RELATIVE_CURRENT)
 411           *  * attributes    Keyed array of attributes.  Key is attribute
 412           *            name, value is attribute value.
 413           *  * @return Boolean.  True on success, False otherwise.
 414            */
 415  		 function set_attributes ($data) { return False; }
 416  
 417          /**
 418           *  * Check if a location (file or directory) exists
 419           *  *
 420           *  * string    Path to location
 421           *  * relatives    Relativity array (default: RELATIVE_CURRENT)
 422           *  * @return Boolean.  True if file exists, False otherwise.
 423            */
 424  		function file_exists ($data) { return False; }
 425  
 426          /**
 427           *  * Determine size of location
 428           *  *
 429           *  * string    Path to location
 430           *  * relatives    Relativity array (default: RELATIVE_CURRENT)
 431           *  * checksubdirs    Boolean.  If set, include the size of
 432           *                all subdirectories recursively.
 433           *  * @return Integer.  Size of location in bytes.
 434            */
 435  		function get_size ($data) { return 0; }
 436  
 437          /**
 438           *  * Return detailed information for location(s)
 439           *  *
 440           *  * string    Path to location
 441           *  * relatives    Relativity array (default: RELATIVE_CURRENT)
 442           *  * checksubdirs    Boolean.  If set, return information for all
 443           *                subdirectories recursively.
 444           *  * mime    String.  Only return information for locations with MIME type
 445           *            specified.  VFS classes must recogize these special types:
 446           *                "Directory" - Location is a directory
 447           *                " " - Location doesn't not have a MIME type
 448           *  * nofiles    Boolean.  If set and 'string' is a directory, return
 449           *            information about the directory, not the files in it.
 450           *  * @return Array of arrays of file information.
 451           *       Keys may vary depending on the implementation, but must include
 452           *       at least those attributes listed in $this->attributes.
 453            */
 454          function ls ($data) { return array(array()); }
 455  
 456          /*
 457           * Linked directory functions.
 458           *
 459           * Overview:
 460           * One 'special' feature that VFS classes must support
 461           * is linking an otherwise unrelated 'real' directory into
 462           * the virtual filesystem.  For a traditional filesystem, this
 463           * might mean linking /var/specialdir in the real filesystem to
 464           * /home/user/specialdir in the VFS.  For networked filesystems,
 465           * this might mean linking 'another.host.com/dir' to
 466           * 'this.host.com/home/user/somedir'.
 467           *
 468           * This is a feature that will be used mostly be administrators,
 469           * in order to present a consistent view to users.  Each VFS class
 470           * will almost certainly need a new interface for the administrator
 471           * to use to make links, but the concept is the same across all the
 472           * VFS backends.
 473           *
 474           * Note that by using $this->linked_dirs in conjunction with
 475           * $this->path_parts(), you can keep the implementation of linked
 476           * directories very isolated in your code.
 477           *
 478           * PUBLIC functions (mandatory):
 479           *
 480           * make_link - Create a real to virtual directory link
 481           */
 482  
 483          /**
 484           *  * Create a real to virtual directory link
 485           *  *
 486           *  * rdir    Real directory to make link from/to
 487           *  * vdir    Virtual directory to make link to/from
 488           *  * relatives    Relativity array (default: RELATIVE_CURRENT, RELATIVE_CURRENT)
 489           *  * @return Boolean.  True on success, False otherwise.
 490            */
 491  		function make_link ($data) { return False; }
 492  
 493          /*
 494           * Miscellaneous functions.
 495           *
 496           * PUBLIC functions (mandatory):
 497           *
 498           * update_real - Ensure that information about a location is
 499           *         up-to-date
 500           *
 501           * compress - Archives a file or set of files in a compressed file
 502           *
 503           * extract - Dearchives a file or set of files of a compressed file
 504           */
 505  
 506          /**
 507           *  * Ensure that information about a location is up-to-date
 508           *  *
 509           *  * Some VFS backends store information about locations
 510           *           in a secondary location, for example in a database
 511           *           or in a cache file.  update_real() can be called to
 512           *           ensure that the information in the secondary location
 513           *           is up-to-date.
 514           *  * string    Path to location
 515           *  * relatives    Relativity array (default: RELATIVE_CURRENT)
 516           *  * @return Boolean.  True on success, False otherwise.
 517            */
 518  		function update_real ($data) { return False; }
 519          
 520          /**
 521           *  * Creates an archive from a file or a set of files
 522           *  *
 523           *  * files    File names to be stored in archive (array)
 524           *  * name  Name of archive
 525           *  * type  The type of compression, can be 'zip'(default)or 'gz'
 526           *  * relatives    Relativity array (default: RELATIVE_CURRENT)
 527           *  *           Note: the last item is the relativity of the dest archive
 528           *  * @return Boolean.  True on success, False otherwise.
 529            */
 530  
 531  		function compress ($data) { return False; }
 532  
 533          /**
 534           *  * Extracts a file (or files) from archive 
 535           *  *
 536           *  * name  Name of archive
 537           *  * dest  The destination path of files to be extracted
 538           *  * type  The type of compression, can be 'zip' or 'gz'. If
 539           *  *                 not specified, uses according to the extension
 540           *  * files    Files to be extracted from archive
 541           *  * relatives    Relativity array (default: RELATIVE_CURRENT)
 542           *  *    Note: the first item is the relativity of the archive, the last of
 543           *  *          the dest dir
 544           *  * @return Boolean.  True on success, False otherwise.
 545            */
 546           
 547  		function extract ($data) { return False; }
 548  
 549  
 550   
 551           /*
 552           * SHARED FUNCTIONS
 553           *
 554           * The rest of the functions in this file are shared between
 555           * all derived VFS classes.
 556           *
 557           * Derived classes can overload any of these functions if they
 558           * see it fit to do so, as long as the prototypes and return
 559           * values are the same for public functions, and the function
 560           * accomplishes the same goal.
 561           *
 562           * PRIVATE functions:
 563           *
 564           * securitycheck - Check if location string is ok to use in VFS functions
 565           *
 566           * sanitize - Remove any possible security problems from a location
 567           *          string (i.e. remove leading '..')
 568           *
 569           * clean_string - Clean location string.  This function is used if
 570           *          any special characters need to be escaped or removed
 571           *          before accessing a database, network protocol, etc.
 572           *          The default is to escape characters before doing an SQL
 573           *          query.
 574           *
 575           * getabsolutepath - Translate a location string depending on the
 576           *             relativity.  This is the only function that is
 577           *             directly concerned with relativity.
 578           *
 579           * get_ext_mime_type - Return MIME type based on file extension
 580           *
 581           * PUBLIC functions (mandatory):
 582           *
 583           * set_relative - Sets the current relativity, the relativity used
 584           *          when RELATIVE_CURRENT is passed to a function
 585           *
 586           * get_relative - Return the current relativity
 587           *
 588           * path_parts - Return information about the component parts of a location string
 589           *
 590           * cd - Change current directory.  This function is used to store the
 591           *    current directory in a standard way, so that it may be accessed
 592           *    throughout phpGroupWare to provide a consistent view for the user.
 593           *
 594           * pwd - Return current directory
 595           *
 596           * copy - Alias for cp
 597           *
 598           * move - Alias for mv
 599           *
 600           * delete - Alias for rm
 601           *
 602           * dir - Alias for ls
 603           *
 604           * command_line - Process and run a Unix-sytle command line
 605           *
 606           * compress - Archives a file or set of files in a compressed file
 607           *
 608           * extract - Dearchives a file or set of files of a compressed file
 609           */
 610  
 611          /* PRIVATE functions */
 612  
 613          /**
 614           *  * Check if location string is ok to use in VFS functions
 615           *  *
 616           *  * Checks for basic violations such as ..
 617           *           If securitycheck () fails, run your string through $this->sanitize ()
 618           *  * string    Path to location
 619           *  * @return Boolean.  True if string is ok, False otherwise.
 620            */
 621  		function securitycheck ($data)
 622          {
 623              if (!is_array ($data))
 624              {
 625                  $data = array ();
 626              }
 627  
 628              if (substr ($data['string'], 0, 1) == "\\" || strstr ($data['string'], "..") || strstr ($data['string'], "\\..") || strstr ($data['string'], ".\\."))
 629              {
 630                  return False;
 631              }
 632              else
 633              {
 634                  return True;
 635              }
 636          }
 637  
 638          /**
 639           *  * Remove any possible security problems from a location
 640           *  *
 641           *         string (i.e. remove leading '..')
 642           *  * You should not pass all filenames through sanitize ()
 643           *           unless you plan on rejecting .files.  Instead, pass
 644           *           the name through securitycheck () first, and if it fails,
 645           *           pass it through sanitize.
 646           *  * string    Path to location
 647           *  * @return String. 'string' with any security problems fixed.
 648            */
 649  		function sanitize ($data)
 650          {
 651              if (!is_array ($data))
 652              {
 653                  $data = array ();
 654              }
 655  
 656              /* We use path_parts () just to parse the string, not translate paths */
 657              $p = $this->path_parts (array(
 658                      'string' => $data['string'],
 659                      'relatives' => array (RELATIVE_NONE)
 660                  )
 661              );
 662  
 663              return (ereg_replace ("^\.+", '', $p->fake_name));
 664          }
 665  
 666          /**
 667           *  * Clean location string.  This function is used if
 668           *  *
 669           *         any special characters need to be escaped or removed
 670           *         before accessing a database, network protocol, etc.
 671           *         The default is to escape characters before doing an SQL
 672           *         query.
 673           *  * string    Location string to clean
 674           *  * @return String.  Cleaned version of 'string'.
 675            */
 676  		function clean_string ($data)
 677          {
 678              if (!is_array ($data))
 679              {
 680                  $data = array ();
 681              }
 682  
 683              $string = $GLOBALS['egw']->db->db_addslashes ($data['string']);
 684  
 685              return $string;
 686          }
 687  
 688          /**
 689           *  * Translate a location string depending on the
 690           *  *
 691           *         relativity. This is the only function that is
 692           *         directly concerned with relativity.
 693           *  * string    Path to location, relative to mask[0].
 694           *  *             Defaults to empty string.
 695           *  * mask    Relativity array (default: RELATIVE_CURRENT)
 696           *  * fake    Boolean.  If set, returns the 'fake' path,
 697           *            i.e. /home/user/dir/file.  This is not always
 698           *            possible,  use path_parts() instead.
 699           *  * @return String. Full fake or real path, or False on error.
 700            */
 701  		function getabsolutepath ($data)
 702          {
 703              if (!is_array ($data))
 704              {
 705                  $data = array ();
 706              }
 707  
 708              $default_values = array
 709                  (
 710                      'string'    => False,
 711                      'mask'    => array (RELATIVE_CURRENT),
 712                      'fake'    => True
 713                  );
 714  
 715              $data = array_merge ($this->default_values ($data, $default_values), $data);
 716  
 717              $currentdir = $this->pwd (False);
 718  
 719              /* If they supply just VFS_REAL, we assume they want current relativity */
 720              if ($data['mask'][0] == VFS_REAL)
 721              {
 722                  $data['mask'][0] |= RELATIVE_CURRENT;
 723              }
 724  
 725              if (!$this->securitycheck (array(
 726                      'string'    => $data['string']
 727                  ))
 728              )
 729              {
 730                  return False;
 731              }
 732  
 733              if ($data['mask'][0] & RELATIVE_NONE)
 734              {
 735                  return $data['string'];
 736              }
 737  
 738              if ($data['fake'])
 739              {
 740                  $sep = '/';
 741              }
 742              else
 743              {
 744                  $sep = SEP;
 745              }
 746  
 747              /* if RELATIVE_CURRENT, retrieve the current mask */
 748              if ($data['mask'][0] & RELATIVE_CURRENT)
 749              {
 750                  $mask = $data['mask'][0];
 751                  /* Respect any additional masks by re-adding them after retrieving the current mask*/
 752                  $data['mask'][0] = $this->get_relative () + ($mask - RELATIVE_CURRENT);
 753              }
 754  
 755              if ($data['fake'])
 756              {
 757                  $basedir = "/";
 758              }
 759              else
 760              {
 761                  $basedir = $this->basedir . $sep;
 762  
 763                  /* This allows all requests to use /'s */
 764                  $data['string'] = preg_replace ("|/|", $sep, $data['string']);
 765              }
 766  
 767              if (($data['mask'][0] & RELATIVE_PATH) && $currentdir)
 768              {
 769                  $basedir = $basedir . $currentdir . $sep;
 770              }
 771              elseif (($data['mask'][0] & RELATIVE_USER) || ($data['mask'][0] & RELATIVE_USER_APP))
 772              {
 773                  $basedir = $basedir . $this->fakebase . $sep;
 774              }
 775  
 776              if ($data['mask'][0] & RELATIVE_CURR_USER)
 777              {
 778                  $basedir = $basedir . $this->working_lid . $sep;
 779              }
 780  
 781              if (($data['mask'][0] & RELATIVE_USER) || ($data['mask'][0] & RELATIVE_USER_APP))
 782              {
 783                  $basedir = $basedir . $GLOBALS['egw_info']['user']['account_lid'] . $sep;
 784              }
 785  
 786              if ($data['mask'][0] & RELATIVE_USER_APP)
 787              {
 788                  $basedir = $basedir . "." . $GLOBALS['egw_info']['flags']['currentapp'] . $sep;
 789              }
 790  
 791              /* Don't add string if it's a /, just for aesthetics */
 792              if ($data['string'] && $data['string'] != $sep)
 793              {
 794                  $basedir = $basedir . $data['string'];
 795              }
 796  
 797              /* Let's not return // */
 798              while (ereg ($sep . $sep, $basedir))
 799              {
 800                  $basedir = ereg_replace ($sep . $sep, $sep, $basedir);
 801              }
 802  
 803              $basedir = ereg_replace ($sep . '$', '', $basedir);
 804  
 805              return $basedir;
 806          }
 807  
 808          /**
 809           *  * Return MIME type based on file extension
 810           *  *
 811           *  * Internal use only.  Applications should call vfs->file_type ()
 812           *  * @author skeeter
 813           *  * string    Real path to file, with or without leading paths
 814           *  * @return String.  MIME type based on file extension.
 815            */
 816  		function get_ext_mime_type ($data)
 817          {
 818              if (!is_array ($data))
 819              {
 820                  $data = array ();
 821              }
 822  
 823              $file=basename($data['string']);
 824              $mimefile=EGW_API_INC.'/phpgw_mime.types';
 825              $fp=fopen($mimefile,'r');
 826              $contents = explode("\n",fread($fp,filesize($mimefile)));
 827              fclose($fp);
 828  
 829              $parts=explode('.',strtolower($file));
 830              $ext=$parts[(sizeof($parts)-1)];
 831  
 832              for($i=0;$i<sizeof($contents);$i++)
 833              {
 834                  if (!ereg("^#",$contents[$i]))
 835                  {
 836                      $line=split("[[:space:]]+", $contents[$i]);
 837                      if (sizeof($line) >= 2)
 838                      {
 839                          for($j=1;$j<sizeof($line);$j++)
 840                          {
 841                              if($line[$j] == $ext)
 842                              {
 843                                  return $line[0];
 844                              }
 845                          }
 846                      }
 847                  }
 848              }
 849  
 850              return '';
 851           }
 852  
 853          /* PUBLIC functions (mandatory) */
 854  
 855          /**
 856           *  * Sets the current relativity, the relativity used
 857           *  *
 858           *         when RELATIVE_CURRENT is passed to a function
 859           *  * mask    Relative bitmask.  If not set, relativity
 860           *            will be returned to the default.
 861           *  * @return Void
 862            */
 863  		function set_relative ($data)
 864          {
 865              if (!is_array ($data))
 866              {
 867                  $data = array ();
 868              }
 869  
 870              if (!$data['mask'])
 871              {
 872                  unset ($this->relative);
 873              }
 874              else
 875              {
 876                  $this->relative = $data['mask'];
 877              }
 878          }
 879  
 880          /**
 881           *  * Return the current relativity
 882           *  *
 883           *  * Returns relativity bitmask, or the default
 884           *           of "completely relative" if unset
 885           *  * @return Integer.  One of the RELATIVE_* defines.
 886            */
 887  		function get_relative ()
 888          {
 889              if (isset ($this->relative) && $this->relative)
 890              {
 891                  return $this->relative;
 892              }
 893              else
 894              {
 895                  return RELATIVE_ALL;
 896              }
 897          }
 898  
 899          /**
 900           *  * Return information about the component parts of a location string
 901           *  *
 902           *  * Most VFS functions call path_parts() with their 'string' and
 903           *           'relatives' arguments before doing their work, in order to
 904           *           determine the file/directory to work on.
 905           *  * string    Path to location
 906           *  * relatives    Relativity array (default: RELATIVE_CURRENT)
 907           *  * object    If set, return an object instead of an array
 908           *  * nolinks    Don't check for linked directories (made with
 909           *            make_link()).  Used internally to prevent recursion.
 910           *  * @return Array or object.  Contains the fake and real component parts of the path.
 911           *  * Returned values are:
 912           *        mask
 913           *        outside
 914           *        fake_full_path
 915           *        fake_leading_dirs
 916           *        fake_extra_path        BROKEN
 917           *        fake_name
 918           *        real_full_path
 919           *        real_leading_dirs
 920           *        real_extra_path        BROKEN
 921           *        real_name
 922           *        fake_full_path_clean
 923           *        fake_leading_dirs_clean
 924           *        fake_extra_path_clean    BROKEN
 925           *        fake_name_clean
 926           *        real_full_path_clean
 927           *        real_leading_dirs_clean
 928           *        real_extra_path_clean    BROKEN
 929           *        real_name_clean
 930           *    "clean" values are run through vfs->clean_string () and
 931           *    are safe for use in SQL queries that use key='value'
 932           *    They should be used ONLY for SQL queries, so are used
 933           *    mostly internally
 934           *    mask is either RELATIVE_NONE or RELATIVE_NONE|VFS_REAL,
 935           *    and is used internally
 936           *    outside is boolean, True if 'relatives' contains VFS_REAL
 937            */
 938  		function path_parts ($data)
 939          {
 940              if (!is_array ($data))
 941              {
 942                  $data = array ();
 943              }
 944  
 945              $default_values = array
 946                  (
 947                      'relatives'    => array (RELATIVE_CURRENT),
 948                      'object'    => True,
 949                      'nolinks'    => False
 950                  );
 951  
 952              $data = array_merge ($this->default_values ($data, $default_values), $data);
 953  
 954              $sep = SEP;
 955  
 956              $rarray['mask'] = RELATIVE_NONE;
 957  
 958              if (!($data['relatives'][0] & VFS_REAL))
 959              {
 960                  $rarray['outside'] = False;
 961                  $fake = True;
 962              }
 963              else
 964              {
 965                  $rarray['outside'] = True;
 966                  $rarray['mask'] |= VFS_REAL;
 967              }
 968  
 969              $string = $this->getabsolutepath (array(
 970                      'string'    => $data['string'],
 971                      'mask'    => array ($data['relatives'][0]),
 972                      'fake'    => $fake
 973                  )
 974              );
 975  
 976              if ($fake)
 977              {
 978                  $base_sep = '/';
 979                  $base = '/';
 980  
 981                  $opp_base = $this->basedir . $sep;
 982  
 983                  $rarray['fake_full_path'] = $string;
 984              }
 985              else
 986              {
 987                  $base_sep = $sep;
 988                  if (substr($string,0,strlen($this->basedir)+1) == $this->basedir . $sep)
 989                  {
 990                      $base = $this->basedir . $sep;
 991                  }
 992                  else
 993                  {
 994                      $base = $sep;
 995                  }
 996  
 997                  $opp_base = '/';
 998  
 999                  $rarray['real_full_path'] = $string;
1000              }
1001  
1002              /* This is needed because of substr's handling of negative lengths */
1003              $baselen = strlen ($base);
1004              $lastslashpos = @strrpos ($string, $base_sep);
1005              $length = $lastslashpos < $baselen ? 0 : $lastslashpos - $baselen;
1006  
1007              $extra_path = $rarray['fake_extra_path'] = $rarray['real_extra_path'] = substr ($string, strlen ($base), $length);
1008              if($string[1] != ':')
1009              {
1010                   $name = $rarray['fake_name'] = $rarray['real_name'] = substr ($string, @strrpos ($string, $base_sep) + 1);
1011              }
1012              else
1013              {
1014                  $name = $rarray['fake_name'] = $rarray['real_name'] = $string;
1015              }
1016  
1017              if ($fake)
1018              {
1019                  $rarray['real_extra_path'] ? $dispsep = $sep : $dispsep = '';
1020                  $rarray['real_full_path'] = $opp_base . $rarray['real_extra_path'] . $dispsep . $rarray['real_name'];
1021                  if ($extra_path)
1022                  {
1023                      $rarray['fake_leading_dirs'] = $base . $extra_path;
1024                      $rarray['real_leading_dirs'] = $opp_base . $extra_path;
1025                  }
1026                  elseif (@strrpos ($rarray['fake_full_path'], $sep) == 0)
1027                  {
1028                      /* If there is only one $sep in the path, we don't want to strip it off */
1029                      $rarray['fake_leading_dirs'] = $sep;
1030                      $rarray['real_leading_dirs'] = substr ($opp_base, 0, strlen ($opp_base) - 1);
1031                  }
1032                  else
1033                  {
1034                      /* These strip the ending / */
1035                      $rarray['fake_leading_dirs'] = substr ($base, 0, strlen ($base) - 1);
1036                      $rarray['real_leading_dirs'] = substr ($opp_base, 0, strlen ($opp_base) - 1);
1037                  }
1038              }
1039              else
1040              {
1041                  if($rarray['fake_name'][1] != ':')
1042                  {
1043                       $rarray['fake_full_path'] = $opp_base . $rarray['fake_extra_path'] . '/' . $rarray['fake_name'];
1044                  }
1045                  else
1046                  {
1047                      $rarray['fake_full_path'] = $rarray['fake_name'];
1048                  }
1049                  if ($extra_path)
1050                  {
1051                      $rarray['fake_leading_dirs'] = $opp_base . $extra_path;
1052                      $rarray['real_leading_dirs'] = $base . $extra_path;
1053                  }
1054                  else
1055                  {
1056                      $rarray['fake_leading_dirs'] = substr ($opp_base, 0, strlen ($opp_base) - 1);
1057                      $rarray['real_leading_dirs'] = substr ($base, 0, strlen ($base) - 1);
1058                  }
1059              }
1060  
1061              /* We check for linked dirs made with make_link ().  This could be better, but it works */
1062              if (!$data['nolinks'])
1063              {
1064                  reset ($this->linked_dirs);
1065                  while (list ($num, $link_info) = each ($this->linked_dirs))
1066                  {
1067                      if (ereg ("^$link_info[directory]/$link_info[name](/|$)", $rarray['fake_full_path']))
1068                      {
1069                          $rarray['real_full_path'] = ereg_replace ("^$this->basedir", '', $rarray['real_full_path']);
1070                          $rarray['real_full_path'] = ereg_replace ("^$link_info[directory]" . SEP . "$link_info[name]", $link_info['link_directory'] . SEP . $link_info['link_name'], $rarray['real_full_path']);
1071  
1072                          $p = $this->path_parts (array(
1073                                  'string'    => $rarray['real_full_path'],
1074                                  'relatives'    => array (RELATIVE_NONE|VFS_REAL),
1075                                  'nolinks'    => True
1076                              )
1077                          );
1078  
1079                          $rarray['real_leading_dirs'] = $p->real_leading_dirs;
1080                          $rarray['real_extra_path'] = $p->real_extra_path;
1081                          $rarray['real_name'] = $p->real_name;
1082                      }
1083                  }
1084              }
1085  
1086              /*
1087                   We have to count it before because new keys will be added,
1088                   which would create an endless loop
1089              */
1090              $count = count ($rarray);
1091              reset ($rarray);
1092              for ($i = 0; (list ($key, $value) = each ($rarray)) && $i != $count; $i++)
1093              {
1094                  $rarray[$key . '_clean'] = $this->clean_string (array ('string' => $value));
1095              }
1096  
1097              if ($data['object'])
1098              {
1099                  $robject =& new path_class;
1100  
1101                  reset ($rarray);
1102                  while (list ($key, $value) = each ($rarray))
1103                  {
1104                      $robject->$key = $value;
1105                  }
1106              }
1107  
1108              /*
1109              echo "<br>fake_full_path: $rarray[fake_full_path]
1110                  <br>fake_leading_dirs: $rarray[fake_leading_dirs]
1111                  <br>fake_extra_path: $rarray[fake_extra_path]
1112                  <br>fake_name: $rarray[fake_name]
1113                  <br>real_full_path: $rarray[real_full_path]
1114                  <br>real_leading_dirs: $rarray[real_leading_dirs]
1115                  <br>real_extra_path: $rarray[real_extra_path]
1116                  <br>real_name: $rarray[real_name]";
1117              */
1118  
1119              if ($data['object'])
1120              {
1121                  return ($robject);
1122              }
1123              else
1124              {
1125                  return ($rarray);
1126              }
1127          }
1128  
1129          /**
1130           *  * Change current directory.  This function is used to store the
1131           *  *
1132           *         current directory in a standard way, so that it may be accessed
1133           *         throughout phpGroupWare to provide a consistent view for the user.
1134           *  * To cd to the root '/', use:
1135           *        cd (array(
1136           *            'string' => '/',
1137           *            'relative' => False,
1138           *            'relatives' => array (RELATIVE_NONE)
1139           *        ));
1140           *  * string    Directory location to cd into.  Default is '/'.
1141           *  * relative    If set, add target to current path.
1142           *            Else, pass 'relative' as mask to getabsolutepath()
1143           *            Default is True.
1144           *  * relatives    Relativity array (default: RELATIVE_CURRENT)
1145            */
1146          function cd ($data = '')
1147          {
1148              if (!is_array ($data))
1149              {
1150                  $noargs = 1;
1151                  $data = array ();
1152              }
1153  
1154              $default_values = array
1155                  (
1156                      'string'    => '/',
1157                      'relative'    => True,
1158                      'relatives'    => array (RELATIVE_CURRENT)
1159                  );
1160  
1161              $data = array_merge ($this->default_values ($data, $default_values), $data);
1162  
1163              if ($data['relatives'][0] & VFS_REAL)
1164              {
1165                  $sep = SEP;
1166              }
1167              else
1168              {
1169                  $sep = '/';
1170              }
1171  
1172              if ($data['relative'] == 'relative' || $data['relative'] == True)
1173              {
1174                  /* if 'string' is "/" and 'relative' is set, we cd to the user/group home dir */
1175                  if ($data['string'] == '/')
1176                  {
1177                      $data['relatives'][0] = RELATIVE_USER;
1178                      $basedir = $this->getabsolutepath (array(
1179                              'string'    => False,
1180                              'mask'    => array ($data['relatives'][0]),
1181                              'fake'    => True
1182                          )
1183                      );
1184                  }
1185                  else
1186                  {
1187                      $currentdir = $GLOBALS['egw']->session->appsession('vfs','');
1188                      $basedir = $this->getabsolutepath (array(
1189                              'string'    => $currentdir . $sep . $data['string'],
1190                              'mask'    => array ($data['relatives'][0]),
1191                              'fake'    => True
1192                          )
1193                      );
1194                  }
1195              }
1196              else
1197              {
1198                  $basedir = $this->getabsolutepath (array(
1199                          'string'    => $data['string'],
1200                          'mask'    => array ($data['relatives'][0])
1201                      )
1202                  );
1203              }
1204  
1205              $GLOBALS['egw']->session->appsession('vfs','',$basedir);
1206  
1207              return True;
1208          }
1209  
1210          /**
1211           *  * Return current directory
1212           *  *
1213           *  * full    If set, return full fake path, else just
1214           *            the extra dirs (False strips the leading /).
1215           *            Default is True.
1216           *  * @return String.  The current directory.
1217            */
1218  		function pwd ($data = '')
1219          {
1220              if (!is_array ($data))
1221              {
1222                  $data = array ();
1223              }
1224  
1225              $default_values = array
1226                  (
1227                      'full'    => True
1228                  );
1229  
1230              $data = array_merge ($this->default_values ($data, $default_values), $data);
1231  
1232              $currentdir = $GLOBALS['egw']->session->appsession('vfs','');
1233  
1234              if (!$data['full'])
1235              {
1236                  $currentdir = ereg_replace ("^/", '', $currentdir);
1237              }
1238  
1239              if ($currentdir == '' && $data['full'])
1240              {
1241                  $currentdir = '/';
1242              }
1243  
1244              $currentdir = trim ($currentdir);
1245  
1246              return $currentdir;
1247          }
1248  
1249          /**
1250           *  * shortcut to cp
1251           *  *
1252            */
1253  		function copy ($data)
1254          {
1255              return $this->cp ($data);
1256          }
1257  
1258          /**
1259           *  * shortcut to mv
1260           *  *
1261            */
1262  		function move ($data)
1263          {
1264              return $this->mv ($data);
1265          }
1266  
1267          /**
1268           *  * shortcut to rm
1269           *  *
1270            */
1271  		function delete ($data)
1272          {
1273              return $this->rm ($data);
1274          }
1275  
1276          /**
1277           *  * shortcut to ls
1278           *  *
1279            */
1280  		function dir ($data)
1281          {
1282              return $this->ls ($data);
1283          }
1284  
1285          /**
1286           *  * Process and run a Unix-sytle command line
1287           *  *
1288           *  * EXPERIMENTAL.  DANGEROUS.  DO NOT USE THIS UNLESS YOU
1289           *           KNOW WHAT YOU'RE DOING!
1290           *  *            This is mostly working, but the command parser needs
1291           *           to be improved to take files with spaces into
1292           *           consideration (those should be in "").
1293           *  * command_line    Unix-style command line with one of the
1294           *                commands in the $args array
1295           *  * @return The return value of the actual VFS call
1296            */
1297  		function command_line ($data)
1298          {
1299              if (!is_array ($data))
1300              {
1301                  $data = array ();
1302              }
1303  
1304              $args = array
1305              (
1306                  array ('name'    => 'mv', 'params'    => 2),
1307                  array ('name'    => 'cp', 'params'    => 2),
1308                  array ('name'    => 'rm', 'params'    => 1),
1309                  array ('name'    => 'ls', 'params'    => -1),
1310                  array ('name'    => 'du', 'params'    => 1, 'func'    => get_size),
1311                  array ('name'    => 'cd', 'params'    => 1),
1312                  array ('name'    => 'pwd', 'params'    => 0),
1313                  array ('name'    => 'cat', 'params'    => 1, 'func'    => read),
1314                  array ('name'    => 'file', 'params'    => 1, 'func'    => file_type),
1315                  array ('name'    => 'mkdir', 'params'    => 1),
1316                  array ('name'    => 'touch', 'params'    => 1)
1317              );
1318  
1319              if (!$first_space = strpos ($data['command_line'], ' '))
1320              {
1321                  $first_space = strlen ($data['command_line']);
1322              }
1323              if ((!$last_space = strrpos ($data['command_line'], ' ')) || ($last_space == $first_space))
1324              {
1325                  $last_space = strlen ($data['command_line']) + 1;
1326              }
1327              $argv[0] = substr ($data['command_line'], 0, $first_space);
1328              if (strlen ($argv[0]) != strlen ($data['command_line']))
1329              {
1330                  $argv[1] = substr ($data['command_line'], $first_space + 1, $last_space - ($first_space + 1));
1331                  if ((strlen ($argv[0]) + 1 + strlen ($argv[1])) != strlen ($data['command_line']))
1332                  {
1333                      $argv[2] = substr ($data['command_line'], $last_space + 1);
1334                  }
1335              }
1336              $argc = count ($argv);
1337  
1338              reset ($args);
1339              while (list (,$arg_info) = each ($args))
1340              {
1341                  if ($arg_info['name'] == $argv[0])
1342                  {
1343                      $command_ok = 1;
1344                      if (($argc == ($arg_info['params'] + 1)) || ($arg_info['params'] == -1))
1345                      {
1346                          $param_count_ok = 1;
1347                      }
1348                      break;
1349                  }
1350              }
1351  
1352              if (!$command_ok)
1353              {
1354  //                return E_VFS_BAD_COMMAND;
1355                  return False;
1356              }
1357              if (!$param_count_ok)
1358              {
1359  //                return E_VFS_BAD_PARAM_COUNT;
1360                  return False;
1361              }
1362  
1363              for ($i = 1; $i != ($arg_info['params'] + 1); $i++)
1364              {
1365                  if (substr ($argv[$i], 0, 1) == "/")
1366                  {
1367                      $relatives[] = RELATIVE_NONE;
1368                  }
1369                  else
1370                  {
1371                      $relatives[] = RELATIVE_ALL;
1372                  }
1373              }
1374  
1375              $func = $arg_info['func'] ? $arg_info['func'] : $arg_info['name'];
1376  
1377              if (!$argv[2])
1378              {
1379                  $rv = $this->$func (array(
1380                          'string'    => $argv[1],
1381                          'relatives'    => $relatives
1382                      )
1383                  );
1384              }
1385              else
1386              {
1387                  $rv = $this->$func (array(
1388                          'from'    => $argv[1],
1389                          'to'    => $argv[2],
1390                          'relatives'    => $relatives
1391                      )
1392                  );
1393              }
1394  
1395              return ($rv);
1396          }
1397  
1398          /* Helper functions, not public */
1399  
1400  		function default_values ($data, $default_values)
1401          {
1402              for ($i = 0; list ($key, $value) = each ($default_values); $i++)
1403              {
1404                  if (!isset ($data[$key]))
1405                  {
1406                      $data[$key] = $value;
1407                  }
1408              }
1409  
1410              return $data;
1411          }
1412  
1413      }
1414      
1415      include (EGW_API_INC . '/class.vfs_' . $GLOBALS['egw_info']['server']['file_repository'] . '.inc.php');


Généré le : Sun Feb 25 17:20:01 2007 par Balluche grâce à PHPXref 0.7