eZ Publish  [trunk]
ezcollaborationitemhandler.php
Go to the documentation of this file.
00001 <?php
00002 /**
00003  * File containing the eZCollaborationItemHandler class.
00004  *
00005  * @copyright Copyright (C) 1999-2012 eZ Systems AS. All rights reserved.
00006  * @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2
00007  * @version //autogentag//
00008  * @package kernel
00009  */
00010 
00011 /*!
00012   \class eZCollaborationItemHandler ezcollaborationitemhandler.php
00013   \brief The class eZCollaborationItemHandler does
00014 
00015 */
00016 
00017 class eZCollaborationItemHandler
00018 {
00019     /*
00020      Definitions for notification handling for collaboration handlers.
00021     */
00022     const NOTIFICATION_COLLECTION_ONE_FOR_ALL = 1;
00023     const NOTIFICATION_COLLECTION_PER_USER = 2;
00024     const NOTIFICATION_COLLECTION_PER_PARTICIPATION_ROLE = 3;
00025 
00026     /*!
00027      Initializes the handler with identifier and name.
00028      Optional parameters can be placed in \a $parameters.
00029     */
00030     function eZCollaborationItemHandler( $typeIdentifier, $typeName, $parameters = array() )
00031     {
00032         $parameters = array_merge( array( 'use-messages' => false,
00033                                           'type-class-list' => array(),
00034                                           'notification-collection-handling' => self::NOTIFICATION_COLLECTION_ONE_FOR_ALL,
00035                                           'notification-types' => false ),
00036                                    $parameters );
00037         $typeClassList = $parameters['type-class-list'];
00038         $this->Info['type-identifier'] = $typeIdentifier;
00039         $this->Info['type-class-list'] = $typeClassList;
00040         $this->Info['type-name'] = $typeName;
00041         $this->Info['use-messages'] = $parameters['use-messages'];
00042         $this->Info['notification-collection-handling'] = $parameters['notification-collection-handling'];
00043         $this->Info['notification-types'] = $parameters['notification-types'];
00044         $this->NotificationCollectionHandling = $parameters['notification-collection-handling'];
00045         $this->NotificationTypes = $parameters['notification-types'];
00046     }
00047 
00048     function attributes()
00049     {
00050         return array( 'info',
00051                       'notification_types' );
00052     }
00053 
00054     /*!
00055      \return true if the attribute \a $attribute exists.
00056     */
00057     function hasAttribute( $attr )
00058     {
00059         return in_array( $attr, $this->attributes() );
00060     }
00061 
00062     /*!
00063      \return the attribute \a $attribute if it exists or \c null.
00064     */
00065     function attribute( $attribute )
00066     {
00067         if ( $attribute == 'info' )
00068         {
00069             return $this->Info;
00070         }
00071         else if ( $attribute == 'notification_types' )
00072         {
00073             return $this->notificationTypes();
00074         }
00075 
00076         eZDebug::writeError( "Attribute '$attribute' does not exist", __METHOD__ );
00077         return null;
00078     }
00079 
00080     /*!
00081       \return what kind of notification types this handler supports. Can either return an array or a boolean.
00082       If it returns \c true the handler supports notification but does not have subnotifications.
00083       If it returns \c false the handler does not support notificiation.
00084       If it returns an array the array contains a list associative arrays each containing a \c name and \c value entry.
00085     */
00086     function notificationTypes()
00087     {
00088         return $this->NotificationTypes;
00089     }
00090 
00091     /*!
00092      \return how the handler wants collections to be made.
00093      \note The default is to create one collection for all participants.
00094     */
00095     function notificationCollectionHandling()
00096     {
00097         return $this->NotificationCollectionHandling;
00098     }
00099 
00100     function notificationParticipantTemplate( $participantRole )
00101     {
00102         return 'participant.tpl';
00103     }
00104 
00105     /*!
00106      \static
00107      Handles a notification event for collaboration items.
00108      \note The default implementation sends out a generic email.
00109      \note Transaction unsafe. If you call several transaction unsafe methods you must enclose
00110      the calls within a db transaction; thus within db->begin and db->commit.
00111     */
00112     static function handleCollaborationEvent( $event, $item, &$parameters )
00113     {
00114         $participantList = eZCollaborationItemParticipantLink::fetchParticipantList( array( 'item_id' => $item->attribute( 'id' ),
00115                                                                                              'participant_type' => eZCollaborationItemParticipantLink::TYPE_USER,
00116                                                                                              'as_object' => false ) );
00117 
00118         $userIDList = array();
00119         $participantMap = array();
00120         foreach ( $participantList as $participant )
00121         {
00122             $userIDList[] = $participant['participant_id'];
00123             $participantMap[$participant['participant_id']] = $participant;
00124         }
00125 
00126 //         $collaborationIdentifier = $event->attribute( 'collaboration_identifier' );
00127         $collaborationIdentifier = $event->attribute( 'data_text1' );
00128         $ruleList = eZCollaborationNotificationRule::fetchItemTypeList( $collaborationIdentifier, $userIDList, false );
00129         $userIDList = array();
00130         foreach ( $ruleList as $rule )
00131         {
00132             $userIDList[] = $rule['user_id'];
00133         }
00134         $userList = array();
00135         if ( count( $userIDList ) > 0 )
00136         {
00137             $db = eZDB::instance();
00138             $userIDListText = $db->generateSQLINStatement( $userIDList, 'contentobject_id', false, false, 'int' );
00139             $userList = $db->arrayQuery( "SELECT contentobject_id, email FROM ezuser WHERE $userIDListText" );
00140         }
00141         else
00142             return eZNotificationEventHandler::EVENT_SKIPPED;
00143 
00144         $itemHandler = $item->attribute( 'handler' );
00145         $collectionHandling = $itemHandler->notificationCollectionHandling();
00146 
00147         $db = eZDB::instance();
00148         $db->begin();
00149         if ( $collectionHandling == self::NOTIFICATION_COLLECTION_ONE_FOR_ALL )
00150         {
00151             $tpl = eZTemplate::factory();
00152             $tpl->resetVariables();
00153             $tpl->setVariable( 'collaboration_item', $item );
00154             $result = $tpl->fetch( 'design:notification/handler/ezcollaboration/view/plain.tpl' );
00155             $subject = $tpl->variable( 'subject' );
00156             if ( $tpl->hasVariable( 'message_id' ) )
00157                 $parameters['message_id'] = $tpl->variable( 'message_id' );
00158             if ( $tpl->hasVariable( 'references' ) )
00159                 $parameters['references'] = $tpl->variable( 'references' );
00160             if ( $tpl->hasVariable( 'reply_to' ) )
00161                 $parameters['reply_to'] = $tpl->variable( 'reply_to' );
00162             if ( $tpl->hasVariable( 'from' ) )
00163                 $parameters['from'] = $tpl->variable( 'from' );
00164             if ( $tpl->hasVariable( 'content_type' ) )
00165                 $parameters['content_type'] = $tpl->variable( 'content_type' );
00166 
00167             $collection = eZNotificationCollection::create( $event->attribute( 'id' ),
00168                                                             eZCollaborationNotificationHandler::NOTIFICATION_HANDLER_ID,
00169                                                             eZCollaborationNotificationHandler::TRANSPORT );
00170 
00171             $collection->setAttribute( 'data_subject', $subject );
00172             $collection->setAttribute( 'data_text', $result );
00173             $collection->store();
00174 
00175             foreach( $userList as $subscriber )
00176             {
00177                 $collection->addItem( $subscriber['email'] );
00178             }
00179         }
00180         else if ( $collectionHandling == self::NOTIFICATION_COLLECTION_PER_PARTICIPATION_ROLE )
00181         {
00182             $userCollection = array();
00183             foreach( $userList as $subscriber )
00184             {
00185                 $contentObjectID = $subscriber['contentobject_id'];
00186                 $participant = $participantMap[$contentObjectID];
00187                 $participantRole = $participant['participant_role'];
00188                 $userItem = array( 'participant' => $participant,
00189                                    'email' => $subscriber['email'] );
00190                 if ( !isset( $userCollection[$participantRole] ) )
00191                     $userCollection[$participantRole] = array();
00192                 $userCollection[$participantRole][] = $userItem;
00193             }
00194 
00195             $tpl = eZTemplate::factory();
00196             $tpl->resetVariables();
00197             foreach( $userCollection as $participantRole => $collectionItems )
00198             {
00199                 $templateName = $itemHandler->notificationParticipantTemplate( $participantRole );
00200                 if ( !$templateName )
00201                     $templateName = eZCollaborationItemHandler::notificationParticipantTemplate( $participantRole );
00202 
00203                 $itemInfo = $itemHandler->attribute( 'info' );
00204                 $typeIdentifier = $itemInfo['type-identifier'];
00205                 $tpl->setVariable( 'collaboration_item', $item );
00206                 $tpl->setVariable( 'collaboration_participant_role', $participantRole );
00207                 $result = $tpl->fetch( 'design:notification/handler/ezcollaboration/view/' . $typeIdentifier . '/' . $templateName );
00208                 $subject = $tpl->variable( 'subject' );
00209                 if ( $tpl->hasVariable( 'message_id' ) )
00210                     $parameters['message_id'] = $tpl->variable( 'message_id' );
00211                 if ( $tpl->hasVariable( 'references' ) )
00212                     $parameters['references'] = $tpl->variable( 'references' );
00213                 if ( $tpl->hasVariable( 'reply_to' ) )
00214                     $parameters['reply_to'] = $tpl->variable( 'reply_to' );
00215                 if ( $tpl->hasVariable( 'from' ) )
00216                     $parameters['from'] = $tpl->variable( 'from' );
00217                 if ( $tpl->hasVariable( 'content_type' ) )
00218                     $parameters['content_type'] = $tpl->variable( 'content_type' );
00219 
00220                 $collection = eZNotificationCollection::create( $event->attribute( 'id' ),
00221                                                                 eZCollaborationNotificationHandler::NOTIFICATION_HANDLER_ID,
00222                                                                 eZCollaborationNotificationHandler::TRANSPORT );
00223 
00224                 $collection->setAttribute( 'data_subject', $subject );
00225                 $collection->setAttribute( 'data_text', $result );
00226                 $collection->store();
00227                 foreach ( $collectionItems as $collectionItem )
00228                 {
00229                     $collection->addItem( $collectionItem['email'] );
00230                 }
00231             }
00232         }
00233         else if ( $collectionHandling == self::NOTIFICATION_COLLECTION_PER_USER )
00234         {
00235         }
00236         else
00237         {
00238             eZDebug::writeError( "Unknown collaboration notification collection handling type '$collectionHandling', skipping notification", __METHOD__ );
00239         }
00240         $db->commit();
00241 
00242         return eZNotificationEventHandler::EVENT_HANDLED;
00243     }
00244 
00245     /*!
00246      \return true if the attribute \a $attribute exists in the content data.
00247     */
00248     function hasContentAttribute( $collaborationItem, $attribute )
00249     {
00250         $content = $collaborationItem->content();
00251         if ( is_array( $content ) )
00252         {
00253             return array_key_exists( $attribute, $content );
00254         }
00255         return false;
00256     }
00257 
00258     /*!
00259      \return the attribute \a $attribute if it exists in the content data or \c null.
00260     */
00261     function contentAttribute( $collaborationItem, $attribute )
00262     {
00263         $content = $collaborationItem->content();
00264         if ( is_array( $content ) )
00265         {
00266             if ( array_key_exists( $attribute, $content ) )
00267                 return $content[$attribute];
00268         }
00269         $content = null;
00270         return $content;
00271     }
00272 
00273     /*!
00274      \return a list of classes this handler supports.
00275     */
00276     function classes()
00277     {
00278         return $this->Info['type-class-list'];
00279     }
00280 
00281     /*!
00282      \return the template name for the viewmode \a $viewmode.
00283     */
00284     function template( $viewMode )
00285     {
00286         $templateName = $this->templateName();
00287         return "design:collaboration/handlers/view/$viewMode/$templateName";
00288     }
00289 
00290     /*!
00291      \return the name of the template file for this handler.
00292      Default is to append .tpl to the identifier.
00293     */
00294     function templateName()
00295     {
00296         return $this->Info['type-identifier'] . '.tpl';
00297     }
00298 
00299     /*!
00300      \return the title of the collaboration item.
00301     */
00302     function title( $collaborationItem )
00303     {
00304         return $this->Info['type-name'];
00305     }
00306 
00307     /*!
00308      \return true if the collaboration item \a $collaborationItem supports messages.
00309      \note The handler can either determine this by passing \a $useMessages to the constructor
00310            or by reimplementing this function to do it per item.
00311     */
00312     function useMessages( $collaborationItem )
00313     {
00314         return $this->Info['use-messages'];
00315     }
00316 
00317     /*!
00318      \return the number of messages for the collaboration item \a $collaborationItem.
00319      \note The default implementation returns 0, if you want real counts
00320            the handler must reimplement this function.
00321     */
00322     function messageCount( $collaborationItem )
00323     {
00324         return 0;
00325     }
00326 
00327     /*!
00328      \return the number of unread messages for the collaboration item \a $collaborationItem.
00329      \note The default implementation returns 0, if you want real counts
00330            the handler must reimplement this function.
00331     */
00332     function unreadMessageCount( $collaborationItem )
00333     {
00334         return 0;
00335     }
00336 
00337     /*!
00338      This is called whenever the item is considered to be read,
00339      it can be used by handlers to update when the item was last read.
00340      \note Default implementation does nothing.
00341     */
00342     function readItem( $collaborationItem, $viewMode = false )
00343     {
00344     }
00345 
00346     /*!
00347      This is called whenever a collaboration item is to be removed.
00348      Reimplementing this function can be used to cleanup external tables
00349      or other resources.
00350     */
00351     function removeItem( $collaborationItem )
00352     {
00353     }
00354 
00355     /*!
00356      \static
00357      \return the ini object which handles collaboration settings.
00358     */
00359     static function ini()
00360     {
00361         return eZINI::instance( 'collaboration.ini' );
00362     }
00363 
00364     /*!
00365      \return a textual representation of the participant type id \a $participantType
00366      \note It's up to the real handlers to implement this if they use custom participation types.
00367     */
00368     function participantTypeString( $participantType )
00369     {
00370         return null;
00371     }
00372 
00373     /*!
00374      \return a textual representation of the participant role id \a $participantRole
00375      \note It's up to the real handlers to implement this if they use custom participation roles.
00376     */
00377     function participantRoleString( $participantRole )
00378     {
00379         return null;
00380     }
00381 
00382     /*!
00383      \return a description of the role id \a $roleID in the current language.
00384      \note It's up to the real handlers to implement this if they use custom participation roles.
00385     */
00386     function roleName( $collaborationID, $roleID )
00387     {
00388         return null;
00389     }
00390 
00391     /*!
00392      \return the content of the collaborationitem.
00393      \note This is specific to the item type, some might return an array and others an object.
00394     */
00395     function content( $collaborationItem )
00396     {
00397         return null;
00398     }
00399 
00400     /*!
00401      This function is called when a custom action is executed for a specific collaboration item.
00402      The module object is available in \a $module and the item in \a $collaborationItem.
00403      \note The default does nothing, the function must be reimplemented in real handlers.
00404      \sa isCustomAction
00405     */
00406     function handleCustomAction( $module, $collaborationItem )
00407     {
00408     }
00409 
00410     /*!
00411      \return true if the current custom action is \a $name.
00412     */
00413     function isCustomAction( $name )
00414     {
00415         $http = eZHTTPTool::instance();
00416         $postVariable = 'CollaborationAction_' . $name;
00417         return $http->hasPostVariable( $postVariable );
00418     }
00419 
00420     /*!
00421      \return true if the custom input variable \a $name exists.
00422     */
00423     function hasCustomInput( $name )
00424     {
00425         $http = eZHTTPTool::instance();
00426         $postVariable = 'Collaboration_' . $name;
00427         return $http->hasPostVariable( $postVariable );
00428     }
00429 
00430     /*!
00431      \return value of the custom input variable \a $name.
00432     */
00433     function customInput( $name )
00434     {
00435         $http = eZHTTPTool::instance();
00436         $postVariable = 'Collaboration_' . $name;
00437         return $http->postVariable( $postVariable );
00438     }
00439 
00440     /*!
00441      \static
00442      \return an array with directories which acts as default collaboration repositories.
00443      \sa handlerRepositories
00444     */
00445     static function defaultRepositories()
00446     {
00447         $collabINI = eZCollaborationItemHandler::ini();
00448         return $collabINI->variable( 'HandlerSettings', 'Repositories' );
00449     }
00450 
00451     /*!
00452      \static
00453      \return an array with directories which acts as collaboration extension repositories.
00454      \sa handlerRepositories
00455     */
00456     static function extensionRepositories()
00457     {
00458         $collabINI = eZCollaborationItemHandler::ini();
00459         return $collabINI->variable( 'HandlerSettings', 'Extensions' );
00460     }
00461 
00462     /*!
00463      \static
00464      \return an array with directories which acts as collaboration repositories.
00465      \sa defaultRepositories, extensionRepositories
00466     */
00467     static function handlerRepositories()
00468     {
00469         $extensions = eZCollaborationItemHandler::extensionRepositories();
00470         $repositories = eZCollaborationItemHandler::defaultRepositories();
00471         $extensionRoot = eZExtension::baseDirectory();
00472         foreach ( $extensions as $extension )
00473         {
00474             $handlerPath = eZDir::path( array( $extensionRoot, $extension, 'collaboration' ) );
00475             if ( file_exists( $handlerPath ) )
00476                 $repositories[] = $handlerPath;
00477         }
00478         return $repositories;
00479     }
00480 
00481     /*!
00482      \static
00483      \return an array with handler identifiers that are considered active.
00484     */
00485     static function activeHandlers()
00486     {
00487         $collabINI = eZCollaborationItemHandler::ini();
00488         return $collabINI->variable( 'HandlerSettings', 'Active' );
00489     }
00490 
00491     /*!
00492      \static
00493      \return a unique instance of the handler for the identifier \a $handler.
00494      If \a $repositories is left out it will use the handlerRepositories.
00495     */
00496     static function instantiate( $handler, $repositories = false )
00497     {
00498         $objectCache =& $GLOBALS["eZCollaborationHandlerObjectCache"];
00499         if ( !isset( $objectCache ) )
00500             $objectCache = array();
00501         if ( isset( $objectCache[$handler] ) )
00502             return $objectCache[$handler];
00503         if ( $repositories === false )
00504         {
00505             $repositories = eZCollaborationItemHandler::handlerRepositories();
00506         }
00507         $handlerInstance = null;
00508         $foundHandlerFile = false;
00509         $foundHandler = false;
00510         foreach ( $repositories as $repository )
00511         {
00512             $handlerFile = $handler . 'collaborationhandler.php';
00513             $handlerClass = $handler . 'collaborationhandler';
00514             $handlerPath = eZDir::path( array( $repository, $handler, $handlerFile ) );
00515             if ( file_exists( $handlerPath ) )
00516             {
00517                 $foundHandlerFile = true;
00518                 include_once( $handlerPath );
00519                 if ( class_exists( $handlerClass ) )
00520                 {
00521                     $foundHandler = true;
00522                     $handlerInstance = new $handlerClass();
00523                     $objectCache[$handler] = $handlerInstance;
00524                     $handlerClasses = $handlerInstance->classes();
00525                     foreach ( $handlerClasses as $handlerClass )
00526                     {
00527                     }
00528                 }
00529             }
00530         }
00531         if ( !$foundHandlerFile )
00532         {
00533             eZDebug::writeWarning( "Collaboration file '$handlerFile' could not be found in " . implode( ', ', $repositories ), __METHOD__ );
00534         }
00535         else if ( !$foundHandler )
00536         {
00537             eZDebug::writeWarning( "Collaboration class '$handlerClass' does not exist", __METHOD__ );
00538         }
00539         return $handlerInstance;
00540     }
00541 
00542     /*!
00543      \static
00544      \return a list of collaboration handler objects.
00545      \sa instantiate, activeHandlers
00546     */
00547     static function fetchList()
00548     {
00549         $list =& $GLOBALS['eZCollaborationList'];
00550         if ( isset( $list ) )
00551             return $list;
00552         $list = array();
00553         $activeHandlers = eZCollaborationItemHandler::activeHandlers();
00554         $repositories = eZCollaborationItemHandler::handlerRepositories();
00555         foreach ( $activeHandlers as $handler )
00556         {
00557             $handlerInstance = eZCollaborationItemHandler::instantiate( $handler, $repositories );
00558             if ( $handlerInstance !== null )
00559                 $list[] = $handlerInstance;
00560         }
00561         return $list;
00562     }
00563 
00564     /// \privatesection
00565     public $Info;
00566 }
00567 
00568 ?>