In this part of our tutorial series, we use the person information added in the previous part to award activity points to users adding new pieces of information and to also create activity events for these pieces of information.
The first step to support activity points is to register an object type for the com.woltlab.wcf.user.activityPointEvent object type definition for created person information and specify the default number of points awarded per piece of information:
Additionally, the phrase wcf.user.activityPoint.objectType.com.woltlab.wcf.people.information (in general: wcf.user.activityPoint.objectType.{objectType}) has to be added.
The activity points are awarded when new pieces are created via PersonInformation::create() using UserActivityPointHandler::fireEvent() and removed in PersonInformation::create() via UserActivityPointHandler::removeEvents() if pieces of information are deleted.
Lastly, we have to add two components for updating data:
First, we register a new rebuild data worker
<?phpnamespacewcf\system\worker;usewcf\data\person\information\PersonInformationList;usewcf\system\user\activity\point\UserActivityPointHandler;/** * Worker implementation for updating person information. * * @author Matthias Schmidt * @copyright 2001-2022 WoltLab GmbH * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php> * @package WoltLabSuite\Core\System\Worker * * @method PersonInformationList getObjectList() */finalclassPersonInformationRebuildDataWorkerextendsAbstractRebuildDataWorker{/** * @inheritDoc */protected$objectListClassName=PersonInformationList::class;/** * @inheritDoc */protected$limit=500;/** * @inheritDoc */protectedfunctioninitObjectList(){parent::initObjectList();$this->objectList->sqlOrderBy='person_information.personID';}/** * @inheritDoc */publicfunctionexecute(){parent::execute();if(!$this->loopCount){UserActivityPointHandler::getInstance()->reset('com.woltlab.wcf.people.information');}if(!\count($this->objectList)){return;}$itemsToUser=[];foreach($this->getObjectList()as$personInformation){if($personInformation->userID){if(!isset($itemsToUser[$personInformation->userID])){$itemsToUser[$personInformation->userID]=0;}$itemsToUser[$personInformation->userID]++;}}UserActivityPointHandler::getInstance()->fireEvents('com.woltlab.wcf.people.information',$itemsToUser,false);}}
which updates the number of instances for which any user received person information activity points.
(This data worker also requires the phrases wcf.acp.rebuildData.com.woltlab.wcf.people.information and wcf.acp.rebuildData.com.woltlab.wcf.people.information.description).
Second, we add an event listener for UserActivityPointItemsRebuildDataWorker to update the total user activity points awarded for person information:
<?phpnamespacewcf\system\event\listener;usewcf\system\database\util\PreparedStatementConditionBuilder;usewcf\system\user\activity\point\UserActivityPointHandler;usewcf\system\WCF;usewcf\system\worker\UserActivityPointItemsRebuildDataWorker;/** * Updates the user activity point items counter for person information. * * @author Matthias Schmidt * @copyright 2001-2022 WoltLab GmbH * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php> * @package WoltLabSuite\Core\System\Event\Listener */finalclassPersonUserActivityPointItemsRebuildDataWorkerListenerextendsAbstractEventListener{protectedfunctiononExecute(UserActivityPointItemsRebuildDataWorker$worker):void{$objectType=UserActivityPointHandler::getInstance()->getObjectTypeByName('com.woltlab.wcf.people.information');$conditionBuilder=newPreparedStatementConditionBuilder();$conditionBuilder->add('user_activity_point.objectTypeID = ?',[$objectType->objectTypeID]);$conditionBuilder->add('user_activity_point.userID IN (?)',[$worker->getObjectList()->getObjectIDs()]);$sql="UPDATE wcf1_user_activity_point user_activity_point SET user_activity_point.items = ( SELECT COUNT(*) FROM wcf1_person_information person_information WHERE person_information.userID = user_activity_point.userID ), user_activity_point.activityPoints = user_activity_point.items * ?{$conditionBuilder}";$statement=WCF::getDB()->prepare($sql);$statement->execute([$objectType->points,...$conditionBuilder->getParameters()]);}}
To support user activity events, an object type for com.woltlab.wcf.user.recentActivityEvent has to be registered with a class implementing wcf\system\user\activity\event\IUserActivityEvent:
<?phpnamespacewcf\system\user\activity\event;usewcf\data\person\information\PersonInformationList;usewcf\system\SingletonFactory;usewcf\system\WCF;/** * User activity event implementation for person information. * * @author Matthias Schmidt * @copyright 2001-2022 WoltLab GmbH * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php> * @package WoltLabSuite\Core\System\User\Activity\Event */finalclassPersonInformationUserActivityEventextendsSingletonFactoryimplementsIUserActivityEvent{/** * @inheritDoc */publicfunctionprepare(array$events){$objectIDs=\array_column($events,'objectID');$informationList=newPersonInformationList();$informationList->setObjectIDs($objectIDs);$informationList->readObjects();$information=$informationList->getObjects();foreach($eventsas$event){if(isset($information[$event->objectID])){$personInformation=$information[$event->objectID];$event->setIsAccessible();$event->setTitle(WCF::getLanguage()->getDynamicVariable('wcf.user.profile.recentActivity.personInformation',['person'=>$personInformation->getPerson(),'personInformation'=>$personInformation,]));$event->setDescription($personInformation->getFormattedExcerpt());}}}}
PersonInformationUserActivityEvent::prepare() must check for all events whether the associated piece of information still exists and if it is the case, mark the event as accessible via the setIsAccessible() method, set the title of the activity event via setTitle(), and set a description of the event via setDescription() for which we use the newly added PersonInformation::getFormattedExcerpt() method.
Lastly, we have to add the phrase wcf.user.recentActivity.com.woltlab.wcf.people.information, which is shown in the list of activity events as the type of activity event.