diff --git a/code/web/sys/Community/Campaign.php b/code/web/sys/Community/Campaign.php index cf260e6dcc..cec85c22b5 100644 --- a/code/web/sys/Community/Campaign.php +++ b/code/web/sys/Community/Campaign.php @@ -3,6 +3,7 @@ require_once ROOT_DIR . '/sys/Community/CampaignMilestone.php'; require_once ROOT_DIR . '/sys/Community/UserCampaign.php'; require_once ROOT_DIR . '/sys/Community/Reward.php'; +require_once ROOT_DIR . '/sys/Community/CampaignAccess.php'; require_once ROOT_DIR . '/sys/Account/User.php'; @@ -22,11 +23,14 @@ class Campaign extends DataObject { /** @var AvailableMilestones[] */ private $_availableMilestones; + protected $_allowPatronTypeAccess; + public static function getObjectStructure($context = ''): array { $milestoneList = Milestone::getMilestoneList(); $milestoneStructure = CampaignMilestone::getObjectStructure($context); unset($milestoneStructure['campaignId']); + $patronTypeList = PType::getPatronTypeList(); $rewardList = Reward::getRewardList(); return [ 'id' => [ @@ -85,10 +89,53 @@ public static function getObjectStructure($context = ''): array { 'label' => 'Reward for Completing Campaign', 'values' => $rewardList, 'description' => 'The reward given for completing the campaign.' - ] + ], + 'allowPatronTypeAccess' => [ + 'property' => 'allowPatronTypeAccess', + 'type' => 'multiSelect', + 'listStyle' => 'checkboxSimple', + 'label' => 'Patron Type Access', + 'description' => 'Define what patron types should have access to this campaign', + 'values' => $patronTypeList, + 'hideInLists' => false, + ], ]; } + public function getPatronTypeAccess() { + if (!isset($this->_allowPatronTypeAccess) && $this->id) { + $this->_allowPatronTypeAccess = []; + $patronTypeLink = new CampaignAccess(); + $patronTypeLink->campaignId = $this->id; + $patronTypeLink->find(); + while ($patronTypeLink->fetch()) { + $this->_allowPatronTypeAccess[$patronTypeLink->patronTypeId] = $patronTypeLink->patronTypeId; + } + } + return $this->_allowPatronTypeAccess; + } + + public function savePatronTypeAccess() { + if (isset($this->_allowPatronTypeAccess) && is_array($this->_allowPatronTypeAccess)) { + $this->clearPatronTypeAccess(); + + foreach ($this->_allowPatronTypeAccess as $patronTypeId) { + $link = new CampaignAccess(); + $link->campaignId = $this->id; + $link->patronTypeId = $patronTypeId; + $link->insert(); + } + unset($this->_allowPatronTypeAccess); + } + } + + private function clearPatronTypeAccess() { + //Delete links to the patron types + $link = new CampaignAccess(); + $link->campaignId = $this->id; + return $link->delete(true); + } + public function getUsers() { if (is_null($this->_users)) { $this->_users = []; @@ -131,7 +178,9 @@ public function getUsersForCampaign() { } public function __get($name) { - if ($name == 'availableMilestones') { + if ($name == 'allowPatronTypeAccess') { + return $this->getPatronTypeAccess(); + } else if ($name == 'availableMilestones') { return $this->getMilestones(); } else { return parent::__get($name); @@ -139,7 +188,9 @@ public function __get($name) { } public function __set($name, $value) { - if ($name == 'availableMilestones') { + if ($name == 'allowPatronTypeAccess') { + $this->_allowPatronTypeAccess = $value; + } else if ($name == 'availableMilestones') { $this->_availableMilestones = $value; } else { parent::__set($name, $value); @@ -180,6 +231,7 @@ public function getRewardName() { public function update($context = '') { $ret = parent::update(); if ($ret !== FALSE) { + $this->savePatronTypeAccess(); $this->saveMilestones(); } return $ret; @@ -193,11 +245,20 @@ public function update($context = '') { public function insert($context = '') { $ret = parent::insert(); if ($ret !== FALSE) { + $this->savePatronTypeAccess(); $this->saveMilestones(); } return $ret; } + public function delete($useWhere = false) : int { + $ret = parent::delete($useWhere); + if ($ret && !empty($this->id)) { + $this->clearPatronTypeAccess(); + } + return $ret; + } + public static function getAllCampaigns() : array { $campaign = new Campaign(); $campaignList = []; @@ -219,6 +280,27 @@ public static function getCampaignById($id) { return null; } + /** + * Finds and retrieves campaign records based on user access and login status. + * + * If the user is not logged in or is an Aspen admin user, it performs a standard find operation. + * Otherwise, it filters campaigns based on the user's patron type, ensuring that the user has + * access to the campaign. This function supports optional fetching of the first match and + * requires at least one match to return results if specified. + * + * @param bool $fetchFirst Optional. Whether to fetch the first matching record. Default is false. + * @param bool $requireOneMatchToReturn Optional. Whether one match is required to return results. Default is true. + * @return bool True if a record is found, false otherwise. + */ + public function find($fetchFirst = false, $requireOneMatchToReturn = true): bool { + if (!UserAccount::isLoggedIn() || UserAccount::getActiveUserObj()->isAspenAdminUser()) + return parent::find($fetchFirst, $requireOneMatchToReturn); + + $this->joinAdd(new CampaignAccess(), 'INNER', 'ce_campaign_patron_type_access', 'id', 'campaignId'); + $this->whereAdd("ce_campaign_patron_type_access.patronTypeId = '" . UserAccount::getActiveUserObj()->getPTypeObj()->id . "'"); + return parent::find($fetchFirst, $requireOneMatchToReturn); + } + /** * Retrieves a list of active campaigns. * diff --git a/code/web/sys/Community/CampaignAccess.php b/code/web/sys/Community/CampaignAccess.php new file mode 100644 index 0000000000..ae096edb74 --- /dev/null +++ b/code/web/sys/Community/CampaignAccess.php @@ -0,0 +1,9 @@ + [ + 'title' => 'Create Campaign Access', + 'description' => 'Add table for campaign access', + 'sql' => [ + "CREATE TABLE ce_campaign_patron_type_access ( + id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + campaignId INT NOT NULL, + patronTypeId INT NOT NULL + ) ENGINE = InnoDB", + ], + ], 'create_milestones' => [ 'title' => 'Create Milestones', 'description' => 'Add table for milestones',