Contents
1. ApplicationDevelopmentGuide/Introduction
1. Overview of
application writing
2. What does the
eGroupWare API provide?
2. ApplicationDevelopmentGuide/Guidelines
1. Requirements
2. Writing/porting
your application
3. ApplicationDevelopmentGuide/InstallingYourApplication
1. Overview
2. Automatic features
3. Adding files,
directories and icons.
4. Making eGroupWare
aware of your application
5. Hooking into
Administration page
6. Hooking into
Preferences page
4. ApplicationDevelopmentGuide/Infrastructure
1. Overview
2. Directory tree
3. Translations
5. ApplicationDevelopmentGuide/APIGuide
1. API Hooks
2. API index.php
3. API setup
4. API templates
5. API-BO
6. API-SO
7. API-UI
8. Deprecated APIs
6. ApplicationDevelopmentGuide/APIFunctions
1. Introduction
2. Basic functions
3. Application
Functions
4. File functions
5. Email/NNTP Functions
6. Content History
7. ApplicationDevelopmentGuide/ConfigurationVariables
1. Introduction
2. User information
3. Group information
4. Server information
5. Database information
6. Mail information
7. NNTP information
8. Application
information
8. ApplicationDevelopmentGuide/UsingLanguageSupport
1. Overview
2. How to use lang
support
3. Common return codes
9. ApplicationDevelopmentGuide/UsingTemplates
1. Overview
2. How to use PHPLIB
templates
10. ApplicationDevelopmentGuide/eTemplateReferenz
1. Introduction - The
concept of the eTemplates
2. The xml-interface
to the eTemplates
3. Syntax and
Parameter Referenz
4. How to implement
new widgets / extensions to the eTemplates?
Installing your application
Overview
It is fairly simple to add and delete applications to/from eGroupWare.
Adding files, directories and icons.
Guidelines
Requirements
Introduction
eGroupWare is a web based groupware application framework (API), for
writing applications. Integrated applications such as email, calendar,
todo list, address book, and file manager are included.
Overview of application writing
We have attempted to make writing application for eGroupWare as
painless as possible. We hope any pain and suffering is cause by making
your application work, but not dealing with eGroupWare itself.
What does the eGroupWare API provide?
The eGroupWare API handles session management, user/group management,
has support for multiple databases, using the PHPLIB database
abstraction method, we support templates using the PHPLIB Templates
class, a file system interface, and even a network i/o interface.
On top of these standard functions, eGroupWare provides several
functions to give you the information you need about the users
environment, and to properly plug into eGroupWare.
These guidelines must be followed for any application that wants
considered for inclusion into eGroupWare deluxe:
* It must run on PHP4.1.0
* SQL statements must be compatible with both MySQL,
PostgreSQL, M$ SQL Server and MaxDB
* It must use our default header.inc.php include.
* It must use our $GLOBALS['phpgw']->link($url)
for all links (this is for session support).
* It must use "POST" for form submit methods.
* It must respect eGW group rights and eGW user
permissions.
* It must use our directory structure, template
support and lang (multi-language) support.
* Where possible it should run on both Unix and NT
platforms.
* For applications that do not meet these
requirements, they can be available to users via the eGroupWare "3rd
Party Apps" listing on our website. If you need help converting your
application to templates and our lang support, we will try to connect
you with someone to help.
Writing/porting your application
Include files
Each PHP page you write will need to include the header.inc.php along
with a few variables.
This is done by putting this at the top of each PHP page.
<?php
$GLOBALS['phpgw_info']['flags']['currentapp'] = 'appname';
include('../header.inc.php');
?>
Of course change application name to fit.
This include will provide the following things:
* The phpgwAPI - The eGroupWare API will be loaded.
* The eGW navbar will be loaded (by default, but can
be disabled until a later point.
* The eGW footer will be loaded, which closes
several connections.
Additionally, to provide compatibility with stock applications, these
files will be included:
* appname/inc/functions.inc.php - This file is
loaded just after the phpgwAPI and before any HTML code is generated.
This file should include all your application specific functions..
Stock applications include any additional files needed from within this
file.
* appname/inc/header.inc.php - This file is loaded
just after the system header/navbar, and allows developers to use it
for whatever they need to load.
* appname/inc/footer.inc.php - This file is loaded
just before the system footer, allowing developers to close connections
and whatever else they need.
Note: The above 3 files are depricated and not used for OOP
(/index.php?menuaction=app.obj.method) calls.
You will need to create the following directories for your code
(replace 'appname' with your application name)
--appname
+--inc
| |--functions.inc.php
| |--header.inc.php
| |--hook_preferences.inc.php
| |--hook_admin.inc.php
| +--footer.inc.php
+--js
| |--base
| +--js_package_name
+--setup
| |--default_records.inc.php
| |--setup.inc.php
| +--tables_current.inc.php
+--templates
+--default
Making eGroupWare aware of your application
To make the application aware of your application, add your application
details to the applications table. This can be done via the GUI
administration screen, or via a SQL script. The script below should
only be used during initial development. You should use the eGroupWare
setup system for install and updating the final version of your
application.
INSERT INTO phpgw_applications (app_name, app_title, app_enabled)
VALUES('appname', 'The App
name', 1);
Administration / Site configuration
The Site configuration stores site-wide applications settings and is
only accessible by Admins.
The format is the same as for the hook_preferences, but its called
<app>/inc/hook_admin.inc.php. Here is an example:
{
$file = Array(
'Site configuration' =>
$GLOBALS['phpgw']->link('/index.php',array(
'menuaction' =>
'admin.uiconfig.admin',
'appname' => $appname
)),
'Global Categories' =>
$GLOBALS['phpgw']->link('/index.php',array(
'menuaction' =>
'admin.uicategories.index',
'appname' => $appname,
'global_cats'=>
'True'
))
);
//Do not modify below this line
display_section($appname,$file);
}
Again you dont need the Global Categories if your app does not use
Categories and you can use your own function if for the site-config if
your app has special requirements, you can realice with the existing
with uiconfig which uses a old phplib-template (atm. you should look
for the config.tpl of one of the apps).
Please note the display_section-call has only 2 parameters from 0.9.16
on, as the app-title is generated by the applications class.
If you have addition please add them here or mail them to ralfbecker
Preferences
Preferences are are used to store settings on a per user basis.
Admins can give defaults and force preferences to certain values (the
users can't change and does not get shown).
Preferences can have more descriptive helptexts which get shown when
the user clicks on [Help] or has helptexts as default enabled in his
prefs.
How to enable an app to use preferences and specialy the
user/default/forced tabs ?
You need to setup 2 files / hooks for your applications:
1. <app>/inc/hook_preferences.inc.php: This file defines a
Section for your app in the users preferences.
{
// Only Modify the $file variables.....
$file = array(
'Preferences' =>
$GLOBALS['phpgw']->link('/preferences/preferences.php','appname='.$appname),
'Grant Access' =>
$GLOBALS['phpgw']->link('/index.php','menuaction=preferences.uiaclprefs.index&acl_app='.$appname),
'Edit Categories' =>
$GLOBALS['phpgw']->link('/index.php','menuaction=preferences.uicategories.index&cats_app='
. $appname . &cats_level=True&global_cats=True')
);
//Do not modify below this line
display_section($appname,$file);
}
Cause you can skip the Grant Access and Edit Categories sections, if
you dont use ACL and/or Categories.
Please note the display_section-call has only 2 parameters from 0.9.16
on, as the app-title is generated by the applications class and placed
in $GLOBALS['phpgw_info']['apps'][<app>]['title'] to be accessed
by all apps.
2. <app>/inc/hook_settings.inc.php: This file defines the certain
input-fields with labels, helptexts, names and defaults for your
preferences.
The 3 types of prefs (user/default/forced) are handled by the
preferences-app, you dont have to care.
All input-fields have min. two necessary and more optional parameters:
1. label is displayed in front of the input field. Dont
use a lang()-call on it, thats done by the prefs itself.
2. name is a string under which u will later find the
preference in
$GLOBALS['phpgw_info']['user']['preferences'][<app>][<name>]
3. helptext optional, if helptexts are availible, a button
is shown for the user to switch them on/off
4. default a default-value (only for the user-prefs and
not for passwords)
Some input types have more params availible, see
there.
This are the types of input-fields availible:
* Inputboxes: The are for entering strings and can
have 2 optional parameters length and max-length
create_input_box('Enter prefix (max. 40
chars)','prefix','long help text','phpgw_',20,40);
* Checkboxes: The value is either '1' or '0' which
evaluates to True and False in php. You can't have '' as this cant be
set as default or forced preference !
create_check_box('Show on main
screen','homeShowEvents','long help text',1);
* Selectboxes: Beside the 4 standard params, the
selectboxes have a 5 prameter which is an array with value - label
pairs.
The label is shown in the selectbox and the value is
returned as preference when the label is selected.
create_select_box('Default Filter for
InfoLog','defaultFilter',array('own' => 'own Items','others' =>
'other peoples stuff'),'long help text','own');
(Please note the array with the options is the 3.
parameter, helptext and default are following as 4. and 5. parameter
!!!)
* Textarea: The are for entering a bigger, multiline
Text. They have 2 extra parameters rows and cols:
create_text_area('Signature','sig','long help
text','--',4,40);
* Passwordbox: it hides its content by displaying
asterixes while entering and an empty field (which is not saved) while
updateing.
create_password_box('Password (max. 12
chars)','password','choose a good one',12,12);
* Headers: You can have one or more header-lines
with a descriptive text as a kind of paragraph headings. They are in
the table-header-color and in bold writeing. To do so call the function
show_list(lang('Headertext')); after (!) each paragraph. If you dont
call it, it is called automaticaly at the end and displays and empty
header-line.
3. As all hooks they have to be registered in
<app>/setup/setup.inc.php (only the hooks part is shown here):
$setup_info[<app>]['hooks'][] = 'preferences';
$setup_info[<app>]['hooks'][] = 'settings';
Hooks get installed whit the app by setup or when you manualy call
Admin / Find and Register all Application Hooks.
Proposal: Changes for Preferences
In short: A new column app_name should be add to phpgw_preferences, to
allow apps to set defaults and forced prefs (to not show all possible
prefs after a new install) via their
<app>/setup/default_records.inc.php.
Infrastructure
Overview
eGroupWare attempts to provide developers with a sound directory
structure to work from. The directory layout may seem complex at first,
but after some use, you will see that it is designed to accommodate a
large number of applications and functions.
Directory treeS
--eGroupWare
|
+--admin
|
+--docs (installation docs)
|
+--files (Note: must be out of webserver document root!)
| |
| +--groups
| |
| +--homes
| |
| +--users
|
+--phpgwapi
| |
| +--cron (eGroupWare's optional daemons)
| |
| +--doc (developers docs)
| |
| +--inc
| | |
| | +--class.phpgw.inc.php
| | |
| | +--phpgw_info.inc.php
| | |
| | +--class.common.inc.php
| | |
| | +--etc..
| |
| +--js (javascript)
| | |
| | +--base
| | |
| | +--js_package_name
| |
| +--manual
| |
| +--setup
| | |
| | +--baseline.inc.php
| | |
| | +--default_records.inc.php
| | |
| | +--tables_current.inc.php
| | |
| | +--tables_update.inc.php
| |
| +--templates
| | |
| | +--default
| | | |
| | | +--images
| | |
| | +--verilak
| | |
| | +--images
| |
| +--themes
| |
| +--default.theme
|
+--preferences
|
+--setup
Translations
The translations are now being done through the database, and may be
configurable to use other mechanisms in future releases.
You can use the developer_tools translations application for creating
the "lang files", which will be installed through the setup
application. Alternatively you can edit the files manually. The file
naming convention for the lang files is phpgw_<langcode>.lang.
The files are stored in the app/setup directory. The format of the
files is as follows:
english phrase in lower case appname
** Translated phrase in desired case.
Notes:
* replace ** with the desired language code, as used
in the filename
* tabs are used to deliniate "columns"
The eGroupWare (“eGW”) suite of applications is built upon a very
powerful, flexible set of APIs, referred to as phpgwapi. This document
will introduce you to the architecture and the major components,
allowing you to start programming for eGW quickly, whether working on
an existing application or building your own project.
The APIs allow you to separate the HTML code from the application
logic, which makes development and maintenance of the application much
simpler. It is recommended that you utilize this model whenever
possible Within the PHP code, Within the PHP code, all eGW applications
should be written to use a three-tier structure, which separates the
user interface (“UI”) components from the business rules (“BO”) and
from the data manipulation (“SO”) routines. This ensures proper data
encapsulation and integrity of the system by avoiding function or
variable name collisions.
Here is the directory/file structure that should be used for all new
and converted applications:
* eGroupWare Root (ex. /var/www/html/egroupware/)
o myapp/
+ index.php (stub entry point)
+ templates/
# default/ (required)
* *.tpl
# idots/ (optional)
* *.tpl
# ... (optional)
+ inc/
# class_ui*.inc.php
# class_bo*.inc.php
# class_so*.inc.php
# hook_*.inc.php
# functions.inc.php (deprecated)
# header.inc.php (deprecated)
+ setup/
# setup.inc.php
# phpgw_*.lang
# tables_*.inc.php
For those developers interested in porting a PHP application to
phpgwapi, check the eGW website for the App Conversion Guide.
The only script called directly by the browser should be the index.php
script in eGroupWare's root directory. The query string argument
menuaction indicates to the system which application and method to
load. This argument is comprised of three components: an application
name, a class, and a method. For example, given myapp.ui.runme, eGW
knows to load the application myapp through the class ui, and call the
method runme.
A simple index.php file should be included in the application's top
directory, which sets certain phpgwapi flags and then calls ExecMethod
on the primary function, typically named index, located in one of the
UI classes.
The Template class in phpgwapi is used to fill in the *.tpl files of
your application. Use of this class can be a little tricky, but once
you learn how it works, it proves to be very flexible in how you
present your application's interface.
[Click here] for an introduction to the Template system, which is based
on [PHPlib]'s [template] system.
Business Object Components
These classes encapsulate the business rules that should be applied to
the data before displaying to the user. An example function is one that
pulls data using an SO class, performs some calculations on the result
set, then passes the data up to the calling UI class for display to the
user.
Similar to the UI filenames, the BO classes should be in contained in
files under <appname>/inc/, named class.bo<section>.inc.php.
These classes should contain a member variable $so named for the
corresponding SO classes.
Storage Object Components
The methods in these classes are responsible for communicating with a
back-end storage service, such as a database or LDAP directory. This is
also the right time to clean up the data for processing, such as
removing trailing whitespace from the fields in a database result set.
As noted in the BO notes, the SO classes should be contained in files
under <appname>/inc/, named class.so<section>.inc.php.
These classes may contain a member variable $db as a shortcut to the
global variable $GLOBAL['phpgw']->db.
User Interface Components
Only the methods in the UI classes should generate code to the client.
This includes X/HTML, XML, PNG image data, or any other data that goes
directly to the browser. And these are the only methods that should be
called directly through the browser via the menuaction query string
argument. This is enforced through the use of the $public_functions
array, defined at the top of the class. eGW will check that a called
method is in this array before executing it.
Note that you may need methods that generate HTML but that are not
called directly, such as a helper method that just generates a
drop-down menu. These helper methods do belong in a UI class, but
should not be listed in the $public_functions array.
A relatively small application may have need of only one UI class, in
which case the PHP file should be contained in files under
<myapp>/inc/, named class.ui.inc.php. If you need or want to
split your UI functions into multiple sections, then the filename
should be class.ui<section>.inc.php. For instance, the calendar
app has uicalendar, uialarm, and uiholiday, among others. This makes it
easier to identify a given file's use.
These classes should contain a member variable $bo named for the
corresponding BO* classes. All other variables should be used strictly
for the purpose of UI generation, and the use of $GLOBAL variables
should be minimized.
* <myapp>/inc/functions.inc.php
o This is the
container for all non-class functions, which are loaded into the
current script's global execution space. Because of the potential for
name collisions and “weirdness”, the use of this file is discouraged by
the eGW development team.
* <myapp>/inc/header.inc.php
o This file will
be used to execute a set of commands at the same location on every
page. The use of this file is deprecated, in favor of building the
functionality into the application's templates and/or UI methods.
The API
Introduction
eGroupWare attempts to provide developers with a useful API to handle
common tasks. To do this we have created a multi-dimensional class
$GLOBALS['phpgw']->.
This allows for terrific code organization, and help developers easily
identify the file that the function is in. All the files that are part
of this class are in the inc/core directory and are named to match the
sub-class.
Example: $phpgw->send->msg() is in the
inc/phpgwapi/class.send.inc.php file. (Edit this: this way is
depreciated.)
Basic functions
$GLOBALS['phpgw']->link
$GLOBALS['phpgw']->link($url, $args)
Add support for session management. ALL links must use this, that
includes href's form actions and header location's.
If you are just doing a form action back to the same page, you can use
it without any parameters.
This function is right at the core of the class because it is used so
often, we wanted to save developers a few keystrokes. Example:
<form name=copy method=post action="<?php echo
$GLOBALS['phpgw']->link();?>">
/* If session management is done via passing url parameters */
/* The the result would be */
/* <form name=copy method=post
action="somepage.php?sessionid=87687693276?kp3=kjh98u80"> */
Application Functions
$GLOBALS['phpgw']->common->phpgw_header
$GLOBALS['phpgw']->phpgw_header()
Print out the start of the HTML page, including the navigation bar and
includes appname/inc/header.php, if using deprecated linear scripts
style.
$GLOBALS['phpgw']->common->phpgw_footer
$GLOBALS['phpgw']->phpgw_footer()
Prints the system footer, and includes appname/inc/footer.php
$GLOBALS['phpgw']->common->appsession
$GLOBALS['phpgw']->common->appsession($data)
Store important information session information that your application
needs.
$GLOBALS['phpgw']->appsession will return the value of your session
data is you leave the parameter empty [i.e.
$GLOBALS['phpgw']->appsession()], otherwise it will store whatever
data you send to it.
You can also store a comma delimited string and use explode() to turn
it back into an array when you receive the value back.
Example:
$GLOBALS['phpgw']->common->appsession("/path/to/something");
echo "Dir: " . $GLOBALS['phpgw']->common->appsession();
File functions
See Virtual File System (VFS) Developers Guide for more info.
Email/NNTP Functions
$phpgw->send->msg
$phpgw->msg->send($service, $to, $subject, $body, $msgtype, $cc,
$bcc)
Send a message via email or NNTP and returns any error codes.
Example:
$to = 'someuser@domain.com';
$subject = 'Hello buddy';
$body = "Give me a call\n Been wondering what your up to.";
$errors = $GLOBALS['phpgw']->msg->send('email', $to, $subject,
$body);
The API
Introduction
eGroupWare attempts to provide developers with a useful API to handle
common tasks.
To do this we have created a multi-dimensional class
$GLOBALS['phpgw']->.
This allows for terrific code organization, and help developers easily
identify the file that the function is in. All the files that are part
of this class are in the inc/core directory and are named to match the
sub-class.
Example: $phpgw->send->msg() is in the
inc/phpgwapi/class.send.inc.php file. (Edit this: this way is
depreciated.)
Basic functions
$GLOBALS['phpgw']->link
$GLOBALS['phpgw']->link($url, $args)
Add support for session management. ALL links must use this, that
includes href's form actions and header location's.
If you are just doing a form action back to the same page, you can use
it without any parameters.
This function is right at the core of the class because it is used so
often, we wanted to save developers a few keystrokes. Example:
<form name=copy method=post action="<?php echo
$GLOBALS['phpgw']->link();?>">
/* If session management is done via passing url parameters */
/* The the result would be */
/* <form name=copy method=post
action="somepage.php?sessionid=87687693276?kp3=kjh98u80"> */
Application Functions
$GLOBALS['phpgw']->common->phpgw_header
$GLOBALS['phpgw']->phpgw_header()
Print out the start of the HTML page, including the navigation bar and
includes appname/inc/header.php, if using deprecated linear scripts
style.
$GLOBALS['phpgw']->common->phpgw_footer
$GLOBALS['phpgw']->phpgw_footer()
Prints the system footer, and includes appname/inc/footer.php
$GLOBALS['phpgw']->common->appsession
$GLOBALS['phpgw']->common->appsession($data)
Store important information session information that your application
needs.
$GLOBALS['phpgw']->appsession will return the value of your session
data is you leave the parameter empty [i.e.
$GLOBALS['phpgw']->appsession()], otherwise it will store whatever
data you send to it.
You can also store a comma delimited string and use explode() to turn
it back into an array when you receive the value back.
Example:
$GLOBALS['phpgw']->common->appsession("/path/to/something");
echo "Dir: " . $GLOBALS['phpgw']->common->appsession();
File functions
See Virtual File System (VFS) Developers Guide for more info.
Email/NNTP Functions
$phpgw->send->msg
$phpgw->msg->send($service, $to, $subject, $body, $msgtype, $cc,
$bcc)
Send a message via email or NNTP and returns any error codes.
Example:
$to = 'someuser@domain.com';
$subject = 'Hello buddy';
$body = "Give me a call\n Been wondering what your up to.";
$errors = $GLOBALS['phpgw']->msg->send('email', $to, $subject,
$body);
Description
This class keeps track of added, modified and deleted entries for
eGroupWare applications and is currently integrated into following
eGroupWare applications:
* Calendar
* AddressBook
* InfoLog
Global UID's
Because this class was designed in the first place to support SycnML it
is working global UID's. It always returns global UID's. There are
functions in phpgwapi which translates them back to UID's again.
Why global UID's?
Inside eGroupWare any application has it's own tables. This allows any
application to have it's own numbering schema. But that's not neccesary
the same when we synchronize with some other device(for example mobile
phone or other eGroupWare installation). When working with global UID's
you make sure that there can't be any collision with UID's.
How does a global UID look like?
<appname>-<uid>-<eGroupWare systemid>
Using the class
The class is available for any application as
$GLOBALS['egw']->contenthistory
The class provides 3 functions:
getHistory($_appName, $_action, $_ts)
This function returns all GUID's of entries which got addeded, modified
or deleted since the given timestamp.
Example:
$GLOBALS['egw']->contenthistory->getHistory('calendar',
'changed', '103483821');
getTSforAction($_guid, $_action)
This function returns a timestamp when a GUID got added, modified or
deleted.
Example:
$GLOBALS['egw']->contenthistory->getTSforAction('calendar-123-7s7dzf8szddfzsd@example.org',
'added');
updateTimeStamp($_appName, $_id, $_action, $_ts)
This function updates the timestamp when an entry got added, modified
or deleted. This function get's called from inside the applications.
Example:
$GLOBALS['egw']->contenthistory->updateTimeStamp('calendar',
'123', 'deleted', '103483821');
Google
this site the web
Update Notification
Enter the email to be notified about changes of the website:
Unsubscribe
all languages
Amazon
[Web Database Applications with PHP & MySQL : Buy at amazon.com]
Web Database Applications with PHP & MySQL
Configuration Variables
Introduction
eGroupWare attempts to provide developers with as much information
about the user, group, server, and application configuration as
possible.
To do this we provide a multi-dimensional array called
"$GLOBALS['egw_info']", which includes all the information about your
environment.
Due to the multi-dimensional array approach. getting these values is
easy.
Here are some examples:
<?php
// To do a hello username
echo "Hello " . $GLOBALS['egw_info']['user']['fullname'];
//If username first name is John and last name is Doe, prints: 'Hello
John Doe'
?>
<?php
// To find out the location of the imap server
echo 'IMAP Server is named: ' .
$GLOBALS['egw_info']['server']['imap_server'];
//If imap is running on localhost, prints: 'IMAP Server is named:
localhost'
?>
User information
$GLOBALS['egw_info']['user']['userid'] = The user ID.
$GLOBALS['egw_info']['user']['sessionid'] = The session ID
$GLOBALS['egw_info']['user']['theme'] = Selected theme
$GLOBALS['egw_info']['user']['private_dir'] = Users private dir. Use
eGroupWare core functions for access to the files.
$GLOBALS['egw_info']['user']['firstname'] = Users first name
$GLOBALS['egw_info']['user']['lastname'] = Users last name
$GLOBALS['egw_info']['user']['fullname'] = Users Full Name
$GLOBALS['egw_info']['user']['groups'] = Groups the user is a member of
$GLOBALS['egw_info']['user']['app_perms'] = If the user has access to
the current application
$GLOBALS['egw_info']['user']['lastlogin'] = Last time the user logged
in.
$GLOBALS['egw_info']['user']['lastloginfrom'] = Where they logged in
from the last time.
$GLOBALS['egw_info']['user']['lastpasswd_change'] = Last time they
changed their password.
$GLOBALS['egw_info']['user']['passwd'] = Hashed password.
$GLOBALS['egw_info']['user']['status'] = If the user is enabled.
$GLOBALS['egw_info']['user']['logintime'] = Time they logged into their
current session.
$GLOBALS['egw_info']['user']['session_dla'] = Last time they did
anything in their current session
$GLOBALS['egw_info']['user']['session_ip'] = Current IP address
Important Note: If you wish to remain application compatibility with
phpgroupware, or you wish your application works in the 1.x branch of
egroupware, you should use $GLOBALS['phpgw_info'] instead. However
$GLOBALS['egw_info'] will be no longer supported or updated, and might
be removed from future version.
Group information
$GLOBALS['egw_info']['group']['group_names'] = List of groups.
Server information
$egw_info[``server''][``server_root''] = Main installation directory
$egw_info[``server''][``include_root''] = Location of the 'inc'
directory. $egw_info[``server''][``temp_dir''] = Directory that can be
used for temporarily storing files $egw_info[``server''][``files_dir'']
= Directory er and group files are stored
$egw_info[``server''][``common_include_dir''] = Location of the
core/shared include files. $egw_info[``server''][``template_dir''] =
Active template files directory. This is defaulted by the server, and
changeable by the user. $egw_info[``server''][``dir_separator''] =
Allows compatibility with WindowsNT directory format
$egw_info[``server''][``encrpytkey''] = Key used for encryption
functions $egw_info[``server''][``site_title''] = Site Title will show
in the title bar of each webpage.
$egw_info[``server''][``webserver_url''] = URL to eGroupWare
installation. $egw_info[``server''][``hostname''] = Name of the server
eGroupWare is installed upon. $egw_info[``server''][``charset''] =
default charset, default:iso-8859-1 $egw_info[``server''][``version'']
= eGroupWare version.
Database information
It is unlikely you will need these, because $GLOBALS['egw']->db will
already be loaded as a database for you to use.
$egw_info[``server''][``db_host''] = Address of the database server.
Usually this is set to localhost. $egw_info[``server''][``db_name''] =
Database name. $egw_info[``server''][``db_user''] = User name.
$egw_info[``server''][``db_pass''] = Password
$egw_info[``server''][``db_type''] = Type of database. Currently MySQL
and PostgreSQL are supported.
Mail information
It is unlikely you will need these, because most email needs are
services thru core eGroupWare functions.
$egw_info[``server''][``mail_server''] = Address of the IMAP server.
Usually this is set to localhost.
$egw_info[``server''][``mail_server_type''] = IMAP or POP3
$egw_info[``server''][``imap_server_type''] = Cyrus or Uwash
$egw_info[``server''][``imap_port''] = This is usually 143, and should
only be changed if there is a good reason.
$egw_info[``server''][``mail_suffix] = This is the domain name, used to
add to email address
$egw_info[``server''][``mail_login_type''] = This adds support for
VMailMgr. Generally this should be set to 'standard'.
$egw_info[``server''][``smtp_server''] = Address of the SMTP server.
Usually this is set to localhost.
$egw_info[``server''][``smtp_port''] = This is usually 25, and should
only be changed if there is a good reason
NNTP information
$egw_info[``server''][``nntp_server''] = Address of the NNTP server.
$egw_info[``server''][``nntp_port''] = This is usually XX, and should
only be changed if there is a good reason.
$egw_info[``server''][``nntp_sender''] = Unknown
$egw_info[``server''][``nntp_organization''] = Unknown
$egw_info[``server''][``nntp_admin''] = Unknown
Application information
Each application has the following information available.
$egw_info[``apps''][``appname''][``title''] = The title of the
application.
$egw_info[``apps''][``appname''][``enabled''] = If the application is
enabled. True or False.
$egw_info[``server''][``app_include_dir''] = Location of the current
application include files.
$egw_info[``server''][``app_template_dir''] = Location of the current
application tpl files.
$egw_info[``server''][``app_lang_dir''] = Location of the current lang
directory.
$egw_info[``server''][``app_auth''] = If the server and current user
have access to current application
$egw_info[``server''][``app_current''] = name of the current
application.
Using Language Support
Overview
eGroupWare is built using a multi-language support scheme. This means
the pages can be translated to other languages very easily.
Translations of text strings are stored in the eGroupWare database, and
can be modified by the eGroupWare administrator.
How to use lang support
The lang() function is your application's interface to eGroupWare's
internationalization support.
While developing your application, just wrap all your text output with
calls to lang(), as in the following code:
$x = 42;
echo lang("The counter is %1",$x)."<br>";
This will attempt to translate ``The counter is %1'', and return a
translated version based on the current application and language in
use. Note how the position that $x will end up is controlled by the
format string, not by building up the string in your code. This allows
your application to be translated to languages where the actual number
is not placed at the end of the string.
When a translation is not found, the original text will be returned
with a * after the string. This makes it easy to develop your
application, then go back and add missing translations (identified by
the *) later.
Without a specific translation in the lang table, the above code will
print:
The counter is 42*<br>
If the current user speaks Italian, they string returned may instead be:
il contatore è 42<br>;
The lang function
lang($key, $m1="", $m2="", $m3="", $m4="", $m5="",
$m6="", $m7="", $m8="",
$m9="", $m10="")
[$key ]
is the string to translate
and may contain replacement directives of the form %n.
[$m1 ]
is the first replacement
value or may be an array of replacement values (in which case $m2 and
above are ignored).
[$m2 - $m10 ]
the 2nd through 10th
replacement values if $m1 is not an array.
The database is searched for rows with a lang.message_id that matches
$key. If a translation is not found, the original $key is used. The
translation engine then replaces all tokens of the form %N with the Nth
parameter (either $m1[N] or $mN).
Adding translation data
The TranslationTools (former developer_tools) allow easily create new
translations of eGW applications.
A developer also can use them to create the english lang-file by
searching for new phrases in his sources.
The lang table
The translation class uses the lang table for all translations. We are
concerned with 4 of the columns to create a translation:
[message_id ]
The key to identify the
message (the $key passed to the lang() function). This is written in
English.
[app_name ]
The application the
translation applies to, or common if it is common across multiple
applications.
[lang ]
The code for the language
the translation is in.
[content ]
The translated string.
translating the content to reflect the message_id string in the lang
language. If the string is specific to your application, put your
application name in for app_name otherwise use the name common. The
message_id should be in lower case for a small increase in speed.
Common return codes
If you browse through the eGroupWare sources, you may notice a pattern
to the return codes used in the higher-level functions. The codes used
are partially documented in the doc/developers/CODES file.
Codes are used as a simple way to communicate common error and progress
conditions back to the user. They are mapped to a text string through
the check_code() function, which passes the strings through lang()
before returning.
For example, calling
echo check_code(13);
Would print
Your message has been sent
translated into the current language.
Overview
eGroupWare is built using a templates based design. This means the
display pages, stored in tpl files, can be translated to other
languages, made to look completely different.
How to use PHPLIB templates
For Further info read the PHPLIBs documentation for their template
class. http://phplib.sanisoft.com
eTemplate is a new widget-based template system, which is used eg. for
the InfoLog application.
There's a [Tutorial].
The eTemplateReferenz document is currently not migrated to wiki yet,
for a (perhaps) wiki bug. I'll do it asap -- ZhangWeiwu
A Style Guide for eGroupWare descrtibes the comon look and feel of
eGroupware.
Why do we need a Style Guide for eGroupWare ?
It influences:
* how easily users get used to eGroupWare,
* how much they apreciate and accept it,
* see it as one system and not a bunch of single
apps.
o pobably the
best thing to achieve this is designing a programm flow chart. Also
helpfull for inside people and developers. Having a flowchart the user
can see and diced better if this is what he want and need. (joao)
It is important that all apps and of cause the API adhear to the
StyleGuide !!!
The eGroupWare StyleGuide should only differ for very good reason from
other well known style guides like [KDE] or MSWindows, as that's what
the users know and expect. The main justification for such a divergence
would be that we are building a web application.
''We need a volunteer with good eGroupWare knowledge, not necessarly a
developer, to create this document.
I just start adding stuff here, please comment on it !!! -- RalfBecker
* application header: we have 3 types of application
headers atm
1. bold app-title
above a horizontal ruler (sometimes with appended -
<sub-function>)
2. line in
table-header background-color with bold app-title
3. no header at all
(eg. Calendar standard view and email for some views)
o We need to
decide for one type for a general app. I would prefer #1, as it allows
to have some extra buttons / action icons right alligned above the
ruler (eg. InfoLog Add Note/ToDo/Phonecall Icons)
o Apps with a
very unique look of there standard views like Calendar or Email might
be ok without any app-header (#3) for these standard-views, but not for
the other dialogs (eg. not the edit/add event in Calendar).
+ don know ... may be it is only a little bit more difficult to get
this app ligned up (joao)
* We created now a standard way to specify the
application header, see App-Titles and iDots Sidebox Menu for the
details. Which type of app-header to use, depends now on the selected
template-set! -- RalfBecker
* am I too late? I like ability to use a header with
extra links/buttons but to maximum the available space, they should be
under the application title (not right justified and in line with it).
Also, I think extra buttons/links should be arranged in a table format
which lends itself to the application title being a bold, shaded
background, table header. IMO the most important thing on the page is
NOT the app name (I know it, I clicked on it). With my 800x600 laptop
display, screen real estate is reserved for valuable information
* confirmation dialogs: eg. Delete the entry
'Testentry' ?
o The text about
the implications of the decision should be clear to all users
o the message
should contain a title/name of the entry to eg. delete
+ don't take this too hard, but I HATE confirmations and turn them off
whenever possible. It takes an extra click and delay for page load. I
have figured out what delete means and if I do it by accident and don't
hit stop fast enough, I'll live with the consequences
+ that is ok but for the user we need then a clear app manual (joao)
+ Can't we use Javascript confirmation dialogs. Specially for slow
connections it very irritating to load a new screen only for the
confirmation. Maybe this can be a General Preference Setting? mipmip
+ java may be slow on certain PCs also, what about a simple html-pop-up
showing only the relevant info or question? (joao)
o Buttons
(rather than links) should be used
+ - I prefer links over buttons for almost everything (buttons should
be used sparingly). If I expect another screen to appear, I can open
the link directly into a new window and continue working while waiting
for it to load. Consider me a power user if you must but I have better
things to do than wait for a page load
+ that also, the average user do not know about this possibilities
(unless it is about certain downloads:) so not worth to build it in or
explain it. Work applications should be straight and clear, step to
step, 1-2-3, the average user will fill up his 8 hours and will no be a
poweruser ... so more we build in more the company falls back to
standard 'terminal-apps' (joao)
+ links look like web-pages not like applications and in my oppinion
eGW should try to look like an application
o Buttons should
be in this order [Yes] [No] (if aplicable: [Cancel])
+ mhhh, I guess no -cancel- yes is the appropriate sequence the
rightmost button ever should be the final decision, yes = save (joao)
o If the Yes/No
answer can be missunderstood, make it [Yes - Delete] [No - Cancel]
o If the app has
a app-header the confirmation dialog should have it too.
o yes, valid for
all table data, e-mail to reports, the action buttons shoul be on top
of the list as well as on the button to, so the user can use the
nearest ones (joao)
* edit dialogs
o should have
lines in alternating colors and if applicable sub-headers in the
table-header color
+ definitely, makes it much easier to read
o should have
left aligned [Save] and [Cancel] buttons and right aligned [Delete] /
[Help] buttons - if required
o don't know, I
believe that the most logical sequence is from left to right, right
aligned and the final action on the most right, so when I am in a data
input form the YES or SAVE button should be in the rightmost position
under the last form field. That is as handwriting. You set the point at
the end of the last word, no need to go back to left ... (joao)
+ if the table layout (and total table width) is suitable, I prefer
buttons centred within the columns. especially if they are close to
alignment with the input boxes on the page (allows for an easy
workflow/eye follow)
* add dialogs
o should have
lines in alternating colors and if applicable sub-headers in the
table-header color
o should have
left aligned [Add] and [Cancel] buttons and have right aligned [Clear]
/ [Help] buttons - if required
* program flow
o each dialog
should return to the calling page / state, eg. if you click on edit in
a list or entries, you should end there again
+ An App should give A standard output/error report after every action
that is done. There must be a standard message box to show these mipmip
+ Like I wrote in usability, I believe that we have a wast space in the
app title header. No need to have an extra line somewhere. This msg can
appear n top of the app, right of the app header, another + it is ever
visible
o each dialog
should have a cancel button, which returs without saveing to the
previous page
o this cancel
button I like to discuss. For me a cancel button is a special button
and most of the cancel buttons in most apps do not make any sense.
Think about the meaning of the word! When I want a button which brings
me b a c k then write return on it. The cancel button should be present
(for me) only in situations where I need to confirm the final action:
Do you really want to delete this data? Here I need CANCEL and YES.
Going deaper even the famous OK is not correct. OK is a confirmation to
a question but not the order to save data right. So on a input form may
be should be a SAVE button and not a OK button. Let's find out what
else and try to use better labels. (joao)
+ each dialog should go to next page anticipated to be desired most
often by users. Program flow should be easy to follow and as intuitive
as possible. Consider the browser back button my cancel function (I do)
* preferences and admin/configuration should be made
via the standard eGW functions, to
o have a common
look-and-feel
o use the
3-level user/default/admin approach, to
+ be customizable by the admin (eg. admin can force/switch off certain
unwanted prefs)
+ more comfortable to the user
o use the long
helptexts (most users and admin have no idea what most of our
configurable options do)
o see How to
hook into Admin and Preferences for more on this
If you have comments or points to add please do so here or mail them to
ralfbecker
Preferences
Preferences are are used to store settings on a per user basis.
Admins can give defaults and force preferences to certain values (the
users can't change and does not get shown).
Preferences can have more descriptive helptexts which get shown when
the user clicks on [Help] or has helptexts as default enabled in his
prefs.
How to enable an app to use preferences and specialy the
user/default/forced tabs ?
You need to setup 2 files / hooks for your applications:
1. <app>/inc/hook_preferences.inc.php: This file defines a
Section for your app in the users preferences.
{
// Only Modify the $file variables.....
$file = array(
'Preferences' =>
$GLOBALS['phpgw']->link('/preferences/preferences.php','appname='.$appname),
'Grant Access' =>
$GLOBALS['phpgw']->link('/index.php','menuaction=preferences.uiaclprefs.index&acl_app='.$appname),
'Edit Categories' =>
$GLOBALS['phpgw']->link('/index.php','menuaction=preferences.uicategories.index&cats_app='
. $appname . &cats_level=True&global_cats=True')
);
//Do not modify below this line
display_section($appname,$file);
}
Cause you can skip the Grant Access and Edit Categories sections, if
you dont use ACL and/or Categories.
Please note the display_section-call has only 2 parameters from 0.9.16
on, as the app-title is generated by the applications class and placed
in $GLOBALS['phpgw_info']['apps'][<app>]['title'] to be accessed
by all apps.
2. <app>/inc/hook_settings.inc.php: This file defines the certain
input-fields with labels, helptexts, names and defaults for your
preferences.
The 3 types of prefs (user/default/forced) are handled by the
preferences-app, you dont have to care.
All input-fields have min. two necessary and more optional parameters:
1. label is displayed in front of the input field. Dont
use a lang()-call on it, thats done by the prefs itself.
2. name is a string under which u will later find the
preference in
$GLOBALS['phpgw_info']['user']['preferences'][<app>][<name>]
3. helptext optional, if helptexts are availible, a button
is shown for the user to switch them on/off
4. default a default-value (only for the user-prefs and
not for passwords)
Some input types have more params availible, see
there.
This are the types of input-fields availible:
* Inputboxes: The are for entering strings and can
have 2 optional parameters length and max-length
create_input_box('Enter prefix (max. 40
chars)','prefix','long help text','phpgw_',20,40);
* Checkboxes: The value is either '1' or '0' which
evaluates to True and False in php. You can't have '' as this cant be
set as default or forced preference !
create_check_box('Show on main
screen','homeShowEvents','long help text',1);
* Selectboxes: Beside the 4 standard params, the
selectboxes have a 5 prameter which is an array with value - label
pairs.
The label is shown in the selectbox and the value is
returned as preference when the label is selected.
create_select_box('Default Filter for
InfoLog','defaultFilter',array('own' => 'own Items','others' =>
'other peoples stuff'),'long help text','own');
(Please note the array with the options is the 3.
parameter, helptext and default are following as 4. and 5. parameter
!!!)
* Textarea: The are for entering a bigger, multiline
Text. They have 2 extra parameters rows and cols:
create_text_area('Signature','sig','long help
text','--',4,40);
* Passwordbox: it hides its content by displaying
asterixes while entering and an empty field (which is not saved) while
updateing.
create_password_box('Password (max. 12
chars)','password','choose a good one',12,12);
* Headers: You can have one or more header-lines
with a descriptive text as a kind of paragraph headings. They are in
the table-header-color and in bold writeing. To do so call the function
show_list(lang('Headertext')); after (!) each paragraph. If you dont
call it, it is called automaticaly at the end and displays and empty
header-line.
3. As all hooks they have to be registered in
<app>/setup/setup.inc.php (only the hooks part is shown here):
$setup_info[<app>]['hooks'][] = 'preferences';
$setup_info[<app>]['hooks'][] = 'settings';
Hooks get installed whit the app by setup or when you manualy call
Admin / Find and Register all Application Hooks.
Proposal: Changes for Preferences
In short: A new column app_name should be add to phpgw_preferences, to
allow apps to set defaults and forced prefs (to not show all possible
prefs after a new install) via their
<app>/setup/default_records.inc.php.
Administration / Site configuration
The Site configuration stores site-wide applications settings and is
only accessible by Admins.
The format is the same as for the hook_preferences, but its called
<app>/inc/hook_admin.inc.php. Here is an example:
{
$file = Array(
'Site configuration' =>
$GLOBALS['phpgw']->link('/index.php',array(
'menuaction' =>
'admin.uiconfig.admin',
'appname' => $appname
)),
'Global Categories' =>
$GLOBALS['phpgw']->link('/index.php',array(
'menuaction' =>
'admin.uicategories.index',
'appname' => $appname,
'global_cats'=>
'True'
))
);
//Do not modify below this line
display_section($appname,$file);
}
Again you dont need the Global Categories if your app does not use
Categories and you can use your own function if for the site-config if
your app has special requirements, you can realice with the existing
with uiconfig which uses a old phplib-template (atm. you should look
for the config.tpl of one of the apps).
Please note the display_section-call has only 2 parameters from 0.9.16
on, as the app-title is generated by the applications class.
If you have addition please add them here or mail them to ralfbecker
The file <app>/setup/setup.inc.php is needed by each eGroupWare
application. I makes certain important settings for the installation
and configuration of the app.
As an example, have a look for the setup.inc.php of the calendar:
<?php
$setup_info['calendar']['name'] =
'calendar'; // the title is not longer here!
$setup_info['calendar']['version'] = '0.9.13.007'; // of your app, NOT
the overal egw version
$setup_info['calendar']['app_order'] = 3;
$setup_info['calendar']['enable'] = 1;
/* Informations for the about-page */
$setup_info['calendar']['author'] = 'Mark Peters';
$setup_info['calendar']['license'] = 'GPL';
$setup_info['calendar']['description'] =
'Powerful calendar with meeting request system and
ACL security.';
$setup_info['calendar']['note'] =
'Bassed on Webcalendar by <a
href="http://www.radix.net/~cknudsen" target="_blank">Craig
Knudsen</a>.';
$setup_info['calendar']['maintainer'] = array(
'name' => 'Ralf Becker',
'email' => 'ralfbecker@outdoor-training.de'
);
/* the tables this app uses */
$setup_info['calendar']['tables'][] =
'phpgw_cal'; // there are more tables in the
cal, just an example here
/* The hooks this app includes, needed for hooks registration */
$setup_info['calendar']['hooks'][] =
'admin'; // to
show up in the admin page
$setup_info['calendar']['hooks'][] = 'deleteaccount'; // gets
called when an account gets deleted
$setup_info['calendar']['hooks'][] =
'email'; // to
recognise the notifications
$setup_info['calendar']['hooks'][] =
'home'; //
to show up on the startpage
$setup_info['calendar']['hooks'][] = 'manual';
$setup_info['calendar']['hooks'][] = 'preferences';
// to show up on the preference page
$setup_info['calendar']['hooks'][] =
'settings'; // settings for 3-level
prefs
$setup_info['calendar']['hooks'][] = 'sidebox_menu'; //
iDots sidebox menu
/* Dependencies for this app to work */
$setup_info['calendar']['depends'][] = array(
'appname' => 'phpgwapi',
'versions' => Array('0.9.14','0.9.15')
);
Some of the hooks here have a more detailed description in How to hook
into Admin and Preferences.
eGroupWare Setup
June 18, 2001 MilesLott A developer introduction to using the next
generation setup application for egroupware.
1. Introduction
1.1 Welcome
Thanks for taking the time to look over this document. If you are a
developer who is new to egroupware, this document will be invaluable to
your success during the life of your application. This is in addition
to the other fine documentation available in the phpgwapi/doc directory
in your install. Even long-time phpgw developers should benefit this
document. Herein, I will attempt to outline the critical steps required
in order to get along with setup.
1.2 Overview
With setup3, we introduce several new capabilities and technologies for
the developer and end user alike. Michael Dean was kind enough to offer
up schema_proc to form the core of an abstracted and
database-independent upgrade process. This enables developers to write
a single set of upgrades and table definitions, which should then work
on MySQL and PostgreSQL, or any other database type we might add in the
future.
Adding to this to control the process was a good chunk of the old setup
program, written by Dan Kuykendall (Seek3r). Dan had everything to do
with the new dependencies support and with the format of the
$setup_info array in setup3.
Setup3 adds multi-language support for the setup application, a long
missed feature, I would imagine.
Setup3 gives each application developer control over their application
install and upgrade processes, while giving them access to work within
a realm formerly owned by only the former core egroupware applications.
Yes, this is extra work for the developer. But it is hoped that setup3
is also viewed as a tool that can truly enhance the development process.
OK. Let's dive right in...
2. Application setup files
The files in this section are contained within each application/setup
directory. Every app will some of these files in order to operate with
setup3.
2.1 setup.inc.php (Required)
Basic information
The values in this section must be used by all applications.
The first section of setup.inc.php defines the very basic and yet
critical information about the application. Take a look at the
following section:
$setup_info['addressbook']['name'] = 'addressbook';
$setup_info['addressbook']['title'] = 'Addressbook';
$setup_info['addressbook']['version'] = '0.9.13.002';
$setup_info['addressbook']['app_order'] = 4;
$setup_info['addressbook']['enable'] = 1;
'name' is used throughout egroupware, typically in $phpgw_info flags
such as 'currentapp' or as the 'app_name' almost everywhere else.
'title' would be used in the navbar, admin, preferences, as well as in
the application itself.
The 'version' string defines the version of the application and table
code. This would be incremented whenever you create a new upgrade
function, and typically only for table modifications. If the change is
significant from the last code update, you could increment this here
also. Incrementing this version string is not trivial, so please do
read the rest of this document for more information about that.
'app_order' determines the order of applications in the navbar. If the
number you set here is the same as is set for another app, the app
whose 'name' is first in the English alphabet would appear first.
Smaller numbers show closer to the top or left end of the navbar,
depending upon the layout.
The 'enable' string is used by the egroupware API to determine whether
an application is disabled, enabled, or enabled but hidden from the
navbar. Most applications will want this set to a value of 1 (enabled).
The notifywindow app sets this to 2, which keeps it off the navbar. An
enable of 0 would disable the app by default. There is one other
special case, 3, which is used primarily by the API itself. From the
perspective of setup3, the API is an application just like any other
application. By setting the 'enable' flag to 3, the API is still
enabled, but will not be assignable to a user as a real application. It
will thereby be hidden from the admin for application and user/group
editing.
Table info
Only applications with database tables will use entries in this section.
The next section of $setup_info values is an array defining all of the
application's database tables:
$setup_info['addressbook']['tables'] = array(
'phpgw_addressbook',
'phpgw_addressbook_extra'
);
This is a simple array, and must list accurately the current table
names you are using in your application. This list will match a much
more complex array of table specifications, as you will see below.
Hooks
Some applications will use this section.
The hooks array part of $setup_info contains a simple list of hooks the
application will use:
$setup_info['addressbook']['hooks'][] = 'preferences';
$setup_info['addressbook']['hooks'][] = 'admin';
Here we also note a different method of 'stuffing the array.' In any
case, this list of hooks will be required soon in order for your
hook_admin.inc.php and other files to work. This is being done to cut
down on the manual directory listing and file_exists loops done
currently to discover hook files. Other than 'preferences' and 'admin',
'home', 'manual', 'after_navbar' and 'navbar_end' are all valid hook
entries.
Dependencies
All applications will have at least one entry here.
The final section, or array of data, is a listing of the other
applications your application requires in order to function:
$setup_info['addressbook']['depends'][] = array(
'appname' => 'phpgwapi',
'versions' => Array(
'0.9.10',
'0.9.11',
'0.9.12',
'0.9.13'
)
);
This is the standard dependency array for all egroupware applications.
It states that this application requires the phpgwapi, and lists the
versions with which versions this app is compatible. This list would
need to be appended upon each new API release, assuming your
application is compatible with this new API version. You may list other
applications here, e.g. your app might depend upon 'email' in order to
work properly.
Do NOT list applications here without considering this: If you do list
an application here, and your app does not really require it, your
application will not install unless that other application is already
installed. This is handled normally within the install/upgrade process
loops, which will install only applications whose dependencies are
satisfied. Using a multipass function, the applications are installed
in the correct order to ensure that dependencies are resolved. In all
cases, the API would be installed first in every new install or
upgrade, since all applications depend on the API.
2.2 tables_baseline.inc.php (Recommended)
Any application that has at least one upgrade routine will have this
file.
The tables_baseline file represents the earliest supported version of
an application's tables. This file is used only in the upgrade process,
and is critical to its success. It contains an array of
database-independent table, field, key and index definitions.
This array is formatted for use by the class.schema_proc_array.inc.php
file in setup3. See the tables_update section below for more detail
about schema_proc, but for now, here is a simple table definition in
this format:
$phpgw_baseline = array(
'skel' => array(
'fd' => array(
'skel_id' => array('type' => 'auto','nullable' => false),
'skel_owner' => array('type' => 'varchar','precision' => 25),
'skel_access' => array('type' => 'varchar','precision' => 10),
'skel_cat' => array('type' => 'int','precision' => 4),
'skel_des' => array('type' => 'text'),
'skel_pri' => array('type' => 'int','precision' => 4)
),
'pk' => array('skel_id'),
'fk' => array(),
'ix' => array(),
'uc' => array()
)
);
This multi-dimensional array contains 1 subarray with 5 subs of its
own. The first array ('skel' above) defines the table name. Below that
are 5 sections, 'fd' for field definitions, 'pk' to define primary
keys, 'fk' to define foreign keys, 'ix' to define indexed fields, and
'uc' to define columns that require unique values. In the above
example, the table 'skel' has 6 fields (skel_id, skel_owner,
skel_access, skel_cat, skel_des, skel_pri), and 'skel_id' is defined
also as the primary key for this table. More information on this array
is below. But, this format was chosen as an available solution for
defining tables and fields without having to maintain seperate files
for different databases.
2.3 tables_current.inc.php (Recommended)
All applications with tables will need this file.
The tables_current file defines the current table definition that
matches the 'version' string in $setup_info as well as the current
code. This file is used only for new installs, or whenever the
application is removed and reinstalled. The format and name of the
array in this file is the same as for the tables_baseline file listed
above. In fact, whenever it is required to change your table
definitions, you would start by copying the current file over to become
the tables_baseline file. After having created your upgrade routines,
you would then recreate the current file to match the new table
definitions.
2.4 tables_update.inc.php (Recommended)
Any application which requires an upgrade to a previous version's
tables will need this file.
This file will be the most complex of all setup-oriented files with
which you will be working. It will contain all upgrade functions
capable of upgrading any possible version of your egroupware app. These
upgrade routines roughly match the old setup program's upgrade
functions, but the use of objects and the methods have changed
dramatically. The simplest version upgrade routine would look like:
$test[] = "0.9.3pre10";
function addressbook_upgrade0_9_3pre10()
{
global $setup_info;
$setup_info['addressbook']['currentver'] = '0.9.3';
return $setup_info['addressbook']['currentver'];
}
This upgrade function merely updates the current version number. Note
that there is not only an upgrade function, but also the setting of a
value in the $test array. The name 'test' is a holdover from the old
setup program, and is an arbitrary choice. However, this name must be
used for the upgrade process to work. Prior to each of your upgrade
functions, add the value of the previous version to $test.
Now look at the function name. The name is important and should be
structured as the application name and the version from which you are
intending to upgrade. The '.'s in the version string are replaced with
'_'.
Inside the function, we global the $setup_info array. Next, we alter
the version number in that array, for our application. Please be
careful to specify YOUR application name here. The very last thing we
do is to return this new version to the calling function. The upgrade
process relies on the value returned, since it uses this directly to
determine the new version. This may appear illogical on some level, but
it does work. The reason for returning this value instead of a True or
1, etc. has to do with variable scope and lifetime. In this way, even
the globaling of $setup_info inside the function may have little effect
on the upgrade process. But, there may be values in this array you
would want to use within the function. More on that later.
There is one other variable you would need if doing any database
operations here. If you global $phpgw_setup, you will then have access
to db and schema_proc objects and functions. The objects of interest
here are:
* $phpgw_setup->oProc
* $phpgw_setup->db.
For most database work you should use the oProc object. This also has a
db object that should be used for most standard phpgw API db class
functions, including $db->query, next_record, num_rows, and f. The
use of these for standard db operations is critical to the upgrade
process. Schema_proc has a flag that can be set to determine what mode
of upgrade we are in. This flag is set in the setup class during the
upgrade process, and should not be altered locally.
This flag is a decision on whether to alter the database or the
schema_proc array. The tables_baseline file above is loaded by setup
prior to running your upgrade routines. If the current installed
version is greater than the current upgrade routine, we don't need to
alter the database yet. But schema_proc instead alters the
$phpgw_baseline array in memory. The maintenance of this array is done
even when we do alter the database. Once our version number in the test
array matches the currently installed version of an application, real
work on the tables begins.
'Why bother modifying this array at all', you may ask. The array must
be maintained in order to keep current table definition status. This is
used in some schema_proc functions when altering columns and tables.
This is especially critical for pgsql schema_proc functions.
By using the $phpgw_setup->oProc object for basic inserts and
queries, we acheive the ability to run all upgrade functions in every
upgrade cycle without actually altering the database until we reach the
current version we actually want to upgrade. For example:
$sql = "SELECT * FROM phpgw_addressbook_extra WHERE
contact_name='notes'";
$phpgw_setup->oProc->query($sql,__LINE__,__FILE__);
while($phpgw_setup->oProc->next_record()) {
We could have used $phpgw_setup->db or even a copy for the above
activity. However, using the above method ensures that an array only
upgrade does just that. If the flag was set in setup telling
schema_proc to alter the array only, we do not want to touch the tables
for inserts or selects yet. In this case,
$phpgw_setup->oProc->next_record() returns False, and the loop is
skipped. The $phpgw_baseline array does not know about table content,
only table and field definitions.
If the upgrade function containing this method is actually working on
the tables (currentver <= the upgrade function), then next_record()
is returned as the expected action of pulling the next row of data.
Inside of this while loop, you can safely use $phpgw_setup->db, or
preferably a copy, to do the insert/delete, etc you want to have happen
here.
$cid = $phpgw_setup->oProc->f('contact_id');
$cvalu = $phpgw_setup->oProc->f('contact_value');
$update = "UPDATE phpgw_addressbook set note='" . $cvalu . "' WHERE
id=" . $cid;
$db1->query($update);
$delete = "DELETE FROM phpgw_addressbook_extra WHERE contact_id=" .
$cid . " AND contact_name='notes'";
$db1->query($delete);
}
$db1 is a copy of $phpgw_setup->db, to avoid potential conflicts
with the rest of setup's db activities.
In addition to the basic API db class functions, schema_proc introduces
the following special functions:
function DropTable($sTableName)
function DropColumn($sTableName, $aTableDef, $sColumnName)
function RenameTable($sOldTableName, $sNewTableName)
function RenameColumn($sTableName, $sOldColumnName, $sNewColumnName)
function AlterColumn($sTableName, $sColumnName, $aColumnDef)
function AddColumn($sTableName, $sColumnName, $aColumnDef)
function CreateTable($sTableName, $aTableDef)
Please use these functions where appropriate in place of standard SQL
CREATE, DROP, and ALTER TABLE commands. This will ensure that your
upgrade script works for all supported databases.
Of these functions, DropTable, RenameTable, and RenameColumn are pretty
straightforward. Pass these the table names you wish to Drop/Rename,
and schema_proc will handle the rest, including indexes and sequences,
where applicable.
The remaining functions require some explanation:
* CreateTable:
$phpgw_setup->oProc->CreateTable(
'categories', array(
'fd' => array(
'cat_id' => array('type' => 'auto','nullable' => false),
'account_id' => array('type' => 'int','precision' =>
4,'nullable' => false, 'default' => 0),
'app_name' => array('type' => 'varchar','precision' =>
25,'nullable' => false),
'cat_name' => array('type' => 'varchar', 'precision' => 150,
'nullable' => false),
'cat_description' => array('type' => 'text', 'nullable' =>
false)
),
'pk' => array('cat_id'),
'ix' => array(),
'fk' => array(),
'uc' => array()
)
);
Does this look familiar? The array passed to CreateTable is in the
format used also in tables_baseline and tables_current. Note a slight
difference where the table name is being passed as a seperate argument.
The second argument to the function is the table definition array,
starting with 'fd'.
* AddColumn:
$phpgw_setup->oProc->AddColumn('phpgw_categories','cat_access',array('type'
=> 'varchar', 'precision' => 25));
Here we pass the table name of an existing table, the new column name,
and a field definition. This definition is merely a slice of the table
arrays found earlier in this document.
* AlterColumn:
$phpgw_setup->oProc->AlterColumn('phpgw_sessions','session_action',array('type'
=> 'varchar', 'precision' => '255'));
The format of this function matches AddColumn. It is also a simple case
of passing the table name, field name, and field definition.
* DropColumn:
$newtbldef = array(
"fd" => array(
'acl_appname' => array('type' => 'varchar', 'precision' => 50),
'acl_location' => array('type' => 'varchar', 'precision' =>
255),
'acl_account' => array('type' => 'int', 'precision' => 4),
'acl_rights' => array('type' => 'int', 'precision' => 4)
),
'pk' => array(),
'ix' => array(),
'fk' => array(),
'uc' => array()
);
$phpgw_setup->oProc->DropColumn('phpgw_acl',$newtbldef,'acl_account_type');
This is the most complicated function in schema_proc, from the user's
perspective. Its complexity is necessitated by the requirement of some
databases to recreate a table in the case of dropping a column. Note
that the table definition array is being used yet again. The array
defined here should match the table definition you want after this
function has completed. Here, we are dropping the column
'acl_account_type' from the table 'phpgw_acl', and the table definition
does not have this column defined. You could copy information from your
tables_current file here and edit it to match the desired new table
spec, less the column you wish to drop.
There are additional functions within schema_proc, the majority of
which are not to be called directly. They are used internally. If you
do wish to investigate further, use class.schema_proc.inc.php as your
guide. This master file includes the class.schema_proc_DBMS.inc.php and
class.schema_proc_array.inc.php files. The DBMS files should not be
used as a guide, since their functions are called from the master
class, and the parameters are different from what you might expect
relative to the master.
PLEASE, DO NOT WRITE TO OR ALTER ANOTHER APPLICATION'S TABLES OR THE
API TABLES IN YOUR APPLICATION UPGRADE FUNCTIONS!
2.5 default_records.inc.php (Optional)
Any application with tables that wants to load some default data will
need this file.
The default_records file consists of a list of SQL INSERTs using the
$oProc object directly:
$oProc->query("INSERT INTO phpgw_inv_statuslist (status_name) VALUES
('available')");
$oProc->query("INSERT INTO phpgw_inv_statuslist (status_name) VALUES
('no longer available')");
$oProc->query("INSERT INTO phpgw_inv_statuslist (status_name) VALUES
('back order')");
In this case, the developer wanted to insert some status information,
which was then used in a select box on an html form. Using the
default_records file, every new install will have this data included.
This file should consist of queries applicable to the tables defined in
setup.inc.php and tables_current.inc.php.
2.6 test_data.inc.php (Optional)
Any developer wanting to test the full list of upgrade routines can use
this file.
test_data.inc.php is similar to default_records above. It is called
only by schematoy.php and is never installed with a new install or
upgrade. This is a developer-only file. The INSERTs here should be
applicable to the tables_baseline table definitions.
2.7 language files (Required)
All applications should have at least a file of English translations,
used for their application lang() calls.
* Format of a lang file:
{phrase}{TAB}{appname}{TAB}{LANG_CODE}{TAB}{translation}
e.g:
first name common en First Name
first name common de Vorname
* Filenames:
phpgw_{LANG_CODE}.lang
e.g.
English: phpgw_en.lang
German: phpgw_de.lang
Please see the contents of the API 'languages' table for the correct
setting of the LANG_CODE.
3. Developer Tools
3.1 sqltoarray.php
Displays the current schema_proc array defining an application's tables.
This web application reads the current table status live from the
database. It then parses this information into a hopefully correct
table definition array for schema_proc. Upon visiting this app, you are
shown a list of currently installed applications with defined tables.
You may then select one app or all apps, and then submit the form. From
this form you may then download a tables_current file, suitable for
commission to cvs. Please do check the format to make sure the
definitions are correct.
3.2 schematoy.php
Runs the full cycle of upgrades, including optional test_data.
This app is not beautiful, may bomb on you, and will definitely drop
your application's tables. The display is similar to the user/admin
tool, applications.php. You are shown a list of apps with tables.
Select one app, and enter a target version. Upon submission of the form:
* All application tables are dropped.
* tables_baseline.inc.php is loaded.
* test_data.inc.php is loaded
* tables_update.inc.php is loaded.
* a full application upgrade test begins.
This will give a LOT of debugging output. Depending on your database,
the process may take quite awhile. This tool should be considered as a
destructive test of the full upgrade cycle. If the upgrade process is
successful, you can then check the loaded test_data to see that it is
still in place as expected after all the table modifications, etc. If
not, it should be clear where the error has occurred. Look for the
usual INVALID SQL warnings, among others.
3.3 tools subdirectory
some utilities for sql file conversion, etc.
In the tools directory under setup3, there should be at least a couple
of hopefully handy perl or shell scripts. These are for running on the
commandline only, and might apply to converting SQL files into lang
files, etc. They are not expected to be perfect, but might offer some
assistance or ideas for additional utilities. Use these at your own
risk or benefit.
4. The install/upgrade process
4.1 Overview
Setup internal upgrade functions
Setup uses a common set of functions for new installs and upgrades.
These are implemented as multi-pass loops. For a single application
install or upgrade, a single pass is done. For multiple application
installs or upgrades, multiple passes are done automatically. The order
of install in a mass install or upgrade is determined by application
dependencies. The other determining factor is the order in which the
application directories and setup.inc.php files are read from the
filesystem.
4.2 New installs
Detection
Each run of index.php or applications.php in setup3 first runs a set of
detection routines. These read the data from each setup.inc.php file,
and from the 'applications' or 'phpgw_applications' table as
appropriate, and only if one of these tables exists. This data is
parsed into the $setup_info array. In this case, this array contains
information about all applications. Based on the information gathered,
a status flag is set to one of the following values:
* U - Upgrade required/available
* R - upgrade in pRogress
* C - upgrade Completed successfully
* D - Dependency failure
* F - upgrade Failed
* V - Version mismatch at end of upgrade
* M - Missing files at start of upgrade (Not used,
proposed only)
Using this information, the setup logic in index.php determines what
mode we are in. index.php is not capable of being selective about which
application it found as being out of sync. It is designed only for
'Simple Application Management', which is Step 1 of the setup process.
For more selective application manipulation, use applications.php.
index.php then tells the user that 1) their applications are current 2)
some of their applications are out of sync 3) no db exists, etc. For a
new install, all applications will be out of sync, since there is not
even an 'phpgw_applications' table in the database to tell setup what
the status is for any application.
Selection
There is no selection for application installs in 'new install' mode.
All physically present applications will be installed, or at least
attempted.
Installation
Once the setup user clicks the magic button to install all
applications, the following occurs:
* The setup_info array is passed to the
process_pass() function, using a method='new'
* Applications whose status flag='U' (API on first
pass) are then handed off to the process_current() function. This
handles inclusion and installation of the application's
tables_current.inc.php file.
* The application is registered as a new application
in the 'phpgw_applications' table. If for some reason there is old data
in this table for this application, it will be updated instead. Its
hooks, if any, are registered in the 'phpgw_hooks' table.
* Next, this array is passed to the
process_default_records() function. If this file is present in the
current application's setup directory, the queries here are run to
install the data to the application's table(s).
* The above is repeated until all application status
flags equal 'C'. However, if an application install failed for some
reason, it will then be skipped on the next pass. This keeps the loop
from running away.
4.3 Upgrades
Detection
Only an API version mismatch will trigger an automated request for the
user to upgrade their install. Once the api is current, they can move
on to applications.php for more 'Advanced Application Management',
which is Step 4 of the setup process. However, if the API is out of
sync, clicking 'Upgrade' in index.php will also attempt to upgrade
other applications which may be out of sync, as well. As the phpgwapi
continues to stabilize, it is felt that this method of upgrading will
become less and less common.
Selection
Within applications.php, a color-coded matrix of application status and
actions is displayed. Depending on the status flag of each application,
certain actions will be either enabled or disabled. These actions
include 'install', 'upgrade', 'remove'. If something is very wrong with
previous attempts to install or upgrade an application, another column
called 'resolution' will then display a link. This link will display
additional information which would be helpful for determining how to
resolve the problem. Assuming all is well, the user can select
applications requiring upgrade from this list. Once selected, they
submit the form. This runs the follow three routines in order:
* remove
* install
* upgrade
Upgrade
The idea here is that multiple actions can be selected and run in order
in one click. In any case, once they select an application for upgrade,
the following occurs:
* A stripped down version of the setup_info array is
passed to the process_upgrade() function. This array contains only the
information for the selected application
* Within process_upgrade(), the
tables_baseline.inc.php file for the application is loaded.
* The tables_update.inc.php file for the application
is loaded
* The contents of the test array is used to loop
through the entire list of upgrade functions for the application. The
application's unique function names are rebuilt, then run.
* When the currentver (installed) matches the
version (available), process_upgrade() exits, setting the status flag
for the app to 'C'.
* Just prior to exiting, the application and its
hooks are updated into the 'phpgw_applications' and 'phpgw_hooks'
tables.
4.4 Uninstallation/Removal
Selection
Selective removal of an application is done via applications.php, in a
manner similar to the method above for upgrades.
Uninstallation
Once an application is selected for removal:
* A stripped down version of the setup_info array is
passed to the process_droptables() function. This function removes all
of the application's defined tables, but only after first checking to
see if the tables are there. In this way, we attempt to cut down on the
number of errors sent to the browser.
* The application's hooks are deregistered (removed
from 'phpgw_hooks').
* The application itself is deregistered (removed
from 'phpgw_applications').
5. Caveats
5.1 Must see info
Auto fields
For auto type fields, schema_proc creates a sequence automatically
based on the table name for databases that require sequences. In the
case of postgresql, the limit for this name based on our tests is 31
characters. The schema_proc format is:
$sSequenceSQL = sprintf("CREATE SEQUENCE seq_%s", $sTableName);
This limits the maximum length for a tablename to 27 characters. Based
on the tablename standard in phpgw of 'phpgw_tablename', you are
further limited to 21 characters in which to describe your table. You
will need to be less descriptive in some cases, e.g. use
'phpgw_widget_cats' instead of 'phpgw_widget_info_categories'.
To maintain compatibility with MySQL 3.22.X, please always add
"'nullable' => False" to your field spec for an auto field. This and
probably older versions of MySQL require that specification within the
SQL for a field that will also be an index or unique field, which for
our uses should typically be true for an auto field. MySQL 3.23.X and
PostgreSQL do not have this issue.
Default 0
For int fields, a default of 0 is not assumed. Only some databases will
set this default for you, MySQL being one. You will need to explicitly
define this default in the table definition. Also, for auto fields, do
not enter a default, since the resulting SQL query would fail on many
RDBMS.
Coding Standards
* Format your code so that we can read it, please!
* Use tabs for formatting, NOT SPACES. Tabs create
smaller files and editors allow developers to view a tab as however
many spaces as they prefer. Spaces do not allow this. There is one
exception (see arrays below).
* Use ' instead of " for strings. This is a
performance issue, and prevents a lot of inconsistent coding styles.
* Use the Standard Header in the top of all your
scripts
* Comments go on the line ABOVE the code, NOT to the
right of the code!
* For each section of code put a section divider
with basic explanation of the following code/functions. It should look
like this:
/****************************************************************************\
* These functions are used to pick my
nose
*
\****************************************************************************/
* Do not document every bit of code in comments. PHP
is an interpreted language and it will be nasty on performance.
* Use switch statements where many elseif's are
going to be used. Switch is faster and I like it better!
* If' statements need to use the following format:
if ($var == 'example')
{
echo 'This is only an example';
}
else
{
echo 'This is not a test.
This is the real thing';
}
//Do NOT make if statements like this:
if ($var == 'example'){ echo 'An example'; }
* All other styles are not
to be used.
* ALL 'if' statements MUST have matching { }
(brackets). Do NOT create 'if' statements like this:
if ($a == b)
dosomething();
//or:
if ($a == b) dosomething();
* They make the code more
difficult to read and follow.
* class/function format:
class testing
{
function print_to_screen()
{
global phpgw,
phpgw_info;
if ($var ==
'example')
{
echo 'This is only an example';
}
else
{
echo 'This is not a test. This is the real thing';
}
}
}
* Associative arrays must be written in the
following manner:
$array = array
(
'var' =>
'value',
'var2' =>
'value2'
);
* Note that tabs are
preferred around the '=>'.
* Use the long format for <?php. Do NOT use <?.
* All code should start with 1 tab. Example:
<?php
dosomething();
if ($a)
{
dosomemorestuff();
}
//NOT:
<?php
dosomething();
if ($a)
{
dosomemorestuff();
}
* Use lower case for variable and function names. No
stubbly-case (mixed-case) code.
//correct
var $my_var;
function my_function()
//incorrect
var $MyVar;
function MyFunction()
Thanks for following these rules :)
eGroupWare Dependencies
eGroupWare is extremely flexible, and so there are many optional
dependencies. The dependecies are categorized below.
PHP
The current stable version of eGroupWare will run on any version of php
4.1.0+.
Databases
You must have a database, any of the following are currently supported.
* MySQL 3.23.x
* PostgreSQL - 7.2.x
* SQLServer - ??
* Orcale - coming soon?
* SAP - been mentioned
NOTE: You must have support for the database included in php
Developers please refer to this [RDMS functionality X reference] when
developing your apps
LDAP
LDAP can be use for storing account or contact data in eGroupWare.
* OpenLDAP
* Netscape Directory Server -??
NOTE: You must have support for LDAP included in php
Mail Servers
eGroupWare supports various mailservers
Courier-IMAP
Cyrus-IMAP
UW-IMAP
MS Exchange IMAP access (5.5 tested)
NOTE: You must have support for IMAP included in php to use the default
email client
NOTE for POP3: if you only want to use POP3, not imap, then it is
possible to use AngleMail without PHP-IMAP module installed. This
applies ONLY for POP3 servers. However it is still recommended to have
php with the PHP-IMAP module installed because this configuration also
works with POP3 and is somewhat better supported - Angles.
ACL - Access Control Lists
Allows to grant other people access to your data on a per user of per
group basis.
The principle of the ACL is to grant access, that means:
* you can say: user x or group y are allowed to read
my data
* the admin can say: all members of group x allow
each other or an other group or user to access there data
* access can be granted for the following levels
(and each mixture of them):
o read - read
non-privat (!) data
o edit - change
data
o add - add new
entries
o delete -
delete data
o privat -
access data marked as privat (can not be granted on group-level))
* not all eGroupWare applications have ACL and/or
all of the above levels implemented
Where to set these grants / the ACL:
1. on a per user basis, each user can do it in his
preferences for each app: Grant access
2. on a per group basis, an admin can set it in admin /
group-manager (Group accounts) by clicking on the blue squares behind
some app (not all apps implement group level ACL)
good ACL practices for admin's
* create groups by function and assign people to
them, have one group with all users
* assign ACL's only on group level
Examples
* Set up a group so that they can eg. read / see
each others calendar:
This can be archived most easy with a group-ACL's.
That way it works not only for users who are in that group at the
moment, but also for users added later and its automaticaly removed if
the user is removed from that group. Go to 'Admin / Group accounts' and
edit the concerned group. In the edit view click on the blue square in
the ACL column behind the calendar app. This will open another window
with the ACL for that group and the calendar app. Now you check
read-access for the group itself.
* Allow a secretary to "manage" my calendar:
Manage means for me he has to be able to add
appointsments in my calendar and confirm them on my behalf. You have to
grant him read, edit and add access to your calendar. Go to your
preferences and start Calendar / Grant access. Check read, edit and add
for that user. He can then select your calendar in any view and add
appointsments to it.
If you have question or more content please add it to this page or mail
them to ralfbecker
Categories help to organize the data in different eGroupWare
applications.
Example: You might create a categorie 'Customers' and assign it in the
AddressBook to each address/contact which is a customer. You can now
use it to show only the customers. To do so you have to select that
Categorie in the List of the AddressBook.
Most of the apps support the phpGW categorie system and there are 3
kind of categories:
* Global Categories: the are availible for all apps
and all users. Only Admins are allowed to create global cats (go to
Administration / Admin / Global Categories).
* Application-global Categories: the are availible
for all users but only in the app they are created for. They can also
only be created by Admin's, like the global categories (go to
Administration / the appalication / Global Categories).
* User Categories: these categories can be added by
each user in his preferences.
Which type of categorie to use: If u need a categorie for more then one
app, make it a Global categorie (eg. the 'Cusomter' cat might be
usefull in other apps too). If you need a categorie only in one app
make it an Application-global Categorie. And last but not least, if you
no admin, or your categories are not useful for other users make it a
User Categorie.
Categories can be aranged hierachical, so u can have sub-categories
like 'customers / first time' or 'customer / key accounts'.
In the planner view in Calendar categories can be used to assign colors
to each categoris of appointments / events. To do so, add the color as
rgb-value after the description (eg. '#FF0000' for red).
Categories help to organize the data in different eGroupWare
applications.
Example: You might create a categorie 'Customers' and assign it in the
AddressBook to each address/contact which is a customer. You can now
use it to show only the customers. To do so you have to select that
Categorie in the List of the AddressBook.
Most of the apps support the phpGW categorie system and there are 3
kind of categories:
* Global Categories: the are availible for all apps
and all users. Only Admins are allowed to create global cats (go to
Administration / Admin / Global Categories).
* Application-global Categories: the are availible
for all users but only in the app they are created for. They can also
only be created by Admin's, like the global categories (go to
Administration / the appalication / Global Categories).
* User Categories: these categories can be added by
each user in his preferences.
Which type of categorie to use: If u need a categorie for more then one
app, make it a Global categorie (eg. the 'Cusomter' cat might be
usefull in other apps too). If you need a categorie only in one app
make it an Application-global Categorie. And last but not least, if you
no admin, or your categories are not useful for other users make it a
User Categorie.
Categories can be aranged hierachical, so u can have sub-categories
like 'customers / first time' or 'customer / key accounts'.
In the planner view in Calendar categories can be used to assign colors
to each categoris of appointments / events. To do so, add the color as
rgb-value after the description (eg. '#FF0000' for red).
Timed Asynchron Services vor eGroupWare
This general API interface allows all app's to start tasks at certain
times.
Eg. the user should get
* a notification, if a delegated task in InfoLog is
not started / finished at the given start- / endtime (notification not
received from the user its delegated to).
* an alarm from the calendar for a Meeting or for a
sheduled Phonecall in InfoLog
* the backup app should run nightly at 2am.
Installation
For windows follow the installation instructions at
TimedAsyncServicesWindows
On a Linux or other *nix system you usualy only have to hit the
[Install crontab] button.
The asyncservices are tested on the following linux-systems now:
* SuSE 8.0+: tested by ralfbecker
The webserver-user 'wwwrun' needs to be included in
the group 'trusted', to be able to call the crontab command
* Debian Woody: tested on the phpgroupware.org by
ralfbecker
Problem was the php4-binary is called php4 (not php)
and the db-support is not compiled in the cgi-binary by default. This
is solved now (the class checks for a php4 binary and loads dl() the
db-support).
* Redhat: acording to ReinerJ
* Mandrake: tested
You need to include the webserver-user 'apache' into
/etc/cron.allow, to allow the webserver to use the crontab command
* Gentoo: tested by knecke
You need to include the webserver-user 'apache' into
the group 'cron', to allow the webserver to use the crontab command
If you or your system-administrator dont want to give the webserver the
right to make "his" own crontab entries. You can do it manualy by
adding the following line to your /etc/crontab:
* /5 * * * * <webserver-user> /usr/bin/php -q
<eGW-install-dir>/phpgwapi/cron/asyncservices.php <domain>
Eg. for a standard install on redhat:
* /5 * * * * apache /usr/bin/php -q
/var/www/html/phpgwapi/cron/asyncservices.php default
Now you can log into eGW and go to Admin >> Async Services. As
you now manualy installed the crontab entry, you should select Disabled
(not recomended) for running the asyncservice. If you hit update, you
can check that the asyncservice is (still) called by "crontab".
Please let me know if you have problems with the service or the testjob.
General Documentation
All this can not be done with the normal approach of a web-based
application. Some app's have included scripts, to be installed as cron
jobs (eg. backup).
The new class offers standard eGW service where all app's can register
timer, some data and a callback-methode. That service calls the given
methode with the data at the given time (or repetivly), if the timer is
not canceled before.
Status of the implemenation
The class is up and running in eGW. By default it is only running in
the Fallback mode, which means it only checks for jobs to run after
each page-request. This methode should run on any platform. On a linux
system the service can be run via cron. To do so, you have to go to
Admin -> Async Services and hit [install crontab] (if you havn't do
so already). If it shows no errors you should be able to change run
async service to 'crontab (recomended)'.
If you get an error-message its probably because your webserver-user is
not allowed to use the 'crontab' command. See the next section on how
to change that for your distribution.
If the service is installed in the crontab and runs via 'crontab', you
can test it by starting the test-job. It sends u a mail every 5min (or
what ever times u used when installing it).
How to implement that in a portable (*nix and win) and stable way ?
This can hardly be done in one way only, we need several methodes the
admin can choose from and a default that works without further actions:
1. Fallback Mode: is called on every page-request of any
user and checks if any timer is ready to run.
* Benefits: does
not need any special installation
* Drawbacks: can
not garantee a in-time delivery (depending on the user of the whole
system), might be a performance penality for big installations
2. Crontab: admin installs it via phpGW admin ->
asyncron services to run every 1, 5, 10, ... minutes.
* Benefits:
garanties delivery times in the given frequenz of the script-calls and
is realy asnychron (no user has to wait for the script to do its job)
* Drawbacks:
*nix only, needs the cgi-binary of php and has to be installed by admin
(see above)
3. Service under NT: this could be the NT counterpart for
the cronjob -- not yet implemented / I have no win-system ;-)
function set_timer($time,$id,$methode,$data)
$time:
unix timestamp or array('min','hour','day','month','year') with
execution time. Repeated events are possible to shedule by setting the
array only partly, eg. array('day' => 1) for first day in each month
0am or array('min' => '*/5','hour' => '9-17') for every 5mins in
the time from 9am to 5pm.
$id:
unique id to cancel the request later, if necessary. Should be in a
form like eg. '<app><id>X' where id is the internal id of
app and X might indicate the action.
$methode:
Methode to be called via ExecMethode($methode,$data). $methode has the
form '<app>.<class>.<public function>'.
$data:
This data is passed back when the method is called. It might simply be
an integer id, but it can also be a complete array.
Returns: False if $id already exists, else True
function cancel_timer($id)
Cancels the timer, $id has to be the one used to set it.
Returns: true if the timer exists and is not expired.
Implementation
DB table
'phpgw_timer' => array(
fd => array(
'id' => array('type'
=> 'varchar', precission => '255', 'notnull' => 'True'), //
unique id
'next' => array('type'
=> 'int', precission => '4', 'notnull' => 'True'), // the
timestamp of the next call
'times' => array('type'
=> 'varchar', 'precission' => '256', 'default' => ''), //
serialized array for repetive timers, $time param
'method' => array('type'
=> 'varchar', 'precission' => '80', 'notnull' => 'True'), //
$method param
'data' => array('type'
=> 'text') // serialized $data param
),
'pk' => array('id'),
'fk' => array( ),
'ix' => array('next'),
'uc' => array( )
);
General Implemenation
set_timer() calculates the next run of the timer and puts that with the
rest of the data in the db.
check_run() is called eg. by the cron-script and querys all timers with
expired next time and executes there methode with the given data. If
the times field is not empty the next execution time is calculated and
the db updated with it, else the row is deleted.
cancel_timer() querys the db for the given id and deletes the row
* NT/W2K has a at service. This is like the cron
daemon. Linux has the at daemon too. (lkneschke)