' . lang("error") . ': | ' . $error[0] . ' |
'; + } + + $output_text .= ' | ' . $fs . $tab[1]["label"] + . $fse . ' | '; + if ($i == count($tabs)) { + $output_text .= ''; + } else { + $output_text .= ' | '; + } + } else { + if ($i == 1) { + $output_text .= ' | '; + } + $output_text .= ' | ' . $fs . $tab[1]["label"] . $fse + . ' | '; + 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 .= " |
"
+ . 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(); + } + + } diff --git a/phpgwapi/inc/class.crypto.inc.php b/phpgwapi/inc/class.crypto.inc.php new file mode 100644 index 0000000000..0572a7999d --- /dev/null +++ b/phpgwapi/inc/class.crypto.inc.php @@ -0,0 +1,122 @@ +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"]["versions"]["mcrypt"] != "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"]["versions"]["mcrypt"] != "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"]["versions"]["mcrypt"]) { + // 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"]["versions"]["mcrypt"]) { + // 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/inc/class.db.inc.php b/phpgwapi/inc/class.db.inc.php new file mode 100644 index 0000000000..bc220709fc --- /dev/null +++ b/phpgwapi/inc/class.db.inc.php @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/phpgwapi/inc/class.db_msql.inc.php b/phpgwapi/inc/class.db_msql.inc.php new file mode 100644 index 0000000000..924bb789d2 --- /dev/null +++ b/phpgwapi/inc/class.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
Session halted.";
+ $phpgw->common->phpgw_exit(True);
+ }
+ }
+
+ function haltmsg($msg)
+ {
+ printf("Database error: %s ";
+ ora_commiton($this->Link_ID);
+ }
+ if($this->Debug) {
+ printf(" Session halted.";
+ $phpgw->common->phpgw_exit(True);
+ }
+ }
+
+ 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/inc/class.db_sybase.inc.php b/phpgwapi/inc/class.db_sybase.inc.php
new file mode 100644
index 0000000000..7a15412ea0
--- /dev/null
+++ b/phpgwapi/inc/class.db_sybase.inc.php
@@ -0,0 +1,133 @@
+
+ *
+ * metadata() contributed by Adelino Monteiro
\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/inc/class.db_odbc.inc.php b/phpgwapi/inc/class.db_odbc.inc.php
new file mode 100644
index 0000000000..dd3518ca60
--- /dev/null
+++ b/phpgwapi/inc/class.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[
");
+
+ # 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/inc/class.db_oracle.inc.php b/phpgwapi/inc/class.db_oracle.inc.php
new file mode 100644
index 0000000000..833259ed39
--- /dev/null
+++ b/phpgwapi/inc/class.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
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;$ix
\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/inc/class.db_pgsql.inc.php b/phpgwapi/inc/class.db_pgsql.inc.php
new file mode 100644
index 0000000000..2c93a70cb0
--- /dev/null
+++ b/phpgwapi/inc/class.db_pgsql.inc.php
@@ -0,0 +1,271 @@
+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,$strip_slashes = "")
+ {
+ if ($strip_slashes || ($this->auto_stripslashes && ! $strip_slashes)) {
+ return stripslashes($this->Record[$Name]);
+ } else {
+ return $this->Record[$Name];
+ }
+ }
+
+ function p($Name) {
+ print $this->Record[$Name];
+ }
+
+ function halt($msg, $line = "", $file = "")
+ {
+ global $phpgw;
+
+ 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") {
+ echo "
\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/inc/class.hooks.inc.php b/phpgwapi/inc/class.hooks.inc.php
new file mode 100644
index 0000000000..27d09c9b68
--- /dev/null
+++ b/phpgwapi/inc/class.hooks.inc.php
@@ -0,0 +1,75 @@
+\n";
+ exit;
+ } unset($d1);unset($d2);unset($d3);
+
+ 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/inc/class.network.inc.php b/phpgwapi/inc/class.network.inc.php
new file mode 100644
index 0000000000..70f4bb58b6
--- /dev/null
+++ b/phpgwapi/inc/class.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/inc/class.nextmatchs.inc.php b/phpgwapi/inc/class.nextmatchs.inc.php
new file mode 100644
index 0000000000..df97f870ed
--- /dev/null
+++ b/phpgwapi/inc/class.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 = "";
+ 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 = ""
+ . " ";
+
+ 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 .= "\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 .= " ";
+
+ 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/inc/class.phpgw.inc.php b/phpgwapi/inc/class.phpgw.inc.php
new file mode 100644
index 0000000000..aae80f2718
--- /dev/null
+++ b/phpgwapi/inc/class.phpgw.inc.php
@@ -0,0 +1,245 @@
+ *
+ * -------------------------------------------- *
+ * 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$ */
+
+ /****************************************************************************\
+ * Required classes *
+ \****************************************************************************/
+ /* Load selected database class */
+ if (empty($phpgw_info["server"]["db_type"])){$phpgw_info["server"]["db_type"] = "mysql";}
+ if (empty($phpgw_info["server"]["translation_system"])){$phpgw_info["server"]["translation_system"] = "sql";}
+
+ /****************************************************************************\
+ * Our API class starts here *
+ \****************************************************************************/
+ class phpgw
+ {
+ var $accounts;
+ var $acl;
+ var $auth;
+ var $db;
+ var $debug = 0; // This will turn on debugging information.
+ var $crypto;
+ var $categories;
+ var $common;
+ var $hooks;
+ var $network;
+ var $nextmatchs;
+ var $preferences;
+ var $session;
+ var $send;
+ var $template;
+ var $translation;
+ var $utilities;
+ var $vfs;
+ var $calendar;
+ var $msg;
+ var $addressbook;
+ var $todo;
+
+ // 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, $login;
+ /************************************************************************\
+ * Required classes *
+ \************************************************************************/
+ $this->db = CreateObject("phpgwapi.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");
+ }
+ } else {
+ $config_var = array("encryptkey","auth_type","account_repository");
+ $c= "";
+ for ($i=0;$iPlease 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);
+ }
+ }
+
diff --git a/phpgwapi/inc/class.phpgw.inc.php-bak b/phpgwapi/inc/class.phpgw.inc.php-bak
new file mode 100644
index 0000000000..34470e718c
--- /dev/null
+++ b/phpgwapi/inc/class.phpgw.inc.php-bak
@@ -0,0 +1,258 @@
+ *
+ * -------------------------------------------- *
+ * 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$ */
+
+ /****************************************************************************\
+ * Required classes *
+ \****************************************************************************/
+ /* Load selected database class */
+ if (empty($phpgw_info["server"]["db_type"])){$phpgw_info["server"]["db_type"] = "mysql";}
+ include($phpgw_info["server"]["api_inc"] . "/phpgw_db_".$phpgw_info["server"]["db_type"].".inc.php");
+
+ include($phpgw_info["server"]["api_inc"] . "/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_inc"] . "/phpgw_lang_".$phpgw_info["server"]["translation_system"].".inc.php");
+
+ include($phpgw_info["server"]["api_inc"] . "/phpgw_crypto.inc.php");
+ include($phpgw_info["server"]["api_inc"] . "/phpgw_template.inc.php");
+ include($phpgw_info["server"]["api_inc"] . "/phpgw_common.inc.php");
+
+ /****************************************************************************\
+ * Our API class starts here *
+ \****************************************************************************/
+ class phpgw
+ {
+ var $accounts;
+ var $acl;
+ var $auth;
+ var $db;
+ var $debug = 0; // This will turn on debugging information.
+ // (Not fully working)
+ var $crypto;
+ var $categories;
+ var $common;
+ var $hooks;
+ var $network;
+ var $nextmatchs;
+ var $preferences;
+ var $session;
+ var $send;
+ var $template;
+ var $translation;
+ var $utilities;
+ var $vfs;
+
+ var $calendar;
+ var $msg;
+
+ var $addressbook;
+ var $todo;
+
+ // 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, $login;
+ /************************************************************************\
+ * 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");
+ }
+ } else {
+ $config_var = array("encryptkey","auth_type","account_repository");
+ $c= "";
+ for ($i=0;$iPlease 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);
+ }
+ }
+
diff --git a/phpgwapi/inc/class.preferences.inc.php b/phpgwapi/inc/class.preferences.inc.php
new file mode 100644
index 0000000000..3b915ac8d9
--- /dev/null
+++ b/phpgwapi/inc/class.preferences.inc.php
@@ -0,0 +1,113 @@
+\n";
+
+
+ $db2 = $phpgw->db;
+ $load_pref = True;
+ if (is_long($account_id) && $account_id) {
+ $this->account_id = $account_id;
+ } elseif(is_string($account_id)) {
+ $db2->query("SELECT account_id FROM accounts WHERE account_lid='".$account_id."'",__LINE__,__FILE__);
+ if($db2->num_rows()) {
+ $db2->next_record();
+ $this->account_id = $db2->f("account_id");
+ } else {
+ $load_pref = False;
+ }
+ } else {
+ $load_pref = False;
+ }
+
+//echo "Load Pref = $load_pref
\n";
+//echo "Account ID (After Initializing) = ".$this->account_id."
\n";
+
+ if ($load_pref) {
+ $db2->query("SELECT preference_value FROM preferences WHERE preference_owner=".$this->account_id,__LINE__,__FILE__);
+ $db2->next_record();
+ $pref_info = $db2->f("preference_value");
+ $this->preference = unserialize($pref_info);
+// echo "Preferences = ".$this->get_preferences()."
\n";
+ }
+ }
+
+ // This should be called when you are done makeing changes to the preferences
+ function commit($line = "",$file = "")
+ {
+ global $phpgw, $phpgw_info;
+
+ //echo "
commit called
Line: $line
File: $file".$phpgw_info["user"]["account_id"]."
";
+ if ($this->account_id) {
+ $db = $phpgw->db;
+
+ $db->query("delete from preferences where preference_owner=" . $this->account_id,__LINE__,__FILE__);
+
+ if ($PHP_VERSION < "4.0.0") {
+ $pref_info = addslashes(serialize($this->preference));
+ } else {
+ $pref_info = serialize($this->preference);
+ }
+
+ $db->query("insert into preferences (preference_owner,preference_value) values ("
+ . $this->account_id . ",'" . $pref_info . "')",__LINE__,__FILE__);
+
+ if ($phpgw_info["user"]["account_id"] == $this->account_id) {
+ $phpgw->preferences->preference = $this->get_preferences();
+ $phpgw->accounts->sync(__LINE__,__FILE__);
+ }
+ }
+ }
+
+ // Add a new preference.
+ function change($app_name,$var,$value = "")
+ {
+ global $phpgw_info;
+
+ if (! $value) {
+ global $$var;
+ $value = $$var;
+ }
+
+ $this->preference["$app_name"]["$var"] = $value;
+ }
+
+ function delete($app_name,$var)
+ {
+ if (! $var) {
+ $this->reset($app_name);
+ } else {
+ unset($this->preference["$app_name"]["$var"]);
+ }
+ }
+
+ // This will kill all preferences within a certain app
+ function reset($app_name)
+ {
+ $this->preference["$app_name"] = array();
+ }
+
+ function get_preferences()
+ {
+ return $this->preference;
+ }
+ } //end of preferences class
+?>
\ No newline at end of file
diff --git a/phpgwapi/inc/class.send.inc.php b/phpgwapi/inc/class.send.inc.php
new file mode 100644
index 0000000000..c8e4a63ccd
--- /dev/null
+++ b/phpgwapi/inc/class.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; $i
\n";
+ exit;
+ } unset($d1);
+
+ // Note: We should add a way to force the developer to say which ones to use. (jengo)
+ class utilities
+ {
+ var $rssparser;
+ var $clientsniffer;
+ var $http;
+ var $matrixview;
+ var $menutree;
+ var $sbox;
+
+ function utilities_()
+ {
+ $phpgw->rssparser = CreateObject("phpgwapi.rssparser");
+ $phpgw->clientsniffer = CreateObject("phpgwapi.clientsniffer");
+ $phpgw->http = CreateObject("phpgwapi.http");
+ $phpgw->matrixview = CreateObject("phpgwapi.matrixview");
+ $phpgw->menutree = CreateObject("phpgwapi.menutree");
+ $phpgw->sbox = CreateObject("phpgwapi.sbox");
+ }
+ }
+?>
diff --git a/phpgwapi/inc/class.utilities_clientsniffer.inc.php b/phpgwapi/inc/class.utilities_clientsniffer.inc.php
new file mode 100644
index 0000000000..1b155435a1
--- /dev/null
+++ b/phpgwapi/inc/class.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/inc/class.utilities_http.inc.php b/phpgwapi/inc/class.utilities_http.inc.php
new file mode 100644
index 0000000000..d81bedeb8b
--- /dev/null
+++ b/phpgwapi/inc/class.utilities_http.inc.php
@@ -0,0 +1,467 @@
+
+/*
+ * http.php
+ *
+ *
+ $Id$
+ */
+
+class http
+{
+ var $host_name="";
+ var $host_port=80;
+ var $proxy_host_name="";
+ var $proxy_host_port=80;
+
+ var $request_method="GET";
+ var $user_agent="Manuel Lemos HTTP class test script";
+ var $request_uri="";
+ var $protocol_version="1.0";
+ var $debug=0;
+ var $support_cookies=1;
+ var $cookies=array();
+
+ /* private variables - DO NOT ACCESS */
+
+ var $state="Disconnected";
+ var $connection=0;
+ var $content_length=0;
+ var $read_length=0;
+ var $request_host="";
+ var $months=array(
+ "Jan"=>"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;$value
";
+ $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";
+ $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 "
";
+ echo "\n";
+ echo " \n";
+ $this->out_ruler();
+ }
+ echo "" . $itemname . " \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";
+ 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";
+}
+
+/**
+*
+* private class for out method
+*
+* should not be used from external
+*
+*/
+
+function out_ruler ()
+{
+ echo "sumdays+1; echo "\" bgcolor=black>image1pix ."\"> \n";
+ echo "\n";
+ echo " \n";
+}
+
+/**
+*
+* private class for out method
+*
+* should not be used from external
+*
+*/
+
+function out_monthyear ()
+{
+ global $phpgw;
+
+ echo "\n";
+}
+
+}
+?>
diff --git a/phpgwapi/inc/class.utilities_menutree.inc.php b/phpgwapi/inc/class.utilities_menutree.inc.php
new file mode 100644
index 0000000000..308118f324
--- /dev/null
+++ b/phpgwapi/inc/class.utilities_menutree.inc.php
@@ -0,0 +1,294 @@
+ *
+ * -------------------------------------------- *
+ * 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, $expandlevels="", $num_menus = 50, $invisible_menus = Null){
+ global $phpgw_info, $phpgw;
+
+ $script = $SCRIPT_NAME;
+
+ $img_expand = "templates/default/images/tree_expand.gif";
+ $img_collapse = "templates/default/images/tree_collapse.gif";
+ $img_line = "templates/default/images/tree_vertline.gif";
+ $img_split = "templates/default/images/tree_split.gif";
+ $img_end = "templates/default/images/tree_end.gif";
+ $img_leaf = "templates/default/images/tree_leaf.gif";
+ $img_spc = "templates/default/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; $isumdays+1; echo "\" bgcolor=\"#999999\">image1pix ."\"> \n";
+ echo "";
+ for ($i=0; $i<$maxlevel; $i++) $str .= " \n";
+ }
+
+ /****************************************/
+ /* start new row */
+ /****************************************/
+ $str .= "";
+ $str .= " ";
+
+ /****************************************/
+ /* vertical lines from higher levels */
+ /****************************************/
+ $i=0;
+ while ($i<$tree[$cnt][0]-1) {
+ if ($levels[$i]==1)
+ $str .= " \n";
+ }
+ $cnt++;
+ }
+ $str .= "\n";
+
+ return $str;
+
+ /***************************************************/
+ /* 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/inc/class.utilities_portalbox.inc.php b/phpgwapi/inc/class.utilities_portalbox.inc.php
new file mode 100755
index 0000000000..921ca0f11d
--- /dev/null
+++ b/phpgwapi/inc/class.utilities_portalbox.inc.php
@@ -0,0 +1,155 @@
+$var = $value;
+// echo $var." = ".$this->$var."";
+ else
+ $str .= " ";
+ $i++;
+ }
+
+ /****************************************/
+ /* corner at end of subtree or t-split */
+ /****************************************/
+ if ($tree[$cnt][4]==1) {
+ $str .= " ";
+ $levels[$tree[$cnt][0]-1]=0;
+ } else {
+ $str .= " ";
+ $levels[$tree[$cnt][0]-1]=1;
+ }
+
+ /********************************************/
+ /* Node (with subtree) or Leaf (no subtree) */
+ /********************************************/
+ if ($tree[$cnt+1][0]>$tree[$cnt][0]) {
+
+ if ($expand[$cnt]==0)
+ $str .= " link($script,$params)."\"> ";
+ else
+ $str .= "link($script,$params)."\"> ";
+ } else {
+ /*************************/
+ /* Tree Leaf */
+ /*************************/
+
+ $str .= "";
+ }
+
+ /****************************************/
+ /* output item text */
+ /****************************************/
+ if ($tree[$cnt][2]=="")
+ $str .= " ".$tree[$cnt][1]." ";
+ else
+ $str .= "link($tree[$cnt][2],$params)."\" target=\"".$tree[$cnt][3]."\">".$tree[$cnt][1]." ";
+
+ /****************************************/
+ /* end row */
+ /****************************************/
+
+ $str .= "
\n";
+ }
+
+ function getvar($var="") {
+ if ($var=="" || !isset($this->$var)) {
+ global $phpgw;
+ echo 'Programming Error: '.$this->classname().'->getvar('.$var.')!
\n';
+ $phpgw->common->phpgw_exit();
+ }
+//echo "Var = ".$var."
\n";
+//echo $var." = ".$this->$var."
\n";
+ return $this->$var;
+ }
+
+ /*
+ This is the constructor for the object.
+ */
+ function baseportalbox($title="", $primary="", $secondary="", $tertiary="") {
+ $this->setvar("title",$title);
+// echo "After SetVar Title = ".$this->getvar("title")."
\n";
+ $this->setvar("outerborderwidth",1);
+ $this->setvar("titlebgcolor",$primary);
+ $this->setvar("innerbgcolor",$secondary);
+ $this->setvar("outerbordercolor",$tertiary);
+ }
+ // Methods
+}
+
+class linkbox extends baseportalbox {
+ /*
+ Set up the Object. You will notice, we have not reserved
+ memory space for variables. In this circumstance it is not necessary.
+ */
+
+ /*
+ This is the constructor for the linkbox. The only thing this does
+ is to call the constructor of the parent class. Why? Well, whilst
+ PHP manages a certain part of OO, one of the bits it falls down on
+ (at the moment) is constructors within sub-classes. So, to
+ be sure that the sub-class is instantiated with the constructor of
+ the parent class, I simply call the parent constructor. Of course,
+ if I then wanted to override any of the values, I could easily do so.
+ */
+ function linkbox($title="", $primary="", $secondary="", $tertiary="") {
+ $this->baseportalbox($title, $primary, $secondary, $tertiary);
+ $this->setvar("outerwidth",300);
+ $this->setvar("innerwidth",300);
+ $this->setvar("width",300);
+ }
+ /*
+ This is the only method within the class. Quite simply, as you can see
+ it draws the table(s), placing the required data in the appropriate place.
+ */
+ function draw() {
+ global $phpgw, $phpgw_info;
+
+ $p = new Template($phpgw->common->get_tpl_dir('home'));
+ $p->set_file(array('portal_main' => 'portal_main.tpl',
+ 'portal_linkbox_header' => 'portal_linkbox_header.tpl',
+ 'portal_linkbox' => 'portal_linkbox.tpl',
+ 'portal_linkbox_footer' => 'portal_linkbox_footer.tpl'));
+ $p->set_block('portal_main','portal_linkbox_header','portal_linkbox','portal_linkbox_footer');
+
+ $p->set_var('outer_border',$this->getvar('outerborderwidth'));
+ $p->set_var('outer_width',$this->getvar('width'));
+ $p->set_var('outer_bordercolor',$this->getvar('outerbordercolor'));
+ $p->set_var('outer_bgcolor',$this->getvar('titlebgcolor'));
+ $p->set_var('title',$this->getvar('title'));
+ $p->set_var('inner_width',$this->getvar('width'));
+ $p->set_var('inner_bgcolor',$this->getvar('innerbgcolor'));
+ $p->set_var('header_background_image',$this->getvar('header_background_image'));
+ $p->parse('output','portal_linkbox_header',True);
+
+ for ($x = 0; $x < count($this->data); $x++) {
+ $p->set_var('link',$this->data[$x][1]);
+ $p->set_var('text',$this->data[$x][0]);
+ $p->parse('output','portal_linkbox',True);
+ }
+ $p->parse('output','portal_linkbox_footer',True);
+ return $p->parse('out','portal_main');
+ }
+}
+
+class resultbox extends baseportalbox {
+ /*
+ Set up the Object. You will notice, we have not reserved memory
+ space for variables. In this circumstance it is not necessary.
+ */
+
+ //constructor
+ function resultbox($title="", $primary="", $secondary="", $tertiary="") {
+ $this->baseportalbox($title, $primary, $secondary, $tertiary);
+ $this->setvar("outerwidth",400);
+ $this->setvar("innerwidth",400);
+ }
+ /*
+ This is the only method within the class. Quite simply, as you can see
+ it draws the table(s), placing the required data in the appropriate place.
+ */
+ function draw() {
+ echo '';
+ echo '
';
+ }
+}
+?>
diff --git a/phpgwapi/inc/class.utilities_rssparse.inc.php b/phpgwapi/inc/class.utilities_rssparse.inc.php
new file mode 100644
index 0000000000..a2b3ad3d7c
--- /dev/null
+++ b/phpgwapi/inc/class.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/inc/class.utilities_sbox.inc.php b/phpgwapi/inc/class.utilities_sbox.inc.php
new file mode 100644
index 0000000000..1ccd431381
--- /dev/null
+++ b/phpgwapi/inc/class.utilities_sbox.inc.php
@@ -0,0 +1,208 @@
+';
+ $t_s[$selected] = " selected";
+ for ($i=0; $i<24; $i++) {
+ $s .= '';
+ $s .= "\n";
+ }
+ $s .= "";
+ return $s;
+ }
+
+ function hour_text($name, $selected = 0)
+ {
+ global $phpgw;
+
+ $s = '";
+ return $s;
+ }
+
+ // I would like to add a increment feature
+ function sec_minute_text($name, $selected = 0)
+ {
+ $s = '";
+ return $s;
+ }
+
+ function ap_text($name,$selected)
+ {
+ $selected = strtolower($selected);
+ $t[$selected] = " selected";
+ $s = '";
+ return $s;
+ }
+
+ function full_time($hour_name,$hour_selected,$min_name,$min_selected,$sec_name,$sec_selected,$ap_name,$ap_selected)
+ {
+ // This needs to be changed to support there time format preferences
+ $s = $this->hour_text($hour_name,$hour_selected)
+ . $this->sec_minute_text($min_name,$min_selected)
+ . $this->sec_minute_text($sec_name,$sec_selected)
+ . $this->ap_text($ap_name,$ap_selected);
+ return $s;
+ }
+
+ function getMonthText($name, $selected=0)
+ {
+ $out = "\n";
+ return $out;
+ }
+
+ function getDays($name, $selected=0)
+ {
+ $out = " ';
+ echo ''.$this->getvar("title").' ';
+ echo '';
+ echo ' ';
+ for ($x = 0; $x < count($this->data); $x++) {
+ echo '
';
+ echo '';
+ echo ' ';
+ }
+ echo ''.$this->data[$x][0].' ';
+ echo ''.$this->data[$x][1].' ';
+ echo '