2001-05-25 05:34:24 +02:00
< ? php
2005-07-22 19:59:09 +02:00
/************************************************************************** \
* eGroupWare API - VFS *
* This file written by Jason Wies ( Zone ) < zone @ phpgroupware . org > *
* This class handles file / dir access for eGroupWare *
* Copyright ( C ) 2001 Jason Wies *
* Database layer reworked 2005 / 09 / 20 by RalfBecker - AT - outdoor - training . de *
* -------------------------------------------------------------------------*
* This library is part of the eGroupWare API *
* ------------------------------------------------------------------------ *
* This library is free software ; you can redistribute it and / or modify it *
* under the terms of the GNU Lesser General Public License as published by *
* the Free Software Foundation ; either version 2.1 of the License , *
* or any later version . *
* This library is distributed in the hope that it will be useful , but *
* WITHOUT ANY WARRANTY ; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . *
* See the GNU Lesser General Public License for more details . *
* You should have received a copy of the GNU Lesser General Public License *
* along with this library ; if not , write to the Free Software Foundation , *
* Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA *
\ **************************************************************************/
/* $Id$ */
/**
* Virtual File System with SQL backend
*
* Authors : Zone
*/
2001-05-25 05:34:24 +02:00
2001-07-10 23:35:23 +02:00
/* These are used in calls to extra_sql () */
2001-08-10 02:03:02 +02:00
define ( 'VFS_SQL_SELECT' , 1 );
define ( 'VFS_SQL_DELETE' , 2 );
2001-08-11 11:01:47 +02:00
define ( 'VFS_SQL_UPDATE' , 4 );
2001-07-11 07:57:04 +02:00
2003-02-17 20:34:56 +01:00
class vfs extends vfs_shared
2001-05-25 05:34:24 +02:00
{
2001-08-11 11:01:47 +02:00
var $working_id ;
var $working_lid ;
var $meta_types ;
2001-12-10 05:04:56 +01:00
var $now ;
2004-09-20 12:50:46 +02:00
var $file_actions ; // true if the content is stored in the file-system, false if it's stored in the DB too
2005-02-26 15:00:02 +01:00
var $vfs_table = 'egw_vfs' ;
var $vfs_column_prefix = 'vfs_' ;
2001-09-28 22:41:36 +02:00
2005-07-22 19:59:09 +02:00
/**
* constructor , sets up variables
*
*/
2001-08-11 11:01:47 +02:00
function vfs ()
2001-05-25 05:34:24 +02:00
{
2003-02-17 20:34:56 +01:00
$this -> vfs_shared ();
2005-07-22 19:59:09 +02:00
$this -> basedir = $GLOBALS [ 'egw_info' ][ 'server' ][ 'files_dir' ];
$this -> working_id = $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ];
$this -> working_lid = $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_lid' ];
2001-09-28 22:41:36 +02:00
$this -> now = date ( 'Y-m-d' );
2001-08-11 11:01:47 +02:00
/*
2005-07-22 19:59:09 +02:00
File / dir attributes , each corresponding to a database field . Useful for use in loops
If an attribute was added to the table , add it here and possibly add it to
set_attributes ()
2001-12-10 05:04:56 +01:00
2005-07-22 19:59:09 +02:00
set_attributes now uses this array () . 07 - Dec - 01 skeeter
2001-08-11 11:01:47 +02:00
*/
2001-09-28 22:41:36 +02:00
2003-02-17 20:34:56 +01:00
$this -> attributes [] = 'deleteable' ;
$this -> attributes [] = 'content' ;
2002-08-26 06:20:33 +02:00
2005-02-26 15:00:02 +01:00
// set up the keys as db-column-names
foreach ( $this -> attributes as $n => $attr )
{
unset ( $this -> attributes [ $n ]);
$this -> attributes [ $this -> vfs_column_prefix . $attr ] = $attr ;
}
2002-08-26 06:20:33 +02:00
/*
2005-07-22 19:59:09 +02:00
Decide whether to use any actual filesystem calls ( fopen (), fread (),
unlink (), rmdir (), touch (), etc . ) . If not , then we ' re working completely
in the database .
2002-08-26 06:20:33 +02:00
*/
2005-07-22 19:59:09 +02:00
$this -> file_actions = $GLOBALS [ 'egw_info' ][ 'server' ][ 'file_store_contents' ] == 'filesystem' ||
! $GLOBALS [ 'egw_info' ][ 'server' ][ 'file_store_contents' ];
2004-02-08 23:30:14 +01:00
2003-08-28 16:31:11 +02:00
// test if the files-dir is inside the document-root, and refuse working if so
//
if ( $this -> file_actions && $this -> in_docroot ( $this -> basedir ))
{
2005-07-22 19:59:09 +02:00
$GLOBALS [ 'egw' ] -> common -> egw_header ();
if ( $GLOBALS [ 'egw_info' ][ 'flags' ][ 'noheader' ])
2003-08-28 16:31:11 +02:00
{
echo parse_navbar ();
}
echo '<p align="center"><font color="red"><b>' . lang ( 'Path to user and group files HAS TO BE OUTSIDE of the webservers document-root!!!' ) . " </b></font></p> \n " ;
2005-07-22 19:59:09 +02:00
$GLOBALS [ 'egw' ] -> common -> egw_exit ();
2003-08-28 16:31:11 +02:00
}
2001-08-11 11:01:47 +02:00
/*
2005-07-22 19:59:09 +02:00
These are stored in the MIME - type field and should normally be ignored .
Adding a type here will ensure it is normally ignored , but you will have to
explicitly add it to acl_check (), and to any other SELECT ' s in this file
2001-08-11 11:01:47 +02:00
*/
2001-09-28 22:41:36 +02:00
$this -> meta_types = array ( 'journal' , 'journal-deleted' );
2004-09-20 12:50:46 +02:00
2005-07-22 19:59:09 +02:00
$this -> db = clone ( $GLOBALS [ 'egw' ] -> db );
2004-09-20 12:50:46 +02:00
$this -> db -> set_app ( 'phpgwapi' );
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
/* We store the linked directories in an array now, so we don't have to make the SQL call again */
2004-09-20 12:50:46 +02:00
switch ( $this -> db -> Type )
2002-04-08 16:23:27 +02:00
{
2004-09-20 12:50:46 +02:00
case 'mssql' :
case 'sybase' :
$where = array (
2005-02-26 15:00:02 +01:00
" CONVERT(varchar,vfs_link_directory) != '' " ,
" CONVERT(varchar,vfs_link_name) != '' " ,
2004-09-20 12:50:46 +02:00
);
break ;
default :
$where = array (
2005-02-26 15:00:02 +01:00
" (vfs_link_directory IS NOT NULL OR vfs_link_directory != '') " ,
" (vfs_link_name IS NOT NULL OR vfs_link_name != '') " ,
2004-09-20 12:50:46 +02:00
);
break ;
2002-04-08 16:23:27 +02:00
}
2004-09-20 12:50:46 +02:00
$where [] = $this -> extra_sql ( array ( 'query_type' => VFS_SQL_SELECT ));
2005-02-26 15:00:02 +01:00
$this -> db -> select ( $this -> vfs_table , 'vfs_directory,vfs_name,vfs_link_directory,vfs_link_name' , $where , __LINE__ , __FILE__ );
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
$this -> linked_dirs = array ();
2004-09-20 12:50:46 +02:00
while ( $this -> db -> next_record ())
2001-08-11 11:01:47 +02:00
{
2005-02-26 15:00:02 +01:00
$this -> linked_dirs [] = array (
'directory' => $this -> db -> Record [ 'vfs_directory' ],
'name' => $this -> db -> Record [ 'vfs_name' ],
'link_directory' => $this -> db -> Record [ 'vfs_link_directory' ],
'link_name' => $this -> db -> Record [ 'vfs_link_name' ],
);
2001-08-11 11:01:47 +02:00
}
2005-03-07 18:08:54 +01:00
$this -> grants = $GLOBALS [ 'egw' ] -> acl -> get_grants ( 'filemanager' );
2001-05-25 05:34:24 +02:00
}
2001-09-28 22:41:36 +02:00
2005-07-22 19:59:09 +02:00
/**
* test if $path lies within the webservers document - root
*
*/
2003-08-28 16:31:11 +02:00
function in_docroot ( $path )
{
2005-07-22 19:59:09 +02:00
$docroots = array ( EGW_SERVER_ROOT , $_SERVER [ 'DOCUMENT_ROOT' ]);
2003-08-28 16:31:11 +02:00
foreach ( $docroots as $docroot )
{
$len = strlen ( $docroot );
if ( $docroot == substr ( $path , 0 , $len ))
{
$rest = substr ( $path , $len );
if ( ! strlen ( $rest ) || $rest [ 0 ] == DIRECTORY_SEPARATOR )
{
return True ;
}
}
}
return False ;
}
2005-07-22 19:59:09 +02:00
/**
* Return extra SQL code that should be appended ( AND ' ed ) to certain queries
*
* @ param query_type The type of query to get extra SQL code for , in the form of a VFS_SQL define
* @ return Extra SQL code
*/
2002-01-16 07:36:51 +01:00
function extra_sql ( $data )
2001-08-11 11:01:47 +02:00
{
2002-01-16 07:36:51 +01:00
if ( ! is_array ( $data ))
{
$data = array ( 'query_type' => VFS_SQL_SELECT );
}
2005-12-02 11:43:39 +01:00
if ( $data [ 'query_type' ] == VFS_SQL_SELECT || $data [ 'query_type' ] == VFS_SQL_DELETE || $data [ 'query_type' ] == VFS_SQL_UPDATE )
2001-07-13 07:12:18 +02:00
{
2005-02-26 15:00:02 +01:00
return " ((vfs_mime_type != ' " . implode ( " ' AND vfs_mime_type != ' " , $this -> meta_types ) . " ') OR vfs_mime_type IS NULL) " ;
2001-07-13 07:12:18 +02:00
}
2004-09-20 12:50:46 +02:00
return '' ;
2001-08-11 11:01:47 +02:00
}
2001-09-28 22:41:36 +02:00
2005-07-22 19:59:09 +02:00
/**
* Add a journal entry after ( or before ) completing an operation ,
*
* * and increment the version number . This function should be used internally only
* Note that state_one and state_two are ignored for some VFS_OPERATION ' s , for others
* * they are required . They are ignored for any " custom " operation
* * The two operations that require state_two :
* * operation * state_two
* * VFS_OPERATION_COPIED fake_full_path of copied to
* * VFS_OPERATION_MOVED * fake_full_path of moved to
* * If deleting , you must call add_journal () before you delete the entry from the database
* @ param string File or directory to add entry for
* @ param relatives Relativity array
* @ param operation The operation that was performed . Either a VFS_OPERATION define or
* * a non - integer descriptive text string
* @ param state_one The first " state " of the file or directory . Can be a file name , size ,
* * location , whatever is appropriate for the specific operation
* @ param state_two The second " state " of the file or directory
* @ param incversion Boolean True / False . Increment the version for the file ? Note that this is
* * handled automatically for the VFS_OPERATION defines .
* * i . e . VFS_OPERATION_EDITED would increment the version , VFS_OPERATION_COPIED
* * would not
* @ return Boolean True / False
*/
2002-01-16 07:36:51 +01:00
function add_journal ( $data )
2001-08-11 11:01:47 +02:00
{
2002-01-16 07:36:51 +01:00
if ( ! is_array ( $data ))
2001-09-24 20:17:26 +02:00
{
2002-01-16 07:36:51 +01:00
$data = array ();
2001-09-24 20:17:26 +02:00
}
2002-01-16 07:36:51 +01:00
$default_values = array
(
'relatives' => array ( RELATIVE_CURRENT ),
'state_one' => False ,
'state_two' => False ,
'incversion' => True
);
$data = array_merge ( $this -> default_values ( $data , $default_values ), $data );
2005-07-22 19:59:09 +02:00
$account_id = $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ];
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$p = $this -> path_parts ( array ( 'string' => $data [ 'string' ], 'relatives' => array ( $data [ 'relatives' ][ 0 ])));
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
/* We check that they have some sort of access to the file other than read */
2005-07-22 19:59:09 +02:00
if ( ! $this -> acl_check ( array ( 'string' => $p -> fake_full_path , 'relatives' => array ( $p -> mask ), 'operation' => EGW_ACL_WRITE )) &&
! $this -> acl_check ( array ( 'string' => $p -> fake_full_path , 'relatives' => array ( $p -> mask ), 'operation' => EGW_ACL_EDIT )) &&
! $this -> acl_check ( array ( 'string' => $p -> fake_full_path , 'relatives' => array ( $p -> mask ), 'operation' => EGW_ACL_DELETE )))
2001-07-13 07:12:18 +02:00
{
2001-08-11 11:01:47 +02:00
return False ;
2001-07-13 07:12:18 +02:00
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
if ( ! $this -> file_exists ( array ( 'string' => $p -> fake_full_path , 'relatives' => array ( $p -> mask ))))
2001-07-11 07:57:04 +02:00
{
2001-08-11 11:01:47 +02:00
return False ;
2001-07-11 07:57:04 +02:00
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$ls_array = $this -> ls ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask ),
'checksubdirs' => False ,
'mime_type' => False ,
'nofiles' => True
)
);
2001-08-11 11:01:47 +02:00
$file_array = $ls_array [ 0 ];
2001-09-28 22:41:36 +02:00
2004-09-20 12:50:46 +02:00
$to_write = array ();
foreach ( $file_array as $attribute => $value )
2001-07-11 07:57:04 +02:00
{
2002-08-26 06:20:33 +02:00
if ( $attribute == 'file_id' || $attribute == 'content' )
2001-07-11 07:57:04 +02:00
{
2001-08-11 11:01:47 +02:00
continue ;
2001-07-11 07:57:04 +02:00
}
2001-09-28 22:41:36 +02:00
if ( $attribute == 'owner_id' )
2001-07-11 07:57:04 +02:00
{
2001-08-11 11:01:47 +02:00
$value = $account_id ;
2001-07-11 07:57:04 +02:00
}
2001-09-28 22:41:36 +02:00
if ( $attribute == 'created' )
2001-07-11 07:57:04 +02:00
{
2001-08-11 11:01:47 +02:00
$value = $this -> now ;
2001-07-11 07:57:04 +02:00
}
2001-08-24 09:44:43 +02:00
2004-09-20 12:50:46 +02:00
if ( $attribute == 'modified' && ! $data [ 'modified' ])
2001-08-24 09:44:43 +02:00
{
unset ( $value );
}
2001-09-28 22:41:36 +02:00
if ( $attribute == 'mime_type' )
2001-07-11 07:57:04 +02:00
{
2001-09-28 22:41:36 +02:00
$value = 'journal' ;
2001-07-11 07:57:04 +02:00
}
2001-09-28 22:41:36 +02:00
if ( $attribute == 'comment' )
2001-08-11 11:01:47 +02:00
{
2002-01-16 07:36:51 +01:00
switch ( $data [ 'operation' ])
2001-08-11 11:01:47 +02:00
{
case VFS_OPERATION_CREATED :
2001-09-28 22:41:36 +02:00
$value = 'Created' ;
2002-01-16 07:36:51 +01:00
$data [ 'incversion' ] = True ;
2001-08-11 11:01:47 +02:00
break ;
case VFS_OPERATION_EDITED :
2001-09-28 22:41:36 +02:00
$value = 'Edited' ;
2002-01-16 07:36:51 +01:00
$data [ 'incversion' ] = True ;
2001-08-11 11:01:47 +02:00
break ;
case VFS_OPERATION_EDITED_COMMENT :
2001-09-28 22:41:36 +02:00
$value = 'Edited comment' ;
2002-01-16 07:36:51 +01:00
$data [ 'incversion' ] = False ;
2001-08-11 11:01:47 +02:00
break ;
case VFS_OPERATION_COPIED :
2002-01-16 07:36:51 +01:00
if ( ! $data [ 'state_one' ])
2001-08-11 11:01:47 +02:00
{
2002-01-16 07:36:51 +01:00
$data [ 'state_one' ] = $p -> fake_full_path ;
2001-08-11 11:01:47 +02:00
}
2002-01-16 07:36:51 +01:00
if ( ! $data [ 'state_two' ])
2001-08-11 11:01:47 +02:00
{
return False ;
}
2002-01-16 07:36:51 +01:00
$value = 'Copied ' . $data [ 'state_one' ] . ' to ' . $data [ 'state_two' ];
$data [ 'incversion' ] = False ;
2001-08-11 11:01:47 +02:00
break ;
case VFS_OPERATION_MOVED :
2002-01-16 07:36:51 +01:00
if ( ! $data [ 'state_one' ])
2001-08-11 11:01:47 +02:00
{
2002-01-16 07:36:51 +01:00
$data [ 'state_one' ] = $p -> fake_full_path ;
2001-08-11 11:01:47 +02:00
}
2002-01-16 07:36:51 +01:00
if ( ! $data [ 'state_two' ])
2001-08-11 11:01:47 +02:00
{
return False ;
}
2002-01-16 07:36:51 +01:00
$value = 'Moved ' . $data [ 'state_one' ] . ' to ' . $data [ 'state_two' ];
$data [ 'incversion' ] = False ;
2001-08-11 11:01:47 +02:00
break ;
case VFS_OPERATION_DELETED :
2001-09-28 22:41:36 +02:00
$value = 'Deleted' ;
2002-01-16 07:36:51 +01:00
$data [ 'incversion' ] = False ;
2001-08-11 11:01:47 +02:00
break ;
default :
2002-01-16 07:36:51 +01:00
$value = $data [ 'operation' ];
2001-08-11 11:01:47 +02:00
break ;
}
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
/*
2005-07-22 19:59:09 +02:00
Let ' s increment the version for the file itself . We keep the current
version when making the journal entry , because that was the version that
was operated on . The maximum numbers for each part in the version string :
none . 99.9 . 9
2001-08-11 11:01:47 +02:00
*/
2002-01-16 07:36:51 +01:00
if ( $attribute == 'version' && $data [ 'incversion' ])
2001-08-11 11:01:47 +02:00
{
2004-09-20 12:50:46 +02:00
$version_parts = explode ( '.' , $value );
$newnumofparts = count ( $version_parts );
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
if ( $version_parts [ 3 ] >= 9 )
{
$version_parts [ 3 ] = 0 ;
$version_parts [ 2 ] ++ ;
$version_parts_3_update = 1 ;
}
elseif ( isset ( $version_parts [ 3 ]))
{
$version_parts [ 3 ] ++ ;
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
if ( $version_parts [ 2 ] >= 9 && $version_parts [ 3 ] == 0 && $version_parts_3_update )
{
$version_parts [ 2 ] = 0 ;
$version_parts [ 1 ] ++ ;
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
if ( $version_parts [ 1 ] > 99 )
{
$version_parts [ 1 ] = 0 ;
$version_parts [ 0 ] ++ ;
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
for ( $i = 0 ; $i < $newnumofparts ; $i ++ )
{
if ( ! isset ( $version_parts [ $i ]))
{
break ;
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
if ( $i )
{
2001-09-28 22:41:36 +02:00
$newversion .= '.' ;
2001-08-11 11:01:47 +02:00
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
$newversion .= $version_parts [ $i ];
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$this -> set_attributes ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask ),
'attributes' => array (
2004-09-20 12:50:46 +02:00
'version' => $newversion
)
2002-01-16 07:36:51 +01:00
)
);
2001-08-11 11:01:47 +02:00
}
2001-08-24 09:44:43 +02:00
if ( isset ( $value ))
{
2005-02-26 15:00:02 +01:00
$to_write [ $this -> vfs_column_prefix . $attribute ] = $value ;
2001-08-24 09:44:43 +02:00
}
2001-07-11 07:57:04 +02:00
}
2001-07-12 01:48:25 +02:00
/*
2005-07-22 19:59:09 +02:00
These are some special situations where we need to flush the journal entries
or move the 'journal' entries to 'journal-deleted' . Kind of hackish , but they
provide a consistent feel to the system
2001-07-12 01:48:25 +02:00
*/
2002-01-16 07:36:51 +01:00
if ( $data [ 'operation' ] == VFS_OPERATION_CREATED )
2001-08-11 11:01:47 +02:00
{
$flush_path = $p -> fake_full_path ;
$deleteall = True ;
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
if ( $data [ 'operation' ] == VFS_OPERATION_COPIED || $data [ 'operation' ] == VFS_OPERATION_MOVED )
2001-08-11 11:01:47 +02:00
{
2002-01-16 07:36:51 +01:00
$flush_path = $data [ 'state_two' ];
2001-08-11 11:01:47 +02:00
$deleteall = False ;
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
if ( $flush_path )
{
2002-01-16 07:36:51 +01:00
$flush_path_parts = $this -> path_parts ( array (
'string' => $flush_path ,
'relatives' => array ( RELATIVE_NONE )
)
);
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$this -> flush_journal ( array (
'string' => $flush_path_parts -> fake_full_path ,
'relatives' => array ( $flush_path_parts -> mask ),
'deleteall' => $deleteall
)
);
2001-08-11 11:01:47 +02:00
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
if ( $data [ 'operation' ] == VFS_OPERATION_COPIED )
2001-08-11 11:01:47 +02:00
{
/*
2005-07-22 19:59:09 +02:00
We copy it going the other way as well , so both files show the operation .
The code is a bad hack to prevent recursion . Ideally it would use VFS_OPERATION_COPIED
2001-08-11 11:01:47 +02:00
*/
2002-01-16 07:36:51 +01:00
$this -> add_journal ( array (
'string' => $data [ 'state_two' ],
'relatives' => array ( RELATIVE_NONE ),
'operation' => 'Copied ' . $data [ 'state_one' ] . ' to ' . $data [ 'state_two' ],
'state_one' => NULL ,
'state_two' => NULL ,
'incversion' => False
)
);
2001-08-11 11:01:47 +02:00
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
if ( $data [ 'operation' ] == VFS_OPERATION_MOVED )
2001-08-11 11:01:47 +02:00
{
2002-01-16 07:36:51 +01:00
$state_one_path_parts = $this -> path_parts ( array (
'string' => $data [ 'state_one' ],
'relatives' => array ( RELATIVE_NONE )
)
);
2001-09-28 22:41:36 +02:00
2005-02-26 15:00:02 +01:00
$this -> db -> update ( $this -> vfs_table , array ( 'vfs_mime_type' => 'journal-deleted' ), array (
'vfs_directory' => $state_one_path_parts -> fake_leading_dirs ,
'vfs_name' => $state_one_path_parts -> fake_name ,
'vfs_mime_type' => 'journal' ,
2004-09-20 12:50:46 +02:00
), __LINE__ , __FILE__ );
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
/*
2005-07-22 19:59:09 +02:00
We create the file in addition to logging the MOVED operation . This is an
advantage because we can now search for 'Create' to see when a file was created
2001-08-11 11:01:47 +02:00
*/
2002-01-16 07:36:51 +01:00
$this -> add_journal ( array (
'string' => $data [ 'state_two' ],
'relatives' => array ( RELATIVE_NONE ),
'operation' => VFS_OPERATION_CREATED
)
);
2001-08-11 11:01:47 +02:00
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
/* This is the SQL query we made for THIS request, remember that one? */
2004-09-20 12:50:46 +02:00
$this -> db -> insert ( $this -> vfs_table , $to_write , false , __LINE__ , __FILE__ );
2001-09-28 22:41:36 +02:00
2001-07-12 01:48:25 +02:00
/*
2005-07-22 19:59:09 +02:00
If we were to add an option of whether to keep journal entries for deleted files
or not , it would go in the if here
2001-07-12 01:48:25 +02:00
*/
2002-01-16 07:36:51 +01:00
if ( $data [ 'operation' ] == VFS_OPERATION_DELETED )
2001-08-11 11:01:47 +02:00
{
2004-09-20 12:50:46 +02:00
$this -> db -> update ( $this -> vfs_table , array (
2005-02-26 15:00:02 +01:00
'vfs_mime_type' => 'journal-deleted'
2004-09-20 12:50:46 +02:00
), array (
2005-02-26 15:00:02 +01:00
'vfs_directory' => $p -> fake_leading_dirs ,
'vfs_name' => $p -> fake_name ,
'vfs_mime_type' => 'journal' ,
2006-01-06 05:55:51 +01:00
), __LINE__ , __FILE__ );
2001-08-11 11:01:47 +02:00
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
return True ;
2001-07-12 01:48:25 +02:00
}
2001-09-28 22:41:36 +02:00
2005-07-22 19:59:09 +02:00
/**
* Flush journal entries for $string . Used before adding $string
*
* flush_journal () is an internal function and should be called from add_journal () only
* @ param string File / directory to flush journal entries of
* @ param relatives Realtivity array
* @ param deleteall Delete all types of journal entries , including the active Create entry .
* * Normally you only want to delete the Create entry when replacing the file
* * Note that this option does not effect $deleteonly
* @ param deletedonly Only flush 'journal-deleted' entries ( created when $string was deleted )
* @ return Boolean True / False
*/
2002-01-16 07:36:51 +01:00
function flush_journal ( $data )
2001-05-25 05:34:24 +02:00
{
2002-01-16 07:36:51 +01:00
if ( ! is_array ( $data ))
2001-09-24 20:17:26 +02:00
{
2002-01-16 07:36:51 +01:00
$data = array ();
2001-09-24 20:17:26 +02:00
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$default_values = array
(
'relatives' => array ( RELATIVE_CURRENT ),
'deleteall' => False ,
'deletedonly' => False
);
$data = array_merge ( $this -> default_values ( $data , $default_values ), $data );
$p = $this -> path_parts ( array (
'string' => $data [ 'string' ],
'relatives' => array ( $data [ 'relatives' ][ 0 ])
)
);
2001-09-28 22:41:36 +02:00
2004-09-20 12:50:46 +02:00
$where = array (
2005-02-26 15:00:02 +01:00
'vfs_directory' => $p -> fake_leading_dirs ,
'vfs_name' => $p -> fake_name ,
2004-09-20 12:50:46 +02:00
);
2002-01-16 07:36:51 +01:00
if ( ! $data [ 'deleteall' ])
2001-08-11 11:01:47 +02:00
{
2005-02-26 15:00:02 +01:00
$where [] = " (vfs_mime_type != 'journal' AND vfs_comment != 'Created') " ;
2001-08-11 11:01:47 +02:00
}
2001-09-28 22:41:36 +02:00
2005-02-26 15:00:02 +01:00
$where [] = " (vfs_mime_type='journal-deleted' " . ( ! $data [ 'deletedonly' ] ? " OR vfs_mime_type='journal' " : '' ) . ')' ;
2001-09-28 22:41:36 +02:00
2004-09-20 12:50:46 +02:00
return !! $this -> db -> delete ( $this -> vfs_table , $where , __LINE__ , __FILE__ );
2001-05-25 05:34:24 +02:00
}
2001-09-28 22:41:36 +02:00
2003-02-17 20:34:56 +01:00
/*
* See vfs_shared
*/
2002-01-16 07:36:51 +01:00
function get_journal ( $data )
2001-05-25 05:34:24 +02:00
{
2002-01-16 07:36:51 +01:00
if ( ! is_array ( $data ))
2001-09-24 20:17:26 +02:00
{
2002-01-16 07:36:51 +01:00
$data = array ();
2001-09-24 20:17:26 +02:00
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$default_values = array
(
'relatives' => array ( RELATIVE_CURRENT ),
'type' => False
);
$data = array_merge ( $this -> default_values ( $data , $default_values ), $data );
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$p = $this -> path_parts ( array (
'string' => $data [ 'string' ],
'relatives' => array ( $data [ 'relatives' ][ 0 ])
)
);
if ( ! $this -> acl_check ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask )
)))
2001-08-11 11:01:47 +02:00
{
return False ;
}
2001-09-28 22:41:36 +02:00
2004-09-20 12:50:46 +02:00
$where = array (
2005-02-26 15:00:02 +01:00
'vfs_directory' => $p -> fake_leading_dirs ,
'vfs_name' => $p -> fake_name ,
2004-09-20 12:50:46 +02:00
);
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
if ( $data [ 'type' ] == 1 )
2001-05-25 05:34:24 +02:00
{
2005-02-26 15:00:02 +01:00
$where [] = " vfs_mime_type='journal' " ;
2001-05-25 05:34:24 +02:00
}
2002-01-16 07:36:51 +01:00
elseif ( $data [ 'type' ] == 2 )
2001-07-02 21:00:31 +02:00
{
2005-02-26 15:00:02 +01:00
$where [] = " vfs_mime_type='journal-deleted' " ;
2001-07-02 21:00:31 +02:00
}
2001-05-25 05:34:24 +02:00
else
{
2005-02-26 15:00:02 +01:00
$where [] = " (vfs_mime_type='journal' OR vfs_mime_type='journal-deleted') " ;
2001-05-25 05:34:24 +02:00
}
2001-09-28 22:41:36 +02:00
2004-09-20 12:50:46 +02:00
$this -> db -> select ( $this -> vfs_table , '*' , $where , __LINE__ , __FILE__ );
2001-09-28 22:41:36 +02:00
2005-02-26 15:00:02 +01:00
while (( $row = $this -> db -> Row ( true )))
2001-08-11 11:01:47 +02:00
{
2005-02-26 15:00:02 +01:00
$rarray [] = $this -> remove_prefix ( $row );
2001-09-28 22:41:36 +02:00
}
2001-08-11 11:01:47 +02:00
return $rarray ;
2001-05-25 05:34:24 +02:00
}
2005-02-26 15:00:02 +01:00
2003-02-17 20:34:56 +01:00
/*
* See vfs_shared
*/
2002-01-16 07:36:51 +01:00
function acl_check ( $data )
2001-07-02 21:00:31 +02:00
{
2002-01-16 07:36:51 +01:00
if ( ! is_array ( $data ))
2001-09-24 20:17:26 +02:00
{
2002-01-16 07:36:51 +01:00
$data = array ();
2001-09-24 20:17:26 +02:00
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$default_values = array
(
'relatives' => array ( RELATIVE_CURRENT ),
2005-07-22 19:59:09 +02:00
'operation' => EGW_ACL_READ ,
2002-01-16 07:36:51 +01:00
'must_exist' => False
);
$data = array_merge ( $this -> default_values ( $data , $default_values ), $data );
2001-08-11 11:01:47 +02:00
/* Accommodate special situations */
2002-01-16 07:36:51 +01:00
if ( $this -> override_acl || $data [ 'relatives' ][ 0 ] == RELATIVE_USER_APP )
2001-08-11 11:01:47 +02:00
{
return True ;
}
2001-09-28 22:41:36 +02:00
2002-06-24 05:18:59 +02:00
if ( ! $data [ 'owner_id' ])
2001-08-11 11:01:47 +02:00
{
2002-06-24 05:18:59 +02:00
$p = $this -> path_parts ( array (
'string' => $data [ 'string' ],
'relatives' => array ( $data [ 'relatives' ][ 0 ])
)
);
2001-09-28 22:41:36 +02:00
2002-06-24 05:18:59 +02:00
/* Temporary, until we get symlink type files set up */
if ( $p -> outside )
2001-08-11 11:01:47 +02:00
{
2002-06-24 05:18:59 +02:00
return True ;
2001-08-11 11:01:47 +02:00
}
2001-09-28 22:41:36 +02:00
2002-06-24 05:18:59 +02:00
/* Read access is always allowed here, but nothing else is */
if ( $data [ 'string' ] == '/' || $data [ 'string' ] == $this -> fakebase )
{
2005-07-22 19:59:09 +02:00
if ( $data [ 'operation' ] == EGW_ACL_READ )
2002-06-24 05:18:59 +02:00
{
return True ;
}
else
{
return False ;
}
}
2001-09-28 22:41:36 +02:00
2002-06-24 05:18:59 +02:00
/* If the file doesn't exist, we get ownership from the parent directory */
2002-01-16 07:36:51 +01:00
if ( ! $this -> file_exists ( array (
2002-06-24 05:18:59 +02:00
'string' => $p -> fake_full_path ,
2002-01-16 07:36:51 +01:00
'relatives' => array ( $p -> mask )
))
)
2001-08-11 11:01:47 +02:00
{
2002-06-24 05:18:59 +02:00
if ( $data [ 'must_exist' ])
{
return False ;
}
2001-09-28 22:41:36 +02:00
2002-06-24 05:18:59 +02:00
$data [ 'string' ] = $p -> fake_leading_dirs ;
$p2 = $this -> path_parts ( array (
'string' => $data [ 'string' ],
'relatives' => array ( $p -> mask )
)
);
if ( ! $this -> file_exists ( array (
'string' => $data [ 'string' ],
'relatives' => array ( $p -> mask )
))
)
{
return False ;
}
2001-08-11 11:01:47 +02:00
}
else
{
2002-06-24 05:18:59 +02:00
$p2 = $p ;
2005-03-07 18:08:54 +01:00
//echo "using parent directory for acl-check, ";
2001-08-11 11:01:47 +02:00
}
2002-06-24 05:18:59 +02:00
/*
2005-07-22 19:59:09 +02:00
We don ' t use ls () to get owner_id as we normally would ,
because ls () calls acl_check (), which would create an infinite loop
2002-06-24 05:18:59 +02:00
*/
2005-02-26 15:00:02 +01:00
$this -> db -> select ( $this -> vfs_table , 'vfs_owner_id' , array (
'vfs_directory' => $p2 -> fake_leading_dirs ,
'vfs_name' => $p2 -> fake_name ,
2004-09-20 12:50:46 +02:00
$this -> extra_sql ( array ( 'query_type' => VFS_SQL_SELECT ))
), __LINE__ , __FILE__ );
$this -> db -> next_record ();
2002-06-24 05:18:59 +02:00
2005-02-26 15:00:02 +01:00
$owner_id = $this -> db -> Record [ 'vfs_owner_id' ];
2002-06-24 05:18:59 +02:00
}
else
{
$owner_id = $data [ 'owner_id' ];
2001-08-11 11:01:47 +02:00
}
2005-03-07 18:08:54 +01:00
//echo "owner=$owner_id, ";
2001-09-28 22:41:36 +02:00
2002-06-24 06:02:14 +02:00
/* This is correct. The ACL currently doesn't handle undefined values correctly */
if ( ! $owner_id )
{
$owner_id = 0 ;
}
2005-07-22 19:59:09 +02:00
$user_id = $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ];
2005-03-07 18:08:54 +01:00
//echo "user=$user_id, ";
2001-08-11 11:01:47 +02:00
/* They always have access to their own files */
2005-10-05 00:59:14 +02:00
/* Files with owner_id = 0 are created by apps, and need at least to be readable */
if ( $owner_id == $user_id || ( $owner_id == 0 && $data [ 'operation' ] == EGW_ACL_READ ))
2001-08-11 11:01:47 +02:00
{
return True ;
}
2005-03-07 18:08:54 +01:00
$rights = $this -> grants [ $owner_id ];
//echo "rights=$rights, ";
2002-01-16 07:36:51 +01:00
if ( $rights & $data [ 'operation' ])
2001-07-02 21:00:31 +02:00
{
2001-08-11 11:01:47 +02:00
return True ;
2001-07-02 21:00:31 +02:00
}
2001-08-11 11:01:47 +02:00
elseif ( ! $rights && $group_ok )
2001-07-02 21:00:31 +02:00
{
2005-07-22 19:59:09 +02:00
return $GLOBALS [ 'egw_info' ][ 'server' ][ 'acl_default' ] == 'grant' ;
2001-07-02 21:00:31 +02:00
}
else
{
return False ;
}
}
2001-09-28 22:41:36 +02:00
2003-02-17 20:34:56 +01:00
/*
* See vfs_shared
*/
2002-01-16 07:36:51 +01:00
function read ( $data )
2001-05-25 05:34:24 +02:00
{
2002-01-16 07:36:51 +01:00
if ( ! is_array ( $data ))
2001-09-24 20:17:26 +02:00
{
2002-01-16 07:36:51 +01:00
$data = array ();
2001-09-24 20:17:26 +02:00
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$default_values = array
(
'relatives' => array ( RELATIVE_CURRENT )
);
$data = array_merge ( $this -> default_values ( $data , $default_values ), $data );
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$p = $this -> path_parts ( array (
'string' => $data [ 'string' ],
'relatives' => array ( $data [ 'relatives' ][ 0 ])
)
);
if ( ! $this -> acl_check ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask ),
2005-07-22 19:59:09 +02:00
'operation' => EGW_ACL_READ
2002-01-16 07:36:51 +01:00
))
)
2001-08-11 11:01:47 +02:00
{
return False ;
}
2001-09-28 22:41:36 +02:00
2002-08-26 06:20:33 +02:00
if ( $this -> file_actions || $p -> outside )
2001-05-25 05:34:24 +02:00
{
2004-09-20 12:50:46 +02:00
if (( $fp = fopen ( $p -> real_full_path , 'rb' )))
2002-08-26 06:20:33 +02:00
{
$contents = fread ( $fp , filesize ( $p -> real_full_path ));
fclose ( $fp );
}
else
{
$contents = False ;
}
2001-05-25 05:34:24 +02:00
}
else
{
2002-08-26 06:20:33 +02:00
$ls_array = $this -> ls ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask ),
)
);
$contents = $ls_array [ 0 ][ 'content' ];
2001-05-25 05:34:24 +02:00
}
2002-01-16 07:36:51 +01:00
2001-12-20 03:38:02 +01:00
return $contents ;
2001-05-25 05:34:24 +02:00
}
2001-09-28 22:41:36 +02:00
2003-02-17 20:34:56 +01:00
/*
* See vfs_shared
*/
2002-01-16 07:36:51 +01:00
function write ( $data )
2001-07-02 21:00:31 +02:00
{
2002-01-16 07:36:51 +01:00
if ( ! is_array ( $data ))
2001-09-24 20:17:26 +02:00
{
2002-01-16 07:36:51 +01:00
$data = array ();
2001-09-24 20:17:26 +02:00
}
2002-01-16 07:36:51 +01:00
$default_values = array
(
'relatives' => array ( RELATIVE_CURRENT ),
'content' => ''
);
$data = array_merge ( $this -> default_values ( $data , $default_values ), $data );
$p = $this -> path_parts ( array (
'string' => $data [ 'string' ],
'relatives' => array ( $data [ 'relatives' ][ 0 ])
)
);
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
if ( $this -> file_exists ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask )
))
)
2001-08-11 11:01:47 +02:00
{
2005-07-22 19:59:09 +02:00
$acl_operation = EGW_ACL_EDIT ;
2001-08-11 11:01:47 +02:00
$journal_operation = VFS_OPERATION_EDITED ;
}
else
{
2005-07-22 19:59:09 +02:00
$acl_operation = EGW_ACL_ADD ;
2001-08-11 11:01:47 +02:00
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
if ( ! $this -> acl_check ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask ),
'operation' => $acl_operation
))
)
2001-08-11 11:01:47 +02:00
{
return False ;
}
2001-09-28 22:41:36 +02:00
2003-10-04 09:37:03 +02:00
umask ( 0177 );
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
/*
2005-07-22 19:59:09 +02:00
If 'string' doesn ' t exist , touch () creates both the file and the database entry
If 'string' does exist , touch () sets the modification time and modified by
2001-08-11 11:01:47 +02:00
*/
2002-01-16 07:36:51 +01:00
$this -> touch ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask )
)
);
2001-09-28 22:41:36 +02:00
2002-08-26 06:20:33 +02:00
if ( $this -> file_actions )
2001-08-11 11:01:47 +02:00
{
2004-09-20 12:50:46 +02:00
if (( $fp = fopen ( $p -> real_full_path , 'wb' )))
2002-08-26 06:20:33 +02:00
{
2004-09-06 05:48:10 +02:00
fwrite ( $fp , $data [ 'content' ]);
2002-08-26 06:20:33 +02:00
fclose ( $fp );
$write_ok = 1 ;
}
}
2001-09-28 22:41:36 +02:00
2002-08-26 06:20:33 +02:00
if ( $write_ok || ! $this -> file_actions )
{
if ( $this -> file_actions )
{
$set_attributes_array = array (
'size' => filesize ( $p -> real_full_path )
);
}
else
{
$set_attributes_array = array (
'size' => strlen ( $data [ 'content' ]),
'content' => $data [ 'content' ]
);
}
$this -> set_attributes ( array
(
2002-01-16 07:36:51 +01:00
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask ),
2002-08-26 06:20:33 +02:00
'attributes' => $set_attributes_array
2002-01-16 07:36:51 +01:00
)
);
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
if ( $journal_operation )
{
2002-01-16 07:36:51 +01:00
$this -> add_journal ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask ),
'operation' => $journal_operation
)
);
2001-08-11 11:01:47 +02:00
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
return True ;
}
else
{
return False ;
}
2001-07-02 21:00:31 +02:00
}
2001-09-28 22:41:36 +02:00
2003-02-17 20:34:56 +01:00
/*
* See vfs_shared
*/
2002-01-16 07:36:51 +01:00
function touch ( $data )
2001-05-25 05:34:24 +02:00
{
2002-01-16 07:36:51 +01:00
if ( ! is_array ( $data ))
2001-09-24 20:17:26 +02:00
{
2002-01-16 07:36:51 +01:00
$data = array ();
2001-09-24 20:17:26 +02:00
}
2002-01-16 07:36:51 +01:00
$default_values = array
(
'relatives' => array ( RELATIVE_CURRENT )
);
$data = array_merge ( $this -> default_values ( $data , $default_values ), $data );
2005-07-22 19:59:09 +02:00
$account_id = $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ];
$currentapp = $GLOBALS [ 'egw_info' ][ 'flags' ][ 'currentapp' ];
2002-01-16 07:36:51 +01:00
$p = $this -> path_parts ( array (
'string' => $data [ 'string' ],
'relatives' => array ( $data [ 'relatives' ][ 0 ])
)
);
2001-09-28 22:41:36 +02:00
2003-10-04 09:37:03 +02:00
umask ( 0177 );
2001-09-28 22:41:36 +02:00
2002-08-26 06:20:33 +02:00
if ( $this -> file_actions )
2001-07-13 07:12:18 +02:00
{
2002-08-26 06:20:33 +02:00
/*
2005-07-22 19:59:09 +02:00
PHP ' s touch function will automatically decide whether to
create the file or set the modification time
2002-08-26 06:20:33 +02:00
*/
$rr = @ touch ( $p -> real_full_path );
if ( $p -> outside )
{
return $rr ;
}
2001-08-11 11:01:47 +02:00
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
/* We, however, have to decide this ourselves */
2002-01-16 07:36:51 +01:00
if ( $this -> file_exists ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask )
))
)
{
if ( ! $this -> acl_check ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask ),
2005-07-22 19:59:09 +02:00
'operation' => EGW_ACL_EDIT
2002-01-16 07:36:51 +01:00
)))
2001-08-11 11:01:47 +02:00
{
return False ;
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$vr = $this -> set_attributes ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask ),
'attributes' => array (
'modifiedby_id' => $account_id ,
'modified' => $this -> now
)
)
);
2001-08-11 11:01:47 +02:00
}
else
{
2002-01-16 07:36:51 +01:00
if ( ! $this -> acl_check ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask ),
2005-07-22 19:59:09 +02:00
'operation' => EGW_ACL_ADD
2002-01-16 07:36:51 +01:00
))
)
2001-08-11 11:01:47 +02:00
{
return False ;
}
2001-09-28 22:41:36 +02:00
2004-09-20 12:50:46 +02:00
$query = $this -> db -> insert ( $this -> vfs_table , array (
2005-02-26 15:00:02 +01:00
'vfs_owner_id' => $this -> working_id ,
'vfs_directory' => $p -> fake_leading_dirs ,
'vfs_name' => $p -> fake_name ,
2004-09-20 12:50:46 +02:00
), false , __LINE__ , __FILE__ );
2002-01-16 07:36:51 +01:00
$this -> set_attributes ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask ),
'attributes' => array (
'createdby_id' => $account_id ,
'created' => $this -> now ,
'size' => 0 ,
'deleteable' => 'Y' ,
'app' => $currentapp
)
)
);
$this -> correct_attributes ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask )
2001-09-28 22:41:36 +02:00
)
);
2001-08-11 11:01:47 +02:00
2002-01-16 07:36:51 +01:00
$this -> add_journal ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask ),
'operation' => VFS_OPERATION_CREATED
)
);
2001-08-11 11:01:47 +02:00
}
2001-09-28 22:41:36 +02:00
2004-09-20 12:50:46 +02:00
return $rr || $vr || $query ;
2001-05-25 05:34:24 +02:00
}
2001-09-28 22:41:36 +02:00
2003-02-17 20:34:56 +01:00
/*
* See vfs_shared
2004-02-08 23:30:14 +01:00
* If $data [ 'symlink' ] the file is symlinked instead of copied
2003-02-17 20:34:56 +01:00
*/
2002-01-16 07:36:51 +01:00
function cp ( $data )
2001-05-25 05:34:24 +02:00
{
2002-01-16 07:36:51 +01:00
if ( ! is_array ( $data ))
2001-09-24 20:17:26 +02:00
{
2002-01-16 07:36:51 +01:00
$data = array ();
2001-09-24 20:17:26 +02:00
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$default_values = array
(
'relatives' => array ( RELATIVE_CURRENT , RELATIVE_CURRENT )
);
$data = array_merge ( $this -> default_values ( $data , $default_values ), $data );
2005-07-22 19:59:09 +02:00
$account_id = $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ];
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$f = $this -> path_parts ( array (
'string' => $data [ 'from' ],
'relatives' => array ( $data [ 'relatives' ][ 0 ])
)
);
$t = $this -> path_parts ( array (
'string' => $data [ 'to' ],
'relatives' => array ( $data [ 'relatives' ][ 1 ])
)
);
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
if ( ! $this -> acl_check ( array (
'string' => $f -> fake_full_path ,
'relatives' => array ( $f -> mask ),
2005-07-22 19:59:09 +02:00
'operation' => EGW_ACL_READ
2002-01-16 07:36:51 +01:00
))
)
2001-07-02 21:00:31 +02:00
{
return False ;
}
2001-09-28 22:41:36 +02:00
2004-09-20 12:50:46 +02:00
if (( $exists = $this -> file_exists ( array (
2002-01-16 07:36:51 +01:00
'string' => $t -> fake_full_path ,
'relatives' => array ( $t -> mask )
2004-09-20 12:50:46 +02:00
)))
2002-01-16 07:36:51 +01:00
)
2001-08-11 11:01:47 +02:00
{
2002-01-16 07:36:51 +01:00
if ( ! $this -> acl_check ( array (
'string' => $t -> fake_full_path ,
'relatives' => array ( $t -> mask ),
2005-07-22 19:59:09 +02:00
'operation' => EGW_ACL_EDIT
2002-01-16 07:36:51 +01:00
))
)
2001-08-11 11:01:47 +02:00
{
return False ;
}
}
else
{
2002-01-16 07:36:51 +01:00
if ( ! $this -> acl_check ( array (
'string' => $t -> fake_full_path ,
'relatives' => array ( $t -> mask ),
2005-07-22 19:59:09 +02:00
'operation' => EGW_ACL_ADD
2002-01-16 07:36:51 +01:00
))
)
2001-08-11 11:01:47 +02:00
{
return False ;
}
}
2001-09-28 22:41:36 +02:00
2003-10-04 09:37:03 +02:00
umask ( 0177 );
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
if ( $this -> file_type ( array (
'string' => $f -> fake_full_path ,
'relatives' => array ( $f -> mask )
)) != 'Directory'
)
2001-08-11 11:01:47 +02:00
{
2002-08-26 06:20:33 +02:00
if ( $this -> file_actions )
2001-08-11 11:01:47 +02:00
{
2004-02-08 23:30:14 +01:00
if ( @ $data [ 'symlink' ])
{
if ( $exists )
{
@ unlink ( $t -> real_full_path );
}
if ( ! symlink ( $f -> real_full_path , $t -> real_full_path ))
{
return False ;
}
}
elseif ( ! copy ( $f -> real_full_path , $t -> real_full_path ))
2002-08-26 06:20:33 +02:00
{
return False ;
}
$size = filesize ( $t -> real_full_path );
}
else
{
$content = $this -> read ( array (
'string' => $f -> fake_full_path ,
'relatives' => array ( $f -> mask )
)
);
$size = strlen ( $content );
2001-08-11 11:01:47 +02:00
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
if ( $t -> outside )
{
return True ;
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$ls_array = $this -> ls ( array (
'string' => $f -> fake_full_path ,
'relatives' => array ( $f -> mask ),
'checksubdirs' => False ,
'mime_type' => False ,
'nofiles' => True
)
);
2001-08-11 11:01:47 +02:00
$record = $ls_array [ 0 ];
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
if ( $this -> file_exists ( array (
'string' => $data [ 'to' ],
'relatives' => array ( $data [ 'relatives' ][ 1 ])
))
)
2001-08-11 11:01:47 +02:00
{
2002-08-26 06:20:33 +02:00
$set_attributes_array = array (
'createdby_id' => $account_id ,
'created' => $this -> now ,
'size' => $size ,
'mime_type' => $record [ 'mime_type' ],
'deleteable' => $record [ 'deleteable' ],
'comment' => $record [ 'comment' ],
'app' => $record [ 'app' ]
);
if ( ! $this -> file_actions )
{
$set_attributes_array [ 'content' ] = $content ;
}
2002-01-16 07:36:51 +01:00
$this -> set_attributes ( array (
'string' => $t -> fake_full_path ,
'relatives' => array ( $t -> mask ),
2002-08-26 06:20:33 +02:00
'attributes' => $set_attributes_array
2002-01-16 07:36:51 +01:00
)
);
$this -> add_journal ( array (
'string' => $t -> fake_full_path ,
'relatives' => array ( $t -> mask ),
'operation' => VFS_OPERATION_EDITED
2001-09-28 22:41:36 +02:00
)
);
2001-08-11 11:01:47 +02:00
}
else
{
2002-01-16 07:36:51 +01:00
$this -> touch ( array (
'string' => $t -> fake_full_path ,
'relatives' => array ( $t -> mask )
)
);
2002-08-26 06:20:33 +02:00
$set_attributes_array = array (
'createdby_id' => $account_id ,
'created' => $this -> now ,
'size' => $size ,
'mime_type' => $record [ 'mime_type' ],
'deleteable' => $record [ 'deleteable' ],
'comment' => $record [ 'comment' ],
'app' => $record [ 'app' ]
);
if ( ! $this -> file_actions )
{
$set_attributes_array [ 'content' ] = $content ;
}
2002-01-16 07:36:51 +01:00
$this -> set_attributes ( array (
2002-08-26 06:20:33 +02:00
'string' => $t -> fake_full_path ,
'relatives' => array ( $t -> mask ),
'attributes' => $set_attributes_array
2001-09-28 22:41:36 +02:00
)
);
2001-08-11 11:01:47 +02:00
}
2002-01-16 07:36:51 +01:00
$this -> correct_attributes ( array (
'string' => $t -> fake_full_path ,
'relatives' => array ( $t -> mask )
)
);
2001-08-11 11:01:47 +02:00
}
else /* It's a directory */
{
/* First, make the initial directory */
2002-01-16 07:36:51 +01:00
$this -> mkdir ( array (
'string' => $data [ 'to' ],
'relatives' => array ( $data [ 'relatives' ][ 1 ])
)
);
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
/* Next, we create all the directories below the initial directory */
2003-09-21 15:54:07 +02:00
foreach ( $this -> ls ( array (
2002-01-16 07:36:51 +01:00
'string' => $f -> fake_full_path ,
'relatives' => array ( $f -> mask ),
'checksubdirs' => True ,
'mime_type' => 'Directory'
2003-09-21 15:54:07 +02:00
)) as $entry )
2001-08-11 11:01:47 +02:00
{
2001-09-28 22:41:36 +02:00
$newdir = ereg_replace ( " ^ $f->fake_full_path " , " $t->fake_full_path " , $entry [ 'directory' ]);
2002-01-16 07:36:51 +01:00
$this -> mkdir ( array (
'string' => $newdir . '/' . $entry [ 'name' ],
'relatives' => array ( $t -> mask )
)
);
2001-08-11 11:01:47 +02:00
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
/* Lastly, we copy the files over */
2003-09-21 15:54:07 +02:00
foreach ( $this -> ls ( array (
2002-01-16 07:36:51 +01:00
'string' => $f -> fake_full_path ,
'relatives' => array ( $f -> mask )
2003-09-21 15:54:07 +02:00
)) as $entry )
2001-08-11 11:01:47 +02:00
{
2001-09-28 22:41:36 +02:00
if ( $entry [ 'mime_type' ] == 'Directory' )
2001-08-11 11:01:47 +02:00
{
continue ;
}
2001-09-28 22:41:36 +02:00
$newdir = ereg_replace ( " ^ $f->fake_full_path " , " $t->fake_full_path " , $entry [ 'directory' ]);
2002-01-16 07:36:51 +01:00
$this -> cp ( array (
'from' => " $entry[directory] / $entry[name] " ,
'to' => " $newdir / $entry[name] " ,
'relatives' => array ( $f -> mask , $t -> mask )
)
);
2001-08-11 11:01:47 +02:00
}
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
if ( ! $f -> outside )
2001-07-02 21:00:31 +02:00
{
2002-01-16 07:36:51 +01:00
$this -> add_journal ( array (
'string' => $f -> fake_full_path ,
'relatives' => array ( $f -> mask ),
'operation' => VFS_OPERATION_COPIED ,
'state_one' => NULL ,
'state_two' => $t -> fake_full_path
)
);
2001-07-02 21:00:31 +02:00
}
2001-09-28 22:41:36 +02:00
2001-05-25 05:34:24 +02:00
return True ;
}
2001-09-28 22:41:36 +02:00
2003-02-17 20:34:56 +01:00
/*
* See vfs_shared
*/
2002-01-16 07:36:51 +01:00
function mv ( $data )
2001-07-02 21:00:31 +02:00
{
2002-01-16 07:36:51 +01:00
if ( ! is_array ( $data ))
2001-09-24 20:17:26 +02:00
{
2002-01-16 07:36:51 +01:00
$data = array ();
2001-09-24 20:17:26 +02:00
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$default_values = array
(
'relatives' => array ( RELATIVE_CURRENT , RELATIVE_CURRENT )
);
$data = array_merge ( $this -> default_values ( $data , $default_values ), $data );
2005-07-22 19:59:09 +02:00
$account_id = $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ];
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$f = $this -> path_parts ( array (
'string' => $data [ 'from' ],
'relatives' => array ( $data [ 'relatives' ][ 0 ])
)
);
$t = $this -> path_parts ( array (
'string' => $data [ 'to' ],
'relatives' => array ( $data [ 'relatives' ][ 1 ])
)
);
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
if ( ! $this -> acl_check ( array (
'string' => $f -> fake_full_path ,
'relatives' => array ( $f -> mask ),
2005-07-22 19:59:09 +02:00
'operation' => EGW_ACL_READ
2002-01-16 07:36:51 +01:00
))
|| ! $this -> acl_check ( array (
'string' => $f -> fake_full_path ,
'relatives' => array ( $f -> mask ),
2005-07-22 19:59:09 +02:00
'operation' => EGW_ACL_DELETE
2002-01-16 07:36:51 +01:00
))
)
2001-07-02 21:00:31 +02:00
{
return False ;
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
if ( ! $this -> acl_check ( array (
'string' => $t -> fake_full_path ,
'relatives' => array ( $t -> mask ),
2005-07-22 19:59:09 +02:00
'operation' => EGW_ACL_ADD
2002-01-16 07:36:51 +01:00
))
)
2001-07-02 21:00:31 +02:00
{
return False ;
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
if ( $this -> file_exists ( array (
'string' => $t -> fake_full_path ,
'relatives' => array ( $t -> mask )
))
)
2001-05-25 05:34:24 +02:00
{
2002-01-16 07:36:51 +01:00
if ( ! $this -> acl_check ( array (
'string' => $t -> fake_full_path ,
'relatives' => array ( $t -> mask ),
2005-07-22 19:59:09 +02:00
'operation' => EGW_ACL_EDIT
2002-01-16 07:36:51 +01:00
))
)
2001-08-11 11:01:47 +02:00
{
return False ;
}
2001-05-25 05:34:24 +02:00
}
2001-09-28 22:41:36 +02:00
2003-10-04 09:37:03 +02:00
umask ( 0177 );
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
/* We can't move directories into themselves */
2002-01-16 07:36:51 +01:00
if (( $this -> file_type ( array (
'string' => $f -> fake_full_path ,
'relatives' => array ( $f -> mask )
) == 'Directory' ))
&& ereg ( " ^ $f->fake_full_path " , $t -> fake_full_path )
)
2001-06-18 23:18:22 +02:00
{
2001-09-28 22:41:36 +02:00
if (( $t -> fake_full_path == $f -> fake_full_path ) || substr ( $t -> fake_full_path , strlen ( $f -> fake_full_path ), 1 ) == '/' )
2001-08-11 11:01:47 +02:00
{
return False ;
}
2001-06-18 23:18:22 +02:00
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
if ( $this -> file_exists ( array (
'string' => $f -> fake_full_path ,
'relatives' => array ( $f -> mask )
))
)
2001-06-18 23:18:22 +02:00
{
2001-08-11 11:01:47 +02:00
/* We get the listing now, because it will change after we update the database */
2002-01-16 07:36:51 +01:00
$ls = $this -> ls ( array (
'string' => $f -> fake_full_path ,
'relatives' => array ( $f -> mask )
)
);
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
if ( $this -> file_exists ( array (
'string' => $t -> fake_full_path ,
'relatives' => array ( $t -> mask )
))
)
2001-08-24 09:44:43 +02:00
{
2002-01-16 07:36:51 +01:00
$this -> rm ( array (
'string' => $t -> fake_full_path ,
'relatives' => array ( $t -> mask )
)
);
2001-08-24 09:44:43 +02:00
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
/*
2005-07-22 19:59:09 +02:00
We add the journal entry now , before we delete . This way the mime_type
field will be updated to 'journal-deleted' when the file is actually deleted
2001-08-11 11:01:47 +02:00
*/
if ( ! $f -> outside )
{
2002-01-16 07:36:51 +01:00
$this -> add_journal ( array (
'string' => $f -> fake_full_path ,
'relatives' => array ( $f -> mask ),
'operation' => VFS_OPERATION_MOVED ,
'state_one' => $f -> fake_full_path ,
'state_two' => $t -> fake_full_path
)
);
2001-08-11 11:01:47 +02:00
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
/*
2005-07-22 19:59:09 +02:00
If the from file is outside , it won ' t have a database entry ,
so we have to touch it and find the size
2001-08-11 11:01:47 +02:00
*/
if ( $f -> outside )
{
$size = filesize ( $f -> real_full_path );
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$this -> touch ( array (
'string' => $t -> fake_full_path ,
'relatives' => array ( $t -> mask )
)
);
2005-02-26 15:00:02 +01:00
$this -> db -> update ( $this -> vfs_table , array ( 'vfs_size' => $size ), array (
'vfs_directory' => $t -> fake_leading_dirs ,
'vfs_name' => $t -> fake_name ,
2004-09-20 12:50:46 +02:00
$this -> extra_sql ( array ( 'query_type' => VFS_SQL_UPDATE )),
), __LINE__ , __FILE__ );
2001-08-11 11:01:47 +02:00
}
elseif ( ! $t -> outside )
{
2004-09-20 12:50:46 +02:00
$this -> db -> update ( $this -> vfs_table , array (
2005-02-26 15:00:02 +01:00
'vfs_directory' => $t -> fake_leading_dirs ,
'vfs_name' => $t -> fake_name ,
2004-09-20 12:50:46 +02:00
), array (
2005-02-26 15:00:02 +01:00
'vfs_directory' => $f -> fake_leading_dirs ,
'vfs_name' => $f -> fake_name ,
2004-09-20 12:50:46 +02:00
$this -> extra_sql ( array ( 'query_type' => VFS_SQL_UPDATE )),
), __LINE__ , __FILE__ );
2001-08-11 11:01:47 +02:00
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$this -> set_attributes ( array (
'string' => $t -> fake_full_path ,
'relatives' => array ( $t -> mask ),
'attributes' => array (
'modifiedby_id' => $account_id ,
'modified' => $this -> now
)
)
);
$this -> correct_attributes ( array (
'string' => $t -> fake_full_path ,
'relatives' => array ( $t -> mask )
2001-09-28 22:41:36 +02:00
)
);
2002-08-26 06:20:33 +02:00
if ( $this -> file_actions )
{
2004-09-20 12:50:46 +02:00
rename ( $f -> real_full_path , $t -> real_full_path );
2002-08-26 06:20:33 +02:00
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
/*
2005-07-22 19:59:09 +02:00
This removes the original entry from the database
The actual file is already deleted because of the rename () above
2001-08-11 11:01:47 +02:00
*/
if ( $t -> outside )
{
2002-01-16 07:36:51 +01:00
$this -> rm ( array (
'string' => $f -> fake_full_path ,
'relatives' => $f -> mask
)
);
2001-08-11 11:01:47 +02:00
}
2001-06-18 23:18:22 +02:00
}
else
{
2001-08-11 11:01:47 +02:00
return False ;
2001-05-25 05:34:24 +02:00
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
if ( $this -> file_type ( array (
'string' => $t -> fake_full_path ,
'relatives' => array ( $t -> mask )
)) == 'Directory'
)
2001-05-25 05:34:24 +02:00
{
2001-08-11 11:01:47 +02:00
/* We got $ls from above, before we renamed the directory */
2003-09-21 15:54:07 +02:00
foreach ( $ls as $entry )
2001-05-25 05:34:24 +02:00
{
2001-09-28 22:41:36 +02:00
$newdir = ereg_replace ( " ^ $f->fake_full_path " , $t -> fake_full_path , $entry [ 'directory' ]);
2004-09-20 12:50:46 +02:00
$this -> db -> update ( $this -> vfs_table , array (
2005-02-26 15:00:02 +01:00
'vfs_directory' => $newdir
2004-09-20 12:50:46 +02:00
), array (
2005-02-26 15:00:02 +01:00
'vfs_file_id' => $entry [ 'file_id' ],
2004-09-20 12:50:46 +02:00
$this -> extra_sql ( array ( 'query_type' => VFS_SQL_UPDATE ))
), __LINE__ , __FILE__ );
2002-01-16 07:36:51 +01:00
$this -> correct_attributes ( array (
'string' => " $newdir / $entry[name] " ,
'relatives' => array ( $t -> mask )
)
);
2001-05-25 05:34:24 +02:00
}
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$this -> add_journal ( array (
'string' => $t -> fake_full_path ,
'relatives' => array ( $t -> mask ),
'operation' => VFS_OPERATION_MOVED ,
'state_one' => $f -> fake_full_path ,
'state_two' => $t -> fake_full_path
)
);
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
return True ;
2001-07-11 07:57:04 +02:00
}
2001-09-28 22:41:36 +02:00
2003-02-17 20:34:56 +01:00
/*
* See vfs_shared
*/
2002-01-16 07:36:51 +01:00
function rm ( $data )
2001-07-02 21:00:31 +02:00
{
2002-01-16 07:36:51 +01:00
if ( ! is_array ( $data ))
2001-09-24 20:17:26 +02:00
{
2002-01-16 07:36:51 +01:00
$data = array ();
2001-09-24 20:17:26 +02:00
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$default_values = array
(
'relatives' => array ( RELATIVE_CURRENT )
);
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$data = array_merge ( $this -> default_values ( $data , $default_values ), $data );
$p = $this -> path_parts ( array (
'string' => $data [ 'string' ],
'relatives' => array ( $data [ 'relatives' ][ 0 ])
)
);
if ( ! $this -> acl_check ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask ),
2005-07-22 19:59:09 +02:00
'operation' => EGW_ACL_DELETE
2002-01-16 07:36:51 +01:00
))
)
2001-07-02 21:00:31 +02:00
{
return False ;
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
if ( ! $this -> file_exists ( array (
'string' => $data [ 'string' ],
'relatives' => array ( $data [ 'relatives' ][ 0 ])
))
)
2001-08-11 11:01:47 +02:00
{
2002-08-26 06:20:33 +02:00
if ( $this -> file_actions )
{
$rr = unlink ( $p -> real_full_path );
}
else
{
$rr = True ;
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
if ( $rr )
{
return True ;
}
else
{
return False ;
}
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
if ( $this -> file_type ( array (
'string' => $data [ 'string' ],
'relatives' => array ( $data [ 'relatives' ][ 0 ])
)) != 'Directory'
)
2001-08-11 11:01:47 +02:00
{
2002-01-16 07:36:51 +01:00
$this -> add_journal ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask ),
'operation' => VFS_OPERATION_DELETED
)
);
2001-09-28 22:41:36 +02:00
2004-09-20 12:50:46 +02:00
$query = $this -> db -> delete ( $this -> vfs_table , array (
2005-02-26 15:00:02 +01:00
'vfs_directory' => $p -> fake_leading_dirs ,
'vfs_name' => $p -> fake_name ,
2004-09-20 12:50:46 +02:00
$this -> extra_sql ( array ( 'query_type' => VFS_SQL_DELETE ))
), __LINE__ , __FILE__ );
2002-08-26 06:20:33 +02:00
if ( $this -> file_actions )
{
$rr = unlink ( $p -> real_full_path );
}
else
{
$rr = True ;
}
2001-09-28 22:41:36 +02:00
2004-09-20 12:50:46 +02:00
return $query || $rr ;
2001-08-11 11:01:47 +02:00
}
else
{
2002-01-16 07:36:51 +01:00
$ls = $this -> ls ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask )
)
);
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
/* First, we cycle through the entries and delete the files */
2003-09-21 15:54:07 +02:00
foreach ( $ls as $entry )
2001-08-11 11:01:47 +02:00
{
2001-09-28 22:41:36 +02:00
if ( $entry [ 'mime_type' ] == 'Directory' )
2001-08-11 11:01:47 +02:00
{
continue ;
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$this -> rm ( array (
'string' => " $entry[directory] / $entry[name] " ,
'relatives' => array ( $p -> mask )
)
);
2001-08-11 11:01:47 +02:00
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
/* Now we cycle through again and delete the directories */
2003-09-21 15:54:07 +02:00
foreach ( $ls as $entry )
2001-08-11 11:01:47 +02:00
{
2001-09-28 22:41:36 +02:00
if ( $entry [ 'mime_type' ] != 'Directory' )
2001-08-11 11:01:47 +02:00
{
continue ;
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
/* Only the best in confusing recursion */
2002-01-16 07:36:51 +01:00
$this -> rm ( array (
'string' => " $entry[directory] / $entry[name] " ,
'relatives' => array ( $p -> mask )
)
);
2001-08-11 11:01:47 +02:00
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
/* If the directory is linked, we delete the placeholder directory */
2002-01-16 07:36:51 +01:00
$ls_array = $this -> ls ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask ),
'checksubdirs' => False ,
'mime_type' => False ,
'nofiles' => True
)
);
2001-08-11 11:01:47 +02:00
$link_info = $ls_array [ 0 ];
2001-09-28 22:41:36 +02:00
if ( $link_info [ 'link_directory' ] && $link_info [ 'link_name' ])
2001-08-11 11:01:47 +02:00
{
2002-01-16 07:36:51 +01:00
$path = $this -> path_parts ( array (
'string' => $link_info [ 'directory' ] . '/' . $link_info [ 'name' ],
'relatives' => array ( $p -> mask ),
'nolinks' => True
)
);
2002-08-26 06:20:33 +02:00
if ( $this -> file_actions )
{
rmdir ( $path -> real_full_path );
}
2001-08-11 11:01:47 +02:00
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
/* Last, we delete the directory itself */
2002-01-16 07:36:51 +01:00
$this -> add_journal ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask ),
'operaton' => VFS_OPERATION_DELETED
)
);
2001-09-28 22:41:36 +02:00
2004-09-20 12:50:46 +02:00
$this -> db -> delete ( $this -> vfs_table , array (
2005-02-26 15:00:02 +01:00
'vfs_directory' => $p -> fake_leading_dirs ,
'vfs_name' => $p -> fake_name ,
2004-09-20 12:50:46 +02:00
$this -> extra_sql ( array ( 'query_type' => VFS_SQL_DELETE ))
), __LINE__ , __FILE__ );
2001-09-28 22:41:36 +02:00
2002-08-26 06:20:33 +02:00
if ( $this -> file_actions )
{
rmdir ( $p -> real_full_path );
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
return True ;
}
2001-07-02 21:00:31 +02:00
}
2001-09-28 22:41:36 +02:00
2003-02-17 20:34:56 +01:00
/*
* See vfs_shared
*/
2002-01-16 07:36:51 +01:00
function mkdir ( $data )
2001-06-14 08:39:10 +02:00
{
2002-01-16 07:36:51 +01:00
if ( ! is_array ( $data ))
2001-09-24 20:17:26 +02:00
{
2002-01-16 07:36:51 +01:00
$data = array ();
2001-09-24 20:17:26 +02:00
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$default_values = array
(
'relatives' => array ( RELATIVE_CURRENT )
);
$data = array_merge ( $this -> default_values ( $data , $default_values ), $data );
2005-07-22 19:59:09 +02:00
$account_id = $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ];
$currentapp = $GLOBALS [ 'egw_info' ][ 'flags' ][ 'currentapp' ];
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$p = $this -> path_parts ( array (
'string' => $data [ 'string' ],
'relatives' => array ( $data [ 'relatives' ][ 0 ])
)
);
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
if ( ! $this -> acl_check ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask ),
2005-07-22 19:59:09 +02:00
'operation' => EGW_ACL_ADD )
2002-01-16 07:36:51 +01:00
)
)
2005-07-22 19:59:09 +02:00
{ //echo "!acl_check('$p->fake_full_path',EGW_ACL_ADD)";
2001-06-14 08:39:10 +02:00
return False ;
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
/* We don't allow /'s in dir names, of course */
2004-09-20 12:50:46 +02:00
if ( strstr ( $p -> fake_name , '/' ))
2005-03-07 18:08:54 +01:00
{ //echo "strstr('$p->fake_name','/')";
2001-08-11 11:01:47 +02:00
return False ;
2001-07-11 07:57:04 +02:00
}
2001-09-28 22:41:36 +02:00
2003-10-04 09:37:03 +02:00
umask ( 077 );
2001-09-28 22:41:36 +02:00
2002-08-26 06:20:33 +02:00
if ( $this -> file_actions )
2001-06-18 23:18:22 +02:00
{
2004-09-20 12:50:46 +02:00
if ( !@ is_dir ( $p -> real_leading_dirs )) // eg. /home or /group does not exist
2003-09-21 15:54:07 +02:00
{
2004-09-20 12:50:46 +02:00
if ( !@ mkdir ( $p -> real_leading_dirs , 0770 )) // ==> create it
2005-03-07 18:08:54 +01:00
{ //echo "!mkdir('$p->real_leading_dirs')";
2003-09-21 15:54:07 +02:00
return False ;
}
}
if ( @ is_dir ( $p -> real_full_path )) // directory already exists
{
$this -> update_real ( $data , True ); // update its contents
}
elseif ( !@ mkdir ( $p -> real_full_path , 0770 ))
2005-03-07 18:08:54 +01:00
{ //echo "!mkdir('$p->real_full_path')";
2002-08-26 06:20:33 +02:00
return False ;
}
2001-06-18 23:18:22 +02:00
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
if ( ! $this -> file_exists ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask )
))
)
{
2004-09-20 12:50:46 +02:00
$this -> db -> insert ( $this -> vfs_table , array (
2005-02-26 15:00:02 +01:00
'vfs_owner_id' => $this -> working_id ,
'vfs_name' => $p -> fake_name ,
'vfs_directory' => $p -> fake_leading_dirs ,
2004-09-20 12:50:46 +02:00
), false , __LINE__ , __FILE__ );
2002-01-16 07:36:51 +01:00
$this -> set_attributes ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask ),
'attributes' => array (
'createdby_id' => $account_id ,
'size' => 4096 ,
'mime_type' => 'Directory' ,
'created' => $this -> now ,
'deleteable' => 'Y' ,
'app' => $currentapp
)
)
);
$this -> correct_attributes ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask )
2001-09-28 22:41:36 +02:00
)
);
2002-01-16 07:36:51 +01:00
$this -> add_journal ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask ),
'operation' => VFS_OPERATION_CREATED
)
);
2001-06-18 23:18:22 +02:00
}
2001-08-11 11:01:47 +02:00
else
2005-03-07 18:08:54 +01:00
{ //echo"!file_exists('$p->fake_full_path');";
2001-08-11 11:01:47 +02:00
return False ;
2001-06-18 23:18:22 +02:00
}
2001-08-11 11:01:47 +02:00
return True ;
2001-05-25 05:34:24 +02:00
}
2001-09-28 22:41:36 +02:00
2003-02-17 20:34:56 +01:00
/*
* See vfs_shared
*/
2002-01-16 07:36:51 +01:00
function make_link ( $data )
2001-05-25 05:34:24 +02:00
{
2002-01-16 07:36:51 +01:00
if ( ! is_array ( $data ))
2001-09-24 20:17:26 +02:00
{
2002-01-16 07:36:51 +01:00
$data = array ();
2001-09-24 20:17:26 +02:00
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$default_values = array
(
'relatives' => array ( RELATIVE_CURRENT , RELATIVE_CURRENT )
);
$data = array_merge ( $this -> default_values ( $data , $default_values ), $data );
$vp = $this -> path_parts ( array (
'string' => $data [ 'vdir' ],
'relatives' => array ( $data [ 'relatives' ][ 0 ])
)
);
$rp = $this -> path_parts ( array (
'string' => $data [ 'rdir' ],
'relatives' => array ( $data [ 'relatives' ][ 1 ])
)
);
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
if ( ! $this -> acl_check ( array (
'string' => $vp -> fake_full_path ,
'relatives' => array ( $vp -> mask ),
2005-07-22 19:59:09 +02:00
'operation' => EGW_ACL_ADD
2002-01-16 07:36:51 +01:00
))
)
2001-05-25 05:34:24 +02:00
{
2001-08-11 11:01:47 +02:00
return False ;
2001-05-25 05:34:24 +02:00
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
if (( ! $this -> file_exists ( array (
'string' => $rp -> real_full_path ,
'relatives' => array ( $rp -> mask )
)))
&& ! mkdir ( $rp -> real_full_path , 0770 ))
2001-06-16 05:54:10 +02:00
{
2001-08-11 11:01:47 +02:00
return False ;
2001-06-16 05:54:10 +02:00
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
if ( ! $this -> mkdir ( array (
'string' => $vp -> fake_full_path ,
'relatives' => array ( $vp -> mask )
))
)
2001-06-16 05:54:10 +02:00
{
return False ;
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$size = $this -> get_size ( array (
'string' => $rp -> real_full_path ,
'relatives' => array ( $rp -> mask )
)
);
$this -> set_attributes ( array (
'string' => $vp -> fake_full_path ,
'relatives' => array ( $vp -> mask ),
'attributes' => array (
'link_directory' => $rp -> real_leading_dirs ,
'link_name' => $rp -> real_name ,
'size' => $size
)
)
);
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$this -> correct_attributes ( array (
'string' => $vp -> fake_full_path ,
'relatives' => array ( $vp -> mask )
2001-09-28 22:41:36 +02:00
)
);
2001-08-11 11:01:47 +02:00
return True ;
2001-05-25 05:34:24 +02:00
}
2001-09-28 22:41:36 +02:00
2003-02-17 20:34:56 +01:00
/*
* See vfs_shared
*/
2002-01-16 07:36:51 +01:00
function set_attributes ( $data )
2001-05-25 05:34:24 +02:00
{
2002-01-16 07:36:51 +01:00
if ( ! is_array ( $data ))
2001-09-24 20:17:26 +02:00
{
2002-01-16 07:36:51 +01:00
$data = array ();
2001-09-24 20:17:26 +02:00
}
2002-01-16 07:36:51 +01:00
$default_values = array
(
'relatives' => array ( RELATIVE_CURRENT ),
'attributes' => array ()
);
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$data = array_merge ( $this -> default_values ( $data , $default_values ), $data );
$p = $this -> path_parts ( array (
'string' => $data [ 'string' ],
'relatives' => array ( $data [ 'relatives' ][ 0 ])
)
);
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
/*
2005-07-22 19:59:09 +02:00
This is kind of trivial , given that set_attributes () can change owner_id ,
size , etc .
2001-08-11 11:01:47 +02:00
*/
2002-01-16 07:36:51 +01:00
if ( ! $this -> acl_check ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask ),
2005-07-22 19:59:09 +02:00
'operation' => EGW_ACL_EDIT
2002-01-16 07:36:51 +01:00
))
)
2001-05-25 05:34:24 +02:00
{
2001-08-11 11:01:47 +02:00
return False ;
2001-05-25 05:34:24 +02:00
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
if ( ! $this -> file_exists ( array (
'string' => $data [ 'string' ],
'relatives' => array ( $data [ 'relatives' ][ 0 ])
))
)
{
return False ;
}
2001-12-20 03:38:02 +01:00
2001-08-11 11:01:47 +02:00
/*
2005-07-22 19:59:09 +02:00
All this voodoo just decides which attributes to update
depending on if the attribute was supplied in the 'attributes' array
2001-08-11 11:01:47 +02:00
*/
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$ls_array = $this -> ls ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask ),
'checksubdirs' => False ,
'nofiles' => True
)
);
2001-08-11 11:01:47 +02:00
$record = $ls_array [ 0 ];
2001-09-28 22:41:36 +02:00
2004-09-20 12:50:46 +02:00
$to_write = array ();
2003-09-21 15:54:07 +02:00
foreach ( $this -> attributes as $attribute )
2001-05-25 05:34:24 +02:00
{
2002-01-16 07:36:51 +01:00
if ( isset ( $data [ 'attributes' ][ $attribute ]))
2001-05-25 05:34:24 +02:00
{
2002-01-16 07:36:51 +01:00
/*
2005-07-22 19:59:09 +02:00
Indicate that the EDITED_COMMENT operation needs to be journaled ,
but only if the comment changed
2002-01-16 07:36:51 +01:00
*/
if ( $attribute == 'comment' && $data [ 'attributes' ][ $attribute ] != $record [ $attribute ])
2001-08-11 11:01:47 +02:00
{
2002-01-16 07:36:51 +01:00
$edited_comment = 1 ;
2001-08-11 11:01:47 +02:00
}
2005-02-26 15:00:02 +01:00
$to_write [ $this -> vfs_column_prefix . $attribute ] = $data [ 'attributes' ][ $attribute ];
2001-12-10 05:04:56 +01:00
}
}
2002-01-16 07:36:51 +01:00
2004-09-20 12:50:46 +02:00
if ( ! count ( $to_write ))
2003-09-21 15:54:07 +02:00
{
return True ; // nothing to do
}
2004-09-20 12:50:46 +02:00
if ( ! $this -> db -> update ( $this -> vfs_table , $to_write , array (
2005-02-26 15:00:02 +01:00
'vfs_file_id' => $record [ 'file_id' ],
2004-09-20 12:50:46 +02:00
$this -> extra_sql ( array ( 'query_type' => VFS_SQL_UPDATE )),
), __LINE__ , __FILE__ ))
2001-07-09 07:09:27 +02:00
{
2004-09-20 12:50:46 +02:00
return False ;
2001-08-11 11:01:47 +02:00
}
2004-09-20 12:50:46 +02:00
if ( $edited_comment )
2001-08-11 11:01:47 +02:00
{
2004-09-20 12:50:46 +02:00
$this -> add_journal ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask ),
'operation' => VFS_OPERATION_EDITED_COMMENT
)
);
2001-07-09 07:09:27 +02:00
}
2004-09-20 12:50:46 +02:00
return True ;
2001-05-25 05:34:24 +02:00
}
2001-09-28 22:41:36 +02:00
2005-07-22 19:59:09 +02:00
/**
* Set the correct attributes for 'string' ( e . g . owner )
*
* @ param string File / directory to correct attributes of
* @ param relatives Relativity array
* @ return Boolean True / False
*/
2002-01-16 07:36:51 +01:00
function correct_attributes ( $data )
2001-05-25 05:34:24 +02:00
{
2002-01-16 07:36:51 +01:00
if ( ! is_array ( $data ))
2001-09-24 20:17:26 +02:00
{
2002-01-16 07:36:51 +01:00
$data = array ();
2001-09-24 20:17:26 +02:00
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$default_values = array
(
'relatives' => array ( RELATIVE_CURRENT )
);
$data = array_merge ( $this -> default_values ( $data , $default_values ), $data );
$p = $this -> path_parts ( array (
'string' => $data [ 'string' ],
'relatives' => array ( $data [ 'relatives' ][ 0 ])
)
);
2001-09-28 22:41:36 +02:00
if ( $p -> fake_leading_dirs != $this -> fakebase && $p -> fake_leading_dirs != '/' )
2001-05-25 05:34:24 +02:00
{
2002-01-16 07:36:51 +01:00
$ls_array = $this -> ls ( array (
'string' => $p -> fake_leading_dirs ,
'relatives' => array ( $p -> mask ),
'checksubdirs' => False ,
'nofiles' => True
)
);
$set_attributes_array = Array (
2002-01-07 11:50:42 +01:00
'owner_id' => $ls_array [ 0 ][ 'owner_id' ]
);
2001-08-11 11:01:47 +02:00
}
elseif ( preg_match ( " +^ $this->fakebase\ /(.*) $ +U " , $p -> fake_full_path , $matches ))
{
2002-01-16 07:36:51 +01:00
$set_attributes_array = Array (
2005-07-22 19:59:09 +02:00
'owner_id' => $GLOBALS [ 'egw' ] -> accounts -> name2id ( $matches [ 1 ])
2002-01-07 11:50:42 +01:00
);
2001-05-25 05:34:24 +02:00
}
else
{
2002-01-16 07:36:51 +01:00
$set_attributes_array = Array (
2002-01-07 11:50:42 +01:00
'owner_id' => 0
);
2001-05-25 05:34:24 +02:00
}
2001-12-15 05:24:37 +01:00
2002-01-16 07:36:51 +01:00
$this -> set_attributes ( array (
2005-07-22 19:59:09 +02:00
'string' => $p -> fake_full_path ,
2002-01-16 07:36:51 +01:00
'relatives' => array ( $p -> mask ),
'attributes' => $set_attributes_array
)
);
2001-12-15 05:24:37 +01:00
2002-01-16 07:36:51 +01:00
return True ;
2001-12-15 05:24:37 +01:00
}
2003-02-17 20:34:56 +01:00
/*
* See vfs_shared
*/
2002-01-16 07:36:51 +01:00
function file_type ( $data )
2001-05-25 05:34:24 +02:00
{
2002-01-16 07:36:51 +01:00
if ( ! is_array ( $data ))
2001-09-24 20:17:26 +02:00
{
2002-01-16 07:36:51 +01:00
$data = array ();
2001-09-24 20:17:26 +02:00
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$default_values = array
(
'relatives' => array ( RELATIVE_CURRENT )
);
$data = array_merge ( $this -> default_values ( $data , $default_values ), $data );
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$p = $this -> path_parts ( array (
'string' => $data [ 'string' ],
'relatives' => array ( $data [ 'relatives' ][ 0 ])
)
);
if ( ! $this -> acl_check ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask ),
2005-07-22 19:59:09 +02:00
'operation' => EGW_ACL_READ ,
2002-01-16 07:36:51 +01:00
'must_exist' => True
))
)
2001-07-11 07:57:04 +02:00
{
2001-08-11 11:01:47 +02:00
return False ;
2001-07-11 07:57:04 +02:00
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
if ( $p -> outside )
2001-07-13 07:12:18 +02:00
{
2001-08-11 11:01:47 +02:00
if ( is_dir ( $p -> real_full_path ))
{
2001-09-28 22:41:36 +02:00
return ( 'Directory' );
2001-08-11 11:01:47 +02:00
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
/*
2005-07-22 19:59:09 +02:00
We don ' t return an empty string here , because it may still match with a database query
because of linked directories
2001-08-11 11:01:47 +02:00
*/
2001-07-13 07:12:18 +02:00
}
2001-09-28 22:41:36 +02:00
2001-07-13 07:12:18 +02:00
/*
2005-07-22 19:59:09 +02:00
We don ' t use ls () because it calls file_type () to determine if it has been
passed a directory
2001-07-13 07:12:18 +02:00
*/
2005-02-26 15:00:02 +01:00
$db2 = clone ( $this -> db );
$db2 -> select ( $this -> vfs_table , 'vfs_mime_type' , array (
'vfs_directory' => $p -> fake_leading_dirs ,
'vfs_name' => $p -> fake_name ,
2004-09-20 12:50:46 +02:00
$this -> extra_sql ( array ( 'query_type' => VFS_SQL_SELECT ))
), __LINE__ , __FILE__ );
2001-12-20 03:38:02 +01:00
$db2 -> next_record ();
2005-02-26 15:00:02 +01:00
$mime_type = $db2 -> Record [ 'vfs_mime_type' ];
2005-07-22 19:59:09 +02:00
if ( ! $mime_type && ( $mime_type = $this -> get_ext_mime_type ( array ( 'string' => $data [ 'string' ]))))
2001-12-15 05:24:37 +01:00
{
2005-07-22 19:59:09 +02:00
$db2 -> update ( $this -> vfs_table , array (
'vfs_mime_type' => $mime_type
), array (
'vfs_directory' => $p -> fake_leading_dirs ,
'vfs_name' => $p -> fake_name ,
$this -> extra_sql ( array ( 'query_type' => VFS_SQL_SELECT ))
), __LINE__ , __FILE__ );
2001-12-15 05:24:37 +01:00
}
return $mime_type ;
2001-07-13 07:12:18 +02:00
}
2001-09-28 22:41:36 +02:00
2003-02-17 20:34:56 +01:00
/*
* See vfs_shared
*/
2002-01-16 07:36:51 +01:00
function file_exists ( $data )
2001-07-09 07:09:27 +02:00
{
2002-01-16 07:36:51 +01:00
if ( ! is_array ( $data ))
2001-09-24 20:17:26 +02:00
{
2002-01-16 07:36:51 +01:00
$data = array ();
2001-09-24 20:17:26 +02:00
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$default_values = array
(
'relatives' => array ( RELATIVE_CURRENT )
);
$data = array_merge ( $this -> default_values ( $data , $default_values ), $data );
$p = $this -> path_parts ( array (
'string' => $data [ 'string' ],
'relatives' => array ( $data [ 'relatives' ][ 0 ])
)
);
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
if ( $p -> outside )
{
2002-01-16 07:36:51 +01:00
$rr = file_exists ( $p -> real_full_path );
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
return $rr ;
2001-12-15 05:24:37 +01:00
}
2001-09-28 22:41:36 +02:00
2005-02-26 15:00:02 +01:00
$db2 = clone ( $this -> db );
$db2 -> select ( $this -> vfs_table , 'vfs_name' , array (
'vfs_directory' => $p -> fake_leading_dirs ,
'vfs_name' => $p -> fake_name ,
2004-09-20 12:50:46 +02:00
$this -> extra_sql ( array ( 'query_type' => VFS_SQL_SELECT ))
), __LINE__ , __FILE__ );
2001-12-20 03:38:02 +01:00
2004-09-20 12:50:46 +02:00
return $db2 -> next_record ();
2001-07-09 07:09:27 +02:00
}
2001-09-28 22:41:36 +02:00
2003-02-17 20:34:56 +01:00
/*
* See vfs_shared
*/
2002-01-16 07:36:51 +01:00
function get_size ( $data )
2001-05-25 05:34:24 +02:00
{
2002-01-16 07:36:51 +01:00
if ( ! is_array ( $data ))
2001-09-24 20:17:26 +02:00
{
2002-01-16 07:36:51 +01:00
$data = array ();
2001-09-24 20:17:26 +02:00
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$default_values = array
(
'relatives' => array ( RELATIVE_CURRENT ),
'checksubdirs' => True
);
$data = array_merge ( $this -> default_values ( $data , $default_values ), $data );
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$p = $this -> path_parts ( array (
'string' => $data [ 'string' ],
'relatives' => array ( $data [ 'relatives' ][ 0 ])
)
);
if ( ! $this -> acl_check ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask ),
2005-07-22 19:59:09 +02:00
'operation' => EGW_ACL_READ ,
2002-01-16 07:36:51 +01:00
'must_exist' => True
))
)
2001-08-11 11:01:47 +02:00
{
return False ;
}
2001-09-28 22:41:36 +02:00
2001-07-02 22:38:49 +02:00
/*
2005-07-22 19:59:09 +02:00
WIP - this should run through all of the subfiles / directories in the directory and tally up
their sizes . Should modify ls () to be able to return a list for files outside the virtual root
2001-07-02 22:38:49 +02:00
*/
2001-08-11 11:01:47 +02:00
if ( $p -> outside )
2001-07-02 22:38:49 +02:00
{
2002-01-16 07:36:51 +01:00
$size = filesize ( $p -> real_full_path );
return $size ;
2001-07-02 22:38:49 +02:00
}
2001-09-28 22:41:36 +02:00
2003-09-21 15:54:07 +02:00
foreach ( $this -> ls ( array (
2002-01-16 07:36:51 +01:00
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask ),
'checksubdirs' => $data [ 'checksubdirs' ],
'nofiles' => ! $data [ 'checksubdirs' ]
2003-09-21 15:54:07 +02:00
)) as $file_array )
2001-08-11 11:01:47 +02:00
{
/*
2005-07-22 19:59:09 +02:00
Make sure the file is in the directory we want , and not
some deeper nested directory with a similar name
2001-08-11 11:01:47 +02:00
*/
2002-01-16 07:36:51 +01:00
/*
if ( @! ereg ( '^' . $file_array [ 'directory' ], $p -> fake_full_path ))
2001-08-11 11:01:47 +02:00
{
continue ;
}
2002-01-16 07:36:51 +01:00
*/
2001-09-28 22:41:36 +02:00
$size += $file_array [ 'size' ];
2001-08-11 11:01:47 +02:00
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
if ( $data [ 'checksubdirs' ])
2001-08-11 11:01:47 +02:00
{
2005-02-26 15:00:02 +01:00
$this -> db -> select ( $this -> vfs_table , 'vfs_size' , array (
'vfs_directory' => $p -> fake_leading_dirs ,
'vfs_name' => $p -> fake_name ,
2004-09-20 12:50:46 +02:00
$this -> extra_sql ( array ( 'query_type' => VFS_SQL_SELECT ))
), __LINE__ , __FILE__ );
$this -> db -> next_record ();
$size += $this -> db -> Record [ 0 ];
2001-08-11 11:01:47 +02:00
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
return $size ;
2001-05-25 05:34:24 +02:00
}
2001-09-28 22:41:36 +02:00
2005-07-22 19:59:09 +02:00
/**
* Check if $this -> working_id has write access to create files in $dir
*
* Simple call to acl_check
* @ param string Directory to check access of
* @ param relatives Relativity array
* @ return Boolean True / False
*/
2002-01-16 07:36:51 +01:00
function checkperms ( $data )
2001-05-25 05:34:24 +02:00
{
2002-01-16 07:36:51 +01:00
if ( ! is_array ( $data ))
2001-09-24 20:17:26 +02:00
{
2002-01-16 07:36:51 +01:00
$data = array ();
2001-09-24 20:17:26 +02:00
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$default_values = array
(
'relatives' => array ( RELATIVE_CURRENT )
);
$data = array_merge ( $this -> default_values ( $data , $default_values ), $data );
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$p = $this -> path_parts ( array (
'string' => $data [ 'string' ],
'relatives' => array ( $data [ 'relatives' ][ 0 ])
)
);
2004-09-20 12:50:46 +02:00
return $this -> acl_check ( array (
2002-01-16 07:36:51 +01:00
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask ),
2005-07-22 19:59:09 +02:00
'operation' => EGW_ACL_ADD
2004-09-20 12:50:46 +02:00
));
2001-05-25 05:34:24 +02:00
}
2001-09-28 22:41:36 +02:00
2003-02-17 20:34:56 +01:00
/*
* See vfs_shared
2004-02-08 23:30:14 +01:00
* If $data [ 'readlink' ] then a readlink is tryed on the real file
* If $data [ 'file_id' ] then the file_id is used instead of a path
2003-02-17 20:34:56 +01:00
*/
2002-01-16 07:36:51 +01:00
function ls ( $data )
2001-07-13 07:12:18 +02:00
{
2002-01-16 07:36:51 +01:00
if ( ! is_array ( $data ))
2001-09-24 20:17:26 +02:00
{
2002-01-16 07:36:51 +01:00
$data = array ();
2001-09-24 20:17:26 +02:00
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$default_values = array
(
'relatives' => array ( RELATIVE_CURRENT ),
'checksubdirs' => True ,
'mime_type' => False ,
'nofiles' => False ,
'orderby' => 'directory'
);
$data = array_merge ( $this -> default_values ( $data , $default_values ), $data );
$p = $this -> path_parts ( array (
'string' => $data [ 'string' ],
'relatives' => array ( $data [ 'relatives' ][ 0 ])
)
);
2001-08-11 11:01:47 +02:00
$dir = $p -> fake_full_path ;
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
/* If they pass us a file or 'nofiles' is set, return the info for $dir only */
2004-09-20 12:50:46 +02:00
if ( @ $data [ 'file_id' ] || ( $this -> file_type ( array (
2002-01-16 07:36:51 +01:00
'string' => $dir ,
'relatives' => array ( $p -> mask )
2004-09-20 12:50:46 +02:00
)) != 'Directory' || $data [ 'nofiles' ]) && ! $p -> outside )
2001-07-13 07:12:18 +02:00
{
2001-08-11 11:01:47 +02:00
/* SELECT all, the, attributes */
2004-02-08 23:30:14 +01:00
if ( @ $data [ 'file_id' ])
{
2005-02-26 15:00:02 +01:00
$where = array ( 'vfs_file_id' => $data [ 'file_id' ]);
2004-02-08 23:30:14 +01:00
}
else
{
2004-09-20 12:50:46 +02:00
$where = array (
2005-02-26 15:00:02 +01:00
'vfs_directory' => $p -> fake_leading_dirs ,
'vfs_name' => $p -> fake_name ,
2004-09-20 12:50:46 +02:00
$this -> extra_sql ( array ( 'query_type' => VFS_SQL_SELECT ))
);
2004-02-08 23:30:14 +01:00
}
2005-02-26 15:00:02 +01:00
$this -> db -> select ( $this -> vfs_table , array_keys ( $this -> attributes ), $where , __LINE__ , __FILE__ );
2001-09-28 22:41:36 +02:00
2005-02-26 15:00:02 +01:00
$record = $this -> db -> Row ( true , $this -> vfs_column_prefix );
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
/* We return an array of one array to maintain the standard */
$rarray = array ();
2003-09-21 15:54:07 +02:00
foreach ( $this -> attributes as $attribute )
2001-08-11 11:01:47 +02:00
{
2002-01-16 07:36:51 +01:00
if ( $attribute == 'mime_type' && ! $record [ $attribute ])
2001-12-15 05:24:37 +01:00
{
2002-01-16 07:36:51 +01:00
$record [ $attribute ] = $this -> get_ext_mime_type ( array (
2004-09-20 12:50:46 +02:00
'string' => $p -> fake_name
2002-01-16 07:36:51 +01:00
)
);
2001-12-15 05:24:37 +01:00
if ( $record [ $attribute ])
{
2004-09-20 12:50:46 +02:00
$this -> db -> update ( $this -> vfs_table , array (
2005-02-26 15:00:02 +01:00
'vfs_mime_type' => $record [ $attribute ]
2004-09-20 12:50:46 +02:00
), array (
2005-02-26 15:00:02 +01:00
'vfs_directory' => $p -> fake_leading_dirs ,
'vfs_name' => $p -> fake_name ,
2004-09-20 12:50:46 +02:00
$this -> extra_sql ( array ( 'query_type' => VFS_SQL_SELECT ))
), __LINE__ , __FILE__ );
2001-12-15 05:24:37 +01:00
}
}
2002-01-16 07:36:51 +01:00
2001-08-11 11:01:47 +02:00
$rarray [ 0 ][ $attribute ] = $record [ $attribute ];
2001-07-13 07:12:18 +02:00
}
2004-02-08 23:30:14 +01:00
if ( $this -> file_actions && @ $data [ 'readlink' ]) // test if file is a symlink and get it's target
{
$rarray [ 0 ][ 'symlink' ] = @ readlink ( $p -> real_full_path );
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
return $rarray ;
2001-07-13 07:12:18 +02:00
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
//WIP - this should recurse using the same options the virtual part of ls () does
/* If $dir is outside the virutal root, we have to check the file system manually */
if ( $p -> outside )
2001-07-13 07:12:18 +02:00
{
2002-01-16 07:36:51 +01:00
if ( $this -> file_type ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( $p -> mask )
)) == 'Directory'
&& ! $data [ 'nofiles' ]
)
2001-08-11 11:01:47 +02:00
{
$dir_handle = opendir ( $p -> real_full_path );
2004-09-20 12:50:46 +02:00
while (( $filename = readdir ( $dir_handle )))
2001-08-11 11:01:47 +02:00
{
2001-09-28 22:41:36 +02:00
if ( $filename == '.' || $filename == '..' )
2001-08-11 11:01:47 +02:00
{
continue ;
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$rarray [] = $this -> get_real_info ( array (
'string' => $p -> real_full_path . SEP . $filename ,
'relatives' => array ( $p -> mask )
)
);
2001-08-11 11:01:47 +02:00
}
}
else
{
2002-01-16 07:36:51 +01:00
$rarray [] = $this -> get_real_info ( array (
'string' => $p -> real_full_path ,
'relatives' => array ( $p -> mask )
)
);
2001-08-11 11:01:47 +02:00
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
return $rarray ;
2001-07-13 07:12:18 +02:00
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
/* $dir's not a file, is inside the virtual root, and they want to check subdirs */
2004-09-20 12:50:46 +02:00
/* SELECT all, the, attributes FROM $this->vfs_table WHERE file=$dir */
2005-02-26 15:00:02 +01:00
$db2 = clone ( $this -> db );
2004-09-20 12:50:46 +02:00
$where = array (
2005-02-26 15:00:02 +01:00
'vfs_directory LIKE ' . $this -> db -> quote ( $dir . '%' ),
2004-09-20 12:50:46 +02:00
$this -> extra_sql ( array ( 'query_type' => VFS_SQL_SELECT )),
);
2002-01-16 07:36:51 +01:00
if ( $data [ 'mime_type' ])
2001-05-25 05:34:24 +02:00
{
2005-02-26 15:00:02 +01:00
$where [ 'vfs_mime_type' ] = $data [ 'mime_type' ];
2001-05-25 05:34:24 +02:00
}
2005-02-26 15:00:02 +01:00
$this -> db -> select ( $this -> vfs_table , array_keys ( $this -> attributes ), $where , __LINE__ , __FILE__ , false ,
isset ( $this -> attributes [ $this -> vfs_column_prefix . $data [ 'orderby' ]]) ?
'ORDER BY ' . $this -> vfs_column_prefix . $data [ 'orderby' ] : '' );
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
$rarray = array ();
2005-02-26 15:00:02 +01:00
for ( $i = 0 ; ( $record = $this -> db -> Row ( true , $this -> vfs_column_prefix )); $i ++ )
2001-07-10 23:35:23 +02:00
{
2001-08-11 11:01:47 +02:00
/* Further checking on the directory. This makes sure /home/user/test won't match /home/user/test22 */
2002-01-16 07:36:51 +01:00
if ( @! ereg ( " ^ $dir (/| $ ) " , $record [ 'directory' ]))
2001-08-11 11:01:47 +02:00
{
continue ;
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
/* If they want only this directory, then $dir should end without a trailing / */
2002-01-16 07:36:51 +01:00
if ( ! $data [ 'checksubdirs' ] && ereg ( " ^ $dir / " , $record [ 'directory' ]))
2001-08-11 11:01:47 +02:00
{
continue ;
}
2001-09-28 22:41:36 +02:00
2003-09-21 15:54:07 +02:00
foreach ( $this -> attributes as $attribute )
2001-08-11 11:01:47 +02:00
{
2002-01-16 07:36:51 +01:00
if ( $attribute == 'mime_type' && ! $record [ $attribute ])
2001-12-15 05:24:37 +01:00
{
2002-01-16 07:36:51 +01:00
$record [ $attribute ] = $this -> get_ext_mime_type ( array (
2004-09-20 12:50:46 +02:00
'string' => $p -> fake_name
2002-01-16 07:36:51 +01:00
)
);
2001-12-15 05:24:37 +01:00
if ( $record [ $attribute ])
{
2004-09-20 12:50:46 +02:00
$db2 -> update ( $this -> vfs_table , array (
2005-02-26 15:00:02 +01:00
'vfs_mime_type' => $record [ $attribute ]
2004-09-20 12:50:46 +02:00
), array (
2005-02-26 15:00:02 +01:00
'vfs_directory' => $p -> fake_leading_dirs ,
'vfs_name' => $p -> fake_name ,
2004-09-20 12:50:46 +02:00
$this -> extra_sql ( array ( 'query_type' => VFS_SQL_SELECT ))
), __LINE__ , __FILE__ );
2001-12-15 05:24:37 +01:00
}
}
2002-01-16 07:36:51 +01:00
2001-08-11 11:01:47 +02:00
$rarray [ $i ][ $attribute ] = $record [ $attribute ];
}
2001-07-10 23:35:23 +02:00
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
return $rarray ;
2001-05-25 05:34:24 +02:00
}
2001-09-28 22:41:36 +02:00
2003-02-17 20:34:56 +01:00
/*
* See vfs_shared
*/
2003-09-21 15:54:07 +02:00
function update_real ( $data , $recursive = False )
2001-08-11 11:01:47 +02:00
{
2002-01-16 07:36:51 +01:00
if ( ! is_array ( $data ))
2001-09-24 20:17:26 +02:00
{
2002-01-16 07:36:51 +01:00
$data = array ();
2001-09-24 20:17:26 +02:00
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$default_values = array
(
'relatives' => array ( RELATIVE_CURRENT )
);
$data = array_merge ( $this -> default_values ( $data , $default_values ), $data );
$p = $this -> path_parts ( array (
'string' => $data [ 'string' ],
'relatives' => array ( $data [ 'relatives' ][ 0 ])
)
);
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
if ( file_exists ( $p -> real_full_path ))
2001-07-13 07:12:18 +02:00
{
2001-08-11 11:01:47 +02:00
if ( is_dir ( $p -> real_full_path ))
2001-07-13 07:12:18 +02:00
{
2001-08-11 11:01:47 +02:00
$dir_handle = opendir ( $p -> real_full_path );
2004-09-20 12:50:46 +02:00
while (( $filename = readdir ( $dir_handle )))
2001-07-13 07:12:18 +02:00
{
2001-09-28 22:41:36 +02:00
if ( $filename == '.' || $filename == '..' )
2001-08-11 11:01:47 +02:00
{
continue ;
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$rarray [] = $this -> get_real_info ( array (
'string' => $p -> fake_full_path . '/' . $filename ,
'relatives' => array ( RELATIVE_NONE )
)
);
2001-07-13 07:12:18 +02:00
}
}
2001-08-11 11:01:47 +02:00
else
2001-07-13 07:12:18 +02:00
{
2002-01-16 07:36:51 +01:00
$rarray [] = $this -> get_real_info ( array (
'string' => $p -> fake_full_path ,
'relatives' => array ( RELATIVE_NONE )
)
);
2001-07-13 07:12:18 +02:00
}
2001-09-28 22:41:36 +02:00
2001-08-24 09:44:43 +02:00
if ( ! is_array ( $rarray ))
{
$rarray = array ();
}
2004-09-20 12:50:46 +02:00
foreach ( $rarray as $file_array )
2001-07-13 07:12:18 +02:00
{
2002-01-16 07:36:51 +01:00
$p2 = $this -> path_parts ( array (
'string' => $file_array [ 'directory' ] . '/' . $file_array [ 'name' ],
'relatives' => array ( RELATIVE_NONE )
)
);
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
/* Note the mime_type. This can be "Directory", which is how we create directories */
2002-01-07 11:50:42 +01:00
$set_attributes_array = Array (
'size' => $file_array [ 'size' ],
'mime_type' => $file_array [ 'mime_type' ]
);
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
if ( ! $this -> file_exists ( array (
'string' => $p2 -> fake_full_path ,
'relatives' => array ( RELATIVE_NONE )
))
)
2001-08-11 11:01:47 +02:00
{
2002-01-16 07:36:51 +01:00
$this -> touch ( array (
'string' => $p2 -> fake_full_path ,
'relatives' => array ( RELATIVE_NONE )
)
);
}
2003-09-21 15:54:07 +02:00
$this -> set_attributes ( array (
'string' => $p2 -> fake_full_path ,
'relatives' => array ( RELATIVE_NONE ),
'attributes' => $set_attributes_array
)
);
if ( $recursive && $file_array [ 'mime_type' ] == 'Directory' )
2002-01-16 07:36:51 +01:00
{
2003-09-21 15:54:07 +02:00
$dir_data = $data ;
$dir_data [ 'string' ] = $file_array [ 'directory' ] . '/' . $file_array [ 'name' ];
$this -> update_real ( $dir_data , $recursive );
2001-08-11 11:01:47 +02:00
}
2001-07-13 07:12:18 +02:00
}
}
}
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
/* Helper functions */
2001-09-28 22:41:36 +02:00
2002-06-24 05:18:59 +02:00
/* This fetchs all available file system information for string (not using the database) */
2002-01-16 07:36:51 +01:00
function get_real_info ( $data )
2001-07-13 07:12:18 +02:00
{
2002-01-16 07:36:51 +01:00
if ( ! is_array ( $data ))
2001-09-24 20:17:26 +02:00
{
2002-01-16 07:36:51 +01:00
$data = array ();
2001-09-24 20:17:26 +02:00
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$default_values = array
(
'relatives' => array ( RELATIVE_CURRENT )
);
$data = array_merge ( $this -> default_values ( $data , $default_values ), $data );
$p = $this -> path_parts ( array (
'string' => $data [ 'string' ],
'relatives' => array ( $data [ 'relatives' ][ 0 ])
)
);
2001-09-28 22:41:36 +02:00
2001-08-11 11:01:47 +02:00
if ( is_dir ( $p -> real_full_path ))
{
2001-09-28 22:41:36 +02:00
$mime_type = 'Directory' ;
2001-08-11 11:01:47 +02:00
}
2001-12-15 05:24:37 +01:00
else
{
2002-01-16 07:36:51 +01:00
$mime_type = $this -> get_ext_mime_type ( array (
'string' => $p -> fake_name
)
);
2001-12-15 05:24:37 +01:00
if ( $mime_type )
{
2004-09-20 12:50:46 +02:00
$this -> db -> update ( $this -> vfs_table , array (
2005-02-26 15:00:02 +01:00
'vfs_mime_type' => $mime_type
2004-09-20 12:50:46 +02:00
), array (
2005-02-26 15:00:02 +01:00
'vfs_directory' => $p -> fake_leading_dirs ,
'vfs_name' => $p -> fake_name ,
2004-09-20 12:50:46 +02:00
$this -> extra_sql ( array ( 'query_type' => VFS_SQL_SELECT ))
), __LINE__ , __FILE__ );
2001-12-15 05:24:37 +01:00
}
}
2001-09-28 22:41:36 +02:00
2002-01-16 07:36:51 +01:00
$size = filesize ( $p -> real_full_path );
2001-09-28 22:41:36 +02:00
$rarray = array (
'directory' => $p -> fake_leading_dirs ,
'name' => $p -> fake_name ,
2002-01-16 07:36:51 +01:00
'size' => $size ,
2001-09-28 22:41:36 +02:00
'mime_type' => $mime_type
);
2004-09-20 12:50:46 +02:00
return $rarray ;
2001-07-13 07:12:18 +02:00
}
2001-05-25 05:34:24 +02:00
}
2004-09-20 12:50:46 +02:00
?>