From 0f045fcdb96c0b894b0e7750898054d0958499e3 Mon Sep 17 00:00:00 2001 From: Jonas Raoni Soares da Silva Date: Sat, 20 May 2023 11:31:29 +0300 Subject: [PATCH] pkp/pkp-lib#8333 Updated code to consider the possibility of having NULL instead of 0 --- classes/context/ContextDAO.php | 2 +- classes/emailTemplate/DAO.php | 6 +-- classes/filter/FilterDAO.php | 52 +++++++++---------- classes/filter/FilterGroupDAO.php | 4 +- classes/filter/PersistableFilter.php | 4 +- classes/log/EmailLogDAO.php | 2 +- classes/navigationMenu/NavigationMenuDAO.php | 14 ++--- .../NavigationMenuItemAssignmentDAO.php | 10 ++-- .../navigationMenu/NavigationMenuItemDAO.php | 20 +++---- classes/notification/NotificationDAO.php | 16 +++--- .../NotificationSubscriptionSettingsDAO.php | 2 +- classes/notification/PKPNotification.php | 2 +- classes/plugins/PluginSettingsDAO.php | 12 ++--- classes/security/RoleDAO.php | 12 ++--- classes/security/Validation.php | 2 +- classes/site/VersionDAO.php | 2 +- .../stageAssignment/StageAssignmentDAO.php | 2 +- classes/user/Collector.php | 2 +- classes/user/User.php | 2 + classes/userGroup/Collector.php | 2 +- classes/userGroup/DAO.php | 2 +- classes/userGroup/UserGroup.php | 6 +-- .../userGroup/relationships/UserUserGroup.php | 3 +- 23 files changed, 90 insertions(+), 91 deletions(-) diff --git a/classes/context/ContextDAO.php b/classes/context/ContextDAO.php index 5d702a04f5d..77c3f17f376 100644 --- a/classes/context/ContextDAO.php +++ b/classes/context/ContextDAO.php @@ -192,7 +192,7 @@ public function resequence() $result = $this->retrieve('SELECT ' . $this->primaryKeyColumn . ' AS context_id FROM ' . $this->tableName . ' ORDER BY seq'); $i = 1; for ($i = 1; $row = (array) $result->current(); $i += 2 && $result->next()) { - $this->update('UPDATE ' . $this->tableName . ' SET seq = ? WHERE ' . $this->primaryKeyColumn . ' = ?', [$i, $row['context_id']]); + $this->update('UPDATE ' . $this->tableName . ' SET seq = ? WHERE COALESCE(' . $this->primaryKeyColumn . ', 0) = ?', [$i, (int) $row['context_id']]); $result->next(); $i += 2; } diff --git a/classes/emailTemplate/DAO.php b/classes/emailTemplate/DAO.php index 779c0ecc4b3..fd76066ea41 100644 --- a/classes/emailTemplate/DAO.php +++ b/classes/emailTemplate/DAO.php @@ -161,9 +161,9 @@ public function fromRow(object $row): EmailTemplate $schema = $this->schemaService->get($this->schema); $contextDao = Application::getContextDAO(); - $supportedLocalesJson = $row->context_id === PKPApplication::CONTEXT_SITE ? - DB::table('site')->first()->supported_locales : - DB::table($contextDao->settingsTableName) + $supportedLocalesJson = (int) $row->context_id === PKPApplication::CONTEXT_SITE + ? DB::table('site')->first()->supported_locales + : DB::table($contextDao->settingsTableName) ->where($contextDao->primaryKeyColumn, $row->context_id) ->where('setting_name', 'supportedLocales') ->value('setting_value'); diff --git a/classes/filter/FilterDAO.php b/classes/filter/FilterDAO.php index c3e4f7d8137..ca18d2b9972 100644 --- a/classes/filter/FilterDAO.php +++ b/classes/filter/FilterDAO.php @@ -65,13 +65,13 @@ class FilterDAO extends \PKP\db\DAO * @param array $settings key-value pairs that can be directly written * via \PKP\core\DataObject::setData(). * @param bool $asTemplate - * @param int $contextId the context the filter should be installed into + * @param ?int $contextId the context the filter should be installed into * @param array $subFilters sub-filters (only allowed when the filter is a CompositeFilter) * @param bool $persist whether to actually persist the filter * * @return PersistableFilter|boolean the new filter if installation successful, otherwise 'false'. */ - public function configureObject($filterClassName, $filterGroupSymbolic, $settings = [], $asTemplate = false, $contextId = 0, $subFilters = [], $persist = true) + public function configureObject($filterClassName, $filterGroupSymbolic, $settings = [], $asTemplate = false, $contextId = null, $subFilters = [], $persist = true) { // Retrieve the filter group from the database. $filterGroupDao = DAORegistry::getDAO('FilterGroupDAO'); /** @var FilterGroupDAO $filterGroupDao */ @@ -127,11 +127,11 @@ public function configureObject($filterClassName, $filterGroupSymbolic, $setting * Insert a new filter instance (transformation). * * @param PersistableFilter $filter The configured filter instance to be persisted - * @param int $contextId + * @param ?int $contextId * * @return int the new filter id */ - public function insertObject($filter, $contextId = \PKP\core\PKPApplication::CONTEXT_ID_NONE) + public function insertObject($filter, $contextId = null) { $filterGroup = $filter->getFilterGroup(); assert($filterGroup->getSymbolic() != FILTER_GROUP_TEMPORARY_ONLY); @@ -141,12 +141,12 @@ public function insertObject($filter, $contextId = \PKP\core\PKPApplication::CON (filter_group_id, context_id, display_name, class_name, is_template, parent_filter_id, seq) VALUES (?, ?, ?, ?, ?, ?, ?)'), [ - (int) $filterGroup->getId(), - (int) $contextId, + (int) $filterGroup->getId() ?: null, + (int) $contextId ?: null, $filter->getDisplayName(), $filter->getClassName(), $filter->getIsTemplate() ? 1 : 0, - (int) $filter->getParentFilterId(), + (int) $filter->getParentFilterId() ?: null, (int) $filter->getSequence() ] ); @@ -187,7 +187,7 @@ public function getObjectById($filterId, $allowSubfilter = false) { $result = $this->retrieve( 'SELECT * FROM filters - WHERE ' . ($allowSubfilter ? '' : 'parent_filter_id = 0 AND ') . ' + WHERE ' . ($allowSubfilter ? '' : 'parent_filter_id IS NULL AND ') . ' filter_id = ?', [(int) $filterId] ); @@ -200,20 +200,20 @@ public function getObjectById($filterId, $allowSubfilter = false) * (transformations) that are based on the given class. * * @param string $className - * @param int $contextId + * @param ?int $contextId * @param bool $getTemplates set true if you want filter templates * rather than actual transformations * @param bool $allowSubfilters * * @return DAOResultFactory */ - public function getObjectsByClass($className, $contextId = \PKP\core\PKPApplication::CONTEXT_ID_NONE, $getTemplates = false, $allowSubfilters = false) + public function getObjectsByClass($className, $contextId = null, $getTemplates = false, $allowSubfilters = false) { $result = $this->retrieve( - 'SELECT * FROM filters - WHERE context_id = ? AND + 'SELECT * FROM filters + WHERE COALESCE(context_id, 0) = ? AND LOWER(class_name) = LOWER(?) AND - ' . ($allowSubfilters ? '' : ' parent_filter_id = 0 AND ') . ' + ' . ($allowSubfilters ? '' : ' parent_filter_id IS NULL AND ') . ' ' . ($getTemplates ? ' is_template = 1' : ' is_template = 0'), [(int) $contextId, $className] ); @@ -228,20 +228,20 @@ public function getObjectsByClass($className, $contextId = \PKP\core\PKPApplicat * * @param string $groupSymbolic * @param string $className - * @param int $contextId + * @param ?int $contextId * @param bool $getTemplates set true if you want filter templates * rather than actual transformations * @param bool $allowSubfilters * * @return DAOResultFactory */ - public function getObjectsByGroupAndClass($groupSymbolic, $className, $contextId = \PKP\core\PKPApplication::CONTEXT_ID_NONE, $getTemplates = false, $allowSubfilters = false) + public function getObjectsByGroupAndClass($groupSymbolic, $className, $contextId = null, $getTemplates = false, $allowSubfilters = false) { $result = $this->retrieve( 'SELECT f.* FROM filters f' . ' INNER JOIN filter_groups fg ON f.filter_group_id = fg.filter_group_id' . - ' WHERE fg.symbolic = ? AND f.context_id = ? AND LOWER(f.class_name) = LOWER(?)' . - ' ' . ($allowSubfilters ? '' : 'AND f.parent_filter_id = 0') . + ' WHERE fg.symbolic = ? AND COALESCE(f.context_id, 0) = ? AND LOWER(f.class_name) = LOWER(?)' . + ' ' . ($allowSubfilters ? '' : 'AND f.parent_filter_id IS NULL') . ' AND ' . ($getTemplates ? 'f.is_template = 1' : 'f.is_template = 0'), [$groupSymbolic, (int) $contextId, $className] ); @@ -280,7 +280,7 @@ public function getObjectsByTypeDescription($inputTypeDescription, $outputTypeDe ' INNER JOIN filter_groups fg ON f.filter_group_id = fg.filter_group_id' . ' WHERE LOWER(fg.input_type) LIKE LOWER(?)' . ' AND LOWER(fg.output_type) LIKE LOWER(?)' . - ' AND f.parent_filter_id = 0 AND f.is_template = 0', + ' AND f.parent_filter_id IS NULL AND f.is_template = 0', [$inputTypeDescription, $outputTypeDescription] ); @@ -325,7 +325,7 @@ public function getObjectsByTypeDescription($inputTypeDescription, $outputTypeDe * will be returned when $checkRuntimeEnvironment is set to 'true'. * * @param string $groupSymbolic - * @param int $contextId returns filters from context 0 and + * @param ?int $contextId returns filters from context 0 and * the given filters of all contexts if set to null * @param bool $getTemplates set true if you want filter templates * rather than actual transformations @@ -334,15 +334,15 @@ public function getObjectsByTypeDescription($inputTypeDescription, $outputTypeDe * * @return array filter instances (transformations) in the given group */ - public function getObjectsByGroup($groupSymbolic, $contextId = \PKP\core\PKPApplication::CONTEXT_ID_NONE, $getTemplates = false, $checkRuntimeEnvironment = true) + public function getObjectsByGroup($groupSymbolic, $contextId = null, $getTemplates = false, $checkRuntimeEnvironment = true) { // 1) Get all available transformations in the group. $result = $this->retrieve( 'SELECT f.* FROM filters f' . ' INNER JOIN filter_groups fg ON f.filter_group_id = fg.filter_group_id' . ' WHERE LOWER(fg.symbolic) = LOWER(?) AND ' . ($getTemplates ? 'f.is_template = 1' : 'f.is_template = 0') . - ' ' . ($contextId ? 'AND f.context_id in (0, ' . (int)$contextId . ')' : '') . - ' AND f.parent_filter_id = 0', + ' ' . ($contextId ? 'AND COALESCE(f.context_id, 0) IN (0, ' . (int)$contextId . ')' : '') . + ' AND f.parent_filter_id IS NULL', [$groupSymbolic] ); @@ -381,11 +381,11 @@ class_name = ?, seq = ? WHERE filter_id = ?', [ - (int) $filterGroup->getId(), + (int) $filterGroup->getId() ?: null, $filter->getDisplayName(), $filter->getClassName(), $filter->getIsTemplate() ? 1 : 0, - (int) $filter->getParentFilterId(), + (int) $filter->getParentFilterId() ?: null, (int) $filter->getSequence(), (int) $filter->getId() ] @@ -541,13 +541,13 @@ public function _fromRow($row) $lockedFilters[$filterId] = true; // Instantiate the filter. - $filter = $this->_newDataObject($row['class_name'], (int)$row['filter_group_id']); + $filter = $this->_newDataObject($row['class_name'], (int)$row['filter_group_id'] ?: null); // Configure the filter instance $filter->setId((int)$row['filter_id']); $filter->setDisplayName($row['display_name']); $filter->setIsTemplate((bool)$row['is_template']); - $filter->setParentFilterId((int)$row['parent_filter_id']); + $filter->setParentFilterId((int) $row['parent_filter_id'] ?: null); $filter->setSequence((int)$row['seq']); $this->getDataObjectSettings('filter_settings', 'filter_id', $row['filter_id'], $filter); diff --git a/classes/filter/FilterGroupDAO.php b/classes/filter/FilterGroupDAO.php index b2f9757121e..d0a4ad62d9f 100644 --- a/classes/filter/FilterGroupDAO.php +++ b/classes/filter/FilterGroupDAO.php @@ -70,8 +70,8 @@ public function getObjectById($filterGroupId) { $result = $this->retrieve( 'SELECT * FROM filter_groups' . - ' WHERE filter_group_id = ?', - [$filterGroupId] + ' WHERE COALESCE(filter_group_id, 0) = ?', + [(int) $filterGroupId] ); $row = (array) $result->current(); return $row ? $this->_fromRow($row) : null; diff --git a/classes/filter/PersistableFilter.php b/classes/filter/PersistableFilter.php index f742431841f..cfff3205d78 100644 --- a/classes/filter/PersistableFilter.php +++ b/classes/filter/PersistableFilter.php @@ -126,7 +126,7 @@ public function getIsTemplate() /** * Set the parent filter id * - * @param int $parentFilterId + * @param ?int $parentFilterId */ public function setParentFilterId($parentFilterId) { @@ -136,7 +136,7 @@ public function setParentFilterId($parentFilterId) /** * Get the parent filter id * - * @return int + * @return ?int */ public function getParentFilterId() { diff --git a/classes/log/EmailLogDAO.php b/classes/log/EmailLogDAO.php index 75daa5c4e8b..a116eb5b0a3 100644 --- a/classes/log/EmailLogDAO.php +++ b/classes/log/EmailLogDAO.php @@ -156,7 +156,7 @@ public function insertObject($entry) $this->datetimeToDB($entry->getDateSent()) ), [ - $entry->getSenderId(), + $entry->getSenderId() ?: null, $entry->getEventType(), $entry->getAssocType(), $entry->getAssocId(), diff --git a/classes/navigationMenu/NavigationMenuDAO.php b/classes/navigationMenu/NavigationMenuDAO.php index ca0316f5d8b..a6d1001951d 100644 --- a/classes/navigationMenu/NavigationMenuDAO.php +++ b/classes/navigationMenu/NavigationMenuDAO.php @@ -54,7 +54,7 @@ public function getById($navigationMenuId, $contextId = null) } $result = $this->retrieve( 'SELECT * FROM navigation_menus WHERE navigation_menu_id = ?' . - ($contextId !== null ? ' AND context_id = ?' : ''), + ($contextId !== null ? ' AND COALESCE(context_id, 0) = ?' : ''), $params ); @@ -71,7 +71,7 @@ public function getById($navigationMenuId, $contextId = null) */ public function getByContextId($contextId) { - $result = $this->retrieve('SELECT * FROM navigation_menus WHERE context_id = ?', [(int) $contextId]); + $result = $this->retrieve('SELECT * FROM navigation_menus WHERE COALESCE(context_id, 0) = ?', [(int) $contextId]); return new DAOResultFactory($result, $this, '_fromRow'); } @@ -85,7 +85,7 @@ public function getByContextId($contextId) */ public function getByArea($contextId, $areaName) { - $result = $this->retrieve('SELECT * FROM navigation_menus WHERE area_name = ? and context_id = ?', [$areaName, (int) $contextId]); + $result = $this->retrieve('SELECT * FROM navigation_menus WHERE area_name = ? AND COALESCE(context_id, 0) = ?', [$areaName, (int) $contextId]); return new DAOResultFactory($result, $this, '_fromRow'); } @@ -99,7 +99,7 @@ public function getByArea($contextId, $areaName) */ public function getByTitle($contextId, $title) { - $result = $this->retrieve('SELECT * FROM navigation_menus WHERE context_id = ? and title = ?', [(int) $contextId, $title]); + $result = $this->retrieve('SELECT * FROM navigation_menus WHERE COALESCE(context_id, 0) = ? AND title = ?', [(int) $contextId, $title]); $row = (array) $result->current(); return $row ? $this->_fromRow($row) : null; } @@ -114,7 +114,7 @@ public function getByTitle($contextId, $title) */ public function navigationMenuExistsByTitle($contextId, $title) { - $result = $this->retrieve('SELECT COUNT(*) AS row_count FROM navigation_menus WHERE title = ? AND context_id = ?', [$title, (int) $contextId]); + $result = $this->retrieve('SELECT COUNT(*) AS row_count FROM navigation_menus WHERE title = ? AND COALESCE(context_id, 0) = ?', [$title, (int) $contextId]); $row = (array) $result->current(); return $row && $row['row_count'] != 0; } @@ -158,7 +158,7 @@ public function insertObject($navigationMenu) { $this->update( 'INSERT INTO navigation_menus (title, area_name, context_id) VALUES (?, ?, ?)', - [$navigationMenu->getTitle(), $navigationMenu->getAreaName(), (int) $navigationMenu->getContextId()] + [$navigationMenu->getTitle(), $navigationMenu->getAreaName(), (int) $navigationMenu->getContextId() ?: null] ); $navigationMenu->setId($this->getInsertId()); return $navigationMenu->getId(); @@ -182,7 +182,7 @@ public function updateObject($navigationMenu) [ $navigationMenu->getTitle(), $navigationMenu->getAreaName(), - (int) $navigationMenu->getContextId(), + (int) $navigationMenu->getContextId() ?: null, (int) $navigationMenu->getId(), ] ); diff --git a/classes/navigationMenu/NavigationMenuItemAssignmentDAO.php b/classes/navigationMenu/NavigationMenuItemAssignmentDAO.php index 66464b4b17b..bbe16e40291 100644 --- a/classes/navigationMenu/NavigationMenuItemAssignmentDAO.php +++ b/classes/navigationMenu/NavigationMenuItemAssignmentDAO.php @@ -130,9 +130,9 @@ public function getByMenuIdAndParentId($menuId, $parentId) { $result = $this->retrieve( 'SELECT nmh.* - FROM navigation_menu_item_assignments as nmh - WHERE nmh.navigation_menu_id = ? - AND nmh.parent_id = ?', + FROM navigation_menu_item_assignments as nmh + WHERE nmh.navigation_menu_id = ? + AND COALESCE(nmh.parent_id, 0) = ?', [(int) $menuId, (int) $parentId] ); return new DAOResultFactory($result, $this, '_fromRow'); @@ -180,7 +180,7 @@ public function updateObject($navigationMenuItemAssignment) [ (int) $navigationMenuItemAssignment->getMenuId(), (int) $navigationMenuItemAssignment->getMenuItemId(), - (int) $navigationMenuItemAssignment->getParentId(), + (int) $navigationMenuItemAssignment->getParentId() ?: null, (int) $navigationMenuItemAssignment->getSequence(), (int) $navigationMenuItemAssignment->getId(), ] @@ -207,7 +207,7 @@ public function insertObject($assignment) [ (int) $assignment->getMenuId(), (int) $assignment->getMenuItemId(), - (int) $assignment->getParentId(), + (int) $assignment->getParentId() ?: null, (int) $assignment->getSequence(), ] ); diff --git a/classes/navigationMenu/NavigationMenuItemDAO.php b/classes/navigationMenu/NavigationMenuItemDAO.php index 9aebc6048b0..c16eb7ce2c8 100755 --- a/classes/navigationMenu/NavigationMenuItemDAO.php +++ b/classes/navigationMenu/NavigationMenuItemDAO.php @@ -56,7 +56,7 @@ public function getById($navigationMenuItemId) public function getByPath($contextId, $path) { $result = $this->retrieve( - 'SELECT * FROM navigation_menu_items WHERE path = ? and context_id = ? and type= ?', + 'SELECT * FROM navigation_menu_items WHERE path = ? AND COALESCE(context_id, 0) = ? AND type = ?', [$path, (int) $contextId, 'NMI_TYPE_CUSTOM'] ); @@ -74,7 +74,7 @@ public function getByPath($contextId, $path) public function getByContextId($contextId) { $result = $this->retrieve( - 'SELECT * FROM navigation_menu_items WHERE context_id = ?', + 'SELECT * FROM navigation_menu_items WHERE COALESCE(context_id, 0) = ?', [(int) $contextId] ); @@ -114,11 +114,11 @@ public function getByTypeAndTitleLocaleKey($contextId, $menuItemType, $menuItemT { $result = $this->retrieve( 'SELECT * - FROM navigation_menu_items - LEFT JOIN navigation_menu_item_settings ON (navigation_menu_items.navigation_menu_item_id = navigation_menu_item_settings.navigation_menu_item_id) - WHERE navigation_menu_items.type = ? - AND (navigation_menu_item_settings.setting_name = \'titleLocaleKey\' and navigation_menu_item_settings.setting_value = ?) - AND navigation_menu_items.context_id = ?', + FROM navigation_menu_items + LEFT JOIN navigation_menu_item_settings ON (navigation_menu_items.navigation_menu_item_id = navigation_menu_item_settings.navigation_menu_item_id) + WHERE navigation_menu_items.type = ? + AND (navigation_menu_item_settings.setting_name = \'titleLocaleKey\' and navigation_menu_item_settings.setting_value = ?) + AND COALESCE(navigation_menu_items.context_id, 0) = ?', [$menuItemType, $menuItemTitleLocaleKey, (int) $contextId] ); $row = (array) $result->current(); @@ -141,7 +141,7 @@ public function getByType($type, $contextId = null) } $result = $this->retrieve( 'SELECT * FROM navigation_menu_items WHERE type = ?' . - ($contextId !== null ? ' AND context_id = ?' : ''), + ($contextId !== null ? ' AND COALESCE(context_id, 0) = ?' : ''), $params ); return new DAOResultFactory($result, $this, '_fromRow'); @@ -223,7 +223,7 @@ public function insertObject($navigationMenuItem) (?, ?, ?)', [ $navigationMenuItem->getPath(), - (int) $navigationMenuItem->getContextId(), + (int) $navigationMenuItem->getContextId() ?: null, $navigationMenuItem->getType(), ] ); @@ -253,7 +253,7 @@ public function updateObject($navigationMenuItem) WHERE navigation_menu_item_id = ?', [ $navigationMenuItem->getPath(), - (int) $navigationMenuItem->getContextId(), + (int) $navigationMenuItem->getContextId() ?: null, $navigationMenuItem->getType(), (int) $navigationMenuItem->getId(), ] diff --git a/classes/notification/NotificationDAO.php b/classes/notification/NotificationDAO.php index 99bf91a26b2..8e6b3bc1bc2 100644 --- a/classes/notification/NotificationDAO.php +++ b/classes/notification/NotificationDAO.php @@ -19,6 +19,7 @@ namespace PKP\notification; use APP\notification\Notification; +use Illuminate\Database\Query\Builder; use Illuminate\Support\Facades\DB; use PKP\core\Core; use PKP\core\PKPApplication; @@ -61,8 +62,7 @@ public function getByUserId(?int $userId, int $level = Notification::NOTIFICATIO ->where('user_id', '=', $userId) ->where('level', '=', $level) ->when($type !== null, fn ($query) => $query->where('type', '=', $type)) - ->when($contextId === PKPApplication::CONTEXT_SITE, fn ($query) => $query->whereNull('context_id')) - ->when($contextId, fn ($query) => $query->where('context_id', '=', $contextId)) + ->when($contextId !== null, fn ($query) => $query->where(DB::raw('COALESCE(context_id, 0)'), '=', (int) $contextId)) ->orderBy('date_created', 'desc') ->get(); return new DAOResultFactory($result, $this, '_fromRow'); @@ -142,9 +142,9 @@ public function insertObject(Notification $notification): int $this->datetimeToDB(Core::getCurrentDate()) ), [ - $notification->getUserId() ? (int) $notification->getUserId() : null, + (int) $notification->getUserId() ?: null, (int) $notification->getLevel(), - $notification->getContextId() ? (int) $notification->getContextId() : null, + (int) $notification->getContextId() ?: null, (int) $notification->getType(), (int) $notification->getAssocType(), (int) $notification->getAssocId() @@ -166,15 +166,11 @@ public function insertObject(Notification $notification): int public function build(int $contextId, int $level, int $type, int $assocType, int $assocId, ?int $userId = null): Notification { DB::table('notifications') - ->when( - $contextId === PKPApplication::CONTEXT_SITE, - fn ($query) => $query->whereNull('context_id'), - fn ($query) => $query->where('context_id', '=', $contextId) - ) + ->when(fn (Builder $query) => $query->where(DB::raw('COALESCE(context_id, 0)'), '=', (int) $contextId)) ->where('level', '=', $level) ->where('assoc_type', '=', $assocType) ->where('assoc_id', '=', $assocId) - ->when($userId !== null, fn ($query, $userId) => $query->where('user_id', '=', $userId)) + ->when($userId !== null, fn (Builder $query) => $query->where('user_id', '=', $userId)) ->delete(); $notification = $this->newDataObject(); diff --git a/classes/notification/NotificationSubscriptionSettingsDAO.php b/classes/notification/NotificationSubscriptionSettingsDAO.php index 055eb2d2631..894a187f429 100644 --- a/classes/notification/NotificationSubscriptionSettingsDAO.php +++ b/classes/notification/NotificationSubscriptionSettingsDAO.php @@ -196,7 +196,7 @@ public function getSubscribedUserIds(array $blockedNotificationKey, array $block fn (Builder $q) => $q->from('user_user_groups', 'uug') ->join('user_groups AS ug', 'uug.user_group_id', '=', 'ug.user_group_id') ->whereColumn('uug.user_id', '=', 'u.user_id') - ->whereIn('ug.context_id', $contextIds) + ->whereIn(DB::raw('COALESCE(ug.context_id, 0)'), $contextIds) ->when(!is_null($roleIds), fn (Builder $q) => $q->whereIn('ug.role_id', $roleIds)) )->pluck('user_id'); } diff --git a/classes/notification/PKPNotification.php b/classes/notification/PKPNotification.php index 1a2b8254e0f..dd70721465b 100644 --- a/classes/notification/PKPNotification.php +++ b/classes/notification/PKPNotification.php @@ -249,7 +249,7 @@ public function getContextId() */ public function setContextId($contextId) { - $this->setData('context_id', $contextId); + $this->setData('context_id', (int) $contextId ?: null); } } diff --git a/classes/plugins/PluginSettingsDAO.php b/classes/plugins/PluginSettingsDAO.php index f0c40de864b..591920aae46 100644 --- a/classes/plugins/PluginSettingsDAO.php +++ b/classes/plugins/PluginSettingsDAO.php @@ -73,7 +73,7 @@ public function settingExists($contextId, $pluginName, $name) { $pluginName = strtolower_codesafe($pluginName); $result = $this->retrieve( - 'SELECT COUNT(*) AS row_count FROM plugin_settings WHERE plugin_name = ? AND context_id = ? AND setting_name = ?', + 'SELECT COUNT(*) AS row_count FROM plugin_settings WHERE plugin_name = ? AND COALESCE(context_id, 0) = ? AND setting_name = ?', [$pluginName, (int) $contextId, $name] ); $row = $result->current(); @@ -113,7 +113,7 @@ public function getPluginSettings($contextId, $pluginName) $pluginName = strtolower_codesafe($pluginName); $result = $this->retrieve( - 'SELECT setting_name, setting_value, setting_type FROM plugin_settings WHERE plugin_name = ? AND context_id = ?', + 'SELECT setting_name, setting_value, setting_type FROM plugin_settings WHERE plugin_name = ? AND COALESCE(context_id, 0) = ?', [$pluginName, (int) $contextId] ); @@ -148,7 +148,7 @@ public function updateSetting($contextId, $pluginName, $name, $value, $type = nu $value = $this->convertToDB($value, $type); DB::table('plugin_settings')->updateOrInsert( - ['context_id' => (int) $contextId, 'plugin_name' => $pluginName, 'setting_name' => $name], + ['context_id' => (int) $contextId ?: null, 'plugin_name' => $pluginName, 'setting_name' => $name], ['setting_value' => $value, 'setting_type' => $type] ); } @@ -169,7 +169,7 @@ public function deleteSetting($contextId, $pluginName, $name) $cache->setCache($name, null); return $this->update( - 'DELETE FROM plugin_settings WHERE plugin_name = ? AND setting_name = ? AND context_id = ?', + 'DELETE FROM plugin_settings WHERE plugin_name = ? AND setting_name = ? AND COALESCE(context_id, 0) = ?', [$pluginName, $name, (int) $contextId] ); } @@ -189,7 +189,7 @@ public function deleteSettingsByPlugin($contextId, $pluginName) $cache->flush(); return $this->update( - 'DELETE FROM plugin_settings WHERE context_id = ? AND plugin_name = ?', + 'DELETE FROM plugin_settings WHERE COALESCE(context_id, 0) = ? AND plugin_name = ?', [(int) $contextId, $pluginName] ); } @@ -202,7 +202,7 @@ public function deleteSettingsByPlugin($contextId, $pluginName) public function deleteByContextId($contextId) { return $this->update( - 'DELETE FROM plugin_settings WHERE context_id = ?', + 'DELETE FROM plugin_settings WHERE COALESCE(context_id, 0) = ?', [(int) $contextId] ); } diff --git a/classes/security/RoleDAO.php b/classes/security/RoleDAO.php index c1ee3deaa28..74382e449ee 100644 --- a/classes/security/RoleDAO.php +++ b/classes/security/RoleDAO.php @@ -48,7 +48,7 @@ public function userHasRole($contextId, $userId, $roleId) $roleId = is_array($roleId) ? join(',', array_map('intval', $roleId)) : (int) $roleId; $result = $this->retrieve( 'SELECT count(*) AS row_count FROM user_groups ug JOIN user_user_groups uug ON ug.user_group_id = uug.user_group_id - WHERE ug.context_id = ? AND uug.user_id = ? AND ug.role_id IN (' . $roleId . ')', + WHERE COALESCE(ug.context_id, 0) = ? AND uug.user_id = ? AND ug.role_id IN (' . $roleId . ')', [(int) $contextId, (int) $userId] ); $row = (array) $result->current(); @@ -70,10 +70,10 @@ public function getByUserId($userId, $contextId = null) $params[] = (int) $contextId; } $result = $this->retrieve( - 'SELECT DISTINCT ug.role_id AS role_id - FROM user_groups ug - JOIN user_user_groups uug ON ug.user_group_id = uug.user_group_id - WHERE uug.user_id = ?' . ($contextId !== null ? ' AND ug.context_id = ?' : ''), + 'SELECT DISTINCT ug.role_id AS role_id + FROM user_groups ug + JOIN user_user_groups uug ON ug.user_group_id = uug.user_group_id + WHERE uug.user_id = ?' . ($contextId !== null ? ' AND COALESCE(ug.context_id, 0) = ?' : ''), $params ); @@ -102,7 +102,7 @@ public function getByUserIdGroupedByContext(int $userId) foreach ($userGroups as $userGroup) { $role = $roleDao->newDataObject(); $role->setRoleId($userGroup->getRoleId()); - $roles[$userGroup->getContextId()][$userGroup->getRoleId()] = $role; + $roles[(int) $userGroup->getContextId()][$userGroup->getRoleId()] = $role; } return $roles; diff --git a/classes/security/Validation.php b/classes/security/Validation.php index 6bfdfe9ebe7..2ec6774841b 100644 --- a/classes/security/Validation.php +++ b/classes/security/Validation.php @@ -474,7 +474,7 @@ public static function canAdminister($administeredUserId, $administratorUserId) // that the administrator user doesn't have a manager role in. $userGroups = Repo::userGroup()->userUserGroups($administeredUserId); foreach ($userGroups as $userGroup) { - if ($userGroup->getContextId() != \PKP\core\PKPApplication::CONTEXT_SITE && !$roleDao->userHasRole($userGroup->getContextId(), $administratorUserId, Role::ROLE_ID_MANAGER)) { + if ((int) $userGroup->getContextId() != \PKP\core\PKPApplication::CONTEXT_SITE && !$roleDao->userHasRole($userGroup->getContextId(), $administratorUserId, Role::ROLE_ID_MANAGER)) { // Found an assignment: disqualified. return false; } diff --git a/classes/site/VersionDAO.php b/classes/site/VersionDAO.php index 8d929271dd9..4dde1962774 100644 --- a/classes/site/VersionDAO.php +++ b/classes/site/VersionDAO.php @@ -187,7 +187,7 @@ public function getCurrentProducts(?int $contextId): array LEFT JOIN plugin_settings ps ON LOWER(v.product_class_name) = ps.plugin_name AND ps.setting_name = \'enabled\' - ' . ($contextId !== null ? ' AND (context_id = ? OR v.sitewide = 1) ' : '') . ' + ' . ($contextId !== null ? ' AND (COALESCE(context_id, 0) = ? OR v.sitewide = 1) ' : '') . ' WHERE v.current = 1 AND (ps.setting_value = \'1\' OR v.lazy_load <> 1)', $contextId !== null ? [$contextId] : [], false diff --git a/classes/stageAssignment/StageAssignmentDAO.php b/classes/stageAssignment/StageAssignmentDAO.php index c80a49a4d1d..b0e50cbd922 100644 --- a/classes/stageAssignment/StageAssignmentDAO.php +++ b/classes/stageAssignment/StageAssignmentDAO.php @@ -197,7 +197,7 @@ public function getByUserGroupId($userGroupId, $contextId) $result = $this->retrieve( 'SELECT * FROM stage_assignments sa' . ' JOIN submissions s ON s.submission_id = sa.submission_id' - . ' WHERE sa.user_group_id = ? AND s.context_id = ?', + . ' WHERE sa.user_group_id = ? AND COALESCE(s.context_id, 0) = ?', [(int) $userGroupId, (int) $contextId] ); diff --git a/classes/user/Collector.php b/classes/user/Collector.php index 681f83dc2c6..69ac14bf598 100644 --- a/classes/user/Collector.php +++ b/classes/user/Collector.php @@ -455,7 +455,7 @@ protected function buildUserGroupFilter(Builder $query): self ) ->when($this->excludeRoles !== null, fn ($query) => $query->whereNotIn('ug.role_id', $this->excludeRoles)) ->when($this->roleIds !== null, fn ($query) => $query->whereIn('ug.role_id', $this->roleIds)) - ->when($this->contextIds !== null, fn ($query) => $query->whereIn('ug.context_id', $this->contextIds)) + ->when($this->contextIds !== null, fn ($query) => $query->whereIn(DB::raw('COALESCE(ug.context_id, 0)'), $this->contextIds)) ); return $this; } diff --git a/classes/user/User.php b/classes/user/User.php index 92d5f585dca..fb0d42981de 100644 --- a/classes/user/User.php +++ b/classes/user/User.php @@ -435,6 +435,7 @@ public function hasRole($roles, $contextId) */ public function getRoles($contextId, $noCache = false) { + $contextId = (int) $contextId; if ($noCache || empty($this->_roles[$contextId])) { $userRolesDao = DAORegistry::getDAO('RoleDAO'); /** @var RoleDAO $userRolesDao */ $this->setRoles($userRolesDao->getByUserId($this->getId(), $contextId), $contextId); @@ -451,6 +452,7 @@ public function getRoles($contextId, $noCache = false) */ public function setRoles($roles, $contextId) { + $contextId = (int) $contextId; $this->_roles[$contextId] = $roles; } } diff --git a/classes/userGroup/Collector.php b/classes/userGroup/Collector.php index 6f7fd236f11..84b631736a7 100644 --- a/classes/userGroup/Collector.php +++ b/classes/userGroup/Collector.php @@ -243,7 +243,7 @@ public function getQueryBuilder(): Builder } if (isset($this->contextIds)) { - $q->whereIn('ug.context_id', $this->contextIds); + $q->whereIn(DB::raw('COALESCE(ug.context_id, 0)'), $this->contextIds); } if (isset($this->roleIds)) { diff --git a/classes/userGroup/DAO.php b/classes/userGroup/DAO.php index 15869322c22..79353b8afec 100644 --- a/classes/userGroup/DAO.php +++ b/classes/userGroup/DAO.php @@ -153,7 +153,7 @@ public function getUserCountByContextId(?int $contextId = null): Collection return DB::table('user_groups', 'ug') ->join('user_user_groups AS uug', 'uug.user_group_id', '=', 'ug.user_group_id') ->join('users AS u', 'u.user_id', '=', 'uug.user_id') - ->when($contextId !== null, fn (Builder $query) => $query->where('ug.context_id', '=', $contextId)) + ->when($contextId !== null, fn (Builder $query) => $query->where(DB::raw('COALESCE(ug.context_id, 0)'), '=', $contextId)) ->where('u.disabled', '=', 0) ->groupBy('ug.user_group_id') ->select('ug.user_group_id') diff --git a/classes/userGroup/UserGroup.php b/classes/userGroup/UserGroup.php index 94ee3e81dab..eb9c4e5e865 100644 --- a/classes/userGroup/UserGroup.php +++ b/classes/userGroup/UserGroup.php @@ -60,7 +60,7 @@ public function setPath($path) /** * Get the context ID * - * @return int + * @return ?int */ public function getContextId() { @@ -70,11 +70,11 @@ public function getContextId() /** * Set the context ID * - * @param int $contextId + * @param ?int $contextId */ public function setContextId($contextId) { - $this->setData('contextId', $contextId); + $this->setData('contextId', (int) $contextId ?: null); } /** diff --git a/classes/userGroup/relationships/UserUserGroup.php b/classes/userGroup/relationships/UserUserGroup.php index 9e05a74c911..11b62240286 100644 --- a/classes/userGroup/relationships/UserUserGroup.php +++ b/classes/userGroup/relationships/UserUserGroup.php @@ -17,6 +17,7 @@ use APP\facades\Repo; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Casts\Attribute; +use Illuminate\Support\Facades\DB; class UserUserGroup extends \Illuminate\Database\Eloquent\Model { @@ -71,6 +72,6 @@ public function scopeWithContextId(Builder $query, int $contextId): Builder { return $query ->join('user_groups as ug', 'user_user_groups.user_group_id', '=', 'ug.user_group_id') - ->where('ug.context_id', $contextId); + ->where(DB::raw('COALESCE(ug.context_id, 0)'), $contextId); } }