From e06196cafb2856f44fc49bd2eb4294ac53a574bf Mon Sep 17 00:00:00 2001 From: Pedro Amorim Date: Fri, 8 Nov 2024 14:43:15 -0100 Subject: [PATCH] anotehr WIP --- code/web/services/Community/AJAX.php | 1 + code/web/sys/Community/CampaignMilestone.php | 169 ++++++++++++++++++ .../CampaignMilestoneProgressEntry.php | 6 +- code/web/sys/Community/Milestone.php | 163 ----------------- code/web/sys/Community/action-hooks.php | 44 ++--- .../community_engagement_updates.php | 14 +- 6 files changed, 203 insertions(+), 194 deletions(-) diff --git a/code/web/services/Community/AJAX.php b/code/web/services/Community/AJAX.php index 4da099986b..0f67627381 100644 --- a/code/web/services/Community/AJAX.php +++ b/code/web/services/Community/AJAX.php @@ -34,6 +34,7 @@ function milestoneRewardGivenUpdate() { $milestoneId = $_GET['milestoneId']; $campaignMilestoneProgress = new CampaignMilestoneUsersProgress(); + #TODO: Add a campaignId check $campaignMilestoneProgress->userId = $userId; $campaignMilestoneProgress->milestoneId = $milestoneId; diff --git a/code/web/sys/Community/CampaignMilestone.php b/code/web/sys/Community/CampaignMilestone.php index 802951c7f2..d829fdff03 100644 --- a/code/web/sys/Community/CampaignMilestone.php +++ b/code/web/sys/Community/CampaignMilestone.php @@ -122,4 +122,173 @@ public static function getMilestoneProgress($campaignId, $userId, $milestoneId) ]; } + /** + * Gets a list of milestones for a given object and table name that are related to + * a patron enrolled in an active campaign and of type $tableName + * + * @param object $object The object to check + * @param string $tableName The table name to check for + * @param int $userId The user id of the patron + * @return CampaignMilestone|false Returns a Milestone object if one is found, false otherwise + */ + public static function getCampaignMilestonesToUpdate($object, $tableName, $userId) + { + + # Bail if not the table we want + if ($object->__table != $tableName) + return false; + + # Bail if no active campaigns exist + $activeCampaigns = Campaign::getActiveCampaignsList(); + if (!count($activeCampaigns)) + return false; + + # Bail if this object does not relate to a patron enrolled in an active campaign + $userCampaigns = new UserCampaign(); + $userCampaigns->whereAdd("campaignId IN (" . implode(",", array_keys($activeCampaigns)) . ")"); + $userCampaigns->userId = $userId; + if (!$userCampaigns->find()) + return false; + + # Bail if no user active campaigns' milestones are of type $tableName + $userActiveCampaigns = []; + while ($userCampaigns->fetch()) { + array_push($userActiveCampaigns, $userCampaigns->campaignId); + } + $campaignMilestone = new CampaignMilestone(); + $campaignMilestone->milestoneType = $tableName; + $campaignMilestone->joinAdd(new Milestone(), 'LEFT', 'milestones', 'milestoneId', 'id'); + $campaignMilestone->whereAdd('milestones.milestoneType = "' . $tableName . '" AND ce_campaign_milestones.campaignId IN (' . implode(',', $userActiveCampaigns) . ')'); + + if (!$campaignMilestone->find()) + return false; + + + #This is returning 4? + var_dump($campaignMilestone); + + return $campaignMilestone; + } + + /** + * Adds a new CampaignMilestoneProgressEntry for a given milestone, object, and user. + * + * @param Milestone $milestone The milestone associated with this progress entry. + * @param mixed $object The object associated with this progress entry. + * @param int $userId The user id associated with this progress entry. + */ + public function addCampaignMilestoneProgressEntry( $object, $userId) + { + require_once ROOT_DIR . '/sys/Community/UserCampaign.php'; + + if (!$this->conditionalsCheck($object)) + return; + + # Check if this campaign milestone already has progress for this user + $campaignMilestoneUsersProgress = new CampaignMilestoneUsersProgress(); + $campaignMilestoneUsersProgress->ce_milestone_id = $this->ce_milestone_id; + $campaignMilestoneUsersProgress->ce_campaign_id = $this->ce_campaign_id; + $campaignMilestoneUsersProgress->userId = $userId; + + # If there isn't one, create it. + if (!$campaignMilestoneUsersProgress->find(true)) { + $campaignMilestoneUsersProgress->progress = 0; + $campaignMilestoneUsersProgress->insert(); + } + + $campaignMilestoneProgressEntry = new CampaignMilestoneProgressEntry(); + $campaignMilestoneProgressEntry->initialize( + $this, + [ + "object" => $object, + "userId" => $userId, + "campaignMilestoneUsersProgress" => $campaignMilestoneUsersProgress + ] + ); + + $campaignMilestoneUsersProgress->progress++; + $campaignMilestoneUsersProgress->update(); + } + + /** + * Checks if a given object meets the conditionals of this milestone. + * + * If the object does not have a groupedWorkId, it is assumed to meet the conditionals. + * If the milestone does not have a conditional operator, field, or value, it is assumed + * to meet the conditionals. + * + * Otherwise, this method uses the groupedWorkDriver to get the value of the specified + * field from the grouped work. It then checks if the value matches the conditional + * operator and value. If it does, it returns true. If not, it returns false. + * + * @param mixed $object The object to check against the conditionals. + * @return bool True if the object meets the conditionals, false otherwise. + */ + protected function conditionalsCheck($object) + { + + if (!$this->conditionalOperator || !$this->conditionalValue || !$this->conditionalField) + return true; + + if (!$object->groupedWorkId) + return false; + + if( $this->conditionalField == 'user_list' && is_numeric($this->conditionalValue) ) { + return $this->conditionalsListCheck($object); + } + + require_once ROOT_DIR . '/RecordDrivers/GroupedWorkDriver.php'; + $groupedWorkDriver = new GroupedWorkDriver($object->groupedWorkId); + + if (!$fieldValues = $groupedWorkDriver->getSolrField($this->conditionalField)) + return false; + + if(!is_array($fieldValues)){ + $fieldValues = [$fieldValues]; + } + + if ($this->conditionalOperator == 'like') { + #Convert this foreach to array_map + foreach ($fieldValues as $fieldValue) { + if (str_contains(strtolower($fieldValue), strtolower($this->conditionalValue))) { + return true; + } + } + return false; + } elseif ($this->conditionalOperator == 'equals') { + foreach ($fieldValues as $fieldValue) { + if (strtolower($fieldValue) == strtolower($this->conditionalValue)) { + return true; + } + } + return false; + } elseif ($this->conditionalOperator == 'is_not') { + foreach ($fieldValues as $fieldValue) { + if (strtolower($fieldValue) != strtolower($this->conditionalValue)) { + return true; + } + } + return false; + } + + return false; + } + + /** + * Checks if a grouped work is on a certain list. + * + * @param $object The grouped work object to check. + * + * @return bool true if the grouped work is on the list, false otherwise. + */ + protected function conditionalsListCheck($object){ + require_once ROOT_DIR . '/sys/UserLists/UserListEntry.php'; + $listEntry = new UserListEntry(); + $listEntry->whereAdd("source ='GroupedWork'"); + $listEntry->whereAdd("sourceId ='" . $object->groupedWorkId . "'"); + $whereOp = $this->conditionalOperator == 'is_not' ? '!=' : '='; + $listEntry->whereAdd('listId '.$whereOp. ' ' . $this->conditionalValue); + return $listEntry->find(true); + } + } \ No newline at end of file diff --git a/code/web/sys/Community/CampaignMilestoneProgressEntry.php b/code/web/sys/Community/CampaignMilestoneProgressEntry.php index 0fd4e40b27..534b6abd96 100644 --- a/code/web/sys/Community/CampaignMilestoneProgressEntry.php +++ b/code/web/sys/Community/CampaignMilestoneProgressEntry.php @@ -15,7 +15,7 @@ class CampaignMilestoneProgressEntry extends DataObject /** * Initializes a new CampaignMilestoneProgressEntry object by setting its ce_milestone_id to the provided milestone object * - * @param Milestone $milestone The milestone associated with this progress entry. + * @param CampaignMilestone $campaignMilestone The campaign milestone associated with this progress entry. * @param mixed $args Optional arguments to further configure the progress entry. Expects the following structure: * * [ @@ -26,10 +26,10 @@ class CampaignMilestoneProgressEntry extends DataObject * * @return void */ - public function initialize(Milestone $milestone, $args = null) + public function initialize(CampaignMilestone $campaignMilestone, $args = null) { - $this->ce_milestone_id = $milestone->id; + $this->ce_milestone_id = $campaignMilestone->ce_milestone_id; if (!$args) return; diff --git a/code/web/sys/Community/Milestone.php b/code/web/sys/Community/Milestone.php index 69c56278a8..6793a6efd0 100644 --- a/code/web/sys/Community/Milestone.php +++ b/code/web/sys/Community/Milestone.php @@ -120,169 +120,6 @@ public static function getConditionalFields() { return $conditionalFields; } - /** - * Gets a list of milestones for a given object and table name that are related to - * a patron enrolled in an active campaign and of type $tableName - * - * @param object $object The object to check - * @param string $tableName The table name to check for - * @param int $userId The user id of the patron - * @return Milestone|false Returns a Milestone object if one is found, false otherwise - */ - public static function getMilestonesToUpdate($object, $tableName, $userId) - { - - # Bail if not the table we want - if ($object->__table != $tableName) - return false; - - # Bail if no active campaigns exist - $activeCampaigns = Campaign::getActiveCampaignsList(); - if (!count($activeCampaigns)) - return false; - - # Bail if this object does not relate to a patron enrolled in an active campaign - $userCampaigns = new UserCampaign(); - $userCampaigns->whereAdd("campaignId IN (" . implode(",", array_keys($activeCampaigns)) . ")"); - $userCampaigns->userId = $userId; - if (!$userCampaigns->find()) - return false; - - # Bail if no user active campaigns' milestones are of type $tableName - $userActiveCampaigns = []; - while ($userCampaigns->fetch()) { - array_push($userActiveCampaigns, $userCampaigns->campaignId); - } - $milestone = new Milestone(); - $milestone->milestoneType = $tableName; - $milestone->joinAdd(new CampaignMilestone(), 'LEFT', 'campaignMilestones', 'id', 'milestoneId'); - $milestone->whereAdd('campaignMilestones.campaignId IN (' . implode(',', $userActiveCampaigns) . ')'); - - if (!$milestone->find()) - return false; - return $milestone; - } - - /** - * Adds a new CampaignMilestoneProgressEntry for a given milestone, object, and user. - * - * @param Milestone $milestone The milestone associated with this progress entry. - * @param mixed $object The object associated with this progress entry. - * @param int $userId The user id associated with this progress entry. - */ - public function addCampaignMilestoneProgressEntry( $object, $userId) - { - require_once ROOT_DIR . '/sys/Community/UserCampaign.php'; - - if (!$this->conditionalsCheck($object)) - return; - - # Check if this milestone already has progress for this user - $campaignMilestoneUsersProgress = new CampaignMilestoneUsersProgress(); - $campaignMilestoneUsersProgress->ce_milestone_id = $this->id; - $campaignMilestoneUsersProgress->userId = $userId; - - # If there isn't one, create it. - if (!$campaignMilestoneUsersProgress->find(true)) { - $campaignMilestoneUsersProgress->progress = 0; - $campaignMilestoneUsersProgress->insert(); - } - - $campaignMilestoneProgressEntry = new CampaignMilestoneProgressEntry(); - $campaignMilestoneProgressEntry->initialize( - $this, - [ - "object" => $object, - "userId" => $userId, - "campaignMilestoneUsersProgress" => $campaignMilestoneUsersProgress - ] - ); - - $campaignMilestoneUsersProgress->progress++; - $campaignMilestoneUsersProgress->update(); - } - - /** - * Checks if a given object meets the conditionals of this milestone. - * - * If the object does not have a groupedWorkId, it is assumed to meet the conditionals. - * If the milestone does not have a conditional operator, field, or value, it is assumed - * to meet the conditionals. - * - * Otherwise, this method uses the groupedWorkDriver to get the value of the specified - * field from the grouped work. It then checks if the value matches the conditional - * operator and value. If it does, it returns true. If not, it returns false. - * - * @param mixed $object The object to check against the conditionals. - * @return bool True if the object meets the conditionals, false otherwise. - */ - protected function conditionalsCheck($object) - { - - if (!$this->conditionalOperator || !$this->conditionalValue || !$this->conditionalField) - return true; - - if (!$object->groupedWorkId) - return false; - - if( $this->conditionalField == 'user_list' && is_numeric($this->conditionalValue) ) { - return $this->conditionalsListCheck($object); - } - - require_once ROOT_DIR . '/RecordDrivers/GroupedWorkDriver.php'; - $groupedWorkDriver = new GroupedWorkDriver($object->groupedWorkId); - - if (!$fieldValues = $groupedWorkDriver->getSolrField($this->conditionalField)) - return false; - - if(!is_array($fieldValues)){ - $fieldValues = [$fieldValues]; - } - - if ($this->conditionalOperator == 'like') { - #Convert this foreach to array_map - foreach ($fieldValues as $fieldValue) { - if (str_contains(strtolower($fieldValue), strtolower($this->conditionalValue))) { - return true; - } - } - return false; - } elseif ($this->conditionalOperator == 'equals') { - foreach ($fieldValues as $fieldValue) { - if (strtolower($fieldValue) == strtolower($this->conditionalValue)) { - return true; - } - } - return false; - } elseif ($this->conditionalOperator == 'is_not') { - foreach ($fieldValues as $fieldValue) { - if (strtolower($fieldValue) != strtolower($this->conditionalValue)) { - return true; - } - } - return false; - } - - return false; - } - - /** - * Checks if a grouped work is on a certain list. - * - * @param $object The grouped work object to check. - * - * @return bool true if the grouped work is on the list, false otherwise. - */ - protected function conditionalsListCheck($object){ - require_once ROOT_DIR . '/sys/UserLists/UserListEntry.php'; - $listEntry = new UserListEntry(); - $listEntry->whereAdd("source ='GroupedWork'"); - $listEntry->whereAdd("sourceId ='" . $object->groupedWorkId . "'"); - $whereOp = $this->conditionalOperator == 'is_not' ? '!=' : '='; - $listEntry->whereAdd('listId '.$whereOp. ' ' . $this->conditionalValue); - return $listEntry->find(true); - } - /** * @return array */ diff --git a/code/web/sys/Community/action-hooks.php b/code/web/sys/Community/action-hooks.php index 1860dcdb99..98ccd17501 100644 --- a/code/web/sys/Community/action-hooks.php +++ b/code/web/sys/Community/action-hooks.php @@ -1,6 +1,6 @@ userId); - if (!$milestone) + $campaignMilestone = CampaignMilestone::getCampaignMilestonesToUpdate($value, 'user_checkout', $value->userId); + if (!$campaignMilestone) return; - while ($milestone->fetch()) { - if (_campaignMilestoneProgressEntryObjectAlreadyExists($value, $milestone)) + while ($campaignMilestone->fetch()) { + if (_campaignMilestoneProgressEntryObjectAlreadyExists($value, $campaignMilestone)) return; - $milestone->addCampaignMilestoneProgressEntry($value, $value->userId); + $campaignMilestone->addCampaignMilestoneProgressEntry($value, $value->userId); } return; }); @@ -36,15 +36,15 @@ */ add_action('after_object_insert', 'after_hold_insert', function ($value) { - $milestone = Milestone::getMilestonesToUpdate($value, 'user_hold', $value->userId); - if (!$milestone) + $campaignMilestone = CampaignMilestone::getCampaignMilestonesToUpdate($value, 'user_hold', $value->userId); + if (!$campaignMilestone) return; - while ($milestone->fetch()) { - if (_campaignMilestoneProgressEntryObjectAlreadyExists($value, $milestone)) + while ($campaignMilestone->fetch()) { + if (_campaignMilestoneProgressEntryObjectAlreadyExists($value, $campaignMilestone)) return; - $milestone->addCampaignMilestoneProgressEntry($value, $value->userId); + $campaignMilestone->addCampaignMilestoneProgressEntry($value, $value->userId); } return; }); @@ -59,12 +59,12 @@ */ add_action('after_object_insert', 'after_list_insert', function ($value) { - $milestone = Milestone::getMilestonesToUpdate($value, 'user_list', $value->user_id); - if (!$milestone) + $campaignMilestone = CampaignMilestone::getCampaignMilestonesToUpdate($value, 'user_list', $value->user_id); + if (!$campaignMilestone) return; - while ($milestone->fetch()) { - $milestone->addCampaignMilestoneProgressEntry($value, $value->user_id); + while ($campaignMilestone->fetch()) { + $campaignMilestone->addCampaignMilestoneProgressEntry($value, $value->user_id); } return; }); @@ -79,12 +79,12 @@ */ add_action('after_object_insert', 'after_work_review_insert', function ($value) { - $milestone = Milestone::getMilestonesToUpdate($value, 'user_work_review', $value->userId); - if (!$milestone) + $campaignMilestone = CampaignMilestone::getCampaignMilestonesToUpdate($value, 'user_work_review', $value->userId); + if (!$campaignMilestone) return; - while ($milestone->fetch()) { - $milestone->addCampaignMilestoneProgressEntry($value, $value->userId); + while ($campaignMilestone->fetch()) { + $campaignMilestone->addCampaignMilestoneProgressEntry($value, $value->userId); } return; }); @@ -95,13 +95,13 @@ * For example, for checkouts and holds, these may be purged from the database and re-fetched from the ILS. * * @param object $value The object containing the sourceId, recordId, and userId. - * @param Milestone $milestone The milestone object. + * @param CampaignMilestone $campaignMilestone The milestone object. * @return bool Returns true if an entry exists, false otherwise. */ -function _campaignMilestoneProgressEntryObjectAlreadyExists($value, $milestone) +function _campaignMilestoneProgressEntryObjectAlreadyExists($value, $campaignMilestone) { $campaignMilestoneProgressEntryCheck = new CampaignMilestoneProgressEntry(); - $campaignMilestoneProgressEntryCheck->initialize($milestone); + $campaignMilestoneProgressEntryCheck->initialize($campaignMilestone); if ($campaignMilestoneProgressEntryCheck->find()) { while ($campaignMilestoneProgressEntryCheck->fetch()) { $decoded_object = json_decode($campaignMilestoneProgressEntryCheck->object); diff --git a/code/web/sys/DBMaintenance/community_engagement_updates.php b/code/web/sys/DBMaintenance/community_engagement_updates.php index 037428c21f..7b72a4e498 100644 --- a/code/web/sys/DBMaintenance/community_engagement_updates.php +++ b/code/web/sys/DBMaintenance/community_engagement_updates.php @@ -60,6 +60,7 @@ function getCommunityEngagementUpdates() { "CREATE TABLE IF NOT EXISTS ce_campaign_milestone_progress_entries ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, userId INT NOT NULL, + ce_campaign_id INT NOT NULL, #TODO: this may not be needed ce_milestone_id INT NOT NULL, ce_campaign_milestone_users_progress_id INT NOT NULL, tableName VARCHAR(100), @@ -75,6 +76,7 @@ function getCommunityEngagementUpdates() { "CREATE TABLE IF NOT EXISTS ce_campaign_milestone_users_progress ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, userId INT NOT NULL, + ce_campaign_id INT NOT NULL, ce_milestone_id INT NOT NULL, progress INT NOT NULL, rewardGiven TINYINT DEFAULT 0 @@ -214,8 +216,8 @@ function getCommunityEngagementUpdates() { (1, 1, 10, -1), (2, 2, 10, -1), (2, 3, 10, -1), - (3, 3, 10, -1), (2, 4, 15, -1), + (3, 3, 10, -1), (3, 4, 10, -1), (5, 5, 12, -1)", # Insert rewards @@ -224,11 +226,11 @@ function getCommunityEngagementUpdates() { ('Test Reward 2', 'This is a test reward', 0), ('Test Reward 3', 'This is a test reward', 0)", # Insert some users milestones progress - "INSERT INTO ce_campaign_milestone_users_progress (userId, ce_milestone_id, progress, rewardGiven) VALUES - (3, 1, 4, 1), - (3, 2, 6, 0), - (3, 3, 3, 1), - (3, 4, 8, 0)", + "INSERT INTO ce_campaign_milestone_users_progress (userId, ce_campaign_id, ce_milestone_id, progress, rewardGiven) VALUES + (3, 5, 1, 4, 1), + (3, 2, 2, 6, 0), + (3, 2, 3, 3, 1), + (3, 2, 4, 8, 0)", # Enable the community module "UPDATE modules SET enabled = 1 WHERE name = 'Community'" ],