2010-09-10 16:45:26 +00:00
< ? php
/**
* $Id $
*
* KnowledgeTree Community Edition
* Document Management Made Simple
* Copyright ( C ) 2008 , 2009 KnowledgeTree Inc .
*
*
* This program is free software ; you can redistribute it and / or modify it under
* the terms of the GNU General Public License version 3 as published by the
* Free Software Foundation .
*
* This program is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE . See the GNU General Public License for more
* details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http :// www . gnu . org / licenses />.
*
* You can contact KnowledgeTree Inc . , PO Box 7775 #87847, San Francisco,
* California 94120 - 7775 , or email info @ knowledgetree . com .
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices , as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7 ( b ) of the GNU General Public License version 3 ,
* these Appropriate Legal Notices must retain the display of the " Powered by
* KnowledgeTree " logo and retain the original copyright notice. If the display of the
* logo is not reasonably feasible for technical reasons , the Appropriate Legal Notices
* must display the words " Powered by KnowledgeTree " and retain the original
* copyright notice .
* Contributor ( s ) : ______________________________________
*
*/
require_once ( KT_LIB_DIR . " /session/control.inc " );
require_once ( KT_LIB_DIR . " /ktentity.inc " );
require_once ( KT_LIB_DIR . " /database/datetime.inc " );
require_once ( KT_LIB_DIR . " /dashboard/NotificationRegistry.inc.php " );
require_once ( KT_LIB_DIR . '/users/User.inc' );
require_once ( KT_LIB_DIR . '/documentmanagement/Document.inc' );
require_once ( KT_LIB_DIR . '/foldermanagement/Folder.inc' );
require_once ( KT_LIB_DIR . '/workflow/workflowutil.inc.php' );
require_once ( KT_LIB_DIR . '/templating/templating.inc.php' );
require_once ( KT_LIB_DIR . '/dispatcher.inc.php' );
/**
* class Notification
*
* Represents a basic message , about an item , to a user . This ends up on the dashboard .
*/
class KTNotification extends KTEntity {
/** primary key value */
var $iId = - 1 ;
var $iUserId ;
// sType and sLabel provide the title of the dashboard alert.
var $sLabel ; // a simple label - e.g. the document's title, or so forth.
var $sType ; // namespaced item type. (e.g. ktcore/subscriptions, word/officeupload)
// this is used to create the appropriate renderobj.
var $dCreationTime = null ; // the date/time of this items creation.
// iData1 and iData2 and integers, which can be used for whatever.
// sData1 and sData2 are similar.
// (i.e. you get very stupid subclassing semantics with up to 4 variables this way.
var $iData1 ;
var $iData2 ;
// sData1 and sData2 are 255-length character fields
var $sData1 ;
var $sData2 ;
// sText1 is a 65535-length text field
var $sText1 ;
var $_bUsePearError = true ;
function getId () { return $this -> iId ; }
function getLabel () { return $this -> sLabel ; }
function setLabel ( $sLabel ) { $this -> sLabel = $sLabel ; }
function getType () { return $this -> sType ; }
function setType ( $sType ) { $this -> sType = $sType ; }
function getIntData1 () { return $this -> iData1 ; }
function setIntData1 ( $iData1 ) { $this -> iData1 = $iData1 ; }
function getIntData2 () { return $this -> iData2 ; }
function setIntData2 ( $iData2 ) { $this -> iData2 = $iData2 ; }
function getStrData1 () { return $this -> sData1 ; }
function setStrData1 ( $sData1 ) { $this -> sData1 = $sData1 ; }
function getStrData2 () { return $this -> sData2 ; }
function setStrData2 ( $sData2 ) { $this -> sData2 = $sData2 ; }
function getTextData1 () { return $this -> sText1 ; }
function setTextData1 ( $mValue ) { $this -> sText1 = $mValue ; }
var $_aFieldToSelect = array (
" iId " => " id " ,
" iUserId " => " user_id " ,
" sLabel " => " label " ,
" sType " => " type " ,
" dCreationDate " => " creation_date " ,
" iData1 " => " data_int_1 " ,
" iData2 " => " data_int_2 " ,
" sData1 " => " data_str_1 " ,
" sData2 " => " data_str_2 " ,
" sText1 " => " data_text_1 " ,
);
function _table () {
return KTUtil :: getTableName ( 'notifications' );
}
function render () {
$notificationRegistry =& KTNotificationRegistry :: getSingleton ();
$handler = $notificationRegistry -> getHandler ( $this -> sType );
if ( is_null ( $handler )) { return null ; }
return $handler -> handleNotification ( $this );
}
function & getHandler () {
$notificationRegistry =& KTNotificationRegistry :: getSingleton ();
$handler =& $notificationRegistry -> getHandler ( $this -> sType );
return $handler ;
}
// Static function
function & get ( $iId ) { return KTEntityUtil :: get ( 'KTNotification' , $iId ); }
function & getList ( $sWhereClause = null , $aOptions = null ) {
if ( ! is_array ( $aOptions )) $aOptions = array ( $aOptions );
$aOptions [ 'orderby' ] = KTUtil :: arrayGet ( $aOptions , 'orderby' , 'creation_date DESC' );
return KTEntityUtil :: getList2 ( 'KTNotification' , $sWhereClause , $aOptions );
}
function & createFromArray ( $aOptions ) { return KTEntityUtil :: createFromArray ( 'KTNotification' , $aOptions ); }
}
/** register the base handlers. */
// abstract base-class for notification handler.
class KTNotificationHandler extends KTStandardDispatcher {
// FIXME rename this to renderNotification
// called to _render_ the notification.
function handleNotification ( $oKTNotification ) {
$oTemplating =& KTTemplating :: getSingleton ();
$oTemplate = $oTemplating -> loadTemplate ( " kt3/notifications/generic " );
$aTemplateData = array ( " context " => $oKTNotification , " oKTConfig " => $oKTConfig );
return $oTemplate -> render ( $aTemplateData );
}
function do_main () {
$this -> resolveNotification ( $this -> notification );
}
// called to resolve the notification (typically from /notify.php?id=xxxxx
function resolveNotification ( $oKTNotification ) {
$_SESSION [ 'KTErrorMessage' ][] = _kt ( " This notification handler does not support publication. " );
exit ( redirect ( generateControllerLink ( 'dashboard' )));
}
}
// FIXME consider refactoring this into plugins/ktcore/ktstandard/KTSubscriptions.php
class KTSubscriptionNotification extends KTNotificationHandler {
/* Subscription Notifications
*
* Subscriptions are a large part of the notification volume .
* That said , notifications cater to a larger group , so there is some
* degree of mismatch between the two .
*
* Mapping the needs of subscriptions onto the provisions of notifications
* works as :
*
* $oKTN -> label : object name [ e . g . Document Name ]
* $oKTN -> strData1 : event type [ AddFolder , AddDocument , etc . ]
* $oKTN -> strData2 : _location_ name . ( e . g . folder of the subscription . )
* $oKTN -> intData1 : object id ( e . g . document_id , folder_id )
* $oKTN -> intData2 : actor id ( e . g . user_id )
*
*/
var $notificationType = 'ktcore/subscriptions' ;
var $_eventObjectMap = array (
" AddFolder " => 'folder' ,
" RemoveSubscribedFolder " => '' , // nothing. your subscription is now gone.
" RemoveChildFolder " => 'folder' ,
" AddDocument " => 'document' ,
" RemoveSubscribedDocument " => '' , // nothing. your subscription is now gone.
" RemoveChildDocument " => 'folder' ,
" ModifyDocument " => 'document' ,
" CheckInDocument " => 'document' ,
" CheckOutDocument " => 'document' ,
" MovedDocument " => 'folder' ,
" MovedDocument2 " => 'document' ,
" CopiedDocument " => 'folder' ,
" CopiedDocument2 " => 'document' ,
" ArchivedDocument " => 'document' , // can go through and request un-archival (?)
" RestoredArchivedDocument " => 'document' ,
" DiscussDocument " => 'document' ,
);
function KTSubscriptionNotification () {
$this -> _eventTypeNames = array (
" AddFolder " => _kt ( 'Folder added' ),
" RemoveSubscribedFolder " => _kt ( 'Folder removed' ), // nothing. your subscription is now gone.
" RemoveChildFolder " => _kt ( 'Folder removed' ),
" AddDocument " => _kt ( 'Document added' ),
" RemoveSubscribedDocument " => _kt ( 'Document removed' ), // nothing. your subscription is now gone.
" RemoveChildDocument " => _kt ( 'Document removed' ),
" ModifyDocument " => _kt ( 'Document modified' ),
" CheckInDocument " => _kt ( 'Document checked in' ),
" CheckOutDocument " => _kt ( 'Document checked out' ),
" MovedDocument " => _kt ( 'Document moved' ),
" ArchivedDocument " => _kt ( 'Document archived' ), // can go through and request un-archival (?)
" RestoredArchivedDocument " => _kt ( 'Document restored' ),
" DiscussDocument " => _kt ( 'Document Discussions updated' ),
);
//parent::KTNotificationHandler();
}
// helper method to extract / set the various pieces of information
function _getSubscriptionData ( $oKTNotification ) {
$info = array (
'object_name' => $oKTNotification -> getLabel (),
'event_type' => $oKTNotification -> getStrData1 (),
'location_name' => $oKTNotification -> getStrData2 (),
'object_id' => $oKTNotification -> getIntData1 (),
'actor_id' => $oKTNotification -> getIntData2 (),
'has_actor' => false ,
'notify_id' => $oKTNotification -> getId (),
);
$info [ 'title' ] = KTUtil :: arrayGet ( $this -> _eventTypeNames , $info [ 'event_type' ], 'Subscription alert:' ) . ': ' . $info [ 'object_name' ];
if ( $info [ 'actor_id' ] !== null ) {
$oTempUser = User :: get ( $info [ 'actor_id' ]);
if ( PEAR :: isError ( $oTempUser ) || ( $oTempUser == false )) {
// no-act
$info [ 'actor' ] = null ;
} else {
$info [ 'actor' ] = $oTempUser ;
$info [ 'has_actor' ] = true ;
}
}
if ( $info [ 'object_id' ] !== null ) {
$info [ 'object' ] = $this -> _getEventObject ( $info [ 'event_type' ], $info [ 'object_id' ]);
}
return $info ;
}
// resolve the object type based on the alert type.
function _getEventObject ( $sAlertType , $id ) {
$t = KTUtil :: arrayGet ( $this -> _eventObjectMap , $sAlertType , '' );
if ( $t == 'document' ) {
$o = Document :: get ( $id );
if ( PEAR :: isError ( $o ) || ( $o == false )) { return null ;
} else { return $o ; }
} else if ( $t == 'folder' ) {
$o = Folder :: get ( $id );
if ( PEAR :: isError ( $o ) || ( $o == false )) { return null ;
} else { return $o ; }
} else {
return null ;
}
}
function _getEventObjectType ( $sAlertType ) {
return KTUtil :: arrayGet ( $this -> _eventObjectMap , $sAlertType , '' );
}
function handleNotification ( $oKTNotification ) {
$oSubscriptionContent = new SubscriptionContent ();
return $oSubscriptionContent -> getNotificationAlertContent ( $oKTNotification );
}
// helper to _create_ a notification, in a way that is slightly less opaque.
function & generateSubscriptionNotification ( $aOptions ) {
$creationInfo = array ();
/*
" iId " => " id " ,
" iUserId " => " user_id " ,
" sLabel " => " label " ,
" sType " => " type " ,
" dCreationDate " => " creation_date " ,
" iData1 " => " data_int_1 " ,
" iData2 " => " data_int_2 " ,
" sData1 " => " data_str_1 " ,
" sData2 " => " data_str_2 " ,
'object_name' => $oKTNotification -> getLabel (),
'event_type' => $oKTNotification -> getStrData1 (),
'location_name' => $oKTNotification -> getStrData2 (),
'object_id' => $oKTNotification -> getIntData1 (),
'actor_id' => $oKTNotification -> getIntData2 (),
'has_actor' => false ,
*/
$creationInfo [ 'sLabel' ] = $aOptions [ 'target_name' ];
$creationInfo [ 'sData1' ] = $aOptions [ 'event_type' ];
$creationInfo [ 'sData2' ] = $aOptions [ 'location_name' ];
$creationInfo [ 'iData1' ] = $aOptions [ 'object_id' ];
$creationInfo [ 'iData2' ] = $aOptions [ 'actor_id' ];
$creationInfo [ 'iUserId' ] = $aOptions [ 'target_user' ];
$creationInfo [ 'sType' ] = 'ktcore/subscriptions' ;
$creationInfo [ 'dCreationDate' ] = getCurrentDateTime (); // erk.
global $default ;
//$default->log->debug('subscription notification: from ' . print_r($aOptions, true));
$default -> log -> debug ( 'subscription notification: using ' . print_r ( $creationInfo , true ));
$oNotification =& KTNotification :: createFromArray ( $creationInfo );
$default -> log -> debug ( 'subscription notification: created ' . print_r ( $oNotification , true ));
return $oNotification ; // $res.
}
/**
* View the notification , and clear if requested
*
* @ param unknown_type $oKTNotification
*/
function resolveNotification ( $oKTNotification ) {
$notify_action = KTUtil :: arrayGet ( $_REQUEST , 'notify_action' , null );
if ( $notify_action == 'clear' ) {
$_SESSION [ 'KTInfoMessage' ][] = _kt ( 'Cleared notification.' );
$oKTNotification -> delete ();
exit ( redirect ( generateControllerLink ( 'dashboard' )));
}
// otherwise, we want to redirect the to object represented by the item.
// - viewDocument and viewFolder are the appropriate items.
// - object_id
$info = $this -> _getSubscriptionData ( $oKTNotification );
$object_type = $this -> _getEventObjectType ( $info [ 'event_type' ]);
if ( $object_type == '' ) {
$_SESSION [ 'KTErrorMessage' ][] = 'This notification has no "target". Please report as a bug that this subscription should only have a clear action.' . $object_type ;
exit ( redirect ( generateControllerLink ( 'dashboard' )));
}
if ( $object_type == 'document' ) {
if ( $info [ 'object_id' ] !== null ) { // fails and generates an error with no doc-id.
$params = 'fDocumentId=' . $info [ 'object_id' ];
$url = generateControllerLink ( 'viewDocument' , $params );
//$oKTNotification->delete(); // clear the alert.
exit ( redirect ( $url ));
}
} else if ( $object_type == 'folder' ) {
if ( $info [ 'object_id' ] !== null ) { // fails and generates an error with no doc-id.
$params = 'fFolderId=' . $info [ 'object_id' ];
$url = generateControllerLink ( 'browse' , $params );
//$oKTNotification->delete(); // clear the alert.
exit ( redirect ( $url ));
}
}
$_SESSION [ 'KTErrorMessage' ][] = sprintf ( 'This notification has no "target". Please inform the %s developers that there is a target bug with type: ' . $info [ 'event_type' ], APP_NAME );
exit ( redirect ( generateControllerLink ( 'dashboard' )));
}
}
class KTWorkflowNotification extends KTNotificationHandler {
function & clearNotificationsForDocument ( $oDocument ) {
$aNotifications = KTNotification :: getList ( 'data_int_1 = ' . $oDocument -> getId ());
foreach ( $aNotifications as $oNotification ) {
$oNotification -> delete ();
}
}
function & newNotificationForDocument ( $oDocument , $oUser , $oState , $oActor , $sComments ) {
$aInfo = array ();
$aInfo [ 'sData1' ] = $oState -> getName ();
$aInfo [ 'sData2' ] = $sComments ;
$aInfo [ 'iData1' ] = $oDocument -> getId ();
$aInfo [ 'iData2' ] = $oActor -> getId ();
$aInfo [ 'sType' ] = 'ktcore/workflow' ;
$aInfo [ 'dCreationDate' ] = getCurrentDateTime ();
$aInfo [ 'iUserId' ] = $oUser -> getId ();
2011-02-15 14:54:52 +00:00
$aInfo [ 'sLabel' ] = $oDocument -> getFullPath ();
2010-09-10 16:45:26 +00:00
$oNotification = KTNotification :: createFromArray ( $aInfo );
$handler = new KTWorkflowNotification ();
if ( $oUser -> getEmailNotification () && ( strlen ( $oUser -> getEmail ()) > 0 )) {
$emailContent = $handler -> handleNotification ( $oNotification );
2011-02-15 14:54:52 +00:00
$emailSubject = sprintf ( _kt ( 'Notificación sobre el trabajo: %s' ), $oDocument -> getName ());
2010-09-10 16:45:26 +00:00
$oEmail = new EmailAlert ( $oUser -> getEmail (), $emailSubject , $emailContent );
$oEmail -> send ();
}
return $oNotification ;
}
function handleNotification ( $oKTNotification ) {
$oTemplating =& KTTemplating :: getSingleton ();
$oTemplate =& $oTemplating -> loadTemplate ( 'ktcore/workflow/workflow_notification' );
$oDoc = Document :: get ( $oKTNotification -> getIntData1 ());
$isBroken = ( PEAR :: isError ( $oDoc ) || ( $oDoc -> getStatusID () != LIVE ));
$oTemplate -> setData ( array (
'context' => $this ,
'document_id' => $oKTNotification -> getIntData1 (),
'state_name' => $oKTNotification -> getStrData1 (),
'actor' => User :: get ( $oKTNotification -> getIntData2 ()),
'document_name' => $oKTNotification -> getLabel (),
'notify_id' => $oKTNotification -> getId (),
'document' => $oDoc ,
'is_broken' => $isBroken ,
));
return $oTemplate -> render ();
}
function resolveNotification ( $oKTNotification ) {
$notify_action = KTUtil :: arrayGet ( $_REQUEST , 'notify_action' , null );
if ( $notify_action == 'clear' ) {
$_SESSION [ 'KTInfoMessage' ][] = _kt ( 'Workflow Notification cleared.' );
$oKTNotification -> delete ();
exit ( redirect ( generateControllerLink ( 'dashboard' )));
}
$params = 'fDocumentId=' . $oKTNotification -> getIntData1 ();
$url = generateControllerLink ( 'viewDocument' , $params );
//$oKTNotification->delete(); // clear the alert.
exit ( redirect ( $url ));
}
}
?>