2001-07-12 01:17:32 +02:00
< ? php
/************************************************************************** \
2003-12-19 03:26:17 +01:00
* eGroupWare - InfoLog *
* http :// www . eGroupWare . org *
2001-07-12 01:17:32 +02:00
* Written by Ralf Becker < RalfBecker @ outdoor - training . de > *
* originaly based on todo written by Joseph Engo < jengo @ phpgroupware . org > *
* -------------------------------------------- *
* 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$ */
2005-10-01 22:18:41 +02:00
include_once ( EGW_API_INC . '/class.solink.inc.php' );
2005-04-06 13:05:57 +02:00
/**
* storage object / db - layer for InfoLog
*
* all values passed to this class are run either through intval or addslashes to prevent query - insertion
* and for pgSql 7.3 compatibility
*
* @ package infolog
* @ author RalfBecker - At - outdoor - training . de
* @ copyright GPL - GNU General Public License
*/
2001-07-12 01:17:32 +02:00
class soinfolog // DB-Layer
{
2005-02-08 18:53:03 +01:00
var $db ;
2001-07-12 01:17:32 +02:00
var $grants ;
var $data = array ( );
2001-10-03 20:56:42 +02:00
var $user ;
2005-07-14 19:12:50 +02:00
var $info_table = 'egw_infolog' ;
var $extra_table = 'egw_infolog_extra' ;
2003-06-14 15:51:53 +02:00
2005-04-06 13:05:57 +02:00
/**
* constructor
*/
2001-07-14 23:44:01 +02:00
function soinfolog ( $info_id = 0 )
{
2005-04-06 13:05:57 +02:00
$this -> db = clone ( $GLOBALS [ 'egw' ] -> db );
2004-09-19 18:15:53 +02:00
$this -> db -> set_app ( 'infolog' );
2005-04-06 13:05:57 +02:00
$this -> grants = $GLOBALS [ 'egw' ] -> acl -> get_grants ( 'infolog' );
$this -> user = $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ];
2001-10-03 20:56:42 +02:00
2005-04-06 13:05:57 +02:00
$this -> links =& new solink ();
2002-09-01 22:41:36 +02:00
2005-04-06 13:05:57 +02:00
$this -> tz_offset = $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'tz_offset' ];
2003-09-08 02:40:42 +02:00
2001-07-14 23:44:01 +02:00
$this -> read ( $info_id );
2001-07-12 01:17:32 +02:00
}
2005-04-06 13:05:57 +02:00
/**
* checks if user has the $required_rights to access $info_id ( private access is handled too )
*
* @ param $info_id Id of InfoLog entry
* @ param $required_rights EGW_ACL_xyz anded together
* @ return boolean True if access is granted else False
*/
2001-07-14 23:44:01 +02:00
function check_access ( $info_id , $required_rights )
{
if ( $info_id != $this -> data [ 'info_id' ]) // already loaded?
{
// dont change our own internal data,
// dont use new as it changes $phpgw->db
$private_info = $this ;
2001-07-12 01:17:32 +02:00
$info = $private_info -> read ( $info_id );
2001-07-14 23:44:01 +02:00
}
else
{
2001-07-12 01:17:32 +02:00
$info = $this -> data ;
}
if ( ! $info || ! $info_id )
2001-07-14 23:44:01 +02:00
{
2001-07-12 01:17:32 +02:00
return False ;
2001-07-14 23:44:01 +02:00
}
2001-07-12 01:17:32 +02:00
$owner = $info [ 'info_owner' ];
2001-07-14 23:44:01 +02:00
2004-03-10 01:58:18 +01:00
$access_ok = $owner == $this -> user || // user has all rights
// ACL only on public entrys || $owner granted _PRIVATE
( !! ( $this -> grants [ $owner ] & $required_rights ) ||
// implicite read-rights for responsible user !!!
2005-10-05 09:50:47 +02:00
in_array ( $this -> user , $info [ 'info_responsible' ]) && $required_rights == EGW_ACL_READ ) &&
//$info['info_responsible'] == $this->user && $required_rights == EGW_ACL_READ) &&
2004-03-10 01:58:18 +01:00
( $info [ 'info_access' ] == 'public' ||
2005-04-06 13:05:57 +02:00
!! ( $this -> grants [ $owner ] & EGW_ACL_PRIVATE ));
2004-03-10 01:58:18 +01:00
2004-03-13 18:58:37 +01:00
//echo "<p>check_access(info_id=$info_id (owner=$owner, user=$user),required_rights=$required_rights): access".($access_ok?"Ok":"Denied")."</p>\n";
2004-03-10 01:58:18 +01:00
return $access_ok ;
2001-07-12 01:17:32 +02:00
}
2001-07-14 23:44:01 +02:00
2005-04-06 13:05:57 +02:00
/**
* generate sql to be AND ' ed into a query to ensure ACL is respected ( incl . _PRIVATE )
*
* @ param $filter : none | all - list all entrys user have rights to see < br >
2005-07-14 09:35:11 +02:00
* private | own - list only his personal entrys ( incl . those he is responsible for !!! ), my = entries the user is responsible for
2005-04-06 13:05:57 +02:00
* @ return string the necesary sql
*/
2004-02-05 14:37:29 +01:00
function aclFilter ( $filter = False )
2001-07-14 23:44:01 +02:00
{
2005-07-14 09:35:11 +02:00
preg_match ( '/(my|own|privat|all|none|user)([0-9]*)/' , $filter_was = $filter , $vars );
2001-07-15 23:42:17 +02:00
$filter = $vars [ 1 ];
2003-09-07 18:55:36 +02:00
$f_user = intval ( $vars [ 2 ]);
2001-07-15 23:42:17 +02:00
2005-07-14 09:35:11 +02:00
if ( isset ( $this -> acl_filter [ $filter . $f_user ]))
2001-07-14 23:44:01 +02:00
{
2005-07-14 09:35:11 +02:00
return $this -> acl_filter [ $filter . $f_user ]; // used cached filter if found
2001-07-14 23:44:01 +02:00
}
if ( is_array ( $this -> grants ))
{
2004-03-10 01:58:18 +01:00
foreach ( $this -> grants as $user => $grant )
2001-07-14 23:44:01 +02:00
{
// echo "<p>grants: user=$user, grant=$grant</p>";
2005-04-06 13:05:57 +02:00
if ( $grant & ( EGW_ACL_READ | EGW_ACL_EDIT ))
2001-07-14 23:44:01 +02:00
{
2001-07-12 01:17:32 +02:00
$public_user_list [] = $user ;
2001-07-14 23:44:01 +02:00
}
2005-04-06 13:05:57 +02:00
if ( $grant & EGW_ACL_PRIVATE )
2001-07-14 23:44:01 +02:00
{
2001-07-12 01:17:32 +02:00
$private_user_list [] = $user ;
2001-07-14 23:44:01 +02:00
}
2001-07-12 01:17:32 +02:00
}
2001-07-14 23:44:01 +02:00
if ( count ( $private_user_list ))
2003-09-07 18:55:36 +02:00
{
2003-06-14 15:51:53 +02:00
$has_private_access = 'info_owner IN (' . implode ( ',' , $private_user_list ) . ')' ;
2003-09-07 18:55:36 +02:00
}
2001-07-12 01:17:32 +02:00
}
2001-10-03 20:56:42 +02:00
$filtermethod = " (info_owner= $this->user " ; // user has all rights
2005-07-14 09:35:11 +02:00
if ( $filter == 'my' )
{
2005-10-05 09:50:47 +02:00
$filtermethod .= " AND info_responsible='0' " ;
2005-07-14 09:35:11 +02:00
}
2003-11-14 13:05:47 +01:00
// implicit read-rights for responsible user
2005-10-13 17:26:45 +02:00
$filtermethod .= " OR ( " . $this -> db -> concat ( " ',' " , 'info_responsible' , " ',' " ) . " LIKE '%, $this->user ,%' AND info_access='public') " ;
2003-11-14 13:05:47 +01:00
2003-09-07 18:55:36 +02:00
// private: own entries plus the one user is responsible for
2001-07-15 23:42:17 +02:00
if ( $filter == 'private' || $filter == 'own' )
2001-07-14 23:44:01 +02:00
{
2005-10-13 17:26:45 +02:00
$filtermethod .= " OR ( " . $this -> db -> concat ( " ',' " , 'info_responsible' , " ',' " ) . " LIKE '%, $this->user ,%' " .
2004-08-22 21:22:53 +02:00
( $filter == 'own' && count ( $public_user_list ) ? // offer's should show up in own, eg. startpage, but need read-access
" OR info_status = 'offer' AND info_owner IN( " . implode ( ',' , $public_user_list ) . ')' : '' ) . " ) " .
2001-10-04 21:04:58 +02:00
" AND (info_access='public' " . ( $has_private_access ? " OR $has_private_access " : '' ) . ')' ;
2001-07-14 23:44:01 +02:00
}
2005-07-14 09:35:11 +02:00
elseif ( $filter != 'my' ) // none --> all entrys user has rights to see
2001-07-14 23:44:01 +02:00
{
if ( $has_private_access )
{
2001-07-12 01:17:32 +02:00
$filtermethod .= " OR $has_private_access " ;
}
2001-07-14 23:44:01 +02:00
if ( count ( $public_user_list ))
2003-09-07 18:55:36 +02:00
{
2001-07-12 01:17:32 +02:00
$filtermethod .= " OR (info_access='public' AND info_owner IN( " . implode ( ',' , $public_user_list ) . '))' ;
}
}
$filtermethod .= ') ' ;
2003-09-07 18:55:36 +02:00
if ( $filter == 'user' && $f_user > 0 )
{
2005-10-13 17:26:45 +02:00
$filtermethod = " ((info_owner= $f_user AND info_responsible=0 OR " . $this -> db -> concat ( " ',' " , 'info_responsible' , " ',' " ) . " LIKE '%, $f_user ,%') AND $filtermethod ) " ;
2003-09-07 18:55:36 +02:00
}
2004-02-05 14:37:29 +01:00
//echo "<p>aclFilter(filter='$filter_was',user='$user') = '$filtermethod', privat_user_list=".print_r($privat_user_list,True).", public_user_list=".print_r($public_user_list,True)."</p>\n";
2005-10-05 09:50:47 +02:00
2005-07-14 09:35:11 +02:00
return $this -> acl_filter [ $filter . $f_user ] = $filtermethod ; // cache the filter
2003-09-07 18:55:36 +02:00
}
2001-07-12 01:17:32 +02:00
2005-04-06 13:05:57 +02:00
/**
* generate sql to filter based on the status of the log - entry
*
* @ param $filter done = done or billed , open = not () done or billed ), offer = offer
* @ return string the necesary sql
*/
2001-07-15 23:42:17 +02:00
function statusFilter ( $filter = '' )
{
2004-05-09 00:42:38 +02:00
preg_match ( '/(done|open|offer)/' , $filter , $vars );
2001-07-15 23:42:17 +02:00
$filter = $vars [ 1 ];
switch ( $filter )
{
case 'done' : return " AND info_status IN ('done','billed') " ;
case 'open' : return " AND NOT (info_status IN ('done','billed')) " ;
case 'offer' : return " AND info_status = 'offer' " ;
}
return '' ;
}
2005-04-06 13:05:57 +02:00
/**
* generate sql to filter based on the start - and enddate of the log - entry
*
* @ param $filter upcoming = startdate is in the future < br >
* today startdate < tomorrow < br >
* overdue enddate < tomorrow < br >
* limitYYYY / MM / DD not older or open
* @ return string the necesary sql
*/
2001-07-15 23:42:17 +02:00
function dateFilter ( $filter = '' )
{
2004-05-09 00:42:38 +02:00
preg_match ( '/(upcoming|today|overdue|date)([-\\/.0-9]*)/' , $filter , $vars );
2001-07-15 23:42:17 +02:00
$filter = $vars [ 1 ];
2003-09-07 18:55:36 +02:00
if ( isset ( $vars [ 2 ]) && ! empty ( $vars [ 2 ]) && ( $date = split ( '[-/.]' , $vars [ 2 ])))
{
2003-09-08 02:40:42 +02:00
$today = mktime ( - $this -> tz_offset , 0 , 0 , intval ( $date [ 1 ]), intval ( $date [ 2 ]), intval ( $date [ 0 ]));
$tomorrow = mktime ( - $this -> tz_offset , 0 , 0 , intval ( $date [ 1 ]), intval ( $date [ 2 ]) + 1 , intval ( $date [ 0 ]));
2003-09-07 18:55:36 +02:00
}
else
{
2003-09-08 02:40:42 +02:00
$now = getdate ( time () - 60 * 60 * $this -> tz_offset );
$tomorrow = mktime ( - $this -> tz_offset , 0 , 0 , $now [ 'mon' ], $now [ 'mday' ] + 1 , $now [ 'year' ]);
2003-09-07 18:55:36 +02:00
}
2001-07-15 23:42:17 +02:00
switch ( $filter )
{
2003-06-14 15:51:53 +02:00
case 'upcoming' :
return " AND info_startdate >= ' $tomorrow ' " ;
case 'today' :
return " AND info_startdate < ' $tomorrow ' " ;
case 'overdue' :
return " AND (info_enddate != 0 AND info_enddate < ' $tomorrow ') " ;
2003-09-07 18:55:36 +02:00
case 'date' :
if ( ! $today || ! $tomorrow )
{
return '' ;
}
return " AND ( $today <= info_startdate AND info_startdate < $tomorrow ) " ;
2004-03-10 01:58:18 +01:00
case 'limit' :
return " AND (info_modified >= ' $today ' OR NOT (info_status IN ('done','billed'))) " ;
2001-07-15 23:42:17 +02:00
}
return '' ;
}
2005-04-06 13:05:57 +02:00
/**
* initialise the internal $this -> data to be empty
*
* only non - empty values got initialised
*/
2001-07-14 23:44:01 +02:00
function init ()
{
2004-03-10 01:58:18 +01:00
$this -> data = array (
2005-07-14 19:12:50 +02:00
'info_owner' => $this -> user ,
'info_priority' => 1 ,
2005-10-05 09:50:47 +02:00
'info_responsible' => array (),
2003-06-14 15:51:53 +02:00
);
2004-03-10 01:58:18 +01:00
}
2005-04-06 13:05:57 +02:00
/**
* read InfoLog entry $info_id
*
* some cacheing is done to prevent multiple reads of the same entry
*
* @ param $info_id id of log - entry
* @ return array / boolean the entry as array or False on error ( eg . entry not found )
*/
2001-07-14 23:44:01 +02:00
function read ( $info_id ) // did _not_ ensure ACL
{
2005-07-14 09:35:11 +02:00
$info_id = ( int ) $info_id ;
2003-06-14 15:51:53 +02:00
2001-07-12 01:17:32 +02:00
if ( $info_id <= 0 || $info_id != $this -> data [ 'info_id' ] &&
2004-09-19 18:15:53 +02:00
( ! $this -> db -> select ( $this -> info_table , '*' , array ( 'info_id' => $info_id ), __LINE__ , __FILE__ ) ||
2005-07-14 09:35:11 +02:00
! (( $this -> data = $this -> db -> row ( true )))))
2001-07-12 01:17:32 +02:00
{
$this -> init ( );
return False ;
}
2005-10-05 09:50:47 +02:00
if ( ! is_array ( $this -> data [ 'info_responsible' ]))
{
$this -> data [ 'info_responsible' ] = $this -> data [ 'info_responsible' ] ? explode ( ',' , $this -> data [ 'info_responsible' ]) : array ();
}
2001-07-14 23:44:01 +02:00
if ( $info_id != $this -> data [ 'info_id' ]) // data yet read in
{
2004-09-19 18:15:53 +02:00
$this -> db -> select ( $this -> extra_table , 'info_extra_name,info_extra_value' , array ( 'info_id' => $info_id ), __LINE__ , __FILE__ );
2003-08-28 16:31:11 +02:00
while ( $this -> db -> next_record ())
{
$this -> data [ '#' . $this -> db -> f ( 0 )] = $this -> db -> f ( 1 );
}
2001-07-19 01:54:43 +02:00
}
2002-10-16 02:23:39 +02:00
return $this -> data ;
2001-07-12 01:17:32 +02:00
}
2005-04-06 13:05:57 +02:00
/**
* delete InfoLog entry $info_id AND the links to it
*
* @ param int $info_id id of log - entry
* @ param bool $delete_children delete the children , if not set there parent - id to $new_parent
* @ param int $new_parent new parent - id to set for subs
*/
2003-12-19 03:26:17 +01:00
function delete ( $info_id , $delete_children = True , $new_parent = 0 ) // did _not_ ensure ACL
2001-07-14 23:44:01 +02:00
{
2003-12-19 03:26:17 +01:00
//echo "<p>soinfolog::delete($info_id,'$delete_children',$new_parent)</p>\n";
2004-09-19 18:15:53 +02:00
if (( int ) $info_id <= 0 )
2003-06-14 15:51:53 +02:00
{
return ;
}
2004-09-19 18:15:53 +02:00
$this -> db -> delete ( $this -> info_table , array ( 'info_id' => $info_id ), __LINE__ , __FILE__ );
$this -> db -> delete ( $this -> extra_table , array ( 'info_id' => $info_id ), __LINE__ , __FILE__ );
2002-09-01 22:41:36 +02:00
$this -> links -> unlink ( 0 , 'infolog' , $info_id );
2001-07-12 01:17:32 +02:00
if ( $this -> data [ 'info_id' ] == $info_id )
2001-07-14 23:44:01 +02:00
{
2001-07-12 01:17:32 +02:00
$this -> init ( );
2001-07-14 23:44:01 +02:00
}
2003-08-28 16:31:11 +02:00
// delete children, if they are owned by the user
if ( $delete_children )
{
2005-02-08 18:53:03 +01:00
$db2 = clone ( $this -> db ); // we need an extra result-set
2004-09-19 18:15:53 +02:00
$db2 -> select ( $this -> info_table , 'info_id' , array (
'info_id_parent' => $info_id ,
'info_owner' => $this -> user ,
), __LINE__ , __FILE__ );
2003-08-28 16:31:11 +02:00
while ( $db2 -> next_record ())
{
$this -> delete ( $db2 -> f ( 0 ), $delete_children );
}
}
2004-09-19 18:15:53 +02:00
// set parent_id to $new_parent or 0 for all not deleted children
$this -> db -> update ( $this -> info_table , array ( 'info_id_parent' => $new_parent ), array ( 'info_id_parent' => $info_id ), __LINE__ , __FILE__ );
2001-07-12 01:17:32 +02:00
}
2005-04-06 13:05:57 +02:00
/**
* changes or deletes entries with a spezified owner ( for hook_delete_account )
*
* @ param $owner old owner
* @ param $new_owner new owner or 0 if entries should be deleted
*/
2002-11-20 20:58:15 +01:00
function change_delete_owner ( $owner , $new_owner = 0 ) // new_owner=0 means delete
{
2004-09-19 18:15:53 +02:00
if ( ! ( int ) $new_owner )
2002-11-20 20:58:15 +01:00
{
2005-02-08 18:53:03 +01:00
$db2 = clone ( $this -> db ); // we need an extra result-set
2004-09-19 18:15:53 +02:00
$db2 -> select ( $this -> info_table , 'info_id' , array ( 'info_owner' => $owner ), __LINE__ , __FILE__ );
2003-08-28 16:31:11 +02:00
while ( $db2 -> next_record ())
{
$this -> delete ( $this -> db -> f ( 0 ), False );
}
2002-11-20 20:58:15 +01:00
}
else
{
2004-09-19 18:15:53 +02:00
$this -> db -> update ( $this -> info_table , array ( 'info_owner' => $new_owner ), array ( 'info_owner' => $owner ), __LINE__ , __FILE__ );
2002-11-20 20:58:15 +01:00
}
2004-09-19 18:15:53 +02:00
$this -> db -> update ( $this -> info_table , array ( 'info_responsible' => $new_owner ), array ( 'info_responsible' => $owner ), __LINE__ , __FILE__ );
2002-11-20 20:58:15 +01:00
}
2005-04-06 13:05:57 +02:00
/**
* writes the given $values to InfoLog , a new entry gets created if info_id is not set or 0
*
* @ param array $values with the data of the log - entry
* @ return int the info_id
*/
2001-07-14 23:44:01 +02:00
function write ( $values ) // did _not_ ensure ACL
{
2005-10-05 09:50:47 +02:00
//echo "soinfolog::write()values="; _debug_array($values);
2004-09-19 18:15:53 +02:00
$info_id = ( int ) $values [ 'info_id' ];
2003-08-28 16:31:11 +02:00
2005-10-05 09:50:47 +02:00
if ( isset ( $values [ 'info_responsible' ]))
{
$values [ 'info_responsible' ] = count ( $values [ 'info_responsible' ]) ? implode ( ',' , $values [ 'info_responsible' ]) : '0' ;
}
2004-09-19 18:15:53 +02:00
$table_def = $this -> db -> get_table_definitions ( 'infolog' , $this -> info_table );
$to_write = array ();
2003-08-28 16:31:11 +02:00
foreach ( $values as $key => $val )
2001-07-14 23:44:01 +02:00
{
2004-09-19 18:15:53 +02:00
if ( $key != 'info_id' && isset ( $table_def [ 'fd' ][ $key ]))
2001-07-14 23:44:01 +02:00
{
2004-09-19 18:15:53 +02:00
$to_write [ $key ] = $this -> data [ $key ] = $val ; // update internal data
2001-07-12 01:17:32 +02:00
}
}
2003-08-28 16:31:11 +02:00
if (( $this -> data [ 'info_id' ] = $info_id ))
2001-07-14 23:44:01 +02:00
{
2004-09-19 18:15:53 +02:00
$this -> db -> update ( $this -> info_table , $to_write , array ( 'info_id' => $info_id ), __LINE__ , __FILE__ );
2001-07-14 23:44:01 +02:00
}
else
{
2005-10-05 09:50:47 +02:00
if ( ! isset ( $to_write [ 'info_id_parent' ])) $to_write [ 'info_id_parent' ] = 0 ; // must not be null
2004-09-19 18:15:53 +02:00
$this -> db -> insert ( $this -> info_table , $to_write , false , __LINE__ , __FILE__ );
$this -> data [ 'info_id' ] = $this -> db -> get_last_insert_id ( $this -> info_table , 'info_id' );
2001-07-20 01:00:51 +02:00
}
2003-08-28 16:31:11 +02:00
//echo "<p>soinfolog.write values= "; _debug_array($values);
// write customfields now
foreach ( $values as $key => $val )
{
if ( $key [ 0 ] != '#' )
{
continue ; // no customfield
}
$this -> data [ $key ] = $val ; // update internal data
2004-09-19 18:15:53 +02:00
$this -> db -> insert ( $this -> extra_table , array (
'info_extra_value' => $val
), array (
'info_id' => $info_id ,
'info_extra_name' => substr ( $key , 1 ),
), __LINE__ , __FILE__ );
2003-08-28 16:31:11 +02:00
}
2002-09-01 22:41:36 +02:00
// echo "<p>soinfolog.write this->data= "; _debug_array($this->data);
2003-06-14 15:51:53 +02:00
return $this -> data [ 'info_id' ];
2001-07-12 01:17:32 +02:00
}
2001-07-14 23:44:01 +02:00
2005-04-06 13:05:57 +02:00
/**
* count the sub - entries of $info_id
*
* @ param $info_id id of log - entry
* @ return int the number of sub - entries
*/
2001-07-14 23:44:01 +02:00
function anzSubs ( $info_id )
{
2003-06-14 15:51:53 +02:00
if (( $info_id = intval ( $info_id )) <= 0 )
2002-10-16 02:23:39 +02:00
{
return 0 ;
}
2004-09-19 18:15:53 +02:00
$this -> db -> select ( $this -> info_table , 'count(*)' , array (
'info_id_parent' => $info_id ,
$this -> aclFilter ()
), __LINE__ , __FILE__ );
2001-07-14 23:44:01 +02:00
$this -> db -> next_record ();
2004-02-05 14:37:29 +01:00
//echo "<p>anzSubs($info_id) = ".$this->db->f(0)." ($sql)</p>\n";
2001-07-14 23:44:01 +02:00
return $this -> db -> f ( 0 );
}
2005-04-06 13:05:57 +02:00
/**
* searches InfoLog for a certain pattern in $query
*
* @ param $query [ order ] column - name to sort after
* @ param $query [ sort ] sort - order DESC or ASC
* @ param $query [ filter ] string with combination of acl - , date - and status - filters , eg . 'own-open-today' or ''
* @ param $query [ cat_id ] category to use or 0 or unset
* @ param $query [ search ] pattern to search , search is done in info_from , info_subject and info_des
* @ param $query [ action ] / $query [ action_id ] if only entries linked to a specified app / entry show be used
* @ param & $query [ start ], & $query [ total ] nextmatch - parameters will be used and set if query returns less entries
* @ param $query [ col_filter ] array with column - name - data pairs , data == '' means no filter ( ! )
* @ param $query [ subs ] boolean return subs or not , if unset the user preference is used
* @ return array with id ' s as key of the matching log - entries
*/
2004-03-10 01:58:18 +01:00
function search ( & $query )
2001-07-14 23:44:01 +02:00
{
2004-03-10 01:58:18 +01:00
//echo "<p>soinfolog.search(".print_r($query,True).")</p>\n";
2002-09-01 22:41:36 +02:00
$action2app = array (
2002-10-14 02:39:47 +02:00
'addr' => 'addressbook' ,
'proj' => 'projects' ,
2002-10-16 02:23:39 +02:00
'event' => 'calendar'
2002-09-01 22:41:36 +02:00
);
2004-03-10 01:58:18 +01:00
$action = isset ( $action2app [ $query [ 'action' ]]) ? $action2app [ $query [ 'action' ]] : $query [ 'action' ];
2002-10-16 02:23:39 +02:00
if ( $action != '' )
{
2004-03-10 01:58:18 +01:00
$links = $this -> links -> get_links ( $action == 'sp' ? 'infolog' : $action , $query [ 'action_id' ], 'infolog' );
2002-10-16 02:23:39 +02:00
if ( count ( $links ))
2002-09-01 22:41:36 +02:00
{
2004-09-19 18:15:53 +02:00
$link_extra = ( $action == 'sp' ? 'OR' : 'AND' ) . " $this->info_table .info_id IN ( " . implode ( ',' , $links ) . ')' ;
2002-09-01 22:41:36 +02:00
}
}
2004-03-13 18:58:37 +01:00
if ( ! empty ( $query [ 'order' ]) && eregi ( '^[a-z_0-9, ]+$' , $query [ 'order' ]) && ( empty ( $query [ 'sort' ]) || eregi ( '^(DESC|ASC)$' , $query [ 'sort' ])))
2001-07-14 23:44:01 +02:00
{
2004-03-13 18:58:37 +01:00
$order = array ();
foreach ( explode ( ',' , $query [ 'order' ]) as $val )
{
$val = trim ( $val );
2004-07-25 03:41:37 +02:00
$val = ( substr ( $val , 0 , 5 ) != 'info_' ? 'info_' : '' ) . $val ;
if ( $val == 'info_des' && $this -> db -> Type == 'mssql' )
{
$val = " CAST( $val AS varchar) " ;
}
$order [] = $val ;
2004-03-13 18:58:37 +01:00
}
$ordermethod = 'ORDER BY ' . implode ( ',' , $order ) . ' ' . $query [ 'sort' ];
2001-07-14 23:44:01 +02:00
}
else
{
2004-03-13 18:58:37 +01:00
$ordermethod = 'ORDER BY info_datemodified DESC' ; // newest first
2001-07-14 23:44:01 +02:00
}
2004-03-10 01:58:18 +01:00
$filtermethod = $this -> aclFilter ( $query [ 'filter' ]);
$filtermethod .= $this -> statusFilter ( $query [ 'filter' ]);
$filtermethod .= $this -> dateFilter ( $query [ 'filter' ]);
2003-12-09 01:08:31 +01:00
2004-03-10 01:58:18 +01:00
if ( is_array ( $query [ 'col_filter' ]))
2003-12-09 01:08:31 +01:00
{
2004-03-10 01:58:18 +01:00
foreach ( $query [ 'col_filter' ] as $col => $data )
2003-12-09 01:08:31 +01:00
{
2004-03-13 18:58:37 +01:00
if ( substr ( $col , 0 , 5 ) != 'info_' ) $col = 'info_' . $col ;
if ( ! empty ( $data ) && eregi ( '^[a-z_0-9]+$' , $col ))
2003-12-09 01:08:31 +01:00
{
2005-10-05 09:50:47 +02:00
if ( $col == 'info_responsible' )
{
$data = ( int ) $data ;
if ( ! $data ) continue ;
2005-10-13 17:26:45 +02:00
$filtermethod .= " AND ( " . $this -> db -> concat ( " ',' " , 'info_responsible' , " ',' " ) . " LIKE '%, $data ,%' OR info_responsible='0' AND info_owner= $data ) " ;
2005-10-05 09:50:47 +02:00
}
else
{
if ( ! $this -> table_defs ) $this -> table_defs = $this -> db -> get_table_definitions ( 'infolog' , $this -> info_table );
$filtermethod .= ' AND ' . $col . '=' . $this -> db -> quote ( $data , $this -> table_defs [ 'fd' ][ $col ][ 'type' ]);
}
2003-12-09 01:08:31 +01:00
}
}
}
2003-09-07 18:55:36 +02:00
//echo "<p>filtermethod='$filtermethod'</p>";
2001-07-14 23:44:01 +02:00
2004-04-05 00:23:47 +02:00
if (( int ) $query [ 'cat_id' ])
2001-07-14 23:44:01 +02:00
{
2004-04-05 00:23:47 +02:00
//$filtermethod .= ' AND info_cat='.intval($query['cat_id']).' ';
2005-04-06 13:05:57 +02:00
if ( ! is_object ( $GLOBALS [ 'egw' ] -> categories ))
2004-04-05 00:23:47 +02:00
{
2005-04-06 13:05:57 +02:00
$GLOBALS [ 'egw' ] -> categories =& CreateObject ( 'phpgwapi.categories' );
2004-04-05 00:23:47 +02:00
}
2005-04-06 13:05:57 +02:00
$cats = $GLOBALS [ 'egw' ] -> categories -> return_all_children (( int ) $query [ 'cat_id' ]);
2004-04-05 00:23:47 +02:00
$filtermethod .= ' AND info_cat' . ( count ( $cats ) > 1 ? ' IN (' . implode ( ',' , $cats ) . ') ' : '=' . ( int ) $query [ 'cat_id' ]);
2001-07-14 23:44:01 +02:00
}
2003-08-28 16:31:11 +02:00
$join = '' ;
2004-03-23 09:22:46 +01:00
if ( $query [ 'query' ]) $query [ 'search' ] = $query [ 'query' ]; // allow both names
2004-03-10 01:58:18 +01:00
if ( $query [ 'search' ]) // we search in _from, _subject, _des and _extra_value for $query
2001-07-14 23:44:01 +02:00
{
2004-09-19 18:15:53 +02:00
$pattern = $this -> db -> quote ( '%' . $query [ 'search' ] . '%' );
$columns = array ( 'info_from' , 'info_subject' , 'info_extra_value' );
switch ( $this -> db -> Type )
{
case 'sapdb' :
case 'maxdb' :
// at the moment MaxDB 7.5 cant cast nor search text columns, it's suppost to change in 7.6
break ;
default :
$columns [] = 'info_des' ;
}
$sql_query = 'AND (' . implode ( " LIKE $pattern OR " , $columns ) . " LIKE $pattern ) " ;
$join = " LEFT JOIN $this->extra_table ON $this->info_table .info_id= $this->extra_table .info_id " ;
2001-07-14 23:44:01 +02:00
}
2004-03-10 01:58:18 +01:00
$pid = 'AND info_id_parent=' . ( $action == 'sp' ? $query [ 'action_id' ] : 0 );
2001-07-14 23:44:01 +02:00
2005-04-06 13:05:57 +02:00
if ( ! $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'infolog' ][ 'listNoSubs' ] &&
2004-09-08 18:04:37 +02:00
$action != 'sp' || isset ( $query [ 'subs' ]) && $query [ 'subs' ])
2001-07-14 23:44:01 +02:00
{
$pid = '' ;
}
2002-10-16 02:23:39 +02:00
$ids = array ( );
if ( $action == '' || $action == 'sp' || count ( $links ))
2003-06-14 15:51:53 +02:00
{
2004-09-19 18:15:53 +02:00
$sql_query = " FROM $this->info_table $join WHERE ( $filtermethod $pid $sql_query ) $link_extra " ;
2004-08-07 14:10:12 +02:00
switch ( $this -> db -> Type )
{
2004-09-19 18:15:53 +02:00
// mssql and others cant use DISTICT if text columns (info_des) are involved
2004-08-07 14:10:12 +02:00
case 'mssql' :
case 'sapdb' :
case 'maxdb' :
$distinct = '' ;
break ;
default :
$distinct = 'DISTINCT' ;
}
2004-09-19 18:15:53 +02:00
$this -> db -> query ( $sql = " SELECT $distinct $this->info_table .info_id " . $sql_query , __LINE__ , __FILE__ );
2004-03-10 01:58:18 +01:00
$query [ 'total' ] = $this -> db -> num_rows ();
2001-07-14 23:44:01 +02:00
2004-03-10 01:58:18 +01:00
if ( ! $query [ 'start' ] || $query [ 'start' ] > $query [ 'total' ])
2002-10-16 02:23:39 +02:00
{
2004-03-10 01:58:18 +01:00
$query [ 'start' ] = 0 ;
2002-10-16 02:23:39 +02:00
}
2004-09-19 18:15:53 +02:00
$this -> db -> limit_query ( $sql = " SELECT $distinct $this->info_table .* $sql_query $ordermethod " , $query [ 'start' ], __LINE__ , __FILE__ );
2003-11-14 13:05:47 +01:00
//echo "<p>sql='$sql'</p>\n";
2005-07-14 09:35:11 +02:00
while (( $info =& $this -> db -> row ( true )))
2005-10-05 09:50:47 +02:00
{
$info [ 'info_responsible' ] = $info [ 'info_responsible' ] ? explode ( ',' , $info [ 'info_responsible' ]) : array ();
2005-07-14 09:35:11 +02:00
$ids [ $info [ 'info_id' ]] =& $info ;
2002-10-16 02:23:39 +02:00
}
2001-07-14 23:44:01 +02:00
}
2002-10-16 02:23:39 +02:00
else
2001-07-14 23:44:01 +02:00
{
2004-03-10 01:58:18 +01:00
$query [ 'start' ] = $query [ 'total' ] = 0 ;
2001-07-14 23:44:01 +02:00
}
return $ids ;
}
2001-07-12 01:17:32 +02:00
}