[ Index ]
 

Code source de b2evolution 2.1.0-beta

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/blogs/inc/files/model/ -> _filelist.class.php (source)

   1  <?php
   2  /**

   3   * This file implements the Filelist class.

   4   *

   5   * This file is part of the evoCore framework - {@link http://evocore.net/}

   6   * See also {@link http://sourceforge.net/projects/evocms/}.

   7   *

   8   * @copyright (c)2003-2007 by Francois PLANQUE - {@link http://fplanque.net/}

   9   * Parts of this file are copyright (c)2004-2006 by Daniel HAHLER - {@link http://thequod.de/contact}.

  10   *

  11   * {@internal License choice

  12   * - If you have received this file as part of a package, please find the license.txt file in

  13   *   the same folder or the closest folder above for complete license terms.

  14   * - If you have received this file individually (e-g: from http://evocms.cvs.sourceforge.net/)

  15   *   then you must choose one of the following licenses before using the file:

  16   *   - GNU General Public License 2 (GPL) - http://www.opensource.org/licenses/gpl-license.php

  17   *   - Mozilla Public License 1.1 (MPL) - http://www.opensource.org/licenses/mozilla1.1.php

  18   * }}

  19   *

  20   * {@internal Open Source relicensing agreement:

  21   * Daniel HAHLER grants Francois PLANQUE the right to license

  22   * Daniel HAHLER's contributions to this file and the b2evolution project

  23   * under any OSI approved OSS license (http://www.opensource.org/licenses/).

  24   * }}

  25   *

  26   * @package evocore

  27   *

  28   * {@internal Below is a list of authors who have contributed to design/coding of this file: }}

  29   * @author blueyed: Daniel HAHLER

  30   * @author fplanque: Francois PLANQUE

  31   *

  32   * @version $Id: _filelist.class.php,v 1.1 2007/06/25 10:59:55 fplanque Exp $

  33   */
  34  if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );
  35  
  36  
  37  load_class('files/model/_file.class.php');
  38  
  39  
  40  /**

  41   * Holds a list of File objects.

  42   *

  43   * Can hold an arbitrary list of Files.

  44   * Can list files in a directory by itself.

  45   * Can walk recursively down a directory tree to list in "flat mode".

  46   * Can sort file list.

  47   * Can iterate through list.

  48   * Cannot hold files with different root type/ID.

  49   *

  50   * @see File

  51   * @package evocore

  52   */
  53  class Filelist
  54  {
  55      /**

  56       * Flat mode? (all files recursive without dirs)

  57       * @param boolean

  58       */
  59      var $flatmode;
  60  
  61      /**

  62       * Do we want to include directories? (This gets used by {@link load()}).

  63       * @var boolean

  64       */
  65      var $include_dirs = true;
  66  
  67      /**

  68       * Do we want to include files? (This gets used by {@link load()}).

  69       * @var boolean

  70       */
  71      var $include_files = true;
  72  
  73      /**

  74       * The root of the file list.

  75       *

  76       * All files in this list MUST have that same FileRoot. Adding will fail otherwise.

  77       *

  78       * @var FileRoot

  79       */
  80      var $_FileRoot;
  81  
  82      /**

  83       * Path to list with trailing slash.

  84       *

  85       * false if we are constructing an arbitrary list (i-e not tied to a single directory)

  86       * fp> should use NULL instead of false

  87       *

  88       * @var string

  89       * @access protected

  90       */
  91      var $_ads_list_path = false;
  92  
  93      /**

  94       * Path to list reltive to root, with trailing slash

  95       *

  96       * false if we are constructing an arbitrary list (i-e not tied to a single directory)

  97       * fp> should use NULL instead of false

  98       *

  99       * @param string

 100       * @access protected

 101       */
 102      var $_rds_list_path = false;
 103  
 104      /**

 105       * Filename filter pattern

 106       *

 107       * Will be matched against the filename part (not the path)

 108       * NULL if disabled

 109       *

 110       * Can be a regular expression (see {@link Filelist::$_filter_is_regexp}), internally with delimiters/modifiers!

 111       *

 112       * Use {@link set_filter()} to set it.

 113       *

 114       * @var string

 115       * @access protected

 116       */
 117      var $_filter = NULL;
 118  
 119      /**

 120       * Is the filter a regular expression? NULL if unknown

 121       *

 122       * Use {@link set_filter()} to set it.

 123       *

 124       * @see Filelist::$_filter

 125       * @var boolean

 126       * @access protected

 127       */
 128      var $_filter_is_regexp = NULL;
 129  
 130      /**

 131       * The list of Files.

 132       * @var array

 133       * @access protected

 134       */
 135      var $_entries = array();
 136  
 137      /**

 138       * Index on File IDs (id => {@link $_entries} key).

 139       *

 140       * Note: fplanque>> what's the purpose of the md5 IDs??

 141       *

 142       * @todo make these direct links to &File objects

 143       * @var array

 144       * @access protected

 145       */
 146      var $_md5_ID_index = array();
 147  
 148      /**

 149       * Index on full paths (path => {@link $_entries} key).

 150       * @todo make these direct links to &File objects

 151       * @var array

 152       * @access protected

 153       */
 154      var $_full_path_index = array();
 155  
 156      /**

 157       * Index on (r)elative (s)lash terminated (f)ile/(d)irectory paths (rdfs_path => key into {@link $_entries}).

 158       *

 159       * @todo make these direct links to &File objects

 160       *

 161       * @var array

 162       * @access protected

 163       */
 164      var $_rdfs_rel_path_index = array();
 165  
 166      /**

 167       * Index on sort order (order # => {@link $_entries} key).

 168       * @todo make these direct links to &File objects

 169       * @var array

 170       * @access protected

 171       */
 172      var $_order_index = array();
 173  
 174      /**

 175       * Number of entries in the {@link $_entries} array

 176       *

 177       * Note: $_total_entries = $_total_dirs + $_total_files

 178       *

 179       * @var integer

 180       * @access protected

 181       */
 182      var $_total_entries = 0;
 183  
 184      /**

 185       * Number of directories

 186       * @var integer

 187       * @access protected

 188       */
 189      var $_total_dirs = 0;
 190  
 191      /**

 192       * Number of files

 193       * @var integer

 194       * @access protected

 195       */
 196      var $_total_files = 0;
 197  
 198      /**

 199       * Number of bytes

 200       * @var integer

 201       * @access protected

 202       */
 203      var $_total_bytes = 0;
 204  
 205      /**

 206       * Index of the current iterator position.

 207       *

 208       * This is the key of {@link $_order_index}

 209       *

 210       * @var integer

 211       * @access protected

 212       */
 213      var $_current_idx = -1;
 214  
 215      /**

 216       * What column is the list ordered on?

 217       *

 218       * Possible values are: 'name', 'path', 'type', 'size', 'lastmod', 'perms'

 219       *

 220       * @var string

 221       * @access protected

 222       */
 223      var $_order = NULL;
 224  
 225      /**

 226       * Are we sorting ascending (or descending)?

 227       *

 228       * NULL is default and means ascending for 'name', descending for the rest

 229       *

 230       * @var boolean

 231       * @access protected

 232       */
 233      var $_order_asc = NULL;
 234  
 235      /**

 236       * User preference: Sort dirs not at top

 237       *

 238       * @var boolean

 239       */
 240      var $_dirs_not_at_top = false;
 241  
 242      /**

 243       * User preference: Load and show hidden files?

 244       *

 245       * "Hidden files" are prefixed with a dot .

 246       *

 247       * @var boolean

 248       */
 249      var $_show_hidden_files = false;
 250  
 251      /**

 252       * User preference: recursive size of dirs?

 253       *

 254       * The load() & sort() methods use this.

 255       *

 256       * @var boolean

 257       * @access protected

 258       */
 259      var $_use_recursive_dirsize = false;
 260  
 261  
 262      /**

 263       * Constructor

 264       *

 265       * @param FileRoot See FileRootCache::get_by_type_and_ID()

 266       * @param boolean|string Default path for the files, false if you want to create an arbitrary list; NULL for the Fileroot's ads_path.

 267       * @param integer ID of the user, the group or the collection the file belongs to...

 268       */
 269  	function Filelist( $FileRoot, $path = NULL )
 270      {
 271          global $AdminUI;
 272  
 273          if( ! is_object($FileRoot) )
 274          {
 275              debug_die( 'Fatal: $FileRoot is no object!' );
 276          }
 277  
 278          if( is_null($path) )
 279          {
 280              $path = $FileRoot->ads_path;
 281          }
 282          $this->_ads_list_path = $path;
 283          $this->_FileRoot = & $FileRoot;
 284  
 285          if( ! empty($this->_ads_list_path) )
 286          {
 287              // Get the subpath relative to root

 288              $this->_rds_list_path = $this->rdfs_relto_root_from_adfs( $this->_ads_list_path );
 289          }
 290      }
 291  
 292  
 293      /**

 294       * Loads or reloads the filelist entries.

 295       *

 296       * NOTE: this does not work for arbitrary lists!

 297       *

 298       * @todo flatmode always shows hidden files, even if we don't want them :/

 299       *

 300       * @uses $flatmode

 301       * @return boolean True on sucess, false on failure (not accessible)

 302       */
 303  	function load()
 304      {
 305          global $Messages;
 306  
 307          if( !$this->_ads_list_path )
 308          {    // We have no path to load from: (happens when FM finds no available root OR we have an arbitrary)
 309              // echo 'Cannot load a filelist with no list path' ;

 310              return false;
 311          }
 312  
 313          // Clears the list (for RE-loads):

 314          $this->_total_entries = 0;
 315          $this->_total_bytes = 0;
 316          $this->_total_files = 0;
 317          $this->_total_dirs = 0;
 318          $this->_entries = array();
 319          $this->_md5_ID_index = array();
 320          $this->_full_path_index = array();
 321          $this->_rdfs_rel_path_index = array();
 322          $this->_order_index = array();
 323  
 324          // Attempt list files for requested directory: (recursively if flat mode):

 325          if( ($filepath_array = get_filenames( $this->_ads_list_path, $this->include_files, $this->include_dirs, true, $this->flatmode )) === false )
 326          {
 327              $Messages->add( sprintf( T_('Cannot open directory &laquo;%s&raquo;!'), $this->_ads_list_path ), 'fl_error' );
 328              return false;
 329          }
 330  
 331          // Loop through file list:

 332          foreach( $filepath_array as $adfp_path )
 333          {
 334              // Extract the filename from the full path

 335              $name = basename( $adfp_path );
 336  
 337              // Check for hidden status...

 338              if( ( ! $this->_show_hidden_files) && (substr($name, 0, 1) == '.') )
 339              { // Do not load & show hidden files (prefixed with .)
 340                  continue;
 341              }
 342  
 343              // Check filter...

 344              if( $this->_filter !== NULL )
 345              { // Filter: must match filename
 346                  if( $this->_filter_is_regexp )
 347                  { // Filter is a reg exp:
 348                      if( ! preg_match( $this->_filter, $name ) )
 349                      { // does not match the regexp filter
 350                          continue;
 351                      }
 352                  }
 353                  else
 354                  { // Filter is NOT a regexp:
 355                      if( ! fnmatch( $this->_filter, $name ) )
 356                      {
 357                          continue;
 358                      }
 359                  }
 360              }
 361  
 362              // Extract the file's relative path to the root

 363              $rdfp_path_relto_root = $this->rdfs_relto_root_from_adfs( $adfp_path );
 364              // echo '<br>'.$rdfp_rel_path;

 365  
 366              // Add the file into current list:

 367              $this->add_by_subpath( $rdfp_path_relto_root, true );
 368          }
 369  
 370          return true;
 371      }
 372  
 373  
 374      /**

 375       * Add a File object to the list (by reference).

 376       *

 377       * @param File File object (by reference)

 378       * @param boolean Has the file to exist to get added?

 379       * @return boolean true on success, false on failure

 380       */
 381  	function add( & $File, $mustExist = false )
 382      {
 383          if( !is_a( $File, 'file' ) )
 384          {    // Passed object is not a File!! :(
 385              return false;
 386          }
 387  
 388          // Integrity check:

 389          if( $File->_FileRoot->ID != $this->_FileRoot->ID )
 390          {
 391              debug_die( 'Adding file '.$File->_FileRoot->ID.':'.$File->get_rdfs_rel_path().' to filelist '.$this->_FileRoot->ID.' : root mismatch!' );
 392          }
 393  
 394          if( $mustExist && ! $File->exists() )
 395          {    // File does not exist..
 396              return false;
 397          }
 398  
 399  
 400          $this->_entries[$this->_total_entries] = & $File;
 401          $this->_md5_ID_index[$File->get_md5_ID()] = $this->_total_entries;
 402          $this->_full_path_index[$File->get_full_path()] = $this->_total_entries;
 403          $this->_rdfs_rel_path_index[$File->get_rdfs_rel_path()] = $this->_total_entries;
 404          // add file to the end of current list:

 405          $this->_order_index[$this->_total_entries] = $this->_total_entries;
 406  
 407          // Count 1 more entry (file or dir)

 408          $this->_total_entries++;
 409  
 410          if( $File->is_dir() )
 411          {    // Count 1 more directory
 412              $this->_total_dirs++;
 413  
 414              // fplanque>> TODO: get this outta here??

 415              // blueyed>> Where does it belong instead?

 416              if( $this->_use_recursive_dirsize )
 417              { // We want to use recursive directory sizes
 418                  // won't be done in the File constructor

 419                  $File->setSize( get_dirsize_recursive( $File->get_full_path() ) );
 420              }
 421          }
 422          else
 423          {    // Count 1 more file
 424              $this->_total_files++;
 425          }
 426  
 427          // Count total bytes in this dir

 428          $this->_total_bytes += $File->get_size();
 429  
 430          return true;
 431      }
 432  
 433  
 434      /**

 435       * Update the name dependent caches

 436       *

 437       * This is especially useful after a name change of one of the files in the list

 438       */
 439  	function update_caches()
 440      {
 441          $this->_md5_ID_index = array();
 442          $this->_full_path_index = array();
 443          $this->_rdfs_rel_path_index = array();
 444  
 445          $count = 0;
 446          foreach( $this->_entries as $loop_File )
 447          {
 448              $this->_md5_ID_index[$loop_File->get_md5_ID()] = $count;
 449              $this->_full_path_index[$loop_File->get_full_path()] = $count;
 450              $this->_rdfs_rel_path_index[$loop_File->get_rdfs_rel_path()] = $count;
 451              $count++;
 452          }
 453      }
 454  
 455  
 456      /**

 457       * Add a file to the list, by filename.

 458       *

 459       * This is a stub for {@link Filelist::add()}.

 460       *

 461       * @param string Subpath for this file/folder, relative the associated root, including trailing slash (if directory)

 462       * @param boolean Has the file to exist to get added?

 463       * @return boolean true on success, false on failure (path not allowed,

 464       *                 file does not exist)

 465       */
 466  	function add_by_subpath( $rel_path, $mustExist = false )
 467      {
 468          $FileCache = & get_Cache( 'FileCache' );
 469          $NewFile = & $FileCache->get_by_root_and_path( $this->_FileRoot->type, $this->_FileRoot->in_type_ID, $rel_path );
 470  
 471          return $this->add( $NewFile, $mustExist );
 472      }
 473  
 474  
 475      /**

 476       * Sort the entries by sorting the internal {@link $_order_index} array.

 477       *

 478       * @param string The order to use ('name', 'type', 'lastmod', .. )

 479       * @param boolean Ascending (true) or descending

 480       * @param boolean Sort directories at top?

 481       */
 482  	function sort( $order = NULL, $orderasc = NULL, $dirsattop = NULL )
 483      {
 484          if( ! $this->_total_entries )
 485          {
 486              return false;
 487          }
 488  
 489          if( $order !== NULL )
 490          { // New order
 491              $this->_order = $order;
 492          }
 493          elseif( $this->_order === NULL )
 494          { // Init
 495              $this->_order = 'name';
 496          }
 497  
 498          if( $orderasc !== NULL )
 499          { // New ascending/descending setting
 500              $this->_order_asc = $orderasc;
 501          }
 502          elseif( $this->_order_asc === NULL )
 503          { // Init: ascending for 'name' and 'path', else descending
 504              $this->_order_asc = ( ( $this->_order == 'name' || $this->_order == 'path' ) ? 1 : 0 );
 505          }
 506  
 507          if( $dirsattop !== NULL )
 508          {
 509              $this->_dirs_not_at_top = ! $dirsattop;
 510          }
 511  
 512          usort( $this->_order_index, array( $this, '_sort_callback' ) );
 513  
 514          // Reset the iterator:

 515          $this->restart();
 516      }
 517  
 518  
 519      /**

 520       * usort callback function for {@link Filelist::sort()}

 521       *

 522       * @access protected

 523       * @return integer

 524       */
 525  	function _sort_callback( $a, $b )
 526      {
 527          $FileA = & $this->_entries[$a];
 528          $FileB = & $this->_entries[$b];
 529  
 530          // What colmun are we sorting on?

 531          switch( $this->_order )
 532          {
 533              case 'size':
 534                  if( $this->_use_recursive_dirsize )
 535                  {    // We are using recursive directory sizes:
 536                      $r = $FileA->get_size() - $FileB->get_size();
 537                  }
 538                  else
 539                  {
 540                      $r = $FileA->is_dir() && $FileB->is_dir() ?
 541                                      strcasecmp( $FileA->get_name(), $FileB->get_name() ) :
 542                                      ( $FileA->get_size() - $FileB->get_size() );
 543                  }
 544                  break;
 545  
 546              case 'path': // group by dir
 547                  $r = strcasecmp( $FileA->get_dir(), $FileB->get_dir() );
 548                  if( $r == 0 )
 549                  {
 550                      $r = strcasecmp( $FileA->get_name(), $FileB->get_name() );
 551                  }
 552                  break;
 553  
 554              case 'lastmod':
 555                  $r = $FileB->get_lastmod_ts() - $FileA->get_lastmod_ts();
 556                  break;
 557  
 558              case 'perms':
 559                  // This will use literal representation ( 'r', 'r+w' / octal )

 560                  $r = strcasecmp( $FileA->get_perms(), $FileB->get_perms() );
 561                  break;
 562  
 563              case 'fsowner':
 564                  $r = strcasecmp( $FileA->get_fsowner_name(), $FileB->get_fsowner_name() );
 565                  break;
 566  
 567              case 'fsgroup':
 568                  $r = strcasecmp( $FileA->get_fsgroup_name(), $FileB->get_fsgroup_name() );
 569                  break;
 570  
 571              case 'type':
 572                  if( $r = strcasecmp( $FileA->get_type(), $FileB->get_type() ) )
 573                  {
 574                      break;
 575                  }
 576                  // same type: continue to name:

 577              default:
 578              case 'name':
 579                  $r = strcasecmp( $FileA->get_name(), $FileB->get_name() );
 580                  if( $r == 0 )
 581                  { // same name: look at path
 582                      $r = strcasecmp( $FileA->get_dir(), $FileB->get_dir() );
 583                  }
 584                  break;
 585          }
 586  
 587          if( ! $this->_order_asc )
 588          { // We want descending order: switch order
 589              $r = - $r;
 590          }
 591  
 592          if( ! $this->_dirs_not_at_top )
 593          {    // We want dirs to be on top, always:
 594              if( $FileA->is_dir() && !$FileB->is_dir() )
 595              {
 596                  $r = -1;
 597              }
 598              elseif( $FileB->is_dir() && !$FileA->is_dir() )
 599              {
 600                  $r = 1;
 601              }
 602          }
 603  
 604          return $r;
 605      }
 606  
 607  
 608      /**

 609       * Get the used order.

 610       *

 611       * @return string

 612       */
 613  	function get_sort_order()
 614      {
 615          return $this->translate_order( $this->_order );
 616      }
 617  
 618  
 619      /**

 620       * Get the link to sort by a column. Handle current order and appends an

 621       * icon to reflect the current state (ascending/descending), if the column

 622       * is the same we're sorting by.

 623       *

 624       * @todo get this outta here. This is NOT a displayable object.

 625       * We might want to have a "FileListResults" object that derives from Widget/Results/FilteredResults (the more the better)

 626       * This object is what the SQL or the ItemQuery object is to Results or to ItemList2. The model and the display should not be mixed.

 627       * IF NOT doing the clean objects, move this at least to file.funcs.

 628       *

 629       * @param string The type (name, path, size, ..)

 630       * @param string The text for the anchor.

 631       * @return string

 632       */
 633  	function get_sort_link( $type, $atext )
 634      {
 635          global $AdminUI;
 636  
 637          $newAsc = $this->_order == $type ? (1 - $this->is_sorting_asc()) :  1;
 638  
 639          $r = '<a href="'.regenerate_url( 'fm_order,fm_orderasc', 'fm_order='.$type.'&amp;fm_orderasc='.$newAsc ).'" title="'.T_('Change Order').'"';
 640  
 641          /**

 642           * @todo get this outta here. This is NOT a displayable object.

 643           * We might want to have a "FileListResults" object that derives from Widget/Results/FilteredResults (the more the better)

 644           * This object is what the SQL or the ItemQuery object is to Results or to ItemList2. The model and the display should not be mixed.

 645           * IF NOT doing the clean objects, move this at least to file.funcs.

 646           */
 647          $result_params = $AdminUI->get_template('Results');
 648  
 649  
 650          // Sorting icon:

 651          if( $this->_order != $type )
 652          { // Not sorted on this column:
 653              $r .= ' class="basic_sort_link">'.$result_params['basic_sort_off'];
 654          }
 655          elseif( $this->is_sorting_asc($type) )
 656          { // We are sorting on this column , in ascneding order:
 657              $r .=    ' class="basic_current">'.$result_params['basic_sort_asc'];
 658          }
 659          else
 660          { // Descending order:
 661              $r .=    ' class="basic_current">'.$result_params['basic_sort_desc'];
 662          }
 663  
 664          $r .= ' '.$atext;
 665  
 666  
 667          return $r.'</a>';
 668      }
 669  
 670  
 671      /**

 672       * Reset the iterator

 673       */
 674  	function restart()
 675      {
 676          $this->_current_idx = -1;
 677      }
 678  
 679  
 680      /**

 681       * Are we sorting ascending?

 682       *

 683       * @param string The type (empty for current order type)

 684       * @return integer 1 for ascending sorting, 0 for descending

 685       */
 686  	function is_sorting_asc( $col = '' )
 687      {
 688          if( $this->_order_asc === NULL )
 689          { // We have not specified a sort order by now, use default:
 690              if( empty($col) )
 691              {
 692                  $col = $this->_order;
 693              }
 694              return ( $col == 'name' || $col == 'path' ) ? 1 : 0;
 695          }
 696          else
 697          {    // Use previsously specified sort order:
 698              return ( $this->_order_asc ) ? 1 : 0;
 699          }
 700      }
 701  
 702  
 703      /**

 704       * Set the filter.

 705       *

 706       * @param string Filter string (for regular expressions, if no delimiter/modifiers are included, we try magically adding them)

 707       * @param boolean Is the filter a regular expression? (it's a glob pattern otherwise)

 708       */
 709  	function set_filter( $filter_string, $filter_is_regexp )
 710      {
 711          global $Messages;
 712  
 713          $this->_filter_is_regexp = $filter_is_regexp;
 714  
 715          if( $this->_filter_is_regexp && ! empty($filter_string) )
 716          {
 717              if( ! is_regexp( $filter_string, true ) )
 718              {
 719                  // Try with adding delimiters:

 720                  $filter_string_delim = '~'.str_replace( '~', '\~', $filter_string ).'~';
 721                  if( is_regexp( $filter_string_delim, true ) )
 722                  {
 723                      $filter_string = $filter_string_delim;
 724                  }
 725                  else
 726                  {
 727                      $Messages->add( sprintf( T_('The filter &laquo;%s&raquo; is not a regular expression.'), $filter_string ), 'fl_error' );
 728                      $filter_string = '~.*~';
 729                  }
 730              }
 731          }
 732  
 733          $this->_filter = empty($filter_string) ? NULL : $filter_string;
 734      }
 735  
 736  
 737      /**

 738       * Is a filter active?

 739       *

 740       * @return boolean

 741       */
 742  	function is_filtering()
 743      {
 744          return ($this->_filter !== NULL);
 745      }
 746  
 747  
 748      /**

 749       * Does the list contain a specific File?

 750       *

 751       * @param File the File object to look for

 752       * @return boolean

 753       */
 754  	function contains( & $File )
 755      {
 756          return isset( $this->_md5_ID_index[ $File->get_md5_ID() ] );
 757      }
 758  
 759  
 760      /**

 761       * Return the current filter

 762       *

 763       * @param boolean add a note when it's a regexp or no filter?

 764       * @return string the filter

 765       */
 766  	function get_filter( $verbose = true )
 767      {
 768          if( $this->_filter === NULL )
 769          {    // Filtering is not active
 770              return $verbose ? T_('No filter') : '';
 771          }
 772          else
 773          {    // Filtering is active
 774              return $this->_filter
 775                              .( $verbose && $this->_filter_is_regexp ? ' ('.T_('regular expression').')' : '' );
 776          }
 777      }
 778  
 779  
 780      /**

 781       * Is the current Filter a regexp?

 782       *

 783       * @return NULL|boolean true if regexp, NULL if no filter set

 784       */
 785  	function is_filter_regexp()
 786      {
 787          return $this->_filter_is_regexp;
 788      }
 789  
 790  
 791      /**

 792       * Get the total number of entries in the list.

 793       *

 794       * @return integer

 795       */
 796  	function count()
 797      {
 798          return $this->_total_entries;
 799      }
 800  
 801  
 802      /**

 803       * Get the total number of directories in the list

 804       *

 805       * @return integer

 806       */
 807  	function count_dirs()
 808      {
 809          return $this->_total_dirs;
 810      }
 811  
 812  
 813      /**

 814       * Get the total number of files in the list

 815       *

 816       * @return integer

 817       */
 818  	function count_files()
 819      {
 820          return $this->_total_files;
 821      }
 822  
 823  
 824      /**

 825       * Get the total number of bytes of all files in the list

 826       *

 827       * @return integer

 828       */
 829  	function count_bytes()
 830      {
 831          return $this->_total_bytes;
 832      }
 833  
 834  
 835      /**

 836       * Get the next entry and increment internal counter.

 837       *

 838       * @param string can be used to query only 'file's or 'dir's.

 839       * @return File object (by reference) on success, false on end of list

 840       */
 841      function & get_next( $type = '' )
 842      {
 843          /*

 844           * DEBUG: return the same file 10 times, useful for profiling

 845              static $debugMakeLonger = 0;

 846              if( $debugMakeLonger-- == 0 )

 847              {

 848                  $this->_current_idx++;

 849                  $debugMakeLonger = 9;

 850              }

 851          */
 852  
 853          if( !isset($this->_order_index[$this->_current_idx + 1]) )
 854          {    // End of list:
 855              $r = false;
 856              return $r;
 857          }
 858          $this->_current_idx++;
 859  
 860          $index = $this->_order_index[$this->_current_idx];
 861  
 862          if( $type != '' )
 863          {
 864              if( $type == 'dir' && !$this->_entries[ $index ]->is_dir() )
 865              { // we want a dir
 866                  $r = & $this->get_next( 'dir' );
 867                  return $r;
 868              }
 869              elseif( $type == 'file' && $this->_entries[ $index ]->is_dir() )
 870              { // we want a file
 871                  $r = & $this->get_next( 'file' );
 872                  return $r;
 873              }
 874          }
 875  
 876          return $this->_entries[ $index ];
 877      }
 878  
 879  
 880      /**

 881       * Get a file by its relative (to root) path.

 882       *

 883       * @param string the RELATIVE path (with ending slash for directories)

 884       * @return mixed File object (by reference) on success, false on failure.

 885       */
 886      function & get_by_rdfs_path( $rdfs_path )
 887      {
 888          $path = str_replace( '\\', '/', $rdfs_path );
 889  
 890          if( isset( $this->_rdfs_rel_path_index[ $rdfs_path ] ) )
 891          {
 892              return $this->_entries[ $this->_rdfs_rel_path_index[ $rdfs_path ] ];
 893          }
 894          else
 895          {
 896              $r = false;
 897              return $r;
 898          }
 899      }
 900  
 901  
 902      /**

 903       * Get a file by its full path.

 904       *

 905       * @param string the full/absolute path (with ending slash for directories)

 906       * @return mixed File object (by reference) on success, false on failure.

 907       */
 908      function & get_by_full_path( $adfs_path )
 909      {
 910          $path = str_replace( '\\', '/', $adfs_path );
 911  
 912          if( isset( $this->_full_path_index[ $adfs_path ] ) )
 913          {
 914              return $this->_entries[ $this->_full_path_index[ $adfs_path ] ];
 915          }
 916          else
 917          {
 918              $r = false;
 919              return $r;
 920          }
 921      }
 922  
 923  
 924      /**

 925       * Get a file by it's ID.

 926       *

 927       * @param string the ID (MD5 of path and name)

 928       * @return mixed File object (by reference) on success, false on failure.

 929       */
 930      function & get_by_md5_ID( $md5id )
 931      {
 932          if( isset( $this->_md5_ID_index[ $md5id ] ) )
 933          {
 934              return $this->_entries[ $this->_md5_ID_index[ $md5id ] ];
 935          }
 936          else
 937          {
 938              $r = false;
 939              return $r;
 940          }
 941      }
 942  
 943  
 944      /**

 945       * Get a file by index.

 946       *

 947       * @param integer Index of the entries (starting with 0)

 948       * @param boolean added by fp (set to false when it's a problem)

 949       * @return File

 950       */
 951      function & get_by_idx( $index, $halt_on_error = true )
 952      {
 953          if( isset( $this->_order_index[ $index ] ) )
 954          {
 955              return $this->_entries[ $this->_order_index[ $index ] ];
 956          }
 957          elseif( !$halt_on_error )
 958          {
 959              $r = false;
 960              return $r;
 961          }
 962  
 963          debug_die( 'Requested file does not exist!' );
 964      }
 965  
 966  
 967      /**

 968       * Get the FileLists FileRoot

 969       *

 970       * @return FileRoot

 971       */
 972      function & get_FileRoot()
 973      {
 974          return $this->_FileRoot;
 975      }
 976  
 977  
 978      /**

 979       * Get the FileLists root type.

 980       *

 981       * @return string

 982       */
 983  	function get_root_type()
 984      {
 985          return $this->_FileRoot->type;
 986      }
 987  
 988  
 989      /**

 990       * Get the FileLists root ID (in_type_ID).

 991       *

 992       * @return FileRoot

 993       */
 994  	function get_root_ID()
 995      {
 996          return $this->_FileRoot->in_type_ID;
 997      }
 998  
 999  
1000      /**

1001       * Get absolute path to list.

1002       */
1003  	function get_ads_list_path()
1004      {
1005          return $this->_ads_list_path;
1006      }
1007  
1008      /**

1009       * Get path to list relative to root.

1010       */
1011  	function get_rds_list_path()
1012      {
1013          return $this->_rds_list_path;
1014      }
1015  
1016  
1017      /**

1018       * Get the path (and name) of a {@link File} relative to the {@link Filelist::$_FileRoot::$ads_path}.

1019       *

1020       * @param string

1021       * @return string

1022       */
1023  	function rdfs_relto_root_from_adfs( $adfs_path )
1024      {
1025          // Check that the file is inside root:

1026          if( substr( $adfs_path, 0, strlen($this->_FileRoot->ads_path) ) != $this->_FileRoot->ads_path )
1027          {
1028              debug_die( 'rdfs_relto_root_from_adfs: Path is NOT inside of root!' );
1029          }
1030  
1031          // Return only the relative part:

1032          return substr( $adfs_path, strlen($this->_FileRoot->ads_path) );
1033      }
1034  
1035  
1036      /**

1037       * Removes a {@link File} from the entries list.

1038       *

1039       * This handles indexes and number of total entries, bytes, files/dirs.

1040       *

1041       * @return boolean true on success, false if not found in list.

1042       */
1043  	function remove( & $File )
1044      {
1045          if( isset( $this->_md5_ID_index[ $File->get_md5_ID() ] ) )
1046          {
1047              $this->_total_entries--;
1048              $this->_total_bytes -= $File->get_size();
1049  
1050              if( $File->is_dir() )
1051              {
1052                  $this->_total_dirs--;
1053              }
1054              else
1055              {
1056                  $this->_total_files--;
1057              }
1058  
1059              // unset from indexes

1060              $index = $this->_full_path_index[ $File->get_full_path() ]; // current index

1061              unset( $this->_entries[ $this->_md5_ID_index[ $File->get_md5_ID() ] ] );
1062              unset( $this->_md5_ID_index[ $File->get_md5_ID() ] );
1063              unset( $this->_full_path_index[ $File->get_full_path() ] );
1064              unset( $this->_rdfs_rel_path_index[ $File->get_rdfs_rel_path() ] );
1065  
1066              // get the ordered index right: move all next files downwards

1067              $order_key = array_search( $index, $this->_order_index );
1068              unset( $this->_order_index[$order_key] );
1069              $this->_order_index = array_values( $this->_order_index );
1070  
1071              if( $this->_current_idx > -1 && $this->_current_idx >= $order_key )
1072              { // We have removed a file before or at the $order_key'th position
1073                  $this->_current_idx--;
1074              }
1075              return true;
1076          }
1077          return false;
1078      }
1079  
1080  
1081      /**

1082       * Get the list of File entries.

1083       *

1084       * You can use a method on each object to get this as result instead of the object

1085       * itself.

1086       *

1087       * @param string Use this method on every File and put the result into the list.

1088       * @return array The array with the File objects or method results

1089       */
1090  	function get_array( $method = NULL )
1091      {
1092          $r = array();
1093  
1094          if( is_string($method) )
1095          {
1096              foreach( $this->_order_index as $index )
1097              {
1098                  $r[] = $this->_entries[ $index ]->$method();
1099              }
1100          }
1101          else
1102          {
1103              foreach( $this->_order_index as $index )
1104              {
1105                  $r[] = & $this->_entries[ $index ];
1106              }
1107          }
1108  
1109          return $r;
1110      }
1111  
1112  
1113      /**

1114       * Get a MD5 checksum over the entries.

1115       * Used to identify a unique filelist.

1116       *

1117       * @return string md5 hash

1118       */
1119  	function md5_checksum()
1120      {
1121          return md5( serialize( $this->_entries ) );
1122      }
1123  
1124  
1125      /**

1126       * Attempt to load meta data for all files in the list.

1127       *

1128       * Will attempt only once per file and cache the result.

1129       */
1130  	function load_meta()
1131      {
1132          global $DB, $Debuglog;
1133  
1134          $to_load = array();
1135  
1136          for( $i=0; $i<count($this->_entries); $i++ )
1137          {    // For each file:
1138              $loop_File = & $this->_entries[$i];
1139              // echo '<br>'.$loop_File->get_full_path();

1140  
1141              if( $loop_File->meta != 'unknown' )
1142              { // We have already loaded meta data:
1143                  continue;
1144              }
1145  
1146              $to_load[] = $DB->quote( $loop_File->get_rdfp_rel_path() );
1147          }
1148  
1149          if( count( $to_load ) )
1150          {    // We have something to load...
1151              /**

1152               * @var FileCache

1153               */
1154              $FileCache = & get_Cache( 'FileCache' );
1155  
1156              $rows = $DB->get_results( "
1157                  SELECT *
1158                    FROM T_files
1159                   WHERE file_root_type = '".$this->_FileRoot->type."'
1160                     AND file_root_ID = ".$this->_FileRoot->in_type_ID."
1161                     AND file_path IN (".implode( ',', $to_load ).")",
1162                  OBJECT, 'Load FileList meta data' );
1163  
1164              if( count($rows) )
1165              { // Go through rows of loaded meta data...
1166                  foreach( $rows as $row )
1167                  {
1168                      // Retrieve matching File object:

1169                      /**

1170                       * @var File

1171                       */
1172                      $loop_File = & $FileCache->get_by_root_and_path( $row->file_root_type, $row->file_root_ID, $row->file_path );
1173  
1174                      // Associate meta data to File object:

1175                      $loop_File->load_meta( false, $row );
1176                  }
1177              }
1178          }
1179  
1180          // For all Files that still have no meta data, memorize that we could not find any meta data

1181          for( $i=0; $i<count($this->_entries); $i++ )
1182          {    // For each file:
1183              $loop_File = & $this->_entries[$i];
1184  
1185              if( $loop_File->meta == 'unknown' )
1186              {
1187                  $loop_File->meta = 'notfound';
1188              }
1189          }
1190  
1191          // Has sth been loaded?

1192          return count( $to_load ) && count($rows);
1193      }
1194  
1195  
1196      /**

1197       * Returns cwd, where the accessible directories (below root) are clickable

1198       *

1199       * @return string cwd as clickable html

1200       */
1201  	function get_cwd_clickable( $clickableOnly = true )
1202      {
1203          if( empty($this->_ads_list_path) )
1204          {
1205              return ' -- '.T_('No directory.').' -- ';
1206          }
1207  
1208          // Get the part of the path which is not clickable:

1209          $r = substr( $this->_FileRoot->ads_path, 0, strrpos( substr($this->_FileRoot->ads_path, 0, -1), '/' )+1 );
1210  
1211          // get the part that is clickable

1212          $clickabledirs = explode( '/', substr( $this->_ads_list_path, strlen($r) ) );
1213  
1214          if( $clickableOnly )
1215          {
1216              $r = '';
1217          }
1218  
1219          $cd = '';
1220          foreach( $clickabledirs as $nr => $dir )
1221          {
1222              if( empty($dir) )
1223              {
1224                  break;
1225              }
1226              if( $nr )
1227              {
1228                  $cd .= $dir.'/';
1229              }
1230              $r .= '<a href="'.regenerate_url( 'path', 'path='.$cd )
1231                      .'" title="'.T_('Change to this directory').'">'.$dir.'</a>/';
1232          }
1233  
1234          return $r;
1235      }
1236  
1237  }
1238  
1239  /*

1240   * $Log: _filelist.class.php,v $

1241   * Revision 1.1  2007/06/25 10:59:55  fplanque

1242   * MODULES (refactored MVC)

1243   *

1244   * Revision 1.28  2007/06/19 23:15:08  blueyed

1245   * doc fixes

1246   *

1247   * Revision 1.27  2007/04/26 00:11:10  fplanque

1248   * (c) 2007

1249   *

1250   * Revision 1.26  2007/02/10 18:01:58  waltercruz

1251   * Changing double quotes to single quotes

1252   *

1253   * Revision 1.25  2007/01/24 13:28:38  fplanque

1254   * todo

1255   *

1256   * Revision 1.24  2007/01/24 13:26:56  fplanque

1257   * fixed sort by type

1258   *

1259   * Revision 1.23  2007/01/24 12:18:25  blueyed

1260   * Fixed PHP-fnmatch() implementation (for Windows)

1261   *

1262   * Revision 1.22  2006/12/24 00:52:56  fplanque

1263   * Make posts with images - Proof of concept

1264   *

1265   * Revision 1.21  2006/12/07 23:13:10  fplanque

1266   * @var needs to have only one argument: the variable type

1267   * Otherwise, I can't code!

1268   *

1269   * Revision 1.20  2006/12/07 20:03:32  fplanque

1270   * Woohoo! File editing... means all skin editing.

1271   *

1272   * Revision 1.19  2006/11/24 18:27:24  blueyed

1273   * Fixed link to b2evo CVS browsing interface in file docblocks

1274   */
1275  ?>


Généré le : Thu Nov 29 23:58:50 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics