mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-07 16:44:20 +01:00
removed outdated docu
This commit is contained in:
parent
dc12a69e9a
commit
a05b0f0fa1
@ -1,6 +0,0 @@
|
|||||||
|
|
||||||
We plan to organize documents centralized on wiki site, for easy maintain. For the latest documents, please visite the public wiki http://egroupware.org/wiki/
|
|
||||||
|
|
||||||
The documents currently in this directory will most likely be moved to wiki upon next update, and please developers don't store more documents here.
|
|
||||||
|
|
||||||
--- message drop by zhangweiwu@realss.com
|
|
@ -1,109 +0,0 @@
|
|||||||
// There is a accounts_shared which added functions that are identical for all
|
|
||||||
|
|
||||||
class accounts_{
|
|
||||||
var $db;
|
|
||||||
var $account_id;
|
|
||||||
var $data;
|
|
||||||
var $memberships;
|
|
||||||
var $members;
|
|
||||||
|
|
||||||
function read_repository()
|
|
||||||
{
|
|
||||||
/**************************************************************************\
|
|
||||||
* Read values for $this->account_id and put them into $this->data and *
|
|
||||||
* then return $this->data *
|
|
||||||
* *
|
|
||||||
* These are the values that should be set: *
|
|
||||||
* $this->data["account_id"] *
|
|
||||||
* $this->data["account_lid"] *
|
|
||||||
* $this->data["account_type"] *
|
|
||||||
* $this->data["firstname"] *
|
|
||||||
* $this->data["lastname"] *
|
|
||||||
* $this->data["fullname"] *
|
|
||||||
* $this->data["lastlogin"] *
|
|
||||||
* $this->data["lastloginfrom"] *
|
|
||||||
* $this->data["lastpasswd_change"] *
|
|
||||||
* $this->data["status"] *
|
|
||||||
\**************************************************************************/
|
|
||||||
}
|
|
||||||
|
|
||||||
/**************************************************************************\
|
|
||||||
* These are the standard $this->account_id specific functions *
|
|
||||||
\**************************************************************************/
|
|
||||||
|
|
||||||
function save_repository(){
|
|
||||||
/**************************************************************************\
|
|
||||||
* Store the values in $this->data to the repository *
|
|
||||||
\**************************************************************************/
|
|
||||||
}
|
|
||||||
|
|
||||||
/**************************************************************************\
|
|
||||||
* These are the generic functions. Not specific to $this->account_id *
|
|
||||||
\**************************************************************************/
|
|
||||||
|
|
||||||
function add($account_name, $account_type, $first_name, $last_name, $passwd = False) {
|
|
||||||
/**************************************************************************\
|
|
||||||
* Create a new account. Password is optional because of our seperated *
|
|
||||||
* auth class structure *
|
|
||||||
\**************************************************************************/
|
|
||||||
}
|
|
||||||
|
|
||||||
function delete($account_id) {
|
|
||||||
/**************************************************************************\
|
|
||||||
* Accept both acount_name or account_id and use name2id to convert to id *
|
|
||||||
* delete account. I have not worked the details of how hooks will be used *
|
|
||||||
* by apps to delete the users data. For now ignore the issue. *
|
|
||||||
\**************************************************************************/
|
|
||||||
}
|
|
||||||
|
|
||||||
function get_list()
|
|
||||||
{
|
|
||||||
/**************************************************************************\
|
|
||||||
* Return a list of users *
|
|
||||||
\**************************************************************************/
|
|
||||||
}
|
|
||||||
|
|
||||||
function name2id($account_name)
|
|
||||||
{
|
|
||||||
/**************************************************************************\
|
|
||||||
* Return the account_id for the account_name requested *
|
|
||||||
* Return False if you cannot find the given account_name *
|
|
||||||
\**************************************************************************/
|
|
||||||
}
|
|
||||||
|
|
||||||
function id2name($account_id)
|
|
||||||
{
|
|
||||||
/**************************************************************************\
|
|
||||||
* Return the account_id for the account_name requested *
|
|
||||||
* Return False if you cannot find the given account_name *
|
|
||||||
\**************************************************************************/
|
|
||||||
}
|
|
||||||
|
|
||||||
function get_type($account_id)
|
|
||||||
{
|
|
||||||
/**************************************************************************\
|
|
||||||
* Return the account_type for the account_id requested *
|
|
||||||
* Return False if you cannot find the given account_id *
|
|
||||||
\**************************************************************************/
|
|
||||||
}
|
|
||||||
|
|
||||||
function exists($accountname)
|
|
||||||
{
|
|
||||||
/**************************************************************************\
|
|
||||||
* Check to see if an account exists. If string is sent, *
|
|
||||||
* use $this->name2id to get the id. *
|
|
||||||
* Return True or False as appropriate *
|
|
||||||
\**************************************************************************/
|
|
||||||
}
|
|
||||||
|
|
||||||
function auto_add($account_name, $passwd, $default_prefs=False, $default_acls= False)
|
|
||||||
{
|
|
||||||
/**************************************************************************\
|
|
||||||
* This is used to auto create an account. First make sure the account_name *
|
|
||||||
* doesnt exist by using $this->exists and then create the account. *
|
|
||||||
* This function still needs to have some details worked out for dealing *
|
|
||||||
* the default values. *
|
|
||||||
\**************************************************************************/
|
|
||||||
}
|
|
||||||
} //end of class
|
|
||||||
?>
|
|
@ -1,95 +0,0 @@
|
|||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
||||||
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>egroupware.org</title>
|
|
||||||
<link rel="STYLESHEET" type="text/css" href="phpgw.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body link="#ff6600" vlink="#6666aa">
|
|
||||||
|
|
||||||
<center>
|
|
||||||
<table border="0" cellspacing="0" cellpadding="0" width="100%">
|
|
||||||
<tr>
|
|
||||||
<td align="right">
|
|
||||||
<table border="0" cellspacing="3" cellpadding="3">
|
|
||||||
<tr>
|
|
||||||
<td><a href="http://www.egroupware.org/"><img src="../templates/default/images/logo.gif"></a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td valign="top" width="85%">
|
|
||||||
<table border="0" cellpadding="2"><tr><td>
|
|
||||||
<p>You can get your own copy of the eGroupWare CVS tree by using a CVS client from your own system. If you don't already
|
|
||||||
have one, you can find one at <a href="http://www.cvshome.org">http://www.cvshome.org</a>.
|
|
||||||
You can get your own copy of the tree with the commands:</p>
|
|
||||||
|
|
||||||
<pre>cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/egroupware login</pre>
|
|
||||||
|
|
||||||
<p>When it asks you for a password, simply press the Enter key</p>
|
|
||||||
<p>Then type:</p>
|
|
||||||
|
|
||||||
<pre>cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/egroupware co [ -r <TAG> ] <MODULE></pre>
|
|
||||||
|
|
||||||
<p>This will create a <tt><MODULE></tt> directory in your current
|
|
||||||
directory. It may take a bit of time, especially if your network connection
|
|
||||||
is slow or the module is an espeicially large one. But once it is done, you
|
|
||||||
will have an up to date copy of the master CVS source for that module. You
|
|
||||||
can then at any time cd into this directory and type:</p>
|
|
||||||
|
|
||||||
<pre>cvs -z3 update -dP</pre>
|
|
||||||
|
|
||||||
<p>to update your source tree to be in sync with the master tree. (The -z3 sets
|
|
||||||
the compression level)</p>
|
|
||||||
|
|
||||||
<p>The <tt><TAG></tt> refers to the release version that you
|
|
||||||
wish to checkout. At this time, tags that would be of use are:
|
|
||||||
<pre>
|
|
||||||
"Version-0_9_10-branch" - most recent release with patches applied,
|
|
||||||
"HEAD" - a development version and should be treated as such.
|
|
||||||
</pre>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
<p>Valid module names are:</p>
|
|
||||||
<table border="0" cellpadding="1" cellspacing="1">
|
|
||||||
<tr><td>egroupware * </td><td>The core eGoupWare libraries</td></tr>
|
|
||||||
<tr><td>phpgwapi * </td><td>The eGoupWare API</td></tr>
|
|
||||||
<tr><td>addressbook * </td><td>an addressbook</td></tr>
|
|
||||||
<tr><td>admin * </td><td>Administration module</td></tr>
|
|
||||||
<tr><td>bookmarks </td><td>Bookmark manager</td></tr>
|
|
||||||
<tr><td>calendar * </td><td>personal/Group calendar</td></tr>
|
|
||||||
<tr><td>comic </td><td>Comic Strip system</td></tr>
|
|
||||||
<tr><td>email * </td><td>EMAIL reader (interfaces to IMAP/POP3)</td></tr>
|
|
||||||
<tr><td>filemanager * </td><td>Personal/Group Filemanagement</td></tr>
|
|
||||||
<tr><td>forum </td><td>A forum system</td></tr>
|
|
||||||
<tr><td>ftp </td><td>web based FTP client</td></tr>
|
|
||||||
<tr><td>headlines </td><td>news site headline system</td></tr>
|
|
||||||
<tr><td>manual * </td><td>online eGoupWare manual</td></tr>
|
|
||||||
<tr><td>news_admin </td><td>create system wide news for your eGoupWare installation</td></tr>
|
|
||||||
<tr><td>polls * </td><td>create/administer polls</td></tr>
|
|
||||||
<tr><td>preferences * </td><td>Manage eGoupWare user preferences</td></tr>
|
|
||||||
<tr><td>projects </td><td>?</td></tr>
|
|
||||||
<tr><td>setup * </td><td>eGoupWare setup</td></tr>
|
|
||||||
<tr><td>stocks </td><td>stock info grabber</td></tr>
|
|
||||||
<tr><td>tts </td><td>Trouble Ticket System</td></tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<p>You should probably check out <code>egroupware</code> first, then
|
|
||||||
<code>cd egroupware</code>, and then check out any additional modules that you
|
|
||||||
want.<br>We suggest at a minimum that you install those modules that mare marked with an "*".</p>
|
|
||||||
|
|
||||||
<p>Please keep in mind that the CVS '-r HEAD' version may not always work correctly,
|
|
||||||
may be unpredictable, etc. The CVS '-r HEAD' version is a development version
|
|
||||||
and should be treated as such.</p>
|
|
||||||
</td></tr></table></td>
|
|
||||||
</tr></table>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</center>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,60 +0,0 @@
|
|||||||
-------------------------------
|
|
||||||
- Suggested PHP Configuration -
|
|
||||||
-------------------------------
|
|
||||||
|
|
||||||
This is a suggested php.ini config for running eGroupWare on php4. It
|
|
||||||
is roughly in the order of the paramters in your php.ini file. These recommendations
|
|
||||||
are based on feedback from users and developers.
|
|
||||||
|
|
||||||
RESOURCES
|
|
||||||
max_execution_time = 90
|
|
||||||
This allows for encoding/decoding large file attachments on slower machines and
|
|
||||||
other complex functions.
|
|
||||||
|
|
||||||
memory_limit = 20M
|
|
||||||
At least this value should help with more complex operations.
|
|
||||||
|
|
||||||
ERRORS
|
|
||||||
error_reporting = E_ALL & ~E_NOTICE
|
|
||||||
Having this set to E_ALL, will cause all types of problems if left to
|
|
||||||
display on the screen. E_NOTICE are non-fatal errors such as undefined
|
|
||||||
variable etc. Having this set to E_ALL only will dramatically increase
|
|
||||||
the size of your log files if you log errors.
|
|
||||||
|
|
||||||
display_errors = Off
|
|
||||||
This can cause header output problems if left on. They are better stored in
|
|
||||||
your log file and that way you have a record of any problems.
|
|
||||||
|
|
||||||
log_errors = On
|
|
||||||
See above.
|
|
||||||
|
|
||||||
DATABASES
|
|
||||||
[dbms].allow_persistent = On
|
|
||||||
This must be set to on if you want to use persistent database
|
|
||||||
connections. Change [dbms] to whatever db you want to use, i.e. mysql or
|
|
||||||
pgsql.
|
|
||||||
|
|
||||||
FILE UPLOADING
|
|
||||||
file_uploads = On
|
|
||||||
If you want to use email,phpwebhosting, infolog or any apps that upload files
|
|
||||||
this must be set to on.
|
|
||||||
|
|
||||||
upload_max_filesize = 5M
|
|
||||||
At least this. This will allow for larger email attachments and
|
|
||||||
phpwebhosting files. Use filesize * 4 = memory_limit to allow for
|
|
||||||
base64 encodes.
|
|
||||||
|
|
||||||
PHP4 SESSIONS
|
|
||||||
session.save_path = /tmp
|
|
||||||
Your httpd must be able to read and write to this directory, if you
|
|
||||||
intend to use php4 sessions.
|
|
||||||
|
|
||||||
session.gc_maxlifetime = 1440
|
|
||||||
Set this to what you want to be your session time out limit. It is in
|
|
||||||
seconds, so set it to 3660 if you want it to one hour ... the default is
|
|
||||||
24mins, which is generally too short.
|
|
||||||
|
|
||||||
REGISTER GLOBALS
|
|
||||||
register_globals = On
|
|
||||||
Until release eGroupWare will not work, if the value is set to Off.
|
|
||||||
All further releases will support the Off setting.
|
|
@ -1,21 +0,0 @@
|
|||||||
body { font-family: Geneva,Arial,Helvetica,sans-serif; font-size: 10pt; }
|
|
||||||
pre { font-family: Lucida Console, monospace; font-size: 10pt; }
|
|
||||||
tt { font-family: Lucida Console, monospace; font-size: 10pt; }
|
|
||||||
td { font-family: Geneva,Arial,Helvetica,sans-serif; font-size: 10pt; }
|
|
||||||
|
|
||||||
.h1 { font-size: 18pt; color: white; font-family: Verdana,Geneva,Arial,Helvetica,sans-serif; }
|
|
||||||
.h1black { font-size: 18pt; color: black; font-family: Verdana,Geneva,Arial,Helvetica,sans-serif; }
|
|
||||||
.h2 { font-size: 14pt; color: #ccccff; }
|
|
||||||
.h2black { font-size: 14pt; color: black; }
|
|
||||||
|
|
||||||
a { color: #333399; text-decoration: underline; }
|
|
||||||
a:visited { color: #6666aa; text-decoration: underline; }
|
|
||||||
a:hover { color: #0000ff; text-decoration: underline; }
|
|
||||||
|
|
||||||
a.side { color: #ff9900; text-decoration: none; }
|
|
||||||
a.side:visited { color: #ffcc66; text-decoration: none; }
|
|
||||||
a.side:hover { color: #ffffcc; text-decoration: underline; }
|
|
||||||
|
|
||||||
a.anchor { color: #000066; text-decoration: none; }
|
|
||||||
|
|
||||||
td.side { color: white; }
|
|
Binary file not shown.
@ -1,164 +0,0 @@
|
|||||||
#!/usr/bin/perl
|
|
||||||
#Created by Jason Wies (Zone, zone@users.sourceforge.net)
|
|
||||||
#Copyright 2001 Jason Wies
|
|
||||||
#Released under GNU Public License
|
|
||||||
|
|
||||||
#Converts HeaderDoc style inline comments to LyX style LaTeX
|
|
||||||
#Usage: ./inline2lyx.pl file Title Author Date Abstract
|
|
||||||
|
|
||||||
if (!@ARGV[0])
|
|
||||||
{
|
|
||||||
print "Usage: ./inline2lyx.pl file Title Author Date Abstract\n";
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$output .= '\lyxformat 2.16
|
|
||||||
\textclass linuxdoc
|
|
||||||
\language default
|
|
||||||
\inputencoding latin1
|
|
||||||
\fontscheme default
|
|
||||||
\graphics default
|
|
||||||
\paperfontsize default
|
|
||||||
\spacing single
|
|
||||||
\papersize Default
|
|
||||||
\paperpackage a4
|
|
||||||
\use_geometry 0
|
|
||||||
\use_amsmath 0
|
|
||||||
\paperorientation portrait
|
|
||||||
\secnumdepth 2
|
|
||||||
\tocdepth 2
|
|
||||||
\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
|
|
||||||
' . @ARGV[1] . '
|
|
||||||
\layout Author
|
|
||||||
|
|
||||||
' . @ARGV[2] . '
|
|
||||||
|
|
||||||
\layout Date
|
|
||||||
|
|
||||||
' . @ARGV[3] . '
|
|
||||||
|
|
||||||
\layout Abstract
|
|
||||||
|
|
||||||
' . @ARGV[4] . '
|
|
||||||
|
|
||||||
\layout Section
|
|
||||||
|
|
||||||
' . @ARGV[1];
|
|
||||||
|
|
||||||
$file = `cat @ARGV[0]`;
|
|
||||||
|
|
||||||
@lines = split ('\n', $file);
|
|
||||||
|
|
||||||
foreach $line (@lines)
|
|
||||||
{
|
|
||||||
undef $start;
|
|
||||||
undef $class;
|
|
||||||
undef $function;
|
|
||||||
undef $abstract;
|
|
||||||
undef $param;
|
|
||||||
undef $result;
|
|
||||||
undef $discussion;
|
|
||||||
undef $end;
|
|
||||||
undef $layout;
|
|
||||||
|
|
||||||
if ($line =~ /\/\*\!/)
|
|
||||||
{
|
|
||||||
$in = 1;
|
|
||||||
$start = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($looking && $line =~ /function/)
|
|
||||||
{
|
|
||||||
$layout = "verbatim";
|
|
||||||
undef $looking;
|
|
||||||
}
|
|
||||||
elsif (!$in)
|
|
||||||
{
|
|
||||||
goto next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($line =~ /\@(class)/)
|
|
||||||
{
|
|
||||||
$layout = "subsection";
|
|
||||||
$name = $1;
|
|
||||||
$class = 1;
|
|
||||||
}
|
|
||||||
if ($line =~ /\@(function)/)
|
|
||||||
{
|
|
||||||
$layout = "subsection";
|
|
||||||
$name = $1;
|
|
||||||
$function = 1;
|
|
||||||
}
|
|
||||||
if ($line =~ /\@(abstract)/)
|
|
||||||
{
|
|
||||||
$layout = "standard";
|
|
||||||
$name = $1;
|
|
||||||
$abstract = 1;
|
|
||||||
}
|
|
||||||
if ($line =~ /\@(description)/)
|
|
||||||
{
|
|
||||||
$layout = "standard";
|
|
||||||
$name = $1;
|
|
||||||
$description = 1;
|
|
||||||
}
|
|
||||||
if ($line =~ /\@(param)/)
|
|
||||||
{
|
|
||||||
$layout = "standard";
|
|
||||||
$name = $1;
|
|
||||||
$param = 1;
|
|
||||||
}
|
|
||||||
if ($line =~ /\@(result)/)
|
|
||||||
{
|
|
||||||
$layout = "standard";
|
|
||||||
$name = $1;
|
|
||||||
$result = 1;
|
|
||||||
}
|
|
||||||
if ($line =~ /\@(discussion)/)
|
|
||||||
{
|
|
||||||
$layout = "standard";
|
|
||||||
$name = $1;
|
|
||||||
$discussion = 1;
|
|
||||||
}
|
|
||||||
if ($line =~ /\*\// && $in)
|
|
||||||
{
|
|
||||||
undef $in;
|
|
||||||
$looking = 1;
|
|
||||||
$end = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($layout)
|
|
||||||
{
|
|
||||||
$output .= "\n\n" . '\layout ' . ucfirst ($layout);
|
|
||||||
$line =~ s/\@function//;
|
|
||||||
$line =~ s/\@//;
|
|
||||||
$data = ucfirst ($line);
|
|
||||||
if (!$function && !$class)
|
|
||||||
{
|
|
||||||
$data =~ s/$name/$name:/;
|
|
||||||
}
|
|
||||||
$output .= "\n$data";
|
|
||||||
if ($function || $class)
|
|
||||||
{
|
|
||||||
$output .= "\n" . '\begin_inset LatexCommand \label{sec:' . "$data" . '}' . "\n\n" . '\end_inset';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
elsif ($in && !$start)
|
|
||||||
{
|
|
||||||
$output .= '\layout Standard' . "\n$line";
|
|
||||||
}
|
|
||||||
|
|
||||||
next:
|
|
||||||
}
|
|
||||||
|
|
||||||
$output .= "\n" . '\the_end';
|
|
||||||
|
|
||||||
print $output;
|
|
@ -1,28 +0,0 @@
|
|||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
|
||||||
<HTML>
|
|
||||||
<HEAD>
|
|
||||||
<META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 0.9.17">
|
|
||||||
<TITLE>phpgwapi - VFS Class: Introduction and Purpose</TITLE>
|
|
||||||
<LINK HREF="vfs-2.html" REL=next>
|
|
||||||
|
|
||||||
<LINK HREF="vfs.html#toc1" REL=contents>
|
|
||||||
</HEAD>
|
|
||||||
<BODY>
|
|
||||||
<A HREF="vfs-2.html">Next</A>
|
|
||||||
Previous
|
|
||||||
<A HREF="vfs.html#toc1">Contents</A>
|
|
||||||
<HR>
|
|
||||||
<H2><A NAME="sec:introduction"></A> <A NAME="s1">1.</A> <A HREF="vfs.html#toc1">Introduction and Purpose</A></H2>
|
|
||||||
|
|
||||||
<P>The latest version of the VFS for eGroupWare 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.</P>
|
|
||||||
<HR>
|
|
||||||
<A HREF="vfs-2.html">Next</A>
|
|
||||||
Previous
|
|
||||||
<A HREF="vfs.html#toc1">Contents</A>
|
|
||||||
</BODY>
|
|
||||||
</HTML>
|
|
@ -1,143 +0,0 @@
|
|||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
|
||||||
<HTML>
|
|
||||||
<HEAD>
|
|
||||||
<META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 0.9.17">
|
|
||||||
<TITLE>phpgwapi - VFS Class: Basics</TITLE>
|
|
||||||
<LINK HREF="vfs-3.html" REL=next>
|
|
||||||
<LINK HREF="vfs-1.html" REL=previous>
|
|
||||||
<LINK HREF="vfs.html#toc2" REL=contents>
|
|
||||||
</HEAD>
|
|
||||||
<BODY>
|
|
||||||
<A HREF="vfs-3.html">Next</A>
|
|
||||||
<A HREF="vfs-1.html">Previous</A>
|
|
||||||
<A HREF="vfs.html#toc2">Contents</A>
|
|
||||||
<HR>
|
|
||||||
<H2><A NAME="sec:basics"></A> <A NAME="s2">2.</A> <A HREF="vfs.html#toc2">Basics</A></H2>
|
|
||||||
|
|
||||||
<H2><A NAME="sec:prerequisites"></A> <A NAME="ss2.1">2.1</A> <A HREF="vfs.html#toc2.1">Prerequisites</A>
|
|
||||||
</H2>
|
|
||||||
|
|
||||||
<P>You must explicitly enable the VFS class. To do this, set 'enable_vfs_class'
|
|
||||||
to True in $GLOBALS['phpgw_info']['flags'].
|
|
||||||
An example:</P>
|
|
||||||
<P>
|
|
||||||
<PRE>
|
|
||||||
$GLOBALS['phpgw_info']['flags'] = array(
|
|
||||||
'currentapp' => 'filemanaer',
|
|
||||||
'noheader' => False,
|
|
||||||
'noappheader' => False,
|
|
||||||
'enable_vfs_class' => True,
|
|
||||||
'enable_browser_class' => True
|
|
||||||
);
|
|
||||||
</PRE>
|
|
||||||
</P>
|
|
||||||
<H2><A NAME="sec:concepts"></A> <A NAME="ss2.2">2.2</A> <A HREF="vfs.html#toc2.2">Concepts</A>
|
|
||||||
</H2>
|
|
||||||
|
|
||||||
<P>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:</P>
|
|
||||||
<P>
|
|
||||||
<UL>
|
|
||||||
<LI>Files and directories are synonymous in almost all cases</LI>
|
|
||||||
</UL>
|
|
||||||
</P>
|
|
||||||
<P>
|
|
||||||
<PRE>
|
|
||||||
$GLOBALS['phpgw']->vfs->mv (array(
|
|
||||||
'from' => 'file1',
|
|
||||||
'to' => 'dir/file2'
|
|
||||||
));
|
|
||||||
|
|
||||||
$GLOBALS['phpgw']->vfs->mv (array(
|
|
||||||
'from' => 'dir1',
|
|
||||||
'to' => 'dir/dir1'
|
|
||||||
));
|
|
||||||
|
|
||||||
$GLOBALS['phpgw']->vfs->rm (array(
|
|
||||||
'string' => 'file'
|
|
||||||
));
|
|
||||||
|
|
||||||
$GLOBALS['phpgw']->vfs->rm (array(
|
|
||||||
'string' => 'dir'
|
|
||||||
));
|
|
||||||
</PRE>
|
|
||||||
</P>
|
|
||||||
<P>All work as you would except them to. The major exception is:</P>
|
|
||||||
<P>
|
|
||||||
<PRE>
|
|
||||||
$GLOBALS['phpgw']->vfs->touch (array(
|
|
||||||
'string' => 'file'
|
|
||||||
));
|
|
||||||
</PRE>
|
|
||||||
</P>
|
|
||||||
<P>vs.</P>
|
|
||||||
<P>
|
|
||||||
<PRE>
|
|
||||||
$GLOBALS['phpgw']->vfs->mkdir (array(
|
|
||||||
'string' => 'dir'
|
|
||||||
));
|
|
||||||
</PRE>
|
|
||||||
</P>
|
|
||||||
<P>
|
|
||||||
<UL>
|
|
||||||
<LI>Users and groups are synonymous</LI>
|
|
||||||
</UL>
|
|
||||||
</P>
|
|
||||||
<P>As far as the actual paths are concerned, users and groups are
|
|
||||||
the same. /home/username works the same as /home/groupname.</P>
|
|
||||||
<P>
|
|
||||||
<UL>
|
|
||||||
<LI>You should never have to know the real paths of files</LI>
|
|
||||||
</UL>
|
|
||||||
</P>
|
|
||||||
<P>One of the VFS's responsibilities is to translate paths for you.
|
|
||||||
While you certainly <EM>can</EM> operate using full paths, it is much simpler
|
|
||||||
to use the virtual paths. For example, instead of using:</P>
|
|
||||||
<P>
|
|
||||||
<PRE>
|
|
||||||
$GLOBALS['phpgw']->vfs->cp (array(
|
|
||||||
'from' => '/var/www/egroupware/files/home/user/file1',
|
|
||||||
'to' => '/var/www/egroupware/files/home/user/file2',
|
|
||||||
'relatives' => array(
|
|
||||||
RELATIVE_NONE|VFS_REAL,
|
|
||||||
RELATIVE_NONE|VFS_REAL
|
|
||||||
)
|
|
||||||
));
|
|
||||||
</PRE>
|
|
||||||
</P>
|
|
||||||
<P>you might use</P>
|
|
||||||
<P>
|
|
||||||
<PRE>
|
|
||||||
$GLOBALS['phpgw']->vfs->cp (array(
|
|
||||||
'from' => '/home/user/file1',
|
|
||||||
'to' => '/home/user/file2',
|
|
||||||
'relatives' => array(
|
|
||||||
RELATIVE_NONE,
|
|
||||||
RELATIVE_NONE
|
|
||||||
)
|
|
||||||
));
|
|
||||||
</PRE>
|
|
||||||
</P>
|
|
||||||
<P>(We'll get to the RELATIVE's in a minute.)</P>
|
|
||||||
<P>Site administrators should be able to move their files dir around
|
|
||||||
on their system and know that everything will continue to work smoothly.</P>
|
|
||||||
<P>
|
|
||||||
<UL>
|
|
||||||
<LI>Relativity is <EM>vital</EM></LI>
|
|
||||||
</UL>
|
|
||||||
</P>
|
|
||||||
<P>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.</P>
|
|
||||||
<HR>
|
|
||||||
<A HREF="vfs-3.html">Next</A>
|
|
||||||
<A HREF="vfs-1.html">Previous</A>
|
|
||||||
<A HREF="vfs.html#toc2">Contents</A>
|
|
||||||
</BODY>
|
|
||||||
</HTML>
|
|
@ -1,130 +0,0 @@
|
|||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
|
||||||
<HTML>
|
|
||||||
<HEAD>
|
|
||||||
<META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 0.9.17">
|
|
||||||
<TITLE>phpgwapi - VFS Class: Basic Functions</TITLE>
|
|
||||||
<LINK HREF="vfs-4.html" REL=next>
|
|
||||||
<LINK HREF="vfs-2.html" REL=previous>
|
|
||||||
<LINK HREF="vfs.html#toc3" REL=contents>
|
|
||||||
</HEAD>
|
|
||||||
<BODY>
|
|
||||||
<A HREF="vfs-4.html">Next</A>
|
|
||||||
<A HREF="vfs-2.html">Previous</A>
|
|
||||||
<A HREF="vfs.html#toc3">Contents</A>
|
|
||||||
<HR>
|
|
||||||
<H2><A NAME="sec:basic_functions"></A> <A NAME="s3">3.</A> <A HREF="vfs.html#toc3">Basic Functions</A></H2>
|
|
||||||
|
|
||||||
<P>These are two functions you'll need to know before we get into
|
|
||||||
relativity.</P>
|
|
||||||
<H2><A NAME="sec:path_parts"></A> <A NAME="ss3.1">3.1</A> <A HREF="vfs.html#toc3.1">path_parts ()</A>
|
|
||||||
</H2>
|
|
||||||
|
|
||||||
<P>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:</P>
|
|
||||||
<P>
|
|
||||||
<PRE>
|
|
||||||
string
|
|
||||||
relatives
|
|
||||||
object
|
|
||||||
</PRE>
|
|
||||||
</P>
|
|
||||||
<P>'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:</P>
|
|
||||||
<P>
|
|
||||||
<PRE>
|
|
||||||
fake_full_path
|
|
||||||
fake_leading_dirs
|
|
||||||
fake_extra_path
|
|
||||||
fake_name
|
|
||||||
real_full_path
|
|
||||||
real_leading_dirs
|
|
||||||
real_extra_path
|
|
||||||
real_name
|
|
||||||
</PRE>
|
|
||||||
</P>
|
|
||||||
<P>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 "home" to the end of the leading_dirs. To better
|
|
||||||
illustrate, here is an example:</P>
|
|
||||||
<P>
|
|
||||||
<PRE>
|
|
||||||
$p = $GLOBALS['phpgw']->vfs->path_parts (array(
|
|
||||||
'string' => '/home/jason/dir/file',
|
|
||||||
'relatives' => array(
|
|
||||||
RELATIVE_NONE
|
|
||||||
)
|
|
||||||
));
|
|
||||||
</PRE>
|
|
||||||
</P>
|
|
||||||
<P>
|
|
||||||
<UL>
|
|
||||||
<LI>$p->fake_full_path - /home/jason/dir/file</LI>
|
|
||||||
<LI>$p->fake_leading_dirs - /home/jason/dir</LI>
|
|
||||||
<LI>$p->fake_extra_path - home/jason/dir</LI>
|
|
||||||
<LI>$p->fake_name - file</LI>
|
|
||||||
<LI>$p->real_full_path - /var/www/egroupware/files/home/jason/dir/file</LI>
|
|
||||||
<LI>$p->real_leading_dirs - /var/www/egroupware/files/home/jason/dir
|
|
||||||
</LI>
|
|
||||||
<LI>$p->real_extra_path - home/jason/dir</LI>
|
|
||||||
<LI>$p->real_name - file</LI>
|
|
||||||
</UL>
|
|
||||||
</P>
|
|
||||||
<P>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 <EM>getabsolutepath () is depreciated</EM>.
|
|
||||||
getabsolutepath () still exists (albeit in a much different form),
|
|
||||||
and is responsible for some of the path translation, but it is an
|
|
||||||
<EM>internal</EM> 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.</P>
|
|
||||||
<H2><A NAME="sec:cd"></A> <A NAME="ss3.2">3.2</A> <A HREF="vfs.html#toc3.2">cd ()</A>
|
|
||||||
</H2>
|
|
||||||
|
|
||||||
<P>Part of the overall goal for the VFS in eGroupWare 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: </P>
|
|
||||||
<P>
|
|
||||||
<PRE>
|
|
||||||
/* cd to their home directory */
|
|
||||||
$GLOBALS['phpgw']->vfs->cd (array(
|
|
||||||
'string' => '/'
|
|
||||||
));
|
|
||||||
|
|
||||||
/* cd to /home/jason/dir */
|
|
||||||
$GLOBALS['phpgw']->vfs->cd (array(
|
|
||||||
'string' => '/home/jason/dir',
|
|
||||||
'relative' => False,
|
|
||||||
'relatives' => array(
|
|
||||||
RELATIVE_NONE
|
|
||||||
)
|
|
||||||
));
|
|
||||||
|
|
||||||
/* When following the above, cd's to /home/jason/dir/dir2 */
|
|
||||||
$GLOBALS['phpgw']->vfs->cd (array(
|
|
||||||
'string' => 'dir2',
|
|
||||||
'relative' => True
|
|
||||||
));
|
|
||||||
</PRE>
|
|
||||||
</P>
|
|
||||||
<P>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
|
|
||||||
().</P>
|
|
||||||
<P>Now you're ready for relativity.</P>
|
|
||||||
<HR>
|
|
||||||
<A HREF="vfs-4.html">Next</A>
|
|
||||||
<A HREF="vfs-2.html">Previous</A>
|
|
||||||
<A HREF="vfs.html#toc3">Contents</A>
|
|
||||||
</BODY>
|
|
||||||
</HTML>
|
|
@ -1,201 +0,0 @@
|
|||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
|
||||||
<HTML>
|
|
||||||
<HEAD>
|
|
||||||
<META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 0.9.17">
|
|
||||||
<TITLE>phpgwapi - VFS Class: Relativity</TITLE>
|
|
||||||
<LINK HREF="vfs-5.html" REL=next>
|
|
||||||
<LINK HREF="vfs-3.html" REL=previous>
|
|
||||||
<LINK HREF="vfs.html#toc4" REL=contents>
|
|
||||||
</HEAD>
|
|
||||||
<BODY>
|
|
||||||
<A HREF="vfs-5.html">Next</A>
|
|
||||||
<A HREF="vfs-3.html">Previous</A>
|
|
||||||
<A HREF="vfs.html#toc4">Contents</A>
|
|
||||||
<HR>
|
|
||||||
<H2><A NAME="sec:relativity"></A> <A NAME="s4">4.</A> <A HREF="vfs.html#toc4">Relativity</A></H2>
|
|
||||||
|
|
||||||
<P>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
|
|
||||||
<A HREF="vfs-6.html#sec:fakebase">Fakebase directory (changing /home)</A> 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. <EM>You should always use $fakebase when
|
|
||||||
making applications. </EM>I suggest doing $fakebase = $GLOBALS['phpgw']->vfs->fakebase;
|
|
||||||
right off the bat to keep things neater.</P>
|
|
||||||
<H2><A NAME="ss4.1">4.1</A> <A HREF="vfs.html#toc4.1">What is it and how does it work?</A>
|
|
||||||
</H2>
|
|
||||||
|
|
||||||
<P>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 eGoupWare 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.</P>
|
|
||||||
|
|
||||||
<P>
|
|
||||||
<PRE>
|
|
||||||
$GLOBALS['phpgw']->vfs->mv (array(
|
|
||||||
'from' => 'logo.png',
|
|
||||||
'to' => 'logo.png',
|
|
||||||
'relatives' => array(
|
|
||||||
RELATIVE_USER,
|
|
||||||
RELATIVE_ALL
|
|
||||||
)
|
|
||||||
));
|
|
||||||
</PRE>
|
|
||||||
</P>
|
|
||||||
<P>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 "$fakebase/my_group/project1",
|
|
||||||
the call to mv () would be processed as:</P>
|
|
||||||
<P>
|
|
||||||
<PRE>
|
|
||||||
MOVE "$fakebase/jason/logo.png" TO "$fakebase/my_group/project1/logo.png"
|
|
||||||
</PRE>
|
|
||||||
</P>
|
|
||||||
<P>and the actual file system call would be:</P>
|
|
||||||
<P>
|
|
||||||
<PRE>
|
|
||||||
rename ('/var/www/egroupware/files/home/jason/logo.php', '/var/www/egroupware/files/home/my_group/project1/logo.png');
|
|
||||||
</PRE>
|
|
||||||
</P>
|
|
||||||
<P>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 eGoupWare'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 <EM>outside</EM> the virtual root.</P>
|
|
||||||
<P>
|
|
||||||
<PRE>
|
|
||||||
$GLOBALS['phpgw']->vfs->mv (array(
|
|
||||||
'from' => $GLOBALS['phpgw_info']['server']['temp_dir'] . '/' . $randomdir . '/' . $randomfile,
|
|
||||||
'to' => 'attachments/actual_name.ext',
|
|
||||||
'relatives' => array(
|
|
||||||
RELATIVE_NONE|VFS_REAL,
|
|
||||||
RELATIVE_USER
|
|
||||||
)
|
|
||||||
));
|
|
||||||
</PRE>
|
|
||||||
</P>
|
|
||||||
<P>$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 <EM>outside</EM> 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):</P>
|
|
||||||
<P>
|
|
||||||
<PRE>
|
|
||||||
rename ('/var/www/egroupware/tmp/0ak5adftgh7/jX42sC9M', '/var/www/egroupware/files/home/jason/attachments/actual_name.ext');
|
|
||||||
</PRE>
|
|
||||||
</P>
|
|
||||||
<P>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:</P>
|
|
||||||
<P>
|
|
||||||
<PRE>
|
|
||||||
$GLOBALS['phpgw']->vfs->write (array(
|
|
||||||
'string' => 'file.name~',
|
|
||||||
'relatives' => array(
|
|
||||||
RELATIVE_USER_APP
|
|
||||||
),
|
|
||||||
'content' => $contents
|
|
||||||
));
|
|
||||||
</PRE>
|
|
||||||
</P>
|
|
||||||
<P>This assumes that ~/.htmledit exists of course. The backup
|
|
||||||
file "file.name~" 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.</P>
|
|
||||||
<H2><A NAME="sec:relatives_complete_list"></A> <A NAME="ss4.2">4.2</A> <A HREF="vfs.html#toc4.2">Complete List</A>
|
|
||||||
</H2>
|
|
||||||
|
|
||||||
<P>Here is the complete list of RELATIVE defines, and what they
|
|
||||||
do:</P>
|
|
||||||
<P>
|
|
||||||
<DL>
|
|
||||||
<DT><B>RELATIVE_ROOT</B><DD><P>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.</P>
|
|
||||||
<DT><B>RELATIVE_USER</B><DD><P>User's home directory</P>
|
|
||||||
<DT><B>RELATIVE_CURR_USER</B><DD><P>Current user's home directory. If the
|
|
||||||
current directory is $fakebase/my_group/project1, this will
|
|
||||||
return is $fakebase/my_group</P>
|
|
||||||
<DT><B>RELATIVE_USER_APP</B><DD><P>Append .appname to the user's home directory,
|
|
||||||
where appname is the current application's appname</P>
|
|
||||||
<DT><B>RELATIVE_PATH</B><DD><P>DO NOT USE. Relative to the current directory,
|
|
||||||
used in RELATIVE_ALL</P>
|
|
||||||
<DT><B>RELATIVE_NONE</B><DD><P>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</P>
|
|
||||||
<DT><B>RELATIVE_CURRENT</B><DD><P>An alias for the currently set RELATIVE
|
|
||||||
define, or RELATIVE_ALL if none is set (see the Defaults section)</P>
|
|
||||||
<DT><B>VFS_REAL</B><DD><P>File is outside of the virtual root. Usually used
|
|
||||||
with RELATIVE_NONE</P>
|
|
||||||
<DT><B>RELATIVE_ALL</B><DD><P>Relative to the current directory. Use RELATIVE_ALL<EM></EM>instead of RELATIVE_PATH</P>
|
|
||||||
</DL>
|
|
||||||
</P>
|
|
||||||
<H2><A NAME="sec:relatives_defaults"></A> <A NAME="ss4.3">4.3</A> <A HREF="vfs.html#toc4.3">Defaults</A>
|
|
||||||
</H2>
|
|
||||||
|
|
||||||
<P>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), <EM>unless</EM> 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:</P>
|
|
||||||
<P>
|
|
||||||
<PRE>
|
|
||||||
$GLOBALS['phpgw']->vfs->set_relative (array(
|
|
||||||
'mask' => RELATIVE_NONE|VFS_REAL
|
|
||||||
));
|
|
||||||
|
|
||||||
$GLOBALS['phpgw']->vfs->read (array(
|
|
||||||
'string' => '/etc/passwd'
|
|
||||||
));
|
|
||||||
|
|
||||||
$GLOBALS['phpgw']->vfs->cp (array(
|
|
||||||
'from' => '/usr/include/stdio.h',
|
|
||||||
'to' => '/tmp/stdio.h'
|
|
||||||
));
|
|
||||||
|
|
||||||
$GLOBALS['phpgw']->vfs->cp (array(
|
|
||||||
'from' => '/usr/share/pixmaps/yes.xpm',
|
|
||||||
'to' => 'icons/yes.xpm',
|
|
||||||
'relatives' => array(
|
|
||||||
RELATIVE_CURRENT,
|
|
||||||
RELATIVE_USER
|
|
||||||
)
|
|
||||||
));
|
|
||||||
</PRE>
|
|
||||||
</P>
|
|
||||||
<P>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.</P>
|
|
||||||
<HR>
|
|
||||||
<A HREF="vfs-5.html">Next</A>
|
|
||||||
<A HREF="vfs-3.html">Previous</A>
|
|
||||||
<A HREF="vfs.html#toc4">Contents</A>
|
|
||||||
</BODY>
|
|
||||||
</HTML>
|
|
@ -1,25 +0,0 @@
|
|||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
|
||||||
<HTML>
|
|
||||||
<HEAD>
|
|
||||||
<META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 0.9.17">
|
|
||||||
<TITLE>phpgwapi - VFS Class: Function reference</TITLE>
|
|
||||||
<LINK HREF="vfs-6.html" REL=next>
|
|
||||||
<LINK HREF="vfs-4.html" REL=previous>
|
|
||||||
<LINK HREF="vfs.html#toc5" REL=contents>
|
|
||||||
</HEAD>
|
|
||||||
<BODY>
|
|
||||||
<A HREF="vfs-6.html">Next</A>
|
|
||||||
<A HREF="vfs-4.html">Previous</A>
|
|
||||||
<A HREF="vfs.html#toc5">Contents</A>
|
|
||||||
<HR>
|
|
||||||
<H2><A NAME="sec:function_reference"></A> <A NAME="s5">5.</A> <A HREF="vfs.html#toc5">Function reference</A></H2>
|
|
||||||
|
|
||||||
<P>To view the function reference for the VFS, use the doc/inlinedocparser.php
|
|
||||||
script that comes with eGroupWare, ie
|
|
||||||
<A HREF="http://localhost/doc/inlinedocparser.php?fn=class.vfs_sql.inc.php">http://localhost/doc/inlinedocparser.php?fn=class.vfs_sql.inc.php</A>.</P>
|
|
||||||
<HR>
|
|
||||||
<A HREF="vfs-6.html">Next</A>
|
|
||||||
<A HREF="vfs-4.html">Previous</A>
|
|
||||||
<A HREF="vfs.html#toc5">Contents</A>
|
|
||||||
</BODY>
|
|
||||||
</HTML>
|
|
@ -1,110 +0,0 @@
|
|||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
|
||||||
<HTML>
|
|
||||||
<HEAD>
|
|
||||||
<META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 0.9.17">
|
|
||||||
<TITLE>phpgwapi - VFS Class: Notes</TITLE>
|
|
||||||
<LINK HREF="vfs-7.html" REL=next>
|
|
||||||
<LINK HREF="vfs-5.html" REL=previous>
|
|
||||||
<LINK HREF="vfs.html#toc6" REL=contents>
|
|
||||||
</HEAD>
|
|
||||||
<BODY>
|
|
||||||
<A HREF="vfs-7.html">Next</A>
|
|
||||||
<A HREF="vfs-5.html">Previous</A>
|
|
||||||
<A HREF="vfs.html#toc6">Contents</A>
|
|
||||||
<HR>
|
|
||||||
<H2><A NAME="sec:notes"></A> <A NAME="s6">6.</A> <A HREF="vfs.html#toc6">Notes</A></H2>
|
|
||||||
|
|
||||||
<H2><A NAME="sec:database"></A> <A NAME="ss6.1">6.1</A> <A HREF="vfs.html#toc6.1">Database</A>
|
|
||||||
</H2>
|
|
||||||
|
|
||||||
<P>Data about the files and directories within the virtual root
|
|
||||||
is kept in the SQL database. Currently, this information includes:</P>
|
|
||||||
<P>
|
|
||||||
<UL>
|
|
||||||
<LI>File ID (used internally, primary key for table)</LI>
|
|
||||||
<LI>Owner ID (phpGW account_id)</LI>
|
|
||||||
<LI>Created by ID (phpGW account_id)</LI>
|
|
||||||
<LI>Modified by ID (phpGW account_id)</LI>
|
|
||||||
<LI>Created (date)</LI>
|
|
||||||
<LI>Modified (date)</LI>
|
|
||||||
<LI>Size (bytes)</LI>
|
|
||||||
<LI>MIME type</LI>
|
|
||||||
<LI>Deleteable (Y/N/Other?)</LI>
|
|
||||||
<LI>Comment</LI>
|
|
||||||
<LI>App (appname of application that created the file)</LI>
|
|
||||||
<LI>Directory (directory the file or directory is in)</LI>
|
|
||||||
<LI>Name (name of file or directory)</LI>
|
|
||||||
<LI>Link directory (if the file or directory is linked, what the
|
|
||||||
actual directory is)</LI>
|
|
||||||
<LI>Link name (if the file or directory is linked, what the actual
|
|
||||||
name is)</LI>
|
|
||||||
<LI>Version (numeric version of the file)</LI>
|
|
||||||
</UL>
|
|
||||||
</P>
|
|
||||||
<P>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.</P>
|
|
||||||
<P>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.</P>
|
|
||||||
<H2><A NAME="sec:acl_support"></A> <A NAME="ss6.2">6.2</A> <A HREF="vfs.html#toc6.2">ACL support</A>
|
|
||||||
</H2>
|
|
||||||
|
|
||||||
<P>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:</P>
|
|
||||||
<P>
|
|
||||||
<PRE>
|
|
||||||
$GLOBALS['phpgw']->vfs->override_acl = 1;
|
|
||||||
$GLOBALS['phpgw']->vfs->mkdir (array(
|
|
||||||
'string' => $GLOBALS['fakebase']. '/' . $group_array['account_name'],
|
|
||||||
'relatives' => array(
|
|
||||||
RELATIVE_NONE
|
|
||||||
)
|
|
||||||
));
|
|
||||||
$GLOBALS['phpgw']->vfs->override_acl = 0;
|
|
||||||
</PRE>
|
|
||||||
</P>
|
|
||||||
<H2><A NAME="sec:function_aliases"></A> <A NAME="ss6.3">6.3</A> <A HREF="vfs.html#toc6.3">Function aliases</A>
|
|
||||||
</H2>
|
|
||||||
|
|
||||||
<P>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):</P>
|
|
||||||
<P>
|
|
||||||
<UL>
|
|
||||||
<LI>copy -> cp</LI>
|
|
||||||
<LI>move -> rm</LI>
|
|
||||||
<LI>delete -> rm</LI>
|
|
||||||
<LI>dir -> ls</LI>
|
|
||||||
</UL>
|
|
||||||
</P>
|
|
||||||
<H2><A NAME="sec:fakebase"></A> <A NAME="ss6.4">6.4</A> <A HREF="vfs.html#toc6.4">Fakebase directory (changing /home)</A>
|
|
||||||
</H2>
|
|
||||||
|
|
||||||
<P>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 <EM>before</EM> 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. <EM>Application programmers need to recognize that /home is
|
|
||||||
not absolute, and use $GLOBALS['phpgw']->vfs->fakebase
|
|
||||||
instead</EM>. I suggest setting $fakebase = $GLOBALS['phpgw']->vfs->fakebase;
|
|
||||||
right off the bat to keep things neater.</P>
|
|
||||||
<HR>
|
|
||||||
<A HREF="vfs-7.html">Next</A>
|
|
||||||
<A HREF="vfs-5.html">Previous</A>
|
|
||||||
<A HREF="vfs.html#toc6">Contents</A>
|
|
||||||
</BODY>
|
|
||||||
</HTML>
|
|
@ -1,42 +0,0 @@
|
|||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
|
||||||
<HTML>
|
|
||||||
<HEAD>
|
|
||||||
<META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 0.9.17">
|
|
||||||
<TITLE>phpgwapi - VFS Class: About this Document</TITLE>
|
|
||||||
<LINK HREF="vfs-6.html" REL=previous>
|
|
||||||
<LINK HREF="vfs.html#toc7" REL=contents>
|
|
||||||
</HEAD>
|
|
||||||
<BODY>
|
|
||||||
Next
|
|
||||||
<A HREF="vfs-6.html">Previous</A>
|
|
||||||
<A HREF="vfs.html#toc7">Contents</A>
|
|
||||||
<HR>
|
|
||||||
<H2><A NAME="s7">7.</A> <A HREF="vfs.html#toc7">About this Document</A></H2>
|
|
||||||
|
|
||||||
<H2><A NAME="ss7.1">7.1</A> <A HREF="vfs.html#toc7.1">Copyright and License</A>
|
|
||||||
</H2>
|
|
||||||
|
|
||||||
<P>Copyright (c) 2001, 2002 Jason Wies</P>
|
|
||||||
<P>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.</P>
|
|
||||||
<P>A copy of the license is available at
|
|
||||||
<A HREF="http://www.gnu.org/copyleft/fdl.html">http://www.gnu.org/copyleft/fdl.html</A>.</P>
|
|
||||||
<H2><A NAME="ss7.2">7.2</A> <A HREF="vfs.html#toc7.2">History</A>
|
|
||||||
</H2>
|
|
||||||
|
|
||||||
<P>Original document released in June 2001 by Jason Wies.</P>
|
|
||||||
<P>Updated February 2002 to include arrayized parameters, single
|
|
||||||
quotes, and GLOBALS.</P>
|
|
||||||
<H2><A NAME="ss7.3">7.3</A> <A HREF="vfs.html#toc7.3">Contributing</A>
|
|
||||||
</H2>
|
|
||||||
|
|
||||||
maintainer, Jason Wies,
|
|
||||||
<HR>
|
|
||||||
Next
|
|
||||||
<A HREF="vfs-6.html">Previous</A>
|
|
||||||
<A HREF="vfs.html#toc7">Contents</A>
|
|
||||||
</BODY>
|
|
||||||
</HTML>
|
|
@ -1,72 +0,0 @@
|
|||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
|
||||||
<HTML>
|
|
||||||
<HEAD>
|
|
||||||
<META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 0.9.17">
|
|
||||||
<TITLE>phpgwapi - VFS Class</TITLE>
|
|
||||||
<LINK HREF="vfs-1.html" REL=next>
|
|
||||||
|
|
||||||
|
|
||||||
</HEAD>
|
|
||||||
<BODY>
|
|
||||||
<A HREF="vfs-1.html">Next</A>
|
|
||||||
Previous
|
|
||||||
Contents
|
|
||||||
<HR>
|
|
||||||
<H1>phpgwapi - VFS Class</H1>
|
|
||||||
|
|
||||||
<H2>Jason Wies</H2>June 2001, February 2002
|
|
||||||
<HR>
|
|
||||||
<EM>The VFS, or Virtual File System, handles all file system activity
|
|
||||||
for eGroupWare.</EM>
|
|
||||||
<HR>
|
|
||||||
<P>
|
|
||||||
<H2><A NAME="toc1">1.</A> <A HREF="vfs-1.html">Introduction and Purpose</A></H2>
|
|
||||||
|
|
||||||
<P>
|
|
||||||
<H2><A NAME="toc2">2.</A> <A HREF="vfs-2.html">Basics</A></H2>
|
|
||||||
|
|
||||||
<UL>
|
|
||||||
<LI><A NAME="toc2.1">2.1</A> <A HREF="vfs-2.html#ss2.1">Prerequisites</A>
|
|
||||||
<LI><A NAME="toc2.2">2.2</A> <A HREF="vfs-2.html#ss2.2">Concepts</A>
|
|
||||||
</UL>
|
|
||||||
<P>
|
|
||||||
<H2><A NAME="toc3">3.</A> <A HREF="vfs-3.html">Basic Functions</A></H2>
|
|
||||||
|
|
||||||
<UL>
|
|
||||||
<LI><A NAME="toc3.1">3.1</A> <A HREF="vfs-3.html#ss3.1">path_parts ()</A>
|
|
||||||
<LI><A NAME="toc3.2">3.2</A> <A HREF="vfs-3.html#ss3.2">cd ()</A>
|
|
||||||
</UL>
|
|
||||||
<P>
|
|
||||||
<H2><A NAME="toc4">4.</A> <A HREF="vfs-4.html">Relativity</A></H2>
|
|
||||||
|
|
||||||
<UL>
|
|
||||||
<LI><A NAME="toc4.1">4.1</A> <A HREF="vfs-4.html#ss4.1">What is it and how does it work?</A>
|
|
||||||
<LI><A NAME="toc4.2">4.2</A> <A HREF="vfs-4.html#ss4.2">Complete List</A>
|
|
||||||
<LI><A NAME="toc4.3">4.3</A> <A HREF="vfs-4.html#ss4.3">Defaults</A>
|
|
||||||
</UL>
|
|
||||||
<P>
|
|
||||||
<H2><A NAME="toc5">5.</A> <A HREF="vfs-5.html">Function reference</A></H2>
|
|
||||||
|
|
||||||
<P>
|
|
||||||
<H2><A NAME="toc6">6.</A> <A HREF="vfs-6.html">Notes</A></H2>
|
|
||||||
|
|
||||||
<UL>
|
|
||||||
<LI><A NAME="toc6.1">6.1</A> <A HREF="vfs-6.html#ss6.1">Database</A>
|
|
||||||
<LI><A NAME="toc6.2">6.2</A> <A HREF="vfs-6.html#ss6.2">ACL support</A>
|
|
||||||
<LI><A NAME="toc6.3">6.3</A> <A HREF="vfs-6.html#ss6.3">Function aliases</A>
|
|
||||||
<LI><A NAME="toc6.4">6.4</A> <A HREF="vfs-6.html#ss6.4">Fakebase directory (changing /home)</A>
|
|
||||||
</UL>
|
|
||||||
<P>
|
|
||||||
<H2><A NAME="toc7">7.</A> <A HREF="vfs-7.html">About this Document</A></H2>
|
|
||||||
|
|
||||||
<UL>
|
|
||||||
<LI><A NAME="toc7.1">7.1</A> <A HREF="vfs-7.html#ss7.1">Copyright and License</A>
|
|
||||||
<LI><A NAME="toc7.2">7.2</A> <A HREF="vfs-7.html#ss7.2">History</A>
|
|
||||||
<LI><A NAME="toc7.3">7.3</A> <A HREF="vfs-7.html#ss7.3">Contributing</A>
|
|
||||||
</UL>
|
|
||||||
<HR>
|
|
||||||
<A HREF="vfs-1.html">Next</A>
|
|
||||||
Previous
|
|
||||||
Contents
|
|
||||||
</BODY>
|
|
||||||
</HTML>
|
|
File diff suppressed because it is too large
Load Diff
@ -1,648 +0,0 @@
|
|||||||
<!doctype linuxdoc system>
|
|
||||||
|
|
||||||
<article>
|
|
||||||
<!-- LyX 1.1 created this file. For more info see http://www.lyx.org/ -->
|
|
||||||
<title>
|
|
||||||
phpgwapi - VFS Class
|
|
||||||
</title>
|
|
||||||
<author>
|
|
||||||
Jason Wies
|
|
||||||
</author>
|
|
||||||
<date>
|
|
||||||
June 2001, February 2002
|
|
||||||
</date>
|
|
||||||
<abstract>
|
|
||||||
The VFS, or Virtual File System, handles all file system activity
|
|
||||||
for eGoupWare.
|
|
||||||
</abstract>
|
|
||||||
<sect>
|
|
||||||
Introduction and Purpose<label id="sec:introduction" >
|
|
||||||
<p>
|
|
||||||
The latest version of the VFS for eGoupWare 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.
|
|
||||||
</p>
|
|
||||||
<sect>
|
|
||||||
Basics<label id="sec:basics" >
|
|
||||||
<sect1>
|
|
||||||
Prerequisites<label id="sec:prerequisites" >
|
|
||||||
<p>
|
|
||||||
You must explicitly enable the VFS class. To do this, set 'enable_vfs_class'
|
|
||||||
to True in $GLOBALS['phpgw_info']['flags'].
|
|
||||||
An example:
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<verb>
|
|
||||||
$GLOBALS['phpgw_info']['flags'] = array(
|
|
||||||
'currentapp' => 'phpwebhosting',
|
|
||||||
'noheader' => False,
|
|
||||||
'noappheader' => False,
|
|
||||||
'enable_vfs_class' => True,
|
|
||||||
'enable_browser_class' => True
|
|
||||||
);
|
|
||||||
</verb>
|
|
||||||
</p><sect1>
|
|
||||||
Concepts<label id="sec:concepts" >
|
|
||||||
<p>
|
|
||||||
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:
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<itemize>
|
|
||||||
<item>
|
|
||||||
Files and directories are synonymous in almost all cases
|
|
||||||
</itemize>
|
|
||||||
<p>
|
|
||||||
<verb>
|
|
||||||
$GLOBALS['phpgw']->vfs->mv (array(
|
|
||||||
'from' => 'file1',
|
|
||||||
'to' => 'dir/file2'
|
|
||||||
));
|
|
||||||
|
|
||||||
$GLOBALS['phpgw']->vfs->mv (array(
|
|
||||||
'from' => 'dir1',
|
|
||||||
'to' => 'dir/dir1'
|
|
||||||
));
|
|
||||||
|
|
||||||
$GLOBALS['phpgw']->vfs->rm (array(
|
|
||||||
'string' => 'file'
|
|
||||||
));
|
|
||||||
|
|
||||||
$GLOBALS['phpgw']->vfs->rm (array(
|
|
||||||
'string' => 'dir'
|
|
||||||
));
|
|
||||||
</verb>
|
|
||||||
</p><p>
|
|
||||||
All work as you would except them to. The major exception is:
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<verb>
|
|
||||||
$GLOBALS['phpgw']->vfs->touch (array(
|
|
||||||
'string' => 'file'
|
|
||||||
));
|
|
||||||
</verb>
|
|
||||||
</p><p>
|
|
||||||
vs.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<verb>
|
|
||||||
$GLOBALS['phpgw']->vfs->mkdir (array(
|
|
||||||
'string' => 'dir'
|
|
||||||
));
|
|
||||||
|
|
||||||
</verb>
|
|
||||||
<p>
|
|
||||||
<itemize>
|
|
||||||
<item>
|
|
||||||
Users and groups are synonymous
|
|
||||||
</itemize>
|
|
||||||
</p><p>
|
|
||||||
As far as the actual paths are concerned, users and groups are
|
|
||||||
the same. /home/username works the same as /home/groupname.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<itemize>
|
|
||||||
<item>
|
|
||||||
You should never have to know the real paths of files
|
|
||||||
</itemize>
|
|
||||||
</p><p>
|
|
||||||
One of the VFS's responsibilities is to translate paths for you.
|
|
||||||
While you certainly <em>can</em> operate using full paths, it is much simpler
|
|
||||||
to use the virtual paths. For example, instead of using:
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<verb>
|
|
||||||
$GLOBALS['phpgw']->vfs->cp (array(
|
|
||||||
'from' => '/var/www/egroupware/files/home/user/file1',
|
|
||||||
'to' => '/var/www/egroupware/files/home/user/file2',
|
|
||||||
'relatives' => array(
|
|
||||||
RELATIVE_NONE|VFS_REAL,
|
|
||||||
RELATIVE_NONE|VFS_REAL
|
|
||||||
)
|
|
||||||
));
|
|
||||||
</verb>
|
|
||||||
</p><p>
|
|
||||||
you might use
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<verb>
|
|
||||||
$GLOBALS['phpgw']->vfs->cp (array(
|
|
||||||
'from' => '/home/user/file1',
|
|
||||||
'to' => '/home/user/file2',
|
|
||||||
'relatives' => array(
|
|
||||||
RELATIVE_NONE,
|
|
||||||
RELATIVE_NONE
|
|
||||||
)
|
|
||||||
));
|
|
||||||
</verb>
|
|
||||||
</p><p>
|
|
||||||
(We'll get to the RELATIVE's in a minute.)
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Site administrators should be able to move their files dir around
|
|
||||||
on their system and know that everything will continue to work smoothly.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<itemize>
|
|
||||||
<item>
|
|
||||||
Relativity is <em>vital</em>
|
|
||||||
</itemize>
|
|
||||||
</p><p>
|
|
||||||
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.
|
|
||||||
</p>
|
|
||||||
<sect>
|
|
||||||
Basic Functions<label id="sec:basic_functions" >
|
|
||||||
<p>
|
|
||||||
These are two functions you'll need to know before we get into
|
|
||||||
relativity.
|
|
||||||
</p>
|
|
||||||
<sect1>
|
|
||||||
path_parts ()<label id="sec:path_parts" >
|
|
||||||
<p>
|
|
||||||
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:
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<verb>
|
|
||||||
string
|
|
||||||
relatives
|
|
||||||
object
|
|
||||||
</verb>
|
|
||||||
</p><p>
|
|
||||||
'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:
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<verb>
|
|
||||||
fake_full_path
|
|
||||||
fake_leading_dirs
|
|
||||||
fake_extra_path
|
|
||||||
fake_name
|
|
||||||
real_full_path
|
|
||||||
real_leading_dirs
|
|
||||||
real_extra_path
|
|
||||||
real_name
|
|
||||||
</verb>
|
|
||||||
</p><p>
|
|
||||||
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 "home" to the end of the leading_dirs. To better
|
|
||||||
illustrate, here is an example:
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<verb>
|
|
||||||
$p = $GLOBALS['phpgw']->vfs->path_parts (array(
|
|
||||||
'string' => '/home/jason/dir/file',
|
|
||||||
'relatives' => array(
|
|
||||||
RELATIVE_NONE
|
|
||||||
)
|
|
||||||
));
|
|
||||||
</verb>
|
|
||||||
<p>
|
|
||||||
<itemize>
|
|
||||||
<item>
|
|
||||||
$p->fake_full_path - /home/jason/dir/file
|
|
||||||
<item>
|
|
||||||
$p->fake_leading_dirs - /home/jason/dir
|
|
||||||
<item>
|
|
||||||
$p->fake_extra_path - home/jason/dir
|
|
||||||
<item>
|
|
||||||
$p->fake_name - file
|
|
||||||
<item>
|
|
||||||
$p->real_full_path - /var/www/egroupware/files/home/jason/dir/file
|
|
||||||
<item>
|
|
||||||
$p->real_leading_dirs - /var/www/egroupware/files/home/jason/dir
|
|
||||||
|
|
||||||
<item>
|
|
||||||
$p->real_extra_path - home/jason/dir
|
|
||||||
<item>
|
|
||||||
$p->real_name - file
|
|
||||||
</itemize>
|
|
||||||
</p><p>
|
|
||||||
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 <em>getabsolutepath () is depreciated</em>.
|
|
||||||
getabsolutepath () still exists (albeit in a much different form),
|
|
||||||
and is responsible for some of the path translation, but it is an
|
|
||||||
<em>internal</em> 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.
|
|
||||||
</p>
|
|
||||||
<sect1>
|
|
||||||
cd ()<label id="sec:cd" >
|
|
||||||
<p>
|
|
||||||
Part of the overall goal for the VFS in eGoupWare 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:
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<verb>
|
|
||||||
/* cd to their home directory */
|
|
||||||
$GLOBALS['phpgw']->vfs->cd (array(
|
|
||||||
'string' => '/'
|
|
||||||
));
|
|
||||||
|
|
||||||
/* cd to /home/jason/dir */
|
|
||||||
$GLOBALS['phpgw']->vfs->cd (array(
|
|
||||||
'string' => '/home/jason/dir',
|
|
||||||
'relative' => False,
|
|
||||||
'relatives' => array(
|
|
||||||
RELATIVE_NONE
|
|
||||||
)
|
|
||||||
));
|
|
||||||
|
|
||||||
/* When following the above, cd's to /home/jason/dir/dir2 */
|
|
||||||
$GLOBALS['phpgw']->vfs->cd (array(
|
|
||||||
'string' => 'dir2',
|
|
||||||
'relative' => True
|
|
||||||
));
|
|
||||||
</verb>
|
|
||||||
</p><p>
|
|
||||||
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
|
|
||||||
().
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Now you're ready for relativity.
|
|
||||||
</p>
|
|
||||||
<sect>
|
|
||||||
Relativity<label id="sec:relativity" >
|
|
||||||
<p>
|
|
||||||
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
|
|
||||||
<ref id="sec:fakebase" name="Fakebase directory (changing /home)" > 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. <em>You should always use $fakebase when
|
|
||||||
making applications. </em>I suggest doing $fakebase = $GLOBALS['phpgw']->vfs->fakebase;
|
|
||||||
right off the bat to keep things neater.
|
|
||||||
</p>
|
|
||||||
<sect1>
|
|
||||||
What is it and how does it work?
|
|
||||||
<p>
|
|
||||||
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 eGoupWare 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.
|
|
||||||
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<verb>
|
|
||||||
$GLOBALS['phpgw']->vfs->mv (array(
|
|
||||||
'from' => 'logo.png',
|
|
||||||
'to' => 'logo.png',
|
|
||||||
'relatives' => array(
|
|
||||||
RELATIVE_USER,
|
|
||||||
RELATIVE_ALL
|
|
||||||
)
|
|
||||||
));
|
|
||||||
</verb>
|
|
||||||
</p><p>
|
|
||||||
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 "$fakebase/my_group/project1",
|
|
||||||
the call to mv () would be processed as:
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<verb>
|
|
||||||
MOVE "$fakebase/jason/logo.png" TO "$fakebase/my_group/project1/logo.png"
|
|
||||||
</verb>
|
|
||||||
</p><p>
|
|
||||||
and the actual file system call would be:
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<verb>
|
|
||||||
rename ('/var/www/egroupware/files/home/jason/logo.php', '/var/www/egroupware/files/home/my_group/project1/logo.png');
|
|
||||||
</verb>
|
|
||||||
</p><p>
|
|
||||||
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 eGoupWare'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 <em>outside</em> the virtual root.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<verb>
|
|
||||||
$GLOBALS['phpgw']->vfs->mv (array(
|
|
||||||
'from' => $GLOBALS['phpgw_info']['server']['temp_dir'] . '/' . $randomdir . '/' . $randomfile,
|
|
||||||
'to' => 'attachments/actual_name.ext',
|
|
||||||
'relatives' => array(
|
|
||||||
RELATIVE_NONE|VFS_REAL,
|
|
||||||
RELATIVE_USER
|
|
||||||
)
|
|
||||||
));
|
|
||||||
</verb>
|
|
||||||
</p><p>
|
|
||||||
$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 <em>outside</em> 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):
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<verb>
|
|
||||||
rename ('/var/www/egroupware/tmp/0ak5adftgh7/jX42sC9M', '/var/www/egroupware/files/home/jason/attachments/actual_name.ext');
|
|
||||||
</verb>
|
|
||||||
</p><p>
|
|
||||||
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:
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<verb>
|
|
||||||
$GLOBALS['phpgw']->vfs->write (array(
|
|
||||||
'string' => 'file.name˜',
|
|
||||||
'relatives' => array(
|
|
||||||
RELATIVE_USER_APP
|
|
||||||
),
|
|
||||||
'content' => $contents
|
|
||||||
));
|
|
||||||
</verb>
|
|
||||||
</p><p>
|
|
||||||
This assumes that ˜/.htmledit exists of course. The backup
|
|
||||||
file "file.name˜" 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.
|
|
||||||
</p>
|
|
||||||
<sect1>
|
|
||||||
Complete List<label id="sec:relatives_complete_list" >
|
|
||||||
<p>
|
|
||||||
Here is the complete list of RELATIVE defines, and what they
|
|
||||||
do:
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<descrip>
|
|
||||||
<tag>
|
|
||||||
RELATIVE_ROOT</tag>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.
|
|
||||||
<tag>
|
|
||||||
RELATIVE_USER</tag>User's home directory
|
|
||||||
<tag>
|
|
||||||
RELATIVE_CURR_USER</tag>Current user's home directory. If the
|
|
||||||
current directory is $fakebase/my_group/project1, this will
|
|
||||||
return is $fakebase/my_group
|
|
||||||
<tag>
|
|
||||||
RELATIVE_USER_APP</tag>Append .appname to the user's home directory,
|
|
||||||
where appname is the current application's appname
|
|
||||||
<tag>
|
|
||||||
RELATIVE_PATH</tag>DO NOT USE. Relative to the current directory,
|
|
||||||
used in RELATIVE_ALL
|
|
||||||
<tag>
|
|
||||||
RELATIVE_NONE</tag>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
|
|
||||||
<tag>
|
|
||||||
RELATIVE_CURRENT</tag>An alias for the currently set RELATIVE
|
|
||||||
define, or RELATIVE_ALL if none is set (see the Defaults section)
|
|
||||||
<tag>
|
|
||||||
VFS_REAL</tag>File is outside of the virtual root. Usually used
|
|
||||||
with RELATIVE_NONE
|
|
||||||
<tag>
|
|
||||||
RELATIVE_ALL</tag>Relative to the current directory. Use RELATIVE_ALL<em>
|
|
||||||
</em>instead of RELATIVE_PATH
|
|
||||||
</descrip>
|
|
||||||
</p><sect1>
|
|
||||||
Defaults<label id="sec:relatives_defaults" >
|
|
||||||
<p>
|
|
||||||
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), <em>unless</em> 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:
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<verb>
|
|
||||||
$GLOBALS['phpgw']->vfs->set_relative (array(
|
|
||||||
'mask' => RELATIVE_NONE|VFS_REAL
|
|
||||||
));
|
|
||||||
|
|
||||||
$GLOBALS['phpgw']->vfs->read (array(
|
|
||||||
'string' => '/etc/passwd'
|
|
||||||
));
|
|
||||||
|
|
||||||
$GLOBALS['phpgw']->vfs->cp (array(
|
|
||||||
'from' => '/usr/include/stdio.h',
|
|
||||||
'to' => '/tmp/stdio.h'
|
|
||||||
));
|
|
||||||
|
|
||||||
$GLOBALS['phpgw']->vfs->cp (array(
|
|
||||||
'from' => '/usr/share/pixmaps/yes.xpm',
|
|
||||||
'to' => 'icons/yes.xpm',
|
|
||||||
'relatives' => array(
|
|
||||||
RELATIVE_CURRENT,
|
|
||||||
RELATIVE_USER
|
|
||||||
)
|
|
||||||
));
|
|
||||||
</verb>
|
|
||||||
</p><p>
|
|
||||||
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.
|
|
||||||
</p>
|
|
||||||
<sect>
|
|
||||||
Function reference<label id="sec:function_reference" >
|
|
||||||
<p>
|
|
||||||
To view the function reference for the VFS, use the doc/inlinedocparser.php
|
|
||||||
script that comes with eGoupWare, ie <url url="http://localhost/doc/inlinedocparser.php?fn=class.vfs_sql.inc.php" name="http://localhost/doc/inlinedocparser.php?fn=class.vfs_sql.inc.php">.
|
|
||||||
</p>
|
|
||||||
<sect>
|
|
||||||
Notes<label id="sec:notes" >
|
|
||||||
<sect1>
|
|
||||||
Database<label id="sec:database" >
|
|
||||||
<p>
|
|
||||||
Data about the files and directories within the virtual root
|
|
||||||
is kept in the SQL database. Currently, this information includes:
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<itemize>
|
|
||||||
<item>
|
|
||||||
File ID (used internally, primary key for table)
|
|
||||||
<item>
|
|
||||||
Owner ID (phpGW account_id)
|
|
||||||
<item>
|
|
||||||
Created by ID (phpGW account_id)
|
|
||||||
<item>
|
|
||||||
Modified by ID (phpGW account_id)
|
|
||||||
<item>
|
|
||||||
Created (date)
|
|
||||||
<item>
|
|
||||||
Modified (date)
|
|
||||||
<item>
|
|
||||||
Size (bytes)
|
|
||||||
<item>
|
|
||||||
MIME type
|
|
||||||
<item>
|
|
||||||
Deleteable (Y/N/Other?)
|
|
||||||
<item>
|
|
||||||
Comment
|
|
||||||
<item>
|
|
||||||
App (appname of application that created the file)
|
|
||||||
<item>
|
|
||||||
Directory (directory the file or directory is in)
|
|
||||||
<item>
|
|
||||||
Name (name of file or directory)
|
|
||||||
<item>
|
|
||||||
Link directory (if the file or directory is linked, what the
|
|
||||||
actual directory is)
|
|
||||||
<item>
|
|
||||||
Link name (if the file or directory is linked, what the actual
|
|
||||||
name is)
|
|
||||||
<item>
|
|
||||||
Version (numeric version of the file)
|
|
||||||
</itemize>
|
|
||||||
</p><p>
|
|
||||||
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.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
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.
|
|
||||||
</p>
|
|
||||||
<sect1>
|
|
||||||
ACL support<label id="sec:acl_support" >
|
|
||||||
<p>
|
|
||||||
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:
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<verb>
|
|
||||||
$GLOBALS['phpgw']->vfs->override_acl = 1;
|
|
||||||
$GLOBALS['phpgw']->vfs->mkdir (array(
|
|
||||||
'string' => $GLOBALS['fakebase']. '/' . $group_array['account_name'],
|
|
||||||
'relatives' => array(
|
|
||||||
RELATIVE_NONE
|
|
||||||
)
|
|
||||||
));
|
|
||||||
$GLOBALS['phpgw']->vfs->override_acl = 0;
|
|
||||||
</verb>
|
|
||||||
</p><sect1>
|
|
||||||
Function aliases<label id="sec:function_aliases" >
|
|
||||||
<p>
|
|
||||||
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):
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<itemize>
|
|
||||||
<item>
|
|
||||||
copy -> cp
|
|
||||||
<item>
|
|
||||||
move -> rm
|
|
||||||
<item>
|
|
||||||
delete -> rm
|
|
||||||
<item>
|
|
||||||
dir -> ls
|
|
||||||
</itemize>
|
|
||||||
</p><sect1>
|
|
||||||
Fakebase directory (changing /home)<label id="sec:fakebase" >
|
|
||||||
<p>
|
|
||||||
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 <em>before</em> 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. <em>Application programmers need to recognize that /home is
|
|
||||||
not absolute, and use $GLOBALS['phpgw']->vfs->fakebase
|
|
||||||
instead</em>. I suggest setting $fakebase = $GLOBALS['phpgw']->vfs->fakebase;
|
|
||||||
right off the bat to keep things neater.
|
|
||||||
</p>
|
|
||||||
<sect>
|
|
||||||
About this Document
|
|
||||||
<sect1>
|
|
||||||
Copyright and License
|
|
||||||
<p>
|
|
||||||
Copyright (c) 2001, 2002 Jason Wies
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
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.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
A copy of the license is available at <url url="http://www.gnu.org/copyleft/fdl.html" name="http://www.gnu.org/copyleft/fdl.html">.
|
|
||||||
</p>
|
|
||||||
<sect1>
|
|
||||||
History
|
|
||||||
<p>
|
|
||||||
Original document released in June 2001 by Jason Wies.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Updated February 2002 to include arrayized parameters, single
|
|
||||||
quotes, and GLOBALS.
|
|
||||||
</p>
|
|
||||||
<sect1>
|
|
||||||
Contributing
|
|
||||||
<p>
|
|
||||||
Contributions are always welcome. Please send to the current
|
|
||||||
maintainer, Jason Wies,
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
</article>
|
|
@ -1,425 +0,0 @@
|
|||||||
|
|
||||||
Next Previous Contents
|
|
||||||
===============================================================================
|
|
||||||
***** 1. Introduction_and_Purpose *****
|
|
||||||
The latest version of the VFS for eGoupWare 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.
|
|
||||||
===============================================================================
|
|
||||||
Next Previous Contents
|
|
||||||
|
|
||||||
|
|
||||||
Next Previous Contents
|
|
||||||
===============================================================================
|
|
||||||
***** 2. Basics *****
|
|
||||||
***** 2.1 Prerequisites *****
|
|
||||||
You must explicitly enable the VFS class. To do this, set 'enable_vfs_class' to
|
|
||||||
True in $GLOBALS['phpgw_info']['flags']. An example:
|
|
||||||
$GLOBALS['phpgw_info']['flags'] = array(
|
|
||||||
'currentapp' => 'phpwebhosting',
|
|
||||||
'noheader' => False,
|
|
||||||
'noappheader' => False,
|
|
||||||
'enable_vfs_class' => True,
|
|
||||||
'enable_browser_class' => True
|
|
||||||
);
|
|
||||||
***** 2.2 Concepts *****
|
|
||||||
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:
|
|
||||||
* Files and directories are synonymous in almost all cases
|
|
||||||
$GLOBALS['phpgw']->vfs->mv (array(
|
|
||||||
'from' => 'file1',
|
|
||||||
'to' => 'dir/file2'
|
|
||||||
));
|
|
||||||
|
|
||||||
$GLOBALS['phpgw']->vfs->mv (array(
|
|
||||||
'from' => 'dir1',
|
|
||||||
'to' => 'dir/dir1'
|
|
||||||
));
|
|
||||||
|
|
||||||
$GLOBALS['phpgw']->vfs->rm (array(
|
|
||||||
'string' => 'file'
|
|
||||||
));
|
|
||||||
|
|
||||||
$GLOBALS['phpgw']->vfs->rm (array(
|
|
||||||
'string' => 'dir'
|
|
||||||
));
|
|
||||||
All work as you would except them to. The major exception is:
|
|
||||||
$GLOBALS['phpgw']->vfs->touch (array(
|
|
||||||
'string' => 'file'
|
|
||||||
));
|
|
||||||
vs.
|
|
||||||
$GLOBALS['phpgw']->vfs->mkdir (array(
|
|
||||||
'string' => 'dir'
|
|
||||||
));
|
|
||||||
* Users and groups are synonymous
|
|
||||||
As far as the actual paths are concerned, users and groups are the same. /home/
|
|
||||||
username works the same as /home/groupname.
|
|
||||||
* You should never have to know the real paths of files
|
|
||||||
One of the VFS's responsibilities is to translate paths for you. While you
|
|
||||||
certainly can operate using full paths, it is much simpler to use the virtual
|
|
||||||
paths. For example, instead of using:
|
|
||||||
$GLOBALS['phpgw']->vfs->cp (array(
|
|
||||||
'from' => '/var/www/egroupware/files/home/user/file1',
|
|
||||||
'to' => '/var/www/egroupware/files/home/user/file2',
|
|
||||||
'relatives' => array(
|
|
||||||
RELATIVE_NONE|VFS_REAL,
|
|
||||||
RELATIVE_NONE|VFS_REAL
|
|
||||||
)
|
|
||||||
));
|
|
||||||
you might use
|
|
||||||
$GLOBALS['phpgw']->vfs->cp (array(
|
|
||||||
'from' => '/home/user/file1',
|
|
||||||
'to' => '/home/user/file2',
|
|
||||||
'relatives' => array(
|
|
||||||
RELATIVE_NONE,
|
|
||||||
RELATIVE_NONE
|
|
||||||
)
|
|
||||||
));
|
|
||||||
(We'll get to the RELATIVE's in a minute.)
|
|
||||||
Site administrators should be able to move their files dir around on their
|
|
||||||
system and know that everything will continue to work smoothly.
|
|
||||||
* Relativity is vital
|
|
||||||
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.
|
|
||||||
===============================================================================
|
|
||||||
Next Previous Contents
|
|
||||||
|
|
||||||
|
|
||||||
Next Previous Contents
|
|
||||||
===============================================================================
|
|
||||||
***** 3. Basic_Functions *****
|
|
||||||
These are two functions you'll need to know before we get into relativity.
|
|
||||||
***** 3.1 path_parts_() *****
|
|
||||||
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:
|
|
||||||
string
|
|
||||||
relatives
|
|
||||||
object
|
|
||||||
'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:
|
|
||||||
fake_full_path
|
|
||||||
fake_leading_dirs
|
|
||||||
fake_extra_path
|
|
||||||
fake_name
|
|
||||||
real_full_path
|
|
||||||
real_leading_dirs
|
|
||||||
real_extra_path
|
|
||||||
real_name
|
|
||||||
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 "home" to the end of
|
|
||||||
the leading_dirs. To better illustrate, here is an example:
|
|
||||||
$p = $GLOBALS['phpgw']->vfs->path_parts (array(
|
|
||||||
'string' => '/home/jason/dir/file',
|
|
||||||
'relatives' => array(
|
|
||||||
RELATIVE_NONE
|
|
||||||
)
|
|
||||||
));
|
|
||||||
* $p->fake_full_path - /home/jason/dir/file
|
|
||||||
* $p->fake_leading_dirs - /home/jason/dir
|
|
||||||
* $p->fake_extra_path - home/jason/dir
|
|
||||||
* $p->fake_name - file
|
|
||||||
* $p->real_full_path - /var/www/egroupware/files/home/jason/dir/file
|
|
||||||
* $p->real_leading_dirs - /var/www/egroupware/files/home/jason/dir
|
|
||||||
* $p->real_extra_path - home/jason/dir
|
|
||||||
* $p->real_name - file
|
|
||||||
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 getabsolutepath () is depreciated. getabsolutepath () still exists
|
|
||||||
(albeit in a much different form), and is responsible for some of the path
|
|
||||||
translation, but it is an internal 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.
|
|
||||||
***** 3.2 cd_() *****
|
|
||||||
Part of the overall goal for the VFS in eGoupWare 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:
|
|
||||||
/* cd to their home directory */
|
|
||||||
$GLOBALS['phpgw']->vfs->cd (array(
|
|
||||||
'string' => '/'
|
|
||||||
));
|
|
||||||
|
|
||||||
/* cd to /home/jason/dir */
|
|
||||||
$GLOBALS['phpgw']->vfs->cd (array(
|
|
||||||
'string' => '/home/jason/dir',
|
|
||||||
'relative' => False,
|
|
||||||
'relatives' => array(
|
|
||||||
RELATIVE_NONE
|
|
||||||
)
|
|
||||||
));
|
|
||||||
|
|
||||||
/* When following the above, cd's to /home/jason/dir/dir2 */
|
|
||||||
$GLOBALS['phpgw']->vfs->cd (array(
|
|
||||||
'string' => 'dir2',
|
|
||||||
'relative' => True
|
|
||||||
));
|
|
||||||
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 ().
|
|
||||||
Now you're ready for relativity.
|
|
||||||
===============================================================================
|
|
||||||
Next Previous Contents
|
|
||||||
|
|
||||||
|
|
||||||
Next Previous Contents
|
|
||||||
===============================================================================
|
|
||||||
***** 4. Relativity *****
|
|
||||||
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 Fakebase_directory_
|
|
||||||
(changing_/home) 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. You should always use $fakebase when making applications.I
|
|
||||||
suggest doing $fakebase = $GLOBALS['phpgw']->vfs->fakebase; right off the bat
|
|
||||||
to keep things neater.
|
|
||||||
***** 4.1 What_is_it_and_how_does_it_work? *****
|
|
||||||
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
|
|
||||||
eGoupWare 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.
|
|
||||||
$GLOBALS['phpgw']->vfs->mv (array(
|
|
||||||
'from' => 'logo.png',
|
|
||||||
'to' => 'logo.png',
|
|
||||||
'relatives' => array(
|
|
||||||
RELATIVE_USER,
|
|
||||||
RELATIVE_ALL
|
|
||||||
)
|
|
||||||
));
|
|
||||||
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 "$fakebase/my_group/project1", the call to mv
|
|
||||||
() would be processed as:
|
|
||||||
MOVE "$fakebase/jason/logo.png" TO "$fakebase/my_group/project1/logo.png"
|
|
||||||
and the actual file system call would be:
|
|
||||||
rename ('/var/www/egroupware/files/home/jason/logo.php', '/var/www/
|
|
||||||
egroupware/files/home/my_group/project1/logo.png');
|
|
||||||
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 eGoupWare'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 outside the virtual
|
|
||||||
root.
|
|
||||||
$GLOBALS['phpgw']->vfs->mv (array(
|
|
||||||
'from' => $GLOBALS['phpgw_info']['server']['temp_dir'] . '/' . $randomdir
|
|
||||||
. '/' . $randomfile,
|
|
||||||
'to' => 'attachments/actual_name.ext',
|
|
||||||
'relatives' => array(
|
|
||||||
RELATIVE_NONE|VFS_REAL,
|
|
||||||
RELATIVE_USER
|
|
||||||
)
|
|
||||||
));
|
|
||||||
$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 outside 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):
|
|
||||||
rename ('/var/www/egroupware/tmp/0ak5adftgh7/jX42sC9M', '/var/www/
|
|
||||||
egroupware/files/home/jason/attachments/actual_name.ext');
|
|
||||||
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:
|
|
||||||
$GLOBALS['phpgw']->vfs->write (array(
|
|
||||||
'string' => 'file.name~',
|
|
||||||
'relatives' => array(
|
|
||||||
RELATIVE_USER_APP
|
|
||||||
),
|
|
||||||
'content' => $contents
|
|
||||||
));
|
|
||||||
This assumes that ~/.htmledit exists of course. The backup file "file.name~"
|
|
||||||
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.
|
|
||||||
***** 4.2 Complete_List *****
|
|
||||||
Here is the complete list of RELATIVE defines, and what they do:
|
|
||||||
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.
|
|
||||||
RELATIVE_USER
|
|
||||||
User's home directory
|
|
||||||
RELATIVE_CURR_USER
|
|
||||||
Current user's home directory. If the current directory is $fakebase/
|
|
||||||
my_group/project1, this will return is $fakebase/my_group
|
|
||||||
RELATIVE_USER_APP
|
|
||||||
Append .appname to the user's home directory, where appname is the
|
|
||||||
current application's appname
|
|
||||||
RELATIVE_PATH
|
|
||||||
DO NOT USE. Relative to the current directory, used in RELATIVE_ALL
|
|
||||||
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
|
|
||||||
RELATIVE_CURRENT
|
|
||||||
An alias for the currently set RELATIVE define, or RELATIVE_ALL if none
|
|
||||||
is set (see the Defaults section)
|
|
||||||
VFS_REAL
|
|
||||||
File is outside of the virtual root. Usually used with RELATIVE_NONE
|
|
||||||
RELATIVE_ALL
|
|
||||||
Relative to the current directory. Use RELATIVE_ALLinstead of
|
|
||||||
RELATIVE_PATH
|
|
||||||
***** 4.3 Defaults *****
|
|
||||||
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), unless 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:
|
|
||||||
$GLOBALS['phpgw']->vfs->set_relative (array(
|
|
||||||
'mask' => RELATIVE_NONE|VFS_REAL
|
|
||||||
));
|
|
||||||
|
|
||||||
$GLOBALS['phpgw']->vfs->read (array(
|
|
||||||
'string' => '/etc/passwd'
|
|
||||||
));
|
|
||||||
|
|
||||||
$GLOBALS['phpgw']->vfs->cp (array(
|
|
||||||
'from' => '/usr/include/stdio.h',
|
|
||||||
'to' => '/tmp/stdio.h'
|
|
||||||
));
|
|
||||||
|
|
||||||
$GLOBALS['phpgw']->vfs->cp (array(
|
|
||||||
'from' => '/usr/share/pixmaps/yes.xpm',
|
|
||||||
'to' => 'icons/yes.xpm',
|
|
||||||
'relatives' => array(
|
|
||||||
RELATIVE_CURRENT,
|
|
||||||
RELATIVE_USER
|
|
||||||
)
|
|
||||||
));
|
|
||||||
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.
|
|
||||||
===============================================================================
|
|
||||||
Next Previous Contents
|
|
||||||
|
|
||||||
|
|
||||||
Next Previous Contents
|
|
||||||
===============================================================================
|
|
||||||
***** 5. Function_reference *****
|
|
||||||
To view the function reference for the VFS, use the doc/inlinedocparser.php
|
|
||||||
script that comes with eGoupWare, ie http://localhost/doc/
|
|
||||||
inlinedocparser.php?fn=class.vfs_sql.inc.php.
|
|
||||||
===============================================================================
|
|
||||||
Next Previous Contents
|
|
||||||
|
|
||||||
|
|
||||||
Next Previous Contents
|
|
||||||
===============================================================================
|
|
||||||
***** 6. Notes *****
|
|
||||||
***** 6.1 Database *****
|
|
||||||
Data about the files and directories within the virtual root is kept in the SQL
|
|
||||||
database. Currently, this information includes:
|
|
||||||
* File ID (used internally, primary key for table)
|
|
||||||
* Owner ID (phpGW account_id)
|
|
||||||
* Created by ID (phpGW account_id)
|
|
||||||
* Modified by ID (phpGW account_id)
|
|
||||||
* Created (date)
|
|
||||||
* Modified (date)
|
|
||||||
* Size (bytes)
|
|
||||||
* MIME type
|
|
||||||
* Deleteable (Y/N/Other?)
|
|
||||||
* Comment
|
|
||||||
* App (appname of application that created the file)
|
|
||||||
* Directory (directory the file or directory is in)
|
|
||||||
* Name (name of file or directory)
|
|
||||||
* Link directory (if the file or directory is linked, what the actual
|
|
||||||
directory is)
|
|
||||||
* Link name (if the file or directory is linked, what the actual name is)
|
|
||||||
* Version (numeric version of the file)
|
|
||||||
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.
|
|
||||||
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.
|
|
||||||
***** 6.2 ACL_support *****
|
|
||||||
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:
|
|
||||||
$GLOBALS['phpgw']->vfs->override_acl = 1;
|
|
||||||
$GLOBALS['phpgw']->vfs->mkdir (array(
|
|
||||||
'string' => $GLOBALS['fakebase']. '/' . $group_array['account_name'],
|
|
||||||
'relatives' => array(
|
|
||||||
RELATIVE_NONE
|
|
||||||
)
|
|
||||||
));
|
|
||||||
$GLOBALS['phpgw']->vfs->override_acl = 0;
|
|
||||||
***** 6.3 Function_aliases *****
|
|
||||||
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):
|
|
||||||
* copy -> cp
|
|
||||||
* move -> rm
|
|
||||||
* delete -> rm
|
|
||||||
* dir -> ls
|
|
||||||
***** 6.4 Fakebase_directory_(changing_/home) *****
|
|
||||||
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 before 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. Application
|
|
||||||
programmers need to recognize that /home is not absolute, and use $GLOBALS
|
|
||||||
['phpgw']->vfs->fakebase instead. I suggest setting $fakebase = $GLOBALS
|
|
||||||
['phpgw']->vfs->fakebase; right off the bat to keep things neater.
|
|
||||||
===============================================================================
|
|
||||||
Next Previous Contents
|
|
||||||
|
|
||||||
Next Previous Contents
|
|
||||||
===============================================================================
|
|
||||||
***** 7. About_this_Document *****
|
|
||||||
***** 7.1 Copyright_and_License *****
|
|
||||||
Copyright (c) 2001, 2002 Jason Wies
|
|
||||||
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.
|
|
||||||
A copy of the license is available at http://www.gnu.org/copyleft/fdl.html.
|
|
||||||
***** 7.2 History *****
|
|
||||||
Original document released in June 2001 by Jason Wies.
|
|
||||||
Updated February 2002 to include arrayized parameters, single quotes, and
|
|
||||||
GLOBALS.
|
|
||||||
***** 7.3 Contributing *****
|
|
||||||
Contributions are always welcome. Please send to the current maintainer, Jason
|
|
||||||
Wies,
|
|
||||||
===============================================================================
|
|
||||||
Next Previous Contents
|
|
Loading…
Reference in New Issue
Block a user