mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-27 00:58:55 +01:00
Classes for vfs sql implementation v2
Responsible developer: viniciuscb (Vinicius Cubas Brand)
This commit is contained in:
parent
e69b1c0f96
commit
252075f37a
276
phpgwapi/inc/class.vfs_customfields.inc.php
Normal file
276
phpgwapi/inc/class.vfs_customfields.inc.php
Normal file
@ -0,0 +1,276 @@
|
||||
<?php
|
||||
/***************************************************************************\
|
||||
* eGroupWare - File Manager *
|
||||
* http://www.egroupware.org *
|
||||
* Written by: *
|
||||
* - Vinicius Cubas Brand <viniciuscb@users.sourceforge.net> *
|
||||
* sponsored by Thyamad - http://www.thyamad.com *
|
||||
* ------------------------------------------------------------------------- *
|
||||
* Description: Custom Field class handler for VFS (SQL implementation v2) *
|
||||
* ------------------------------------------------------------------------- *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
* option) any later version. *
|
||||
\***************************************************************************/
|
||||
|
||||
class vfs_customfields
|
||||
{
|
||||
var $db;
|
||||
|
||||
function vfs_customfields()
|
||||
{
|
||||
$this->db = $GLOBALS['phpgw']->db;
|
||||
|
||||
}
|
||||
|
||||
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- #
|
||||
# Functions to associate customfields to a file #
|
||||
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- #
|
||||
|
||||
|
||||
//$file_id: the id of the file
|
||||
function & get_fields_by_fileid($file_id)
|
||||
{
|
||||
if (!is_numeric($file_id) || !(((int)$file_id)==$file_id))
|
||||
return false;
|
||||
|
||||
$sql = "SELECT cf.customfield_name as name,
|
||||
cfd.data as data
|
||||
FROM phpgw_vfs2_customfields cf,
|
||||
phpgw_vfs2_customfields_data cfd
|
||||
WHERE cf.customfield_id = cfd.customfield_id
|
||||
AND cf.customfield_active = 'Y'
|
||||
AND cfd.file_id = $file_id";
|
||||
|
||||
$this->db->query($sql,__LINE__,__FILE__);
|
||||
|
||||
while($this->db->next_record())
|
||||
{
|
||||
$result[$this->db->Record['name']] = $this->db->Record['data'];
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
//$data = array(file_id => array('field1'=> 'value', ....),
|
||||
// file_id2 => array(...) ... )
|
||||
// Store will do insert or update, depending if the field exists or
|
||||
// not.
|
||||
function store_fields($data)
|
||||
{
|
||||
if (!is_array($data))
|
||||
return false;
|
||||
|
||||
$fields = $this->get_customfields('customfield_name');
|
||||
|
||||
foreach($data as $file_id => $file_data)
|
||||
{
|
||||
foreach($file_data as $name => $value)
|
||||
{
|
||||
//Column type does not exists
|
||||
if (!array_key_exists($name,$fields))
|
||||
{
|
||||
//TODO ERROR HANDLING
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->db->insert('phpgw_vfs2_customfields_data',
|
||||
array('data' => $value),
|
||||
array('file_id'=>$file_id,'customfield_id'=>$fields[$name]['customfield_id']),
|
||||
__LINE__,__FILE__);
|
||||
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//$data = array('file_id' => array('field1','field2',...),
|
||||
// 'fileid2' => ... )
|
||||
function delete_fields($data)
|
||||
{
|
||||
|
||||
$fields = $this->get_customfields('customfield_name');
|
||||
|
||||
foreach($data as $file_id => $file_fields)
|
||||
{
|
||||
foreach($file_fields as $column_name)
|
||||
{
|
||||
if (!array_key_exists($column_name,$fields))
|
||||
{
|
||||
//TODO ERROR HANDLING
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->db->delete('phpgw_vfs2_customfields_data',
|
||||
array('file_id' => $file_id,'customfield_id'=>$fields[$column_name]['customfield_id']),__LINE__,__FILE__);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Search the files that have $keyword in any field, or in the fields
|
||||
specified in the array fields
|
||||
@param $fields array('field1','fields2',...)*/
|
||||
function search_files($keyword,$fields=null)
|
||||
{
|
||||
|
||||
$where = '';
|
||||
|
||||
if ($fields)
|
||||
{
|
||||
$customfields = $this->get_customfields('customfield_name');
|
||||
|
||||
foreach ($fields as $field)
|
||||
{
|
||||
if ($customfields[$field])
|
||||
{
|
||||
$cf_ids[] = 'customfield_id='.$customfields[$field]['customfield_id'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($cf_ids)
|
||||
{
|
||||
$where = implode(' OR ',$cf_ids);
|
||||
|
||||
$where = 'AND ('.$where.')';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
$sql = "SELECT file_id
|
||||
FROM phpgw_vfs2_customfields_data
|
||||
WHERE data LIKE '%$keyword%'
|
||||
$where";
|
||||
|
||||
$this->db->query($sql,__LINE__,__FILE__);
|
||||
|
||||
$res = array();
|
||||
while($this->db->next_record())
|
||||
{
|
||||
$res[] = $this->db->Record['file_id'];
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- #
|
||||
# Functions to manage custom field types #
|
||||
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- #
|
||||
|
||||
//Gets all custom field types, indexed by $indexedby.
|
||||
//Example: array( 'customfieldname1' => array('customfield_id'=>x,'customfield_description'=>y,'type'=>z...)...)
|
||||
//@param bool $activeonly If true, brings only active fields
|
||||
function get_customfields($indexedby='customfield_name',$activeonly=true)
|
||||
{
|
||||
$where=($activeonly)?array('customfield_active'=>'Y'):array();
|
||||
|
||||
$this->db->select('phpgw_vfs2_customfields','*',$where,
|
||||
__LINE__,__FILE__);
|
||||
|
||||
$result = array();
|
||||
while($this->db->next_record())
|
||||
{
|
||||
$result[] = $this->db->Record;
|
||||
}
|
||||
|
||||
if (!is_array($result[0]) || !array_key_exists($indexedby,$result[0]))
|
||||
{
|
||||
$indexedby = 'customfield_name';
|
||||
}
|
||||
|
||||
$result2 = array();
|
||||
foreach($result as $key => $val)
|
||||
{
|
||||
$result2[$val[$indexedby]] = $val;
|
||||
}
|
||||
|
||||
return $result2;
|
||||
}
|
||||
|
||||
//samething that $this->get_customfields, but returns an array in the
|
||||
//format array('name' => 'description', 'name2'=>'desc2',...)
|
||||
function get_attributes($activeonly=true)
|
||||
{
|
||||
$where=($activeonly)?array('customfield_active'=>'Y'):array();
|
||||
|
||||
$this->db->select('phpgw_vfs2_customfields','*',$where,
|
||||
__LINE__,__FILE__);
|
||||
|
||||
while($this->db->next_record())
|
||||
{
|
||||
$result[] = $this->db->Record;
|
||||
}
|
||||
|
||||
$result2 = array();
|
||||
foreach($result as $key => $val)
|
||||
{
|
||||
$result2[$val['customfield_name']] = $val['customfield_description'];
|
||||
}
|
||||
|
||||
return $result2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Add a new type of custom field
|
||||
//$type can be of the same possible types for egw
|
||||
function add_customfield($name,$description,$type,$precision='',$active='N')
|
||||
{
|
||||
$active = strtoupper($active);
|
||||
|
||||
$res = $this->db->insert('phpgw_vfs2_customfields',array(
|
||||
'customfield_name' => $name,
|
||||
'customfield_description' => $description,
|
||||
'customfield_type' => $type,
|
||||
'customfield_precision' => $precision,
|
||||
'customfield_active' => $active ),
|
||||
__LINE__,__FILE__);
|
||||
|
||||
if ($res)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//Update a customfield type (customfield_name, customfield_description, type, precision, active)
|
||||
function update_customfield($customfield_id,$data)
|
||||
{
|
||||
if (!is_numeric($customfield_id) || !(((int)$customfield_id)==$customfield_id))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($data['customfield_active'])
|
||||
{
|
||||
$data['customfield_active'] = strtoupper($data['customfield_active']);
|
||||
}
|
||||
|
||||
if ($this->db->update('phpgw_vfs2_customfields',$data,array('customfield_id'=>$customfield_id),__LINE__,__FILE__))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//generally better inactivate a field than remove.
|
||||
function remove_customfield($customfield_id)
|
||||
{
|
||||
$res = $this->db->delete('phpgw_vfs2_customfields',array('customfield_id'=>$customfield_id),__LINE__,__FILE__);
|
||||
|
||||
if ($res)
|
||||
{
|
||||
$res2 = $this->db->delete('phpgw_vfs2_customfields_data',array('customfield_id'=>$customfield_id),__LINE__,__FILE__);
|
||||
|
||||
if ($res2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
334
phpgwapi/inc/class.vfs_mimetypes.inc.php
Normal file
334
phpgwapi/inc/class.vfs_mimetypes.inc.php
Normal file
@ -0,0 +1,334 @@
|
||||
<?php
|
||||
/***************************************************************************\
|
||||
* eGroupWare - File Manager *
|
||||
* http://www.egroupware.org *
|
||||
* Written by: *
|
||||
* - Vinicius Cubas Brand <viniciuscb@users.sourceforge.net> *
|
||||
* sponsored by Thyamad - http://www.thyamad.com *
|
||||
* ------------------------------------------------------------------------- *
|
||||
* Description: Mime type class handler for VFS (SQL implementation v2) *
|
||||
* ------------------------------------------------------------------------- *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
* option) any later version. *
|
||||
\***************************************************************************/
|
||||
|
||||
#based on the filetypes.inc.php class by intermesh, see groupoffice.com
|
||||
|
||||
#02 Sep 2004 viniciuscb Initial Release
|
||||
|
||||
class vfs_mimetypes
|
||||
{
|
||||
var $default_filetype_icon;
|
||||
var $db;
|
||||
var $vfs; //Just to get mime types from vfs->get_ext_mime_type()
|
||||
|
||||
var $default_mimetype = "application/OCTET-STREAM";
|
||||
|
||||
function vfs_mimetypes($create_vfs=true)
|
||||
{
|
||||
//use create_vfs=false and after this use $this->set_vfs to keep the
|
||||
// same object (i.e. use reference) in $this->vfs
|
||||
if ($create_vfs)
|
||||
{
|
||||
$this->vfs = CreateObject('phpgwapi.vfs');
|
||||
}
|
||||
|
||||
$this->default_filetype_icon = PHPGW_INCLUDE_ROOT.'/filescenter/icons/default.gif';
|
||||
|
||||
$this->db = $GLOBALS['phpgw']->db;
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
* function add_filetype
|
||||
* @description Adds a new mime_type to the mime_types repository
|
||||
* @note One of the two: extension or mime are required
|
||||
* @param extension string A file extension
|
||||
* @param mime string the mime type according to the RFCs 2046/1524
|
||||
* @param friendly string File type description in human-friendly
|
||||
* format
|
||||
* @param image string content of icon file
|
||||
* @param icon_name string complete path filename of icon image
|
||||
* (note: will be used only when icon_data is not set)
|
||||
* @param mime_magic data used for mime_magic functions (planned)
|
||||
* @param return_image bool if true will return the binary data of image
|
||||
* @result Array with mime_id and other mime info, false otherwise
|
||||
*/
|
||||
function add_filetype($data,$return_image=false,$dont_update=false)
|
||||
{
|
||||
|
||||
if (!$data['extension'] && !$data['mime'])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$data['mime'])
|
||||
{
|
||||
$data['mime'] = $this->get_mime_type($data['extension']);
|
||||
}
|
||||
elseif (!$data['extension'])
|
||||
{
|
||||
$data['extension'] = '(n/a)'; //Thinking in 'Directory'
|
||||
}
|
||||
|
||||
if (!$data['friendly'])
|
||||
{
|
||||
if ($data['extension'] != '(n/a)')
|
||||
{
|
||||
$data['friendly'] = strtoupper($data['extension']).' File';
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['friendly'] = $data['mime'];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!$data['image'])
|
||||
{
|
||||
if (!$data['icon_name'] || !file_exists($data['icon_name']))
|
||||
{
|
||||
$data['icon_name'] = $this->default_filetype_icon;
|
||||
}
|
||||
$fp = fopen($data['icon_name'],"r");
|
||||
$data['image'] = fread($fp,filesize($data['icon_name']));
|
||||
fclose($fp);
|
||||
|
||||
unset($data['icon_name']);
|
||||
}
|
||||
|
||||
|
||||
$where['extension'] = $data['extension'];
|
||||
#$where['mime'] = $data['mime'];
|
||||
|
||||
if ($dont_update)
|
||||
{
|
||||
$this->db->select('phpgw_vfs2_mimetypes','mime_id',$where,__LINE__,__FILE__);
|
||||
if ($this->db->next_record())
|
||||
{
|
||||
return false; //msgerror Existent register that cannot be overwritten
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$res = $this->db->insert('phpgw_vfs2_mimetypes',$data,$where,__LINE__,__FILE__);
|
||||
|
||||
|
||||
if($res)
|
||||
{
|
||||
$this->db->select('phpgw_vfs2_mimetypes','mime_id',$where,
|
||||
__LINE__,__FILE__);
|
||||
|
||||
$this->db->next_record();
|
||||
|
||||
$data['mime_id'] = $this->db->Record['mime_id'];
|
||||
|
||||
if (!$return_image)
|
||||
{
|
||||
unset($data['image']);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* function edit_filetype
|
||||
* @description Edits a mime_type of the mime_types repository
|
||||
* @note mime_id required. Will change only passed vars.
|
||||
* @param extension string A file extension
|
||||
* @param mime string the mime type according to the RFCs 2046/1524
|
||||
* @param friendly string File type description in human-friendly
|
||||
* format
|
||||
* @param image string content of icon file
|
||||
* @param icon_name string complete path filename of icon image
|
||||
* (note: will be used only when icon_data is not set)
|
||||
* @param mime_magic data used for mime_magic functions (planned)
|
||||
* @param return_image bool if true will return the binary data of image
|
||||
* @result Array with mime_id and other mime info, false otherwise
|
||||
*/
|
||||
function edit_filetype($data,$return_image=false)
|
||||
{
|
||||
|
||||
if (!$data['mime_id'])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$where['mime_id'] = $data['mime_id'];
|
||||
|
||||
$res = $this->db->update('phpgw_vfs2_mimetypes',$data,$where,__LINE__,__FILE__);
|
||||
|
||||
|
||||
if($res)
|
||||
{
|
||||
if ($return_image)
|
||||
{
|
||||
$return_fields = '*';
|
||||
}
|
||||
else
|
||||
{
|
||||
$return_fields = 'mime_id,extension,mime,friendly,mime_magic,proper_id';
|
||||
}
|
||||
$this->db->select('phpgw_vfs2_mimetypes',$return_fields,$where,
|
||||
__LINE__,__FILE__);
|
||||
|
||||
$this->db->next_record();
|
||||
|
||||
return $this->db->Record;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
* function get_type
|
||||
* @description Returns a mime type, based in extension or mime_id
|
||||
* @param $desc array have index 'extension', 'mime_id' or 'mime'
|
||||
* @param $return_image if true will return the binary data of image
|
||||
* @result Array with mime_id and other mime info, false otherwise
|
||||
*/
|
||||
function get_type($data, $return_image=false)
|
||||
{
|
||||
|
||||
//TODO error messages
|
||||
if ((!$data['extension'] || $data['extension'] == '(n/a)') &&
|
||||
!$data['mime_id'] && !$data['mime'])
|
||||
return false;
|
||||
|
||||
|
||||
$return_fields = ($return_image)?'*':'mime_id,extension,friendly,mime_magic,mime,proper_id';
|
||||
|
||||
if ($data['mime_id'])
|
||||
{
|
||||
$this->db->select('phpgw_vfs2_mimetypes',$return_fields,
|
||||
array('mime_id'=>$data['mime_id']),__LINE__,__FILE__);
|
||||
}
|
||||
else if ($data['extension'])
|
||||
{
|
||||
$this->db->select('phpgw_vfs2_mimetypes',$return_fields,
|
||||
array('extension'=>$data['extension']),__LINE__,__FILE__);
|
||||
}
|
||||
else if ($data['mime'])
|
||||
{
|
||||
$this->db->select('phpgw_vfs2_mimetypes',$return_fields,
|
||||
array('mime'=>$data['mime']),__LINE__,__FILE__);
|
||||
}
|
||||
|
||||
if($this->db->next_record())
|
||||
return $this->db->Record;
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
* function get_filetypes
|
||||
* @description Returns an array with all file types in the repository
|
||||
* @param $return_images if true, the images are returned in the array
|
||||
* @param $offset int if specified, will bring a subset of repository
|
||||
* @result Array: $arr[1]['mime_id'] ...
|
||||
*/
|
||||
function get_filetypes($return_images=false,$offset=false)
|
||||
{
|
||||
$return_fields = ($return_images)?'*':'mime_id,extension,friendly,mime_magic,mime,proper_id';
|
||||
|
||||
$this->db->select('phpgw_vfs2_mimetypes',$return_fields,false,
|
||||
__LINE__,__FILE__,$offset);
|
||||
|
||||
$result = array();
|
||||
while ($this->db->next_record())
|
||||
{
|
||||
$result[] = $this->db->Record;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/*!
|
||||
* function update_filetype
|
||||
* @description Updates a file type information in the filetype
|
||||
* repository
|
||||
* @param $return_image if true will return the binary data of image
|
||||
* @note parameters in $data: the same of add_filetype()
|
||||
* @result bool true on success, false otherwise
|
||||
*/
|
||||
function update_filetype($data)
|
||||
{
|
||||
if (!$data['mime_id'])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($data['icon_name'])
|
||||
{
|
||||
if (file_exists($data['icon_name']))
|
||||
{
|
||||
$fp = fopen($data['icon_name'],"r");
|
||||
$data['image'] = fread($fp,filesize($icon));
|
||||
fclose($fp);
|
||||
}
|
||||
|
||||
unset($data['icon_name']);
|
||||
}
|
||||
|
||||
|
||||
$where['mime_id'] = $data['mime_id'];
|
||||
|
||||
if ($this->db->update('phpgw_vfs2_mimetypes',$data,$where,__LINE__,
|
||||
__FILE__))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* function delete_filetype
|
||||
* @description deletes a type from the file type repository
|
||||
* @param $mime_id the mime_id of the record
|
||||
* @result bool true on success, false otherwise
|
||||
*/
|
||||
function delete_filetype($mime_id)
|
||||
{
|
||||
if ($this->db->delete('phpgw_vfs2_mimetypes',
|
||||
array('mime_id'=>$mime_id),__LINE__,__FILE__))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function set_vfs(&$vfs)
|
||||
{
|
||||
$this->vfs =& $vfs;
|
||||
}
|
||||
|
||||
#private methods
|
||||
|
||||
function get_mime_type($extension)
|
||||
{
|
||||
return $this->vfs->get_ext_mime_type(array('string'=>$extension));
|
||||
}
|
||||
|
||||
function default_values ($data, $default_values)
|
||||
{
|
||||
for ($i = 0; list ($key, $value) = each ($default_values); $i++)
|
||||
{
|
||||
if (!isset ($data[$key]))
|
||||
{
|
||||
$data[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
373
phpgwapi/inc/class.vfs_prefixes.inc.php
Normal file
373
phpgwapi/inc/class.vfs_prefixes.inc.php
Normal file
@ -0,0 +1,373 @@
|
||||
<?php
|
||||
/***************************************************************************\
|
||||
* eGroupWare - File Manager *
|
||||
* http://www.egroupware.org *
|
||||
* Written by: *
|
||||
* - Vinicius Cubas Brand <viniciuscb@users.sourceforge.net> *
|
||||
* sponsored by Thyamad - http://www.thyamad.com *
|
||||
* ------------------------------------------------------------------------- *
|
||||
* Description: File ID Prefixes class handler for SQL implementation v2 *
|
||||
* ------------------------------------------------------------------------- *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
* option) any later version. *
|
||||
\***************************************************************************/
|
||||
|
||||
#12 Oct 2004 viniciuscb Initial Release
|
||||
|
||||
define ('PHPGW_VFS2_PREFIX_APP','vfs2_prefix'); //for prefix
|
||||
define ('PHPGW_VFS2_PTYPE_APP','vfs2_ptype'); //for file type
|
||||
|
||||
class vfs_prefixes
|
||||
{
|
||||
var $db;
|
||||
|
||||
var $table_fields = array(
|
||||
'prefix_id',
|
||||
'owner_id',
|
||||
'prefix',
|
||||
'prefix_description',
|
||||
'prefix_type'
|
||||
);
|
||||
|
||||
function vfs_prefixes()
|
||||
{
|
||||
$this->db = $GLOBALS['phpgw']->db;
|
||||
}
|
||||
|
||||
/*!
|
||||
* function add
|
||||
* @description Adds a new File ID Prefix to the prefixes repository
|
||||
* @param prefix string (required) A prefix
|
||||
* @param prefix_description string (optional) Brief prefix description
|
||||
* @param owner_id int (required) Owner Id of prefix
|
||||
* @param prefix_type (optional) can be 'p' for prefix, 't' for type.
|
||||
* @result (int) prefix_id
|
||||
*
|
||||
* @note: will search for another equal $prefix in repository. If
|
||||
* exists, returns its prefix_id and if user have permission,
|
||||
* updates this prefix. If don't exists, insert and return its
|
||||
* prefix_id. $dont_update will not do any update if exists, even
|
||||
* if current user can update.
|
||||
*/
|
||||
function add($data,$dont_update=false)
|
||||
{
|
||||
|
||||
if (!$data['prefix'])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$data['prefix_type'])
|
||||
{
|
||||
$data['prefix_type'] = 'p';
|
||||
}
|
||||
|
||||
//eliminate keys which are not a field in table
|
||||
foreach($data as $key => $val)
|
||||
{
|
||||
if (!in_array($key,$this->table_fields))
|
||||
{
|
||||
unset($data[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
//see if exists some equal prefix id
|
||||
$this->db->select('phpgw_vfs2_prefixes','prefix_id',array('prefix' => $data['prefix']));
|
||||
|
||||
if($this->db->next_record()) //exists
|
||||
{
|
||||
if ($dont_update)
|
||||
{
|
||||
return $this->db->Record['prefix_id'];
|
||||
}
|
||||
$data['prefix_id'] = $this->db->Record['prefix_id'];
|
||||
return $this->edit($data);
|
||||
}
|
||||
|
||||
if (!$data['owner_id'])
|
||||
{
|
||||
$data['owner_id'] = $GLOBALS['phpgw_info']['user']['account_id'];
|
||||
}
|
||||
|
||||
$this->db->insert('phpgw_vfs2_prefixes',$data,false,__LINE__,__FILE__);
|
||||
|
||||
$this->db->select('phpgw_vfs2_prefixes','prefix_id',array('prefix' => $data['prefix']));
|
||||
|
||||
if($this->db->next_record()) //exists
|
||||
{
|
||||
return $this->db->Record['prefix_id'];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* function edit
|
||||
* @description Edits a File ID Prefix
|
||||
* @param prefix_id int (required) The ID for prefix
|
||||
* @param prefix string (optional) A prefix
|
||||
* @param prefix_description string (optional) Brief prefix description
|
||||
* @param owner_id int (optional) Owner Id of prefix
|
||||
* @param prefix_type (optional) can be 'p' for prefix, 't' for type.
|
||||
* @result (int) prefix_id
|
||||
* @result (bool) true on success, false on any other possibility
|
||||
*/
|
||||
function edit($data)
|
||||
{
|
||||
if (!$data['prefix_id'])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//eliminate keys which are not a field in table
|
||||
foreach($data as $key => $val)
|
||||
{
|
||||
if (!in_array($key,$this->table_fields))
|
||||
{
|
||||
unset($data[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
$where['prefix_id'] = $data['prefix_id'];
|
||||
unset($data['prefix_id']);
|
||||
|
||||
return $this->db->update('phpgw_vfs2_prefixes',$data,$where,__LINE__,__FILE__);
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
* function remove
|
||||
* @description Removes a File ID Prefix
|
||||
* @param prefix_id int (required) The ID for prefix
|
||||
* @result (bool) true on success, false on any other possibility
|
||||
*/
|
||||
function remove($prefix_id)
|
||||
{
|
||||
return $this->db->delete('phpgw_vfs2_prefixes',array('prefix_id' => $prefix_id),__LINE__,__FILE__);
|
||||
}
|
||||
|
||||
/*!
|
||||
* function get
|
||||
* @description Gets information about a prefix just based in prefix_id
|
||||
* @param prefix_id int (required) The ID for prefix
|
||||
* OR
|
||||
* @param prefix int (required) The prefix
|
||||
* @result (array) with column names as indexes, empty array if inexist
|
||||
*/
|
||||
function get($data)
|
||||
{
|
||||
if (!$data['prefix_id'] && !$data['prefix'])
|
||||
return false;
|
||||
|
||||
|
||||
$this->db->select('phpgw_vfs2_prefixes','*',$data,__LINE__,__FILE__);
|
||||
|
||||
if ($this->db->next_record())
|
||||
{
|
||||
return $this->db->Record;
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
/*!
|
||||
* function get_prefixes
|
||||
* @description Gets all prefixes this user can view, based in querying
|
||||
* acl
|
||||
* @param user_id int (required) The ID of user to whom you want to
|
||||
* know, or will get current user as default
|
||||
* @param status string If 'view', returns info about all prefixes
|
||||
* user can view. if 'owns', return only prefixes user owns
|
||||
* @result (array) with column names as indexes, empty array if inexist
|
||||
*/
|
||||
function get_prefixes($status='view',$user_id=false,$type='p')
|
||||
{
|
||||
if (!$user_id)
|
||||
{
|
||||
$user_id = $GLOBALS['phpgw_info']['user']['account_id'];
|
||||
}
|
||||
|
||||
switch ($status)
|
||||
{
|
||||
case 'owns':
|
||||
$this->db->select('phpgw_vfs2_prefixes','*',array('owner_id'=>$user_id,'prefix_type'=>$type),__LINE__,__FILE__);
|
||||
|
||||
while($this->db->next_record())
|
||||
{
|
||||
$return[] = $this->db->Record;
|
||||
}
|
||||
|
||||
break;
|
||||
case 'view':
|
||||
$acl = CreateObject('phpgwapi.acl',$user_id);
|
||||
|
||||
//fetch ids of prefixes that user can view
|
||||
if (!$pr_list = $acl->get_location_list_for_id(PHPGW_VFS2_PREFIX_APP,PHPGW_ACL_READ,$user_id))
|
||||
{
|
||||
$pr_list = array();
|
||||
}
|
||||
|
||||
//fetch ids of prefixes that groups user belong to can view
|
||||
//Note: this will be in two phases. One: fetch groups user
|
||||
// belongs to. Two: fetch prefix list for these groups
|
||||
|
||||
/* Note: prefixes are organized in phpgwapi.acl in the
|
||||
* following schema:
|
||||
* - appname: (PHPGW_VFS2_PREFIX_APP)
|
||||
* - location: id_prefix
|
||||
* - account_id: Id of user that has grants (not the
|
||||
* grantor. The grantor is only the owner of prefix,
|
||||
* defined in prefixes repository).
|
||||
* - acl_rights: PHPGW_ACL_READ
|
||||
*/
|
||||
|
||||
$user_groups = $GLOBALS['phpgw']->accounts->membership($user_id);
|
||||
|
||||
foreach($user_groups as $group)
|
||||
{
|
||||
if (!$group_pr_list = $acl->get_location_list_for_id(PHPGW_VFS2_PREFIX_APP,PHPGW_ACL_READ,$group['account_id']))
|
||||
{
|
||||
$group_pr_list = array();
|
||||
}
|
||||
|
||||
$pr_list = array_merge($pr_list,$group_pr_list);
|
||||
}
|
||||
|
||||
//remove dupliate values
|
||||
$pr_list = array_unique($pr_list);
|
||||
|
||||
//now we have the list of prefixes user can view. We must
|
||||
//now fetch complete information about prefixes of
|
||||
//phpgw_vfs2_prefixes
|
||||
|
||||
if (!count($pr_list))
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
if ($pr_list)
|
||||
{
|
||||
$prefix_string = '('.implode(',',$pr_list).')';
|
||||
|
||||
$this->db->select('phpgw_vfs2_prefixes','*','prefix_id IN '.$prefix_string." AND prefix_type='$type'",__LINE__,__FILE__);
|
||||
|
||||
while($this->db->next_record())
|
||||
{
|
||||
$return[] = $this->db->Record;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/*!
|
||||
* function update_permissions
|
||||
* @description Updates users who can see a prefix
|
||||
*
|
||||
* @param prefix_id int (required) The prefix that will have permissions
|
||||
* changed
|
||||
* @param user_list array Array with account_ids that can read prefix
|
||||
* as values.
|
||||
*
|
||||
* @result (bool)
|
||||
*/
|
||||
function update_permissions($prefix_id,$user_list)
|
||||
{
|
||||
|
||||
//1. see if current user is owner of the prefix
|
||||
$current_user_id = $GLOBALS['phpgw_info']['user']['account_id'];
|
||||
|
||||
$prefix_info = $this->get(array('prefix_id'=>$prefix_id));
|
||||
|
||||
if ($current_user_id != $prefix_info['owner_id'])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//2. get current permission for prefix
|
||||
$current_permissions = $this->get_permissions(array('prefix_id'=>$prefix_id));
|
||||
|
||||
//3. change permissions
|
||||
$list_of_users_to_add = array_diff($user_list,$current_permissions);
|
||||
$list_of_users_to_del = array_diff($current_permissions,$user_list);
|
||||
|
||||
|
||||
$acl = CreateObject('phpgwapi.acl',$current_user_id);
|
||||
|
||||
foreach($list_of_users_to_add as $user_id)
|
||||
{
|
||||
$acl->account_id = $user_id;
|
||||
$acl->read_repository();
|
||||
#echo "<br>\nAdded: prefix $prefix_id ; user $user_id";
|
||||
$acl->add(PHPGW_VFS2_PREFIX_APP,$prefix_id,PHPGW_ACL_READ);
|
||||
$acl->save_repository();
|
||||
}
|
||||
|
||||
foreach($list_of_users_to_del as $user_id)
|
||||
{
|
||||
$acl->account_id = $user_id;
|
||||
$acl->read_repository();
|
||||
#echo "<br>\nDeleted: prefix $prefix_id ; user $user_id";
|
||||
$acl->delete(PHPGW_VFS2_PREFIX_APP,$prefix_id);
|
||||
$acl->save_repository();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
* function get_permissions
|
||||
* @description This will get all permissions for a given prefix.
|
||||
* In other words, will return an array of all accounts who
|
||||
* can see a prefix. Will not dive into groups' users,
|
||||
* only showing user and group accounts who can see
|
||||
* prefix.
|
||||
*
|
||||
* @param prefix int (required) The File ID Prefix
|
||||
* OR
|
||||
* @param prefix_id int (required) The ID of the File ID Prefix
|
||||
* @param prefixes array The same type of the return of get_prefixes
|
||||
*
|
||||
* @result (array) with column names as indexes, empty array if inexist
|
||||
*/
|
||||
function get_permissions($data)
|
||||
{
|
||||
if (is_numeric($data))
|
||||
{
|
||||
$prefix_id = $data;
|
||||
}
|
||||
elseif ($data['prefix'])
|
||||
{
|
||||
$this->db->select('phpgw_vfs2_prefixes','prefix_id',array('prefix'=>$data['prefix']),__LINE__,__FILE__);
|
||||
if ($this->db->next_record())
|
||||
{
|
||||
$prefix_id = $this->db->Record['prefix_id'];
|
||||
}
|
||||
}
|
||||
elseif($data['prefix_id'])
|
||||
{
|
||||
$prefix_id = $data['prefix_id'];
|
||||
}
|
||||
|
||||
if (!$prefix_id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$acl = CreateObject('phpgwapi.acl');
|
||||
$user_ids = $acl->get_ids_for_location($prefix_id,PHPGW_ACL_READ,PHPGW_VFS2_PREFIX_APP);
|
||||
|
||||
return ($user_ids)?$user_ids:array();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
@ -492,6 +492,10 @@
|
||||
*
|
||||
* update_real - Ensure that information about a location is
|
||||
* up-to-date
|
||||
*
|
||||
* compress - Archives a file or set of files in a compressed file
|
||||
*
|
||||
* extract - Dearchives a file or set of files of a compressed file
|
||||
*/
|
||||
|
||||
/*!
|
||||
@ -507,6 +511,37 @@
|
||||
* @result Boolean. True on success, False otherwise.
|
||||
*/
|
||||
function update_real ($data) { return False; }
|
||||
|
||||
/*!
|
||||
* @function compress
|
||||
* @abstract Creates an archive from a file or a set of files
|
||||
* @required files File names to be stored in archive (array)
|
||||
* @required name Name of archive
|
||||
* @optional type The type of compression, can be 'zip'(default)or 'gz'
|
||||
* @optional relatives Relativity array (default: RELATIVE_CURRENT)
|
||||
* Note: the last item is the relativity of the dest archive
|
||||
* @result Boolean. True on success, False otherwise.
|
||||
*/
|
||||
|
||||
function compress ($data) { return False; }
|
||||
|
||||
/*!
|
||||
* @function extract
|
||||
* @abstract Extracts a file (or files) from archive
|
||||
* @required name Name of archive
|
||||
* @required dest The destination path of files to be extracted
|
||||
* @optional type The type of compression, can be 'zip' or 'gz'. If
|
||||
* not specified, uses according to the extension
|
||||
* @optional files Files to be extracted from archive
|
||||
* @optional relatives Relativity array (default: RELATIVE_CURRENT)
|
||||
* Note: the first item is the relativity of the archive, the last of
|
||||
* the dest dir
|
||||
* @result Boolean. True on success, False otherwise.
|
||||
*/
|
||||
|
||||
function extract ($data) { return False; }
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* SHARED FUNCTIONS
|
||||
@ -526,6 +561,12 @@
|
||||
* sanitize - Remove any possible security problems from a location
|
||||
* string (i.e. remove leading '..')
|
||||
*
|
||||
* clean_string - Clean location string. This function is used if
|
||||
* any special characters need to be escaped or removed
|
||||
* before accessing a database, network protocol, etc.
|
||||
* The default is to escape characters before doing an SQL
|
||||
* query.
|
||||
*
|
||||
* getabsolutepath - Translate a location string depending on the
|
||||
* relativity. This is the only function that is
|
||||
* directly concerned with relativity.
|
||||
@ -543,7 +584,7 @@
|
||||
*
|
||||
* cd - Change current directory. This function is used to store the
|
||||
* current directory in a standard way, so that it may be accessed
|
||||
* throughout eGroupWare to provide a consistent view for the user.
|
||||
* throughout phpGroupWare to provide a consistent view for the user.
|
||||
*
|
||||
* pwd - Return current directory
|
||||
*
|
||||
@ -556,6 +597,10 @@
|
||||
* dir - Alias for ls
|
||||
*
|
||||
* command_line - Process and run a Unix-sytle command line
|
||||
*
|
||||
* compress - Archives a file or set of files in a compressed file
|
||||
*
|
||||
* extract - Dearchives a file or set of files of a compressed file
|
||||
*/
|
||||
|
||||
/* PRIVATE functions */
|
||||
@ -613,6 +658,28 @@
|
||||
return (ereg_replace ("^\.+", '', $p->fake_name));
|
||||
}
|
||||
|
||||
/*!
|
||||
* @function clean_string
|
||||
* @abstract Clean location string. This function is used if
|
||||
* any special characters need to be escaped or removed
|
||||
* before accessing a database, network protocol, etc.
|
||||
* The default is to escape characters before doing an SQL
|
||||
* query.
|
||||
* @required string Location string to clean
|
||||
* @result String. Cleaned version of 'string'.
|
||||
*/
|
||||
function clean_string ($data)
|
||||
{
|
||||
if (!is_array ($data))
|
||||
{
|
||||
$data = array ();
|
||||
}
|
||||
|
||||
$string = $GLOBALS['phpgw']->db->db_addslashes ($data['string']);
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @function getabsolutepath
|
||||
* @abstract Translate a location string depending on the
|
||||
@ -847,6 +914,18 @@
|
||||
* real_leading_dirs
|
||||
* real_extra_path BROKEN
|
||||
* real_name
|
||||
* fake_full_path_clean
|
||||
* fake_leading_dirs_clean
|
||||
* fake_extra_path_clean BROKEN
|
||||
* fake_name_clean
|
||||
* real_full_path_clean
|
||||
* real_leading_dirs_clean
|
||||
* real_extra_path_clean BROKEN
|
||||
* real_name_clean
|
||||
* "clean" values are run through vfs->clean_string () and
|
||||
* are safe for use in SQL queries that use key='value'
|
||||
* They should be used ONLY for SQL queries, so are used
|
||||
* mostly internally
|
||||
* mask is either RELATIVE_NONE or RELATIVE_NONE|VFS_REAL,
|
||||
* and is used internally
|
||||
* outside is boolean, True if 'relatives' contains VFS_REAL
|
||||
@ -999,6 +1078,28 @@
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
We have to count it before because new keys will be added,
|
||||
which would create an endless loop
|
||||
*/
|
||||
$count = count ($rarray);
|
||||
reset ($rarray);
|
||||
for ($i = 0; (list ($key, $value) = each ($rarray)) && $i != $count; $i++)
|
||||
{
|
||||
$rarray[$key . '_clean'] = $this->clean_string (array ('string' => $value));
|
||||
}
|
||||
|
||||
if ($data['object'])
|
||||
{
|
||||
$robject = new path_class;
|
||||
|
||||
reset ($rarray);
|
||||
while (list ($key, $value) = each ($rarray))
|
||||
{
|
||||
$robject->$key = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
echo "<br>fake_full_path: $rarray[fake_full_path]
|
||||
<br>fake_leading_dirs: $rarray[fake_leading_dirs]
|
||||
@ -1012,22 +1113,19 @@
|
||||
|
||||
if ($data['object'])
|
||||
{
|
||||
$robject = new path_class;
|
||||
|
||||
foreach($rarray as $key => $value)
|
||||
{
|
||||
$robject->$key = $value;
|
||||
}
|
||||
return ($robject);
|
||||
}
|
||||
return ($rarray);
|
||||
else
|
||||
{
|
||||
return ($rarray);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @function cd
|
||||
* @abstract Change current directory. This function is used to store the
|
||||
* current directory in a standard way, so that it may be accessed
|
||||
* throughout eGroupWare to provide a consistent view for the user.
|
||||
* throughout phpGroupWare to provide a consistent view for the user.
|
||||
* @discussion To cd to the root '/', use:
|
||||
* cd (array(
|
||||
* 'string' => '/',
|
||||
@ -1306,6 +1404,7 @@
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
424
phpgwapi/inc/class.vfs_sharing.inc.php
Normal file
424
phpgwapi/inc/class.vfs_sharing.inc.php
Normal file
@ -0,0 +1,424 @@
|
||||
<?php
|
||||
/***************************************************************************\
|
||||
* eGroupWare - File Manager *
|
||||
* http://www.egroupware.org *
|
||||
* Written by: *
|
||||
* - Vinicius Cubas Brand <viniciuscb@users.sourceforge.net> *
|
||||
* sponsored by Thyamad - http://www.thyamad.com *
|
||||
* ------------------------------------------------------------------------- *
|
||||
* Description: File Sharing class handler for VFS (SQL implementation v2) *
|
||||
* ------------------------------------------------------------------------- *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
* option) any later version. *
|
||||
\***************************************************************************/
|
||||
|
||||
// This class had to be created because file sharing work very differently
|
||||
// In fm2 than in fm.
|
||||
|
||||
#FIXME this class is completely vfs_sql2 oriented. Must exist implementation
|
||||
# to other types
|
||||
|
||||
class vfs_sharing
|
||||
{
|
||||
var $accounts;
|
||||
var $db;
|
||||
|
||||
/*!
|
||||
* function vfs_sharing
|
||||
* @description Class constructor
|
||||
*/
|
||||
function vfs_sharing()
|
||||
{
|
||||
$this->accounts =& $GLOBALS['phpgw']->accounts;
|
||||
$this->db = $GLOBALS['phpgw']->db;
|
||||
}
|
||||
|
||||
/*!
|
||||
* function set_permissions
|
||||
* @description Add specified permissions that do not exist, remove
|
||||
* unspecified permissions that exist. Easier to call than
|
||||
* add_permissions and then remove_permissions
|
||||
* @param array $data in the following format:
|
||||
* array(
|
||||
* file_id => array(
|
||||
* account_id => acl_rights,
|
||||
* account_id2 => acl_rights2,...
|
||||
* ),
|
||||
* file_id2 ... );
|
||||
*/
|
||||
function set_permissions($data)
|
||||
{
|
||||
//TODO see if a user have permissions in a file. Only if he have
|
||||
//(or if is inside his homedir) he can change permissions
|
||||
if (!$data || !is_array($data))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//search for permissions on files, to know which ones must be
|
||||
//updated/inserted
|
||||
reset($data);
|
||||
while(list($file_id,$account_ids) = each($data))
|
||||
{
|
||||
$file_ids[] = $file_id;
|
||||
}
|
||||
|
||||
$sql = 'SELECT * from phpgw_vfs2_shares
|
||||
WHERE file_id IN ('.implode(',',$file_ids).')';
|
||||
|
||||
$this->db->query($sql,__LINE__,__FILE__);
|
||||
|
||||
while ($this->db->next_record())
|
||||
{
|
||||
$current_shares[$this->db->Record['file_id']][$this->db->Record['account_id']] = $this->db->Record['acl_rights'];
|
||||
}
|
||||
|
||||
//now that we have the current permissions, must know which ones to
|
||||
//insert/update and which ones to delete
|
||||
reset($data);
|
||||
while(list($file_id,$account_ids) = each($data))
|
||||
{
|
||||
reset($account_ids);
|
||||
while(list($account_id,$acl_rights) = each($account_ids))
|
||||
{
|
||||
//exists
|
||||
if (array_key_exists($account_id,$current_shares[$file_id]))
|
||||
{
|
||||
if ($current_shares[$file_id][$account_id] != $acl_rights)
|
||||
{
|
||||
$insert[$file_id][$account_id] = $acl_rights;
|
||||
}
|
||||
|
||||
unset($current_shares[$file_id][$account_id]);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
$insert[$file_id][$account_id] = $acl_rights;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//get which ones to delete
|
||||
reset($current_shares);
|
||||
while(list($file_id,$account_ids) = each($current_shares))
|
||||
{
|
||||
if (is_array($account_ids))
|
||||
{
|
||||
reset($account_ids);
|
||||
while(list($account_id,$acl_rights) = each($account_ids))
|
||||
{
|
||||
$delete[$file_id][$account_id] = $acl_rights;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach($insert as $file_id => $account_ids)
|
||||
{
|
||||
$this->store_permissions($file_id,$account_ids);
|
||||
}
|
||||
|
||||
foreach($delete as $file_id => $account_ids)
|
||||
{
|
||||
$this->remove_permissions($file_id,$account_ids);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* function store_qpermissions
|
||||
* @description Add/update new permissions to a file id
|
||||
* @param account_ids: array('account_id'=> acl_rights,acc_id2=>acl_r2,)
|
||||
*/
|
||||
function store_permissions($file_id,$account_ids)
|
||||
{
|
||||
if (!is_array($account_ids) || !is_numeric($file_id))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach($account_ids as $account_id => $acl_rights)
|
||||
{
|
||||
$this->db->insert('phpgw_vfs2_shares',
|
||||
array('acl_rights'=>$acl_rights),
|
||||
array('account_id'=>$account_id,'file_id'=>$file_id),
|
||||
__LINE__,__FILE__);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* function remove_permissions
|
||||
* @description Remove some permissions of a file id
|
||||
*/
|
||||
function remove_permissions($file_id,$account_ids)
|
||||
{
|
||||
if (!is_array($account_ids) || !is_numeric($file_id))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach($account_ids as $account_id => $acl_rights)
|
||||
{
|
||||
$this->db->delete('phpgw_vfs2_shares',
|
||||
array('account_id'=>$account_id,'file_id'=>$file_id),
|
||||
__LINE__,__FILE__);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* function get_permissions
|
||||
* @description This function will get the permissions set for a given
|
||||
* file, makeing a simple query in the file repository. Does not
|
||||
* search for permissions in parent dirs. If you want to know which
|
||||
* is the permission for a user in a given file TAKING IN COUNT the
|
||||
* parent dirs, use $this->get_file_permissions instead.
|
||||
* @param int file_id The id of the file
|
||||
* @result array with account_id as index, acl_rights as value
|
||||
* @author Vinicius Cubas Brand
|
||||
*/
|
||||
function get_permissions($file_id)
|
||||
{
|
||||
$this->db->select('phpgw_vfs2_shares','acl_rights,account_id',
|
||||
array('file_id'=>$file_id),__LINE__,__FILE__);
|
||||
|
||||
$result = array();
|
||||
|
||||
while ($this->db->next_record())
|
||||
{
|
||||
$result[$this->db->Record['account_id']] = $this->db->Record['acl_rights'];
|
||||
}
|
||||
|
||||
return ($result);
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
* function get_shares
|
||||
* @description Get all shares in which the user have $permission
|
||||
* @param $account_id The id of the user that can read the shared folder
|
||||
* @param $is_owner If true, will get only the shared folders that
|
||||
* $account_id owns. Useful to get the shares that account_id owns
|
||||
* and have configured himself (true), or instead the shares of the
|
||||
* others that he have $permission (false)
|
||||
* @result array with the list of the file_id's of all shares
|
||||
*/
|
||||
function get_shares($account_id,$is_owner=false,$permission=PHPGW_ACL_READ)
|
||||
{
|
||||
if ($is_owner)
|
||||
{
|
||||
$sql = "SELECT DISTINCT sh.file_id as file_id,
|
||||
sh.acl_rights as acl_rights,
|
||||
fls.directory as directory,
|
||||
fls.name as name
|
||||
FROM phpgw_vfs2_shares sh,
|
||||
phpgw_vfs2_files fls
|
||||
WHERE sh.file_id = fls.file_id
|
||||
AND fls.shared = 'Y'
|
||||
AND fls.owner_id = $account_id";
|
||||
}
|
||||
else
|
||||
{
|
||||
//gets the id of all groups $account_id belongs to
|
||||
$groups = $GLOBALS['phpgw']->accounts->membership($account_id);
|
||||
|
||||
foreach($groups as $group)
|
||||
{
|
||||
$accounts[] = $group['account_id'];
|
||||
}
|
||||
|
||||
$accounts[] = $account_id;
|
||||
|
||||
$sql = "SELECT DISTINCT sh.file_id as file_id,
|
||||
sh.acl_rights as acl_rights,
|
||||
fls.directory as directory,
|
||||
fls.name as name
|
||||
FROM phpgw_vfs2_shares sh,
|
||||
phpgw_vfs2_files fls
|
||||
WHERE sh.file_id = fls.file_id
|
||||
AND sh.account_id IN (".implode(',',$accounts).")
|
||||
AND fls.shared = 'Y'
|
||||
AND fls.owner_id != $account_id";
|
||||
}
|
||||
|
||||
$this->db->query($sql,__LINE__,__FILE__);
|
||||
|
||||
$res = array();
|
||||
while($this->db->next_record())
|
||||
{
|
||||
if($this->db->Record['acl_rights'] & $permission)
|
||||
{
|
||||
$res[] = $this->db->Record;
|
||||
}
|
||||
}
|
||||
|
||||
//should be returned the array with complete file description
|
||||
return $res;
|
||||
}
|
||||
|
||||
/*!
|
||||
* function search_shares
|
||||
* @description Search for a shared folder which the user have
|
||||
* $permission and have $keyword related (in directory or filename)
|
||||
* @result array with the list of all shares
|
||||
*/
|
||||
//TODO search by file owner's name
|
||||
function search_shares($account_id,$keyword,$permission=PHPGW_ACL_READ)
|
||||
{
|
||||
if ($account_id != ((int)$account_id))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//gets the id of all groups $account_id belongs to
|
||||
$groups = $GLOBALS['phpgw']->accounts->membership($account_id);
|
||||
|
||||
foreach($groups as $group)
|
||||
{
|
||||
$accounts[] = $group['account_id'];
|
||||
}
|
||||
|
||||
$accounts[] = $account_id;
|
||||
|
||||
$sql = "SELECT DISTINCT sh.file_id as file_id,
|
||||
sh.acl_rights as acl_rights,
|
||||
fls.directory as directory,
|
||||
fls.name as name
|
||||
FROM phpgw_vfs2_shares sh,
|
||||
phpgw_vfs2_files fls
|
||||
WHERE sh.file_id = fls.file_id
|
||||
AND sh.account_id IN (".implode(',',$accounts).")
|
||||
AND ( fls.directory LIKE '%$keyword%'
|
||||
OR fls.name LIKE '%$keyword%')
|
||||
AND fls.shared = 'Y'
|
||||
AND fls.owner_id != $account_id";
|
||||
|
||||
$this->db->query($sql,__LINE__,__FILE__);
|
||||
|
||||
while($this->db->next_record())
|
||||
{
|
||||
if ($this->db->Record['acl_rights'] & $permission)
|
||||
{
|
||||
$res[] = $this->db->Record;
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/*!
|
||||
* function get_file_permissions
|
||||
* @description Get the permissions for a user in a given file
|
||||
* For files in a shared dir, will get the acl rights of the parent
|
||||
* dir, and if not specified, of the parent of the parent, and so on.
|
||||
* NOTE: this consider that files CANNOT have permissions set, only
|
||||
* their parent dir, and the file inherits the nearer parent with
|
||||
* permissions defined
|
||||
* @result int some mask of various PHPGW_ACL_*
|
||||
*/
|
||||
function get_file_permissions($account_id,$file_id)
|
||||
{
|
||||
//get directory/file names
|
||||
$this->db->select('phpgw_vfs2_files','directory,name',
|
||||
array('file_id' => $file_id),__LINE__,__FILE__);
|
||||
|
||||
$this->db->next_record();
|
||||
|
||||
$directory = $this->db->Record['directory'];
|
||||
$name = $this->db->Record['name'];
|
||||
|
||||
$fullname = $directory.'/'.$name;
|
||||
|
||||
$parent_dirs = array();
|
||||
|
||||
$dirs_expl = explode('/',$fullname);
|
||||
|
||||
//put all parents hierarchy in an array
|
||||
$parent_dirs_array[]=$fullname;
|
||||
while(1)
|
||||
{
|
||||
array_pop($dirs_expl);
|
||||
if($dirs_expl[1])
|
||||
{
|
||||
$parent_dirs_array[]=implode('/',$dirs_expl);
|
||||
}
|
||||
else
|
||||
{
|
||||
$parent_dirs_array[]='/';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//gets the id of all groups $account_id belongs to
|
||||
$groups = $GLOBALS['phpgw']->accounts->membership($account_id);
|
||||
|
||||
foreach($groups as $group)
|
||||
{
|
||||
$accounts[] = $group['account_id'];
|
||||
}
|
||||
|
||||
$accounts[] = $account_id;
|
||||
|
||||
$accounts = implode(',',$accounts);
|
||||
|
||||
|
||||
//searches for information in the parent dirs
|
||||
for($i=0; $i<count($parent_dirs_array);$i++)
|
||||
{
|
||||
$dir_name = array_pop(explode('/',$parent_dirs_array[$i]));
|
||||
if ($dir_name)
|
||||
{
|
||||
$sql = "SELECT sh.acl_rights as acl_rights,
|
||||
fls.directory as directory,
|
||||
fls.name as name,
|
||||
fls.owner_id as owner_id
|
||||
FROM phpgw_vfs2_shares sh,
|
||||
phpgw_vfs2_files fls
|
||||
WHERE sh.file_id = fls.file_id
|
||||
AND (sh.account_id IN ($accounts)
|
||||
OR fls.owner_id = $account_id)
|
||||
AND fls.directory = '".$parent_dirs_array[$i+1]."'
|
||||
AND fls.name = '".$dir_name."'";
|
||||
|
||||
$this->db->query($sql,__LINE__,__FILE__);
|
||||
|
||||
/*
|
||||
$this->db->select('phpgw_vfs2_files','file_id',
|
||||
array('directory'=>$parent_dirs_array[$i+1],
|
||||
'name'=>$dir_name), __LINE__,__FILE__);
|
||||
|
||||
$this->db->next_record();
|
||||
|
||||
$this->db->select('phpgw_vfs2_shares','acl_rights',
|
||||
array('file_id'=>$this->db->Record['file_id'],
|
||||
'account_id'=>$account_id),__LINE__,__FILE__);*/
|
||||
|
||||
while ($this->db->next_record())
|
||||
{
|
||||
if ($this->db->Record['owner_id'] == $account_id)
|
||||
{
|
||||
//the user can do anything with any dir or file
|
||||
//inside a dir that belongs to him.
|
||||
return PHPGW_ACL_READ|PHPGW_ACL_EDIT|PHPGW_ACL_ADD;
|
||||
}
|
||||
else
|
||||
{
|
||||
$entered = true;
|
||||
$result |= $this->db->Record['acl_rights'];
|
||||
}
|
||||
}
|
||||
if($entered)
|
||||
{
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
4046
phpgwapi/inc/class.vfs_sql2.inc.php
Normal file
4046
phpgwapi/inc/class.vfs_sql2.inc.php
Normal file
File diff suppressed because it is too large
Load Diff
674
phpgwapi/inc/class.vfs_versionsystem.inc.php
Normal file
674
phpgwapi/inc/class.vfs_versionsystem.inc.php
Normal file
@ -0,0 +1,674 @@
|
||||
<?php
|
||||
/***************************************************************************\
|
||||
* eGroupWare - File Manager *
|
||||
* http://www.egroupware.org *
|
||||
* Written by: *
|
||||
* - Vinicius Cubas Brand <viniciuscb@users.sourceforge.net> *
|
||||
* sponsored by Thyamad - http://www.thyamad.com *
|
||||
* ------------------------------------------------------------------------- *
|
||||
* Description: File version class handler for VFS (SQL implementation v2) *
|
||||
* ------------------------------------------------------------------------- *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
* option) any later version. *
|
||||
\***************************************************************************/
|
||||
|
||||
class vfs_versionsystem
|
||||
{
|
||||
|
||||
/* The high level database handler object */
|
||||
// var $db_highlevel;
|
||||
|
||||
/* Stores the possible amount number of old file backups; In an
|
||||
* inserction, this number will be verified and if there are already
|
||||
* $backups backed up for a file, will delete backup of the oldest
|
||||
* (although keeping the record of operations). 0 for no backup system
|
||||
* and -1 to infinite versions. */
|
||||
var $backups;
|
||||
|
||||
/* tmp dir (without end slash) to store temporary file backups (when
|
||||
* file is snapshotted) */
|
||||
var $tmp_dir;
|
||||
|
||||
/* Virtual file system base class */
|
||||
var $vfs;
|
||||
|
||||
/* Stores information about snapshotted files. Array with the file_id
|
||||
as index. */
|
||||
var $snapshotted_files;
|
||||
|
||||
/* Database handling */
|
||||
var $db;
|
||||
|
||||
/* Now */
|
||||
var $now;
|
||||
|
||||
var $account_id;
|
||||
|
||||
var $last_saved_snapshot=-1;
|
||||
|
||||
var $backup_foldername = '_backup';
|
||||
|
||||
//Operations that create file backups
|
||||
var $backup_operations = array(
|
||||
VFS_OPERATION_EDITED
|
||||
);
|
||||
|
||||
var $attributes = array(
|
||||
'version_id', /* Integer. Unique to each modification. */
|
||||
'file_id', /* Integer. Id of the file that modif. belongs.*/
|
||||
'operation', /* Operation made in modification. */
|
||||
'modifiedby_id', /* phpGW account_id of who last modified */
|
||||
'modified', /* Datetime of modification, in SQL format */
|
||||
'version', /* Version of file prior modification. */
|
||||
'comment', /* Human-readable description of modification. */
|
||||
'backup_file_id', /* file_id of file that is a backup . */
|
||||
'backup_content', /* usable if files are stored in database. */
|
||||
'src', /* source directory in a copy or move operation.*/
|
||||
'dest' /* destination directory in a copy or move operation.*/
|
||||
);
|
||||
|
||||
/*!
|
||||
* @function vfs_versionsystem
|
||||
* @abstract Object constructor
|
||||
* @author Vinicius Cubas Brand
|
||||
*/
|
||||
function vfs_versionsystem($create_vfs=true)
|
||||
{
|
||||
//use create_vfs=false and after this use $this->set_vfs to keep the
|
||||
// same object (i.e. use reference) in $this->vfs instead of
|
||||
// creating a new object.
|
||||
if ($create_vfs)
|
||||
{
|
||||
$this->vfs = CreateObject('phpgwapi.vfs');
|
||||
}
|
||||
|
||||
/* FIXME this takes a value defined in the filescenter
|
||||
* configuration. Better next time to take a value from global api
|
||||
* configuration. must fix here and in the filescenter */
|
||||
if (array_key_exists('filescenter',$GLOBALS['phpgw_info']['user']['preferences']))
|
||||
{
|
||||
$this->backups = $GLOBALS['phpgw_info']['user']['preferences']['filescenter']['vfs_backups'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->backups = 5;
|
||||
}
|
||||
|
||||
$this->snapshotted_files = array();
|
||||
$this->db =& $GLOBALS['phpgw']->db;
|
||||
$this->now = date('Y-m-d H:i:s');
|
||||
$this->account_id = $GLOBALS['phpgw_info']['user']['account_id'];
|
||||
$this->tmp_dir = $GLOBALS['phpgw_info']['server']['temp_dir'];
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
* @function create_initial_version()
|
||||
* @abstract Creates a initial journal entry for a file
|
||||
* @description Must be used after a file has been created. Will create
|
||||
* an initial journal entry in the database. If somehow
|
||||
* the database already have any journal for that file,
|
||||
* this method is wrongly called and will do nothing.
|
||||
* Also if no file is found with that file_id, fails.
|
||||
*
|
||||
* @author Vinicius Cubas Brand
|
||||
*/
|
||||
function create_initial_version($file_id)
|
||||
{
|
||||
if ($GLOBALS['phpgw']->banish_journal)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$GLOBALS['phpgw']->banish_journal = true;
|
||||
|
||||
//See if file exists
|
||||
$this->db->select('phpgw_vfs2_files','*',
|
||||
array('file_id'=>$file_id), __LINE__,__FILE__);
|
||||
|
||||
if (!$this->db->next_record())
|
||||
{
|
||||
$GLOBALS['phpgw']->banish_journal = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
$file_record = $this->db->Record;
|
||||
|
||||
//See if journal for the file already exists
|
||||
$this->db->select('phpgw_vfs2_versioning','*',
|
||||
array('file_id'=>$file_id),__LINE__,__FILE__);
|
||||
|
||||
if ($this->db->next_record())
|
||||
{
|
||||
$GLOBALS['phpgw']->banish_journal = false;
|
||||
return true; //TODO error message
|
||||
}
|
||||
|
||||
$insert_data = array(
|
||||
'file_id' => $file_record['file_id'],
|
||||
'operation' => VFS_OPERATION_CREATED,
|
||||
'modified' => $this->now,
|
||||
'modifiedby_id' => $this->account_id,
|
||||
'version' => '0.0.0.0'
|
||||
);
|
||||
|
||||
$res = $this->db->insert('phpgw_vfs2_versioning',$insert_data,null,
|
||||
__LINE__,__FILE__);
|
||||
|
||||
|
||||
|
||||
if ($res)
|
||||
{
|
||||
$GLOBALS['phpgw']->banish_journal = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
$GLOBALS['phpgw']->banish_journal = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @function save_snapshot()
|
||||
* @abstract Saves a snapshot from a file
|
||||
* @description Must be called before any modification in a file. After
|
||||
* the modification was successful, one must do a vfs_version->commit()
|
||||
* Depending of the type of operation and how backups are set, will
|
||||
* handle backups. If a commit is not made until the end of the script,
|
||||
* no modifications in the journal will be saved.
|
||||
*
|
||||
* @param $file_id int The file_id
|
||||
* @param $operation int A VFS_OPERATION as defined in vfs_shared file
|
||||
* @param $other string Its use will differ depending on the operation:
|
||||
* Copy,Move: $other contains the fake_full_path_clean of destination
|
||||
*
|
||||
* @author Vinicius Cubas Brand
|
||||
* @result bool
|
||||
*/
|
||||
function save_snapshot($file_id,$operation,$comment='',$other='')
|
||||
{
|
||||
|
||||
//Prevent recursive reentrant when working in vfs->copy, f.inst
|
||||
if ($GLOBALS['phpgw']->banish_journal)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$GLOBALS['phpgw']->banish_journal = true;
|
||||
|
||||
$this->db->select('phpgw_vfs2_files','*',
|
||||
array('file_id'=>$file_id), __LINE__,__FILE__);
|
||||
|
||||
if (!$this->db->next_record())
|
||||
{
|
||||
|
||||
$GLOBALS['phpgw']->banish_journal = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
$file_record = $this->db->Record;
|
||||
|
||||
//If already snapshotted, will do a rollback in the old snapshot
|
||||
//before make a new one.
|
||||
if ($this->snapshotted_files[$file_record['file_id']])
|
||||
{
|
||||
$this->rollback($file_record['file_id']);
|
||||
}
|
||||
|
||||
//Create a backup if necessary
|
||||
if ($this->backups != 0 && in_array($operation,$this->backup_operations))
|
||||
{
|
||||
$random_filename = $this->tmp_dir.SEP.$this->random_filename();
|
||||
|
||||
$this->vfs->cp(array(
|
||||
'from' => $file_record['directory'].SEP.$file_record['name'],
|
||||
'to' => $random_filename,
|
||||
'relatives' => array(RELATIVE_ROOT,RELATIVE_NONE|VFS_REAL)
|
||||
));
|
||||
|
||||
$this->vfs->set_attributes(array(
|
||||
'string' => $random_filename,
|
||||
'relatives' => array(RELATIVE_NONE|VFS_REAL),
|
||||
'attributes' => array('is_backup' => 'Y')
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
//backup_file_id and backup_data will be set in commit() only.
|
||||
$insert_data = array(
|
||||
'file_id' => $file_record['file_id'],
|
||||
'operation' => $operation,
|
||||
'modifiedby_id' => $this->account_id,
|
||||
'modified' => $this->now, //Datetime of entry
|
||||
'version' => $file_record['version'],
|
||||
'comment' => $comment,
|
||||
);
|
||||
|
||||
if ($operation == VFS_OPERATION_COPIED || $operation == VFS_OPERATION_MOVED)
|
||||
{
|
||||
$insert_data['src'] = $file_record['directory'].'/'.$file_record['name'];
|
||||
$insert_data['dest'] = $other['dest'];
|
||||
|
||||
}
|
||||
|
||||
/* $file_data is the information of the file, stored in
|
||||
* $this->snapshotted_files. 'insert_data' have the data to be
|
||||
* inserted in the versioning table, 'tmp_filename' is the name of
|
||||
* the temporary backup copy, if any, and 'record' is the
|
||||
* information of the file before changes (that will be made between
|
||||
* the call to save_snapshot() and the call to commit().
|
||||
*/
|
||||
$file_data = array(
|
||||
'insert_data' => $insert_data,
|
||||
'tmp_filename' => $random_filename,
|
||||
'record' => $file_record
|
||||
);
|
||||
|
||||
$this->snapshotted_files[$file_id] = $file_data;
|
||||
$this->last_saved_snapshot = $file_id;
|
||||
|
||||
$GLOBALS['phpgw']->banish_journal = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @function commit()
|
||||
* @abstract Commits the creation of a journal entry
|
||||
* @description Will have to be called after a save_snapshot is made.
|
||||
* If a vfs_version->save_snapshot() call is not made before, this
|
||||
* method does nothing. If no parameter is passed, will commit the
|
||||
* file from the last saved snapshot.
|
||||
*
|
||||
* @param $file_id int The file_id
|
||||
*
|
||||
* @author Vinicius Cubas Brand
|
||||
* @result bool
|
||||
*/
|
||||
function commit($file_id=-1)
|
||||
{
|
||||
//Prevent recursive reentrant when working in vfs->copy, f.inst
|
||||
if ($GLOBALS['phpgw']->banish_journal)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$GLOBALS['phpgw']->banish_journal = true;
|
||||
|
||||
if ($file_id == -1)
|
||||
{
|
||||
if ($this->last_saved_snapshot == -1)
|
||||
{
|
||||
|
||||
$GLOBALS['phpgw']->banish_journal = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
$file_id = $this->last_saved_snapshot;
|
||||
}
|
||||
|
||||
if (!$this->snapshotted_files[$file_id])
|
||||
{
|
||||
|
||||
$GLOBALS['phpgw']->banish_journal = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
$file_data = $this->snapshotted_files[$file_id];
|
||||
|
||||
//if there is any backup to be made, will make these backups and
|
||||
//remove too old backup versions, as defined in configuration.
|
||||
if ($this->backups != 0 && in_array($file_data['insert_data']['operation'],$this->backup_operations))
|
||||
{
|
||||
|
||||
//counts the number of stored backups
|
||||
$where = "file_id=$file_id AND (backup_file_id != NULL OR backup_file_id != '')";
|
||||
|
||||
$this->db->select('phpgw_vfs2_versioning','count(*)',$where,
|
||||
__LINE__,__FILE__);
|
||||
|
||||
$this->db->next_record();
|
||||
|
||||
if ($this->db->Record[0] >= $this->backups && $this->backups != -1)
|
||||
{
|
||||
//Remove old backups
|
||||
|
||||
//Deletes oldest backup(s)
|
||||
$backups_to_be_deleted = $this->db->Record[0] - $this->backups + 1;
|
||||
|
||||
$sql = "SELECT vers.version_id as version_id,
|
||||
vers.backup_file_id as backup_file_id,
|
||||
files.directory as directory,
|
||||
files.name as name
|
||||
FROM phpgw_vfs2_versioning vers,
|
||||
phpgw_vfs2_files files
|
||||
WHERE vers.file_id=$file_id
|
||||
AND vers.backup_file_id = files.file_id
|
||||
ORDER BY vers.modified";
|
||||
|
||||
$this->db->query($sql,__LINE__,__FILE__);
|
||||
|
||||
for ($i = 0; $i < $backups_to_be_deleted; $i++)
|
||||
{
|
||||
//FIXME don't know why this only works 4 the 1st cycle
|
||||
$this->db->next_record();
|
||||
|
||||
$version_file_id = $this->db->Record['backup_file_id'];
|
||||
$version_id = $this->db->Record['version_id'];
|
||||
|
||||
|
||||
$version_directory = $this->db->Record['directory'];
|
||||
$version_name = $this->db->Record['name'];
|
||||
|
||||
//Removes old backup
|
||||
$this->vfs->rm(array(
|
||||
'string' => $version_directory.SEP.$version_name,
|
||||
'relatives' => array(RELATIVE_ROOT)
|
||||
));
|
||||
|
||||
$versions_to_update[] = $version_id;
|
||||
|
||||
}
|
||||
|
||||
if ($versions_to_update)
|
||||
{
|
||||
//updates old journal
|
||||
$update_data = array(
|
||||
'backup_file_id' => '',
|
||||
'backup_content' => ''
|
||||
);
|
||||
|
||||
foreach ($versions_to_update as $key => $val)
|
||||
{
|
||||
|
||||
$update_where = array(
|
||||
'version_id' => $val
|
||||
);
|
||||
|
||||
$this->db->update('phpgw_vfs2_versioning',
|
||||
$update_data,$update_where,__LINE__,__FILE__);
|
||||
}
|
||||
|
||||
}
|
||||
unset($version_id);
|
||||
}
|
||||
|
||||
//create backup folder, if not exists
|
||||
//Important: the backup dir will be inside the virtual root
|
||||
$backup_foldername = $file_data['record']['directory'].SEP.$this->backup_foldername;
|
||||
|
||||
$dir = array(
|
||||
'string' => $backup_foldername,
|
||||
'relatives' => array(RELATIVE_ROOT)
|
||||
);
|
||||
|
||||
if (!$this->vfs->file_exists($dir))
|
||||
{
|
||||
$this->vfs->mkdir($dir); //TODO error messages
|
||||
|
||||
$attributes=array_merge($dir,array(
|
||||
'attributes' => array(
|
||||
'is_backup' => 'Y'
|
||||
)
|
||||
));
|
||||
|
||||
$this->vfs->set_attributes($attributes);
|
||||
}
|
||||
|
||||
//create a backup filename
|
||||
$backup_filename = $this->backup_filename(
|
||||
$file_data['record']['name'],
|
||||
$file_data['insert_data']['version']
|
||||
);
|
||||
|
||||
//move file from temporary location to its definitive location
|
||||
$res = $this->vfs->mv(array(
|
||||
'from' => $file_data['tmp_filename'],
|
||||
'to' => $backup_foldername.SEP.$backup_filename,
|
||||
'relatives' => array(RELATIVE_NONE|VFS_REAL,RELATIVE_ROOT)
|
||||
));
|
||||
|
||||
//sets its attribute as backup
|
||||
$this->vfs->set_attributes(array(
|
||||
'string' => $backup_foldername.SEP.$backup_filename,
|
||||
'relatives' => array(RELATIVE_ROOT),
|
||||
'attributes' => array('is_backup' => 'Y')
|
||||
));
|
||||
|
||||
//TODO backup content in database support
|
||||
|
||||
//Fetch the backup file_id to put this information in the
|
||||
//version table
|
||||
if ($res)
|
||||
{
|
||||
$res_ls = $this->vfs->ls(array(
|
||||
'string' => $backup_foldername.SEP.$backup_filename,
|
||||
'relatives' => RELATIVE_ROOT,
|
||||
'nofiles' => True,
|
||||
'backups' => True
|
||||
));
|
||||
|
||||
if ($res_ls)
|
||||
{
|
||||
$file_data['insert_data']['backup_file_id'] = $res_ls[0]['file_id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$res = $this->db->insert('phpgw_vfs2_versioning',
|
||||
$file_data['insert_data'],null,__LINE__,__FILE__);
|
||||
|
||||
|
||||
|
||||
if ($res)
|
||||
{
|
||||
//If operation is one of the type that increments file version
|
||||
if (in_array($file_data['insert_data']['operation'],$this->backup_operations))
|
||||
{
|
||||
|
||||
$this->db->update('phpgw_vfs2_files',
|
||||
array('version' => $this->inc($file_data['insert_data']['version'])),
|
||||
array('file_id' => $file_data['insert_data']['file_id']),
|
||||
__LINE__, __FILE__
|
||||
);
|
||||
}
|
||||
|
||||
unset($this->snapshotted_files[$file_id]);
|
||||
$this->last_saved_snapshot = -1;
|
||||
|
||||
$GLOBALS['phpgw']->banish_journal = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
$GLOBALS['phpgw']->banish_journal = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* @function rollback()
|
||||
* @abstract Rollbacks the save of the snapshot
|
||||
* @description Will have to be called after a save_snapshot is made.
|
||||
* If a vfs_version->save_snapshot() call is not made before, this
|
||||
* method does nothing. If no parameter is passed, will rollback the
|
||||
* file from the last saved snapshot. This method only deletes the
|
||||
* temporary backup file and the saved file information
|
||||
*
|
||||
* @param $file_id int The file_id
|
||||
*
|
||||
* @author Vinicius Cubas Brand
|
||||
* @result bool
|
||||
*/
|
||||
function rollback($file_id=-1)
|
||||
{
|
||||
//Prevent recursive reentrant when working in vfs->copy, f.inst
|
||||
if ($GLOBALS['phpgw']->banish_journal)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$GLOBALS['phpgw']->banish_journal = true;
|
||||
|
||||
if ($file_id == -1)
|
||||
{
|
||||
if ($this->last_saved_snapshot == -1)
|
||||
{
|
||||
|
||||
$GLOBALS['phpgw']->banish_journal = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
$file_id = $this->last_saved_snapshot;
|
||||
}
|
||||
|
||||
if (!$this->snapshotted_files[$file_id])
|
||||
{
|
||||
|
||||
$GLOBALS['phpgw']->banish_journal = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
$file_data = $this->snapshotted_files[$file_id];
|
||||
|
||||
$this->vfs->rm(array(
|
||||
'string' => $file_data['tmp_filename'],
|
||||
'relatives' => array(RELATIVE_NONE | VFS_REAL)
|
||||
));
|
||||
|
||||
unset($this->snapshotted_files[$file_id]);
|
||||
$this->last_saved_snapshot = -1;
|
||||
|
||||
$GLOBALS['phpgw']->banish_journal = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @function get_journal()
|
||||
* @abstract Returns an array with the journal for a file
|
||||
*/
|
||||
function get_journal($file_id)
|
||||
{
|
||||
//TODO support for database-only storage.
|
||||
$fields = array_diff($this->attributes,array('backup_content'));
|
||||
|
||||
$where = 'file_id='.$file_id.' ORDER BY modified DESC, version DESC, operation DESC';
|
||||
|
||||
|
||||
$this->db->select('phpgw_vfs2_versioning',$fields,$where,
|
||||
__LINE__,__FILE__);
|
||||
|
||||
while ($this->db->next_record())
|
||||
{
|
||||
$result[] = $this->db->Record;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* @function inc()
|
||||
* @abstract Given a file version, increments it using the vfs
|
||||
* versioning pattern and returns the incremented file version.
|
||||
* Analyzes operation and increments the file version taking
|
||||
* consideration of this operation.
|
||||
*
|
||||
* @param $version string The file version
|
||||
* @param $operation int Some VFS_OPERATION as defined in vfs_shared
|
||||
*
|
||||
* @result string
|
||||
*/
|
||||
function inc($version)
|
||||
{
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
$version_parts = split ("\.", $version);
|
||||
$newnumofparts = $numofparts = count ($version_parts);
|
||||
|
||||
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]++;
|
||||
}
|
||||
|
||||
if ($version_parts[2] >= 9 && $version_parts[3] == 0 && $version_parts_3_update)
|
||||
{
|
||||
$version_parts[2] = 0;
|
||||
$version_parts[1]++;
|
||||
}
|
||||
|
||||
if ($version_parts[1] > 99)
|
||||
{
|
||||
$version_parts[1] = 0;
|
||||
$version_parts[0]++;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $newnumofparts; $i++)
|
||||
{
|
||||
if (!isset ($version_parts[$i]))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if ($i)
|
||||
{
|
||||
$newversion .= '.';
|
||||
}
|
||||
|
||||
$newversion .= $version_parts[$i];
|
||||
}
|
||||
|
||||
return $newversion;
|
||||
}
|
||||
|
||||
function set_vfs(&$vfs)
|
||||
{
|
||||
$this->vfs =& $vfs;
|
||||
}
|
||||
|
||||
#helper, private functions
|
||||
|
||||
/*!
|
||||
* @function random_filename()
|
||||
* @abstract Generates a Random Filename
|
||||
*
|
||||
* @result string
|
||||
*/
|
||||
function random_filename()
|
||||
{
|
||||
$filename = '';
|
||||
$filename_length = 8;
|
||||
while (strlen($filename) < $filename_length) {
|
||||
$filename .= chr(rand (97,122));
|
||||
}
|
||||
|
||||
return $filename.'.tmp';
|
||||
}
|
||||
|
||||
/*!
|
||||
* @function backup_filename()
|
||||
* @abstract Return the backup filename for a certain filename + version
|
||||
*
|
||||
* @result string
|
||||
*/
|
||||
function backup_filename($filename,$version)
|
||||
{
|
||||
$version = str_replace('.','_',$version);
|
||||
$fbrk = explode('.',$filename);
|
||||
$fbrk[0] .= '-'.$version;
|
||||
return implode('.',$fbrk);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
Loading…
Reference in New Issue
Block a user