From 94b13882e9b724d96f9c87f786923d1586cf3b59 Mon Sep 17 00:00:00 2001 From: seek3r Date: Mon, 18 Dec 2000 20:09:56 +0000 Subject: [PATCH] adding new dir structure for the api --- phpgwapi/cron/clean_database.pl | 18 + phpgwapi/cron/stalesessions.php | 21 + phpgwapi/cron/stalesessions.pl | 84 + phpgwapi/doc/CHANGELOG | 444 ++++ phpgwapi/doc/CREDITS | 87 + phpgwapi/doc/LICENSE | 342 +++ phpgwapi/doc/README | 1 + phpgwapi/doc/RELEASE-NOTES | 2 + phpgwapi/doc/SECURITY | 27 + phpgwapi/doc/index.html | 2011 +++++++++++++++++ phpgwapi/doc/index.txt | 706 ++++++ phpgwapi/footer.inc.php | 43 + phpgwapi/phpgw.inc.php | 418 ++++ phpgwapi/phpgw_accounts_ldap.inc.php | 310 +++ phpgwapi/phpgw_accounts_shared.inc.php | 289 +++ phpgwapi/phpgw_accounts_sql.inc.php | 228 ++ phpgwapi/phpgw_addressbook.inc.php | 16 + phpgwapi/phpgw_auth_http.inc.php | 27 + phpgwapi/phpgw_auth_ldap.inc.php | 47 + phpgwapi/phpgw_auth_mail.inc.php | 43 + phpgwapi/phpgw_auth_sql.inc.php | 39 + phpgwapi/phpgw_calendar.inc.php | 1483 ++++++++++++ phpgwapi/phpgw_categories.inc.php | 95 + phpgwapi/phpgw_common.inc.php | 983 ++++++++ phpgwapi/phpgw_crypto.inc.php | 123 + phpgwapi/phpgw_db_msql.inc.php | 143 ++ phpgwapi/phpgw_db_mssql.inc.php | 146 ++ phpgwapi/phpgw_db_mysql.inc.php | 394 ++++ phpgwapi/phpgw_db_odbc.inc.php | 172 ++ phpgwapi/phpgw_db_oracle.inc.php | 432 ++++ phpgwapi/phpgw_db_pgsql.inc.php | 259 +++ phpgwapi/phpgw_db_sybase.inc.php | 133 ++ phpgwapi/phpgw_info.inc.php | 120 + phpgwapi/phpgw_lang_sql.inc.php | 77 + phpgwapi/phpgw_network.inc.php | 187 ++ phpgwapi/phpgw_nextmatchs.inc.php | 341 +++ phpgwapi/phpgw_send.inc.php | 248 ++ phpgwapi/phpgw_session.inc.php | 185 ++ phpgwapi/phpgw_template.inc.php | 346 +++ phpgwapi/phpgw_todo.inc.php | 83 + phpgwapi/phpgw_utilities.inc.php | 44 + .../phpgw_utilities_clientsniffer.inc.php | 329 +++ phpgwapi/phpgw_utilities_http.inc.php | 467 ++++ phpgwapi/phpgw_utilities_matrixview.inc.php | 304 +++ phpgwapi/phpgw_utilities_menutree.inc.php | 310 +++ phpgwapi/phpgw_utilities_rssparse.inc.php | 237 ++ phpgwapi/phpgw_utilities_sbox.inc.php | 141 ++ phpgwapi/phpgw_vfs.inc.php | 362 +++ phpgwapi/templates/default/frames.tpl | 7 + phpgwapi/templates/default/frames_body.tpl | 3 + phpgwapi/templates/default/frames_navbar.tpl | 3 + phpgwapi/templates/default/login.tpl | 61 + .../templates/default/login_denylogin.tpl | 14 + .../templates/default/login_selectdomain.tpl | 63 + phpgwapi/templates/default/navbar.tpl | 6 + phpgwapi/templates/default/navbar_column.tpl | 3 + phpgwapi/templates/default/navbar_row.tpl | 6 + phpgwapi/themes/blue.theme | 34 + phpgwapi/themes/default.theme | 40 + phpgwapi/themes/fancy.theme | 40 + phpgwapi/themes/greys.theme | 32 + phpgwapi/themes/heaven.theme | 35 + phpgwapi/themes/mojo.theme | 35 + phpgwapi/themes/rose.theme | 25 + phpgwapi/themes/submarine.theme | 35 + phpgwapi/themes/template2theme.pl | 23 + phpgwapi/themes/theme.template | 36 + phpgwapi/themes/theme2template.pl | 18 + phpgwapi/themes/yellows.theme | 35 + 69 files changed, 13901 insertions(+) create mode 100755 phpgwapi/cron/clean_database.pl create mode 100755 phpgwapi/cron/stalesessions.php create mode 100755 phpgwapi/cron/stalesessions.pl create mode 100644 phpgwapi/doc/CHANGELOG create mode 100644 phpgwapi/doc/CREDITS create mode 100644 phpgwapi/doc/LICENSE create mode 100644 phpgwapi/doc/README create mode 100644 phpgwapi/doc/RELEASE-NOTES create mode 100644 phpgwapi/doc/SECURITY create mode 100644 phpgwapi/doc/index.html create mode 100644 phpgwapi/doc/index.txt create mode 100644 phpgwapi/footer.inc.php create mode 100644 phpgwapi/phpgw.inc.php create mode 100644 phpgwapi/phpgw_accounts_ldap.inc.php create mode 100644 phpgwapi/phpgw_accounts_shared.inc.php create mode 100644 phpgwapi/phpgw_accounts_sql.inc.php create mode 100644 phpgwapi/phpgw_addressbook.inc.php create mode 100644 phpgwapi/phpgw_auth_http.inc.php create mode 100644 phpgwapi/phpgw_auth_ldap.inc.php create mode 100644 phpgwapi/phpgw_auth_mail.inc.php create mode 100644 phpgwapi/phpgw_auth_sql.inc.php create mode 100644 phpgwapi/phpgw_calendar.inc.php create mode 100644 phpgwapi/phpgw_categories.inc.php create mode 100644 phpgwapi/phpgw_common.inc.php create mode 100644 phpgwapi/phpgw_crypto.inc.php create mode 100644 phpgwapi/phpgw_db_msql.inc.php create mode 100644 phpgwapi/phpgw_db_mssql.inc.php create mode 100644 phpgwapi/phpgw_db_mysql.inc.php create mode 100644 phpgwapi/phpgw_db_odbc.inc.php create mode 100644 phpgwapi/phpgw_db_oracle.inc.php create mode 100644 phpgwapi/phpgw_db_pgsql.inc.php create mode 100644 phpgwapi/phpgw_db_sybase.inc.php create mode 100644 phpgwapi/phpgw_info.inc.php create mode 100644 phpgwapi/phpgw_lang_sql.inc.php create mode 100644 phpgwapi/phpgw_network.inc.php create mode 100644 phpgwapi/phpgw_nextmatchs.inc.php create mode 100644 phpgwapi/phpgw_send.inc.php create mode 100644 phpgwapi/phpgw_session.inc.php create mode 100644 phpgwapi/phpgw_template.inc.php create mode 100644 phpgwapi/phpgw_todo.inc.php create mode 100644 phpgwapi/phpgw_utilities.inc.php create mode 100644 phpgwapi/phpgw_utilities_clientsniffer.inc.php create mode 100644 phpgwapi/phpgw_utilities_http.inc.php create mode 100644 phpgwapi/phpgw_utilities_matrixview.inc.php create mode 100644 phpgwapi/phpgw_utilities_menutree.inc.php create mode 100644 phpgwapi/phpgw_utilities_rssparse.inc.php create mode 100644 phpgwapi/phpgw_utilities_sbox.inc.php create mode 100644 phpgwapi/phpgw_vfs.inc.php create mode 100644 phpgwapi/templates/default/frames.tpl create mode 100644 phpgwapi/templates/default/frames_body.tpl create mode 100644 phpgwapi/templates/default/frames_navbar.tpl create mode 100644 phpgwapi/templates/default/login.tpl create mode 100644 phpgwapi/templates/default/login_denylogin.tpl create mode 100644 phpgwapi/templates/default/login_selectdomain.tpl create mode 100644 phpgwapi/templates/default/navbar.tpl create mode 100644 phpgwapi/templates/default/navbar_column.tpl create mode 100644 phpgwapi/templates/default/navbar_row.tpl create mode 100644 phpgwapi/themes/blue.theme create mode 100644 phpgwapi/themes/default.theme create mode 100644 phpgwapi/themes/fancy.theme create mode 100644 phpgwapi/themes/greys.theme create mode 100644 phpgwapi/themes/heaven.theme create mode 100644 phpgwapi/themes/mojo.theme create mode 100644 phpgwapi/themes/rose.theme create mode 100644 phpgwapi/themes/submarine.theme create mode 100755 phpgwapi/themes/template2theme.pl create mode 100644 phpgwapi/themes/theme.template create mode 100755 phpgwapi/themes/theme2template.pl create mode 100644 phpgwapi/themes/yellows.theme diff --git a/phpgwapi/cron/clean_database.pl b/phpgwapi/cron/clean_database.pl new file mode 100755 index 0000000000..f5ac6c7c5a --- /dev/null +++ b/phpgwapi/cron/clean_database.pl @@ -0,0 +1,18 @@ +#!/usr/bin/perl + +use DBI; + +$db_host = 'localhost'; +$db_name = 'phpGroupWare'; +$db_user = 'phpgroupware'; +$db_pass = 'phpgr0upwar3'; + +$dbase = DBI->connect("DBI:mysql:$db_name;$db_host",$db_user,$db_pass); + + +$command = $dbase->do("delete from webcal_entry"); +$command = $dbase->do("delete from webcal_entry_user"); +$command = $dbase->do("delete from webcal_entry_groups"); +$command = $dbase->do("delete from webcal_entry_repeats"); + +$dbase->disconnect(); diff --git a/phpgwapi/cron/stalesessions.php b/phpgwapi/cron/stalesessions.php new file mode 100755 index 0000000000..81e0941de2 --- /dev/null +++ b/phpgwapi/cron/stalesessions.php @@ -0,0 +1,21 @@ + diff --git a/phpgwapi/cron/stalesessions.pl b/phpgwapi/cron/stalesessions.pl new file mode 100755 index 0000000000..7006f5eec5 --- /dev/null +++ b/phpgwapi/cron/stalesessions.pl @@ -0,0 +1,84 @@ +#!/usr/bin/perl +# /**************************************************************************\ +# * phpGroupWare * +# * http://www.phpgroupware.org * +# * Written by Joseph Engo * +# * -------------------------------------------- * +# * This program is free software; you can redistribute it and/or modify it * +# * under the terms of the GNU General Public License as published by the * +# * Free Software Foundation; either version 2 of the License, or (at your * +# * option) any later version. * +# \**************************************************************************/ + +use DBI; + +# Config section + +$db_host = 'localhost'; +$db_name = 'phpGroupWare'; +$db_user = 'phpgroupware'; +$db_pass = 'phpgr0upwar3'; + +# Email users when they don't log out ? +# If you are selecting this option. You might want to customize the message +# below. + +# Note: This takes much longer to clean out the database each time. Since it +# must go select each user and then email them. + +$email_user = 'Y'; +$sendmail_location = '/usr/sbin/sendmail'; + +# Where should the message be comming from ? +$message_from = "webmaster\@athens.prv"; + +# This is how long a user can be at idle before being deleted. Look at the +# SECURITY file for more information. +# The default is set to 2 hours. + +$secs_to_stale = '3600'; + + +# uncomment the line for your database. +# mysql +$dbase = DBI->connect("DBI:mysql:$db_name;$db_host",$db_user,$db_pass); +# postgresql +#$dbase = DBI->connect("DBI:Pg:dbname=$db_name;host=$db_host",$db_user,$db_pass); + +# End of config section + +$staletime = time() - $secs_to_stale; + +if ($email_user eq 'Y') { + $command = $dbase->prepare("select loginid,logintime,ip,sessionid from " + . "sessions where dla <= '$staletime'"); + $command->execute(); + + while (@session_data = $command->fetchrow_array()) { + send_message($session_data[0],$session_data[1],$session_data[2]); + $command2 = $dbase->do("delete from sessions where sessionid='" + . "$session_data[3]'"); + } +} else { + $command = $dbase->do("delete from sessions where dla <= '$staletime'"); +} + +#$command->finish(); +$dbase->disconnect(); + +sub send_message($$$) +{ + my($loginid, $logintime,$IP)=@_; + open ( SENDMAIL, "|$sendmail_location -t" ) || warn "Can't open sendmail"; + print SENDMAIL "To: $loginid\@localhost\n"; + print SENDMAIL "Subject: Important account information\n"; + print SENDMAIL "From: $message_from\n\n"; + print SENDMAIL "According to our records, you have not logged out during "; + print SENDMAIL "your recent session. It is important to that you click "; + print SENDMAIL "on the logout icons when done with your session. "; + print SENDMAIL "\nFor more information, contact your system admin.\n\n"; + print SENDMAIL "Session information:\n"; + print SENDMAIL "logintime: " . localtime( $logintime ) . "\n"; + print SENDMAIL "IP Address: " . $IP . "\n.\n"; + close ( SENDMAIL ); +} diff --git a/phpgwapi/doc/CHANGELOG b/phpgwapi/doc/CHANGELOG new file mode 100644 index 0000000000..4a51dfb7d5 --- /dev/null +++ b/phpgwapi/doc/CHANGELOG @@ -0,0 +1,444 @@ +[0.9.8] - Merged in patch for UW-Maildir IMAP server support + Thanks milosch + - Fixed setup not detecting installed databases with PHP 3 + - Fixed repeating entries being saved properly. + - Added ability for admin to edit any calendar event. + - Fixed entries showing improperly on wrong date. + - Fixed file uploads through filemanager. + - Fixed repeating entries Month select box. + - Fixed calendar week selector starting on Monday on footer. + - Fixed buggy calendar saving when no groups are selected with group access. + - Fixed submitting of calendar entry when javascript turned off. + - Fixed calendar preferences not updating properly + - Fixed denylogin form not display and converted it to a template. + - Added select box option for multiable domains in login.php + - Fixed proxy server support for headlines and check for new version on main screen. + - Fixed headlines preferences and converted headline preferences to a template + - Fixed pgsql upgrade from beta path. + - Fixed chronological ordering of calendar events. + - Changed javascript validation to server side upon submitting calendar events. + - Merged patch for parsing of non-compliant rfc822 email addresses. + Thanks bwulf + - Fixed the addressbook not opening when composing email. + - Applied patch to fix md5 en/decryption. + Thanks milosch + - Fixed login message not showing up. + - Added in feature for frames. This can be a user preference, or a global option + for the admin to disable, allow, or force. + - Added in a few preformace tweaks that will use serialize() and unserialize() for + dropping the phpgw_info array into the session table durring login. + - Changed a few of the icons to our news ones. + - Fixed 12 am/pm problem in calendar. + - Added default filter to calendar preferences. + +[0.9.7] - Fixed SQL error in tts + - Fixed table locking in admin -> edit account + - Added capability to schedule others and not yourself to calendar. + - Fixed d/l'ing of files through filemanager. + - Enhanced Free/Busy calendar view. + - Fix for repeating events not showing in calendar. + - Fix for Day View warning in calendar. + - Fix for TTS with Update by non-email user. + - Fixed admin/accesslog.php wasn't using phpgw_access_log + - Fix for Week View warning in calendar. + - Fix for Matrix View not working with Netscape 6. + - Added text only feature for navbar + - Converted navbar to work off templates + - Merged in patch for filemanager to fix upload in SAFE_MODE + Thanks s837008 + - Cleaned up mainscreen message section, you can also have a login screen message now. + - Merged in update for french + - Merged in update for Spanish + Thanks gmartine + - Merged in patch for calendar for year view + Thanks bwulf + - session class will now use the HTTP_X_FORWARDED_FOR if a user is behind a proxy server. + - Merged in patch to fix the addressbook not displaying all of the fields. + Thanks ydario + - New Calendar table structures and code. + - Applied patch to fix set_time_limit() warnings in safe_mode + Thanks count + - Fixed warning messages in EMail with/without CC header info. + - Fixed errors for TTS mailings. + (This was actually a problem with email, users not having a + Sent folder. Sent Folders automatically created if not exist.) + - Fixed matrixview warnings when viewing manual. + - Fixed problem with moving to prev/next msg in NNTP. + - Fix possible problem connecting to LDAP server. + - Fix home page display of calendar events. + - Added ability to set users defaut calendar view of top icon. + - Changed calednar duration to a true date/time. + - Added ability to filter calendar events based on access. + - Merged in patch adding free() to the pgsql db. + Thanks count + +[0.9.6] - Fix user permissions where not being checked properly. + +[0.9.5] - Fixed NNTP preferences. + - Fixed NNTP read_message - missed converting call for VFS. + - Fixed calendar view of events - change of convert_string_to_names_access(). + - Fixed deletion of user accounts hanging on deleting of calendar events. + - Fix for email in BIG5 charset. + - Fix for adding new users. + - Fixed a bug that was casuing people to have problems logining in when using cookie support. + - Fixed calendar display of 12 hour formats. + - Fixed a few problems with admin -> editaccount not changing the directory name properly. + - Fixed the languages table was using the lang name in upper case while everything else + was using lowercase. + - Added admin section to be able to add legal notices or other messages on the main screen. + Thanks snerd for this idea. + - Added matrix view of individuals and calendar events. + - Fixed parent_page link on footer line. + +[0.9.4] - Fixed calendar week view. + - Displays calendar items in day view without start times. + - You now have to specify which API classes need to be loaded. + - Preformance is much better. + - Fixed a calendar SQL error with stock setups using the demo user. + - Fixed a problem with the email folders only reporting back the number of messages + in the INBOX regardless of which folder it is in. + - Added calendar day view to home page. + - Fixed problem with deletion of accounts. + - Fixed a few problems with error reporting in the accounts section. + Thanks mdean + - Renamed the webcal_entry.cal_create_by field to webcal_entry.cal_owner. + - Split out auth class, so that you can auth from anywhere and still store your accounts in sql or ldap. + - Added mail auth class, that will authenticate users against their email accounts + - Added multiple domain support. + - Fixed a few problems with the categories class + - Fixed nextmatchs calling link() wrong causing the next pages to not be displayed. + - Removed javascript from the login template + - Fixed HTML error in the application status select box for admin -> new/edit application + - Fixed group public filters in addressbook and todo list + - Cleanup up templates in admin section and created a few new templates. + +[0.9.3] - Fixed the new user account form not returning the users firstname or last name when an + error is reported. + - Fixed NNTP to handle new VFS api. + - Fixed a number of preferences bugs on the main screen. + - Fixed E-Mail sigs not being added. + - Moved E-Mail preferences into its own section. + - When changing NNTP servers, now deletes newsgroups and users_newsgroups. + - Applied Patch #102089 - scrollbars for addressbook when composing email. Thanks jaggdedge + - owner fields are now working off account_id instead of account_lid + - Fixed time format on calendar preferences. + - NNTP now uses preferences to store monitored newsgroups. + - Added better error checking in applications admin section. + - Applied Patch #102116 - qmail/vmail spaces in TO:,CC: fields sending email. Thanks jaggdedge + - Email Trash folder is now created if it doesn't exsist + - Added user preferences for sending messages to the trash or just deleteing them. + - Started working on LDAP support. Its some what functional right now, but please be carefull + it has not been fully tested or debugged. + - Fixed appsession() not decrypting data properly. + - mcrypt should be working correctly now. + - Fixed problem with email's addressbook not retrieving records. + - Applied patch for accounts->listusers(). Thanks Mathieu van Loon + - Fixed check for new version not working. + - Merged in patch for vcard support in addressbook. Thanks Qbert + - Merged in patch for better langague support based on iso-639 Thanks zaphod + - Fixed accesslog not showing the logout field properly. + - transy should now be somewhat usable. + - Added automatic email of changes to TTS tickets. + - Fixed show currentusers on navbar preference + - Added new categories class + - Fixed date preferences in todo list + - Added date preferences to addressbook for birthdays + - Fixed group access to calendar items. + +[0.9.2] - Fixed sorting bug in currentusers.php + - Cleaned up error reporting and form in newaccount.php + - Fixed viewaccounts.php not updated to the new accounts table. + - Fixed access_log not being updated durring logouts. + - Fixed email/folders.php not showing the number of messages in the INBOX. + - Fixed messages that where being passed around in the headlines admin section. + - Fixed setup script not working properly with certain version of MySQL. + - Fixed the participants list in the calendar. + - Fixed permission bug that was not checking users access to an app. + - Applied Patch #101453 - CJK character set display. Thanks Park ChungKyu + - Applied Patch #101321 - CZECH lang translation. Thanks Petr Moses + - Now ISO 639 compliant with language translation id. + - Applied Patch #101828 - Swedish lang translation. Thanks Kjell Claesson + - Fixed group management with new groups and navbar problems. + - Changed around the way the preferences work. The $phpgw_info array is also handled a little + differently for preferences. It now looks like: + $phpgw_info["user"]["preferences"][appname][preference name] + - Fixed NNTP call to preferences.php if user does not have any groups selected. + - Fixed setting of default preferences of new users. + - Updated Spanish translations. Thanks gmartine + - Default preferences used if not set in DB. + - NNTP fixed to use the new account table layout. + - NNTP Header problem fixed. + - Applied Patch #101934 - Updated Swedish lang translation. Thanks Kjell Claesson + - Fixed a problem with setup/index.php return a number of errors on fresh PostgreSQL databases. + +[0.9.1] - Fixed a few missing variables with templates. + - editing a product in the inventory program now forwards you back to the category + you where in. + - You can now use decimals in the inventory program. + - Added missing tables for tts and fixed problems with postgresql. + - Fixed changing of password not getting set in session table + - email now displays "Could not open mailbox" if mailbox could + not be opened (formerly displayed just "mailbox empty") + - Added ability to add/edit product status (inventory) + - Fixed displaying of repeated calendar events by owner + - Fixed displaying of calendar events to include group events + - Converted more of the inventory program to use templates + - Added a search field/add button when list products (inventory) + - Fixed editing of calendar entry with regards to start time + - Fixed sorting order in navbar when apps where assigned to a group. + - Fixed groups not being assinged an app properly. + - Fixed timeout for email receiving/sending. + - Changed the format for the accounts, sessions, and preferences tables. + - Started adding support for Oracle databases (Not working yet) + - Added new layout for admin and preferences sections. + - Fixed addressbook entries assigned to groups. + - Fixed accounts not using link() properly and kicking admin out of searchs. + - Removed globalconfig.inc.php and moved it into the database. Theres now a nice new + setup program. + - Updated docs a great deal. + - Group public items should now be working. + - Fixed a wrong data type error when calling sort() on 1 folder. + - Added week number in month view of calendar. (Patch by grasl) + - Moved charset setting from globalconfig.inc.php / DB to lang files. + - A bunch of other minor bug fixes. + +[09072000] - Added print icon that allows you to print out a page without having + the navbar. Thanks Sam Wynn Jr + - on group creation the files directory tried to be created in + "filemanager/groups/" instead of in "files/groups/" - fixed. + Same for the user directory. + - Added error checking for creating/editing an account with no permissions. + - Fixed a db->unlock() issue in editaccount.php + - Fixed a few $phpgw_flags out of place. + - Fixed a problem with attachments not handled properly + - Fixed email/folder.php + - Fixed a problem with link targeting and the navbar. + - Fixed kp3 not being passed properly in chat. + - Changed the icon for NNTP. + - Changed the way session->create() makes the random number. This should fix + the problems on NT. + - Added HTTP Proxy support to phpgw_network. + - Pop3: when a header line started with cc:, from:, ..., but + no information followed the colon, a bunch of error messages were + displayed ("xxx not an object"). Fixed. + - Inventory program now supports changeable status fields. + - Added feature to show minium in stock products in different colors. + - Added error checking for changing a group name to a name that already exsists + - Removed session->hidden_var(), use link() from now on. + NOTE: You need to make sure you use the POST method. GET will cause problems. + - Cookie sessionid support works a little better now. + - Started adding LDAP account authencation support. + - Converted session->loginid, session->firstname, session->lastname, session->con to store + this data in the phpgw_info array. + - Moved check_owner() from session class to common. + - Converted all working apps to use the new lang() function which uses a database instead of + the lang files. (Passing extra variables is not working perfect, yet) + +[08212000] - removed db_lock() and db_unlock() I changed the phpgw_db_* to use them + properly + - remove all remaining references to $dbase and $phpgw_db we are now using + $phpgw->db for database stuff + - Added unlock() in halt() for the database class. This should help prevent + database lockups if the program executes some invailed SQL. + - Moved around the directory layout. The include files and images are now + in the applications directory. + - You can now add permissions to a group, all users within that group + would be granted those permissions. + - NNTP now compatible with PHP3/PHP4. + - Fixed parse errors and footer problems with the calendars printer + friendly version. + - Fixed a problem with the groups directory not being deleted. + - Fixed a problem with not being able to add users to a group. + - Fixed bad links in calendar + - Added feature to be able to remove users from a group automaticly + - changetheme.php will now read the files in the directory. You no longer + need to edit it to add themes + - Fixed a problem with the default sorting order messing up the next matchs + while viewing a message + - Added feature to check for new releases of phpGW + - Added feature to filter out entrys only within a certain group. + This is for the todo list and addressbook. + - Added a search field and next matchs icons to accounts and groups form. + - Fixed the "code" messages not showing up after adding new entrys and what not. + - Started converting the admin section to work off templates + - Started converting the todo list to work off templates + - Added a few new themes + +[08152000] - Fixed a problem with the calendar not showing the months in the users + langague preference. + - Added the new alpha human resources section + - Added the new alpha inventory program + - Added new global var $phpgw_flags + replaces $currentapp, $noheader, $nonavbar + - Small change in the API with the lang files. + - Added missing files for french + - pop_sort() accelerated by using temp file for storing header + information - speed factor > 2 for re-sorts! + - Added a temp quick fix for PostgreSQL not working in the calendar + I am using the old code, so there might be bugs. This is + just until we can find a better solution. + - Added a warning message if users are still apart of a group thats + about to be deleted. + - a bunch of error messages where shown when some header info was + split into multiple lines (on pop account), and address info + could not be built in this case. Fixed. + - Added Dutch and Korean langague support + - Added default app and default sorting order preference + - Fixed multipart handling on pop3 + - Added config option for where the "Powered by" can go, top or bottom + - add/edit/delete accounts code has been cleaned up greatly. + - Better error control in the accounts section + - Fixed check_owner() in session class not reporting the owner properly + +[08072000] - Fixed current users next matchs icons not showing up properly + - Added support to save sent-messages into Sent folder + - Fixed bug where users always see the mail server connection + error on a new installation + - Added cookie support so you can save your session id as a cookie + - Fixed permission bug in preferences with anonymous users + - Fixed permission bug in calendar + - Greatly improved ftp app + - Started adding the new manager permission + - Added link in the admin section to find out your phpinfo() + - A few bug fixes in the admin section + +[08042000] - Fixed repeating events in calendar day view + - Started refering to modules as applications + - Fixed todo list not showing list properly + - Started adding new application layout + - Clean up documentation + - Added better german langague file support. + - Fixed addressbook not showing the group access properly + - Added nextmatchs to email + - Deleting a message will now forward you to the next message + instead of the inbox. + - Added spanish, Itailian and Norwegien lang files. + - EMail now supports POP-3 + - Next matchs icons in email + - Many other fixes and features that we can't remeber :) + +[07122000] - Added multi-langague support + - Added confirms before records are deleted. + - Fixed the footer not being called in the calendar + - Fixed the todo list not showing the list properly + - Added date format thanks vinz + - Renamed session.class to session.inc.php + - Added feature to allow stale uploads to be deleted on + systems that don't support cron + - Fixed calendar searchs + - Added preferences to have text under icons on navigation bar + +[07062000] - Fixed javascript pop-up window upadting wrong fields. + thanks vinz + - Fixed security hole in logout.php + - Added support support for todo list showing who created + the record. + - Added support for date due in todo list. + - Fixed bug in killsession.php thanks vinz + - Added support for day view in calendar + - Added support for hovering descriptions using the alt tag + - Added support for newsheadlines program + thanks Mark Peters + - The calendar sports a new layout. + - Started converting HTML to be HTML 4.0 complient + - Added new filemanager program + - New experimental look for the user section. + +[06302000] - Moved around the inc directorys for better security. + - Fixed the file attachments and parse errors. + - Fixed file uploads for Windows thanks vinz + - Added to bring you back to the same folder you are in + (email) thanks smoser + - Fixed directorys not be deleted properly and should + now work under windows. + - Updated docs a little + - Include pre-alpha release of trouble ticket system + - A few other small bug fixes. + +[06272000] - Updated most of the docs for the new name (phpGroupWare) + - Resolve a few issues with installing on PHP 4. + - editaccounts.php3 now updated the calendar tables properly + - Cleaned up groups.inc and removed no longer used and repeated code + - Fixed broken link in calendar + - Renamed all .php3 so program works in PHP 4. + - Added next and previous links in calendar year view + - Printer friendly version of the calendar no longer show the + navigation bar on top + +[06222000] - Fixed problem with timeformat only showing up if you have calendar + access. + - Added support to select from a few pre-defined date formats + Anyone have suggestions on some more ? + - Fixed problem with create_tables.mysql for calendar global events + thanks Vincent Larchet + - Added support for multiable file uploads. + - Fixed table locking issues in editaccount.php3 + - There is now a config option to point to a differant directory that webdistro is install on. + - A couple of other small bug fixes and code cleanup. + - Fixed a problem with email signatures not working + +[06172000] - Added db_lock() and db_unlock. That should fix the table locking + problems. + - Fixed problem with filtering in todo list. + - Fixed admin viewaccount.php3 not showing permissions properly. + +[06162000] - included new theme thanks Marl + - Made sure that the docs where included this time. + - Fixed javascript error in edit_entry.php thanks marvinhorst + - Fixed problem with edit_entry.php not including current users + loginid + - Renamed functions.inc to calendar.inc to make things easier to + understand. + - Renamed all .php file to .php3 + - Fixed small calendar days, Sa and Su where backwords. + - Removed cal_eventid from webcal_entry_repeats, wasn't needed and was causing problems. + - Fixed a few problems with create_tables.* + - Global public items should now work in the calendar + - Added feature to change users passwords (admin) + - Update some of the docs. + - Renamed and merged some files in the calendar. + - Added percent of users that logged out to accesslog + +[06092000] - Fixed lastlogin information that wasn't updating. + - Added table locks in edit_entry_handler.php (calendar) + - Added feature to annoy users that haven't changed there + password for more then 30 days. + - Added javascript popup window for addressbook in email + Thanks Brian King + +[06082000] - Added new groups class + - Combined permissions and preferences into session.inc + - Renamed session.inc to webdistro_common.inc + - Fixed blank items showing up in the todo list. + - Cleaned up create_tables.* Took out all of the uneeded things. + - Included a new theme, it looks pretty bad on some computers. + But, we need to test things out a little with it. + +[06052000] - Fixed a few permission bugs in the addressbook + - Started converting all programs to use the new session class + - Light code cleanup + - Fixed parse errors in a few places + - Added timezone support + - Updated stalesessions.pl + - Fixed a few possiable security problems with addressbook + +[06032000] - Fixed problems editing accounts using postgresql + - Fixed problems creating account in create_tables.* + - Admin section updated. Sorting features. New layout for current + sessions. + - login.php3 Fixed problem with it not updating users lastlogin + - Fixed problems with adding events to the calendar. + - Fixed problems with repeating events with a frequency of more + then 1. I think I have finally narrowed most of the problems + down. + - Addressbook had the city and street mixed. Thanks Eric Degner + - Added feature to show who created the addressbook entry. + I will add support for this in the todolist later. + - Cleaned up some unneeded files in some of the directorys. + - Added next and previous link in message.php3 for email. + - Converted program to start using the new permissions and + preferences class. + - Fixed session table for mysql + +[06022000] - Calendar bug fixes and code cleanup. + - Security fix for login.php3 diff --git a/phpgwapi/doc/CREDITS b/phpgwapi/doc/CREDITS new file mode 100644 index 0000000000..01106cdf46 --- /dev/null +++ b/phpgwapi/doc/CREDITS @@ -0,0 +1,87 @@ +### Core Developers ### + +* Joseph Engo (aka Jengo) +- Man who started it all. +- Provides project direction, documentation. +- Works on core services session management, permissions, groups class, etc... +- Wrote the following applications +--- Addressbook (orignal work) +--- ToDolist (orignal work) +--- Inventory (orignal work) +--- Email (Adapted from Aeromail, which was written by Mark Cushman http://the.cushman.net/) +--- Calendar (Adapted from WebCalendar, which was written by Craig Knudsen http://www.radix.net/~cknudsen) +- Continues development and project direction. + +* Dan Kuykendall (aka Seek3r) +- Project Administrator/Supervisor. +- Provides project direction, documentation. +- Works on core services such as the $phpgw[] array for application developers. +- Hosts website, and offers commercial support thru Clear River Technologies (http://www.clearrivertech.com) +- Wrote the following applications +--- File Manager (Based on filemanager, which was written by Lacey Pevey http://px.sklar.com/code.html?code_id=258) +--- Chat (orignal work) +- Continues development and project direction. + +### Application Developers ### +* Michael Weber +- Develops/Maintains Trouble Ticket System + +* Vincent Larchet (aka vinz) +- He hops from application to application helping out everywhere +- Keeps phpGW working on NT servers + +* Mark A Peters (aka Skeeter) +- Developed/Maintains Headlines application +- Developed/Maintains NNTP application +- Helps with almost all other applications as well + +* Scott Moser (aka smoser) +-Developed/Maintains the FTP application + +* Itzchak Rehberg (aka izzy) +- has been working on replacement for mail() function +- Developed/Maintains POP-3 class +- Built/Maintains the german language files +- He hops from application to application helping out everywhere + +* Stephan Beal (aka wander) +- Initial quick-n-dirty rbs port from the MRBS system +- Minor bug fixes. +- Conned Hakon into doing the Norwegian translations ;) + +* Marc Logemann (aka Loge) |loge@mail.com| +- Develop/Maintains todo (project management) +- Develops utility classes for phpgwapi +- mental support for Palm Sync issue :) + +### Patch Contributors ### (in alphabetical order) Let us know if we forgot anyone :) +* Wolfgang Lunz +* bachroxx +* brandonne +* Park ChungKyu +* Kjell Claesson +- Swedish translations. +* Simone Cortesi +- Italian translations. +* flimm +* gmartine +* Omer Uner Guclu +* Marvin Horst +* Brian King +* Marl +* Mike Preishuber +* Roy Svendsen +* smoser +* Petr Moses +- Czechoslovakian translations. +* preisel +* Raśl Alexis Betancort Santana +- Great working on our first template set. +* Hakon Tjaum +- Norwegian translations. +* zaphod +- Dutch (?) translations. + +Thanks to Crista Schofield and Eric Degner for *TONS* of Beta testing. +All others on the phpgroupware-developers@lists.sourceforge.net mailing list +And finally every one of our users for the encouragement that keeps us happy, which means more development. diff --git a/phpgwapi/doc/LICENSE b/phpgwapi/doc/LICENSE new file mode 100644 index 0000000000..8a53d829a3 --- /dev/null +++ b/phpgwapi/doc/LICENSE @@ -0,0 +1,342 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + + diff --git a/phpgwapi/doc/README b/phpgwapi/doc/README new file mode 100644 index 0000000000..71c6e1fc45 --- /dev/null +++ b/phpgwapi/doc/README @@ -0,0 +1 @@ +PLEASE SEE THE index.html OR index.txt files. diff --git a/phpgwapi/doc/RELEASE-NOTES b/phpgwapi/doc/RELEASE-NOTES new file mode 100644 index 0000000000..54752dfb08 --- /dev/null +++ b/phpgwapi/doc/RELEASE-NOTES @@ -0,0 +1,2 @@ +This version will NOT work with PHP 4.0.3pl1. This is due to the PHP devteam breaking serialize() and +unserialize(). There is no known work around. diff --git a/phpgwapi/doc/SECURITY b/phpgwapi/doc/SECURITY new file mode 100644 index 0000000000..ce23693938 --- /dev/null +++ b/phpgwapi/doc/SECURITY @@ -0,0 +1,27 @@ +First off, I would not recommend using this in a type of enviroment that +security is a really big concern. I am *NOT* saying that you shouldn't be +concerned about it, but, until the system is thoughly tested. I would not +recommend it. + +Becuase of the current methods that the email system works. It is required +that the users password is in the sessions table. IMAP needs the password +to verify the user. This is one of the main reasons for the stalesessions +program. I do not like keeping passwords in any medium that is not encryped. + +The email system stores its file attachments in a temp directory. For right +now, you need to watch this directory because it can fill up very quickly. +If a user does not finsh composing the message (going else where in the program, +internet connection dieing, browser crash, etc) the file will sit there until +it is deleted. There will be a simple cron program to go through and clean +things up. + +The files/users and files/groups directories need to be writable by the UID +that php runs under (nobody or your apache UID). This is a security risk +if 3rd parties can place php or cgi scripts on your machine, because they +will have full read/write access to those directories. +You should also consider moving the files directory outside of the +tree your webserver has access to to prevent websurfers from directly accessing +the files, or add in .htaccess files to restrict access to that tree. + +Besides this, there is nothing else that I am aware of. Let me know if you +find anything. diff --git a/phpgwapi/doc/index.html b/phpgwapi/doc/index.html new file mode 100644 index 0000000000..b0ad3a6b3b --- /dev/null +++ b/phpgwapi/doc/index.html @@ -0,0 +1,2011 @@ +phpGroupWare Docs V0.05

Dedication

Thanks to Joesph Engo for starting phpGroupWare (at the time called webdistro) and the core of this HOWTO. + Thanks to all the developers and users who contribute to making phpGroupWare such a success. +

Table of Contents
I. Introduction
1. What is phpGroupWare
2. Why should you use it
3. A short History
4. Copyright
II. Installation
5. Requirements
Tested Systems
6. Obtaining phpGroupWare
Released Versions
Developer's version from CVS
7. Installation Steps
Installing from TarBall
Installing from CVS
Setup / Configure phpGroupWare
Testing the install
Installing additional applications
8. Trouble Shooting
I get "Unable to open mailbox" when using the email application
It seems to hang when I try to read my mail
When I log in I see the directory listing instead of a web page
I get garbage that looks like code when I go to the phpGroupWare URL
III. Using phpGroupWare
9. Loging into phpgw
10. checking Email
11. Using Addressbook
12. Using Calender
13. Managing Files with file manager
14. Getting Headlines
15. Human Resources
16. Preferences
17. Using todo
18. Using Trouble ticket
IV. Administering phpGroupWare
19. User Accounts
Creating Accounts
Maintaining Accounts
20. Group Accounts
Creating Accounts
Maintaining Accounts
21. Applications
Installing
Updating
V. Developers Documentation
22. Developing Add-On Apps
Requirements
add your topic seek
23. API documentation
function1(or what ever)
VII. About this document

I. Introduction

Do yo have questions on using phpGroupWare , like What? Why? What for? What's in for me? +

Then you should seriously read this doc :-). +


Chapter 1. What is phpGroupWare

phpGroupWare is a web based groupware application that includes integrated features such as + email, calendar, todo list, address book, file manager, headline news, and a trouble ticket system. + It should run on all systems where PHP is installed and has access to a SQL server (MySQL ,PostgreSQL or Oracle). +


Chapter 2. Why should you use it

You should use it if you would like a powerful groupware system that can be access from anywhere on the Internet. +

For companies with a distributed user base, it's an ideal solution. Oh, and did I mention that its FREE? +


Chapter 3. A short History

phpGroupWare started by Jengo (Joseph Engo) as an application to satisfy his girlfriends need for a webbased calendar/todo_list/email. + At the time it was called webdistro when Seek3r (Dan Kuykendall) discovered this promising project. + The two joined up together and between Seek3r's API design and Jengo's programming skills they renamed the project phpGroupWare and started building the application around the phpgwAPI. +

During this period Seek3r took over project management to free Jengo up to do more development. + This duo worked hard to build a sucessful community around the project. Their efforts paid off, and the project is what it is today due to the efforts of the developers who have joined this community. +


Chapter 4. Copyright

Copyright (c) Dan Kuykendall. +

Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.1 + or any later version published by the Free Software Foundation + A copy of the license is available at + GNU Free Documentation License Making TeXWork + +

II. Installation

Installation/Upgrade and Configuration of phpGroupWare has been made as easy as possible. 
+Most of the work is point and click. 
+By carefully reading this document you can easly install phpGroupWare.

+

Since this is still a beta version we do expect some bugs. +


Chapter 5. Requirements

You will need PHP compiled and installed on your system. You will also need MySQL, PostgreSQL or Oracle setup. +

If you are planning on using the email system, you will need to have an IMAP server installed and IMAP support compiled into PHP, or a POP3 server installed. + You can have it installed as an Apache module or CGI mode for other web servers, the Apache module is preferred. + We will assume that you are running on a Linux or other Unix system for these steps. + Windows is supported, but there is no documentation for it currently. +


Tested Systems

Seek3r has tested: +

  • phpGroupWare.org runs: Red Hat 6.2, Apache/1.3.12,PHP/4.0.2,mod_perl/1.21,MySQL 3.23.10-alpha,Courier-IMAP 0.33+ with qmail 1.03

+ + Blinky has tested: +

  • phpGroupWare.net runs: Red Hat 6.2,Apache/1.3.14 PHP/4.0.3pl1 mod_ssl/2.7.1 OpenSSL/0.9.6 PHP4.03.pl1, MySQL 3.23.10-alpha,qmail 1.03

  • dev boxes are variants on: Red Hat 7.0,mysql-3.23.22-6 (from RH7 RPM), and Sendmail, Courier, or qmail+courier IMAP depending on mood.

+ + + Jengo has tested: +

  • main test box: Red Hat 6.2,Apache 1.3.12,PHP 3.0.16,PostgreSQL 7.2,Sendmail (from RH6.2)

  • laptop is rh 6.1, apache 1.3.?, MySQL and PostgreSQL 7.0 w/ PHP 3.0.16, its a P-90 w/ 40 mb ram and a 800 mb hd

  • Test box: Win2k with IIS5.0, PHP4.0.2 and MySQL

+ There are installations on Windows NT and OS/2, and using MySQL or Oracle as the database. +


Chapter 6. Obtaining phpGroupWare

While we are still in the Beta phase of phpGroupWare, you may + want to track the CVS copy as closely as possible. The released + versions are more stable, but often contain bugs that have been fixed + in the CVS version. +


Released Versions

The downloads section on the site + contains links to the most recent releases, and several mirror sites + for the releases. +


Developer's version from CVS

If you have never used CVS, you may want to read through the doucmentation + found at www.cvshome.org + . + The CVS pages for the core and apps projects can be found at + phpGroupWare Core CVS + , and phpGroupWare Apps CVS. + Follow the directions for Anonymous CVS access and you should + have the most recent development copy of phpGroupWare in no time. +


Chapter 7. Installation Steps

After you have met the system requirements, You can install + it from the TarBall or you can get it directly from CVS. +


Installing from TarBall

The files should be installed in the webserver directory. So all you need to + do is unpack the tar ball and copy the whole directory to the webserver directory +

(eg. /home/httpd/html for default apache configuration in many linux distros). +

You may have to get required permissions to do this. Contact your system + administrator if you dont have the permission to write to your webserver directory. +


Installing from CVS

Grabbing a copy from CVS is not as hard as it may seem. You will need to have a cvs client installed. + Then try the following commands: +

export CVSROOT=':pserver:anonymous@cvs.phpgroupware.sourceforge.net:/cvsroot/phpgroupware'

cvs login (just hit enter when prompted for a password)

cvs checkout phpgroupware

+ If you need to install into a different dirname, you can add ' -d dirname' after 'checkout' and before 'phpgroupware'. + The commands would look like this: +

export CVSROOT=':pserver:anonymous@cvs.phpgroupware.sourceforge.net:/cvsroot/phpgroupware'

cvs login (just hit enter when prompted for a password)

cvs checkout -d dirname phpgroupware

+


Setup / Configure phpGroupWare

The config file

Copy the header.inc.php.sample file to + header.inc.php and edit the file, following the + directions in the comments. +


Create database in MySQL

An empty database will be needed for phpGroupWare. Here are the instructions for doing so with MySQL. + First create the database: +

mysqladmin create phpgroupware -p

+ Then login to the mysql: +

mysql -p

+ Finally grant the needed security rights: +

grant all on phpgroupware.* to phpgroupware@localhost identified by "some_password";

+


Create database in PostreSQL

An empty database will be needed for phpGroupWare. Here are the instructions for doing so with PostgreSQL. + Create the database: +

postmaster -i -D /home/[username]/[dataDir]

+ You will probably need to review PostgreSQL documentation for futher details. +


The Setup Program

Then point your browser to phpgroupware/setup/ which will + create (or upgrade) the database tables. + You wil be asked to login, using the password set in + header.inc.php. Setup will attempt to determine what version + of the phpGroupWare database you have installed, and upgrade to the most recent + version. +

Note
 

The developers are concentrating on getting the beta + working, and have not spent a great deal of time building upgrade scripts from the + alpha versions of phpGroupWare. You are advised to backup your existing alpha + database before running the setup script to avoid problems! +

If you get no error messages, continue on to phpgroupware/setup/config.php + to configure phpGroupWare to your system. +

If you are using the email system you will need to create a temporary directory + where file uploads will be stored. For security reasons, you should chown + nobody.nobody and chmod 700 to that directory. Depending on your system configuration. + Default installs of Apache normally run as the user nobody. You may need your system + administrator to do this for you if you do not have root access. +

If you do not have access to root, create this file and run it. +

?php
+if (mkdir("/path/to/temp/directory",0700)) {
+echo "Directory created successfully";
+} else {
+echo "Error creating directory";
+}
+?
+      

The phpGroupWare Daemon

If you have access to cron, you may want to setup the files in the cron + directory. +

stalesessions.pl - There are 2 reasons for this file. +

  • Users always forget to logout. This way the session doesn't sit around forever, creating a possible security risk.

  • The email system requires plain text passwords which are stored in the sessions table.

+ This file is not required, you can simply disable cron_apps in the admin -> applications section + to clean out the sessions table during login and logout +

stale_uploads.pl - This will delete file attachments for messages that where not + completed. If a users browser crashes, Internet connection dies, etc, their + files will sit there forever unless deleted. You could add a few lines to + logout.php that will look in the temp directory for any stale uploads and delete + them. But, once again, it becomes a performance issue. +


Testing the install

If your config is setup properly you can now login. Point your browser to the + installed location and login with the username demo and the password is 1234 + At this point it would be a good idea to create a new user with administrative privileges and + delete the old one. +


Installing additional applications

Once you have the core phpGroupWare install up and running, + you may want to download and install additional applications. +

You should consult any README or INSTALL + files that come with the new application first, as most require you + to create additional tables in the database, and add additional + translation data to the lang table (typically a file called lang.sql) +

You install the new application within the phpGroupWare install tree by + copying the application directory into the phpGroupWare install location, + and enabling the application through the Administration page. +

For example, this is the process to install the + Headlines application (see http://sourceforge.net/phpgwapps/ for + more on this and other applications). +

  • Download the .tar.gz file for the application, or check out the source with cvs with +

    export CVSROOT=':pserver:anonymous@cvs.phpgroupware.sourceforge.net:/cvsroot/phpgwapps'
    cvs login (just hit enter if prompted for a password)
    cvs co headlines

    +

  • Move the headlines directory into your phpGroupWare + install directory.

  • Log into phpGroupWare as an administrative user, and go to the Administration page. +

  • In the first section, choose the Applications link. +

  • Click on add, and fill in the form.

    Application name + should be identical to the name + of the directory you moved into the phpGroupWare install, in this case use headlines +

    Application Title + is shown in the navigation bar and other places to refer to the + new application. Enter Headlines for this example. +

    Enabled + can be used to disable an application for all users temporially. You + should normal check the box to enable the application. +

  • Back in the Administration page, you need to enable the application for specific users + or user groups by editing them, and checking the new Headlines box that appears + in the middle of the account editing page.

  • Once you have added the Headlines app to your account, you should see a Headlines + entry in the Administration and Preferences pages, and there should be an icon for + the Headlines application in the navigation bar.

  • Once you enable a few of the Headlines sites through the Administration page link, you + should see headlines grabbed from the sites you selected when you click on the Headlines + icon in the navigation bar. +

+


Chapter 8. Trouble Shooting

phpGroupWare is still Beta software, expect some bugs + along the way. If you run into a problem not discussed here, contact us + through one of the methods listed on the website. +

The phpGroupWare developers can most often be seen hanging out in #phpGroupWare + on irc.openprojects.net if you require real-time help. +

+ Also check the FAQ in this directory for additional common questions, + it is available as FAQ.sgml, FAQ.txt and FAQ.html +


I get "Unable to open mailbox" when using the email application

At the time of this writing (2000-09-27) you must use the same + username and password in phpGroupWare that you use to log into + your mail server. If you change your password and it still isn't working, + try logging out of phpGroupWare (the rightmost icon in the navigation bar) + and then log back in. +

An preference page to edit the email settings is being developed, and should + appear shortly after the first beta release. +


It seems to hang when I try to read my mail

This is often a problem if you are using POP3 instead of IMAP, and you have + more than a few hundred messages in your mailbox. +

By default, php is set up to time-out a request that takes over 30 seconds + to complete. phpGroupWare must do a lot of work the first time your POP3 mailbox + is opened, and every time you get new mail, which may take more than the 30 + second timeout. +

You can either clean up your mailbox with another mail program, or + add the line +
set_time_limit(0);
+			
+ to the top of the inc/phpgwapi/phpgw_msg_pop3.inc.php file, just before + the line class msg extends msg_common +

If you choose to edit the file, be patient when loading a large POP3 + mailbox - the author tested against a mailbox with 2500 messages in it, + but it took 15 minutes to load the page. We highly suggest you use IMAP + if you expect to have more than a few hundred messages in your mailbox. +


When I log in I see the directory listing instead of a web page

You are using Apache, this often means you need to add + .php to the DirectoryIndex line in your httpd.conf file. + For example: +
DirectoryIndex index.php index.php3 index.html index.htm index.cgi
+		      
+


I get garbage that looks like code when I go to the phpGroupWare URL

This is often because you have php3 installed, + which does not map .php to the PHP engine. + For PHP3: +
AddType             application/x-httpd-php3 .php3 .php
+			
+For PHP4: +
AddType             application/x-httpd-php .php3 .php
+			
+

III. Using phpGroupWare

Using phpGroupWare is a cake walk , thats what people say :-). Reading this doc would + definitely give a head start. If you ever come cross any problem please report to +


Chapter 9. Loging into phpgw

After your setup you can point your browser to index.php in the + installation directory. If the set up was right you can login with user name demo + and the password is 1234> Now it is recommended to + create a new user with administrative privileges and delete the old one. +

IV. Administering phpGroupWare

To administer phpGroupWare you need not be a PHP hacker. All you need to do is again just + point and click. And hey just a bit of typing too. :). You need to login to phpGroupWare + and click the Administration image. +

Table of Contents
19. User Accounts
20. Group Accounts
21. Applications

Chapter 19. User Accounts

In phpGroupWare it is very easy to maintain User Accounts. You can easily add , remove or + set previleges to the user accordingly. +


Creating Accounts

+ To create a user account goto User Accounts section + of Administration and the click the + Add button. Now a form would be displayed. + FIXME : should i explain the process :-). After submiting the form you would be sent + back to the accounts page and you can now see the new user you have just created. + Isn't it easy !!! +


Maintaining Accounts

Maintaining user accounts is also very easy. Just go to the + User Accounts section . Now you can see + the list of the current users and there logins. You + can now either view their ops or can even edit them. + FIXMEAGIN: need i say anything more :->. +


Chapter 20. Group Accounts

Enter the User Group section. You would see + the current user groups. +


Creating Accounts

Click the Add button. Now fill the form by + selecting the existing users and the persmissions you want to include + in the new group.And you r done. +


Maintaining Accounts

One has always a option to view and edit the groups when ever + needed +


Chapter 21. Applications

There r many applications been developed for phpGroupWare and there would be more + in the future. So insatallation of these application and as well as the future + applications has been made easy the developers. So what you have to do is to + just go to the Application section. +

V. Developers Documentation

This documentation is for developers who want to hack into the core of the + phpGroupWare. Please follow this documentation carefully before u take a jump into + the code :) +


Chapter 22. Developing Add-On Apps

text for developin add on apps (seek its your area)


Requirements

text for requirements +


add your topic seek

text for the appropriate topic +


Chapter 23. API documentation

+ text for the API documentation chapter +


function1(or what ever)

the function you want to include seek. +

VII. About this document

The newest version of this document can be found on our website www.phpgroupware.org + as SGML source, HTML, or TEXT. +


Comments

Comments on this HOWTO should be directed to the phpGroupWare developers mailing list + phpgroupware-developers@lists.sourceforge.net +

To subscribe, go to http://sourceforge.net/mail/?group_id=7305 +


History

This document was started by Joseph Engo and reworked by Dan Kuykendall. +


Version History

Old Version +

  • Created by Jengo, wasn't in SGML HOWTO format.

+

v1.0 (July 6, 2000) +

  • Built proper SGML version.

  • Included the FAQ.

  • Other minor additions.

+

v1.1 (September 27-29, 2000) - blinky +

  • Added Testing Install section

  • Added Trouble-shooting section

  • Added description of application installation

  • Changes for the new setup program

+

v0.01 (October 15 , 2000) - gnrfan , Converted the HOWTO to DocBook format + +

v.0.05 (November 5, 2000) - gnrfan , Completely revamped according to Seek's + idea and intregrated the Developers HOWTO. +

v 0.xx (Somewhere in the near future) - gnrfan, Trail map comming up on + how to hack and learn about coding phpGroupWare(core) and its + apps too :-). +

\ No newline at end of file diff --git a/phpgwapi/doc/index.txt b/phpgwapi/doc/index.txt new file mode 100644 index 0000000000..22a84e0559 --- /dev/null +++ b/phpgwapi/doc/index.txt @@ -0,0 +1,706 @@ + +phpGroupWare Docs V0.05 + +Dan Kuykendall + +Joseph Engo + _________________________________________________________________ + _________________________________________________________________ + +Dedication + + Thanks to Joesph Engo for starting phpGroupWare (at the time called + webdistro) and the core of this HOWTO. Thanks to all the developers + and users who contribute to making phpGroupWare such a success. + + Table of Contents + I. Introduction + + 1. What is phpGroupWare + 2. Why should you use it + 3. A short History + 4. Copyright + + II. Installation + + 5. Requirements + + Tested Systems + + 6. Obtaining phpGroupWare + + Released Versions + Developer's version from CVS + + 7. Installation Steps + + Installing from TarBall + Installing from CVS + Setup / Configure phpGroupWare + Testing the install + Installing additional applications + + 8. Trouble Shooting + + I get "Unable to open mailbox" when using the email + application + + It seems to hang when I try to read my mail + When I log in I see the directory listing instead of a web + page + + I get garbage that looks like code when I go to the + phpGroupWare URL + + III. Using phpGroupWare + + 9. Loging into phpgw + 10. checking Email + 11. Using Addressbook + 12. Using Calender + 13. Managing Files with file manager + 14. Getting Headlines + 15. Human Resources + 16. Preferences + 17. Using todo + 18. Using Trouble ticket + + IV. Administering phpGroupWare + + 19. User Accounts + + Creating Accounts + Maintaining Accounts + + 20. Group Accounts + + Creating Accounts + Maintaining Accounts + + 21. Applications + + Installing + Updating + + V. Developers Documentation + + 22. Developing Add-On Apps + + Requirements + add your topic seek + + 23. API documentation + + function1(or what ever) + + VII. About this document + +I. Introduction + + Do yo have questions on using phpGroupWare , like What? Why? What for? + What's in for me? + + Then you should seriously read this doc :-). + + Table of Contents + 1. What is phpGroupWare + 2. Why should you use it + 3. A short History + 4. Copyright + _________________________________________________________________ + +Chapter 1. What is phpGroupWare + + phpGroupWare is a web based groupware application that includes + integrated features such as email, calendar, todo list, address book, + file manager, headline news, and a trouble ticket system. It should + run on all systems where PHP is installed and has access to a SQL + server (MySQL ,PostgreSQL or Oracle). + _________________________________________________________________ + +Chapter 2. Why should you use it + + You should use it if you would like a powerful groupware system that + can be access from anywhere on the Internet. + + For companies with a distributed user base, it's an ideal solution. + Oh, and did I mention that its FREE? + _________________________________________________________________ + +Chapter 3. A short History + + phpGroupWare started by Jengo (Joseph Engo) as an application to + satisfy his girlfriends need for a webbased calendar/todo_list/email. + At the time it was called webdistro when Seek3r (Dan Kuykendall) + discovered this promising project. The two joined up together and + between Seek3r's API design and Jengo's programming skills they + renamed the project phpGroupWare and started building the application + around the phpgwAPI. + + During this period Seek3r took over project management to free Jengo + up to do more development. This duo worked hard to build a sucessful + community around the project. Their efforts paid off, and the project + is what it is today due to the efforts of the developers who have + joined this community. + _________________________________________________________________ + +Chapter 4. Copyright + + Copyright (c) Dan Kuykendall. + + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.1 or + any later version published by the Free Software Foundation A copy of + the license is available at GNU Free Documentation License Making + TeXWork + +II. Installation + + Installation/Upgrade and Configuration of phpGroupWare has been made a + s easy as possible. + Most of the work is point and click. + By carefully reading this document you can easly install phpGroupWare. + + Since this is still a beta version we do expect some bugs. + + Table of Contents + 5. Requirements + 6. Obtaining phpGroupWare + 7. Installation Steps + 8. Trouble Shooting + _________________________________________________________________ + +Chapter 5. Requirements + + You will need PHP compiled and installed on your system. You will also + need MySQL, PostgreSQL or Oracle setup. + + If you are planning on using the email system, you will need to have + an IMAP server installed and IMAP support compiled into PHP, or a POP3 + server installed. You can have it installed as an Apache module or CGI + mode for other web servers, the Apache module is preferred. We will + assume that you are running on a Linux or other Unix system for these + steps. Windows is supported, but there is no documentation for it + currently. + _________________________________________________________________ + +Tested Systems + + Seek3r has tested: + + * phpGroupWare.org runs: Red Hat 6.2, + Apache/1.3.12,PHP/4.0.2,mod_perl/1.21,MySQL + 3.23.10-alpha,Courier-IMAP 0.33+ with qmail 1.03 + + Blinky has tested: + + * phpGroupWare.net runs: Red Hat 6.2,Apache/1.3.14 PHP/4.0.3pl1 + mod_ssl/2.7.1 OpenSSL/0.9.6 PHP4.03.pl1, MySQL 3.23.10-alpha,qmail + 1.03 + * dev boxes are variants on: Red Hat 7.0,mysql-3.23.22-6 (from RH7 + RPM), and Sendmail, Courier, or qmail+courier IMAP depending on + mood. + + Jengo has tested: + + * main test box: Red Hat 6.2,Apache 1.3.12,PHP 3.0.16,PostgreSQL + 7.2,Sendmail (from RH6.2) + * laptop is rh 6.1, apache 1.3.?, MySQL and PostgreSQL 7.0 w/ PHP + 3.0.16, its a P-90 w/ 40 mb ram and a 800 mb hd + * Test box: Win2k with IIS5.0, PHP4.0.2 and MySQL + + There are installations on Windows NT and OS/2, and using MySQL or + Oracle as the database. + _________________________________________________________________ + +Chapter 6. Obtaining phpGroupWare + + While we are still in the Beta phase of phpGroupWare, you may want to + track the CVS copy as closely as possible. The released versions are + more stable, but often contain bugs that have been fixed in the CVS + version. + _________________________________________________________________ + +Released Versions + + The downloads section on the site contains links to the most recent + releases, and several mirror sites for the releases. + _________________________________________________________________ + +Developer's version from CVS + + If you have never used CVS, you may want to read through the + doucmentation found at www.cvshome.org . The CVS pages for the core + and apps projects can be found at phpGroupWare Core CVS , and + phpGroupWare Apps CVS. Follow the directions for Anonymous CVS access + and you should have the most recent development copy of phpGroupWare + in no time. + _________________________________________________________________ + +Chapter 7. Installation Steps + + After you have met the system requirements, You can install it from + the TarBall or you can get it directly from CVS. + _________________________________________________________________ + +Installing from TarBall + + The files should be installed in the webserver directory. So all you + need to do is unpack the tar ball and copy the whole directory to the + webserver directory + + (eg. /home/httpd/html for default apache configuration in many linux + distros). + + You may have to get required permissions to do this. Contact your + system administrator if you dont have the permission to write to your + webserver directory. + _________________________________________________________________ + +Installing from CVS + + Grabbing a copy from CVS is not as hard as it may seem. You will need + to have a cvs client installed. Then try the following commands: + + export + CVSROOT=':pserver:anonymous@cvs.phpgroupware.sourceforge.net:/cvsroot/ + phpgroupware' + cvs login (just hit enter when prompted for a password) + cvs checkout phpgroupware + If you need to install into a different dirname, you can add ' -d + dirname' after 'checkout' and before 'phpgroupware'. The commands + would look like this: + + export + CVSROOT=':pserver:anonymous@cvs.phpgroupware.sourceforge.net:/cvsroot/ + phpgroupware' + cvs login (just hit enter when prompted for a password) + cvs checkout -d dirname phpgroupware + _________________________________________________________________ + +Setup / Configure phpGroupWare + +The config file + + Copy the header.inc.php.sample file to header.inc.php and edit the + file, following the directions in the comments. + _________________________________________________________________ + +Create database in MySQL + + An empty database will be needed for phpGroupWare. Here are the + instructions for doing so with MySQL. First create the database: + + mysqladmin create phpgroupware -p + Then login to the mysql: + + mysql -p + Finally grant the needed security rights: + + grant all on phpgroupware.* to phpgroupware@localhost identified by + "some_password"; + _________________________________________________________________ + +Create database in PostreSQL + + An empty database will be needed for phpGroupWare. Here are the + instructions for doing so with PostgreSQL. Create the database: + + postmaster -i -D /home/[username]/[dataDir] + You will probably need to review PostgreSQL documentation for futher + details. + _________________________________________________________________ + +The Setup Program + + Then point your browser to phpgroupware/setup/ which will create (or + upgrade) the database tables. You wil be asked to login, using the + password set in header.inc.php. Setup will attempt to determine what + version of the phpGroupWare database you have installed, and upgrade + to the most recent version. + + Note: The developers are concentrating on getting the beta working, + and have not spent a great deal of time building upgrade scripts + from the alpha versions of phpGroupWare. You are advised to backup + your existing alpha database before running the setup script to + avoid problems! + + If you get no error messages, continue on to + phpgroupware/setup/config.php to configure phpGroupWare to your + system. + + If you are using the email system you will need to create a temporary + directory where file uploads will be stored. For security reasons, you + should chown nobody.nobody and chmod 700 to that directory. Depending + on your system configuration. Default installs of Apache normally run + as the user nobody. You may need your system administrator to do this + for you if you do not have root access. + + If you do not have access to root, create this file and run it. +?php +if (mkdir("/path/to/temp/directory",0700)) { +echo "Directory created successfully"; +} else { +echo "Error creating directory"; +} +? + + _________________________________________________________________ + +The phpGroupWare Daemon + + If you have access to cron, you may want to setup the files in the + cron directory. + + stalesessions.pl - There are 2 reasons for this file. + + * Users always forget to logout. This way the session doesn't sit + around forever, creating a possible security risk. + * The email system requires plain text passwords which are stored in + the sessions table. + + This file is not required, you can simply disable cron_apps in the + admin -> applications section to clean out the sessions table during + login and logout + + stale_uploads.pl - This will delete file attachments for messages that + where not completed. If a users browser crashes, Internet connection + dies, etc, their files will sit there forever unless deleted. You + could add a few lines to logout.php that will look in the temp + directory for any stale uploads and delete them. But, once again, it + becomes a performance issue. + _________________________________________________________________ + +Testing the install + + If your config is setup properly you can now login. Point your browser + to the installed location and login with the username demo and the + password is 1234 At this point it would be a good idea to create a new + user with administrative privileges and delete the old one. + _________________________________________________________________ + +Installing additional applications + + Once you have the core phpGroupWare install up and running, you may + want to download and install additional applications. + + You should consult any README or INSTALL files that come with the new + application first, as most require you to create additional tables in + the database, and add additional translation data to the lang table + (typically a file called lang.sql) + + You install the new application within the phpGroupWare install tree + by copying the application directory into the phpGroupWare install + location, and enabling the application through the Administration + page. + + For example, this is the process to install the Headlines application + (see http://sourceforge.net/phpgwapps/ for more on this and other + applications). + + * Download the .tar.gz file for the application, or check out the + source with cvs with + export + CVSROOT=':pserver:anonymous@cvs.phpgroupware.sourceforge.net:/cvsr + oot/phpgwapps' + cvs login (just hit enter if prompted for a password) + cvs co headlines + * Move the headlines directory into your phpGroupWare install + directory. + * Log into phpGroupWare as an administrative user, and go to the + Administration page. + * In the first section, choose the Applications link. + * Click on add, and fill in the form. + Application name should be identical to the name of the directory + you moved into the phpGroupWare install, in this case use + headlines + Application Title is shown in the navigation bar and other places + to refer to the new application. Enter Headlines for this example. + Enabled can be used to disable an application for all users + temporially. You should normal check the box to enable the + application. + * Back in the Administration page, you need to enable the + application for specific users or user groups by editing them, and + checking the new Headlines box that appears in the middle of the + account editing page. + * Once you have added the Headlines app to your account, you should + see a Headlines entry in the Administration and Preferences pages, + and there should be an icon for the Headlines application in the + navigation bar. + * Once you enable a few of the Headlines sites through the + Administration page link, you should see headlines grabbed from + the sites you selected when you click on the Headlines icon in the + navigation bar. + _________________________________________________________________ + +Chapter 8. Trouble Shooting + + Warning + + phpGroupWare is still Beta software, expect some bugs along the way. + If you run into a problem not discussed here, contact us through one + of the methods listed on the website. + + The phpGroupWare developers can most often be seen hanging out in + #phpGroupWare on irc.openprojects.net if you require real-time help. + + Also check the FAQ in this directory for additional common questions, + it is available as FAQ.sgml, FAQ.txt and FAQ.html + _________________________________________________________________ + +I get "Unable to open mailbox" when using the email application + + At the time of this writing (2000-09-27) you must use the same + username and password in phpGroupWare that you use to log into your + mail server. If you change your password and it still isn't working, + try logging out of phpGroupWare (the rightmost icon in the navigation + bar) and then log back in. + + An preference page to edit the email settings is being developed, and + should appear shortly after the first beta release. + _________________________________________________________________ + +It seems to hang when I try to read my mail + + This is often a problem if you are using POP3 instead of IMAP, and you + have more than a few hundred messages in your mailbox. + + By default, php is set up to time-out a request that takes over 30 + seconds to complete. phpGroupWare must do a lot of work the first time + your POP3 mailbox is opened, and every time you get new mail, which + may take more than the 30 second timeout. + + You can either clean up your mailbox with another mail program, or add + the line +set_time_limit(0); + + to the top of the inc/phpgwapi/phpgw_msg_pop3.inc.php file, just + before the line class msg extends msg_common + + If you choose to edit the file, be patient when loading a large POP3 + mailbox - the author tested against a mailbox with 2500 messages in + it, but it took 15 minutes to load the page. We highly suggest you use + IMAP if you expect to have more than a few hundred messages in your + mailbox. + _________________________________________________________________ + +When I log in I see the directory listing instead of a web page + + You are using Apache, this often means you need to add .php to the + DirectoryIndex line in your httpd.conf file. For example: +DirectoryIndex index.php index.php3 index.html index.htm index.cgi + + _________________________________________________________________ + +I get garbage that looks like code when I go to the phpGroupWare URL + + This is often because you have php3 installed, which does not map .php + to the PHP engine. For PHP3: +AddType application/x-httpd-php3 .php3 .php + + For PHP4: +AddType application/x-httpd-php .php3 .php + +III. Using phpGroupWare + + Using phpGroupWare is a cake walk , thats what people say :-). Reading + this doc would definitely give a head start. If you ever come cross + any problem please report to + + Table of Contents + 9. Loging into phpgw + 10. checking Email + 11. Using Addressbook + 12. Using Calender + 13. Managing Files with file manager + 14. Getting Headlines + 15. Human Resources + 16. Preferences + 17. Using todo + 18. Using Trouble ticket + _________________________________________________________________ + +Chapter 9. Loging into phpgw + + After your setup you can point your browser to index.php in the + installation directory. If the set up was right you can login with + user name demo and the password is 1234> Now it is recommended to + create a new user with administrative privileges and delete the old + one. + _________________________________________________________________ + +Chapter 10. checking Email + _________________________________________________________________ + +Chapter 11. Using Addressbook + _________________________________________________________________ + +Chapter 12. Using Calender + _________________________________________________________________ + +Chapter 13. Managing Files with file manager + _________________________________________________________________ + +Chapter 14. Getting Headlines + _________________________________________________________________ + +Chapter 15. Human Resources + _________________________________________________________________ + +Chapter 16. Preferences + _________________________________________________________________ + +Chapter 17. Using todo + _________________________________________________________________ + +Chapter 18. Using Trouble ticket + +IV. Administering phpGroupWare + + To administer phpGroupWare you need not be a PHP hacker. All you need + to do is again just point and click. And hey just a bit of typing too. + :). You need to login to phpGroupWare and click the Administration + image. + + Table of Contents + 19. User Accounts + 20. Group Accounts + 21. Applications + _________________________________________________________________ + +Chapter 19. User Accounts + + In phpGroupWare it is very easy to maintain User Accounts. You can + easily add , remove or set previleges to the user accordingly. + _________________________________________________________________ + +Creating Accounts + + To create a user account goto User Accounts section of Administration + and the click the Add button. Now a form would be displayed. FIXME : + should i explain the process :-). After submiting the form you would + be sent back to the accounts page and you can now see the new user you + have just created. Isn't it easy !!! + _________________________________________________________________ + +Maintaining Accounts + + Maintaining user accounts is also very easy. Just go to the User + Accounts section . Now you can see the list of the current users and + there logins. You can now either view their ops or can even edit them. + FIXMEAGIN: need i say anything more :->. + _________________________________________________________________ + +Chapter 20. Group Accounts + + Enter the User Group section. You would see the current user groups. + _________________________________________________________________ + +Creating Accounts + + Click the Add button. Now fill the form by selecting the existing + users and the persmissions you want to include in the new group.And + you r done. + _________________________________________________________________ + +Maintaining Accounts + + One has always a option to view and edit the groups when ever needed + _________________________________________________________________ + +Chapter 21. Applications + + There r many applications been developed for phpGroupWare and there + would be more in the future. So insatallation of these application and + as well as the future applications has been made easy the developers. + So what you have to do is to just go to the Application section. + _________________________________________________________________ + +Installing + _________________________________________________________________ + +Updating + +V. Developers Documentation + + This documentation is for developers who want to hack into the core of + the phpGroupWare. Please follow this documentation carefully before u + take a jump into the code :) + + Table of Contents + 22. Developing Add-On Apps + 23. API documentation + _________________________________________________________________ + +Chapter 22. Developing Add-On Apps + + text for developin add on apps (seek its your area) + _________________________________________________________________ + +Requirements + + text for requirements + _________________________________________________________________ + +add your topic seek + + text for the appropriate topic + _________________________________________________________________ + +Chapter 23. API documentation + + text for the API documentation chapter + _________________________________________________________________ + +function1(or what ever) + + the function you want to include seek. + +VII. About this document + + The newest version of this document can be found on our website + www.phpgroupware.org as SGML source, HTML, or TEXT. + _________________________________________________________________ + +Comments + + Comments on this HOWTO should be directed to the phpGroupWare + developers mailing list phpgroupware-developers@lists.sourceforge.net + + To subscribe, go to http://sourceforge.net/mail/?group_id=7305 + _________________________________________________________________ + +History + + This document was started by Joseph Engo and reworked by Dan + Kuykendall. + _________________________________________________________________ + +Version History + + Old Version + + * Created by Jengo, wasn't in SGML HOWTO format. + + v1.0 (July 6, 2000) + + * Built proper SGML version. + * Included the FAQ. + * Other minor additions. + + v1.1 (September 27-29, 2000) - blinky + + * Added Testing Install section + * Added Trouble-shooting section + * Added description of application installation + * Changes for the new setup program + + v0.01 (October 15 , 2000) - gnrfan , Converted the HOWTO to DocBook + format + + v.0.05 (November 5, 2000) - gnrfan , Completely revamped according to + Seek's idea and intregrated the Developers HOWTO. + + v 0.xx (Somewhere in the near future) - gnrfan, Trail map comming up + on how to hack and learn about coding phpGroupWare(core) and its apps + too :-). diff --git a/phpgwapi/footer.inc.php b/phpgwapi/footer.inc.php new file mode 100644 index 0000000000..2a3496d0ff --- /dev/null +++ b/phpgwapi/footer.inc.php @@ -0,0 +1,43 @@ + * + * -------------------------------------------- * + * This program is free software; you can redistribute it and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; either version 2 of the License, or (at your * + * option) any later version. * + \**************************************************************************/ + + /* $Id$ */ + + $d1 = strtolower(substr($phpgw_info["server"]["app_inc"],0,3)); + if($d1 == "htt" || $d1 == "ftp") { + echo "Failed attempt to break in via an old Security Hole!
\n"; + exit; + } unset($d1); + + /**************************************************************************\ + * Include the apps footer files if it exists * + \**************************************************************************/ + if (file_exists ($phpgw_info["server"]["app_inc"]."/footer.inc.php")){ + include($phpgw_info["server"]["app_inc"]."/footer.inc.php"); + } + + if ($phpgw_info["server"]["showpoweredbyon"] == "bottom" && $phpgw_info["server"]["showpoweredbyon"] != "top") { + echo "

\n"; + echo "\n"; + echo " "; + if ($phpgw_info["flags"]["parent_page"]) + echo ""; + echo "\n
"; + echo "

\n" . lang("Powered by phpGroupWare version x", + $phpgw_info["server"]["version"]) . "
\n"; + echo "

link($phpgw_info["flags"]["parent_page"])."\">".lang("up")."
\n"; + } + $phpgw->db->disconnect(); + +?> + + diff --git a/phpgwapi/phpgw.inc.php b/phpgwapi/phpgw.inc.php new file mode 100644 index 0000000000..c37f7ff5fc --- /dev/null +++ b/phpgwapi/phpgw.inc.php @@ -0,0 +1,418 @@ + * + * -------------------------------------------- * + * This program is free software; you can redistribute it and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; either version 2 of the License, or (at your * + * option) any later version. * + \**************************************************************************/ + + /* $Id$ */ + + $d1 = strtolower(substr($phpgw_info["server"]["include_root"],0,3)); + $d2 = strtolower(substr($phpgw_info["server"]["server_root"],0,3)); + $d3 = strtolower(substr($phpgw_info["server"]["api_dir"],0,3)); + if($d1 == "htt" || $d1 == "ftp" || $d2 == "htt" || $d2 == "ftp" || $d3 == "htt" || $d3 == "ftp") { + echo "Failed attempt to break in via an old Security Hole!
\n"; + exit; + } unset($d1);unset($d2);unset($d3); + + error_reporting(7); + + /**************************************************************************\ + * Quick verification of updated header.inc.php * + \**************************************************************************/ + if ($phpgw_info["server"]["header_version"] != $phpgw_info["server"]["current_header_version"]){ + echo "You need to port your settings to the new header.inc.php version."; + } + + /**************************************************************************\ + * Load up all the base files * + \**************************************************************************/ + include($phpgw_info["server"]["include_root"] . "/phpgwapi/phpgw_info.inc.php"); + + /**************************************************************************\ + * Required classes * + \**************************************************************************/ + /* Load selected database class */ + if (empty($phpgw_info["server"]["db_type"])){$phpgw_info["server"]["db_type"] = "mysql";} + include($phpgw_info["server"]["api_dir"] . "/phpgw_db_".$phpgw_info["server"]["db_type"].".inc.php"); + + include($phpgw_info["server"]["api_dir"] . "/phpgw_session.inc.php"); + + /* Load selected translation class */ + if (empty($phpgw_info["server"]["translation_system"])){$phpgw_info["server"]["translation_system"] = "sql";} + include($phpgw_info["server"]["api_dir"] . "/phpgw_lang_".$phpgw_info["server"]["translation_system"].".inc.php"); + + include($phpgw_info["server"]["api_dir"] . "/phpgw_crypto.inc.php"); + include($phpgw_info["server"]["api_dir"] . "/phpgw_template.inc.php"); + include($phpgw_info["server"]["api_dir"] . "/phpgw_common.inc.php"); + + /**************************************************************************\ + * Optional classes, which can be disabled for performance increases * + * - they are loaded after pulling in the config from the DB * + \**************************************************************************/ + function load_optional() + { + global $phpgw,$phpgw_info; + + $phpgw->common->key = $phpgw_info["server"]["encryptkey"]; + $phpgw->common->key .= $phpgw_info["user"]["sessionid"]; + $phpgw->common->key .= $phpgw_info["user"]["kp3"]; + $phpgw->common->iv = $phpgw_info["server"]["mcrypt_iv"]; + $phpgw->crypto = new crypto($phpgw->common->key,$phpgw->common->iv); + + if ($phpgw_info["flags"]["enable_categories_class"]) { + include($phpgw_info["server"]["api_dir"] . "/phpgw_categories.inc.php"); + $phpgw->categories = new categories; + } + + if ($phpgw_info["flags"]["enable_network_class"]) { + include($phpgw_info["server"]["api_dir"] . "/phpgw_network.inc.php"); + $phpgw->network = new network; + } + + if ($phpgw_info["flags"]["enable_send_class"]) { + include($phpgw_info["server"]["api_dir"] . "/phpgw_send.inc.php"); + $phpgw->send = new send; + } + + if ($phpgw_info["flags"]["enable_nextmatchs_class"]) { + include($phpgw_info["server"]["api_dir"] . "/phpgw_nextmatchs.inc.php"); + $phpgw->nextmatchs = new nextmatchs; + } + + if ($phpgw_info["flags"]["enable_utilities_class"]) { + include($phpgw_info["server"]["api_dir"] . "/phpgw_utilities.inc.php"); + $phpgw->utilities = new utilities; + } + + if ($phpgw_info["flags"]["enable_vfs_class"]) { + include($phpgw_info["server"]["api_dir"] . "/phpgw_vfs.inc.php"); + $phpgw->vfs = new vfs; + } + + if ($phpgw_info["flags"]["enable_todo_class"]) { + include($phpgw_info["server"]["api_dir"] . "/phpgw_todo.inc.php"); + $phpgw->todo = new todo; + } + + if ($phpgw_info["flags"]["enable_calendar_class"]) { + include($phpgw_info["server"]["api_dir"] . "/phpgw_calendar.inc.php"); + $phpgw->calendar = new calendar; + } + + if ($phpgw_info["flags"]["enable_addressbook_class"]) { + include($phpgw_info["server"]["api_dir"] . "/phpgw_addressbook.inc.php"); + $phpgw->addressbook = new addressbook; + } + + } + + /**************************************************************************\ + * Our API class starts here * + \**************************************************************************/ + class phpgw + { + var $accounts; + var $acl; + var $addressbook; + var $auth; + var $db; + var $debug = 0; // This will turn on debugging information. (Not fully working) + var $crypto; + var $calendar; + var $categories; + var $common; + var $hooks; + var $network; + var $nextmatchs; + var $preferences; + var $session; + var $msg; + var $send; + var $template; + var $todo; + var $translation; + var $utilities; + var $vfs; + + + // This is here so you can decied what the best way to handle bad sessions + // You could redirect them to login.php with code 2 or use the default + // I recommend using the default until all of the bugs are worked out. + + function phpgw() + { + global $phpgw_info, $sessionid; + /**************************************************************************\ + * Required classes * + \**************************************************************************/ + $this->db = new db; + $this->db->Host = $phpgw_info["server"]["db_host"]; + $this->db->Type = $phpgw_info["server"]["db_type"]; + $this->db->Database = $phpgw_info["server"]["db_name"]; + $this->db->User = $phpgw_info["server"]["db_user"]; + $this->db->Password = $phpgw_info["server"]["db_pass"]; + + if ($this->debug) { + $this->db->Debug = 1; + } + + if ($phpgw_info["flags"]["currentapp"] == "login") { + $this->db->query("select * from config",__LINE__,__FILE__); + while($this->db->next_record()) { + $phpgw_info["server"][$this->db->f("config_name")] = $this->db->f("config_value"); + } + } + + /* Load selected authentication class */ + if (empty($phpgw_info["server"]["auth_type"])){$phpgw_info["server"]["auth_type"] = "sql";} + include($phpgw_info["server"]["api_dir"] . "/phpgw_auth_".$phpgw_info["server"]["auth_type"].".inc.php"); + + /* Load selected accounts class */ + if (empty($phpgw_info["server"]["account_repository"])){$phpgw_info["server"]["account_repository"] = $phpgw_info["server"]["auth_type"];} + include($phpgw_info["server"]["api_dir"] . "/phpgw_accounts_".$phpgw_info["server"]["account_repository"].".inc.php"); + include($phpgw_info["server"]["api_dir"] . "/phpgw_accounts_shared.inc.php"); + + /**************************************************************************\ + * Continue adding the classes * + \**************************************************************************/ + $this->auth = new auth; + $this->session = new sessions; + $this->translation = new translation; + $this->common = new common; + $this->accounts = new accounts; + $this->preferences = new preferences; + $this->acl = new acl; + $this->hooks = new hooks; + + $sep = filesystem_separator(); + $template_root = $phpgw_info["server"]["server_root"] . $sep . $phpgw_info["flags"]["currentapp"] + . $sep . "templates" . $sep . $phpgw_info["server"]["default_tplset"]; + if (is_dir($template_root)) { + $this->template = new Template($template_root); + } + + } + /**************************************************************************\ + * Core functions * + \**************************************************************************/ + + /* A function to handle session support via url session id, or cookies */ + function link($url = "", $extravars = "") + { + global $phpgw, $phpgw_info, $usercookie, $kp3, $PHP_SELF; + + if (! $kp3) + $kp3 = $phpgw_info["user"]["kp3"]; + + if (! $url) { // PHP won't allow you to set a var to a var + $url = $PHP_SELF; // or function for default values + } + + if (isset($phpgw_info["server"]["usecookies"]) && $phpgw_info["server"]["usecookies"]) { + if ($extravars) { + $url .= "?$extravars"; + } + } else { + $url .= "?sessionid=" . $phpgw_info["user"]["sessionid"]; + $url .= "&kp3=" . $kp3; + if ($extravars) { + $url .= "&$extravars"; + } + $url .= "&domain=" . $phpgw_info["user"]["domain"]; + if ($phpgw_info["flags"]["newsmode"]) { + $url .= "&newsmode=on"; + } + } + + // next line adds index.php when one is assumed since + // iis will not interpret urls like http://.../addressbook/?xyz=5 + return str_replace("/?", "/index.php?", $url); + } + + function strip_html($s) + { + global $phpgw_info; + $working_langs = array("en" => True); + + return htmlspecialchars(stripslashes($s)); + } + + function redirect($url = "") + { + // This function handles redirects under iis and apache + // it assumes that $phpgw->link() has already been called + + global $HTTP_ENV_VARS; + + $iis = strpos($HTTP_ENV_VARS["SERVER_SOFTWARE"], "IIS", 0); + + if ( !$url ) { + $url = $PHP_SELF; + } + if ( $iis ) { + echo "\n\n\nRedirecting to $url"; + echo "\n"; + echo "\n"; + echo "

Please continue to this page

"; + echo "\n"; + exit; + } else { + Header("Location: $url"); + print("\n\n"); + exit; + } + } + + function lang($key, $m1 = "", $m2 = "", $m3 = "", $m4 = "") + { + global $phpgw; + + return $phpgw->translation->translate($key); + } + + // Some people might prefear to use this one + function _L($key, $m1 = "", $m2 = "", $m3 = "", $m4 = "") + { + global $phpgw; + + return $phpgw->translation->translate($key); + } + + + } + /**************************************************************************\ + * Our API class ends here * + \**************************************************************************/ + /**************************************************************************\ + * Direct functions, which are not part of the API class * + * for whatever reason. * + \**************************************************************************/ + + function lang($key, $m1="", $m2="", $m3="", $m4="", $m5="", $m6="", $m7="", $m8="", $m9="", $m10="" ) + { + global $phpgw; +# TODO: check if $m1 is of type array. If so, use it instead of $m2-$mN (Stephan) + $vars = array( $m1, $m2, $m3, $m4, $m5, $m6, $m7, $m8, $m9, $m10 ); + $value = $phpgw->translation->translate("$key", $vars ); + return $value; + } + + + // Just a temp wrapper. + function check_code($code) + { + global $phpgw; + + return $phpgw->common->check_code($code); + } + + /**************************************************************************\ + * These lines load up the API, fill up the $phpgw_info array, etc * + \**************************************************************************/ + $phpgw = new phpgw; + + if ($phpgw_info["flags"]["currentapp"] != "login" && $phpgw_info["flags"]["currentapp"] != "logout") { + if (! $phpgw->session->verify()) { + Header("Location: " . $phpgw->link($phpgw_info["server"]["webserver_url"] . "/login.php", "cd=10")); + exit; + } + load_optional(); + + phpgw_fillarray(); + $phpgw->common->common_(); + if ($phpgw_info["flags"]["enable_calendar_class"]){ + $printer_friendly = ((isset($friendly) && ($friendly==1))?True:False); + $phpgw->calendar->calendar_($printer_friendly); + } + if ($phpgw_info["flags"]["enable_utilities_class"]){ + $phpgw->utilities->utilities_(); + } + + if (!isset($phpgw_info["flags"]["nocommon_preferences"]) || !$phpgw_info["flags"]["nocommon_preferences"]) { + if (!isset($phpgw_info["user"]["preferences"]["common"]["maxmatchs"]) || !$phpgw_info["user"]["preferences"]["common"]["maxmatchs"]) { + $phpgw->preferences->change("common","maxmatchs",15); + $preferences_update = True; + } + if (!isset($phpgw_info["user"]["preferences"]["common"]["theme"]) || !$phpgw_info["user"]["preferences"]["common"]["theme"]) { + $phpgw->preferences->change("common","theme","default"); + $preferences_update = True; + } + if (!isset($phpgw_info["user"]["preferences"]["common"]["dateformat"]) || !$phpgw_info["user"]["preferences"]["common"]["dateformat"]) { + $phpgw->preferences->change("common","dateformat","m/d/Y"); + $preferences_update = True; + } + if (!isset($phpgw_info["user"]["preferences"]["common"]["timeformat"]) || !$phpgw_info["user"]["preferences"]["common"]["timeformat"]) { + $phpgw->preferences->change("common","timeformat",12); + $preferences_update = True; + } + if (!isset($phpgw_info["user"]["preferences"]["common"]["lang"]) || !$phpgw_info["user"]["preferences"]["common"]["lang"]) { + $phpgw->preferences->change("common","lang","en"); + $preferences_update = True; + } + if ($preferences_update) { + $phpgw->preferences->commit(__LINE__,__FILE__); + } + unset($preferences_update); + } + + /**************************************************************************\ + * These lines load up the themes * + \**************************************************************************/ + include($phpgw_info["server"]["server_root"] . "/themes/" . + $phpgw_info["user"]["preferences"]["common"]["theme"] . ".theme"); + + if ($phpgw_info["theme"]["bg_color"] == "") { + /* Looks like there was a problem finding that theme. Try the default */ + echo "Warning: error locating selected theme"; + include ($phpgw_info["server"]["server_root"] . "/themes/default.theme"); + if ($phpgw_info["theme"]["bg_color"] == "") { + // Hope we don't get to this point. Better then the user seeing a + // complety back screen and not know whats going on + echo "Fatal error: no themes found"; + exit; + } + } + + /**************************************************************************\ + * If they are using frames, we need to set some variables * + \**************************************************************************/ + if (($phpgw_info["user"]["preferences"]["common"]["useframes"] && $phpgw_info["server"]["useframes"] == "allowed") + || ($phpgw_info["server"]["useframes"] == "always")) { + $phpgw_info["flags"]["navbar_target"] = "phpgw_body"; + } + + /**************************************************************************\ + * Verify that the users session is still active otherwise kick them out * + \**************************************************************************/ + if ($phpgw_info["flags"]["currentapp"] != "home" && $phpgw_info["flags"]["currentapp"] != "logout" + && $phpgw_info["flags"]["currentapp"] != "preferences") { + + if (! $phpgw_info["user"]["apps"][$phpgw_info["flags"]["currentapp"]]) { + $phpgw->common->phpgw_header(); + echo "

" . lang("Access not permitted") . "
"; + exit; + } + } + + /**************************************************************************\ + * Load the header unless the developer turns it off * + \**************************************************************************/ + if (!isset($phpgw_info["flags"]["noheader"]) || ! $phpgw_info["flags"]["noheader"]) { + $phpgw->common->phpgw_header(); + } + + /**************************************************************************\ + * Load the app include files if the exists * + \**************************************************************************/ + /* Then the include file */ + if (file_exists ($phpgw_info["server"]["app_inc"]."/functions.inc.php")){ + include($phpgw_info["server"]["app_inc"]."/functions.inc.php"); + } + } + error_reporting(7); diff --git a/phpgwapi/phpgw_accounts_ldap.inc.php b/phpgwapi/phpgw_accounts_ldap.inc.php new file mode 100644 index 0000000000..cf3149a964 --- /dev/null +++ b/phpgwapi/phpgw_accounts_ldap.inc.php @@ -0,0 +1,310 @@ +common->ldapConnect(); + + // search the dn for the given uid + $sri = ldap_search($ds, $phpgw_info["server"]["ldap_context"], "uid=".$phpgw_info["user"]["userid"]); + $allValues = ldap_get_entries($ds, $sri); + + /* Now dump it into the array; take first entry found */ + $phpgw_info["user"]["account_id"] = $allValues[0]["uidnumber"][0]; + $phpgw_info["user"]["account_dn"] = $allValues[0]["dn"]; + $phpgw_info["user"]["account_lid"] = $allValues[0]["uid"][0]; + $phpgw_info["user"]["firstname"] = $allValues[0]["givenname"][0]; + $phpgw_info["user"]["lastname"] = $allValues[0]["sn"][0]; + $phpgw_info["user"]["fullname"] = $allValues[0]["cn"][0]; + +/* + // Please don't remove this code. Lars Kneschke + // remove the "count" value + for ($i=0; $i < $allValues[0]["phpgw_groups"]["count"]; $i++) + { + $phpgw_info["user"]["groups"][] = $allValues[0]["phpgw_groups"][$i]; + } + + // remove the "count" value + for ($i=0; $i < $allValues[0]["phpgw_account_perms"]["count"]; $i++) + { + $phpgw_info["user"]["app_perms"][] = $allValues[0]["phpgw_account_perms"][$i]; + } + + $phpgw_info["user"]["lastlogin"] = $allValues[0]["phpgw_lastlogin"][0]; + $phpgw_info["user"]["lastloginfrom"] = $allValues[0]["phpgw_lastfrom"][0]; + $phpgw_info["user"]["lastpasswd_change"] = $allValues[0]["phpgw_lastpasswd_change"][0]; + $phpgw_info["user"]["status"] = $allValues[0]["phpgw_status"][0]; +*/ + $db = $phpgw->db; + $db->query("select * from accounts where account_lid='" . $phpgw_info["user"]["userid"] . "'",__LINE__,__FILE__); + $db->next_record(); + + $phpgw_info["user"]["groups"] = explode (",",$db->f("account_groups")); + $phpgw_info["user"]["app_perms"] = explode (":",$db->f("account_permissions")); + $phpgw_info["user"]["lastlogin"] = $db->f("account_lastlogin"); + $phpgw_info["user"]["lastloginfrom"] = $db->f("account_lastloginfrom"); + $phpgw_info["user"]["lastpasswd_change"] = $db->f("account_lastpwd_change"); + $phpgw_info["user"]["status"] = $db->f("account_status"); + } + + function read_userData($dn) + { + global $phpgw_info, $phpgw; + + // get a ldap connection handle + $ds = $phpgw->common->ldapConnect(); + + // search the dn for the given uid + $sri = ldap_read($ds,rawurldecode("$dn"),"objectclass=*"); + $allValues = ldap_get_entries($ds, $sri); + + /* Now dump it into the array; take first entry found */ + $userData["account_id"] = $allValues[0]["uidnumber"][0]; + $userData["account_dn"] = $allValues[0]["dn"]; + $userData["account_lid"] = $allValues[0]["uid"][0]; + $userData["firstname"] = $allValues[0]["givenname"][0]; + $userData["lastname"] = $allValues[0]["sn"][0]; + $userData["fullname"] = $allValues[0]["cn"][0]; + +/* // Please don't remove this code. Lars Kneschke + // remove the "count" value + for ($i=0; $i < $allValues[0]["phpgw_groups"]["count"]; $i++) + { + $userData["groups"][] = $allValues[0]["phpgw_groups"][$i]; + } + + // remove the "count" value + for ($i=0; $i < $allValues[0]["phpgw_app_perms"]["count"]; $i++) + { + $userData["app_perms"][] = $allValues[0]["phpgw_account_perms"][$i]; + } + + $userData["lastlogin"] = $allValues[0]["phpgw_lastlogin"][0]; + $userData["lastloginfrom"] = $allValues[0]["phpgw_lastfrom"][0]; + $userData["lastpasswd_change"] = $allValues[0]["phpgw_lastpasswd_change"][0]; + $userData["status"] = $allValues[0]["phpgw_status"][0]; +*/ + + $db = $phpgw->db; + $db->query("select * from accounts where account_lid='" . $userData["account_lid"] . "'",__LINE__,__FILE__); + $db->next_record(); + + $userData["groups"] = explode (",",$db->f("account_groups")); + $userData["app_perms"] = explode (":",$db->f("account_permissions")); + $userData["lastlogin"] = $db->f("account_lastlogin"); + $userData["lastloginfrom"] = $db->f("account_lastloginfrom"); + $userData["lastpasswd_change"] = $db->f("account_lastpwd_change"); + $userData["status"] = $db->f("account_status"); + + return $userData; + } + + function read_groups($lid) { + global $phpgw_info, $phpgw; + $phpgw->db->query("select account_groups from accounts where account_lid='$lid'",__LINE__,__FILE__); + $phpgw->db->next_record(); + + $gl = explode(",",$phpgw->db->f("account_groups")); + for ($i=1; $i<(count($gl)-1); $i++) { + $ga = explode(":",$gl[$i]); + $groups[$ga[0]] = $ga[1]; + } + return $groups; + } + + function read_group_names($lid = "") + { + global $phpgw, $phpgw_info; + + if (! $lid) { + $lid = $phpgw_info["user"]["userid"]; + } + $groups = $this->read_groups($lid); + + $i = 0; + while ($groups && $group = each($groups)) { + $phpgw->db->query("select group_name from groups where group_id=".$group[0],__LINE__,__FILE__); + $phpgw->db->next_record(); + $group_names[$i][0] = $group[0]; + $group_names[$i][1] = $phpgw->db->f("group_name"); + $group_names[$i++][2] = $group[1]; + } + if (! $lid) + $this->group_names = $group_names; + + return $group_names; + } + +/* // This works a little odd, but it is required for apps to be listed in the correct order. + // We first take an array of apps in the correct order and give it a value of 1. Which local means false. + // After the app is verified, it is giving the value of 2, meaning true. + function read_apps($lid) + { + global $phpgw, $phpgw_info; + + // fing enabled apps in this system + $phpgw->db->query("select app_name from applications where app_enabled != 0 order by app_order",__LINE__,__FILE__); + while ($phpgw->db->next_record()) { + $enabled_apps[$phpgw->db->f("app_name")] = 1; + } + + // get a ldap connection handle + $ds = $phpgw->common->ldapConnect(); + + // search the dn for the given uid + $sri = ldap_search($ds, $phpgw_info["server"]["ldap_context"], "uid=$lid"); + $allValues = ldap_get_entries($ds, $sri); + + for ($i=0; $i < $allValues[0]["phpgw_account_perms"]["count"]; $i++) + { + $pl = $allValues[0]["phpgw_account_perms"][$i]; + if ($enabled_apps[$pl]) + { + $enabled_apps[$pl] = 2; + } + } + + // This is to prevent things from being loaded twice + if ($phpgw_info["user"]["userid"] == $lid) { + $group_list = $this->groups; + } else { + $group_list = $this->read_groups($lid); + } + + while ($group_list && $group = each($group_list)) { + $phpgw->db->query("select group_apps from groups where group_id=".$group[0]); + $phpgw->db->next_record(); + + $gp = explode(":",$phpgw->db->f("group_apps")); + for ($i=1,$j=0;$idb; + + $db2->query("select app_name,app_enabled from applications where app_enabled != 0 order by app_order",__LINE__,__FILE__); + while ($db2->next_record()) { + $enabled_apps[$db2->f("app_name")] = 1; + $app_status[$db2->f("app_name")] = $db2->f("app_status"); + } + + if (gettype($lid) == "integer") { + $db2->query("select account_permissions from accounts where account_id=$lid",__LINE__,__FILE__); + } else { + $db2->query("select account_permissions from accounts where account_lid='$lid'",__LINE__,__FILE__); + } + $db2->next_record(); + + $pl = explode(":",$db2->f("account_permissions")); + + for ($i=0; $iread_groups($lid); + + while ($group_list && $group = each($group_list)) { + $db2->query("select group_apps from groups where group_id=".$group[0],__LINE__,__FILE__); + $db2->next_record(); + + $gp = explode(":",$db2->f("group_apps")); + for ($i=1,$j=0;$idb->query("select group_apps from groups where group_id=".$group_id,__LINE__,__FILE__); + $phpgw->db->next_record(); + + $gp = explode(":",$phpgw->db->f("group_apps")); + for ($i=1,$j=0;$idb->query("select account_lid,account_firstname,account_lastname from accounts where account_groups" + . "like '%,$groups,%'",__LINE__,__FILE__); + } else { + $phpgw->db->query("select account_lid,account_firstname,account_lastname from accounts",__LINE__,__FILE__); + } + $i = 0; + while ($phpgw->db->next_record()) { + $accounts["account_lid"][$i] = $phpgw->db->f("account_lid"); + $accounts["account_firstname"][$i] = $phpgw->db->f("account_firstname"); + $accounts["account_lastname"][$i] = $phpgw->db->f("account_lastname"); + $i++; + } + return $accounts; + } + + function accounts_const() + { + global $phpgw, $phpgw_info; + + $this->groups = $this->read_groups($phpgw_info["user"]["userid"]); + $this->apps = $this->read_apps($phpgw_info["user"]["userid"]); + + $phpgw_info["user"]["apps"] = $this->apps; + } + + } diff --git a/phpgwapi/phpgw_accounts_shared.inc.php b/phpgwapi/phpgw_accounts_shared.inc.php new file mode 100644 index 0000000000..98acb8c5a0 --- /dev/null +++ b/phpgwapi/phpgw_accounts_shared.inc.php @@ -0,0 +1,289 @@ +db; + + //echo "
sync called
Line: $line
File:$file"; + + /* ********This sets the server variables from the database******** */ + $db->query("select * from config",__LINE__,__FILE__); + while($db->next_record()) { + $phpgw_info["server"][$db->f("config_name")] = $db->f("config_value"); + } + $phpgw->accounts->accounts_const(__LINE__,__FILE__); + + $phpgw_info_temp["user"] = $phpgw_info["user"]; + $phpgw_info_temp["apps"] = $phpgw_info["apps"]; + $phpgw_info_temp["server"] = $phpgw_info["server"]; + $phpgw_info_temp["hooks"] = $phpgw->hooks->read(); + $phpgw_info_temp["user"]["kp3"] = ""; // We don't want it anywhere in the + // database for security. + + $db->query("update phpgw_sessions set session_info='" . serialize($phpgw_info_temp) + . "' where session_id='" . $phpgw_info["user"]["sessionid"] . "'",__LINE__,__FILE__); + + } + + function add_app($appname,$rebuild = False) + { + if (! $rebuild) { + if (gettype($appname) == "array") { + $t .= ":"; + $t .= implode(":",$appname); + $this->temp_app_list .= $t; + } else { + $this->temp_app_list .= ":" . $appname; + } + } else { + $t = $this->temp_app_list . ":"; + unset($this->temp_app_list); + return $t; + } + } + + function sql_search($table,$owner=0) + { + global $phpgw_info; + global $phpgw; + $s = ""; +// Changed By: Skeeter 29 Nov 00 +// This is to allow the user to search for other individuals group info.... + if(!$owner) { + $owner = $phpgw_info["user"]["account_id"]; + } + $db = $phpgw->db; + $db->query("SELECT account_lid FROM accounts WHERE account_id=".$owner,__LINE__,__FILE__); + $db->next_record(); + $groups = $this->read_groups($db->f("account_lid")); + if (gettype($groups) == "array") { +// echo "\n\n\n\n\ntest: " . count($groups) . "\n\n\n\n\n\n"; + while ($group = each($groups)) { + $s .= " or $table like '%," . $group[0] . ",%'"; + } + } + return $s; + } + + // This is used to split the arrays in the access column into an array + function string_to_array($s) + { + $raw_array = explode(",",$s); + + for ($i=1,$j=0;$idb->query("select group_name from groups where group_id=".$groups[$i]); + $phpgw->db->query("select group_name from groups where group_id=".$group_number[0],__LINE__,__FILE__); + $phpgw->db->next_record(); + $s .= $phpgw->db->f("group_name"); + if (count($groups) != 0 && $i != count($groups)-2) + $s .= ","; + } + return $s; + } + + // This one is used for the access column + // This is used to convert a raw group string (,5,6,7,) into a string of + // there names. + // Example: accounting, billing, developers + function convert_string_to_names_access($gs) + { + global $phpgw; + + $groups = explode(",",$gs); + + $db2 = $phpgw->db; + + $s = ""; $i = 0; + for ($j=1;$jquery("select group_name from groups where group_id=".$groups[$j],__LINE__,__FILE__); + $db2->next_record(); + $group_names[$i] = $db2->f("group_name"); + $i++; + } + return implode(",",$group_names); + } + + // Convert an array into the format needed for the groups column in the accounts table. + // This function is only temp, until we create the wrapper class's for different forms + // of auth. + function groups_array_to_string($groups) + { + $s = ""; + if (count($groups)) { + while (list($t,$group,$level) = each($groups)) { + $s .= "," . $group . ":0"; + } + $s .= ","; + } + return $s; + } + + // Convert an array into the format needed for the access column. + function array_to_string($access,$array) + { + $s = ""; + if ($access == "group" || $access == "public" || $access == "none") { + if (count($array)) { + while ($t = each($array)) { + $s .= "," . $t[1]; + } + $s .= ","; + } + if (! count($array) && $access == "none") { + $s = ""; + } + } + return $s; + } + } + + + + class preferences + { + + function read_preferences() + { + global $phpgw, $phpgw_info; + + $phpgw->db->query("select preference_value from preferences where preference_owner='" + . $phpgw_info["user"]["account_id"] . "'",__LINE__,__FILE__); + $phpgw->db->next_record(); + $phpgw_info["user"]["preferences"] = unserialize($phpgw->db->f("preference_value")); + } + + // This should be called when you are doing changing the $phpgw_info["user"]["preferences"] + // array + function commit($line = "",$file = "") + { + //echo "
commit called
Line: $line
File: $file"; + + global $phpgw_info, $phpgw; + $db = $phpgw->db; + + $db->query("delete from preferences where preference_owner='" . $phpgw_info["user"]["account_id"] + . "'",__LINE__,__FILE__); + + $db->query("insert into preferences (preference_owner,preference_value) values ('" + . $phpgw_info["user"]["account_id"] . "','" . serialize($phpgw_info["user"]["preferences"]) + . "')",__LINE__,__FILE__); + $phpgw->accounts->sync(__LINE__,__FILE__); + } + + // Add a new preference. + function change($app_name,$var,$value = "") + { + global $phpgw_info; + + if (! $value) { + global $$var; + $value = $$var; + } + + $phpgw_info["user"]["preferences"][$app_name][$var] = $value; + } + + function delete($app_name,$var) + { + global $phpgw_info; + unset($phpgw_info["user"]["preferences"][$app_name][$var]); + + } + } //end of preferences class + + + + class acl + { + /* This is a new class. These are sample table entries + insert into phpgw_acl (acl_appname, acl_location, acl_account, acl_account_type, acl_rights) + values('filemanager', 'create', 1, 'u', 4); + insert into phpgw_acl (acl_appname, acl_location, acl_account, acl_account_type, acl_rights) + values('filemanager', 'create', 1, 'g', 2); + insert into phpgw_acl (acl_appname, acl_location, acl_account, acl_account_type, acl_rights) + values('filemanager', 'create', 2, 'u', 1); + insert into phpgw_acl (acl_appname, acl_location, acl_account, acl_account_type, acl_rights) + values('filemanager', 'create', 2, 'g', 2); + */ + + function check($location, $required, $appname = False){ + global $phpgw, $phpgw_info; + if ($appname == False){ + $appname = $phpgw_info["flags"]["currentapp"]; + } + // User piece + $sql = "select acl_rights from phpgw_acl where acl_appname='$appname'"; + $sql .= " and (acl_location in ('$location','everywhere')) and "; + $sql .= "((acl_account_type = 'u' and acl_account = ".$phpgw_info["user"]["account_id"].")"; + + // Group piece + $sql .= " or (acl_account_type='g' and acl_account in (0"; // group 0 covers all users + $memberships = $phpgw->accounts->read_group_names(); + if (is_array($memberships) && count($memberships) > 0){ + for ($idx = 0; $idx < count($memberships); ++$idx){ + $sql .= ",".$memberships[$idx][0]; + } + } + $sql .= ")))"; + $rights = 0; + $phpgw->db->query($sql ,__LINE__,__FILE__); + if ($phpgw->db->num_rows() == 0 && $phpgw_info["server"]["acl_default"] != "deny"){ return True; } + while ($phpgw->db->next_record()) { + if ($phpgw->db->f("acl_rights") == 0){ return False; } + $rights |= $phpgw->db->f("acl_rights"); + } + return !!($rights & $required); + } + + function add($app, $location, $id, $id_type, $rights){ + } + + function edit($app, $location, $id, $id_type, $rights){ + } + + function replace($app, $location, $id, $id_type, $rights){ + } + + function delete($app, $location, $id, $id_type){ + } + + function view($app, $location, $id, $id_type){ + } + + } //end of acl class +?> diff --git a/phpgwapi/phpgw_accounts_sql.inc.php b/phpgwapi/phpgw_accounts_sql.inc.php new file mode 100644 index 0000000000..ff6d91ed41 --- /dev/null +++ b/phpgwapi/phpgw_accounts_sql.inc.php @@ -0,0 +1,228 @@ +db; + + $db2->query("select * from accounts where account_lid='" . $phpgw_info["user"]["userid"] . "'",__LINE__,__FILE__); + $db2->next_record(); + + /* Now dump it into the array */ + $phpgw_info["user"]["account_id"] = $db2->f("account_id"); + $phpgw_info["user"]["firstname"] = $db2->f("account_firstname"); + $phpgw_info["user"]["lastname"] = $db2->f("account_lastname"); + $phpgw_info["user"]["fullname"] = $db2->f("account_firstname") . " " + . $db2->f("account_lastname"); + $phpgw_info["user"]["groups"] = explode (",", $db2->f("account_groups")); + $phpgw_info["user"]["app_perms"] = explode (":", $db2->f("account_permissions")); + $phpgw_info["user"]["lastlogin"] = $db2->f("account_lastlogin"); + $phpgw_info["user"]["lastloginfrom"] = $db2->f("account_lastloginfrom"); + $phpgw_info["user"]["lastpasswd_change"] = $db2->f("account_lastpwd_change"); + $phpgw_info["user"]["status"] = $db2->f("account_status"); + } + + function read_userData($id) + { + global $phpgw_info, $phpgw; + + $db2 = $phpgw->db; + + $db2->query("select * from accounts where account_id='$id'",__LINE__,__FILE__); + $db2->next_record(); + + /* Now dump it into the array */ + $userData["account_id"] = $db2->f("account_id"); + $userData["account_lid"] = $db2->f("account_lid"); + $userData["firstname"] = $db2->f("account_firstname"); + $userData["lastname"] = $db2->f("account_lastname"); + $userData["fullname"] = $db2->f("account_firstname") . " " + . $db2->f("account_lastname"); + $userData["groups"] = explode(",", $db2->f("account_groups")); + $userData["app_perms"] = explode(":", $db2->f("account_permissions")); + $userData["lastlogin"] = $db2->f("account_lastlogin"); + $userData["lastloginfrom"] = $db2->f("account_lastloginfrom"); + $userData["lastpasswd_change"] = $db2->f("account_lastpwd_change"); + $userData["status"] = $db2->f("account_status"); + + return $userData; + } + + function read_groups($lid) + { + global $phpgw_info, $phpgw; + + $db2 = $phpgw->db; + + if ($phpgw_info["user"]["userid"] != $lid) { + $db2->query("select account_groups from accounts where account_lid='$lid'",__LINE__,__FILE__); + $db2->next_record(); + $gl = explode(",",$db2->f("account_groups")); + } else { + $gl = $phpgw_info["user"]["groups"]; + } + + for ($i=1; $i<(count($gl)-1); $i++) { + $ga = explode(":",$gl[$i]); + $groups[$ga[0]] = $ga[1]; + } + return $groups; + } + + function read_group_names($lid = "") + { + global $phpgw, $phpgw_info; + + $db2 = $phpgw->db; + + if (! $lid) { + $lid = $phpgw_info["user"]["userid"]; + } + $groups = $this->read_groups($lid); + + $i = 0; + while ($groups && $group = each($groups)) { + $db2->query("select group_name from groups where group_id=".$group[0],__LINE__,__FILE__); + $db2->next_record(); + $group_names[$i][0] = $group[0]; + $group_names[$i][1] = $db2->f("group_name"); + $group_names[$i++][2] = $group[1]; + } + + if (! $lid) { + $this->group_names = $group_names; + } + + return $group_names; + } + + // This works a little odd, but it is required for apps to be listed in the correct order. + // We first take an array of apps in the correct order and give it a value of 1. Which local means false. + // After the app is verified, it is giving the value of 2, meaning true. + function read_apps($lid) + { + global $phpgw, $phpgw_info; + + $db2 = $phpgw->db; + + $db2->query("select * from applications where app_enabled != '0'",__LINE__,__FILE__); + while ($db2->next_record()) { + $name = $db2->f("app_name"); + $title = $db2->f("app_title"); + $status = $db2->f("app_enabled"); + $phpgw_info["apps"][$name] = array("title" => $title, "enabled" => True, "status" => $status); + + $enabled_apps[$db2->f("app_name")] = 1; + $app_status[$db2->f("app_name")] = $db2->f("app_status"); + } + + if (gettype($lid) == "integer") { + $db2->query("select account_permissions from accounts where account_id=$lid",__LINE__,__FILE__); + } else { + $db2->query("select account_permissions from accounts where account_lid='$lid'",__LINE__,__FILE__); + } + $db2->next_record(); + + $pl = explode(":",$db2->f("account_permissions")); + + for ($i=0; $iread_groups($lid); + + while ($group_list && $group = each($group_list)) { + $db2->query("select group_apps from groups where group_id=".$group[0],__LINE__,__FILE__); + $db2->next_record(); + + $gp = explode(":",$db2->f("group_apps")); + for ($i=1,$j=0;$idb; + + $db2->query("select group_apps from groups where group_id=".$group_id,__LINE__,__FILE__); + $db2->next_record(); + + $gp = explode(":",$db2->f("group_apps")); + for ($i=1,$j=0;$idb; + + if ($groups) { + $db2->query("select account_lid,account_firstname,account_lastname from accounts where account_groups" + . "like '%,$groups,%'",__LINE__,__FILE__); + } else { + $db2->query("select account_lid,account_firstname,account_lastname from accounts",__LINE__,__FILE__); + } + $i = 0; + while ($db2->next_record()) { + $accounts["account_lid"][$i] = $db2->f("account_lid"); + $accounts["account_firstname"][$i] = $db2->f("account_firstname"); + $accounts["account_lastname"][$i] = $db2->f("account_lastname"); + $i++; + } + return $accounts; + } + + + function accounts_const($line,$file) + { + global $phpgw, $phpgw_info; + + //echo "accounts_const called
line: $line
$file"; + + $phpgw->accounts->phpgw_fillarray(); + $phpgw->preferences->read_preferences(); + $this->groups = $this->read_groups($phpgw_info["user"]["userid"]); + $this->apps = $this->read_apps($phpgw_info["user"]["userid"]); + + $phpgw_info["user"]["apps"] = $this->apps; + } + + } diff --git a/phpgwapi/phpgw_addressbook.inc.php b/phpgwapi/phpgw_addressbook.inc.php new file mode 100644 index 0000000000..5a194ad410 --- /dev/null +++ b/phpgwapi/phpgw_addressbook.inc.php @@ -0,0 +1,16 @@ + \ No newline at end of file diff --git a/phpgwapi/phpgw_auth_ldap.inc.php b/phpgwapi/phpgw_auth_ldap.inc.php new file mode 100644 index 0000000000..6ae5536c41 --- /dev/null +++ b/phpgwapi/phpgw_auth_ldap.inc.php @@ -0,0 +1,47 @@ + 0) + { + // we only care about the first dn + $userDN = $allValues[0]["dn"]; + + // generate a bogus password to pass if the user doesn't give us one + // this gets around systems that are anonymous search enabled + if (empty($passwd)) $passwd = crypt(microtime()); + // try to bind as the user with user suplied password + if (ldap_bind($ldap,$userDN, $passwd)) return True; + } + + // Turn error reporting back to normal + error_reporting(7); + + // dn not found or password wrong + return False; + } + } +?> diff --git a/phpgwapi/phpgw_auth_mail.inc.php b/phpgwapi/phpgw_auth_mail.inc.php new file mode 100644 index 0000000000..915e5302a5 --- /dev/null +++ b/phpgwapi/phpgw_auth_mail.inc.php @@ -0,0 +1,43 @@ + \ No newline at end of file diff --git a/phpgwapi/phpgw_auth_sql.inc.php b/phpgwapi/phpgw_auth_sql.inc.php new file mode 100644 index 0000000000..16688bde9b --- /dev/null +++ b/phpgwapi/phpgw_auth_sql.inc.php @@ -0,0 +1,39 @@ +db; + + $local_debug = false; + + if ($local_debug) { + echo "Debug SQL: uid - $username passwd - $passwd"; + } + + $db->query("SELECT * FROM accounts WHERE account_lid = '$username' AND " + . "account_pwd='" . md5($passwd) . "' AND account_status ='A'",__LINE__,__FILE__); + $db->next_record(); + + if ($db->f("account_lid")) { + return True; + } else { + return False; + } + } + } +?> \ No newline at end of file diff --git a/phpgwapi/phpgw_calendar.inc.php b/phpgwapi/phpgw_calendar.inc.php new file mode 100644 index 0000000000..d12ed3f155 --- /dev/null +++ b/phpgwapi/phpgw_calendar.inc.php @@ -0,0 +1,1483 @@ +$var = $val; + } + } + + class calendar + { + var $today = array("full","month","day","year"); + var $printer_friendly = False; + var $repeated_events; + var $checked_events; + var $re = 0; + var $checkd_re = 0; + var $sorted_re = 0; + var $hour_arr = Array(); + var $rowspan_arr = Array(); + var $days = Array(); + var $first_hour; + var $last_hour; + var $rowspan; + var $weekstarttime; + var $daysinweek; + var $filter; + + function calendar_($p_friendly=False) { + global $phpgw; + + $this->printer_friendly = $p_friendly; + + $now = time(); + $this->today = $this->splitdate($now); + } + + function set_filter() { + global $phpgw_info, $phpgw, $filter; + if (!isset($this->filter) || !$this->filter) { + if (isset($filter) && $filter) { + $this->filter = " ".$filter." "; + } else { + if (! $phpgw_info["user"]["preferences"]["calendar"]["defaultfilter"]) { + $phpgw->preferences->change("calendar","defaultfilter","all"); + $phpgw->preferences->commit(); + } + $this->filter = " ".$phpgw_info["user"]["preferences"]["calendar"]["defaultfilter"]." "; + } + } + } + + function group_search($owner=0) { + global $phpgw; + global $phpgw_info; + $owner = $owner==$phpgw_info["user"]["account_id"]?0:$owner; + $groups = substr($phpgw->accounts->sql_search("calendar_entry.cal_group",$owner),4); + if (!$groups) { + return ""; + } else { + return "(calendar_entry.cal_access='group' AND (". $groups .")) "; + } + } + + function get_sunday_before($year,$month,$day) { + global $phpgw; + global $phpgw_info; + $weekday = date("w", mktime(0,0,0,$month,$day,$year)); + if ($phpgw_info["user"]["preferences"]["calendar"]["weekdaystarts"] == "Monday" && $weekday == 0) { + $day -= 7; + $weekday = date("w", mktime(0,0,0,$month,$day,$year) ); + } + return mktime(0,0,0,$month,$day - $weekday,$year) - (3600 * intval($phpgw_info["user"]["preferences"]["common"]["tz_offset"])); + } + + function normalizeminutes(&$minutes) { + $hour = 0; + $min = intval($minutes); + if($min >= 60) { + $hour += $min / 60; + $min %= 60; + } + settype($minutes,"integer"); + $minutes = $min; + return $hour; + } + + function addduration($hour,$minute,$ampm,$duration) { + $minute += $duration; + return $this->fixtime($hour,$minute,$ampm); + } + + function fixtime($hour=0,$minute=0,$ampm="") { + global $phpgw_info; + + $hour += (int)$this->normalizeminutes(&$minute); + if ($hour > 0) { + if ($phpgw_info["user"]["preferences"]["common"]["timeformat"] == "12") { +// $hour %= 12; + if (strtolower($ampm) == "pm" && $hour <> 12) { + $hour += 12; + } + } + } + return ($hour * 10000) + ($minute * 100); + } + + function splittime_($time) + { + global $phpgw_info; + + $temp = array("hour","minute","second","ampm"); + $time = strrev($time); + $second = (int)strrev(substr($time,0,2)); + $minute = (int)strrev(substr($time,2,2)); + $hour = (int)strrev(substr($time,4)); + $temp["second"] = (int)$second; + $temp["minute"] = (int)$minute; + $temp["hour"] = (int)$hour; + $temp["ampm"] = " "; + + return $temp; + } + + function splittime($time) { + global $phpgw_info; + + $temp = array("hour","minute","second","ampm"); + $time = strrev($time); + $second = intval(strrev(substr($time,0,2))); + $minute = intval(strrev(substr($time,2,2))); + $hour = intval(strrev(substr($time,4))); + $hour += $this->normalizeminutes(&$minute); + $temp["second"] = $second; + $temp["minute"] = $minute; + $temp["hour"] = $hour; + $temp["ampm"] = " "; + if ($phpgw_info["user"]["preferences"]["common"]["timeformat"] == "24") { + return $temp; + } + $temp["ampm"] = "am"; + if ((int)$temp["hour"] > 12) { + $temp["hour"] = (int)((int)$temp["hour"] - 12); + $temp["ampm"] = "pm"; + } elseif ((int)$temp["hour"] == 12) { + $temp["ampm"] = "pm"; + } + return $temp; + } + + function makegmttime($hour,$minute,$second,$month,$day,$year) { + global $phpgw; + global $phpgw_info; + + $date = Array("raw","day","month","year","full"); + $date["raw"] = mktime($hour, $minute, $second, $month, $day, $year) - ((60 * 60) * intval($phpgw_info["user"]["preferences"]["common"]["tz_offset"])); + $date["year"] = intval($phpgw->common->show_date($date["raw"],"Y")); + $date["month"] = intval($phpgw->common->show_date($date["raw"],"m")); + $date["day"] = intval($phpgw->common->show_date($date["raw"],"d")); + $date["full"] = intval($phpgw->common->show_date($date["raw"],"Ymd")); + return $date; + } + + function localdates($localtime) { + global $phpgw; + global $phpgw_info; + + $date = Array("raw","day","month","year","full","dow","dm"); + $date["raw"] = $localtime; + $date["year"] = intval($phpgw->common->show_date($date["raw"],"Y")); + $date["month"] = intval($phpgw->common->show_date($date["raw"],"m")); + $date["day"] = intval($phpgw->common->show_date($date["raw"],"d")); + $date["full"] = intval($phpgw->common->show_date($date["raw"],"Ymd")); + $date["dm"] = intval($phpgw->common->show_date($date["raw"],"dm")); + $date["dow"] = intval($phpgw->common->show_date($date["raw"],"w")); + return $date; + } + + function gmtdate($localtime) { + $localtime -= ((60 * 60) * intval($phpgw_info["user"]["preferences"]["common"]["tz_offset"])); + return $this->localdates($localtime); + } + + function splitdate($date) { + $temp = array("day","month","year","full","raw","dayofweek"); + $temp["raw"] = intval($date); + $temp["day"] = intval(date("d",(int)$date)); + $temp["month"] = intval(date("m",(int)$date)); + $temp["year"] = intval(date("Y",(int)$date)); + $temp["full"] = intval(date("Ymd",(int)$date)); + $temp["dayofweek"] = intval(date("w",(int)$date)); + return $temp; + } + + function date_to_epoch($d) { + return $this->splitdate(mktime(2,0,0,intval(substr($d,4,2)),intval(substr($d,6,2)),intval(substr($d,0,4)))); + } + + function overlap($starttime,$endtime,$participants,$groups,$owner=0,$id=0) { + global $phpgw; + global $phpgw_info; + + $retval = Array(); + $ok = False; + + $starttime = $starttime - ((60 * 60) * $phpgw_info["user"]["preferences"]["common"]["tz_offset"]); + $endtime = $endtime - ((60 * 60) * $phpgw_info["user"]["preferences"]["common"]["tz_offset"]); + + if($starttime == $endtime) $endtime = mktime($phpgw->common->show_date($starttime,"H"),$phpgw->common->show_date($starttime,"i"),0,$phpgw->common->show_date($starttime,"m"),$phpgw->common->show_date($starttime,"d") + 1,$phpgw->common->show_date($starttime,"Y")) - ((60*60) * $phpgw_info["user"]["preferences"]["common"]["tz_offset"]) - 1; + + $sql = "SELECT DISTINCT calendar_entry.cal_id " + . "FROM calendar_entry, calendar_entry_user, calendar_entry_repeats " + . "WHERE calendar_entry.cal_id = calendar_entry_user.cal_id " + . "AND (((".$starttime." <= calendar_entry.cal_datetime) AND (".$endtime." >= calendar_entry.cal_datetime) AND (".$endtime." <= calendar_entry.cal_edatetime)) " + . "OR ((".$starttime." >= calendar_entry.cal_datetime) AND (".$starttime." <= calendar_entry.cal_edatetime) AND (".$endtime." >= calendar_entry.cal_edatetime)) " + . "OR ((".$starttime." <= calendar_entry.cal_datetime) AND (".$endtime." >= calendar_entry.cal_edatetime)))"; + + if(count($participants) || is_array($groups)) { + $p_g = ""; + if(count($participants)) { + $p_g .= "("; + for($i=0;$igroup_search($owner); + if ($group) { + if ($p_g) $p_g .= "OR "; + $p_g .= $group; + } + if($p_g) $sql .= " AND (" . $p_g . ")"; + } + if($id) $sql .= " AND calendar_entry.cal_id <> ".$id; + + $phpgw->db->query($sql,__LINE__,__FILE__); + if(!$phpgw->db->num_rows()) return false; + while($phpgw->db->next_record()) { + $retval[] = intval($phpgw->db->f("cal_id")); + $ok = True; + } + if($ok) return $retval; else return False; + } + + function is_private($cal_info,$owner) { + global $phpgw; + global $phpgw_info; + + $is_private = False; + if ($owner == $phpgw_info["user"]["account_id"] || $owner == 0) { + } elseif ($cal_info->access == "private") { + $is_private = True; + } elseif($cal_info->access == "group") { + $is_private = True; + $phpgw->db->query("SELECT account_lid FROM accounts WHERE account_id=".$owner,__LINE__,__FILE__); + $phpgw->db->next_record(); + $groups = $phpgw->accounts->read_groups($phpgw->db->f("account_lid")); + while ($group = each($groups)) { + if (strpos(" ".$cal_info->groups." ",",".$group[0]).",") $is_private = False; + } + } + if ($is_private) { + $str = "private"; + } elseif (strlen($cal_info->name) > 19) { + $str = substr($cal_info->name, 0 , 19); + $str .= "..."; + } else { + $str = $cal_info->name; + } + return $str; + } + + function timematrix($date,$starttime,$endtime,$participants) { + global $phpgw; + global $phpgw_info; + + if(!isset($phpgw_info["user"]["preferences"]["calendar"]["interval"]) || + !$phpgw_info["user"]["preferences"]["calendar"]["interval"]) { + $phpgw_info["user"]["preferences"]["calendar"]["interval"] = 15; + } + $datetime = $this->gmtdate($date["raw"]); + $increment = $phpgw_info["user"]["preferences"]["calendar"]["interval"]; + $interval = (int)(60 / $increment); + + $str = "
".$phpgw->common->show_date($datetime["raw"],"l, F d, Y")."
"; + $str .= ""; + $str .= ""; + $str .= ""; + for($i=0;$i<24;$i++) { + for($j=0;$j<$interval;$j++) + switch($j) { + case 0: + if($interval == 4) { + $k = ($i<=9?"0":substr($i,0,1)); + } + $str .= ""; + break; + case 1: + if($interval == 4) { + $k = ($i<=9?substr($i,0,1):substr($i,1,2)); + } + $str .= ""; + break; + default: + $str .= ""; + break; + } + } + $str .= ""; + $str .= ""; + if(!$endtime) $endtime = $starttime; +// $endtime = $this->splittime_($this->addduration(intval($starttime["hour"]),intval($starttime["minute"]),$starttime["ampm"],$duration)); + + for($i=0;$iread_repeated_events($participants[$i]); + $str .= ""; + $str .= ""; + $events = $this->get_sorted_by_date($datetime["raw"],$participants[$i]); + if(!$this->sorted_re) { + for($j=0;$j<24;$j++) { + for($k=0;$k<$interval;$k++) { + $str .= ""; + } + } + } else { + for($h=0;$h<24;$h++) { + for($m=0;$m<$interval;$m++) { + $index = (($h * 10000) + (($m * $increment) * 100)); + $time_slice[$index]["marker"] = " "; + $time_slice[$index]["color"] = $phpgw_info["theme"]["bg_color"]; + $time_slice[$index]["description"] = ""; + } + } + for($k=0;$k<$this->sorted_re;$k++) { + $event = $events[$k]; + $eventend = $this->splittime($this->addduration($event->hour,$event->minute,$event->ampm,$event->duration)); + if($eventend["ampm"] == "pm") { + $eventend["hour"] += 12; + } + if(!$eventend["hour"]) { + $eventend["hour"] = 23; + $eventend["minute"] = 59; + } + $start = ($event->hour * 10000) + ($event->minute * 100); + $starttemp = $this->splittime("$start"); + $subminute = 0; + for($m=0;$m<$interval;$m++) { + $minutes = $increment * $m; + if(intval($starttemp["minute"]) > $minutes && intval($starttemp["minute"]) < ($minutes + $increment)) { + $subminute = ($starttemp["minute"] - $minutes) * 100; + } + } + $start -= $subminute; + $end = ($eventend["hour"] * 10000) + ($eventend["minute"] * 100); + $endtemp = $this->splittime("$end"); + $addminute = 0; + for($m=0;$m<$interval;$m++) { + $minutes = ($increment * $m); + if($endtemp["minute"] < ($minutes + $increment) && $endtemp["minute"] > $minutes) { + $addminute = ($minutes + $increment - $endtemp["minute"]) * 100; + } + } + $end += $addminute; + $starttemp = $this->splittime("$start"); + $endtemp = $this->splittime("$end"); +// Do not display All-Day events in this free/busy time + if((($starttemp["hour"] == 0) && ($starttemp["minute"] == 0)) && (($endtemp["hour"] == 23) && ($endtemp["minute"] == 59))) { + } else { + for($h=$starttemp["hour"];$h<=$endtemp["hour"];$h++) { + $startminute = 0; + $endminute = $interval; + $hour = $h * 10000; + if($h == intval($starttemp["hour"])) + $startminute = ($starttemp["minute"] / $increment); + if($h == intval($endtemp["hour"])) + $endminute = ($endtemp["minute"] / $increment); + for($m=$startminute;$m<$endminute;$m++) { + $index = ($hour + (($m * $increment) * 100)); + $time_slice[$index]["marker"] = "-"; + $time_slice[$index]["color"] = $phpgw_info["theme"]["bg01"]; + $time_slice[$index]["description"] = $this->is_private($event,$participants[$i]); + } + } + } + } + for($h=0;$h<24;$h++) { + $hour = $h * 10000; + for($m=0;$m<$interval;$m++) { + $index = ($hour + (($m * $increment) * 100)); + $str .= ""; + } + } + } + $str .= ""; + $str .= ""; + } + $str .= "
Participant"; + $str .= "link($phpgw_info["server"]["webserver_url"]."/calendar/edit_entry.php","year=".$datetime["year"]."&month=".$datetime["month"]."&day=".$datetime["day"]."&hour=".$i."&minute=".(interval * $j))."\" onMouseOver=\"window.status='".$i.":".($increment * $j<=9?"0":"").($increment * $j)."'; return true;\">"; + $str .= $k.""; + $str .= "link($phpgw_info["server"]["webserver_url"]."/calendar/edit_entry.php","year=".$datetime["year"]."&month=".$datetime["month"]."&day=".$datetime["day"]."&hour=".$i."&minute=".(interval * $j))."\" onMouseOver=\"window.status='".$i.":".($increment * $j)."'; return true;\">"; + $str .= $k.""; + $str .= "link($phpgw_info["server"]["webserver_url"]."/calendar/edit_entry.php","year=".$datetime["year"]."&month=".$datetime["month"]."&day=".$datetime["day"]."&hour=".$i."&minute=".(interval * $j))."\" onMouseOver=\"window.status='".$i.":".($increment * $j)."'; return true;\">"; + $str .= " 
".$phpgw->common->grab_owner_name($participants[$i])." ".$time_slice[$index]["marker"]."
"; + return $str; + } + + // The orginal patch read this 30+ times in a loop, only read it once. + function read_repeated_events($owner=0) { + global $phpgw; + global $phpgw_info; + + $this->re = 0; + $this->set_filter(); + $owner = !$owner?$phpgw_info["user"]["account_id"]:$owner; + $sql = "SELECT calendar_entry.cal_id " + . "FROM calendar_entry, calendar_entry_repeats, calendar_entry_user " + . "WHERE calendar_entry.cal_id=calendar_entry_repeats.cal_id AND " + . "calendar_entry.cal_id = calendar_entry_user.cal_id AND calendar_entry.cal_type='M' AND "; + $sqlfilter=""; +// Private + if($this->filter==" all " || strpos($this->filter,"private")) { + $sqlfilter .= "(calendar_entry_user.cal_login=".$owner." AND calendar_entry.cal_access='private') "; + } + +// Group Public + if($this->filter==" all " || strpos($this->filter,"group")) { + if($sqlfilter) + $sqlfilter .= "OR "; + $sqlfilter .= "(calendar_entry_user.cal_login=".$owner." OR ".$this->group_search($owner).") "; + } + +// Global Public + if($this->filter==" all " || strpos($this->filter,"public")) { + if($sqlfilter) + $sqlfilter .= "OR "; + $sqlfilter .= "calendar_entry.cal_access='public' "; + } + $orderby = " ORDER BY calendar_entry.cal_datetime ASC, calendar_entry.cal_edatetime ASC, calendar_entry.cal_priority ASC"; + + $db2 = $phpgw->db; + + if($sqlfilter) $sql .= "(".$sqlfilter.") "; + $sql .= $orderby; + + $db2->query($sql,__LINE__,__FILE__); + + $i = 0; + if($db2->num_rows()) { + while ($db2->next_record()) { + $repeated_event_id[$i++] = (int)$db2->f("cal_id"); + } + $this->re = $i; + $this->repeated_events = $this->getevent($repeated_event_id); + } else { + $this->repeated_events = Null; + } + } + + function link_to_entry($id, $pic, $description) { + global $phpgw; + global $phpgw_info; + + $str = ""; + if (!$this->printer_friendly) + $str .= "link($phpgw_info["server"]["webserver_url"]."/calendar/view.php","id=".$id)."\" onMouseOver=\"window.status='" + . lang("View this entry") . "'; return true;\">\"".$description."\""; + + return $str; + } + + function build_time_for_display($fixed_time) { + global $phpgw_info; +// echo "
before: $fixed_time"; + $time = $this->splittime($fixed_time); +// echo "
test -> build_time_for_display () in if " . $time["hour"] . " " . $time["ampm"]; +// echo "
  $fixed_time"; + $str = ""; + $str .= $time["hour"].":".((int)$time["minute"]<=9?"0":"").$time["minute"]; + if ($phpgw_info["user"]["preferences"]["common"]["timeformat"] == "12") { + $str .= " " . $time["ampm"]; + } + return $str; + } + + function check_repeating_entries($datetime) { + global $phpgw; + global $phpgw_info; + + $this->checked_re = 0; + if(!$this->re) return False; + $link = Array(); + $date = $this->gmtdate($datetime); + for ($i=0;$i<$this->re;$i++) { + $rep_events = $this->repeated_events[$i]; + $start = $this->localdates($rep_events->datetime); + if($rep_events->rpt_use_end) + $end = $rep_events->rpt_end; + else + $end = mktime(0,0,0,1,1,2007) - ((60 * 60) * $phpgw_info["users"]["preferences"]["common"]["tz_offset"]); + + $enddate = $this->localdates($end); + // only repeat after the beginning, and if there is an end + // before the end + if ($rep_events->rpt_use_end && ($date["full"] > $enddate["full"])) { + continue; + } + + if ($date["full"] < $start["full"]) { + continue; + } + + if ($date["full"] == $start["full"]) { + $link[$this->checked_re] = $i; + $this->checked_re++; + } else if ($rep_events->rpt_type == 'daily') { + if (floor(($date["raw"] - $start["raw"])/86400) % intval($rep_events->rpt_freq)) + continue; + $link[$this->checked_re] = $i; + $this->checked_re++; + } else if ($rep_events->rpt_type == 'weekly') { + $isDay = strtoupper(substr($rep_events->rpt_days, $date["dow"], 1)); + + /*if ( (floor($diff/86400) % $this->rep_events->rpt_freq) ) // Whats this for ? + ** continue; + */ + if (floor(($date["raw"] - $start["raw"])/604800) % intval($rep_events->rpt_freq)) continue; + if (strcmp($isDay,"Y") == 0) { + $link[$this->checked_re] = $i; + $this->checked_re++; + } + } else if ($rep_events->rpt_type == 'monthlybyday') { + if ((($date["year"] - $start["year"]) * 12 + $date["month"] - $start["month"]) % intval($rep_events->rpt_freq)) continue; + + if (($start["dow"] == $date["dow"]) && + (floor($start["day"]/7) == floor($date["day"]/7))) { + $link[$this->checked_re] = $i; + $this->checked_re++; + } + } else if ($rep_events->rpt_type == 'monthlybydate') { + if ((($date["year"] - $start["year"]) * 12 + $date["month"] - $start["month"]) % intval($rep_events->rpt_freq)) continue; + if ($date["day"] == $start["day"]) { + $link[$this->checked_re] = $i; + $this->checked_re++; + } + } else if ($rep_events->rpt_type == 'yearly') { + if (($date["year"] - $start["year"]) % intval($rep_events->rpt_freq)) continue; + if ($date["dm"] == $start["dm"]) { + $link[$this->checked_re] = $i; + $this->checked_re++; + } + } else { + // unknown rpt type - because of all our else ifs + } + } // end for loop + + if($this->checked_re) { + return $link; + } else { + return False; + } + } // end function + + function get_sorted_by_date($datetime,$owner=0) { + global $phpgw; + global $phpgw_info; + + $this->sorted_re = 0; + $this->set_filter(); + $owner = !$owner?$phpgw_info["user"]["account_id"]:$owner; + $rep_event = $this->check_repeating_entries($datetime,$owner); + $sql = "SELECT DISTINCT calendar_entry.cal_id, calendar_entry.cal_datetime, " + . "calendar_entry.cal_edatetime, calendar_entry.cal_priority " + . "FROM calendar_entry, calendar_entry_user " + . "WHERE ((calendar_entry.cal_datetime >= " . $datetime . " AND calendar_entry.cal_datetime <= ".($datetime + 86399).") OR " + . "(calendar_entry.cal_datetime <= " . $datetime . " AND calendar_entry.cal_edatetime >= ".($datetime + 86399).")) AND " +// . "WHERE (calendar_entry.cal_datetime >= " . $datetime . " AND calendar_entry.cal_datetime <= ".($datetime + 86399).") AND " + . "calendar_entry_user.cal_id=calendar_entry.cal_id AND calendar_entry.cal_type != 'M' AND "; + $sqlfilter = ""; +// Private + if($this->filter==" all " || strpos($this->filter,"private")) { + $sqlfilter .= "(calendar_entry_user.cal_login = ".$owner." AND calendar_entry.cal_access='private') "; + } + +// Group Public + if($this->filter==" all " || strpos($this->filter,"group")) { + if($sqlfilter) + $sqlfilter .= "OR "; + $sqlfilter .= $this->group_search($owner)." "; + } + +// Global Public + if($this->filter==" all " || strpos($this->filter,"public")) { + if($sqlfilter) + $sqlfilter .= "OR "; + $sqlfilter .= "calendar_entry.cal_access='public' "; + } + $orderby = " ORDER BY calendar_entry.cal_datetime ASC, calendar_entry.cal_edatetime ASC, calendar_entry.cal_priority ASC"; + + $db2 = $phpgw->db; + + if($sqlfilter) $sql .= "(".$sqlfilter.") "; + $sql .= $orderby; + + $db2->query($sql,__LINE__,__FILE__); + + $events = Null; + $rep_events = Array(); + if($db2->num_rows()) { + while($db2->next_record()) { + $rep_events[$this->sorted_re++] = (int)$db2->f(0); + } + $events = $this->getevent($rep_events); + } else + $events = Array(new calendar_item); + + if(!$this->checked_re && !$this->sorted_re) return False; + + $e = new calendar_item; + for ($j=0;$j<$this->checked_re;$j++) { + $e = $this->repeated_events[$rep_event[$j]]; + $events[$this->sorted_re++] = $e; + } + if(!$this->sorted_re) return False; + if($this->sorted_re == 1) return $events; + for($outer_loop=0;$outer_loop<$this->sorted_re - 1;$outer_loop++) { + $outer = $events[$outer_loop]; + for($inner_loop=$outer_loop;$inner_loop<$this->sorted_re;$inner_loop++) { + $inner = $events[$inner_loop]; + if(($outer->datetime > $inner->datetime) || (($outer->datetime == $inner->datetime) && ($outer->edatetime > $inner->edatetime))) { + $temp = $events[$inner_loop]; + $events[$inner_loop] = $events[$outer_loop]; + $events[$outer_loop] = $temp; + } + } + } + + if(isset($events)) return $events; else return False; + } + + function large_month_header($month,$year,$display_name = False) { + global $phpgw; + global $phpgw_info; + + $this->weekstarttime = $this->get_sunday_before($year,$month,1); + if ($phpgw_info["user"]["preferences"]["calendar"]["weekdaystarts"] == "Monday") { + $this->days = array(0 => "Mon", 1 => "Tue", 2 => "Wed", 3 => "Thu", 4 => "Fri", 5 => "Sat", 6 => "Sun"); + $this->weekstarttime += 86400; + } else { + $this->days = array(0 => "Sun", 1 => "Mon", 2 => "Tue", 3 => "Wed", 4 => "Thu", 5 => "Fri", 6 => "Sat"); + } + $this->daysinweek = 7; + $str = "\n"; + $str .= "\n"; + + if($display_name) + $str .= "\n"; + + for($i=0;$i<$this->daysinweek;$i++) + $str .= "\n"; + $str .= "\n"; + + return $str; + } + + function display_week($startdate,$weekly,$cellcolor,$display_name = False,$owner=0,$monthstart=0,$monthend=0) { + global $phpgw; + global $phpgw_info; + + $str = ""; + $gr_events = new calendar_item; + $lr_events = new calendar_item; + if($display_name) { + $str .= ""; + } + for ($j=0;$j<$this->daysinweek;$j++) { + $date = $this->gmtdate($startdate + ($j * 24 * 3600)); + if ($weekly || ($date["full"] >= $monthstart && $date["full"] <= $monthend)) { + if($weekly) $cellcolor = $phpgw->nextmatchs->alternate_row_color($cellcolor); + $str .= "\n"; + } else { + $str .= "\n"; + } + } + return $str; + } + + function display_large_month($month,$year,$showyear,$owner=0) { + global $phpgw, $phpgw_info; + + if($owner == $phpgw_info["user"]["account_id"]) $owner = 0; + $this->read_repeated_events($owner); + + $str = ""; + $str .= $this->large_month_header($month,$year,False); + + $monthstart = intval(date("Ymd",mktime(0,0,0,$month ,1,$year))); + $monthend = intval(date("Ymd",mktime(0,0,0,$month + 1,0,$year))); + + $today = $this->splitdate(time()); + + $cellcolor = $phpgw_info["theme"]["row_on"]; + + for ($i=$this->weekstarttime;intval(date("Ymd",$i))<=$monthend;$i += (24 * 3600 * 7)) { + $cellcolor = $phpgw->nextmatchs->alternate_row_color($cellcolor); + + $str .= "\n"; + $str .= $this->display_week($i,False,$cellcolor,False,$owner,$monthstart,$monthend); + } + $str .= "
".lang("name")."".lang($this->days[$i])."
".$phpgw->common->grab_owner_name($owner)."today["full"]) { + $str .= " bgcolor=\"".$phpgw_info["theme"]["cal_today"]."\">"; + } else { + $str .= " bgcolor=\"$cellcolor\">"; + } + + if (!$this->printer_friendly) { + $str .= "link($phpgw_info["server"]["webserver_url"]."/calendar/edit_entry.php","year=".$date_year."&month=".$date["month"]."&day=".$date["day"])."\">" + . "\"".lang("New"; + $str .= "[ link($phpgw_info["server"]["webserver_url"]."/calendar/day.php","month=".$date["month"]."&day=".$date["day"]."&year=".$date["year"])."\">".$date["day"]." ]
\n"; + } else { + $str .= "[ ".$date["day"]." ]
\n"; + } + $str .= ""; + + $rep_events = $this->get_sorted_by_date($date["raw"],$owner); + + if ($this->sorted_re) { + $lr_events = new calendar_item; + for ($k=0;$k<$this->sorted_re;$k++) { + $lr_events = $rep_events[$k]; + $str .= ""; + $pict = "circle.gif"; + for ($outer_loop=0;$outer_loop<$this->re;$outer_loop++) { + $gr_events = $this->repeated_events[$outer_loop]; + if ($gr_events->id == $lr_events->id) { + $pict = "rpt.gif"; + } + } + $str .= $this->link_to_entry($lr_events->id, $pict, $lr_events->description); +// echo "
hour:" . $lr_events->hour . " minute: " . $lr_events->minute . " ap: " . $lr_events->ampm; +// echo "
fixed_time: $fixed_time"; + if (intval($phpgw->common->show_date($lr_events->datetime,"Hi"))) { + if ($phpgw_info["user"]["preferences"]["common"]["timeformat"] == "12") { + $format = "h:i a"; + } else { + $format = "H:i"; + } + $str .= "".$phpgw->common->show_date($lr_events->datetime,$format)."-".$phpgw->common->show_date($lr_events->edatetime,$format)." "; + } + $str .= "
"; + + $str .= ""; + $str .= $this->is_private($lr_events,$owner); + $str .= "
"; + $str .= "
"; + } + } + $str .= "
"; + + if (!$j) { + if(!$this->printer_friendly) { + $str .= "link($phpgw_info["server"]["webserver_url"]."/calendar/week.php","date=".$date["full"])."\">week " .(int)((date("z",($startdate+(24*3600*4)))+7)/7).""; + } else { + $str .= "week " .(int)((date("z",($startdate+(24*3600*4)))+7)/7).""; + } + } + $str .= "
\n"; + + return $str; + } + + function display_large_week($day,$month,$year,$showyear,$owners=0) { + global $phpgw; + global $phpgw_info; + + $start = $this->get_sunday_before($year, $month, $day); + + $cellcolor = $phpgw_info["theme"]["row_off"]; + + if ($phpgw_info["user"]["preferences"]["calendar"]["weekdaystarts"] == "Monday") { + $start += 86400; + } + + $str = ""; + + $true_printer_friendly = $this->printer_friendly; + + if(is_array($owners)) { + $display_name = True; + $counter = count($owners); + $owners_array = $owners; + } else { + $display_name = False; + $counter = 1; + $owners_array[0] = $owners; + } + $str .= $this->large_month_header($month,$year,$display_name); + + for($i=0;$i<$counter;$i++) { + $this->repeated_events = Null; + $owner = $owners_array[$i]; + if($owner <> $phpgw_info["user"]["account_id"] && $owner <> 0) + $this->printer_friendly = True; + else + $this->printer_friendly = $true_printer_friendly; + $this->read_repeated_events($owner); + $str .= ""; + $str .= $this->display_week($start,True,$cellcolor,$display_name,$owner); + } + $this->printer_friendly = $true_printer_friendly; + $str .= ""; + return $str; + } + + function pretty_small_calendar($day,$month,$year,$link="") { + global $phpgw, $phpgw_info, $view; + +// $tz_offset = (-1 * ((60 * 60) * intval($phpgw_info["user"]["preferences"]["common"]["tz_offset"]))); + $date = $this->makegmttime(0,0,0,$month,$day,$year); + $month_ago = intval(date("Ymd",mktime(0,0,0,$month - 1,$day,$year))); + $month_ahead = intval(date("Ymd",mktime(0,0,0,$month + 1,$day,$year))); + $monthstart = intval(date("Ymd",mktime(0,0,0,$month,1,$year))); + $monthend = intval(date("Ymd",mktime(0,0,0,$month + 1,0,$year))); + + $weekstarttime = $this->get_sunday_before($year,$month,1); + if ($phpgw_info["user"]["preferences"]["calendar"]["weekdaystarts"] == "Monday") { + $days = array(0 => "Monday", 1 => "Tuesday", 2 => "Wednesday", 3 => "Thursday", 4 => "Friday", 5 => "Saturday", 6 => "Sunday"); + $weekstarttime += (3600 * 25); + } else { + $days = array(0 => "Sunday", 1 => "Monday", 2 => "Tuesday", 3 => "Wednesday", 4 => "Thursday", 5 => "Friday", 6 => "Saturday"); + } + $str = ""; + $str .= ""; + $str .= ""; + $str .= ""; + $str .= ""; + $str .= "
"; + $str .= ""; + if ($view == "day") { + $str .= ""; + } + $str .= ""; + + if ($view == "year") { + $str .= '"; + $str .= ""; + } + + if ($view != "year") { + $str .= ""; + } + $str .= ""; + $str .= ""; + for($i=0;$i<7;$i++) { + $str .= ""; + } + $str .= ""; + for($i=$weekstarttime;date("Ymd",$i)<=$monthend;$i += (24 * 3600 * 7)) { + $str .= ""; + for($j=0;$j<7;$j++) { + $cal = $this->gmtdate($i + ($j * 24 * 3600)); + if($cal["full"] >= $monthstart && $cal["full"] <= $monthend) { + $str .= ""; + } else { + $str .= ''; + } + } + $str .= ""; + } + $str .= "
".$day."
'; + } else { + $str .= ''; + } + + if ($view != "year") { + if (!$this->printer_friendly) { + $str .= "link($phpgw_info["server"]["webserver_url"]."/calendar/day.php","date=".$month_ago)."\" class=\"monthlink\">"; + } + $str .= "<"; + if (!$this->printer_friendly) $str .= ""; + $str .= ""; + } + if (!$this->printer_friendly) { + $str .= "link($phpgw_info["server"]["webserver_url"]."/calendar/index.php","year=".$year."&month=".$month)."\">"; + } + $str .= lang($phpgw->common->show_date($date["raw"],"F"))." ".$year; + if(!$this->printer_friendly) $str .= ""; + if ($view != "year") { + $str .= ""; + if (!$this->printer_friendly) { + $str .= "link($phpgw_info["server"]["webserver_url"]."/calendar/day.php","date=".$month_ahead)."\" class=\"monthlink\">"; + } + $str .= ">"; + if (!$this->printer_friendly) { + $str .= ""; + } + $str .= "
".substr(lang($days[$i]),0,2)."
today["full"]) { + $str .= $phpgw_info["theme"]["cal_today"]; + } else { + $str .= $phpgw_info["theme"]["cal_dayview"]; + } + $str .= "\">"; + + if(!$this->printer_friendly) { + $str .= "link($phpgw_info["server"]["webserver_url"]."/calendar/".$link,"year=".$cal["year"]."&month=".$cal["month"]."&day=".$cal["day"])."\" class=\"monthlink\">"; + } + $str .= $cal["day"]; + if(!$this->printer_friendly) $str .= ""; + $str .= ".
"; + $str .= "
"; + return $str; + } + + function display_small_month($month,$year,$showyear,$link="") { + global $phpgw; + global $phpgw_info; + + if($phpgw_info["user"]["preferences"]["calendar"]["weekdaystarts"] == "Monday") { + $days = array(0 => "Mo", 1 => "Tu", 2 => "We", 3 => "Th", 4 => "Fr", 5 => "Sa", 6 => "Su"); + $weekstarttime = $this->get_sunday_before($year,$month,1) + 86400; + } else { + $days = array(0 => "Su", 1 => "Mo", 2 => "Tu", 3 => "We", 4 => "Th", 5 => "Fr", 6 => "Sa"); + $weekstarttime = $this->get_sunday_before($year,$month,1); + } + $daysinweek = 7; + + $str = ""; + $str .= ""; + + $monthstart = $this->splitdate(mktime(0,0,0,$month ,1,$year)); + $monthend = $this->splitdate(mktime(0,0,0,$month + 1,0,$year)); + + $str .= "" + . ""; + for($i=0;$i<$daysinweek;$i++) { + $str .= ""; + } + $str .= ""; + + for($i=$weekstarttime;date("Ymd",$i)<=$monthend["full"];$i+=604800) { + $str .= ""; + for($j=0;$j<$daysinweek;$j++) { + $date = $this->splitdate($i + ($j * 86400)); + if($date["full"]>=$monthstart["full"] && + $date["full"]<=$monthend["full"]) { + $str .= ""; + } else { + $str .= ""; + } + } + $str .= ""; + } + $str .= "
"; + + if(!$this->printer_friendly) { + $str .= "link($phpgw_info["server"]["webserver_url"]."/calendar/index.php","year=$year&month=$month")."\">"; + } + $str .= lang(date("F",$monthstart["raw"])); + + if($showyear) { + $str .= " ".$year; + } + + if(!$this->printer_friendly) { + $str .= ""; + } + + $str .= "
".lang($days[$i])."
"; + if(!$this->printer_friendly || $link) { + $str .= "link($phpgw_info["server"]["webserver_url"]."/calendar/".$link,"year=".$date["year"]."&month=".$date["month"]."&day=".$date["day"])."\">"; + } + $str .= "".date("j",$date["raw"]); + if(!$this->printer_friendly || $link) $str .= ""; + $str .= "
"; + return $str; + } + + + function html_for_event_day_at_a_glance ($event) { + global $phpgw, $phpgw_info; + + if ($phpgw_info["user"]["preferences"]["common"]["timeformat"] == "12") { + $format = "h:i a"; + } else { + $format = "H:i"; + } + + $ind = intval($phpgw->common->show_date($event->datetime,"H")); + + if($ind<$this->first_hour || $ind>$this->last_hour) $ind = 99; + + if(!isset($this->hour_arr[$ind]) || !$this->hour_arr[$ind]) $this->hour_arr[$ind] = ""; + + if (!$this->printer_friendly) { + $this->hour_arr[$ind] .= "link($phpgw_info["server"]["webserver_url"]."/calendar/view.php","id=".$event->id) + . "\" onMouseOver=\"window.status='" + . lang("View this entry")."'; return true;\">"; + } + + $this->hour_arr[$ind] .= "[" . $phpgw->common->show_date($event->datetime,$format); + if ($event->datetime <> $event->edatetime) { // calc end time + $this->hour_arr[$ind] .= " - " . $phpgw->common->show_date($event->edatetime,$format); + $end_t_h = intval($phpgw->common->show_date($event->edatetime,"H")); + $end_t_m = intval($phpgw->common->show_date($event->edatetime,"i")); + if (end_t_m == 0) + $this->rowspan = $end_t_h - $ind; + else + $this->rowspan = $end_t_h - $ind + 1; + if(isset($this->rowspan_arr[$ind])) $r = $this->rowspan_arr[$ind]; else $r = 0; + if ($this->rowspan > $r && $this->rowspan > 1) + $this->rowspan_arr[$ind] = $this->rowspan; + } + $this->hour_arr[$ind] .= "] "; + $this->hour_arr[$ind] .= "\""description . "\">"; + if ($event->priority == 3) + $this->hour_arr[$ind] .= ""; + $this->hour_arr[$ind] .= $event->name; + + if ($event->priority == 3) + $this->hour_arr[$ind] .= ""; + $this->hour_arr[$ind] .= "
"; + } + + function print_day_at_a_glance($date,$owner=0) { + global $phpgw; + global $phpgw_info; + + $this->read_repeated_events($owner); + + $str = ""; + + $str .= ""; + + if (! $phpgw_info["user"]["preferences"]["calendar"]["workdaystarts"] && + ! $phpgw_info["user"]["preferences"]["calendar"]["workdayends"]) { + + $phpgw_info["user"]["preferences"]["calendar"]["workdaystarts"] = 8; + $phpgw_info["user"]["preferences"]["calendar"]["workdayends"] = 16; + } + + $this->first_hour = (int)$phpgw_info["user"]["preferences"]["calendar"]["workdaystarts"] + 1; + $this->last_hour = (int)$phpgw_info["user"]["preferences"]["calendar"]["workdayends"] + 1; + + $events = array(new calendar_item); + + $events = $this->get_sorted_by_date($date["raw"]); + + if(!$events) { + } else { + $event = new calendar_item; + for($i=0;$ihtml_for_event_day_at_a_glance($event); + } + } + + // squish events that use the same cell into the same cell. + // For example, an event from 8:00-9:15 and another from 9:30-9:45 both + // want to show up in the 8:00-9:59 cell. + $this->rowspan = 0; + $this->last_row = -1; + for ($i=0;$i<24;$i++) { + if(isset($this->rowspan_arr[$i])) $r = $this->rowspan_arr[$i]; else $r = 0; + if(isset($this->hour_arr[$i])) $h = $this->hour_arr[$i]; else $h = ""; + if ($this->rowspan > 1) { + if (strlen($h)) { + $this->hour_arr[$this->last_row] .= $this->hour_arr[$i]; + $this->hour_arr[$i] = ""; + $this->rowspan_arr[$i] = 0; + } + $this->rowspan--; + } elseif ($r > 1) { + $this->rowspan = $this->rowspan_arr[$i]; + $this->last_row = $i; + } + } + if (isset($this->hour_arr[99]) && strlen($this->hour_arr[99])) { + $str .= "\n"; + } + $this->rowspan = 0; + for ($i=$this->first_hour;$i<=$this->last_hour;$i++) { + if(isset($this->hour_arr[$i])) $h = $this->hour_arr[$i]; else $h = ""; + $time = $this->build_time_for_display($i * 10000); + $str .= ""; + if ($this->rowspan > 1) { + // this might mean there's an overlap, or it could mean one event + // ends at 11:15 and another starts at 11:30. + if (strlen($h)) + $str .= "\n"; + $this->rowspan--; + } else { + if (!strlen($h)) + $str .= "\n"; + else { + $this->rowspan = isset($this->rowspan_arr[$i])?$this->rowspan_arr[$i]:0; + if ($this->rowspan > 1) + $str .= "\n"; + else + $str .= "\n"; + } + } + } // end for + $str .= "
" + . " ".$this->hour_arr[99]."
"; + + // tooley: the hour - 36400 is a HACK for improper storage of hour allows + // in user preference land. + if(!$this->printer_friendly) { + $str .= "link($phpgw_info["server"]["webserver_url"]."/calendar/edit_entry.php","year=".$date["year"] + . "&month=".$date["month"]."&day=".$date["day"] + . "&hour=".substr($time,0,strpos($time,":")) + . "&minute=".substr($time,strpos($time,":")+1,2))."\">"; + } + $str .= $time; + if(!$this->printer_friendly) { + $str .= ""; + } + $str .= "".$this->hour_arr[$i]."
 
rowspan."\">" + . $this->hour_arr[$i]."
".$this->hour_arr[$i]."
"; + return $str; + } // end function + + function prep($calid) { + global $phpgw; + global $phpgw_info; + + if(!$phpgw_info["user"]["apps"]["calendar"]) return false; + + $cal_id = array(); + if(is_long($calid)) { + if(!$calid) return false; + $cal_id[0] = $calid; + } elseif(is_string($calid)) { + + $phpgw->db->query("SELECT account_id FROM accounts WHERE account_lid='$calid'",__LINE__,__FILE__); + $phpgw->db->next_record(); + $calid = $phpgw->db->f("account_id"); + $phpgw->db->query("SELECT cal_id FROM calendar_entry WHERE cal_owner=".$calid,__LINE__,__FILE__); + while($phpgw->db->next_record()) { + $cal_id[count($cal_id)] = $phpgw->db->f("cal_id"); + } + } elseif(is_array($calid)) { + if(is_string($calid[0])) { + for($i=0;$idb->query("SELECT cal_id FROM calendar_entry WHERE cal_owner=".$calid[$i],__LINE__,__FILE__); + while($phpgw->db->next_record()) { + $cal_id[count($cal_id)] = $phpgw->db->f("cal_id"); + } + } + } elseif(is_long($calid[0])) { + $cal_id = $calid; + } + } + return $cal_id; + } + + function getwithindates($from,$to) { + global $phpgw; + global $phpgw_info; + + if(!$phpgw_info["user"]["apps"]["calendar"]) return false; + + + $phpgw->db->query("SELECT cal_id FROM calendar_entry WHERE cal_date >= ".$from." AND cal_date <= ".$to,__LINE__,__FILE__); + if($phpgw->db->num_rows()) { + while($phpgw->db->next_record()) { + $calid[count($calid)] = intval($phpgw->db->f("cal_id")); + } + return $this->getevent($calid); + } else { + return false; + } + } + + function add($calinfo,$calid=0) { + global $phpgw; + global $phpgw_info; + + if(!$phpgw_info["user"]["apps"]["calendar"]) return false; + if(!$calid) { + $phpgw->db->lock(array('calendar_entry','calendar_entry_user','calendar_entry_repeats')); + $phpgw->db->query("INSERT INTO calendar_entry(cal_name) VALUES('".addslashes($calinfo->name)."')",__LINE__,__FILE__); + $phpgw->db->query("SELECT MAX(cal_id) FROM calendar_entry",__LINE__,__FILE__); + $phpgw->db->next_record(); + $calid = $phpgw->db->f(0); + $phpgw->db->unlock(); + } + if($calid) return $this->modify($calinfo,$calid); + } + + function delete($calid=0) { + global $phpgw; + + $cal_id = $this->prep($calid); + + if(!$cal_id) return false; + + $phpgw->db->lock(array("calendar_entry","calendar_entry_user","calendar_entry_repeats")); + + for($i=0;$idb->query("DELETE FROM calendar_entry_user WHERE cal_id=".$cal_id[$i],__LINE__,__FILE__); + $phpgw->db->query("DELETE FROM calendar_entry_repeats WHERE cal_id=".$cal_id[$i],__LINE__,__FILE__); + $phpgw->db->query("DELETE FROM calendar_entry WHERE cal_id=".$cal_id[$i],__LINE__,__FILE__); + } + $phpgw->db->unlock(); + } + + function modify($calinfo,$calid=0) { + global $phpgw; + global $phpgw_info; + + if(!$phpgw_info["user"]["apps"]["calendar"]) return false; + + if(!$calid) return false; + + $phpgw->db->lock(array("calendar_entry","calendar_entry_user","calendar_entry_repeats")); + + $owner = ($calinfo->owner?$calinfo->owner:$phpgw_info["user"]["account_id"]); + if ($phpgw_info["user"]["preferences"]["common"]["timeformat"] == "12") { + if ($calinfo->ampm == "pm" && ($calinfo->hour < 12 && $calinfo->hour <> 12)) { + $calinfo->hour += 12; + } + if ($calinfo->end_ampm == "pm" && ($calinfo->end_hour < 12 && $calinfo->end_hour <> 12)) { + $calinfo->end_hour += 12; + } + } + $date = mktime($calinfo->hour,$calinfo->minute,0,$calinfo->month,$calinfo->day,$calinfo->year) - ((60*60) * $phpgw_info["user"]["preferences"]["common"]["tz_offset"]); + $enddate = mktime($calinfo->end_hour,$calinfo->end_minute,0,$calinfo->end_month,$calinfo->end_day,$calinfo->end_year) - ((60*60) * $phpgw_info["user"]["preferences"]["common"]["tz_offset"]); + $today = time() - ((60*60) * $phpgw_info["user"]["preferences"]["common"]["tz_offset"]); + + if($calinfo->rpt_type != "none") + $rpt_type = "M"; + else + $rpt_type = "E"; + + $query = "UPDATE calendar_entry SET cal_owner=".$owner.", cal_name='".addslashes($calinfo->name)."', " + . "cal_description='".addslashes($calinfo->description)."', cal_datetime=".$date.", " + . "cal_mdatetime=".$today.", cal_edatetime=".$enddate.", " + . "cal_priority=".$calinfo->priority.", cal_type='".$rpt_type."' "; + + if(($calinfo->access == "public" || $calinfo->access == "group") && count($calinfo->groups)) { + $query .= ", cal_access='".$calinfo->access."', cal_group = '".$phpgw->accounts->array_to_string($calinfo->access,$calinfo->groups)."' "; + } elseif(($calinfo->access == "group") && !count($calinfo->groups)) { + $query .= ", cal_access='private', cal_group = '' "; + } else { + $query .= ", cal_access='".$calinfo->access."', cal_group = '' "; + } + + $query .= "WHERE cal_id=".$calid; + + $phpgw->db->query($query,__LINE__,__FILE__); + + $phpgw->db->query("DELETE FROM calendar_entry_user WHERE cal_id=".$calid,__LINE__,__FILE__); + + while ($participant = each($calinfo->participants)) { + $phpgw->db->query("INSERT INTO calendar_entry_user(cal_id,cal_login,cal_status) " + . "VALUES($calid,".$participant[1].",'A')",__LINE__,__FILE__); + } + + if(strcmp($calinfo->rpt_type,"none") <> 0) { + $freq = ($calinfo->rpt_freq?$calinfo->rpt_freq:0); + + if($calinfo->rpt_use_end) { + $end = mktime(12,0,0,$calinfo->rpt_month,$calinfo->rpt_day,$calinfo->rpt_year) - ((60*60) * $phpgw_info["user"]["preferences"]["common"]["tz_offset"]); + $use_end = 1; + } else { + $end = "NULL"; + $use_end = 0; + } + + if($calinfo->rpt_type == 'weekly' || $calinfo->rpt_type == 'daily') { + $days = ($calinfo->rpt_sun?'y':'n') + . ($calinfo->rpt_mon?'y':'n') + . ($calinfo->rpt_tue?'y':'n') + . ($calinfo->rpt_wed?'y':'n') + . ($calinfo->rpt_thu?'y':'n') + . ($calinfo->rpt_fri?'y':'n') + . ($calinfo->rpt_sat?'y':'n'); + } else { + $days = "nnnnnnn"; + } + $phpgw->db->query("SELECT count(cal_id) FROM calendar_entry_repeats WHERE cal_id=".$calid,__LINE__,__FILE__); + $phpgw->db->next_record(); + $num_rows = $phpgw->db->f(0); + if(!$num_rows) { + $phpgw->db->query("INSERT INTO calendar_entry_repeats(cal_id,cal_type,cal_use_end,cal_end,cal_days,cal_frequency) " + ."VALUES($calid,'".$calinfo->rpt_type."',$use_end,$end,'$days',$freq)",__LINE__,__FILE__); + } else { + $phpgw->db->query("UPDATE calendar_entry_repeats SET cal_type='".$calinfo->rpt_type."', cal_use_end=".$use_end.", " + ."cal_end='".$end."', cal_days='".$days."', cal_frequency=".$freq." " + ."WHERE cal_id=".$calid,__LINE__,__FILE__); + } + } else { + $phpgw->db->query("DELETE FROM calendar_entry_repeats WHERE cal_id=".$calid,__LINE__,__FILE__); + } + $phpgw->db->unlock(); + } + + function getevent($calid) { + global $phpgw; + + $cal_id = $this->prep($calid); + + if(!$cal_id) return false; + + $phpgw->db->lock(array("calendar_entry","calendar_entry_user","calendar_entry_repeats")); + + $calendar = new calendar_item; + + for($i=0;$idb->query("SELECT * FROM calendar_entry WHERE cal_id=".$cal_id[$i],__LINE__,__FILE__); + $phpgw->db->next_record(); + + $calendar->id = (int)$phpgw->db->f("cal_id"); + $calendar->owner = $phpgw->db->f("cal_owner"); + + $calendar->datetime = $phpgw->db->f("cal_datetime"); + $date = $this->date_to_epoch($phpgw->common->show_date($calendar->datetime,"Ymd")); + $calendar->day = $date["day"]; + $calendar->month = $date["month"]; + $calendar->year = $date["year"]; + + $time = $this->splittime($phpgw->common->show_date($calendar->datetime,"His")); + $calendar->hour = (int)$time["hour"]; + $calendar->minute = (int)$time["minute"]; + $calendar->ampm = $time["ampm"]; + +// echo "
TEST: hour: " . (int)$time["hour"]; +// echo "
TEST: minute: " . (int)$time["minute"]; +// echo "
TEST: ampm: " . $time["ampm"]; +// echo "
TEST: hour: " . $calendar->hour; +// echo "
TEST: minute: " . $calendar->minute; +// echo "
TEST: ampm: " . $calendar->ampm; + + $calendar->mdatetime = $phpgw->db->f("cal_mdatetime"); + $date = $this->date_to_epoch($phpgw->common->show_date($calendar->mdatetime,"Ymd")); + $calendar->mod_day = $date["day"]; + $calendar->mod_month = $date["month"]; + $calendar->mod_year = $date["year"]; + + $time = $this->splittime($phpgw->common->show_date($calendar->mdatetime,"His")); + $calendar->mod_hour = (int)$time["hour"]; + $calendar->mod_minute = (int)$time["minute"]; + $calendar->mod_second = (int)$time["second"]; + $calendar->mod_ampm = $time["ampm"]; + + $calendar->edatetime = $phpgw->db->f("cal_edatetime"); + $date = $this->date_to_epoch($phpgw->common->show_date($calendar->edatetime,"Ymd")); + $calendar->end_day = $date["day"]; + $calendar->end_month = $date["month"]; + $calendar->end_year = $date["year"]; + + $time = $this->splittime($phpgw->common->show_date($calendar->edatetime,"His")); + $calendar->end_hour = (int)$time["hour"]; + $calendar->end_minute = (int)$time["minute"]; + $calendar->end_second = (int)$time["second"]; + $calendar->end_ampm = $time["ampm"]; + + $calendar->priority = $phpgw->db->f("cal_priority"); +// not loading webcal_entry.cal_type + $calendar->access = $phpgw->db->f("cal_access"); + $calendar->name = htmlspecialchars(stripslashes($phpgw->db->f("cal_name"))); + $calendar->description = htmlspecialchars(stripslashes($phpgw->db->f("cal_description"))); + if($phpgw->db->f("cal_group")) + $calendar->groups = $phpgw->accounts->string_to_array($phpgw->db->f("cal_group")); + + $phpgw->db->query("SELECT * FROM calendar_entry_repeats WHERE cal_id=".$cal_id[$i],__LINE__,__FILE__); + if($phpgw->db->num_rows()) { + $phpgw->db->next_record(); + + $rpt_type = strtolower($phpgw->db->f("cal_type")); + $calendar->rpt_type = !$rpt_type?"none":$rpt_type; + $calendar->rpt_use_end = $phpgw->db->f("cal_use_end"); + if($calendar->rpt_use_end) { + $calendar->rpt_end = $phpgw->db->f("cal_end"); + $rpt_end = $phpgw->common->show_date($phpgw->db->f("cal_end"),"Ymd"); + $date = $this->date_to_epoch($rpt_end); + $calendar->rpt_end_day = (int)$date["day"]; + $calendar->rpt_end_month = (int)$date["month"]; + $calendar->rpt_end_year = (int)$date["year"]; + } else { + $calendar->rpt_end = 0; + $calendar->rpt_end_day = 0; + $calendar->rpt_end_month = 0; + $calendar->rpt_end_year = 0; + } + $calendar->rpt_freq = (int)$phpgw->db->f("cal_frequency"); + $rpt_days = strtoupper($phpgw->db->f("cal_days")); + $calendar->rpt_days = $rpt_days; + $calendar->rpt_sun = (substr($rpt_days,0,1)=="Y"?1:0); + $calendar->rpt_mon = (substr($rpt_days,1,1)=="Y"?1:0); + $calendar->rpt_tue = (substr($rpt_days,2,1)=="Y"?1:0); + $calendar->rpt_wed = (substr($rpt_days,3,1)=="Y"?1:0); + $calendar->rpt_thu = (substr($rpt_days,4,1)=="Y"?1:0); + $calendar->rpt_fri = (substr($rpt_days,5,1)=="Y"?1:0); + $calendar->rpt_sat = (substr($rpt_days,6,1)=="Y"?1:0); + } + + $phpgw->db->query("SELECT * FROM calendar_entry_user WHERE cal_id=".$cal_id[$i],__LINE__,__FILE__); + if($phpgw->db->num_rows()) { + while($phpgw->db->next_record()) { + $calendar->participants[] = $phpgw->db->f("cal_login"); + $calendar->status[] = $phpgw->db->f("cal_status"); + } + } + $calendar_item[$i] = $calendar; + } + $phpgw->db->unlock(); + return $calendar_item; + } + + function findevent() { + global $phpgw_info; + + if(!$phpgw_info["user"]["apps"]["calendar"]) return false; + } + } diff --git a/phpgwapi/phpgw_categories.inc.php b/phpgwapi/phpgw_categories.inc.php new file mode 100644 index 0000000000..42bf5ddd81 --- /dev/null +++ b/phpgwapi/phpgw_categories.inc.php @@ -0,0 +1,95 @@ +db; + + if (! isset($owner)) { + $owner = $phpgw_info["user"]["account_id"]; + } + + if (! isset($format)) { + $format = "array"; + } + + if ($format == "single") { + $db2->query("select * from categories where cat_id='$cat_id' and account_id='$owner' " + . "and app_name='" . addslashes($app_name) . "'"); + $db2->next_record(); + + $cat_info[]["id"] = $db2->f("cat_id"); + $cat_info[]["name"] = $db2->f("cat_name"); + $cat_info[]["descrption"] = $db2->f("cat_descrption"); + return $cat_info; + } + + if (! $app_name) { + $app_name = $phpgw_info["flags"]["currentapp"]; + } + if (! $account_id) { + $owner = $phpgw_info["user"]["account_id"]; + } + + $db2->query("select cat_id,cat_name,cat_description from categories where app_name='$app_name' " + . "and account_id='$owner'"); + $i = 0; + while ($db2->next_record()) { + if ($format == "array") { + $cat_list[$i]["cat_id"] = $db2->f("cat_id"); + $cat_list[$i]["cat_name"] = $db2->f("cat_name"); + $cat_list[$i]["cat_description"] = $db2->f("cat_description"); + $i++; + } + if ($format == "select") { + $cat_list .= ''; + } + } + return $cat_list; + } + + function add($owner,$app_name,$cat_name,$cat_description = "") + { + global $phpgw; + $db2 = $phpgw->db; + + $db2->query("insert into categories (account_id,app_name,cat_name,cat_description) values ('" + . "$owner','" . addslashes($app_name) . "','" . addslashes($cat_name) . "','" + . addslashes($cat_description) . "')"); + } + + function delete($owner,$app_name,$cat_name) + { + global $phpgw; + $db2 = $phpgw->db; + + $db2->query("delete from categories where account_id='$account_id' and app_name='" + . addslashes($app_name) . "' and cat_name='" . addslashes($cat_name) . "'"); + } + + function edit($owner,$app_name,$cat_name,$cat_description) + { + global $phpgw; + $db2 = $phpgw->db; + + $db2->query("update categories set cat_name='" . addslashes($cat_name) . "', cat_description='" + . addslashes($cat_description) . "' where account_id='$owner' and app_name='" + . addslashes($app_name) . "'"); + } + + } +?> \ No newline at end of file diff --git a/phpgwapi/phpgw_common.inc.php b/phpgwapi/phpgw_common.inc.php new file mode 100644 index 0000000000..c5b13607db --- /dev/null +++ b/phpgwapi/phpgw_common.inc.php @@ -0,0 +1,983 @@ +\n"; + exit; + } unset($d1);unset($d2); + + // Since LDAP will return system accounts, there are a few we don't want to login. + $phpgw_info["server"]["global_denied_users"] = array('root' => True, + 'bin' => True, + 'daemon' => True, + 'adm' => True, + 'lp' => True, + 'sync' => True, + 'shutdown' => True, + 'halt' => True, + 'mail' => True, + 'news' => True, + 'uucp' => True, + 'operator' => True, + 'games' => True, + 'gopher' => True, + 'nobody' => True, + 'xfs' => True, + 'pgsql' => True, + 'mysql' => True, + 'postgres' => True, + 'ftp' => True, + 'gdm' => True, + 'named' => True); + + // I had to create this has a wrapper, becuase the phpgw.inc.php files needs it before the classes + // are finished loading (jengo) + function filesystem_separator() + { + if (PHP_OS == "Windows" || PHP_OS == "OS/2") { + return "\\"; + } else { + return "/"; + } + } + + class common + { + var $phpgw; + var $iv = ""; + var $key = ""; + var $crypto; + + // connect to the ldap server and return a handle + function ldapConnect($host = "", $dn = "", $passwd = "") + { + global $phpgw_info; + + if (! $host) { + $host = $phpgw_info["server"]["ldap_host"]; + } + + if (! $dn) { + $dn = $phpgw_info["server"]["ldap_root_dn"]; + } + + if (! $passwd) { + $passwd = $phpgw_info["server"]["ldap_root_passwd"]; + } + + + // connect to ldap server + if (! $ds = ldap_connect($host)) { + printf("Error: Can't connect to LDAP server %s!
",$host); + return False; + } + + // bind as admin, we not to able to do everything + if (! ldap_bind($ds,$dn,$passwd)) { + printf("Error: Can't bind to LDAP server: %s!
",$dn); + return False; + } + + return $ds; + } + + function randomstring($size) + { + $s = ""; + srand((double)microtime()*1000000); + $random_char = array("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f", + "g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v", + "w","x","y","z","A","B","C","D","E","F","G","H","I","J","K","L", + "M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"); + + for ($i=0; $i<$size; $i++) { + $s .= $random_char[rand(1,61)]; + } + return $s; + } + + // Look at the note towards the top of this file (jengo) + function filesystem_separator() + { + return filesystem_separator(); + } + + function error_list($error) + { + $html_error = ''; + + for ($i=1; $i'; + } + return $html_error . '
' . lang("error") . ': ' . $error[0] . '
'; + } + + function check_owner($record,$link,$label,$extravars = "") + { + global $phpgw, $phpgw_info; + + $s = ' ' . lang($label) . ' '; + if (ereg("^[0-9]+$",$record)) { + if ($record != $phpgw_info["user"]["account_id"]) { + $s = " "; + } + } else { + if ($record != $phpgw_info["user"]["userid"]) { + $s = " "; + } + } + + return $s; + } + + function display_fullname($lid, $firstname, $lastname) + { + if (! $firstname && ! $lastname) { + $s = $lid; + } + if (! $firstname && $lastname) { + $s = $lastname; + } + if ($firstname && ! $lastname) { + $s = $firstname; + } + if ($firstname && $lastname) { + $s = "$lastname, $firstname"; + } + return $s; + } + + function grab_owner_name($id) + { + global $phpgw; + $phpgw->db->query("select account_lid,account_firstname,account_lastname from accounts where account_id=".$id,__LINE__,__FILE__); + $phpgw->db->next_record(); + + return $phpgw->common->display_fullname($phpgw->db->f("account_lid"),$phpgw->db->f("account_firstname"),$phpgw->db->f("account_lastname")); + } + + function create_tabs($tabs, $selected, $fontsize = "") + { + global $phpgw_info; + $output_text = ''; + $ir = $phpgw_info["server"]["webserver_url"] . "/images"; + + if ($fontsize) { + $fs = ''; + $fse = ''; + } + + $i = 1; + while ($tab = each($tabs)) { + if ($tab[0] == $selected) { + if ($i == 1) { + $output_text .= ''; + } + + $output_text .= ''; + if ($i == count($tabs)) { + $output_text .= ''; + } else { + $output_text .= ''; + } + } else { + if ($i == 1) { + $output_text .= ''; + } + $output_text .= ''; + if (($i + 1) == $selected) { + $output_text .= ''; + } else if ($i == $selected || $i != count($tabs)) { + $output_text .= ''; + } else if ($i == count($tabs)) { + if ($i == $selected) { + $output_text .= ''; + } else { + $output_text .= ''; + } + } else { + if ($i != count($tabs)) { + $output_text .= ''; + } + } + } + $i++; + $output_text .= "\n"; + } + $output_text .= "
 ' . $fs . $tab[1]["label"] + . $fse . '  ' . $fs . $tab[1]["label"] . $fse + . ' 
\n"; + return $output_text; + } + + function show_icon(&$tpl, $td_width, $appname, $description = "") + { + global $phpgw_info, $colspan, $phpgw; + + if ($appname && (($appname=="home" || $appname=="logout" || $appname == "print" || $appname == "preferences") + || ($phpgw_info["user"]["apps"][$appname]))) { + + if (isset($phpgw_info["flags"]["navbar_target"]) && $phpgw_info["flags"]["navbar_target"]) { + $target = ' target="' . $phpgw_info["flags"]["navbar_target"] . '"'; + if ($appname == "logout") { + $target = ' target="_top"'; + } + } else { + $target = ""; + } + + if (isset($colspan) && $colspan) { + $colspan++; + } else { + $colspan = 1; + } + + if (!isset($description) || !$description) { + $description = $phpgw_info["apps"][$appname]["title"]; + } + + $urlbasename = $phpgw_info["server"]["webserver_url"]; + + if ($appname == "home") { + $output_text = "link($urlbasename."/index.php"); + } elseif ($appname == "logout") { + $output_text = "link($urlbasename."/logout.php"); + } elseif ($appname == "print") { + $output_text = "link($urlbasename."/$appname/".$view); +// end change + } else { + $output_text = "link($urlbasename."/$appname/index.php"); + } + $output_text .= "\"$target>"; + + if ($phpgw_info["user"]["preferences"]["common"]["navbar_format"] != "text") { + if ($appname != "home" && $appname != "logout" && $appname != "print") { + $output_text .= "\"""; + } else { + $output_text .= "\"""; + } + } + + if (ereg("text",$phpgw_info["user"]["preferences"]["common"]["navbar_format"])) { + $output_text .= "
" . lang($description) . ""; + } + $output_text .= "
"; + $tpl->set_var("td_align","center"); + $tpl->set_var("td_width",$td_width); + $tpl->set_var("colspan",1); + $tpl->set_var("value",$output_text); + $tpl->parse("navbar_columns","navbar_column",True); + } + } + + function navbar() + { + global $cd,$phpgw,$phpgw_info,$colspan,$PHP_SELF; + $tpl = new Template($phpgw_info["server"]["template_dir"]); + $tpl->set_file(array("navbar" => "navbar.tpl", + "navbar_row" => "navbar_row.tpl", + "navbar_column" => "navbar_column.tpl" + )); + + $urlbasename = $phpgw_info["server"]["webserver_url"]; + + if (ereg("text",$phpgw_info["user"]["preferences"]["common"]["navbar_format"])) { + $td_width = "7%"; + } else { + $td_width = "3%"; + } + + // This is hardcoded for right now + if ($phpgw_info["user"]["preferences"]["common"]["navbar_format"] == "text") { + $tpl->set_var("tr_color","FFFFFF"); + } else { + $tpl->set_var("tr_color",$phpgw_info["theme"]["navbar_bg"]); + } + + $tpl->set_var("td_align","left"); + $tpl->set_var("td_width",""); + $tpl->set_var("value"," " . $phpgw_info["user"]["fullname"] . " - " + . lang($phpgw->common->show_date(time(),"l")) . " " + . lang($phpgw->common->show_date(time(),"F")) . " " + . $phpgw->common->show_date(time(),"d, Y")); + $tpl->parse("navbar_columns","navbar_column",True); + + if ($phpgw_info["user"]["preferences"]["common"]["navbar_format"] == "text") { + $tabs[1]["label"] = "home"; + $tabs[1]["link"] = $phpgw->link($phpgw_info["server"]["webserver_url"] . "/index.php"); + + if ($PHP_SELF == $phpgw_info["server"]["webserver_url"] . "/index.php") { + $selected = 1; + } + + $i = 2; + + while ($permission = each($phpgw_info["user"]["apps"])) { + if ($phpgw_info["apps"][$permission[0]]["status"] != 2) { + $tabs[$i]["label"] = $permission[0]; + $tabs[$i]["link"] = $phpgw->link($phpgw_info["server"]["webserver_url"] . "/" . $permission[0] . "/index.php"); + if (ereg($permission[0],$PHP_SELF)) { + $selected = $i; + } + $i++; + } + } + + $tabs[$i]["label"] = "preferences"; + $tabs[$i]["link"] = $phpgw->link($phpgw_info["server"]["webserver_url"] . "/preferences/index.php"); + if ($PHP_SELF == $phpgw_info["server"]["webserver_url"] . "/preferences/index.php") { + $selected = $i; + } + $i++; + + $tabs[$i]["label"] = "logout"; + $tabs[$i]["link"] = $phpgw->link($phpgw_info["server"]["webserver_url"] . "/logout.php"); + + $tpl->set_var("td_align","center"); + $tpl->set_var("td_width",$td_width); + $tpl->set_var("colspan",1); + $tpl->set_var("value",$this->create_tabs($tabs,$selected,-1)); + $tpl->parse("navbar_columns","navbar_column",True); + + } else { + + $this->show_icon(&$tpl,$td_width,"home","home"); + $this->show_icon(&$tpl,$td_width,"print","print"); + + while ($permission = each($phpgw_info["user"]["apps"])) { + if ($phpgw_info["apps"][$permission[0]]["status"] != 2) { + $this->show_icon(&$tpl,$td_width,$permission[0]); + } + } + + $this->show_icon(&$tpl,$td_width,"preferences","Preferences"); + $this->show_icon(&$tpl,$td_width,"logout","Logout"); + + } // end else + + $tpl->parse("navbar_rows","navbar_row",True); + + if (isset($phpgw_info["user"]["apps"]["admin"]) && isset($phpgw_info["user"]["preferences"]["common"]["show_currentusers"])) { + if ($phpgw_info["server"]["showpoweredbyon"] != "top") { + $phpgw->db->query("select count(*) from phpgw_sessions"); + $phpgw->db->next_record(); + $tpl->set_var("td_align","right"); + $tpl->set_var("td_width",""); + $tpl->set_var("tr_color",$phpgw_info["theme"]["bg_color"]); + $tpl->set_var("value",' ' . lang("Current users") . ': ' . $phpgw->db->f(0) . ''); + $tpl->set_var("colspan",($colspan+1)); + $tpl->parse("navbar_columns","navbar_column"); + $tpl->parse("navbar_rows","navbar_row",True); + } + } + + if ($phpgw_info["server"]["showpoweredbyon"] == "top") { + if ( ! $phpgw_info["user"]["preferences"]["common"]["show_currentusers"]) { + $tpl->set_var("td_align","left"); + $tpl->set_var("td_width",""); + $tpl->set_var("tr_color",$phpgw_info["theme"]["bg_color"]); + $tpl->set_var("value",lang("Powered by phpGroupWare version x",$phpgw_info["server"]["version"])); + $tpl->set_var("colspan",$colspan); + $tpl->parse("navbar_columns","navbar_column"); + $tpl->parse("navbar_rows","navbar_row",True); + } + } + + if ($phpgw_info["server"]["showpoweredbyon"] == "top" + && isset($phpgw_info["user"]["apps"]["admin"]) + && isset($phpgw_info["user"]["preferences"]["common"]["show_currentusers"])) { + + $tpl->set_var("td_align","left"); + $tpl->set_var("td_width",""); + $tpl->set_var("tr_color",$phpgw_info["theme"]["bg_color"]); + $tpl->set_var("value",lang("Powered by phpGroupWare version x",$phpgw_info["server"]["version"])); + $tpl->set_var("colspan",1); + $tpl->parse("navbar_columns","navbar_column"); + + $phpgw->db->query("select count(*) from phpgw_sessions"); + $phpgw->db->next_record(); + $tpl->set_var("td_align","right"); + $tpl->set_var("td_width",""); + $tpl->set_var("value",' ' . lang("Current users") . ': ' . $phpgw->db->f(0) . ''); + $tpl->set_var("colspan",($colspan--)); + $tpl->parse("navbar_columns","navbar_column",True); + $tpl->parse("navbar_rows","navbar_row",True); + } + + $tpl->pparse("out","navbar"); + + // Make the wording a little more user friendly + if ($phpgw_info["user"]["lastpasswd_change"] == 0) { + echo "
" . lang("You are required to change your password " + . "during your first login"); + echo "
Click this image on the navbar: "; + echo "
"; + } else if ($phpgw_info["user"]["lastpasswd_change"] < time() - (86400*30)) { + echo "
" . lang("it has been more then x days since you " + . "changed your password",30) . "
"; + } + if (isset($cd) && $cd) { + echo "
" . check_code($cd) . "
"; + } + + unset($colspan); + + /**************************************************************************\ + * Load the app include files if the exists * + \**************************************************************************/ + /* Then the include file */ + if (file_exists ($phpgw_info["server"]["app_inc"]."/header.inc.php")) { + include($phpgw_info["server"]["app_inc"]."/header.inc.php"); + } + } + + function phpgw_header() { + global $phpgw, $phpgw_info, $HTMLCOMPLAINT; + + echo " "; + echo ""; + echo ""; + echo "".$phpgw_info["server"]["site_title"].""; + echo "translation->translate("charset")."\">"; + echo ""; + echo ""; + if ($phpgw_info["server"]["htmlcompliant"]) { + echo ("\n"); + } else { + echo ("\n"); + } + if ((! isset($phpgw_info["flags"]["nonavbar"]) || ! $phpgw_info["flags"]["nonavbar"]) && ! $phpgw_info["flags"]["navbar_target"]) { + $this->navbar(); + } + } + + function phpgw_footer() + { + global $phpgw, $phpgw_info, $HTMLCOMPLAINT; + include($phpgw_info["server"]["api_dir"] . "/footer.inc.php"); + + // Clean up mcrypt + if (is_object($this->crypto)) { + $this->crypto->cleanup(); + unset($this->crypto); + } + } + + function hex2bin($data) + { + $len = strlen($data); + return pack("H" . $len, $data); + } + + function encrypt($data) { + global $phpgw_info, $phpgw; + + $data = serialize($data); + return $phpgw->crypto->encrypt($data); + } + + function decrypt($data) { + global $phpgw_info, $phpgw; + + $data = $phpgw->crypto->decrypt($data); + return unserialize($data); + } + + function des_cryptpasswd($userpass, $random) + { + $lcrypt = "{crypt}"; + $password = crypt($userpass); + $ldappassword = sprintf("%s%s", $lcrypt, $password); + + return $ldappassword; + } + + function md5_cryptpasswd($userpass, $random) + { + $bsalt = "$1$"; + $esalt = "$"; // patch + $lcrypt = "{crypt}"; +// $modsalt = sprintf("%s%s", $bsalt, $random); + $modsalt = sprintf("%s%s%s", $bsalt, $random, $esalt); // patch + $password = crypt($userpass, $modsalt); + $ldappassword = sprintf("%s%s", $lcrypt, $password); + + return $ldappassword; + } + + function encrypt_password($password) + { + global $phpgw, $phpgw_info; + + if ($phpgw_info["server"]["ldap_encryption_type"] == "DES") { + $salt = $this->randomstring(2); + $e_password = $this->des_cryptpasswd($password, $salt); + } + if ($phpgw_info["server"]["ldap_encryption_type"] == "MD5") { +// $salt = $this->randomstring(9); + $salt = $this->randomstring(8); // patch + $e_password = $this->md5_cryptpasswd($password, $salt); + } + return $e_password; + } + + + function hook($location = ""){ + global $phpgw, $phpgw_info; + + /* First include the apps own hook file */ + $appname = $phpgw_info["flags"]["currentapp"]; + $f = $phpgw_info["server"]["server_root"] . "/" . $appname . "/inc/hook_".$phpgw_info["flags"]["currentapp"]; + if ($location != ""){$f .= "_".$location.".inc.php";}else{$f .= ".inc.php";} + if (file_exists($f)) {include($f);} + + /* Then add the rest */ + reset ($phpgw_info["user"]["app_perms"]); + while (list (, $appname) = each ($phpgw_info["user"]["app_perms"])){ + if ($appname != "" || $appname != $phpgw_info["flags"]["currentapp"]){ + $f = $phpgw_info["server"]["server_root"] . "/" . $appname . "/inc/hook_".$phpgw_info["flags"]["currentapp"]; + if ($location != ""){$f .= "_".$location.".inc.php";}else{$f .= ".inc.php"; } + if (file_exists($f)) {include($f);} + } + } + } + + function appsession($data = "##NOTHING##") { + global $phpgw_info, $phpgw; + + if ($data == "##NOTHING##") { /* This allows the user to put "" as the value. */ + $phpgw->db->query("select content from phpgw_app_sessions where sessionid = '" + .$phpgw_info["user"]["sessionid"]."' and loginid = '" + .$phpgw_info["user"]["userid"]."' and app = '" + .$phpgw_info["flags"]["currentapp"] . "'",__LINE__,__FILE__); + if($phpgw->db->num_rows()) { + $phpgw->db->next_record(); + $data = $phpgw->db->f("content"); + $data = $this->decrypt($data); + return $data; + } + } else { + $data = $this->encrypt($data); + $phpgw->db->query("select * from phpgw_app_sessions where sessionid = '" + . $phpgw_info["user"]["sessionid"] . "' and app = '" + . $phpgw_info["flags"]["currentapp"] . "'",__LINE__,__FILE__); + if ($phpgw->db->num_rows()==0) { + $phpgw->db->query("INSERT INTO phpgw_app_sessions (sessionid,loginid,app,content)" + ." VALUES ('".$phpgw_info["user"]["sessionid"]."','" + .$phpgw_info["user"]["userid"] + ."','".$phpgw_info["flags"]["currentapp"]."','".$data."');",__LINE__,__FILE__); + } else { + $phpgw->db->query("update phpgw_app_sessions set content = '$data' where sessionid = '" + .$phpgw_info["user"]["sessionid"]."' and loginid = '" + .$phpgw_info["user"]["userid"]."'",__LINE__,__FILE__); + } + $data = $this->decrypt($data); + return $data; + } + } + + // This function will add preferences for the specified app to the phpgw_info[] array + // i(knecke) had moved this function phpgw_accounts_* class preferences +/* + function read_preferences($app_name) + { + global $phpgw, $phpgw_info; + $sql = "select preference_name,preference_value, preference_appname from preferences where " + . "preference_owner='".$phpgw_info["user"]["account_id"]."' AND preference_appname='$app_name'"; + + $phpgw->db->query($sql,__LINE__,__FILE__); + while($phpgw->db->next_record()) { + $phpgw_info["user"]["preferences"][$phpgw->db->f("preference_appname")][$phpgw->db->f("preference_name")] = $phpgw->db->f("preference_value"); + } + } + + // Add a new preference. + // i(knecke) had moved this function phpgw_accounts_* class preferences + function preferences_add($account_id,$var,$app_name,$value = "") + { + if ($value) { + global $phpgw; + $phpgw->db->query("insert into preferences (preference_owner,preference_name," + . "preference_value,preference_appname) values ('$account_id','$var','$value','" + . "$app_name')",__LINE__,__FILE__); + } else { + global $$var, $phpgw; + $phpgw->db->query("insert into preferences (preference_owner,preference_name," + . "preference_value,preference_appname) values ('$account_id','$var','". $$var + . "','$app_name')",__LINE__,__FILE__); + } + + } + + // i(knecke) had moved this function phpgw_accounts_* class preferences + function preferences_delete($method,$account_id,$var = "", $var2 = "") + { + global $phpgw; + + switch ($method) + { + case "all": $phpgw->db->query("delete from preferences where preference_owner='" + . "$account_id'",__LINE__,__FILE__); break; + // I may take this one out in the future. If you need it, let me know. (jengo) + case "notheme": $phpgw->db->query("delete from preferences where preference_owner='" + . "$account_id' and preference_name != 'theme'",__LINE__,__FILE__); break; + case "onlyvar": $phpgw->db->query("delete from preferences where preference_owner='" + . "$account_id' and preference_name='$var'",__LINE__,__FILE__); break; + case "byapp": $phpgw->db->query("delete from preferences where preference_owner='" + . "$account_id' and preference_appname='$var'",__LINE__,__FILE__); break; + case "byappnotheme": $phpgw->db->query("delete from preferences where preference_owner='" + . "$account_id' and preference_appname='$var' and preference_name !='theme'",__LINE__,__FILE__); break; + case "byappvar": $phpgw->db->query("delete from preferences where preference_owner='" + . "$account_id' and preference_appname='".substr($var,0,strpos($var,"|"))."' " + . "and preference_name='".substr($var,strpos($var,"|")+1)."'",__LINE__,__FILE__); break; + case "byappvar_single": $phpgw->db->query("delete from preferences where preference_owner='" + . "$account_id' and preference_appname='$var' " + . "and preference_name='$var2'",__LINE__,__FILE__); break; + + default: return; + } + } + + // i(knecke) had moved this function phpgw_accounts_* class preferences + function preferences_update($account_id,$var,$app_name) + { + $this->preferences_delete("onlyvar",$account_id,$var); + $this->preferences_add($account_id,$var,$app_name); + } +*/ + + function show_date($t = "", $format = "") + { + global $phpgw_info; + + if (! $t) + $t = time(); + + $t = $t + ((60*60) * $phpgw_info["user"]["preferences"]["common"]["tz_offset"]); + + if (! $format) { + $format = $phpgw_info["user"]["preferences"]["common"]["dateformat"] . " - "; + if ($phpgw_info["user"]["preferences"]["common"]["timeformat"] == "12") { + $format .= "h:i:s a"; + } else { + $format .= "H:i:s"; + } + } + return date($format,$t); + } + + function dateformatorder($yearstr,$monthstr,$daystr,$add_seperator = False) + { + global $phpgw_info; + $dateformat = strtolower($phpgw_info["user"]["preferences"]["common"]["dateformat"]); + $sep = substr($phpgw_info["user"]["preferences"]["common"]["dateformat"],1,1); + + $dlarr[strpos($dateformat,'y')] = $yearstr; + $dlarr[strpos($dateformat,'m')] = $monthstr; + $dlarr[strpos($dateformat,'d')] = $daystr; + ksort($dlarr); + + if ($add_seperator) { + return (implode($sep,$dlarr)); + } else { + return (implode(" ",$dlarr)); + } + } + + function formattime($hour,$min,$sec="") + { + global $phpgw_info; + + $h12 = $hour; + if ($phpgw_info["user"]["preferences"]["common"]["timeformat"] == "12") { + if ($hour > 12) + $ampm = " pm"; + else + $ampm = " am"; + $h12 %= 12; + if ($h12 == 0 && $hour) + $h12 = 12; + if ($h12 == 0 && ! $hour) + $h12 = 0; + } else + $h12 = $hour; + + if ($sec) + $sec = ":$sec"; + + return "$h12:$min$sec$ampm"; + } + + // This will be moved into the applications area. + function check_code($code) + { + $s = "
"; + switch ($code) + { + case 13: $s .= lang("Your message has been sent");break; + case 14: $s .= lang("New entry added sucessfully");break; + case 15: $s .= lang("Entry updated sucessfully"); break; + case 16: $s .= lang("Entry has been deleted sucessfully"); break; + case 18: $s .= lang("Password has been updated"); break; + case 19: $s .= lang("Session has been killed"); break; + case 27: $s .= lang("Account has been updated"); break; + case 28: $s .= lang("Account has been created"); break; + case 29: $s .= lang("Account has been deleted"); break; + case 30: $s .= lang("Your settings have been updated"); break; + case 31: $s .= lang("Group has been added"); break; + case 32: $s .= lang("Group has been deleted"); break; + case 33: $s .= lang("Group has been updated"); break; + case 34: $s .= lang("Account has been deleted") . "

" + . lang("Error deleting x x directory",lang("users")," ".lang("private")." ") + . ",
" . lang("Please x by hand",lang("delete")) . "

" + . lang("To correct this error for the future you will need to properly set the") + . "
" . lang("permissions to the files/users directory") + . "
" . lang("On *nix systems please type: x","chmod 707 " + . $phpgw_info["server"]["files_dir"] . "/users/"); + break; + case 35: $s .= lang("Account has been updated") . "

" + . lang("Error renaming x x directory",lang("users"), + " ".lang("private")." ") + . ",
" . lang("Please x by hand", + lang("rename")) . "

" + . lang("To correct this error for the future you will need to properly set the") + . "
" . lang("permissions to the files/users directory") + . "
" . lang("On *nix systems please type: x","chmod 707 " + . $phpgw_info["server"]["files_dir"] . "/users/"); + break; + case 36: $s .= lang("Account has been created") . "

" + . lang("Error creating x x directory",lang("users"), + " ".lang("private")." ") + . ",
" . lang("Please x by hand", + lang("create")) . "

" + . lang("To correct this error for the future you will need to properly set the") + . "
" . lang("permissions to the files/users directory") + . "
" . lang("On *nix systems please type: x","chmod 707 " + . $phpgw_info["server"]["files_dir"] . "/users/"); + break; + case 37: $s .= lang("Group has been added") . "

" + . lang("Error creating x x directory",lang("groups")," ") + . ",
" . lang("Please x by hand", + lang("create")) . "

" + . lang("To correct this error for the future you will need to properly set the") + . "
" . lang("permissions to the files/users directory") + . "
" . lang("On *nix systems please type: x","chmod 707 " + . $phpgw_info["server"]["files_dir"] . "/groups/"); + break; + case 38: $s .= lang("Group has been deleted") . "

" + . lang("Error deleting x x directory",lang("groups")," ") + . ",
" . lang("Please x by hand", + lang("delete")) . "

" + . lang("To correct this error for the future you will need to properly set the") + . "
" . lang("permissions to the files/users directory") + . "
" . lang("On *nix systems please type: x","chmod 707 " + . $phpgw_info["server"]["files_dir"] . "/groups/"); + break; + case 39: $s .= lang("Group has been updated") . "

" + . lang("Error renaming x x directory",lang("groups")," ") + . ",
" . lang("Please x by hand", + lang("rename")) . "

" + . lang("To correct this error for the future you will need to properly set the") + . "
" . lang("permissions to the files/users directory") + . "
" . lang("On *nix systems please type: x","chmod 707 " + . $phpgw_info["server"]["files_dir"] . "/groups/"); + break; + case 40: $s .= lang("You have not entered a\nBrief Description")."."; + break; + case 41: $s .= lang("You have not entered a\nvalid time of day."); + break; + case 42: $s .= lang("You have not entered a\nvalid date."); + break; + default: return ""; + } + return $s; + } + + function phpgw_error($error,$line = "", $file = "") + { + echo "

phpGroupWare internal error:

$error"; + if ($line) { + echo "Line: $line"; + } + if ($file) { + echo "File: $file"; + } + echo "

Your session has been halted."; + exit; + } + + + function create_phpcode_from_array($array) + { + while (list($key, $val) = each($array)) { + if (is_array($val)) { + while (list($key2, $val2) = each($val)) { + if (is_array($val2)) { + while (list($key3, $val3) = each ($val2)) { + if (is_array($val3)) { + while (list($key4, $val4) = each ($val3)) { + $s .= '$phpgw_info["' . $key . '"]["' . $key2 . '"]["' . $key3 . '"]["' .$key4 . '"]="' . $val4 . '";'; + $s .= "\n"; + } + } else { + $s .= '$phpgw_info["' . $key . '"]["' . $key2 . '"]["' . $key3 . '"]="' . $val3 . '";'; + $s .= "\n"; + } + } + } else { + $s .= '$phpgw_info["' . $key .'"]["' . $key2 . '"]="' . $val2 . '";'; + $s .= "\n"; + } + } + } else { + $s .= '$phpgw_info["' . $key . '"]="' . $val . '";'; + $s .= "\n"; + } + } + return $s; + } + + + // This will return the full phpgw_info array, used for debugging + function debug_phpgw_info() + { + global $phpgw_info; + + while (list($key, $val) = each($phpgw_info)) { + if (is_array($val)) { + while (list($key2, $val2) = each($val)) { + if (is_array($val2)) { + while (list($key3, $val3) = each ($val2)) { + if (is_array($val3)) { + while (list($key4, $val4) = each ($val3)) { + echo "phpgw_info[$key][$key2][$key3][$key4]=$val4
"; + } + } else { + echo "phpgw_info[$key][$key2][$key3]=$val3
"; + } + } + } else { + echo "phpgw_info[$key][$key2]=$val2
"; + } + } + } else { + echo "phpgw_info[$key]=$val
"; + } + } + } + + // This will return a list of functions in the API + function debug_list_core_functions() + { + global $phpgw_info; + + echo "
core functions
"; + echo "

";
+       chdir($phpgw_info["server"]["include_root"]."/phpgwapi");
+       system("grep -r '^[ \t]*function' *");
+       echo "
"; + } + + function common_() + { + global $phpgw, $phpgw_info; + $phpgw_info["server"]["dir_separator"] = $this->filesystem_separator(); + } + + } + + + class hooks + { + function read() + { + global $phpgw; + $db = $phpgw->db; + + $db->query("select * from phpgw_hooks"); + while ($db->next_record()) { + $return_array[$db->f("hook_id")]["app"] = $db->f("hook_appname"); + $return_array[$db->f("hook_id")]["location"] = $db->f("hook_location"); + $return_array[$db->f("hook_id")]["filename"] = $db->f("hook_filename"); + } + return $return_array; + } + + function proccess($type,$where = "") + { + global $phpgw_info, $phpgw; + + $currentapp = $phpgw_info["flags"]["currentapp"]; + $type = strtolower($type); + + if ($type != "location" && $type != "app") { + return False; + } + + // Add a check to see if that location/app has a hook + // This way it doesn't have to loop everytime + + while ($hook = each($phpgw_info["hooks"])) { + if ($type == "app") { + if ($hook[1]["app"] == $currentapp) { + $include_file = $phpgw_info["server"]["server_root"] . "/" + . $currentapp . "/hooks/" + . $hook[1]["app"] . $hook[1]["filename"]; + include($include_file); + } + + } else if ($type == "location") { + if ($hook[1]["location"] == $where) { + $include_file = $phpgw_info["server"]["server_root"] . "/" + . $hook[1]["app"] . "/hooks/" + . $hook[1]["filename"]; + if (! is_file($include_file)) { + $phpgw->common->phpgw_error("Failed to include hook: $include_file"); + } else { + include($include_file); + } + } + } + } + } + + + } diff --git a/phpgwapi/phpgw_crypto.inc.php b/phpgwapi/phpgw_crypto.inc.php new file mode 100644 index 0000000000..687c4561f4 --- /dev/null +++ b/phpgwapi/phpgw_crypto.inc.php @@ -0,0 +1,123 @@ +td = false; + if (PHP_VERSION > "4.0.2pl1") { + $keysize = mcrypt_get_key_size(MCRYPT_TRIPLEDES); + $ivsize = mcrypt_get_iv_size(MCRYPT_TRIPLEDES,MCRYPT_MODE_CBC); + } else { + $keysize = 8; + $ivsize = 8; + } + } else { + // Start up mcrypt + $this->td = mcrypt_module_open (MCRYPT_TRIPLEDES, "", MCRYPT_MODE_CBC, ""); + + $ivsize = mcrypt_enc_get_iv_size($this->td); + $keysize = mcrypt_enc_get_key_size($this->td); + } + + // Hack IV to be the correct size + $x = strlen($iv); + for ($i = 0; $i < $ivsize; $i++) { + $this->iv .= $iv[$i % $x]; + } + + // Hack Key to be the correct size + $x = strlen($key); + + for ($i = 0; $i < $keysize; $i++) { + $this->key .= $key[$i % $x]; + } + if ($phpgw_info["server"]["mcrypt_version"] != "old") { + mcrypt_generic_init ($this->td, $this->key, $this->iv); + } + } + // If mcrypt isn't loaded key and iv are not needed + } + + function cleanup() + { + global $phpgw_info; + + if ($phpgw_info["server"]["mcrypt_enabled"] && extension_loaded("mcrypt")) { + if ($phpgw_info["server"]["mcrypt_version"] != "old") { + mcrypt_generic_end ($this->td); + } + } + } + function hex2bin($data) + { + $len = strlen($data); + return pack("H" . $len, $data); + } + + function encrypt($data) { + global $phpgw_info; + + $data = serialize($data); + + // Disable all encryption if the admin didn't set it up + if ($phpgw_info["server"]["mcrypt_enabled"] && extension_loaded("mcrypt")) { + switch ($phpgw_info["server"]["mcrypt_version"]) { + // The old code, only works with mcrypt <= 2.2.x + case "old": { + $encrypteddata = mcrypt_cbc(MCRYPT_TripleDES, $this->key, $data, MCRYPT_ENCRYPT); + break; + } + default: { // Handle 2.4 and newer API + $encrypteddata = mcrypt_generic($this->td, $data); + } + } + + $encrypteddata = bin2hex($encrypteddata); + return $encrypteddata; + } else { // No mcrypt == insecure ! + return $data; + } + } + + function decrypt($encrypteddata) { + global $phpgw_info; + + // Disable all encryption if the admin didn't set it up + if ($phpgw_info["server"]["mcrypt_enabled"] && extension_loaded("mcrypt")) { + $data = $this->hex2bin($encrypteddata); + + switch ($phpgw_info["server"]["mcrypt_version"]) { + // The old code, only works with mcrypt <= 2.2.x + case "old": { + $data = mcrypt_cbc(MCRYPT_TripleDES, $this->key, $data, MCRYPT_DECRYPT); + break; + } + default: { // Handle 2.4 and newer API + $data = mdecrypt_generic($this->td, $data); + } + } + return unserialize($data); + } else { + return unserialize($encrypteddata); + } + } + + } // class crypto diff --git a/phpgwapi/phpgw_db_msql.inc.php b/phpgwapi/phpgw_db_msql.inc.php new file mode 100644 index 0000000000..924bb789d2 --- /dev/null +++ b/phpgwapi/phpgw_db_msql.inc.php @@ -0,0 +1,143 @@ + + * + * $Id$ + * + */ + +class db { + var $Host = ""; + var $Database = ""; + + var $Link_ID = 0; + var $Query_ID = 0; + var $Record = array(); + var $Row; + + var $Error = ""; + + var $Auto_Free = 0; ## Set this to 1 for automatic msql_free_result() + + function connect() { + // Not connected? Then connect? + if ( 0 == $this->Link_ID ) { + // Check for local connect + $this->Link_ID = empty($this->Host)? + $this->Link_ID=msql_pconnect(): + $this->Link_ID=msql_pconnect($this->Host); + } + + // Still not connected? Raise error. + if ( 0 == $this->Link_ID ) { + $this->halt("Link-ID == false, pconnect failed"); + } + + // Select current database + if (!msql_select_db($this->Database, $this->Link_ID)) { + $this->halt("cannot use database ".$this->Database); + } + } + + function query($Query_String) { + $this->connect(); + +# printf("Debug: query = %s
\n", $Query_String); + + $this->Query_ID = msql_query($Query_String,$this->Link_ID); + $this->Row = 0; + $this->Error = msql_error(); + if (!$this->Query_ID) { + $this->halt("Invalid SQL: ".$Query_String); + } + + return $this->Query_ID; + } + + function next_record() { + $this->Record = msql_fetch_array($this->Query_ID); + $this->Row += 1; + $this->Error = msql_error(); + + $stat = is_array($this->Record); + if (!$stat && $this->Auto_Free) { + msql_free_result($this->Query_ID); + $this->Query_ID = 0; + } + return $stat; + } + + function seek($pos) { + $status = msql_data_seek($this->Query_ID, $pos); + if ($status) + $this->Row = $pos; + return; + } + + function metadata($table) { + $count = 0; + $id = 0; + $res = array(); + + $this->connect(); + $id = @msql_list_fields($this->Database, $table); + if ($id < 0) { + $this->Error = msql_error(); + $this->halt("Metadata query failed."); + } + $count = msql_num_fields($id); + + for ($i=0; $i<$count; $i++) { + $res[$i]["table"] = msql_fieldtable ($id, $i); + $res[$i]["name"] = msql_fieldname ($id, $i); + $res[$i]["type"] = msql_fieldtype ($id, $i); + $res[$i]["len"] = msql_fieldlen ($id, $i); + $res[$i]["flags"] = msql_fieldflags ($id, $i); + $res["meta"][$res[$i]["name"]] = $i; + $res["num_fields"]= $count; + } + + msql_free_result($id); + return $res; + } + + function affected_rows() { + return msql_affected_rows($this->Query_ID); + } + + function num_rows() { + return msql_num_rows($this->Query_ID); + } + + function num_fields() { + return msql_num_fields($this->Query_ID); + } + + function nf() { + return $this->num_rows(); + } + + function np() { + print $this->num_rows(); + } + + function f($Name) { + return $this->Record[$Name]; + } + + function p($Name) { + print $this->Record[$Name]; + } + + function halt($msg) { + printf("Database error: %s
\n", $msg); + printf("MSQL Error: %s
\n", $this->Error); + die("Session halted."); + } +} +?> diff --git a/phpgwapi/phpgw_db_mssql.inc.php b/phpgwapi/phpgw_db_mssql.inc.php new file mode 100644 index 0000000000..ff09e6d72a --- /dev/null +++ b/phpgwapi/phpgw_db_mssql.inc.php @@ -0,0 +1,146 @@ +This is using the MSSQL class
"; + +class db { + var $Host = ""; + var $Database = ""; + var $User = ""; + var $Password = ""; + + var $Link_ID = 0; + var $Query_ID = 0; + var $Record = array(); + var $Row = 0; + + var $Errno = 0; + var $Error = ""; + + var $Auto_Free = 0; ## set this to 1 to automatically free results + + + function connect() { + if ( 0 == $this->Link_ID ) { + $this->Link_ID=mssql_pconnect($this->Host, $this->User, $this->Password); + if (!$this->Link_ID) + $this->halt("Link-ID == false, mssql_pconnect failed"); + else + mssql_select_db($this->Database, $this->Link_ID); + } + } + function free_result(){ + mssql_free_result($this->Query_ID); + $this->Query_ID = 0; + } + + function query($Query_String) { + if (!$this->Link_ID) + $this->connect(); + +# printf("
Debug: query = %s
\n", $Query_String); + + $this->Query_ID = mssql_query($Query_String, $this->Link_ID); + $this->Row = 0; + if (!$this->Query_ID) { + $this->Errno = 1; + $this->Error = "General Error (The MSSQL interface cannot return detailed error messages)."; + $this->halt("Invalid SQL: ".$Query_String); + } + return $this->Query_ID; + } + + function next_record() { + + if ($this->Record = mssql_fetch_row($this->Query_ID)) { + // add to Record[] + $count = mssql_num_fields($this->Query_ID); + for ($i=0; $i<$count; $i++){ + $fieldinfo = mssql_fetch_field($this->Query_ID,$i); + $this->Record[strtolower($fieldinfo->name)] = $this->Record[$i]; + } + $this->Row += 1; + $stat = 1; + } else { + if ($this->Auto_Free) { + $this->free_result(); + } + $stat = 0; + } + return $stat; + } + + function seek($pos) { + mssql_data_seek($this->Query_ID,$pos); + $this->Row = $pos; + } + + function metadata($table) { + $count = 0; + $id = 0; + $res = array(); + + $this->connect(); + $id = mssql_query("select * from $table", $this->Link_ID); + if (!$id) { + $this->Errno = 1; + $this->Error = "General Error (The MSSQL interface cannot return detailed error messages)."; + $this->halt("Metadata query failed."); + } + $count = mssql_num_fields($id); + + for ($i=0; $i<$count; $i++) { + $info = mssql_fetch_field($id, $i); + $res[$i]["table"] = $table; + $res[$i]["name"] = $info["name"]; + $res[$i]["len"] = $info["max_length"]; + $res[$i]["flags"] = $info["numeric"]; + } + $this->free_result(); + return $res; + } + + function affected_rows() { + return mssql_affected_rows($this->Query_ID); + } + + function num_rows() { + return mssql_num_rows($this->Query_ID); + } + + function num_fields() { + return mssql_num_fields($this->Query_ID); + } + + function nf() { + return $this->num_rows(); + } + + function np() { + print $this->num_rows(); + } + + function f($Field_Name) { + return $this->Record[strtolower($Field_Name)]; + } + + function p($Field_Name) { + print $this->f($Field_Name); + } + + function halt($msg) { + printf("Database error: %s
\n", $msg); + printf("MSSQL Error: %s (%s)
\n", + $this->Errno, + $this->Error); + die("Session halted."); + } +} +?> diff --git a/phpgwapi/phpgw_db_mysql.inc.php b/phpgwapi/phpgw_db_mysql.inc.php new file mode 100644 index 0000000000..66e2138eb2 --- /dev/null +++ b/phpgwapi/phpgw_db_mysql.inc.php @@ -0,0 +1,394 @@ +query($query); + } + + /* public: some trivial reporting */ + function link_id() { + return $this->Link_ID; + } + + function query_id() { + return $this->Query_ID; + } + + /* public: connection management */ + function connect($Database = "", $Host = "", $User = "", $Password = "") { + /* Handle defaults */ + if ("" == $Database) + $Database = $this->Database; + if ("" == $Host) + $Host = $this->Host; + if ("" == $User) + $User = $this->User; + if ("" == $Password) + $Password = $this->Password; + + /* establish connection, select database */ + if ( 0 == $this->Link_ID ) { + + $this->Link_ID=mysql_pconnect($Host, $User, $Password); + if (!$this->Link_ID) { + $this->halt("pconnect($Host, $User, \$Password) failed."); + return 0; + } + + if (!@mysql_select_db($Database,$this->Link_ID)) { + $this->halt("cannot use database ".$this->Database); + return 0; + } + } + + return $this->Link_ID; + } + + // This only affects systems not using persistant connections + function disconnect() + { + return mysql_close($this->Link_ID); + } + + /* public: discard the query result */ + function free() { + @mysql_free_result($this->Query_ID); + $this->Query_ID = 0; + } + + /* public: perform a query */ + // I added the line and file section so we can have better error reporting. (jengo) + function query($Query_String, $line = "", $file = "") { + /* No empty queries, please, since PHP4 chokes on them. */ + if ($Query_String == "") + /* The empty query string is passed on from the constructor, + * when calling the class without a query, e.g. in situations + * like these: '$db = new db_Subclass;' + */ + return 0; + + if (!$this->connect()) { + return 0; /* we already complained in connect() about that. */ + }; + + # New query, discard previous result. + if ($this->Query_ID) { + $this->free(); + } + + if ($this->Debug) + printf("Debug: query = %s
\n", $Query_String); + + $this->Query_ID = @mysql_query($Query_String,$this->Link_ID); + $this->Row = 0; + $this->Errno = mysql_errno(); + $this->Error = mysql_error(); + if (! $this->Query_ID) { + $this->halt("Invalid SQL: ".$Query_String, $line, $file); + } + + # Will return nada if it fails. That's fine. + return $this->Query_ID; + } + + /* public: walk result set */ + function next_record() { + if (!$this->Query_ID) { + $this->halt("next_record called with no query pending."); + return 0; + } + + $this->Record = @mysql_fetch_array($this->Query_ID); + $this->Row += 1; + $this->Errno = mysql_errno(); + $this->Error = mysql_error(); + + $stat = is_array($this->Record); + if (!$stat && $this->Auto_Free) { + $this->free(); + } + return $stat; + } + + /* public: position in result set */ + function seek($pos = 0) { + $status = @mysql_data_seek($this->Query_ID, $pos); + if ($status) + $this->Row = $pos; + else { + $this->halt("seek($pos) failed: result has ".$this->num_rows()." rows"); + + /* half assed attempt to save the day, + * but do not consider this documented or even + * desireable behaviour. + */ + @mysql_data_seek($this->Query_ID, $this->num_rows()); + $this->Row = $this->num_rows; + return 0; + } + + return 1; + } + + /* public: table locking */ + function lock($table, $mode="write") { + $this->connect(); + + $query="lock tables "; + if (is_array($table)) { + while (list($key,$value)=each($table)) { + if ($key=="read" && $key!=0) { + $query.="$value read, "; + } else { + $query.="$value $mode, "; + } + } + $query=substr($query,0,-2); + } else { + $query.="$table $mode"; + } + $res = @mysql_query($query, $this->Link_ID); + if (!$res) { + $this->halt("lock($table, $mode) failed."); + return 0; + } + return $res; + } + + function unlock() { + $this->connect(); + + $res = @mysql_query("unlock tables"); + if (!$res) { + $this->halt("unlock() failed."); + return 0; + } + return $res; + } + + + /* public: evaluate the result (size, width) */ + function affected_rows() { + return @mysql_affected_rows($this->Link_ID); + } + + function num_rows() { + return @mysql_num_rows($this->Query_ID); + } + + function num_fields() { + return @mysql_num_fields($this->Query_ID); + } + + /* public: shorthand notation */ + function nf() { + return $this->num_rows(); + } + + function np() { + print $this->num_rows(); + } + + function f($Name) { + return $this->Record[$Name]; + } + + function p($Name) { + print $this->Record[$Name]; + } + + /* public: sequence numbers */ + function nextid($seq_name) { + $this->connect(); + + if ($this->lock($this->Seq_Table)) { + /* get sequence number (locked) and increment */ + $q = sprintf("select nextid from %s where seq_name = '%s'", + $this->Seq_Table, + $seq_name); + $id = @mysql_query($q, $this->Link_ID); + $res = @mysql_fetch_array($id); + + /* No current value, make one */ + if (!is_array($res)) { + $currentid = 0; + $q = sprintf("insert into %s values('%s', %s)", + $this->Seq_Table, + $seq_name, + $currentid); + $id = @mysql_query($q, $this->Link_ID); + } else { + $currentid = $res["nextid"]; + } + $nextid = $currentid + 1; + $q = sprintf("update %s set nextid = '%s' where seq_name = '%s'", + $this->Seq_Table, + $nextid, + $seq_name); + $id = @mysql_query($q, $this->Link_ID); + $this->unlock(); + } else { + $this->halt("cannot lock ".$this->Seq_Table." - has it been created?"); + return 0; + } + return $nextid; + } + + /* public: return table metadata */ + function metadata($table='',$full=false) { + $count = 0; + $id = 0; + $res = array(); + + /* + * Due to compatibility problems with Table we changed the behavior + * of metadata(); + * depending on $full, metadata returns the following values: + * + * - full is false (default): + * $result[]: + * [0]["table"] table name + * [0]["name"] field name + * [0]["type"] field type + * [0]["len"] field length + * [0]["flags"] field flags + * + * - full is true + * $result[]: + * ["num_fields"] number of metadata records + * [0]["table"] table name + * [0]["name"] field name + * [0]["type"] field type + * [0]["len"] field length + * [0]["flags"] field flags + * ["meta"][field name] index of field named "field name" + * The last one is used, if you have a field name, but no index. + * Test: if (isset($result['meta']['myfield'])) { ... + */ + + // if no $table specified, assume that we are working with a query + // result + if ($table) { + $this->connect(); + $id = @mysql_list_fields($this->Database, $table); + if (!$id) + $this->halt("Metadata query failed."); + } else { + $id = $this->Query_ID; + if (!$id) + $this->halt("No query specified."); + } + + $count = @mysql_num_fields($id); + + // made this IF due to performance (one if is faster than $count if's) + if (!$full) { + for ($i=0; $i<$count; $i++) { + $res[$i]["table"] = @mysql_field_table ($id, $i); + $res[$i]["name"] = @mysql_field_name ($id, $i); + $res[$i]["type"] = @mysql_field_type ($id, $i); + $res[$i]["len"] = @mysql_field_len ($id, $i); + $res[$i]["flags"] = @mysql_field_flags ($id, $i); + } + } else { // full + $res["num_fields"]= $count; + + for ($i=0; $i<$count; $i++) { + $res[$i]["table"] = @mysql_field_table ($id, $i); + $res[$i]["name"] = @mysql_field_name ($id, $i); + $res[$i]["type"] = @mysql_field_type ($id, $i); + $res[$i]["len"] = @mysql_field_len ($id, $i); + $res[$i]["flags"] = @mysql_field_flags ($id, $i); + $res["meta"][$res[$i]["name"]] = $i; + } + } + + // free the result only if we were called on a table + if ($table) @mysql_free_result($id); + return $res; + } + + /* private: error handling */ + function halt($msg, $line = "", $file = "") { + $this->unlock(); // Just in case there is a table currently locked + + $this->Error = @mysql_error($this->Link_ID); + $this->Errno = @mysql_errno($this->Link_ID); + if ($this->Halt_On_Error == "no") + return; + + $this->haltmsg($msg); + + if ($file) { + printf("
File: %s",$file); + } + if ($line) { + printf("
Line: %s",$line); + } + + if ($this->Halt_On_Error != "report") + die("

Session halted."); + } + + function haltmsg($msg) + { + printf("Database error: %s
\n", $msg); + if ($this->Errno != "0" && $this->Error != "()") { + printf("MySQL Error: %s (%s)
\n",$this->Errno,$this->Error); + } + } + + function table_names() { + $this->query("SHOW TABLES"); + $i=0; + while ($info=mysql_fetch_row($this->Query_ID)) + { + $return[$i]["table_name"]= $info[0]; + $return[$i]["tablespace_name"]=$this->Database; + $return[$i]["database"]=$this->Database; + $i++; + } + return $return; + } +} diff --git a/phpgwapi/phpgw_db_odbc.inc.php b/phpgwapi/phpgw_db_odbc.inc.php new file mode 100644 index 0000000000..dd3518ca60 --- /dev/null +++ b/phpgwapi/phpgw_db_odbc.inc.php @@ -0,0 +1,172 @@ +Link_ID ) { + $this->Link_ID=odbc_pconnect($this->Database, $this->User, $this->Password, $this->UseODBCCursor); + if (!$this->Link_ID) { + $this->halt("Link-ID == false, odbc_pconnect failed"); + } + } + } + + function query($Query_String) { + $this->connect(); + +# printf("
Debug: query = %s
\n", $Query_String); + +# rei@netone.com.br suggested that we use this instead of the odbc_exec(). +# He is on NT, connecting to a Unix MySQL server with ODBC. -- KK +# $this->Query_ID = odbc_prepare($this->Link_ID,$Query_String); +# $this->Query_Ok = odbc_execute($this->Query_ID); + + $this->Query_ID = odbc_exec($this->Link_ID,$Query_String); + $this->Row = 0; + odbc_binmode($this->Query_ID, 1); + odbc_longreadlen($this->Query_ID, 4096); + + if (!$this->Query_ID) { + $this->Errno = 1; + $this->Error = "General Error (The ODBC interface cannot return detailed error messages)."; + $this->halt("Invalid SQL: ".$Query_String); + } + return $this->Query_ID; + } + + function next_record() { + $this->Record = array(); + $stat = odbc_fetch_into($this->Query_ID, ++$this->Row, &$this->Record); + if (!$stat) { + if ($this->Auto_Free) { + odbc_free_result($this->Query_ID); + $this->Query_ID = 0; + }; + } else { + // add to Record[] + $count = odbc_num_fields($this->Query_ID); + for ($i=1; $i<=$count; $i++) + $this->Record[strtolower(odbc_field_name ($this->Query_ID, $i)) ] = $this->Record[ $i - 1 ]; + } + return $stat; + } + + function seek($pos) { + $this->Row = $pos; + } + + function metadata($table) { + $count = 0; + $id = 0; + $res = array(); + + $this->connect(); + $id = odbc_exec($this->Link_ID, "select * from $table"); + if (!$id) { + $this->Errno = 1; + $this->Error = "General Error (The ODBC interface cannot return detailed error messages)."; + $this->halt("Metadata query failed."); + } + $count = odbc_num_fields($id); + + for ($i=1; $i<=$count; $i++) { + $res[$i]["table"] = $table; + $name = odbc_field_name ($id, $i); + $res[$i]["name"] = $name; + $res[$i]["type"] = odbc_field_type ($id, $name); + $res[$i]["len"] = 0; // can we determine the width of this column? + $res[$i]["flags"] = ""; // any optional flags to report? + } + + odbc_free_result($id); + return $res; + } + + function affected_rows() { + return odbc_num_rows($this->Query_ID); + } + + function num_rows() { + # Many ODBC drivers don't support odbc_num_rows() on SELECT statements. + $num_rows = odbc_num_rows($this->Query_ID); + //printf ($num_rows."
"); + + # This is a workaround. It is intended to be ugly. + if ($num_rows < 0) { + $i=10; + while (odbc_fetch_row($this->Query_ID, $i)) + $i*=10; + + $j=0; + while ($i!=$j) { + $k= $j+intval(($i-$j)/2); + if (odbc_fetch_row($this->Query_ID, $k)) + $j=$k; + else + $i=$k; + if (($i-$j)==1) { + if (odbc_fetch_row($this->Query_ID, $i)) + $j=$i; + else + $i=$j; + }; + //printf("$i $j $k
"); + }; + $num_rows=$i; + } + + return $num_rows; + } + + function num_fields() { + return count($this->Record)/2; + } + + function nf() { + return $this->num_rows(); + } + + function np() { + print $this->num_rows(); + } + + function f($Field_Name) { + return $this->Record[strtolower($Field_Name)]; + } + + function p($Field_Name) { + print $this->f($Field_Name); + } + + function halt($msg) { + printf("Database error: %s
\n", $msg); + printf("ODBC Error: %s (%s)
\n", + $this->Errno, + $this->Error); + die("Session halted."); + } +} +?> diff --git a/phpgwapi/phpgw_db_oracle.inc.php b/phpgwapi/phpgw_db_oracle.inc.php new file mode 100644 index 0000000000..833259ed39 --- /dev/null +++ b/phpgwapi/phpgw_db_oracle.inc.php @@ -0,0 +1,432 @@ +query($query); + } + + /* public: some trivial reporting */ + function link_id() { + return $this->Link_ID; + } + + function query_id() { + return $this->Query_ID; + } + + function connect() { + ## see above why we do this + if ($this->OraPutEnv) { + PutEnv("ORACLE_SID=$this->Database"); + PutEnv("ORACLE_HOME=$this->Home"); + } + if ( 0 == $this->Link_ID ) { + if($this->Debug) { + printf("
Connect()ing to $this->Database...
\n"); + } + if($this->Remote) { + if($this->Debug) { + printf("
connect() $this->User/******@$this->Database.world
\n"); + } + $this->Link_ID=ora_plogon + ("$this->User/$this->Password@$this->Database",""); + /************** (comment by SSilk) + this dosn't work on my system: + $this->Link_ID=ora_plogon + ("$this->User@$this->Database.world","$this->Password"); + ***************/ + } else { + if($this->Debug) { + printf("
connect() $this->User, $this->Password
\n"); + } + $this->Link_ID=ora_plogon("$this->User","$this->Password"); + /* (comment by SSilk: don't know how this could work, but I leave this untouched!) */ + } + if($this->Debug) { + printf("
connect() Link_ID: $this->Link_ID
\n"); + } + if (!$this->Link_ID) { + $this->halt("connect() Link-ID == false " . + "($this->Link_ID), ora_plogon failed"); + } else { + //echo "commit on

"; + ora_commiton($this->Link_ID); + } + if($this->Debug) { + printf("
connect() Obtained the Link_ID: $this->Link_ID
\n"); + } + } + } + + ## In order to increase the # of cursors per system/user go edit the + ## init.ora file and increase the max_open_cursors parameter. Yours is on + ## the default value, 100 per user. + ## We tried to change the behaviour of query() in a way, that it tries + ## to safe cursors, but on the other side be carefull with this, that you + ## don't use an old result. + ## + ## You can also make extensive use of ->disconnect()! + ## The unused QueryIDs will be recycled sometimes. + + function query($Query_String) { + + /* No empty queries, please, since PHP4 chokes on them. */ + if ($Query_String == "") + /* The empty query string is passed on from the constructor, + * when calling the class without a query, e.g. in situations + * like these: '$db = new DB_Sql_Subclass;' + */ + return 0; + + $this->connect(); + $this->lastQuery=$Query_String; + + if (!$this->Query_ID) { + $this->Query_ID= ora_open($this->Link_ID); + } + if($this->Debug) { + printf("Debug: query = %s
\n", $Query_String); + printf("
Debug: Query_ID: %d
\n", $this->Query_ID); + } + + if(!@ora_parse($this->Query_ID,$Query_String)) { + $this->Errno=ora_errorcode($this->Query_ID); + $this->Error=ora_error($this->Query_ID); + $this->halt("
ora_parse() failed:
$Query_String
Snap & paste this to sqlplus!"); + } elseif (!@ora_exec($this->Query_ID)) { + $this->Errno=ora_errorcode($this->Query_ID); + $this->Error=ora_error($this->Query_ID); + $this->halt("
\n$Query_String\n
Snap & paste this to sqlplus!"); + } + + $this->Row=0; + + if(!$this->Query_ID) { + $this->halt("Invalid SQL: ".$Query_String); + } + + return $this->Query_ID; + } + + function next_record() { + if (!$this->no_next_fetch && + 0 == ora_fetch($this->Query_ID)) { + if ($this->Debug) { + printf("
next_record(): ID: %d,Rows: %d
\n", + $this->Query_ID,$this->num_rows()); + } + $this->Row +=1; + + $errno=ora_errorcode($this->Query_ID); + if(1403 == $errno) { # 1043 means no more records found + $this->Errno=0; + $this->Error=""; + $this->disconnect(); + $stat=0; + } else { + $this->Error=ora_error($this->Query_ID); + $this->Errno=$errno; + if($this->Debug) { + printf("
%d Error: %s", + $this->Errno, + $this->Error); + } + $stat=0; + } + } else { + $this->no_next_fetch=false; + for($ix=0;$ixQuery_ID);$ix++) { + $col=strtolower(ora_columnname($this->Query_ID,$ix)); + $value=ora_getcolumn($this->Query_ID,$ix); + $this->Record[ "$col" ] = $value; +# echo"[$col]: $value
\n"; + } + $stat=1; + } + + return $stat; + } + + ## seek() works only for $pos - 1 and $pos + ## Perhaps I make a own implementation, but my + ## opinion is, that this should be done by PHP3 + function seek($pos) { + if ($this->Row - 1 == $pos) { + $this->no_next_fetch=true; + } elseif ($this->Row == $pos ) { + ## do nothing + } else { + $this->halt("Invalid seek(): Position is cannot be handled by API.
". + "Difference too big. Wanted: $pos Current pos: $this->Row"); + } + if ($Debug) echo "
Debug: seek = $pos
"; + $this->Row=$pos; + } + + function lock($table, $mode = "write") { + if ($mode == "write") { + $result = ora_do($this->Link_ID, "lock table $table in row exclusive mode"); + } else { + $result = 1; + } + return $result; + } + + function unlock() { + return ora_do($this->Link_ID, "commit"); + } + + function metadata($table,$full=false) { + $count = 0; + $id = 0; + $res = array(); + + /* + * Due to compatibility problems with Table we changed the behavior + * of metadata(); + * depending on $full, metadata returns the following values: + * + * - full is false (default): + * $result[]: + * [0]["table"] table name + * [0]["name"] field name + * [0]["type"] field type + * [0]["len"] field length + * [0]["flags"] field flags ("NOT NULL", "INDEX") + * [0]["format"] precision and scale of number (eg. "10,2") or empty + * [0]["index"] name of index (if has one) + * [0]["chars"] number of chars (if any char-type) + * + * - full is true + * $result[]: + * ["num_fields"] number of metadata records + * [0]["table"] table name + * [0]["name"] field name + * [0]["type"] field type + * [0]["len"] field length + * [0]["flags"] field flags ("NOT NULL", "INDEX") + * [0]["format"] precision and scale of number (eg. "10,2") or empty + * [0]["index"] name of index (if has one) + * [0]["chars"] number of chars (if any char-type) + * ["meta"][field name] index of field named "field name" + * The last one is used, if you have a field name, but no index. + * Test: if (isset($result['meta']['myfield'])) {} ... + */ + + $this->connect(); + + ## This is a RIGHT OUTER JOIN: "(+)", if you want to see, what + ## this query results try the following: + ## $table = new Table; $db = new my_DB_Sql; # you have to make + ## # your own class + ## $table->show_results($db->query(see query vvvvvv)) + ## + $this->query("SELECT T.table_name,T.column_name,T.data_type,". + "T.data_length,T.data_precision,T.data_scale,T.nullable,". + "T.char_col_decl_length,I.index_name". + " FROM ALL_TAB_COLUMNS T,ALL_IND_COLUMNS I". + " WHERE T.column_name=I.column_name (+)". + " AND T.table_name=I.table_name (+)". + " AND T.table_name=UPPER('$table') ORDER BY T.column_id"); + + $i=0; + while ($this->next_record()) { + $res[$i]["table"] = $this->Record[table_name]; + $res[$i]["name"] = strtolower($this->Record[column_name]); + $res[$i]["type"] = $this->Record[data_type]; + $res[$i]["len"] = $this->Record[data_length]; + if ($this->Record[index_name]) $res[$i]["flags"] = "INDEX "; + $res[$i]["flags"] .= ( $this->Record[nullable] == 'N') ? '' : 'NOT NULL'; + $res[$i]["format"]= (int)$this->Record[data_precision].",". + (int)$this->Record[data_scale]; + if ("0,0"==$res[$i]["format"]) $res[$i]["format"]=''; + $res[$i]["index"] = $this->Record[index_name]; + $res[$i]["chars"] = $this->Record[char_col_decl_length]; + if ($full) { + $j=$res[$i]["name"]; + $res["meta"][$j] = $i; + $res["meta"][strtoupper($j)] = $i; + } + if ($full) $res["meta"][$res[$i]["name"]] = $i; + $i++; + } + if ($full) $res["num_fields"]=$i; +# $this->disconnect(); + return $res; + } + + ## THIS FUNCTION IS UNSTESTED! + function affected_rows() { + if ($Debug) echo "
Debug: affected_rows=". ora_numrows($this->Query_ID)."
"; + return ora_numrows($this->Query_ID); + } + + ## Known bugs: It will not work for SELECT DISTINCT and any + ## other constructs which are depending on the resulting rows. + ## So you *really need* to check every query you make, if it + ## will work with it. + ## + ## Also, for a qualified replacement you need to parse the + ## selection, cause this will fail: "SELECT id, from FROM ..."). + ## "FROM" is - as far as I know a keyword in Oracle, so it can + ## only be used in this way. But you have been warned. + function num_rows() { + $curs=ora_open($this->Link_ID); + + ## this is the important part and it is also the HACK! + if (eregi("^[[:space:]]*SELECT[[:space:]]",$this->lastQuery) ) { + $from_pos = strpos(strtoupper($this->lastQuery),"FROM"); + $q = "SELECT count(*) ". substr($this->lastQuery, $from_pos); + + ORA_parse($curs,$q); + ORA_exec($curs); + ORA_fetch($curs); + if ($Debug) echo "
Debug: num_rows=". ORA_getcolumn($curs,0)."
"; + return(ORA_getcolumn($curs,0)); + } else { + $this->halt("Last Query was not a SELECT: $this->lastQuery"); + } + } + + function num_fields() { + if ($Debug) echo "
Debug: num_fields=". ora_numcols($this->Query_ID) . "
"; + return ora_numcols($this->Query_ID); + } + + function nf() { + return $this->num_rows(); + } + + function np() { + print $this->num_rows(); + } + + function f($Name) { + return $this->Record[$Name]; + } + + function p($Name) { + print $this->Record[$Name]; + } + + /* public: sequence number */ + function nextid($seq_name) + { + $this->connect(); + + /* Independent Query_ID */ + $Query_ID = ora_open($this->Link_ID); + + if(!@ora_parse($Query_ID,"SELECT $seq_name.NEXTVAL FROM DUAL")) + { + // There is no such sequence yet, then create it + if(!@ora_parse($Query_ID,"CREATE SEQUENCE $seq_name") + || + !@ora_exec($Query_ID) + ) + { + $this->halt("
nextid() function - unable to create sequence"); + return 0; + } + @ora_parse($Query_ID,"SELECT $seq_name.NEXTVAL FROM DUAL"); + } + if (!@ora_exec($Query_ID)) { + $this->halt("
ora_exec() failed:
nextID function"); + } + if (@ora_fetch($Query_ID) ) { + $next_id = ora_getcolumn($Query_ID, 0); + } + else { + $next_id = 0; + } + if ( Query_ID > 0 ) { + ora_close(Query_ID); + } + + return $next_id; + } + + function disconnect() { + if($this->Debug) { + echo "Debug: Disconnecting $this->Query_ID...
\n"; + } + if ( $this->Query_ID < 1 ) { + echo "Warning: disconnect(): Cannot free ID $this->Query_ID\n"; +# return(); + } + ora_close($this->Query_ID); + $this->Query_ID=0; + } + + /* private: error handling */ + function halt($msg) { + if ($this->Halt_On_Error == "no") + return; + + $this->haltmsg($msg); + + if ($this->Halt_On_Error != "report") + die("Session halted."); + } + + function haltmsg($msg) { + printf("Database error: %s
\n", $msg); + printf("Oracle Error: %s (%s)
\n", + $this->Errno, + $this->Error); + } + + function table_names() { + $this->connect(); + $this->query(" + SELECT table_name,tablespace_name + FROM user_tables"); + $i=0; + while ($this->next_record()) + { + $info[$i]["table_name"] =$this->Record["table_name"]; + $info[$i]["tablespace_name"]=$this->Record["tablespace_name"]; + $i++; + } + return $info; + } +} diff --git a/phpgwapi/phpgw_db_pgsql.inc.php b/phpgwapi/phpgw_db_pgsql.inc.php new file mode 100644 index 0000000000..d8875cfbb3 --- /dev/null +++ b/phpgwapi/phpgw_db_pgsql.inc.php @@ -0,0 +1,259 @@ +query($query); + } + + function connect() { + if ( 0 == $this->Link_ID ) { + $cstr = "dbname=".$this->Database. + $this->ifadd($this->Host, "host="). + $this->ifadd($this->Port, "port="). + $this->ifadd($this->User, "user="). + $this->ifadd($this->Password, "password="); + $this->Link_ID=pg_pconnect($cstr); + if (!$this->Link_ID) { + $this->halt("Link-ID == false, pconnect failed"); + } + } + } + + // This only affects systems not using persistant connections + function disconnect() + { + return pg_close($this->Link_ID); + } + + // I added the line and file section so we can have better error reporting. (jengo) + function query($Query_String, $line = "", $file = "") { + /* No empty queries, please, since PHP4 chokes on them. */ + if ($Query_String == "") + /* The empty query string is passed on from the constructor, + * when calling the class without a query, e.g. in situations + * like these: '$db = new db_Subclass;' + */ + return 0; + + $this->connect(); + +# printf("
Debug: query = %s
\n", $Query_String); + + $this->Query_ID = pg_Exec($this->Link_ID, $Query_String); + $this->Row = 0; + + $this->Error = pg_ErrorMessage($this->Link_ID); + $this->Errno = ($this->Error == "")?0:1; + if (! $this->Query_ID) { + $this->halt("Invalid SQL: ".$Query_String, $line, $file); + } + + return $this->Query_ID; + } + + // public: discard the query result + function free() { + @pg_freeresult($this->Query_ID); + $this->Query_ID = 0; + } + + function next_record() { + $this->Record = @pg_fetch_array($this->Query_ID, $this->Row++); + + $this->Error = pg_ErrorMessage($this->Link_ID); + $this->Errno = ($this->Error == "")?0:1; + + $stat = is_array($this->Record); + if (!$stat && $this->Auto_Free) { + pg_freeresult($this->Query_ID); + $this->Query_ID = 0; + } + return $stat; + } + + function seek($pos) { + $this->Row = $pos; + } + + function lock($table, $mode = "write") { + $result = pg_Exec($this->Link_ID, "begin work"); + if ($mode == "write") { + if (is_array($table)) { + while ($t = each($table)) { + $result = pg_Exec($this->Link_ID,"lock table $t[1] in share mode"); + } + } else { + $result = pg_Exec($this->Link_ID, "lock table $table in share mode"); + } + } else { + $result = 1; + } + return $result; + } + + function unlock() { + return pg_Exec($this->Link_ID, "commit work"); + } + + + /* public: sequence numbers */ + function nextid($seq_name) { + $this->connect(); + + if ($this->lock($this->Seq_Table)) { + /* get sequence number (locked) and increment */ + $q = sprintf("select nextid from %s where seq_name = '%s'", + $this->Seq_Table, + $seq_name); + $id = @pg_Exec($this->Link_ID, $q); + $res = @pg_Fetch_Array($id, 0); + + /* No current value, make one */ + if (!is_array($res)) { + $currentid = 0; + $q = sprintf("insert into %s values('%s', %s)", + $this->Seq_Table, + $seq_name, + $currentid); + $id = @pg_Exec($this->Link_ID, $q); + } else { + $currentid = $res["nextid"]; + } + $nextid = $currentid + 1; + $q = sprintf("update %s set nextid = '%s' where seq_name = '%s'", + $this->Seq_Table, + $nextid, + $seq_name); + $id = @pg_Exec($this->Link_ID, $q); + $this->unlock(); + } else { + $this->halt("cannot lock ".$this->Seq_Table." - has it been created?"); + return 0; + } + return $nextid; + } + + + + function metadata($table) { + $count = 0; + $id = 0; + $res = array(); + + $this->connect(); + $id = pg_exec($this->Link_ID, "select * from $table"); + if ($id < 0) { + $this->Error = pg_ErrorMessage($id); + $this->Errno = 1; + $this->halt("Metadata query failed."); + } + $count = pg_NumFields($id); + + for ($i=0; $i<$count; $i++) { + $res[$i]["table"] = $table; + $res[$i]["name"] = pg_FieldName ($id, $i); + $res[$i]["type"] = pg_FieldType ($id, $i); + $res[$i]["len"] = pg_FieldSize ($id, $i); + $res[$i]["flags"] = ""; + } + + pg_FreeResult($id); + return $res; + } + + function affected_rows() { + return pg_cmdtuples($this->Query_ID); + } + + function num_rows() { + return pg_numrows($this->Query_ID); + } + + function num_fields() { + return pg_numfields($this->Query_ID); + } + + function nf() { + return $this->num_rows(); + } + + function np() { + print $this->num_rows(); + } + + function f($Name) { + return $this->Record[$Name]; + } + + function p($Name) { + print $this->Record[$Name]; + } + + function halt($msg, $line = "", $file = "") { + if($this->Halt_On_Error == "no") { + return; + } + $this->unlock(); // Just in case there is a table currently locked + + printf("Database error: %s
\n", $msg); + printf("PostgreSQL Error: %s (%s)
\n", + $this->Errno, + $this->Error); + if ($file) { + printf("
File: %s",$file); + } + if ($line) { + printf("
Line: %s",$line); + } + + if($this->Halt_On_Error == "yes") { + die("

Session halted."); + } + } + + function table_names() { + $this->query("select relname from pg_class where relkind = 'r' and not relname like 'pg_%'"); + $i=0; + while ($this->next_record()) + { + $return[$i]["table_name"]= $this->f(0); + $return[$i]["tablespace_name"]=$this->Database; + $return[$i]["database"]=$this->Database; + $i++; + } + return $return; + } +} diff --git a/phpgwapi/phpgw_db_sybase.inc.php b/phpgwapi/phpgw_db_sybase.inc.php new file mode 100644 index 0000000000..7a15412ea0 --- /dev/null +++ b/phpgwapi/phpgw_db_sybase.inc.php @@ -0,0 +1,133 @@ + + * + * metadata() contributed by Adelino Monteiro + * + * $Id$ + * + */ + +class db { + var $Host = ""; + var $Database = ""; + var $User = ""; + var $Password = ""; + + var $Link_ID = 0; + var $Query_ID = 0; + var $Record = array(); + var $Row; + + var $Auto_Free = 0; ## Set this to 1 for automatic sybase_free_result() + + function connect() { + if ( 0 == $this->Link_ID ) { + $this->Link_ID=sybase_pconnect($this->Host,$this->User,$this->Password); + if (!$this->Link_ID) { + $this->halt("Link-ID == false, pconnect failed"); + } + if(!sybase_select_db($this->Database, $this->Link_ID)) { + $this->halt("cannot use database ".$this->Database); + } + } + } + + function query($Query_String) { + $this->connect(); + +# printf("Debug: query = %s
\n", $Query_String); + + $this->Query_ID = sybase_query($Query_String,$this->Link_ID); + $this->Row = 0; + if (!$this->Query_ID) { + $this->halt("Invalid SQL: ".$Query_String); + } + + return $this->Query_ID; + } + + function next_record() { + $this->Record = sybase_fetch_array($this->Query_ID); + $this->Row += 1; + + $stat = is_array($this->Record); + if (!$stat && $this->Auto_Free) { + sybase_free_result($this->Query_ID); + $this->Query_ID = 0; + } + return $stat; + } + + function seek($pos) { + $status = sybase_data_seek($this->Query_ID, $pos); + if ($status) + $this->Row = $pos; + return; + } + + function metadata($table) { + $count = 0; + $id = 0; + $res = array(); + + $this->connect(); + $result = $this->query("exec sp_columns $table"); + if ($result < 0) { + $this->Errno = 1; + $this->Error = "Metadata query failed"; + $this->halt("Metadata query failed."); + } + $count = sybase_num_rows($result); + + for ($i=0; $i<$count; $i++) { + $res[$i]["table"] = $table ; + $res[$i]["name"] = sybase_result ($result, $i, "COLUMN_NAME"); + $res[$i]["type"] = sybase_result ($result, $i, "TYPE_NAME"); + $res[$i]["len"] = sybase_result ($result, $i, "LENGTH"); + $res[$i]["position"] = sybase_result ($result, $i, "ORDINAL_POSITION"); + $res[$i]["flags"] = sybase_result ($result, $i, "REMARKS"); + + } + } + + function affected_rows() { + return sybase_affected_rows($this->Query_ID); + } + + function num_rows() { + return sybase_num_rows($this->Query_ID); + } + + function num_fields() { + return sybase_num_fields($this->Query_ID); + } + + function nf() { + return $this->num_rows(); + } + + function np() { + print $this->num_rows(); + } + + function f($Name) { + return $this->Record[$Name]; + } + + function p($Name) { + print $this->Record[$Name]; + } + + function halt($msg) { + printf("Database error: %s
\n", $msg); + printf("Sybase Error
\n"); + die("Session halted."); + } +} +?> diff --git a/phpgwapi/phpgw_info.inc.php b/phpgwapi/phpgw_info.inc.php new file mode 100644 index 0000000000..22b2d8f8a9 --- /dev/null +++ b/phpgwapi/phpgw_info.inc.php @@ -0,0 +1,120 @@ + * + * -------------------------------------------- * + * This program is free software; you can redistribute it and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; either version 2 of the License, or (at your * + * option) any later version. * + \**************************************************************************/ + + /* $Id$ */ + + $d1 = strtolower(substr($phpgw_info["server"]["include_root"],0,3)); + $d2 = strtolower(substr($phpgw_info["server"]["server_root"],0,3)); + $d3 = strtolower(substr($phpgw_info["server"]["api_dir"],0,3)); + if($d1 == "htt" || $d1 == "ftp" || $d2 == "htt" || $d2 == "ftp" || $d3 == "htt" || $d3 == "ftp") { + echo "Failed attempt to break in via an old Security Hole!
\n"; + exit; + } unset($d1);unset($d2);unset($d3); + + magic_quotes_runtime(false); + + /* Make sure the developer is following the rules. */ + if (!isset($phpgw_info["flags"]["currentapp"])) { + echo "!!! YOU DO NOT HAVE YOUR \$phpgw_info[\"flags\"][\"currentapp\"] SET !!!"; + echo "!!! PLEASE CORRECT THIS SITUATION !!!"; + } + + /* Additional dirs that are set from exsisting information. */ + $phpgw_info["server"]["api_dir"] = $phpgw_info["server"]["include_root"] . "/phpgwapi"; + + if (empty($phpgw_info["server"]["default_tplset"])){ + $phpgw_info["server"]["default_tplset"] = "default"; + } + + if (empty($phpgw_info["server"]["template_dir"])){ + $phpgw_info["server"]["template_dir"] = $phpgw_info["server"]["include_root"]."/templates/".$phpgw_info["server"]["default_tplset"]; + } + + if (!isset($phpgw_domain)) { // make them fix their header + echo "The administration is required to upgrade the header.inc.php file before you can continue."; + exit; + } + + reset($phpgw_domain); + $default_domain = each($phpgw_domain); + $phpgw_info["server"]["default_domain"] = $default_domain[0]; + unset ($default_domain); // we kill this for security reasons + + // This code will handle virtdomains so that is a user logins with user@domain.com, it will switch into virtualization mode. + if (isset($domain)){ + $phpgw_info["user"]["domain"] = $domain; + }elseif (isset($login) && isset($logindomain)){ + if (!ereg ("\@", $login)){ + $login = $login."@".$logindomain; + } + $phpgw_info["user"]["domain"] = $logindomain; + unset ($logindomain); + }elseif (isset($login) && !isset($logindomain)){ + if (ereg ("\@", $login)){ + $login_array = explode("@", $login); + $phpgw_info["user"]["domain"] = $login_array[1]; + }else{ + $phpgw_info["user"]["domain"] = $phpgw_info["server"]["default_domain"]; + $login = $login."@".$phpgw_info["user"]["domain"]; + } + } + + if (isset($phpgw_domain[$phpgw_info["user"]["domain"]])){ + $phpgw_info["server"]["db_host"] = $phpgw_domain[$phpgw_info["user"]["domain"]]["db_host"]; + $phpgw_info["server"]["db_name"] = $phpgw_domain[$phpgw_info["user"]["domain"]]["db_name"]; + $phpgw_info["server"]["db_user"] = $phpgw_domain[$phpgw_info["user"]["domain"]]["db_user"]; + $phpgw_info["server"]["db_pass"] = $phpgw_domain[$phpgw_info["user"]["domain"]]["db_pass"]; + $phpgw_info["server"]["db_type"] = $phpgw_domain[$phpgw_info["user"]["domain"]]["db_type"]; + }else{ + $phpgw_info["server"]["db_host"] = $phpgw_domain[$phpgw_info["server"]["default_domain"]]["db_host"]; + $phpgw_info["server"]["db_name"] = $phpgw_domain[$phpgw_info["server"]["default_domain"]]["db_name"]; + $phpgw_info["server"]["db_user"] = $phpgw_domain[$phpgw_info["server"]["default_domain"]]["db_user"]; + $phpgw_info["server"]["db_pass"] = $phpgw_domain[$phpgw_info["server"]["default_domain"]]["db_pass"]; + $phpgw_info["server"]["db_type"] = $phpgw_domain[$phpgw_info["server"]["default_domain"]]["db_type"]; + } + + if ($phpgw_info["flags"]["currentapp"] != "login" && ! $phpgw_info["server"]["show_domain_selectbox"]) { + unset ($phpgw_domain); // we kill this for security reasons + } + unset ($domain); // we kill this to save memory + + // some constants which can be used in setting user acl rights. + define("PHPGW_ACL_READ",1); + define("PHPGW_ACL_ADD",2); + define("PHPGW_ACL_EDIT",4); + define("PHPGW_ACL_DELETE",8); + + // This function needs to be optimized, its reading duplicate information. + function phpgw_fillarray() + { + global $phpgw, $phpgw_info, $cd, $colspan; + $phpgw_info["server"]["images_dir"] = $phpgw_info["server"]["webserver_url"] . "/images"; + $phpgw_info["server"]["template_dir"] = $phpgw_info["server"]["include_root"] . "/templates/" + . $phpgw_info["server"]["default_tplset"]; + + $phpgw_info["server"]["app_root"] = $phpgw_info["server"]["server_root"]."/".$phpgw_info["flags"]["currentapp"]; + $phpgw_info["server"]["app_inc"] = $phpgw_info["server"]["app_root"]."/inc"; + $phpgw_info["server"]["app_images"] = $phpgw_info["server"]["webserver_url"]."/".$phpgw_info["flags"]["currentapp"]."/images"; + $phpgw_info["server"]["app_tpl"] = $phpgw_info["server"]["app_root"]."/templates/".$phpgw_info["server"]["default_tplset"]; + + /* ********This sets the user variables******** */ + $phpgw_info["user"]["private_dir"] = $phpgw_info["server"]["files_dir"] . "/users/" + . $phpgw_info["user"]["userid"]; + + $phpgw_info["server"]["my_include_dir"] = $phpgw_info["server"]["app_inc"]; + + // This shouldn't happen, but if it does get ride of the warnings it will spit out + if (gettype($phpgw_info["user"]["preferences"]) != "array") { + $phpgw_info["user"]["preferences"] = array(); + } + } +?> diff --git a/phpgwapi/phpgw_lang_sql.inc.php b/phpgwapi/phpgw_lang_sql.inc.php new file mode 100644 index 0000000000..91125f9b29 --- /dev/null +++ b/phpgwapi/phpgw_lang_sql.inc.php @@ -0,0 +1,77 @@ + * + * -------------------------------------------- * + * This program is free software; you can redistribute it and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; either version 2 of the License, or (at your * + * option) any later version. * + \**************************************************************************/ + + /* $Id$ */ + + class translation + { + + function translate($key, $vars=false ) + { + if ( ! $vars ) $vars = array(); + global $phpgw, $phpgw_info, $lang; + $ret = $key; + if (!isset($lang) || !$lang) { + if (isset($phpgw_info["user"]["preferences"]["common"]["lang"]) && + $phpgw_info["user"]["preferences"]["common"]["lang"]) { + $userlang = $phpgw_info["user"]["preferences"]["common"]["lang"]; + }else{ + $userlang = "en"; + } + $sql = "select message_id,content from lang where lang like '".$userlang."' ". + "and (app_name like '".$phpgw_info["flags"]["currentapp"]."' or app_name like 'common')"; + + if (strcasecmp ($phpgw_info["flags"]["currentapp"], "common")>0){ + $sql .= " order by app_name asc"; + }else{ + $sql .= " order by app_name desc"; + } + + $phpgw->db->query($sql,__LINE__,__FILE__); + $phpgw->db->next_record(); + $count = $phpgw->db->num_rows(); + for ($idx = 0; $idx < $count; ++$idx) { + $lang[strtolower ($phpgw->db->f("message_id"))] = $phpgw->db->f("content"); + $phpgw->db->next_record(); + } + } + if (isset($lang[strtolower ($key)]) && $lang[strtolower ($key)]){ + $ret = $lang[strtolower ($key)]; + }else{ + $ret = $key."*"; + } + $ndx = 1; + while( list($key,$val) = each( $vars ) ) { + $ret = preg_replace( "/%$ndx/", $val, $ret ); + ++$ndx; + } + return $ret; + } + + function add_app($app) + { + global $phpgw, $phpgw_info, $lang; + if ($phpgw_info["user"]["preferences"]["common"]["lang"]){ + $userlang = $phpgw_info["user"]["preferences"]["common"]["lang"]; + }else{ + $userlang = "en"; + } + $sql = "select message_id,content from lang where lang like '".$userlang."' and app_name like '".$app."'"; + $phpgw->db->query($sql,__LINE__,__FILE__); + $phpgw->db->next_record(); + $count = $phpgw->db->num_rows(); + for ($idx = 0; $idx < $count; ++$idx) { + $lang[strtolower ($phpgw->db->f("message_id"))] = $phpgw->db->f("content"); + $phpgw->db->next_record(); + } + } + } diff --git a/phpgwapi/phpgw_network.inc.php b/phpgwapi/phpgw_network.inc.php new file mode 100644 index 0000000000..70f4bb58b6 --- /dev/null +++ b/phpgwapi/phpgw_network.inc.php @@ -0,0 +1,187 @@ + * + * -------------------------------------------- * + * This program is free software; you can redistribute it and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; either version 2 of the License, or (at your * + * option) any later version. * + \**************************************************************************/ + + /* $Id$ */ + +class network +{ + var $socket; + var $addcrlf = TRUE; + var $error; + var $errorset = 0; + + function network($addcrlf=true) + { + $this->errorset = 0; + $this->set_addcrlf($addcrlf); + } + + function set_addcrlf($value) + { + $this->addcrlf = $value; + } + + function set_error($code,$msg,$desc) + { + $this->error = array("code","msg","desc"); + $this->error["code"] = $code; + $this->error["msg"] = $msg; + $this->error["desc"] = $desc; +// $this->close_port(); + $this->errorset = 1; + return 0; + } + + function open_port($server,$port,$timeout=15) + { + global $phpgw_info; + + switch($port) { + case 80: + case 443: + if((isset($phpgw_info["server"]["httpproxy_server"]) && $phpgw_info["server"]["httpproxy_server"]) && + (isset($phpgw_info["server"]["httpproxy_port"]) && $phpgw_info["server"]["httpproxy_port"])) { + $server = $phpgw_info["server"]["httpproxy_server"]; + $port = (int)$phpgw_info["server"]["httpproxy_port"]; + } + break; + } + if(floor(phpversion()) == 4) + $this->socket = fsockopen($server,$port,&$errcode,&$errmsg,$timeout); + else + $this->socket = fsockopen($server,$port,&$errcode,&$errmsg); + if (!$this->socket) { + return $this->set_error("Error","$errcode:$errmsg","Connection to $server:$port failed - could not open socket."); + } else { + return 1; + } + } + + function close_port() + { + return fclose($this->socket); + } + + function read_port() + { + return fgets($this->socket, 1024); + } + + function bs_read_port($bytes) + { + return fread($this->socket, $bytes); + } + + function write_port($str) + { + if (isset($this->addcrlf) && $this->addcrlf == True) $str .= "\r\n"; + + $ok = fputs($this->socket,$str); + if (!$ok) + { + return $this->set_error("Error","Connection Lost","lost connection to server"); + } else { + return 1; + } + } + + function bs_write_port($str,$bytes=0) + { + if (isset($this->addcrlf) && $this->addcrlf == True) $str .= "\r\n"; + + if ($bytes) + $ok = fwrite($this->socket,$str,$bytes); + else + $ok = fwrite($this->socket,$str); + + if (!$ok) + { + return $this->set_error("Error","Connection Lost","lost connection to server"); + } else { + return 1; + } + } + + function msg2socket($str,$expected_response,$response) + { + if(!$this->socket && substr($expected_response,1,1) == "+") { + return $this->set_error("521", + "socket does not exist", + "The required socket does not exist. The settings for your mail server may be wrong."); + } + if (!$this->write_port($str)) { + if(substr($expected_response,1,1) == "+") { + return $this->set_error("420", + "lost connection", + "Lost connection to pop server."); + } else { + return 0; + } + } + $response = $this->read_port(); + if (!ereg(strtoupper($expected_response),strtoupper($response))) { + if(substr($expected_response,1,1) == "+") { + return $this->set_error("550", + "", + ""); + } + $pos = strpos(" ",$response); + return $this->set_error(substr($response,0,$pos), + "invalid response($expected_response)", + substr($response,($pos + 1),(strlen($response)-$pos))); + } else { + return 1; + } + } + + // return contents of a web url as an array or false if timeout + function gethttpsocketfile($file) + { + global $phpgw_info; + + $server = str_replace("http://","",$file); + $file = strstr($server,"/"); + $server = str_replace("$file","",$server); + if ($phpgw_info["server"]["httpproxy_server"]) { + if ($this->open_port($server,80, 15)) { + if (! $this->write_port("GET http://" . $server . $file . " HTTP/1.0\n\n")) { + return False; + } + $i = 0; + while ($line = $this->read_port()) { + if (feof($this->socket)) { + break; + } + $lines[] = $line; + $i++; + } + $this->close_port(); + return $lines; + } else { + return False; + } + } else { + if ($this->open_port($server, 80, 15)) { + if (!$this->write_port("GET $file HTTP/1.0\nHost: $server\n\n")) { + return 0; + } + while ($line = $this->read_port()) { + $lines[] = $line; + } + $this->close_port(); + return $lines; + } else { + return 0; + } + } + } +} diff --git a/phpgwapi/phpgw_nextmatchs.inc.php b/phpgwapi/phpgw_nextmatchs.inc.php new file mode 100644 index 0000000000..df97f870ed --- /dev/null +++ b/phpgwapi/phpgw_nextmatchs.inc.php @@ -0,0 +1,341 @@ + * + * -------------------------------------------- * + * This program is free software; you can redistribute it and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; either version 2 of the License, or (at your * + * option) any later version. * + \**************************************************************************/ + + /* $Id$ */ +class nextmatchs +{ + + // I split this up so it can be used in differant layouts. + function show($sn,$start,$total,$extra, $twidth, $bgtheme, + $search_obj=0,$filter_obj=1,$showsearch=1) + { + echo $this->tablestart($sn,$twidth, $bgtheme); + echo $this->left($sn,$start,$total,$extra); + if ($showsearch == 1) + { + echo $this->search($search_obj); + } + echo $this->filter($filter_obj); + echo $this->right($sn,$start,$total,$extra); + echo $this->tableend(); + } + + // -------------------------------------------------------------------- + // same as show, only without direct output for use within templates + // *** the show function can be removed as soon as every program using + // nextmatch is converted to use template and show_tpl (loge) + // -------------------------------------------------------------------- + function show_tpl($sn,$start,$total,$extra, $twidth, $bgtheme, + $search_obj=0,$filter_obj=1,$showsearch=1) + { + $var = $this->tablestart($sn,$twidth, $bgtheme); + $var .= $this->left($sn,$start,$total,$extra); + if ($showsearch == 1) + { + $var .= $this->search($search_obj); + } + $var .= $this->filter($filter_obj); + $var .= $this->right($sn,$start,$total,$extra); + $var .= $this->tableend(); + return $var; + } + + function tablestart($scriptname, $twidth="75%", $bgtheme="D3DCE3") + { + global $filter, $qfield, $start, $order, $sort, $query, $phpgw; + + $str = "

link($scriptname) . "\"> + + + + + + "; + + $str .= "\n\n"; + return $str; + } + + function tableend() + { + $str = "\n
\n
"; + $str .= "
"; + return $str; + } + + + function left($scriptname,$start,$total,$extradata = "") + { + global $filter, $qfield, $order, $sort, $query, $phpgw_info, $phpgw; + + $str = ""; + $maxmatchs = $phpgw_info["user"]["preferences"]["common"]["maxmatchs"]; + + if (( $start != 0 ) && ( $start > $maxmatchs )) + $str .= " link($scriptname,"start=0" + . "&order=$order&filter=$filter&qfield=$qfield" + . "&sort=$sort&query=$query".$extradata) + . "\">\""\n"; + else + $str .= "" + . " \""\n"; + + if ($start != 0) { + // Changing the sorting order screaws up the starting number + if ( ($start - $maxmatchs) < 0) + $t_start = 0; + else + $t_start = ($start - $maxmatchs); + + $str .= "link($scriptname,"start=$t_start" + . "&order=$order&filter=$filter&qfield=$qfield" + . "&sort=$sort&query=$query".$extradata) + . "\">\""\n"; + } else + $str .= "" + . "\""\n"; + + return $str; + } /* left() */ + + function search($search_obj=0) + { + global $query; + + $str = "" + . "
" + . " " + . $this->searchby($search_obj) + . "" + . "
" + . ""; + + return $str; + } /* search() */ + + function filterobj($filtertable, $idxfieldname, $strfieldname) + { + global $phpgw; + + $filter_obj = array(array("none","show all")); + $index = 0; + + $phpgw->db->query("SELECT $idxfieldname, $strfieldname from $filtertable",__LINE__,__FILE__); + while($phpgw->db->next_record()) + { + $index++; + $filter_obj[$index][0] = $phpgw->db->f("$idxfieldname"); + $filter_obj[$index][1] = $phpgw->db->f("$strfieldname"); + } + + return $filter_obj; + } /* filterobj() */ + + function searchby($search_obj) + { + global $qfield, $phpgw, $phpgw_info; + + $str = ""; + if (is_array($search_obj)) + { + $str .= "\n"; + } + + return $str; + + } /* searchby() */ + + function filter($filter_obj) + { + global $filter, $phpgw, $phpgw_info; + + $str = ""; + if (is_long($filter_obj)) + { + if ($filter_obj == 1) + { + $user_groups = + $phpgw->accounts->read_group_names($phpgw_info["user"]["userid"]); + $indexlimit = count($user_groups); + + $filter_obj = array(array("none",lang("show all")), + array("private",lang("only yours"))); + for ($index=0; $index<$indexlimit; $index++) + { + $filter_obj[2+$index][0] = $user_groups[$index][0]; + $filter_obj[2+$index][1] = "Group - " . $user_groups[$index][1]; + } + } + } + + if (is_array($filter_obj)) + { + $str .= "" + . "\n"; + $str .= "\n"; + $str .= "\n"; + } + + return $str; + + } /* filter() */ + + function right($scriptname,$start,$total,$extradata = "") + { + global $filter, $qfield, $order, $sort, $query, $phpgw_info, $phpgw; + $maxmatchs = $phpgw_info["user"]["preferences"]["common"]["maxmatchs"]; + + $str = ""; + if (($total > $maxmatchs) && ($total > $start + $maxmatchs)) + $str .= "link($scriptname,"start=".($start+$maxmatchs) + . "&order=$order&filter=$filter&qfield=$qfield" + . "&sort=$sort&query=$query".$extradata) + . "\">\""\n"; + else + $str .= "\"".lang("Next\n"; + + if (($start != $total - $maxmatchs) + && ( ($total - $maxmatchs) > ($start + $maxmatchs) )) + $str .= "link($scriptname,"start=".($total-$maxmatchs) + . "&order=$order&filter=$filter&qfield=$qfield" + . "&sort=$sort&query=$query".$extradata) + . "\">\"" \n"; + else + $str .= "\"".lang("Last "; + + return $str; + } /* right() */ + + function alternate_row_color($currentcolor = "") + { + global $phpgw_info; + if (! $currentcolor) { + global $tr_color; + $currentcolor = $tr_color; + } + + if ($currentcolor == $phpgw_info["theme"]["row_on"]) { + $tr_color = $phpgw_info["theme"]["row_off"]; + } else { + $tr_color = $phpgw_info["theme"]["row_on"]; + } + return $tr_color; + } + + function show_sort_order($sort,$var,$order,$program,$text,$extra="") + { + global $phpgw, $filter, $qfield, $start, $query; + if (($order == $var) && ($sort == "ASC")) + $sort = "DESC"; + else if (($order == $var) && ($sort == "DESC")) + $sort = "ASC"; + else + $sort = "ASC"; + + return "link($program,"order=$var&sort=$sort" + . "&filter=$filter&qfield=$qfield" + . "&start=$start&query=$query".$extra)."\">$text"; + } + + // Postgre and MySQL switch the vars in limit. This will make it easier + // if there are any other databases that pull this. + function sql_limit($start) + { + global $phpgw_info; + $max = $phpgw_info["user"]["preferences"]["common"]["maxmatchs"]; + + switch ($phpgw_info["server"]["db_type"]) { + case "pgsql": + if ($start == 0) + $l = $max; + else + $l = "$max,$start"; + return $l; + break; + case "mysql": + if ($start == 0) + $l = $max; + else + $l = "$start,$max"; + return $l; + break; + case "oracle": + if ($start == 0) + $l = "rownum < $max"; + else + $l = "rownum >= $start AND rownum <= $max"; +// if ($new_where) +// return "WHERE $l"; +// else +// return "AND $l"; + break; + } + } +} diff --git a/phpgwapi/phpgw_send.inc.php b/phpgwapi/phpgw_send.inc.php new file mode 100644 index 0000000000..c8e4a63ccd --- /dev/null +++ b/phpgwapi/phpgw_send.inc.php @@ -0,0 +1,248 @@ + * + * ------------------------------------------------ * + * This module should replace php's mail() function. It is fully syntax * + * compatible. In addition, when an error occures, a detailed error info * + * is stored in the array $send->err (see ../inc/email/global.inc.php for * + * details on this variable). * + \**************************************************************************/ + + /* $Id$ */ + +class send { + var $err = array("code","msg","desc"); + var $to_res = array(); + + function send() { + $this->err["code"] = " "; + $this->err["msg"] = " "; + $this->err["desc"] = " "; + } + + function msg($service, $to, $subject, $body, $msgtype="", $cc="", $bcc="") { + global $phpgw_info, $phpgw, $attach_sig; + + if ($service == "email") { + $now = getdate(); + $header = "Date: " . gmdate("D, d M Y H:i:s") . " +0000\n"; + $header .= "From: ".$phpgw_info["user"]["fullname"]." <".$phpgw_info["user"]["preferences"]["email"]["address"].">\n"; + $header .= "Reply-To: ".$phpgw_info["user"]["preferences"]["email"]["address"]."\n"; + $header .= "To: $to\n"; + if (!empty($cc)) { + $header .= "Cc: $cc\n"; + } + if (!empty($bcc)) { + $header .= "Bcc: $bcc\n"; + } + if (!empty($msgtype)) { + $header .= "X-phpGW-Type: $msgtype\n"; + } + $header .= "X-Mailer: phpGroupWare (http://www.phpgroupware.org)\n"; + + if ($phpgw_info["user"]["preferences"]["email"]["email_sig"] && $attach_sig) { + $body .= "\n-----\n" . $phpgw_info["user"]["preferences"]["email"]["email_sig"]; + } + + if (ereg("Message-Boundary", $body)) + { + $header .= "Subject: " . stripslashes($subject) . "\n" + . "MIME-Version: 1.0\n" + . "Content-Type: multipart/mixed;\n" + . " boundary=\"Message-Boundary\"\n\n" + . "--Message-Boundary\n" + . "Content-type: text/plain; charset=US-ASCII\n"; +// if (!empty($msgtype)) { +// $header .= "Content-type: text/plain; phpgw-type=".$msgtype."\n"; +// } + + $header .= "Content-Disposition: inline\n" + . "Content-transfer-encoding: 7BIT\n\n" + . $body; + $body = ""; + } else { + $header .= "Subject: " . stripslashes($subject) . "\n" + . "MIME-version: 1.0\n" + . "Content-type: text/plain; charset=\"".lang("charset")."\"\n"; + if (!empty($msgtype)) { + $header .= "Content-type: text/plain; phpgw-type=".$msgtype."\n"; + } + $header .= "Content-Disposition: inline\n" + . "Content-description: Mail message body\n"; + } + if ($phpgw_info["user"]["preferences"]["email"]["mail_server_type"] == "imap" && $phpgw_info["user"]["apps"]["email"]){ + $stream = $phpgw->msg->login("Sent"); + $phpgw->msg->append($stream, "Sent", $header, $body); + $phpgw->msg->close($stream); + } + if (strlen($cc)>1) $to .= ",".$cc; + + if (strlen($bcc)>1) $to .= ",".$bcc; + + $returnccode = $this->smail($to, "", $body, $header); + + return $returnccode; + } elseif ($type == "nntp") { + } + } + + // ==================================================[ some sub-functions ]=== + + function socket2msg($socket) { + $followme = "-"; $this->err["msg"] = ""; + do { + $rmsg = fgets($socket,255); +// echo "< $rmsg
\n"; + $this->err["code"] = substr($rmsg,0,3); + $followme = substr($rmsg,3,1); + $this->err["msg"] = substr($rmsg,4); + if (substr($this->err["code"],0,1) != 2 && substr($this->err["code"],0,1) != 3) { + $rc = fclose($socket); + return false; + } + if ($followme = " ") { break; } + } while ($followme = "-"); + return true; + } + + function msg2socket($socket,$message) { // send single line\n + // echo "raw> $message
\n"; + // echo "hex> ".bin2hex($message)."
\n"; + $rc = fputs($socket,"$message"); + if (!$rc) { + $this->err["code"] = "420"; + $this->err["msg"] = "lost connection"; + $this->err["desc"] = "Lost connection to smtp server."; + $rc = fclose($socket); + return false; + } + return true; + } + + function put2socket($socket,$message) { // check for multiple lines 1st + $pos = strpos($message,"\n"); + if (!is_int($pos)) { // no new line found + $message .= "\r\n"; + $this->msg2socket($socket,$message); + } else { // multiple lines, we have to split it + do { + $msglen = $pos + 1; + $msg = substr($message,0,$msglen); + $message = substr($message,$msglen); + $pos = strpos($msg,"\r\n"); + if (!is_int($pos)) { // line not terminated + $msg = chop($msg)."\r\n"; + } + $pos = strpos($msg,"."); // escape leading periods + if (is_int($pos) && !$pos) { + $msg = "." . $msg; + } + if (!$this->msg2socket($socket,$msg)) { return false; } + $pos = strpos($message,"\n"); + } while (strlen($message)>0); + } + return true; + } + + function check_header($subject,$header) { // check if header contains subject + // and is correctly terminated + $header = chop($header); + $header .= "\n"; + if (is_string($subject) && !$subject) { // no subject specified + return $header; + } + $theader = strtolower($header); + $pos = strpos($theader,"\nsubject:"); + if (is_int($pos)) { // found after a new line + return $header; + } + $pos = strpos($theader,"subject:"); + if (is_int($pos) && !$pos) { // found at start + return $header; + } + $pos = substr($subject,"\n"); + if (!is_int($pos)) $subject .= "\n"; + $subject = "Subject: " .$subject; + $header .= $subject; + return $header; + } + + // ==============================================[ main function: smail() ]=== + + function smail($to,$subject,$message,$header) { + global $phpgw_info; + + $fromuser = $phpgw_info["user"]["preferences"]["email"]["address"]; + $mymachine = $phpgw_info["server"]["hostname"]; + $errcode = ""; $errmsg = ""; // error code and message of failed connection + $timeout = 5; // timeout in secs + + // now we try to open the socket and check, if any smtp server responds + $socket = fsockopen($phpgw_info["server"]["smtp_server"],$phpgw_info["server"]["smtp_port"],$errcode,$errmsg,$timeout); + if (!$socket) { + $this->err["code"] = "420"; + $this->err["msg"] = "$errcode:$errmsg"; + $this->err["desc"] = "Connection to ".$phpgw_info["server"]["smtp_server"].":".$phpgw_info["server"]["smtp_port"]." failed - could not open socket."; + return false; + } else { + $rrc = $this->socket2msg($socket); + } + + // now we can send our message. 1st we identify ourselves and the sender + $cmds = array ( + "\$src = \$this->msg2socket(\$socket,\"HELO \$mymachine\r\n\");", + "\$rrc = \$this->socket2msg(\$socket);", + "\$src = \$this->msg2socket(\$socket,\"MAIL FROM:<\$fromuser>\r\n\");", + "\$rrc = \$this->socket2msg(\$socket);" + ); + for ($src=true,$rrc=true,$i=0; $imsg2socket($socket,"RCPT TO:<$toaddr[$i]>\r\n"); + $rrc = $this->socket2msg($socket); + $this->to_res[$i][addr] = $toaddr[$i]; // for lateron validation + $this->to_res[$i][code] = $this->err["code"]; + $this->to_res[$i][msg] = $this->err["msg"]; + $this->to_res[$i][desc] = $this->err["desc"]; + } + + //now we have to make sure that at least one $to-address was accepted + $stop = 1; + for ($i=0;$ito_res);$i++) { + $rc = substr($this->to_res[$i][code],0,1); + if ($rc == 2) { // at least to this address we can deliver + $stop = 0; + } + } + if ($stop) return false; // no address found we can deliver to + + // now we can go to deliver the message! + if (!$this->msg2socket($socket,"DATA\r\n")) return false; + if (!$this->socket2msg($socket)) return false; + if ($header != "") { + $header = $this->check_header($subject,$header); + if (!$this->put2socket($socket,$header)) return false; + if (!$this->put2socket($socket,"\r\n")) return false; + } + $message = chop($message); + $message .= "\n"; + if (!$this->put2socket($socket,$message)) return false; + if (!$this->msg2socket($socket,".\r\n")) return false; + if (!$this->socket2msg($socket)) return false; + if (!$this->msg2socket($socket,"QUIT\r\n")) return false; + Do { + $closing = $this->socket2msg($socket); + } while ($closing); + return true; + } + +// end of class +} diff --git a/phpgwapi/phpgw_session.inc.php b/phpgwapi/phpgw_session.inc.php new file mode 100644 index 0000000000..634fb56929 --- /dev/null +++ b/phpgwapi/phpgw_session.inc.php @@ -0,0 +1,185 @@ + * + * and Dan Kuykendall * + * -------------------------------------------- * + * This program is free software; you can redistribute it and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; either version 2 of the License, or (at your * + * option) any later version. * + \**************************************************************************/ + + /* $Id$ */ + + class sessions + { + function getuser_ip() + { + global $REMOTE_ADDR, $HTTP_X_FORWARDED_FOR; + + if ($HTTP_X_FORWARDED_FOR) { + return $HTTP_X_FORWARDED_FOR; + } else { + return $REMOTE_ADDR; + } + } + + function verify() + { + global $phpgw, $phpgw_info, $sessionid, $kp3; + $db = $phpgw->db; + $db2 = $phpgw->db; + + $db->query("select * from phpgw_sessions where session_id='$sessionid'",__LINE__,__FILE__); + $db->next_record(); + + if ($db->f("session_info") == "" || $db->f("session_info") == "NULL") { + $phpgw_info["user"]["account_lid"] = $db->f("session_lid"); + $phpgw_info["user"]["sessionid"] = $sessionid; + $phpgw_info["user"]["session_ip"] = $db->f("session_ip"); + + $t = explode("@",$db->f("session_lid")); + $phpgw_info["user"]["userid"] = $t[0]; + + $phpgw->accounts->sync(__LINE__,__FILE__); + + // Now we need to re-read eveything + $db->query("select * from phpgw_sessions where session_id='$sessionid'",__LINE__,__FILE__); + $db->next_record(); + } + + $phpgw_info["user"]["kp3"] = $kp3; + + $phpgw_info_flags = $phpgw_info["flags"]; + $phpgw_info = unserialize(stripslashes($db->f("session_info"))); + $phpgw_info["flags"] = $phpgw_info_flags; + + $userid_array = explode("@",$db->f("session_lid")); + $phpgw_info["user"]["userid"] = $userid_array[0]; + + if ($userid_array[1] != $phpgw_info["user"]["domain"]) { + return False; + } + + if (PHP_OS != "Windows" && (! $phpgw_info["user"]["session_ip"] || $phpgw_info["user"]["session_ip"] != $this->getuser_ip())){ + return False; + } + + $this->update_dla(); + + if (! $phpgw_info["user"]["userid"] ) { + return False; + } else { + return True; + } + } + + // This will remove stale sessions out of the database + function clean_sessions() + { + global $phpgw_info, $phpgw; + + // Note: I need to add a db->lock() in here + + if (!isset($phpgw_info["server"]["cron_apps"]) || ! $phpgw_info["server"]["cron_apps"]) { + $phpgw->db->query("delete from phpgw_sessions where session_dla <= '" . (time() - 7200) + . "'",__LINE__,__FILE__); + } + } + + function create($login,$passwd) + { + global $phpgw_info, $phpgw; + + $this->clean_sessions(); + + $login_array = explode("@", $login); + $phpgw_info["user"]["userid"] = $login_array[0]; + + if ($phpgw_info["server"]["global_denied_users"][$phpgw_info["user"]["userid"]]) { + return False; + } + + if (!$phpgw->auth->authenticate($phpgw_info["user"]["userid"], $passwd)) { + return False; + exit; + } + + $phpgw_info["user"]["sessionid"] = md5($phpgw->common->randomstring(10)); + $phpgw_info["user"]["kp3"] = md5($phpgw->common->randomstring(15)); + + $phpgw->common->key = $phpgw_info["server"]["encryptkey"]; + $phpgw->common->iv = $phpgw_info["server"]["mcrypt_iv"]; + $phpgw->crypto = new crypto($phpgw->common->key,$phpgw->common->iv); + + $phpgw_info["user"]["passwd"] = $phpgw->common->encrypt($passwd); + + if ($phpgw_info["server"]["usecookies"]) { + Setcookie("sessionid",$phpgw_info["user"]["sessionid"]); + Setcookie("kp3",$phpgw_info["user"]["kp3"]); + Setcookie("domain",$phpgw_info["user"]["domain"]); + Setcookie("last_domain",$phpgw_info["user"]["domain"],time()+1209600); + if ($phpgw_info["user"]["domain"] ==$phpgw_info["server"]["default_domain"]) { + Setcookie("last_loginid",$phpgw_info["user"]["userid"],time()+1209600); // For 2 weeks + } else { + Setcookie("last_loginid",$loginid,time()+1209600); // For 2 weeks + } + unset ($phpgw_info["server"]["default_domain"]); // we kill this for security reasons + } + + //$phpgw->accounts->accounts_const(); + + $phpgw_info["user"]["session_ip"] = $this->getuser_ip(); + + $phpgw->db->query("insert into phpgw_sessions values ('" . $phpgw_info["user"]["sessionid"] + . "','".$login."','" . $this->getuser_ip() . "','" + . time() . "','" . time() . "','')",__LINE__,__FILE__); + $phpgw->accounts->sync(__LINE__,__FILE__); + + $phpgw->db->query("insert into phpgw_access_log values ('" . $phpgw_info["user"]["sessionid"] . "','" + . "$login','" . $this->getuser_ip() . "','" . time() + . "','') ",__LINE__,__FILE__); + + $phpgw->db->query("update accounts set account_lastloginfrom='" + . $this->getuser_ip() . "', account_lastlogin='" . time() + . "' where account_lid='".$login."'",__LINE__,__FILE__); + + return $phpgw_info["user"]["sessionid"]; + } + + // This will update the DateLastActive column, so the login does not expire + function update_dla() + { + global $phpgw_info, $phpgw; + + $phpgw->db->query("update phpgw_sessions set session_dla='" . time() . "' where session_id='" + . $phpgw_info["user"]["sessionid"]."'",__LINE__,__FILE__); + } + + function destroy() + { + global $phpgw, $phpgw_info, $sessionid, $kp3; + $phpgw_info["user"]["sessionid"] = $sessionid; + $phpgw_info["user"]["kp3"] = $kp3; + + $phpgw->db->query("delete from phpgw_sessions where session_id='" + . $phpgw_info["user"]["sessionid"] . "'",__LINE__,__FILE__); + $phpgw->db->query("delete from phpgw_app_sessions where sessionid='" + . $phpgw_info["user"]["sessionid"] . "'",__LINE__,__FILE__); + $phpgw->db->query("update phpgw_access_log set lo='" . time() . "' where sessionid='" + . $phpgw_info["user"]["sessionid"] . "'",__LINE__,__FILE__); + if ($phpgw_info["server"]["usecookies"]) { + Setcookie("sessionid"); + Setcookie("kp3"); + if ($phpgw_info["multiable_domains"]) { + Setcookie("domain"); + } + } + $this->clean_sessions(); + return True; + } + + } +?> diff --git a/phpgwapi/phpgw_template.inc.php b/phpgwapi/phpgw_template.inc.php new file mode 100644 index 0000000000..40f4a17290 --- /dev/null +++ b/phpgwapi/phpgw_template.inc.php @@ -0,0 +1,346 @@ + remove undefined variables + * "comment" => replace undefined variables with comments + * "keep" => keep undefined variables + */ + var $unknowns = "remove"; + + /* "yes" => halt, "report" => report error, continue, "no" => ignore error quietly */ + var $halt_on_error = "yes"; + + /* last error message is retained here */ + var $last_error = ""; + + + /***************************************************************************/ + /* public: Constructor. + * root: template directory. + * unknowns: how to handle unknown variables. + */ + function Template($root = ".", $unknowns = "remove") { + $this->set_root($root); + $this->set_unknowns($unknowns); + } + + /* public: setroot(pathname $root) + * root: new template directory. + */ + function set_root($root) { + if (!is_dir($root)) { + $this->halt("set_root: $root is not a directory."); + return false; + } + + $this->root = $root; + return true; + } + + /* public: set_unknowns(enum $unknowns) + * unknowns: "remove", "comment", "keep" + * + */ + function set_unknowns($unknowns = "keep") { + $this->unknowns = $unknowns; + } + + /* public: set_file(array $filelist) + * filelist: array of handle, filename pairs. + * + * public: set_file(string $handle, string $filename) + * handle: handle for a filename, + * filename: name of template file + */ + function set_file($handle, $filename = "") { + if (!is_array($handle)) { + if ($filename == "") { + $this->halt("set_file: For handle $handle filename is empty."); + return false; + } + $this->file[$handle] = $this->filename($filename); + } else { + reset($handle); + while(list($h, $f) = each($handle)) { + $this->file[$h] = $this->filename($f); + } + } + } + + /* public: set_block(string $parent, string $handle, string $name = "") + * extract the template $handle from $parent, + * place variable {$name} instead. + */ + function set_block($parent, $handle, $name = "") { + if (!$this->loadfile($parent)) { + $this->halt("subst: unable to load $parent."); + return false; + } + if ($name == "") + $name = $handle; + + $str = $this->get_var($parent); + $reg = "/(.*)\n\s*/sm"; + preg_match_all($reg, $str, $m); + $str = preg_replace($reg, "{" . "$name}", $str); + $this->set_var($handle, $m[1][0]); + $this->set_var($parent, $str); + } + + /* public: set_var(array $values) + * values: array of variable name, value pairs. + * + * public: set_var(string $varname, string $value) + * varname: name of a variable that is to be defined + * value: value of that variable + */ + function set_var($varname, $value = "") { + if (!is_array($varname)) { + if (!empty($varname)) + if ($this->debug) print "scalar: set *$varname* to *$value*
\n"; + $this->varkeys[$varname] = "/".$this->varname($varname)."/"; + $this->varvals[$varname] = $value; + } else { + reset($varname); + while(list($k, $v) = each($varname)) { + if (!empty($k)) + if ($this->debug) print "array: set *$k* to *$v*
\n"; + $this->varkeys[$k] = "/".$this->varname($k)."/"; + $this->varvals[$k] = $v; + } + } + } + + /* public: subst(string $handle) + * handle: handle of template where variables are to be substituted. + */ + function subst($handle) { + if (!$this->loadfile($handle)) { + $this->halt("subst: unable to load $handle."); + return false; + } + + $str = $this->get_var($handle); + $str = @preg_replace($this->varkeys, $this->varvals, $str); + return $str; + } + + /* public: psubst(string $handle) + * handle: handle of template where variables are to be substituted. + */ + function psubst($handle) { + print $this->subst($handle); + + return false; + } + + /* public: parse(string $target, string $handle, boolean append) + * public: parse(string $target, array $handle, boolean append) + * target: handle of variable to generate + * handle: handle of template to substitute + * append: append to target handle + */ + function parse($target, $handle, $append = false) { + if (!is_array($handle)) { + $str = $this->subst($handle); + if ($append) { + $this->set_var($target, $this->get_var($target) . $str); + } else { + $this->set_var($target, $str); + } + } else { + reset($handle); + while(list($i, $h) = each($handle)) { + $str = $this->subst($h); + $this->set_var($target, $str); + } + } + + return $str; + } + + function pparse($target, $handle, $append = false) { + print $this->parse($target, $handle, $append); + return false; + } + + /* public: get_vars() + */ + function get_vars() { + reset($this->varkeys); + while(list($k, $v) = each($this->varkeys)) { + $result[$k] = $this->varvals[$k]; + } + + return $result; + } + + /* public: get_var(string varname) + * varname: name of variable. + * + * public: get_var(array varname) + * varname: array of variable names + */ + function get_var($varname) { + if (!is_array($varname)) { + return $this->varvals[$varname]; + } else { + reset($varname); + while(list($k, $v) = each($varname)) { + $result[$k] = $this->varvals[$k]; + } + + return $result; + } + } + + /* public: get_undefined($handle) + * handle: handle of a template. + */ + function get_undefined($handle) { + if (!$this->loadfile($handle)) { + $this->halt("get_undefined: unable to load $handle."); + return false; + } + + preg_match_all("/\{([^}]+)\}/", $this->get_var($handle), $m); + $m = $m[1]; + if (!is_array($m)) + return false; + + reset($m); + while(list($k, $v) = each($m)) { + if (!isset($this->varkeys[$v])) + $result[$v] = $v; + } + + if (count($result)) + return $result; + else + return false; + } + + /* public: finish(string $str) + * str: string to finish. + */ + function finish($str) { + switch ($this->unknowns) { + case "keep": + break; + + case "remove": + $str = preg_replace('/{[^ \t\r\n}]+}/', "", $str); + break; + + case "comment": + $str = preg_replace('/{([^ \t\r\n}]+)}/', "", $str); + break; + } + + return $str; + } + + /* public: p(string $varname) + * varname: name of variable to print. + */ + function p($varname) { + print $this->finish($this->get_var($varname)); + } + + function get($varname) { + return $this->finish($this->get_var($varname)); + } + + /***************************************************************************/ + /* private: filename($filename) + * filename: name to be completed. + */ + function filename($filename) { + if (substr($filename, 0, 1) != "/") { + $filename = $this->root."/".$filename; + } + + if (!file_exists($filename)) + $this->halt("filename: file $filename does not exist."); + + return $filename; + } + + /* private: varname($varname) + * varname: name of a replacement variable to be protected. + */ + function varname($varname) { + return preg_quote("{".$varname."}"); + } + + /* private: loadfile(string $handle) + * handle: load file defined by handle, if it is not loaded yet. + */ + function loadfile($handle) { + if (isset($this->varkeys[$handle]) and !empty($this->varvals[$handle])) + return true; + + if (!isset($this->file[$handle])) { + $this->halt("loadfile: $handle is not a valid handle."); + return false; + } + $filename = $this->file[$handle]; + + $str = implode("", @file($filename)); + if (empty($str)) { + $this->halt("loadfile: While loading $handle, $filename does not exist or is empty."); + return false; + } + + $this->set_var($handle, $str); + + return true; + } + + /***************************************************************************/ + /* public: halt(string $msg) + * msg: error message to show. + */ + function halt($msg) { + $this->last_error = $msg; + + if ($this->halt_on_error != "no") + $this->haltmsg($msg); + + if ($this->halt_on_error == "yes") + die("Halted."); + + return false; + } + + /* public, override: haltmsg($msg) + * msg: error message to show. + */ + function haltmsg($msg) { + printf("Template Error: %s
\n", $msg); + } +} diff --git a/phpgwapi/phpgw_todo.inc.php b/phpgwapi/phpgw_todo.inc.php new file mode 100644 index 0000000000..6cfde20b16 --- /dev/null +++ b/phpgwapi/phpgw_todo.inc.php @@ -0,0 +1,83 @@ + * + * -------------------------------------------------------------- * + * This program is free software; you can redistribute it and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; either version 2 of the License, or (at your * + * option) any later version. * + \**************************************************************************/ + + /* $Id$ */ +class todo +{ + var $projectid; + var $parent; + var $owner; + var $access; + var $desc; + var $priority; + var $status; + var $createdate; + var $customernr; + var $hours; + var $deadline; +// array $participants; + + var $db; // database handle + + //======================================== + // CONSTRUCTOR + //======================================== + function todo() + { + // dont know yet + } + + + //======================================== + // adds a project into database (API) + //======================================== + function addproject() + { + global $phpgw_info, $phpgw; + } + + //======================================== + // view project details (API) + //======================================== + function viewproject() + { + global $phpgw_info, $phpgw; + } + + //======================================== + // delete project (API) + //======================================== + function delproject() + { + global $phpgw_info, $phpgw; + } + + //======================================== + // add participant (API) + //======================================== + function addparticipant() + { + global $phpgw_info, $phpgw; + } + + // *************************************************** + // here we got helper methods for APIs + // *************************************************** + + // --------------------- + // helper 1 + //---------------------- + function helper1() + { + global $phpgw_info, $phpgw; + } +} diff --git a/phpgwapi/phpgw_utilities.inc.php b/phpgwapi/phpgw_utilities.inc.php new file mode 100644 index 0000000000..8b392acbca --- /dev/null +++ b/phpgwapi/phpgw_utilities.inc.php @@ -0,0 +1,44 @@ + * + * -------------------------------------------- * + * This program is free software; you can redistribute it and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; either version 2 of the License, or (at your * + * option) any later version. * + \**************************************************************************/ + + /* $Id$ */ + + $d1 = strtolower(substr($phpgw_info["server"]["api_dir"],0,3)); + if($d1 == "htt" || $d1 == "ftp") { + echo "Failed attempt to break in via an old Security Hole!
\n"; + exit; + } unset($d1); + + include($phpgw_info["server"]["api_dir"] . "/phpgw_utilities_rssparse.inc.php"); + include($phpgw_info["server"]["api_dir"] . "/phpgw_utilities_clientsniffer.inc.php"); + include($phpgw_info["server"]["api_dir"] . "/phpgw_utilities_http.inc.php"); + include($phpgw_info["server"]["api_dir"] . "/phpgw_utilities_matrixview.inc.php"); + include($phpgw_info["server"]["api_dir"] . "/phpgw_utilities_menutree.inc.php"); + + class utilities + { + var $rssparser; + var $clientsniffer; + var $http; + var $matrixview; + var $menutree; + + function utilities_() + { + $this->rssparser = new rssparser; + $this->clientsniffer = new clientsniffer; + $this->http = new http; + $this->matrixview = new matrixview; + $this->menutree = new menutree; + } + } +?> diff --git a/phpgwapi/phpgw_utilities_clientsniffer.inc.php b/phpgwapi/phpgw_utilities_clientsniffer.inc.php new file mode 100644 index 0000000000..1b155435a1 --- /dev/null +++ b/phpgwapi/phpgw_utilities_clientsniffer.inc.php @@ -0,0 +1,329 @@ +UA The HTTP USER AGENT String + $is->NAME Browser Name (Netscape, IE, Opera, iCab, Unknown) + $is->VERSION Browser Full Version + $is->MAJORVER Browser Major Version + $is->MINORVER Browser Minor Version + $is->AOL True/False + $is->WEBTV True/False + $is->JS Assumed JavaScript Version Supported by Browser + $is->PLATFORM System Platform (Win16,Win32,Mac,OS2,Unix) + $is->OS System OS (Win98,OS2,Mac68k,linux,bsd,etc...) see code + $is->IP REMOTE_ADDR + + ======================================================================== + + '****************************************/ + /* $Id$ */ + +class clientsniffer +{ var $UA = ""; + var $NAME = "Unknown"; + var $VERSION = 0; + var $MAJORVER = 0; + var $MINORVER = 0; + var $AOL = false; + var $WEBTV = false; + var $JS = 0.0; + var $PLATFORM = "Unknown"; + var $OS = "Unknown"; + var $IP = "Unknown"; + + /* START CONSTRUCTOR */ + function clientsniffer() + { $this->UA = getenv(HTTP_USER_AGENT); + + // Determine NAME Name and Version + if ( eregi( 'MSIE ([0-9].[0-9a-zA-Z]{1,4})',$this->UA,$info) || + eregi( 'Microsoft Internet Explorer ([0-9].[0-9a-zA-Z]{1,4})',$this->UA,$info) ) + { $this->VERSION = $info[1]; + $this->NAME = 'IE'; + } + elseif ( eregi( 'Opera ([0-9].[0-9a-zA-Z]{1,4})',$this->UA,$info) || + eregi( 'Opera/([0-9].[0-9a-zA-Z]{1,4})',$this->UA,$info) ) + { $this->VERSION = $info[1]; + $this->NAME = 'Opera'; + } + elseif ( eregi( 'iCab ([0-9].[0-9a-zA-Z]{1,4})',$this->UA,$info) || + eregi( 'iCab/([0-9].[0-9a-zA-Z]{1,4})',$this->UA,$info) ) + { $this->VERSION = $info[1]; + $this->NAME = 'iCab'; + } + elseif ( eregi( 'Netscape6/([0-9].[0-9a-zA-Z]{1,4})',$this->UA,$info) ) + { $this->VERSION = $info[1]; + $this->NAME = 'Netscape'; + } + elseif ( eregi( 'Mozilla/([0-9].[0-9a-zA-Z]{1,4})',$this->UA,$info) ) + { $this->VERSION = $info[1]; + $this->NAME = 'Netscape'; + } + else + { $this->VERSION = 0; + $this->NAME = 'Unknown'; + } + + // Determine if AOL or WEBTV + if( eregi( 'aol',$this->UA,$info)) + { $this->AOL = true; + } + elseif( eregi( 'webtv',$this->UA,$info)) + { $this->WEBTV = true; + } + + // Determine Major and Minor Version + if($this->VERSION > 0) + { $pos = strpos($this->VERSION,"."); + if ($pos > 0) + { $this->MAJORVER = substr($this->VERSION,0,$pos); + $this->MINORVER = substr($this->VERSION,$pos,strlen($this->VERSION)); + } + else $this->MAJORVER = $this->VERSION; + } + + // Determine Platform and OS + + // Check for Windows 16-bit + if( eregi('Win16',$this->UA) || + eregi('windows 3.1',$this->UA) || + eregi('windows 16-bit',$this->UA) || + eregi('16bit',$this->UA)) + { $this->PLATFORM = "Win16"; + $this->OS = "Win31"; + } + + // Check for Windows 32-bit + if(eregi('Win95',$this->UA) || eregi('windows 95',$this->UA)) + { $this->PLATFORM = "Win32"; + $this->OS = "Win95"; + } + elseif(eregi('Win98',$this->UA) || eregi('windows 98',$this->UA)) + { $this->PLATFORM = "Win32"; + $this->OS = "Win98"; + } + elseif(eregi('WinNT',$this->UA) || eregi('windows NT',$this->UA)) + { $this->PLATFORM = "Win32"; + $this->OS = "WinNT"; + } + else + { $this->PLATFORM = "Win32"; + $this->OS = "Win9xNT"; + } + + // Check for OS/2 + if( eregi('os/2',$this->UA) || + eregi('ibm-webexplorer',$this->UA)) + { $this->PLATFORM = "OS2"; + $this->OS = "OS2"; + } + + // Check for Mac 68000 + if( eregi('68k',$this->UA) || + eregi('68000',$this->UA)) + { $this->PLATFORM = "Mac"; + $this->OS = "Mac68k"; + } + + //Check for Mac PowerPC + if( eregi('ppc',$this->UA) || + eregi('powerpc',$this->UA)) + { $this->PLATFORM = "Mac"; + $this->OS = "MacPPC"; + } + + // Check for Unix Flavor + + //SunOS + if(eregi('sunos',$this->UA)) + { $this->PLATFORM = "Unix"; + $this->OS = "sun"; + } + if(eregi('sunos 4',$this->UA)) + { $this->PLATFORM = "Unix"; + $this->OS = "sun4"; + } + elseif(eregi('sunos 5',$this->UA)) + { $this->PLATFORM = "Unix"; + $this->OS = "sun5"; + } + elseif(eregi('i86',$this->UA)) + { $this->PLATFORM = "Unix"; + $this->OS = "suni86"; + } + + // Irix + if(eregi('irix',$this->UA)) + { $this->PLATFORM = "Unix"; + $this->OS = "irix"; + } + if(eregi('irix 6',$this->UA)) + { $this->PLATFORM = "Unix"; + $this->OS = "irix6"; + } + elseif(eregi('irix 5',$this->UA)) + { $this->PLATFORM = "Unix"; + $this->OS = "irix5"; + } + + //HP-UX + if(eregi('hp-ux',$this->UA)) + { $this->PLATFORM = "Unix"; + $this->OS = "hpux"; + } + if(eregi('hp-ux',$this->UA) && ereg('10.',$this-UA)) + { $this->PLATFORM = "Unix"; + $this->OS = "hpux10"; + } + elseif(eregi('hp-ux',$this->UA) && ereg('09.',$this-UA)) + { $this->PLATFORM = "Unix"; + $this->OS = "hpux9"; + } + + //AIX + if(eregi('aix',$this->UA)) + { $this->PLATFORM = "Unix"; + $this->OS = "aix"; + } + if(eregi('aix1',$this->UA)) + { $this->PLATFORM = "Unix"; + $this->OS = "aix1"; + } + elseif(eregi('aix2',$this->UA)) + { $this->PLATFORM = "Unix"; + $this->OS = "aix2"; + } + elseif(eregi('aix3',$this->UA)) + { $this->PLATFORM = "Unix"; + $this->OS = "aix3"; + } + elseif(eregi('aix4',$this->UA)) + { $this->PLATFORM = "Unix"; + $this->OS = "aix4"; + } + + // Linux + if(eregi('inux',$this->UA)) + { $this->PLATFORM = "Unix"; + $this->OS = "linux"; + } + + //Unixware + if(eregi('unix_system_v',$this->UA)) + { $this->PLATFORM = "Unix"; + $this->OS = "unixware"; + } + + //mpras + if(eregi('ncr',$this->UA)) + { $this->PLATFORM = "Unix"; + $this->OS = "mpras"; + } + + //Reliant + if(eregi('reliantunix',$this->UA)) + { $this->PLATFORM = "Unix"; + $this->OS = "reliant"; + } + + // DEC + if(eregi('dec',$this->UA) || + eregi('osfl',$this->UA) || + eregi('alphaserver',$this->UA) || + eregi('ultrix',$this->UA) || + eregi('alphastation',$this->UA)) + { $this->PLATFORM = "Unix"; + $this->OS = "dec"; + } + + // Sinix + if(eregi('sinix',$this->UA)) + { $this->PLATFORM = "Unix"; + $this->OS = "sinix"; + } + + // FreeBSD + if(eregi('freebsd',$this->UA)) + { $this->PLATFORM = "Unix"; + $this->OS = "freebsd"; + } + + // BSD + if(eregi('bsd',$this->UA)) + { $this->PLATFORM = "Unix"; + $this->OS = "bsd"; + } + + // VMS + if(eregi('vax',$this->UA) || eregi('openvms',$this->UA)) + { $this->PLATFORM = "Unix"; + $this->OS = "vms"; + } + + // SCO + if(eregi('sco',$this->UA) || eregi('unix_sv',$this->UA)) + { $this->PLATFORM = "Unix"; + $this->OS = "sco"; + } + + // Assume JavaScript Version + + // make the code a bit easier to read + $ie = eregi("ie",$this->NAME); + $ie5 = ( eregi("ie",$this->NAME) && ($this->MAJORVER >= 5) ); + $ie4 = ( eregi("ie",$this->NAME) && ($this->MAJORVER >= 4) ); + $ie3 = ( eregi("ie",$this->NAME) && ($this->MAJORVER >= 3) ); + + $nav = eregi("netscape",$this->NAME); + $nav5 = ( eregi("netscape",$this->NAME) && ($this->MAJORVER >= 5) ); + $nav4 = ( eregi("netscape",$this->NAME) && ($this->MAJORVER >= 4) ); + $nav3 = ( eregi("netscape",$this->NAME) && ($this->MAJORVER >= 3) ); + $nav2 = ( eregi("netscape",$this->NAME) && ($this->MAJORVER >= 2) ); + + $opera = eregi("opera",$this->NAME); + + // do the assumption + // update as new versions are released + + // Provide upward compatibilty + if($nav && ($this->MAJORVER > 5)) $this->JS = 1.4; + elseif($ie && ($this->MAJORVER > 5)) $this->JS = 1.3; + // check existing versions + elseif($nav5) $this->JS = 1.4; + elseif(($nav4 && ($this->VERSION > 4.05)) || $ie4) $this->JS = 1.3; + elseif(($nav4 && ($this->VERSION <= 4.05)) || $ie4) $this->JS = 1.2; + elseif($nav3 || $opera) $this->JS = 1.1; + elseif(($nav && ($this->MAJORVER >= 2)) || ($ie && ($this->MAJORVER >=3))) $this->JS = 1.0; + //no idea + else $this->JS = 0.0; + + // Grab IP Address + $this->IP = getenv('REMOTE_ADDR'); + } +} diff --git a/phpgwapi/phpgw_utilities_http.inc.php b/phpgwapi/phpgw_utilities_http.inc.php new file mode 100644 index 0000000000..d81bedeb8b --- /dev/null +++ b/phpgwapi/phpgw_utilities_http.inc.php @@ -0,0 +1,467 @@ +"01", + "Feb"=>"02", + "Mar"=>"03", + "Apr"=>"04", + "May"=>"05", + "Jun"=>"06", + "Jul"=>"07", + "Aug"=>"08", + "Sep"=>"09", + "Oct"=>"10", + "Nov"=>"11", + "Dec"=>"12"); + + /* Private methods - DO NOT CALL */ + + Function OutputDebug($message) + { + echo $message,"\n"; + } + + Function GetLine() + { + for($line="";;) + { + if(feof($this->connection) + || !($part=fgets($this->connection,100))) + return(0); + $line.=$part; + $length=strlen($line); + if($length>=2 + && substr($line,$length-2,2)=="\r\n") + { + $line=substr($line,0,$length-2); + if($this->debug) + $this->OutputDebug("< $line"); + return($line); + } + } + } + + Function PutLine($line) + { + if($this->debug) + $this->OutputDebug("> $line"); + return(fputs($this->connection,"$line\r\n")); + } + + Function PutData($data) + { + if($this->debug) + $this->OutputDebug("> $data"); + return(fputs($this->connection,$data)); + } + + Function Readbytes($length) + { + if($this->debug) + { + if(($bytes=fread($this->connection,$length))!="") + $this->OutputDebug("< $bytes"); + return($bytes); + } + else + return(fread($this->connection,$length)); + } + + Function EndOfInput() + { + return(feof($this->connection)); + } + + Function Connect($host_name,$host_port) + { + if($this->debug) + $this->OutputDebug("Connecting to $host_name..."); + if(($this->connection=fsockopen($host_name,$host_port,&$error))==0) + { + switch($error) + { + case -3: + return("-3 socket could not be created"); + case -4: + return("-4 dns lookup on hostname \"".$host_name."\" failed"); + case -5: + return("-5 connection refused or timed out"); + case -6: + return("-6 fdopen() call failed"); + case -7: + return("-7 setvbuf() call failed"); + default: + return($error." could not connect to the host \"".$host_name."\""); + } + } + else + { + if($this->debug) + $this->OutputDebug("Connected to $host_name"); + $this->state="Connected"; + return(""); + } + } + + Function Disconnect() + { + if($this->debug) + $this->OutputDebug("Disconnected from ".$this->host_name); + fclose($this->connection); + return(""); + } + + /* Public methods */ + + Function Open($arguments) + { + if($this->state!="Disconnected") + return("1 already connected"); + if(IsSet($arguments["HostName"])) + $this->host_name=$arguments["HostName"]; + if(IsSet($arguments["HostPort"])) + $this->host_port=$arguments["HostPort"]; + if(IsSet($arguments["ProxyHostName"])) + $this->proxy_host_name=$arguments["ProxyHostName"]; + if(IsSet($arguments["ProxyHostPort"])) + $this->proxy_host_port=$arguments["ProxyHostPort"]; + if(strlen($this->proxy_host_name)==0) + { + if(strlen($this->host_name)==0) + return("2 it was not specified a valid hostname"); + $host_name=$this->host_name; + $host_port=$this->host_port; + } + else + { + $host_name=$this->proxy_host_name; + $host_port=$this->proxy_host_port; + } + $error=$this->Connect($host_name,$host_port); + if(strlen($error)==0) + $this->state="Connected"; + return($error); + } + + Function Close() + { + if($this->state=="Disconnected") + return("1 already disconnected"); + $error=$this->Disconnect(); + if(strlen($error)==0) + $this->state="Disconnected"; + return($error); + } + + Function SendRequest($arguments) + { + switch($this->state) + { + case "Disconnected": + return("1 connection was not yet established"); + case "Connected": + break; + default: + return("2 can not send request in the current connection state"); + } + if(IsSet($arguments["RequestMethod"])) + $this->request_method=$arguments["RequestMethod"]; + if(IsSet($arguments["User-Agent"])) + $this->user_agent=$arguments["User-Agent"]; + if(strlen($this->request_method)==0) + return("3 it was not specified a valid request method"); + if(IsSet($arguments["RequestURI"])) + $this->request_uri=$arguments["RequestURI"]; + if(strlen($this->request_uri)==0 + || substr($this->request_uri,0,1)!="/") + return("4 it was not specified a valid request URI"); + $request_body=""; + $headers=(IsSet($arguments["Headers"]) ? $arguments["Headers"] : array()); + if($this->request_method=="POST") + { + if(IsSet($arguments["PostValues"])) + { + $values=$arguments["PostValues"]; + if(GetType($values)!="array") + return("5 it was not specified a valid POST method values array"); + for($request_body="",Reset($values),$value=0;$value0) + $request_body.="&"; + $request_body.=Key($values)."=".UrlEncode($values[Key($values)]); + } + $headers["Content-type"]="application/x-www-form-urlencoded"; + } + } + if(strlen($this->proxy_host_name)==0) + $request_uri=$this->request_uri; + else + $request_uri="http://".$this->host_name.($this->host_port==80 ? "" : ":".$this->host_port).$this->request_uri; + if(($success=$this->PutLine($this->request_method." ".$request_uri." HTTP/".$this->protocol_version))) + { + if(($body_length=strlen($request_body))) + $headers["Content-length"]=$body_length; + for($host_set=0,Reset($headers),$header=0;$headerPutLine("$header_name: ".$header_value[Key($header_value)])) + break 2; + } + } + else + { + if(!$success=$this->PutLine("$header_name: $header_value")) + break; + } + if(strtolower(Key($headers))=="host") + { + $this->request_host=strtolower($header_value); + $host_set=1; + } + } + if($success) + { + if(!$host_set) + { + $success=$this->PutLine("Host: ".$this->host_name); + $this->request_host=strtolower($this->host_name); + } + if(count($this->cookies) + && IsSet($this->cookies[0])) + { + $now=gmdate("Y-m-d H-i-s"); + for($cookies=array(),$domain=0,Reset($this->cookies[0]);$domaincookies[0]);Next($this->cookies[0]),$domain++) + { + $domain_pattern=Key($this->cookies[0]); + $match=strlen($this->request_host)-strlen($domain_pattern); + if($match>=0 + && !strcmp($domain_pattern,substr($this->request_host,$match)) + && ($match==0 + || $domain_pattern[0]=="." + || $this->request_host[$match-1]==".")) + { + for(Reset($this->cookies[0][$domain_pattern]),$path_part=0;$path_partcookies[0][$domain_pattern]);Next($this->cookies[0][$domain_pattern]),$path_part++) + { + $path=Key($this->cookies[0][$domain_pattern]); + if(strlen($this->request_uri)>=strlen($path) + && substr($this->request_uri,0,strlen($path))==$path) + { + for(Reset($this->cookies[0][$domain_pattern][$path]),$cookie=0;$cookiecookies[0][$domain_pattern][$path]);Next($this->cookies[0][$domain_pattern][$path]),$cookie++) + { + $cookie_name=Key($this->cookies[0][$domain_pattern][$path]); + $expires=$this->cookies[0][$domain_pattern][$path][$cookie_name]["expires"]; + if($expires=="" + || strcmp($now,$expires)<0) + $cookies[$cookie_name]=$this->cookies[0][$domain_pattern][$path][$cookie_name]; + } + } + } + } + } + for(Reset($cookies),$cookie=0;$cookiePutLine("Cookie: ".UrlEncode($cookie_name)."=".$cookies[$cookie_name]["value"].";"))) + break; + } + } + if($success) + { + if($success) + { + $success=$this->PutLine(""); + if($body_length + && $success) + $success=$this->PutData($request_body); + } + } + } + } + if(!$success) + return("5 could not send the HTTP request"); + $this->state="RequestSent"; + return(""); + } + + Function ReadReplyHeaders(&$headers) + { + switch($this->state) + { + case "Disconnected": + return("1 connection was not yet established"); + case "Connected": + return("2 request was not sent"); + case "RequestSent": + break; + default: + return("3 can not get request headers in the current connection state"); + } + $headers=array(); + $this->content_length=$this->read_length=0; + $this->content_length_set=0; + for(;;) + { + $line=$this->GetLine(); + if(GetType($line)!="string") + return("4 could not read request reply"); + if($line=="") + { + $this->state="GotReplyHeaders"; + return(""); + } + $header_name=strtolower(strtok($line,":")); + $header_value=Trim(Chop(strtok("\r\n"))); + if(IsSet($headers[$header_name])) + { + if(GetType($headers[$header_name])=="string") + $headers[$header_name]=array($headers[$header_name]); + $headers[$header_name][]=$header_value; + } + else + $headers[$header_name]=$header_value; + switch($header_name) + { + case "content-length": + $this->content_length=intval($headers[$header_name]); + $this->content_length_set=1; + break; + case "set-cookie": + if($this->support_cookies) + { + $cookie_name=trim(strtok($headers[$header_name],"=")); + $cookie_value=strtok(";"); + $domain=$this->request_host; + $path="/"; + $expires=""; + $secure=0; + while(($name=strtolower(trim(strtok("="))))!="") + { + $value=UrlDecode(strtok(";")); + switch($name) + { + case "domain": + if($value=="" + || !strpos($value,".",$value[0]==".")) + break; + $domain=strtolower($value); + break; + case "path": + if($value!="" + && $value[0]=="/") + $path=$value; + break; + case "expires": + if(ereg("^((Mon|Monday|Tue|Tuesday|Wed|Wednesday|Thu|Thursday|Fri|Friday|Sat|Saturday|Sun|Sunday), )?([0-9]{2})\\-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\\-([0-9]{2,4}) ([0-9]{2})\\:([0-9]{2})\\:([0-9]{2}) GMT$",$value,$matches)) + { + $year=intval($matches[5]); + if($year<1900) + $year+=($year<70 ? 2000 : 1900); + $expires="$year-".$this->months[$matches[4]]."-".$matches[3]." ".$matches[6].":".$matches[7].":".$matches[8]; + } + break; + case "secure": + $secure=1; + break; + } + } + $this->cookies[$secure][$domain][$path][$cookie_name]=array( + "name"=>$cookie_name, + "value"=>$cookie_value, + "domain"=>$domain, + "path"=>$path, + "expires"=>$expires, + "secure"=>$secure + ); + } + } + } + } + + Function ReadReplyBody(&$body,$length) + { + switch($this->state) + { + case "Disconnected": + return("1 connection was not yet established"); + case "Connected": + return("2 request was not sent"); + case "RequestSent": + if(($error=$this->ReadReplyHeaders(&$headers))!="") + return($error); + break; + case "GotReplyHeaders": + break; + default: + return("3 can not get request headers in the current connection state"); + } + $body=""; + if($this->content_length_set) + $length=min($this->content_length-$this->read_length,$length); + if($length>0 + && !$this->EndOfInput() + && ($body=$this->ReadBytes($length))=="") + return("4 could not get the request reply body"); + return(""); + } + + Function GetPersistentCookies(&$cookies) + { + $now=gmdate("Y-m-d H-i-s"); + $cookies=array(); + for($secure_cookies=0,Reset($this->cookies);$secure_cookiescookies);Next($this->cookies),$secure_cookies++) + { + $secure=Key($this->cookies); + for($domain=0,Reset($this->cookies[$secure]);$domaincookies[$secure]);Next($this->cookies[$secure]),$domain++) + { + $domain_pattern=Key($this->cookies[$secure]); + for(Reset($this->cookies[$secure][$domain_pattern]),$path_part=0;$path_partcookies[$secure][$domain_pattern]);Next($this->cookies[$secure][$domain_pattern]),$path_part++) + { + $path=Key($this->cookies[$secure][$domain_pattern]); + for(Reset($this->cookies[$secure][$domain_pattern][$path]),$cookie=0;$cookiecookies[$secure][$domain_pattern][$path]);Next($this->cookies[$secure][$domain_pattern][$path]),$cookie++) + { + $cookie_name=Key($this->cookies[$secure][$domain_pattern][$path]); + $expires=$this->cookies[$secure][$domain_pattern][$path][$cookie_name]["expires"]; + if($expires!="" + && strcmp($now,$expires)<0) + $cookies[$secure][$domain_pattern][$path][$cookie_name]=$this->cookies[$secure][$domain_pattern][$path][$cookie_name]; + } + } + } + } + } + +}; + diff --git a/phpgwapi/phpgw_utilities_matrixview.inc.php b/phpgwapi/phpgw_utilities_matrixview.inc.php new file mode 100644 index 0000000000..c1c5b4f35c --- /dev/null +++ b/phpgwapi/phpgw_utilities_matrixview.inc.php @@ -0,0 +1,304 @@ +month = $month_int; + $this->year = $year_int; + } + + /** + * + * set a Period for a specified item + * + * setting a period for an element means to define + * a fromDate and and a toDate together with the + * item itself. This will store a timeframe associated + * with an item for later usage + * + * @param string item for the timeframe + * @param date fromdate in format yyyymmdd + * @param date todate in format yyyymmdd + * + * @return boolean false if item cannot be saved + * otherwise true + */ + + function setPeriod ($item, $fromdate, $todate, $color="#990033") + { + $fyear = substr($fromdate,0,4); + $fmonth = substr($fromdate,4,2); + $fday = substr($fromdate,6,2); + + $tyear = substr($todate,0,4); + $tmonth = substr($todate,4,2); + $tday = substr($todate,6,2); + + if(mktime(0,0,0, $tmonth, $tday, $tyear) < mktime(0,0,0, $this->month+1,0,$this->year)) + $this->day = $tday; + else + { + $dinfo = getdate(mktime(0,0,0, $this->month+1,0,$this->year)); + $this->day = $dinfo[mday]; + } + + $go = 1; + $i = 0; + $z = 0; + + while($go==1) + { + // calculates fromdate + // echo date("d/m/Y", mktime(0,0,0, $fmonth, $fday+$i, $fyear)); echo "
"; + $datinfo = getdate(mktime(0,0,0, $fmonth, $fday+$i, $fyear)); + + if($datinfo["mon"]==$this->month + && $datinfo["year"]==$this->year + && $datinfo["mday"]<=$this->day) + { + $t = $datinfo["mday"]; + $this->items_content[$this->items_count][$t] = "x"; + } + + if (mktime(0,0,0, $fmonth, $fday+$i, $fyear) >= + mktime(0,0,0, $this->month+1, 0, $this->year) + || + mktime(0,0,0, $fmonth, $fday+$i, $fyear) >= + mktime(0,0,0, $tmonth, $tday, $tyear)) $go = 0 + ; + $i++; + } + + $this->items_content[$this->items_count][0] = "$item;$color"; + // increase number of items in two-dimensional array + $this->items_count++; +} + +/** +* +* sets the color for empty dayfields +* +* @param string color in hexadecimal (ex. "#336699") +*/ + +function setEmptyFieldColor ($color) +{ + $this->color_emptyfield=$color; +} + +/** +* +* sets the color for calendar day fields +* +* @param string color in hexadecimal (ex. "#336699") +*/ + +function setHeaderFieldColor ($color) +{ + $this->color_headerfield=$color; +} + +/** +* +* sets a new path for 1pixel (pix.gif) gif needed for the table +* default is set actual script dir + /images +* +* @param string path and name to 1pixel gif +*/ + +function set1PixelGif ($filepath) +{ + $this->image1pix=$filepath; +} + +/** +* +* disable selection of new timeframe +* +*/ + +function diableSelection () +{ + $this->selection=0; +} + +/** +* +* return the html code for the matrix +* +* will return the complete html code for the matrix. +* In the calling program you can do some other +* operations on it, because it wont be echoed directly +* +* @return string html code for the matrix +*/ + +function out () +{ + // get days of desired month (month submitted in constructor) + $in = getdate(mktime(0,0,0, $this->month+1,0,$this->year)); + $this->sumdays = $in[mday]; + $this->monthname = $in[month]; + + $this->out_monthyear(); + + echo "
\n"; + echo "\n"; + $this->out_header(); + + // loop through number of items + for($z=0;$z<$this->items_count;$z++) + { + // seperate color and name from first array element + $itemname = strtok($this->items_content[$z][0],";"); + $itemcolor = strtok(";"); + + echo "\n"; + echo "\n"; + // loop through days of desired month + for($r=1;$r<$this->sumdays+1;$r++) + { + if($this->items_content[$z][$r]=="x") $color = $itemcolor; else $color = $this->color_emptyfield; + echo "\n"; + } + echo "\n"; + $this->out_ruler(); + } + echo "
" . $itemname . " 
"; + echo "
\n"; +} + +/** +* +* private class for out method +* +* should not be used from external +* +*/ + +function out_header () +{ + echo "\n"; + echo "sumdays+1; echo "\" bgcolor=black>image1pix . "\">\n"; + echo "\n"; + echo "\n"; + echo "Projectname\n"; + for($i=1;$i<$this->sumdays+1;$i++) + { + echo "color_headerfield; echo "\">" . sprintf("%02d",$i) . "\n"; + } + echo "\n"; + + echo "\n"; + echo "sumdays+1; echo "\" bgcolor=black>image1pix ."\">\n"; + echo "\n"; +} + +/** +* +* private class for out method +* +* should not be used from external +* +*/ + +function out_ruler () +{ + echo "\n"; + echo "sumdays+1; echo "\" bgcolor=\"#999999\">image1pix ."\">\n"; + echo "\n"; +} + +/** +* +* private class for out method +* +* should not be used from external +* +*/ + +function out_monthyear () +{ + global $phpgw; + + echo "
link() . "\" method=\"post\">\n"; + echo ""; + echo "\n"; + echo "\n"; + + if($this->selection==1) + { + echo "\n"; + } + + echo "\n"; + echo "

"; echo $this->monthname; echo " "; echo $this->year; echo "

Month: "; + echo "Year: "; + echo "  "; + echo "
\n"; + echo "
\n"; +} + +} +?> diff --git a/phpgwapi/phpgw_utilities_menutree.inc.php b/phpgwapi/phpgw_utilities_menutree.inc.php new file mode 100644 index 0000000000..0448a243bb --- /dev/null +++ b/phpgwapi/phpgw_utilities_menutree.inc.php @@ -0,0 +1,310 @@ + * + * -------------------------------------------- * + * This program is free software; you can redistribute it and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; either version 2 of the License, or (at your * + * option) any later version. * + \**************************************************************************/ + + /* $Id$ */ + + /*********************************************/ + /* Settings */ + /*********************************************/ + /* */ + /* $treefile variable needs to be set in */ + /* main file */ + /* */ + /*********************************************/ + +class menutree { + function showtree($treefile, $num_menus = 50, $invisible_menus = Null){ + global $phpgw_info; + + $script = $SCRIPT_NAME; + + $img_expand = "images/tree_expand.gif"; + $img_collapse = "images/tree_collapse.gif"; + $img_line = "images/tree_vertline.gif"; + $img_split = "images/tree_split.gif"; + $img_end = "images/tree_end.gif"; + $img_leaf = "images/tree_leaf.gif"; + $img_spc = "images/tree_space.gif"; + + /*********************************************/ + /* Read text file with tree structure */ + /*********************************************/ + + /*********************************************/ + /* read file to $tree array */ + /* tree[x][0] -> tree level */ + /* tree[x][1] -> item text */ + /* tree[x][2] -> item link */ + /* tree[x][3] -> link target */ + /* tree[x][4] -> last item in subtree */ + /*********************************************/ + + $maxlevel=0; + $cnt=0; + + $fd = fopen($treefile, "r"); + if ($fd==0) die("menutree.inc : Unable to open file ".$treefile); + while ($buffer = fgets($fd, 4096)) + { + $tree[$cnt][0]=strspn($buffer,"."); + $tmp=rtrim(substr($buffer,$tree[$cnt][0])); + $node=explode("|",$tmp); + $tree[$cnt][1]=$node[0]; + $tree[$cnt][2]=$node[1]; + $tree[$cnt][3]=$node[2]; + $tree[$cnt][4]=0; + if ($tree[$cnt][0] > $maxlevel) $maxlevel=$tree[$cnt][0]; + $cnt++; + } + fclose($fd); + + for ($i=0; $i=0; $i--) + { + if ( $tree[$i][0] < $lastlevel ) + { + for ($j=$tree[$i][0]+1; $j <= $maxlevel; $j++) + { + $levels[$j]=0; + } + } + if ( $levels[$tree[$i][0]]==0 ) + { + $levels[$tree[$i][0]]=1; + $tree[$i][4]=1; + } + else + $tree[$i][4]=0; + $lastlevel=$tree[$i][0]; + } + + + /*********************************************/ + /* Determine visible nodes */ + /*********************************************/ + + + + $visible[0]=1; // root is always visible + $visible[1]=1; // root is always visible + $visible[2]=1; // root is always visible + $visible[3]=0; // root is always visible + $visible[4]=0; // root is always visible + $visible[5]=0; // root is always visible + $visible[6]=0; // root is always visible + $visible[7]=1; // root is always visible + $visible[8]=0; // root is always visible + $visible[9]=0; // root is always visible + $visible[10]=0; // root is always visible + $visible[11]=1; // root is always visible + $visible[12]=0; // root is always visible + $visible[13]=0; // root is always visible + $visible[14]=0; // root is always visible + $visible[15]=0; // root is always visible + $visible[16]=1; // root is always visible + $visible[17]=1; // root is always visible + $visible[18]=1; // root is always visible + $visible[19]=1; // root is always visible + $visible[20]=1; // root is always visible + $visible[21]=0; // root is always visible + $visible[22]=0; // root is always visible + $visible[23]=1; // root is always visible + $visible[24]=0; // root is always visible + $visible[25]=0; // root is always visible + $visible[26]=1; // root is always visible + $visible[27]=0; // root is always visible + $visible[28]=0; // root is always visible + + + for ($i=0; $i $tree[$n][0] ) + { + if ($tree[$j][0]==$tree[$n][0]+1) $visible[$j]=1; + $j++; + } + } + } + + + for ($i=0; $i $tree[$n][0] ) + { + if ($tree[$j][0]==$tree[$n][0]+1) $visible[$j]=1; + $j++; + } + } + } + + + /*********************************************/ + /* Output nicely formatted tree */ + /*********************************************/ + + for ($i=0; $i<$maxlevel; $i++) $levels[$i]=1; + + $maxlevel++; + + echo "\n"; + echo"\n"; + echo ""; + for ($i=0; $i<$maxlevel; $i++) echo ""; + echo "\n"; + $cnt=0; + while ($cnt"; + + /****************************************/ + /* vertical lines from higher levels */ + /****************************************/ + $i=0; + while ($i<$tree[$cnt][0]-1) + { + if ($levels[$i]==1) + echo ""; + else + echo ""; + $i++; + } + + /****************************************/ + /* corner at end of subtree or t-split */ + /****************************************/ + if ($tree[$cnt][4]==1) + { + echo ""; + $levels[$tree[$cnt][0]-1]=0; + } + else + { + echo ""; + $levels[$tree[$cnt][0]-1]=1; + } + + /********************************************/ + /* Node (with subtree) or Leaf (no subtree) */ + /********************************************/ + if ($tree[$cnt+1][0]>$tree[$cnt][0]) + { + + /****************************************/ + /* Create expand/collapse parameters */ + /****************************************/ + $i=0; $params="?p="; + while($i"; + else + echo ""; + } + else + { + /*************************/ + /* Tree Leaf */ + /*************************/ + + echo ""; + } + + /****************************************/ + /* output item text */ + /****************************************/ + if ($tree[$cnt][2]=="") + echo ""; + else + echo ""; + + /****************************************/ + /* end row */ + /****************************************/ + + echo "\n"; + } + $cnt++; + } + echo "
".$tree[$cnt][1]."".$tree[$cnt][1]."
\n"; + + /***************************************************/ + /* Tree file format */ + /* */ + /* */ + /* The first line is always of format : */ + /* .[rootname] */ + /* */ + /* each line contains one item, the line starts */ + /* with a series of dots(.). Each dot is one level */ + /* deeper. Only one level at a time once is allowed*/ + /* Next comes the come the item name, link and */ + /* link target, seperated by a |. */ + /* */ + /* example: */ + /* */ + /* .top */ + /* ..category 1 */ + /* ...item 1.1|item11.htm|main */ + /* ...item 2.2|item12.htm|main */ + /* ..category 2|cat2overview.htm|main */ + /* ...item 2.1|item21.htm|main */ + /* ...item 2.2|item22.htm|main */ + /* ...item 2.3|item23.htm|main */ + /* */ + /***************************************************/ + } +} diff --git a/phpgwapi/phpgw_utilities_rssparse.inc.php b/phpgwapi/phpgw_utilities_rssparse.inc.php new file mode 100644 index 0000000000..a2b3ad3d7c --- /dev/null +++ b/phpgwapi/phpgw_utilities_rssparse.inc.php @@ -0,0 +1,237 @@ +items)) { + * printf("Title: %s\n", $item["title"]); + * printf("Link: %s\n", $item["link"]); + * printf("Description: %s\n", $item["desc"]); + * } + * + * printf("Channel Title: %s\n", $rss->title); + * printf("Channel Description: %s\n", $rss->desc); + * printf("Channel Link: %s\n", $rss->link); + * + * printf("Image Title: %s\n", $rss->image["title"]); + * printf("Image URL: %s\n", $rss->image["url"]); + * printf("Image Description: %s\n", $rss->image["desc"]); + * printf("Image Link: %s\n", $rss->image["link"]); + * + * + * CHANGES: + * 0.4 - rssparse.php3 now supports the channel image tag and correctly supports + * RSS-style channels. + * + * + * BUGS: + * Width and height tags in image not supported, some other tags not supported + * yet. + * + * + * IMPORTANT NOTE: + * This requires PHP's XML routines. You must configure PHP with --with-xml. + */ + + /* $Id$ */ + +function _rssparse_start_elem ($parser, $elem, $attrs) { + global $_rss; + + if ($elem == "CHANNEL") { + $_rss->depth++; + $_rss->state[$_rss->depth] = "channel"; + $_rss->tmptitle[$_rss->depth] = ""; + $_rss->tmplink[$_rss->depth] = ""; + $_rss->tmpdesc[$_rss->depth] = ""; + } + else if ($elem == "IMAGE") { + $_rss->depth++; + $_rss->state[$_rss->depth] = "image"; + $_rss->tmptitle[$_rss->depth] = ""; + $_rss->tmplink[$_rss->depth] = ""; + $_rss->tmpdesc[$_rss->depth] = ""; + $_rss->tmpurl[$_rss->depth] = ""; + } + else if ($elem == "ITEM") { + $_rss->depth++; + $_rss->state[$_rss->depth] = "item"; + $_rss->tmptitle[$_rss->depth] = ""; + $_rss->tmplink[$_rss->depth] = ""; + $_rss->tmpdesc[$_rss->depth] = ""; + } + else if ($elem == "TITLE") { + $_rss->depth++; + $_rss->state[$_rss->depth] = "title"; + } + else if ($elem == "LINK") { + $_rss->depth++; + $_rss->state[$_rss->depth] = "link"; + } + else if ($elem == "DESCRIPTION") { + $_rss->depth++; + $_rss->state[$_rss->depth] = "desc"; + } + else if ($elem == "URL") { + $_rss->depth++; + $_rss->state[$_rss->depth] = "url"; + } +} + +function _rssparse_end_elem ($parser, $elem) { + global $_rss; + + if ($elem == "CHANNEL") { + $_rss->set_channel($_rss->tmptitle[$_rss->depth], $_rss->tmplink[$_rss->depth], $_rss->tmpdesc[$_rss->depth]); + $_rss->depth--; + } + else if ($elem == "IMAGE") { + $_rss->set_image($_rss->tmptitle[$_rss->depth], $_rss->tmplink[$_rss->depth], $_rss->tmpdesc[$_rss->depth], $_rss->tmpurl[$_rss->depth]); + $_rss->depth--; + } + else if ($elem == "ITEM") { + $_rss->add_item($_rss->tmptitle[$_rss->depth], $_rss->tmplink[$_rss->depth], $_rss->tmpdesc[$_rss->depth]); + $_rss->depth--; + } + else if ($elem == "TITLE") { + $_rss->depth--; + } + else if ($elem == "LINK") { + $_rss->depth--; + } + else if ($elem == "DESCRIPTION") { + $_rss->depth--; + } + else if ($elem == "URL") { + $_rss->depth--; + } +} + +function _rssparse_elem_data ($parser, $data) { + global $_rss; + + if ($_rss->state[$_rss->depth] == "title") { + $_rss->tmptitle[($_rss->depth - 1)] .= $data; + } + else if ($_rss->state[$_rss->depth] == "link") { + $_rss->tmplink[($_rss->depth - 1)] .= $data; + } + else if ($_rss->state[$_rss->depth] == "desc") { + $_rss->tmpdesc[($_rss->depth - 1)] .= $data; + } + else if ($_rss->state[$_rss->depth] == "url") { + $_rss->tmpurl[($_rss->depth - 1)] .= $data; + } +} + +class rssparser { + var $title; + var $link; + var $desc; + var $items = array(); + var $nitems; + var $image = array(); + var $state = array(); + var $tmptitle = array(); + var $tmplink = array(); + var $tmpdesc = array(); + var $tmpurl = array(); + var $depth; + + function rssparser() { + $this->nitems = 0; + $this->depth = 0; + } + + function set_channel($in_title, $in_link, $in_desc) { + $this->title = $in_title; + $this->link = $in_link; + $this->desc = $in_desc; + } + + function set_image($in_title, $in_link, $in_desc, $in_url) { + $this->image["title"] = $in_title; + $this->image["link"] = $in_link; + $this->image["desc"] = $in_desc; + $this->image["url"] = $in_url; + } + + function add_item($in_title, $in_link, $in_desc) { + $this->items[$this->nitems]["title"] = $in_title; + $this->items[$this->nitems]["link"] = $in_link; + $this->items[$this->nitems]["desc"] = $in_desc; + $this->nitems++; + } + + function parse($fp) { + $xml_parser = xml_parser_create(); + + xml_set_element_handler($xml_parser, "_rssparse_start_elem", "_rssparse_end_elem"); + xml_set_character_data_handler($xml_parser, "_rssparse_elem_data"); + + while ($data = fread($fp, 4096)) { + if (!xml_parse($xml_parser, $data, feof($fp))) { + return 1; + } + } + + xml_parser_free($xml_parser); + + return 0; + } +} + +function rssparse ($fp) { + global $_rss; + + $_rss = new rssparser(); + + if ($_rss->parse($fp)) { + return 0; + } + + return $_rss; +} + + diff --git a/phpgwapi/phpgw_utilities_sbox.inc.php b/phpgwapi/phpgw_utilities_sbox.inc.php new file mode 100644 index 0000000000..75a13d650b --- /dev/null +++ b/phpgwapi/phpgw_utilities_sbox.inc.php @@ -0,0 +1,141 @@ +\n"; + + for($i=0;$imonthnames);$i++) + { + $out .= "\n"; + } + $out .= "\n"; + return $out; + } + + function getDays($name, $selected=0) + { + $out = "\n"; + + for(reset($arr);current($arr);next($arr)) + { + $out .= '