- Affected version
- 2.3.0 Beta 4
This does not work as theKinda. There’s only one pre-installed but you can add multiple entries of typeXF:Provider\XenForo
to the provider table in the database if that’s needed.
providerId
is hardcoded in XF\ConnectedAccount\ProviderData
PHP:
public function getDefaultEndpoint(): string
{
/** @var \XF\Entity\ConnectedAccountProvider $provider */
$provider = \XF::app()->em()->find(ConnectedAccountProvider::class, 'xenforo');
return $provider->options['board_url'] . '/api/me';
}
So even if another entry (
xenforo2
) is created manually it would not work as the provider data class would always try to access the API of instance xenforo
.Suggested Fix
Code:
--- src/XF/ConnectedAccount/ProviderData/XenForo.php Sun Apr 14 23:07:34 2024
+++ src/XF/ConnectedAccount/ProviderData/XenForo.php Sun Apr 14 23:07:46 2024
@@ -11,3 +11,3 @@
/** @var \XF\Entity\ConnectedAccountProvider $provider */
- $provider = \XF::app()->em()->find(ConnectedAccountProvider::class, 'xenforo');
+ $provider = \XF::app()->em()->find(ConnectedAccountProvider::class, $this->providerId);
But this change alone is not sufficient:
The service class
XF\ConnectedAccount\Service\XenForo
also can't handle multiple instances and will return the hardcoded provider instance xenforo
:
PHP:
protected function getProvider(): \XF\Entity\ConnectedAccountProvider
{
return \XF::app()->em()->find(\XF\Entity\ConnectedAccountProvider::class, 'xenforo');
}
Changing this so the service class can handle multiple instances as well is more complicated as the service class (unlike the provider data class) currently does not know for which instance if is called.
Possible Fix
Code:
--- src/XF/ConnectedAccount/Provider/AbstractProvider.php Tue Mar 19 22:31:32 2024
+++ src/XF/ConnectedAccount/Provider/AbstractProvider.php Mon Apr 15 00:39:53 2024
@@ -171,3 +171,3 @@
- $provider = \XF::app()->oAuth()->provider($this->getOAuthServiceName(), $config);
+ $provider = \XF::app()->oAuth()->provider($this->getOAuthServiceName(), $config, $this->providerId);
if (!$provider)
--- src/XF/ConnectedAccount/Service/XenForo.php Tue Mar 19 22:31:32 2024
+++ src/XF/ConnectedAccount/Service/XenForo.php Mon Apr 15 00:41:15 2024
@@ -14,2 +14,4 @@
{
+ protected $providerId;
+
protected function getAuthorizationMethod(): int
@@ -66,3 +68,3 @@
{
- return \XF::app()->em()->find(\XF\Entity\ConnectedAccountProvider::class, 'xenforo');
+ return \XF::app()->em()->find(\XF\Entity\ConnectedAccountProvider::class, $this->providerId);
}
@@ -74,2 +76,7 @@
return true;
+ }
+
+ public function setProviderId(string $providerId): void
+ {
+ $this->providerId = $providerId;
}
--- src/XF/SubContainer/OAuth.php Tue Mar 19 22:31:32 2024
+++ src/XF/SubContainer/OAuth.php Mon Apr 15 00:51:02 2024
@@ -44,4 +44,16 @@
- $container->factory('provider', function($serviceName, array $config, Container $c)
+ $container->factory('provider', function($serviceName, array $params, Container $c)
{
+ // optional: keep backwards compatibility for $config
+ if (isset($params['key']))
+ {
+ $config = $params;
+ $providerId = '';
+ }
+ else
+ {
+ $config = $params[0];
+ $providerId = $params[1];
+ }
+
/** @var \OAuth\Common\Consumer\Credentials $credentials */
@@ -76,3 +88,10 @@
- return $serviceFactory->createService($serviceName, $credentials, $storage, $config['scopes']);
+ $service = $serviceFactory->createService($serviceName, $credentials, $storage, $config['scopes']);
+
+ if (method_exists($service, 'setProviderId'))
+ {
+ $service->setProviderId($providerId);
+ }
+
+ return $service;
});
@@ -100,2 +119,3 @@
* @param array $config
+ * @param string $providerId
*
@@ -103,5 +123,5 @@
*/
- public function provider($serviceName, array $config = [])
+ public function provider($serviceName, array $config = [], string $providerId = '')
{
- return $this->container->create('provider', $serviceName, $config);
+ return $this->container->create('provider', $serviceName, [$config, $providerId]);
}
Last edited: