From 4132baef39dd127717e9a7c3e7b7ad62ac6b76a4 Mon Sep 17 00:00:00 2001 From: Matthias Schmidt Date: Thu, 21 May 2020 12:53:39 +0200 Subject: [PATCH] Add popover-related interfaces and popover support for `{anchor}` Close #3318 --- wcfsetup/install/files/js/WCF.User.js | 1 + .../js/WoltLabSuite/Core/BootstrapFrontend.js | 21 +++++----- .../WoltLabSuite/Core/Controller/Popover.js | 22 ++++++++++- .../files/lib/data/IPopoverAction.class.php | 30 ++++++++++++++ .../files/lib/data/IPopoverObject.class.php | 23 +++++++++++ .../files/lib/data/user/User.class.php | 10 ++++- .../lib/data/user/UserProfileAction.class.php | 39 +++++++++++++------ .../AnchorFunctionTemplatePlugin.class.php | 12 +++++- 8 files changed, 132 insertions(+), 26 deletions(-) create mode 100644 wcfsetup/install/files/lib/data/IPopoverAction.class.php create mode 100644 wcfsetup/install/files/lib/data/IPopoverObject.class.php diff --git a/wcfsetup/install/files/js/WCF.User.js b/wcfsetup/install/files/js/WCF.User.js index 975554177a..183305422d 100644 --- a/wcfsetup/install/files/js/WCF.User.js +++ b/wcfsetup/install/files/js/WCF.User.js @@ -2165,6 +2165,7 @@ WCF.User.LikeLoader = Class.extend({ * Loads user profile previews. * * @see WCF.Popover + * @deprecated since 5.3, taken care of by `WoltLabSuite/Core/BootstrapFrontend` via `WoltLabSuite/Core/Controller/Popover` */ WCF.User.ProfilePreview = WCF.Popover.extend({ /** diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/BootstrapFrontend.js b/wcfsetup/install/files/js/WoltLabSuite/Core/BootstrapFrontend.js index 7b46625bdc..0742b7b676 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/BootstrapFrontend.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/BootstrapFrontend.js @@ -58,21 +58,18 @@ define( * Initializes user profile popover. */ _initUserPopover: function() { + ControllerPopover.init({ + className: 'userLink', + dboAction: 'wcf\\data\\user\\UserProfileAction', + identifier: 'com.woltlab.wcf.user' + }); + + // @deprecated since 5.3 ControllerPopover.init({ attributeName: 'data-user-id', className: 'userLink', - identifier: 'com.woltlab.wcf.user', - loadCallback: function(objectId, popover) { - var callback = function(data) { - popover.setContent('com.woltlab.wcf.user', objectId, data.returnValues.template); - }; - - popover.ajaxApi({ - actionName: 'getUserProfile', - className: 'wcf\\data\\user\\UserProfileAction', - objectIDs: [ objectId ] - }, callback, callback); - } + dboAction: 'wcf\\data\\user\\UserProfileAction', + identifier: 'com.woltlab.wcf.user.deprecated' }); } }; diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Controller/Popover.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Controller/Popover.js index 82a4769de5..4f56bbbd0e 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Controller/Popover.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Controller/Popover.js @@ -118,6 +118,7 @@ define(['Ajax', 'Dictionary', 'Environment', 'Dom/ChangeListener', 'Dom/Util', ' _handlers.set(options.identifier, { attributeName: options.attributeName, + dboAction: options.dboAction, elements: options.legacy ? options.className : elByClass(options.className), legacy: options.legacy, loadCallback: options.loadCallback @@ -336,7 +337,26 @@ define(['Ajax', 'Dictionary', 'Environment', 'Dom/ChangeListener', 'Dom/Util', ' else if (data.state === STATE_NONE) { data.state = STATE_LOADING; - _handlers.get(elementData.identifier).loadCallback(elementData.objectId, this); + var handler = _handlers.get(elementData.identifier); + if (handler.loadCallback) { + handler.loadCallback(elementData.objectId, this); + } + else if (handler.dboAction) { + var callback = function(data) { + this.setContent( + elementData.identifier, + elementData.objectId, + data.returnValues.template + ); + }.bind(this); + + this.ajaxApi({ + actionName: 'getPopover', + className: handler.dboAction, + interfaceName: 'wcf\\data\\IPopoverAction', + objectIDs: [ elementData.objectId ] + }, callback, callback); + } } }, diff --git a/wcfsetup/install/files/lib/data/IPopoverAction.class.php b/wcfsetup/install/files/lib/data/IPopoverAction.class.php new file mode 100644 index 0000000000..2992e0b2a0 --- /dev/null +++ b/wcfsetup/install/files/lib/data/IPopoverAction.class.php @@ -0,0 +1,30 @@ + + * @package WoltLabSuite\Core\Data + * @since 5.3 + */ +interface IPopoverAction { + /** + * Validates the `getPopover` action. + */ + public function validateGetPopover(); + + /** + * Returns the requested popover for a specific object. + * + * Return value: + * [ + * 'template' => '...' + * ] + * + * @return string[] + */ + public function getPopover(); +} diff --git a/wcfsetup/install/files/lib/data/IPopoverObject.class.php b/wcfsetup/install/files/lib/data/IPopoverObject.class.php new file mode 100644 index 0000000000..b3404a8e9c --- /dev/null +++ b/wcfsetup/install/files/lib/data/IPopoverObject.class.php @@ -0,0 +1,23 @@ + + * @package WoltLabSuite\Core\Data + * @since 5.3 + */ +interface IPopoverObject extends IIDObject, ITitledLinkObject { + /** + * Returns the CSS class that objects of this type use for popover links. + * + * @return string + */ + public function getPopoverLinkClass(); +} diff --git a/wcfsetup/install/files/lib/data/user/User.class.php b/wcfsetup/install/files/lib/data/user/User.class.php index 761ea0b50c..e824acdeab 100644 --- a/wcfsetup/install/files/lib/data/user/User.class.php +++ b/wcfsetup/install/files/lib/data/user/User.class.php @@ -1,5 +1,6 @@ get('wcf.user.' . $field); }, $this->getBlacklistMatches()); } + + /** + * @inheritDoc + */ + public function getPopoverLinkClass() { + return 'userLink'; + } } diff --git a/wcfsetup/install/files/lib/data/user/UserProfileAction.class.php b/wcfsetup/install/files/lib/data/user/UserProfileAction.class.php index 94fed670b1..da5c8b7474 100644 --- a/wcfsetup/install/files/lib/data/user/UserProfileAction.class.php +++ b/wcfsetup/install/files/lib/data/user/UserProfileAction.class.php @@ -1,5 +1,6 @@ * @package WoltLabSuite\Core\Data\User */ -class UserProfileAction extends UserAction { +class UserProfileAction extends UserAction implements IPopoverAction { /** * @inheritDoc */ - protected $allowGuestAccess = ['getUserProfile', 'getDetailedActivityPointList']; + protected $allowGuestAccess = ['getUserProfile', 'getDetailedActivityPointList', 'getPopover']; /** * @var User @@ -93,8 +94,28 @@ class UserProfileAction extends UserAction { * Validates user profile preview. * * @throws UserInputException + * @deprecated since 5.3, use `validateGetPopover()` */ public function validateGetUserProfile() { + $this->validateGetPopover(); + } + + /** + * Returns user profile preview. + * + * @return array + * @deprecated since 5.3, use `getPopover()` + */ + public function getUserProfile() { + return array_merge($this->getPopover(), [ + 'userID' => reset($this->objectIDs), + ]); + } + + /** + * @inheritDoc + */ + public function validateGetPopover() { WCF::getSession()->checkPermissions(['user.profile.canViewUserProfile']); if (count($this->objectIDs) != 1) { @@ -103,24 +124,21 @@ class UserProfileAction extends UserAction { } /** - * Returns user profile preview. - * - * @return array + * @inheritDoc */ - public function getUserProfile() { + public function getPopover() { $userID = reset($this->objectIDs); if ($userID) { $userProfileList = new UserProfileList(); $userProfileList->getConditionBuilder()->add("user_table.userID = ?", [$userID]); $userProfileList->readObjects(); - $userProfiles = $userProfileList->getObjects(); - if (empty($userProfiles)) { - WCF::getTPL()->assign('unknownUser', true); + if (count($userProfileList)) { + WCF::getTPL()->assign('user', $userProfileList->getSingleObject()); } else { - WCF::getTPL()->assign('user', reset($userProfiles)); + WCF::getTPL()->assign('unknownUser', true); } } else { @@ -129,7 +147,6 @@ class UserProfileAction extends UserAction { return [ 'template' => WCF::getTPL()->fetch('userProfilePreview'), - 'userID' => $userID ]; } diff --git a/wcfsetup/install/files/lib/system/template/plugin/AnchorFunctionTemplatePlugin.class.php b/wcfsetup/install/files/lib/system/template/plugin/AnchorFunctionTemplatePlugin.class.php index 3758d193b6..8e4faec7e3 100644 --- a/wcfsetup/install/files/lib/system/template/plugin/AnchorFunctionTemplatePlugin.class.php +++ b/wcfsetup/install/files/lib/system/template/plugin/AnchorFunctionTemplatePlugin.class.php @@ -1,6 +1,7 @@ $value) { if (!preg_match('~[a-z]+([A-z]+)+~', $name)) { throw new \InvalidArgumentException("Invalid additional argument name '{$name}'."); } + if ($name === 'class') { + $classes = explode(' ', $value); + } + $additionalParameters .= ' ' . strtolower(preg_replace('~([A-Z])~', '-$1', $name)) . '="' . StringUtil::encodeHTML($value) . '"'; } + if ($object !== null && $object instanceof IPopoverObject && in_array($object->getPopoverLinkClass(), $classes)) { + $additionalParameters .= ' data-object-id="' . $object->getObjectID() . '"'; + } + return '' . StringUtil::encodeHTML($content) . ''; } } -- 2.20.1