egroupware/phpgwapi/doc/vfs/vfs.lyx

1119 lines
24 KiB
Plaintext

#LyX 1.1 created this file. For more info see http://www.lyx.org/
\lyxformat 218
\textclass linuxdoc
\language english
\inputencoding latin1
\fontscheme default
\graphics default
\paperfontsize default
\spacing single
\papersize Default
\paperpackage a4
\use_geometry 0
\use_amsmath 0
\paperorientation portrait
\secnumdepth 5
\tocdepth 5
\paragraph_separation indent
\defskip medskip
\quotes_language english
\quotes_times 2
\papercolumns 1
\papersides 1
\paperpagestyle default
\layout Title
\added_space_top vfill \added_space_bottom vfill
phpgwapi - VFS Class
\layout Author
Jason Wies
\layout Date
June 2001, February 2002
\layout Abstract
The VFS, or Virtual File System, handles all file system activity for phpGroupWa
re.
\layout Section
Introduction and Purpose
\begin_inset LatexCommand \label{sec:introduction}
\end_inset
\layout Standard
The latest version of the VFS for phpGroupWare combines actual file system
manipulation with fully integrated database support.
It features nearly transparent handling of files and directories, as well
as files inside and outside the virtual root.
This document is intended to provide API and application developers with
a guide to incorporating the VFS into their work.
\layout Section
Basics
\begin_inset LatexCommand \label{sec:basics}
\end_inset
\layout Subsection
Prerequisites
\begin_inset LatexCommand \label{sec:prerequisites}
\end_inset
\layout Standard
You must explicitly enable the VFS class.
To do this, set 'enable_vfs_class' to True in $GLOBALS['phpgw_info']['flags'].
An example:
\layout Verbatim
$GLOBALS['phpgw_info']['flags'] = array(
\layout Verbatim
'currentapp' => 'phpwebhosting',
\layout Verbatim
'noheader' => False,
\layout Verbatim
'noappheader' => False,
\layout Verbatim
'enable_vfs_class' => True,
\layout Verbatim
'enable_browser_class' => True
\layout Verbatim
);
\layout Subsection
Concepts
\begin_inset LatexCommand \label{sec:concepts}
\end_inset
\layout Standard
The VFS in located in phpgwapi/inc/class.vfs_sql.inc.php.
You can look over it, but I don't suggest trying to understand how it works.
It isn't necessary to know its internals to use it, but you may find the
inline comments helpful.
The basic things to keep in mind:
\layout Itemize
Files and directories are synonymous in almost all cases
\layout Verbatim
$GLOBALS['phpgw']->vfs->mv (array(
\layout Verbatim
'from' => 'file1',
\layout Verbatim
'to' => 'dir/file2'
\layout Verbatim
));
\layout Verbatim
\layout Verbatim
$GLOBALS['phpgw']->vfs->mv (array(
\layout Verbatim
'from' => 'dir1',
\layout Verbatim
'to' => 'dir/dir1'
\layout Verbatim
));
\layout Verbatim
\layout Verbatim
$GLOBALS['phpgw']->vfs->rm (array(
\layout Verbatim
'string' => 'file'
\layout Verbatim
));
\layout Verbatim
\layout Verbatim
$GLOBALS['phpgw']->vfs->rm (array(
\layout Verbatim
'string' => 'dir'
\layout Verbatim
));
\layout Standard
All work as you would except them to.
The major exception is:
\layout Verbatim
$GLOBALS['phpgw']->vfs->touch (array(
\layout Verbatim
'string' => 'file'
\layout Verbatim
));
\layout Standard
vs.
\layout Verbatim
$GLOBALS['phpgw']->vfs->mkdir (array(
\layout Verbatim
'string' => 'dir'
\layout Verbatim
));
\layout Verbatim
\layout Itemize
Users and groups are synonymous
\layout Standard
As far as the actual paths are concerned, users and groups are the same.
/home/username works the same as /home/groupname.
\layout Itemize
You should never have to know the real paths of files
\layout Standard
One of the VFS's responsibilities is to translate paths for you.
While you certainly
\emph on
can
\emph default
operate using full paths, it is much simpler to use the virtual paths.
For example, instead of using:
\layout Verbatim
$GLOBALS['phpgw']->vfs->cp (array(
\layout Verbatim
'from' => '/var/www/phpgroupware/files/home/user/file1',
\layout Verbatim
'to' => '/var/www/phpgroupware/files/home/user/file2',
\layout Verbatim
'relatives' => array(
\layout Verbatim
RELATIVE_NONE|VFS_REAL,
\layout Verbatim
RELATIVE_NONE|VFS_REAL
\layout Verbatim
)
\layout Verbatim
));
\layout Standard
you might use
\layout Verbatim
$GLOBALS['phpgw']->vfs->cp (array(
\layout Verbatim
'from' => '/home/user/file1',
\layout Verbatim
'to' => '/home/user/file2',
\layout Verbatim
'relatives' => array(
\layout Verbatim
RELATIVE_NONE,
\layout Verbatim
RELATIVE_NONE
\layout Verbatim
)
\layout Verbatim
));
\layout Standard
(We'll get to the RELATIVE's in a minute.)
\layout Standard
Site administrators should be able to move their files dir around on their
system and know that everything will continue to work smoothly.
\layout Itemize
Relativity is
\emph on
vital
\layout Standard
Relativity is a new feature in the VFS, and its importance cannot be stressed
enough.
It will make your life much easier, especially for file system intensive
applications, but it will take some getting used to.
If something doesn't work right the first time, chances are great it has
to do with incorrect relativity settings.
We will deal with relativity in depth in the Relativity section.
\layout Section
Basic Functions
\begin_inset LatexCommand \label{sec:basic_functions}
\end_inset
\layout Standard
These are two functions you'll need to know before we get into relativity.
\layout Subsection
path_parts ()
\begin_inset LatexCommand \label{sec:path_parts}
\end_inset
\layout Standard
The job of path_parts () is to translate any given file location into its
many component parts for any relativity.
The values passed to path_parts () are:
\layout Verbatim
string
\layout Verbatim
relatives
\layout Verbatim
object
\layout Standard
'string' is the path you want to translate, 'relatives' is the standard
relativity array, and 'object' specifies how you would like the return
value: if 'object' is True, an object will be returned; if 'object' is
False, an array will be returned.
I think you'll find the object easier to deal with, and we'll be using
it throughout this document.
The most important returned values (but not all) for path_parts () are:
\layout Verbatim
fake_full_path
\layout Verbatim
fake_leading_dirs
\layout Verbatim
fake_extra_path
\layout Verbatim
fake_name
\layout Verbatim
real_full_path
\layout Verbatim
real_leading_dirs
\layout Verbatim
real_extra_path
\layout Verbatim
real_name
\layout Standard
Just like you would think, fake_full_path contains the full virtual path
of 'string', and real_full_path contains the full real path of 'string'.
The fake_name and real_name variables should always be the same, and contain
the final file or directory name.
The leading_dirs contain everything except the name, and the extra_path
is everything from the / before
\begin_inset Quotes eld
\end_inset
home
\begin_inset Quotes erd
\end_inset
to the end of the leading_dirs.
To better illustrate, here is an example:
\layout Verbatim
$p = $GLOBALS['phpgw']->vfs->path_parts (array(
\layout Verbatim
'string' => '/home/jason/dir/file',
\layout Verbatim
'relatives' => array(
\layout Verbatim
RELATIVE_NONE
\layout Verbatim
)
\layout Verbatim
));
\layout Itemize
$p->fake_full_path - /home/jason/dir/file
\layout Itemize
$p->fake_leading_dirs - /home/jason/dir
\layout Itemize
$p->fake_extra_path - home/jason/dir
\layout Itemize
$p->fake_name - file
\layout Itemize
$p->real_full_path - /var/www/phpgroupware/files/home/jason/dir/file
\layout Itemize
$p->real_leading_dirs - /var/www/phpgroupware/files/home/jason/dir
\layout Itemize
$p->real_extra_path - home/jason/dir
\layout Itemize
$p->real_name - file
\layout Standard
As you can see, path_parts () is a very useful function and will save you
from doing those darn substr ()'s yourself.
For those of you used to the prior VFS, note that
\emph on
getabsolutepath () is depreciated
\emph default
.
getabsolutepath () still exists (albeit in a much different form), and
is responsible for some of the path translation, but it is an
\emph on
internal
\emph default
function only.
Applications should only use path_parts ().
We have shown you how to use path_parts () so you can experiment with it
using different paths and relativities as we explore relativity.
\layout Subsection
cd ()
\begin_inset LatexCommand \label{sec:cd}
\end_inset
\layout Standard
Part of the overall goal for the VFS in phpGroupWare is to give the user
a seamless experience during their session.
For example, if they upload a file using a file manager to the directory
/home/my_group/project1, and then go to download an email attachment, the
default directory will be /home/my_group/project1.
This is accomplished using the cd () function.
Examples:
\layout Verbatim
/* cd to their home directory */
\layout Verbatim
$GLOBALS['phpgw']->vfs->cd (array(
\layout Verbatim
'string' => '/'
\layout Verbatim
));
\layout Verbatim
\layout Verbatim
/* cd to /home/jason/dir */
\layout Verbatim
$GLOBALS['phpgw']->vfs->cd (array(
\layout Verbatim
'string' => '/home/jason/dir',
\layout Verbatim
'relative' => False,
\layout Verbatim
'relatives' => array(
\layout Verbatim
RELATIVE_NONE
\layout Verbatim
)
\layout Verbatim
));
\layout Verbatim
\layout Verbatim
/* When following the above, cd's to /home/jason/dir/dir2 */
\layout Verbatim
$GLOBALS['phpgw']->vfs->cd (array(
\layout Verbatim
'string' => 'dir2',
\layout Verbatim
'relative' => True
\layout Verbatim
));
\layout Standard
If 'relative' is True, the 'string' is simply appended to the current path.
If you want to know what the current path is, use $GLOBALS['phpgw']->vfs->pwd
().
\layout Standard
Now you're ready for relativity.
\layout Section
Relativity
\begin_inset LatexCommand \label{sec:relativity}
\end_inset
\layout Standard
Ok, just one last thing before we get into relativity.
You will notice throughout the examples the use of $fakebase.
$GLOBALS['phpgw']->vfs->fakebase is by default '/home'.
The old VFS was hard-coded to use '/home', but the naming choice for this
is now up to administrators.
See the
\begin_inset LatexCommand \ref[Fakebase directory (changing /home)]{sec:fakebase}
\end_inset
section for more information.
Throughout the rest of this document, you will see $fakebase used in calls
to the VFS, and /home used in actual paths.
\emph on
You should always use $fakebase when making applications.
\emph default
I suggest doing $fakebase = $GLOBALS['phpgw']->vfs->fakebase; right off
the bat to keep things neater.
\layout Subsection
What is it and how does it work?
\layout Standard
One of the design challenges for a Virtual File System is to try to figure
out whether the calling application is referring to a file inside or outside
the virtual root, and if inside, exactly where.
To solve this problem, the phpGroupWare VFS uses RELATIVE defines that
are used in bitmasks passed to each function.
The result is that any set of different relativities can be used in combination
with each other.
Let's look at a few examples.
Say you want to move 'logo.png' from the user's home directory to the current
directory.
\layout Verbatim
$GLOBALS['phpgw']->vfs->mv (array(
\layout Verbatim
'from' => 'logo.png',
\layout Verbatim
'to' => 'logo.png',
\layout Verbatim
'relatives' => array(
\layout Verbatim
RELATIVE_USER,
\layout Verbatim
RELATIVE_ALL
\layout Verbatim
)
\layout Verbatim
));
\layout Standard
RELATIVE_USER means relative to the user's home directory.
RELATIVE_ALL means relative to the current directory, as set by cd () and
as reported by pwd ().
So if the current directory was
\begin_inset Quotes eld
\end_inset
$fakebase/my_group/project1
\begin_inset Quotes erd
\end_inset
, the call to mv () would be processed as:
\layout Verbatim
MOVE
\begin_inset Quotes eld
\end_inset
$fakebase/jason/logo.png
\begin_inset Quotes erd
\end_inset
TO
\begin_inset Quotes eld
\end_inset
$fakebase/my_group/project1/logo.png
\begin_inset Quotes erd
\end_inset
\layout Standard
and the actual file system call would be:
\layout Verbatim
rename ('/var/www/phpgroupware/files/home/jason/logo.php', '/var/www/phpgroupware
/files/home/my_group/project1/logo.png');
\layout Standard
Those used to the old VFS will note that you do not have to translate the
path beforehand.
Let's look at another example.
Suppose you were moving an email attachment stored in phpGroupWare's temporary
directory to the 'attachments' directory within the user's home directory
(we're assuming the attachments directory exists).
Note that the temporary directory is
\emph on
outside
\emph default
the virtual root.
\layout Verbatim
$GLOBALS['phpgw']->vfs->mv (array(
\layout Verbatim
'from' => $GLOBALS['phpgw_info']['server']['temp_dir'] .
'/' .
$randomdir .
'/' .
$randomfile,
\layout Verbatim
'to' => 'attachments/actual_name.ext',
\layout Verbatim
'relatives' => array(
\layout Verbatim
RELATIVE_NONE|VFS_REAL,
\layout Verbatim
RELATIVE_USER
\layout Verbatim
)
\layout Verbatim
));
\layout Standard
$randomdir and $randomfile are what the directory and file might be called
before they are given a proper name by the user, which is actual_name.ext
in this example.
RELATIVE_NONE is the define for using full path names.
However, RELATIVE_NONE is still relative to the virtual root, so we pass
along VFS_REAL as well, to say that the file is
\emph on
outside
\emph default
the virtual root, somewhere else in the file system.
Once again, RELATIVE_USER means relative to the user's home directory.
So the actual file system call might look like this (keep in mind that
$randomdir and $randomfile are just random strings):
\layout Verbatim
rename ('/var/www/phpgroupware/tmp/0ak5adftgh7/jX42sC9M', '/var/www/phpgroupware
/files/home/jason/attachments/actual_name.ext');
\layout Standard
Of course you don't have to know that, nor should you be concerned with
it; you can take it for granted that the VFS will translate the paths correctly.
Let's take a look at one more example, this time using the RELATIVE_USER_APP
define.
RELATIVE_USER_APP is used to store quasi-hidden application files, similar
to the Unix convention of ~/.appname.
It simply appends .appname to the user's home directory.
For example, if you were making an HTML editor application named 'htmledit',
and wanted to keep a backup file in case something goes wrong, you could
use RELATIVE_USER_APP to store it:
\layout Verbatim
$GLOBALS['phpgw']->vfs->write (array(
\layout Verbatim
'string' => 'file.name~',
\layout Verbatim
'relatives' => array(
\layout Verbatim
RELATIVE_USER_APP
\layout Verbatim
),
\layout Verbatim
'content' => $contents
\layout Verbatim
));
\layout Standard
This assumes that ~/.htmledit exists of course.
The backup file
\begin_inset Quotes eld
\end_inset
file.name~
\begin_inset Quotes erd
\end_inset
would then be written in $fakebase/jason/.htmledit/file.name~.
Note that storing files like this might not be as good of a solution as
storing them in the temporary directory or in the database.
But it is there in case you need it.
\layout Subsection
Complete List
\begin_inset LatexCommand \label{sec:relatives_complete_list}
\end_inset
\layout Standard
Here is the complete list of RELATIVE defines, and what they do:
\layout Description
RELATIVE_ROOT Don't translate the path at all.
Just prepends a /.
You'll probably want to use RELATIVE_NONE though, which handles both virtual
and real files.
\layout Description
RELATIVE_USER User's home directory
\layout Description
RELATIVE_CURR_USER Current user's home directory.
If the current directory is $fakebase/my_group/project1, this will return
is $fakebase/my_group
\layout Description
RELATIVE_USER_APP Append .appname to the user's home directory, where appname
is the current application's appname
\layout Description
RELATIVE_PATH DO NOT USE.
Relative to the current directory, used in RELATIVE_ALL
\layout Description
RELATIVE_NONE Not relative to anything.
Use this with VFS_REAL for files outside the virtual root.
Note that using RELATIVE_NONE by itself still means relative to the virtual
root
\layout Description
RELATIVE_CURRENT An alias for the currently set RELATIVE define, or RELATIVE_ALL
if none is set (see the Defaults section)
\layout Description
VFS_REAL File is outside of the virtual root.
Usually used with RELATIVE_NONE
\layout Description
RELATIVE_ALL Relative to the current directory.
Use RELATIVE_ALL
\emph on
\emph default
instead of RELATIVE_PATH
\layout Subsection
Defaults
\begin_inset LatexCommand \label{sec:relatives_defaults}
\end_inset
\layout Standard
You might be thinking to yourself that passing along RELATIVE defines with
every VFS call is overkill, especially if your application always uses
the same relativity.
The default RELATIVE define for all VFS calls is RELATIVE_CURRENT.
RELATIVE_CURRENT itself defaults to RELATIVE_ALL (relative to the current
path),
\emph on
unless
\emph default
your application sets a specific relativity.
If your application requires most of the work to be done outside of the
virtual root, you may wish to set RELATIVE_CURRENT to RELATIVE_NONE|VFS_REAL.
set_relative () is the function to do this.
For example:
\layout Verbatim
$GLOBALS['phpgw']->vfs->set_relative (array(
\layout Verbatim
'mask' => RELATIVE_NONE|VFS_REAL
\layout Verbatim
));
\layout Verbatim
\layout Verbatim
$GLOBALS['phpgw']->vfs->read (array(
\layout Verbatim
'string' => '/etc/passwd'
\layout Verbatim
));
\layout Verbatim
\layout Verbatim
$GLOBALS['phpgw']->vfs->cp (array(
\layout Verbatim
'from' => '/usr/include/stdio.h',
\layout Verbatim
'to' => '/tmp/stdio.h'
\layout Verbatim
));
\layout Verbatim
\layout Verbatim
$GLOBALS['phpgw']->vfs->cp (array(
\layout Verbatim
'from' => '/usr/share/pixmaps/yes.xpm',
\layout Verbatim
'to' => 'icons/yes.xpm',
\layout Verbatim
'relatives' => array(
\layout Verbatim
RELATIVE_CURRENT,
\layout Verbatim
RELATIVE_USER
\layout Verbatim
)
\layout Verbatim
));
\layout Standard
You should notice that no relativity array is needed in the other calls
that refer to files outside the virtual root, but one is needed for calls
that include files inside the virtual root.
Any RELATIVE define can be set as the default and works in the same fashion.
To retrieve the currently set define, use get_relative ().
Note that the relativity is reset after each page request; that is, it's
good only for the life of the current page loading, and is not stored in
session management.
\layout Section
Function reference
\begin_inset LatexCommand \label{sec:function_reference}
\end_inset
\layout Standard
To view the function reference for the VFS, use the doc/inlinedocparser.php
script that comes with phpGroupWare, ie
\begin_inset LatexCommand \url[http://localhost/doc/inlinedocparser.php?fn=class.vfs_sql.inc.php]{http://localhost/doc/inlinedocparser.php?fn=class.vfs_sql.inc.php}
\end_inset
.
\layout Section
Notes
\begin_inset LatexCommand \label{sec:notes}
\end_inset
\layout Subsection
Database
\begin_inset LatexCommand \label{sec:database}
\end_inset
\layout Standard
Data about the files and directories within the virtual root is kept in
the SQL database.
Currently, this information includes:
\layout Itemize
File ID (used internally, primary key for table)
\layout Itemize
Owner ID (phpGW account_id)
\layout Itemize
Created by ID (phpGW account_id)
\layout Itemize
Modified by ID (phpGW account_id)
\layout Itemize
Created (date)
\layout Itemize
Modified (date)
\layout Itemize
Size (bytes)
\layout Itemize
MIME type
\layout Itemize
Deleteable (Y/N/Other?)
\layout Itemize
Comment
\layout Itemize
App (appname of application that created the file)
\layout Itemize
Directory (directory the file or directory is in)
\layout Itemize
Name (name of file or directory)
\layout Itemize
Link directory (if the file or directory is linked, what the actual directory
is)
\layout Itemize
Link name (if the file or directory is linked, what the actual name is)
\layout Itemize
Version (numeric version of the file)
\layout Standard
The internal names of these (the database column names) are stored in the
$GLOBALS['phpgw']->vfs->attributes array, which is useful for loops, and
is guaranteed to be up-to-date.
\layout Standard
Note that no information is kept about files outside the virtual root.
If a file is moved outside, all records of it are deleted from the database
(other than the journaling records).
If a file is moved into the virtual root, some information, specifically
MIME-type, is not always stored in the database.
The vital information has defaults: owner is based on where the file is
being stored; size is correctly read; deleteable is set to Y.
\layout Subsection
ACL support
\begin_inset LatexCommand \label{sec:acl_support}
\end_inset
\layout Standard
ACL support is built into the VFS.
vfs->acl_check () does the actual checking, and is called from all VFS
functions as needed.
If the file or directory sent to acl_check () doesn't exist, the permissions
for the parent directory are used to determine access.
ACL checking can be overridden at any time by setting vfs->override_acl.
For example:
\layout Verbatim
$GLOBALS['phpgw']->vfs->override_acl = 1;
\layout Verbatim
$GLOBALS['phpgw']->vfs->mkdir (array(
\layout Verbatim
'string' => $GLOBALS['fakebase'].
'/' .
$group_array['account_name'],
\layout Verbatim
'relatives' => array(
\layout Verbatim
RELATIVE_NONE
\layout Verbatim
)
\layout Verbatim
));
\layout Verbatim
$GLOBALS['phpgw']->vfs->override_acl = 0;
\layout Subsection
Function aliases
\begin_inset LatexCommand \label{sec:function_aliases}
\end_inset
\layout Standard
You might have noticed there are some functions that just pass the arguments
on to other functions.
These are provided in part because of legacy and in part for convenience.
You can use either.
Here is the list (alias -> actual):
\layout Itemize
copy -> cp
\layout Itemize
move -> rm
\layout Itemize
delete -> rm
\layout Itemize
dir -> ls
\layout Subsection
Fakebase directory (changing /home)
\begin_inset LatexCommand \label{sec:fakebase}
\end_inset
\layout Standard
The old VFS was hard-coded to use '/home' as the fake base directory, even
though the user never saw it.
With the new system, crafty administrators may wish to change '/home' to
something else, say '/users' or '/public_html'.
The fake base directory name is stored in $GLOBALS['phpgw']->vfs->fakebase,
and changing it will transparently change it throughout the VFS and all
applications.
However, this must be done
\emph on
before
\emph default
any data is in the VFS database.
If you wish to change it afterwords, you'll have to manually update the
database, replacing the old value with the new value.
\emph on
Application programmers need to recognize that /home is not absolute, and
use $GLOBALS['phpgw']->vfs->fakebase instead
\emph default
.
I suggest setting $fakebase = $GLOBALS['phpgw']->vfs->fakebase; right off
the bat to keep things neater.
\layout Section
About this Document
\layout Subsection
Copyright and License
\layout Standard
Copyright (c) 2001, 2002 Jason Wies
\layout Standard
Permission is granted to copy, distribute and/or modify this document under
the terms of the GNU Free Documentation License, Version 1.1 or any later
version published by the Free Software Foundation; with no Invarient Sections,
with no Front-Cover Texts, and no Back-Cover Texts.
\layout Standard
A copy of the license is available at
\begin_inset LatexCommand \url[http://www.gnu.org/copyleft/fdl.html]{http://www.gnu.org/copyleft/fdl.html}
\end_inset
.
\layout Subsection
History
\layout Standard
Original document released in June 2001 by Jason Wies.
\layout Standard
Updated February 2002 to include arrayized parameters, single quotes, and
GLOBALS.
\layout Subsection
Contributing
\layout Standard
Contributions are always welcome.
Please send to the current maintainer, Jason Wies,
\begin_inset LatexCommand \url[zone@phpgroupware.org]{mailto:zone@phpgroupware.org}
\end_inset
.
\the_end