From 7ec8bc6ef1f243b033521a2c98ed0aaa08c0f0af Mon Sep 17 00:00:00 2001 From: Karthik Kasturi Date: Tue, 19 Aug 2025 20:34:39 +0100 Subject: [PATCH] chore: moved proxy classes to different folder and namespaces --- lib/Controller.php | 17 ++++----- lib/{ => Proxy}/AbstractProxy.php | 49 +++++++++++++++++++------ lib/{ => Proxy}/ShlinkProxy.php | 45 +++++++++-------------- lib/{ => Proxy}/YourlsProxy.php | 53 +++++++++++---------------- tst/YourlsProxyTest.php | 2 +- vendor/composer/autoload_classmap.php | 6 +-- vendor/composer/autoload_static.php | 6 +-- 7 files changed, 91 insertions(+), 87 deletions(-) rename lib/{ => Proxy}/AbstractProxy.php (68%) rename lib/{ => Proxy}/ShlinkProxy.php (55%) rename lib/{ => Proxy}/YourlsProxy.php (51%) diff --git a/lib/Controller.php b/lib/Controller.php index 31e2dbfe..3d608861 100644 --- a/lib/Controller.php +++ b/lib/Controller.php @@ -14,6 +14,9 @@ namespace PrivateBin; use Exception; use PrivateBin\Persistence\ServerSalt; use PrivateBin\Persistence\TrafficLimiter; +use PrivateBin\Proxy\AbstractProxy; +use PrivateBin\Proxy\ShlinkProxy; +use PrivateBin\Proxy\YourlsProxy; /** * Controller @@ -149,10 +152,10 @@ class Controller $this->_jsonld($this->_request->getParam('jsonld')); return; case 'yourlsproxy': - $this->_shortenerproxy($this->_request->getParam('link'), YourlsProxy::class); + $this->_shortenerproxy(new YourlsProxy($this->_conf, $this->_request->getParam('link'))); break; case 'shlinkproxy': - $this->_shortenerproxy($this->_request->getParam('link'), ShlinkProxy::class); + $this->_shortenerproxy(new ShlinkProxy($this->_conf, $this->_request->getParam('link'))); break; } @@ -539,16 +542,10 @@ class Controller * Proxies a link using the specified proxy class, and updates the status or error with the response. * * @access private - * @param string $link The link to be proxied. - * @param string $proxyClass The fully qualified class name of the proxy to use. + * @param AbstractProxy $proxy The instance of the proxy class. */ - private function _shortenerproxy($link, $proxyClass) + private function _shortenerproxy(AbstractProxy $proxy) { - if (!is_subclass_of($proxyClass, AbstractProxy::class)) { - $this->_error = 'Invalid proxy class.'; - return; - } - $proxy = new $proxyClass($this->_conf, $link); if ($proxy->isError()) { $this->_error = $proxy->getError(); } else { diff --git a/lib/AbstractProxy.php b/lib/Proxy/AbstractProxy.php similarity index 68% rename from lib/AbstractProxy.php rename to lib/Proxy/AbstractProxy.php index f02229fd..7dfc25e5 100644 --- a/lib/AbstractProxy.php +++ b/lib/Proxy/AbstractProxy.php @@ -9,14 +9,16 @@ * @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License */ -namespace PrivateBin; +namespace PrivateBin\Proxy; use Exception; +use PrivateBin\Configuration; +use PrivateBin\Json; /** * AbstractProxy * - * Forwards a URL for shortening to shlink and stores the result. + * Forwards a URL for shortening and stores the result. */ abstract class AbstractProxy { @@ -42,20 +44,35 @@ abstract class AbstractProxy * initializes and runs the proxy class * * @access public + * @param Configuration $conf * @param string $link */ - public function __construct(Configuration $conf, $link) + public function __construct(Configuration $conf, string $link) { if (!str_starts_with($link, $conf->getKey('basepath') . '?')) { $this->_error = 'Trying to shorten a URL that isn\'t pointing at our instance.'; return; } - $data = $this->_getcontents($conf, $link); + $proxyUrl = $this->_getProxyUrl($conf); + + if (empty($proxyUrl)) { + $this->_error = 'Error calling proxy. Probably a configuration issue, like missing api url'; + error_log($this->_error); + return; + } + + $data = file_get_contents($proxyUrl, false, + stream_context_create( + array( + 'http' => $this->_getProxyPayload($conf, $link), + ) + ) + ); if ($data == null) { $this->_error = 'Error calling proxy. Probably a configuration issue'; - error_log('Error calling proxy: ' . $this->_error); + error_log($this->_error); return; } @@ -66,22 +83,23 @@ abstract class AbstractProxy $statusCode = $matches[1]; } $this->_error = 'Error calling proxy. HTTP request failed. Status code: ' . $statusCode; - error_log('Error calling proxy: ' . $this->_error); + error_log($this->_error); return; } try { - $data = Json::decode($data); + $jsonData = Json::decode($data); } catch (Exception $e) { $this->_error = 'Error calling proxy. Probably a configuration issue, like wrong or missing config keys.'; error_log('Error calling proxy: ' . $e->getMessage()); return; } - $url = $this->_extractShortUrl($data); + $url = $this->_extractShortUrl($jsonData); if ($url === null) { $this->_error = 'Error calling proxy. Probably a configuration issue, like wrong or missing config keys.'; + error_log('Error calling proxy: ' . $data); } else { $this->_url = $url; } @@ -121,13 +139,14 @@ abstract class AbstractProxy } /** - * Abstract method to get contents from a URL. + * Abstract method to get the payload to send to the URL Shortener * + * @access protected * @param Configuration $conf * @param string $link - * @return mixed + * @return array */ - abstract protected function _getcontents(Configuration $conf, string $link); + abstract protected function _getProxyPayload(Configuration $conf, string $link): array; /** * Abstract method to extract the shortUrl from the response @@ -136,4 +155,12 @@ abstract class AbstractProxy * @return ?string */ abstract protected function _extractShortUrl(array $data): ?string; + + /** + * Abstract method to get the proxy URL + * + * @param Configuration $conf + * @return string + */ + abstract protected function _getProxyUrl(Configuration $conf): string; } diff --git a/lib/ShlinkProxy.php b/lib/Proxy/ShlinkProxy.php similarity index 55% rename from lib/ShlinkProxy.php rename to lib/Proxy/ShlinkProxy.php index 56915609..ee4507cf 100644 --- a/lib/ShlinkProxy.php +++ b/lib/Proxy/ShlinkProxy.php @@ -9,7 +9,10 @@ * @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License */ -namespace PrivateBin; +namespace PrivateBin\Proxy; + +use PrivateBin\Configuration; +use PrivateBin\Json; /** * ShlinkProxy @@ -19,48 +22,37 @@ namespace PrivateBin; class ShlinkProxy extends AbstractProxy { /** - * constructor + * Overrides the abstract parent function to get the proxy URL. * - * initializes and runs ShlinkProxy - * - * @access public - * @param string $link + * @param Configuration $conf + * @return string */ - public function __construct(Configuration $conf, $link) + protected function _getProxyUrl(Configuration $conf): string { - parent::__construct($conf, $link); + return $conf->getKey('apiurl', 'shlink'); } /** * Overrides the abstract parent function to get contents from Shlink API. * * @access protected - * @return string + * @param Configuration $conf + * @param string $link + * @return array */ - protected function _getcontents(Configuration $conf, string $link) + protected function _getProxyPayload(Configuration $conf, string $link): array { - $shlink_api_url = $conf->getKey('apiurl', 'shlink'); $shlink_api_key = $conf->getKey('apikey', 'shlink'); - if (empty($shlink_api_url) || empty($shlink_api_key)) { - return; - } - $body = array( 'longUrl' => $link, ); - return file_get_contents( - $shlink_api_url, false, stream_context_create( - array( - 'http' => array( - 'method' => 'POST', - 'header' => "Content-Type: application/json\r\n" . - 'X-Api-Key: ' . $shlink_api_key . "\r\n", - 'content' => Json::encode($body), - ), - ) - ) + return array( + 'method' => 'POST', + 'header' => "Content-Type: application/json\r\n" . + 'X-Api-Key: ' . $shlink_api_key . "\r\n", + 'content' => Json::encode($body), ); } @@ -74,7 +66,6 @@ class ShlinkProxy extends AbstractProxy protected function _extractShortUrl(array $data): ?string { if ( - !is_null($data) && array_key_exists('shortUrl', $data) ) { return $data['shortUrl']; diff --git a/lib/YourlsProxy.php b/lib/Proxy/YourlsProxy.php similarity index 51% rename from lib/YourlsProxy.php rename to lib/Proxy/YourlsProxy.php index 4f60ba78..ae9e11e7 100644 --- a/lib/YourlsProxy.php +++ b/lib/Proxy/YourlsProxy.php @@ -9,7 +9,9 @@ * @license https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License */ -namespace PrivateBin; +namespace PrivateBin\Proxy; + +use PrivateBin\Configuration; /** * YourlsProxy @@ -20,49 +22,37 @@ namespace PrivateBin; class YourlsProxy extends AbstractProxy { /** - * constructor + * Overrides the abstract parent function to get the proxy URL. * - * initializes and runs YourlsProxy - * - * @access public - * @param string $link + * @param Configuration $conf + * @return string */ - public function __construct(Configuration $conf, $link) + protected function _getProxyUrl(Configuration $conf): string { - parent::__construct($conf, $link); + return $conf->getKey('apiurl', 'yourls'); } /** * Overrides the abstract parent function to get contents from YOURLS API. * * @access protected - * @return string + * @param Configuration $conf + * @param string $link + * @return array */ - protected function _getcontents(Configuration $conf, string $link) + protected function _getProxyPayload(Configuration $conf, string $link): array { - $yourls_api_url = $conf->getKey('apiurl', 'yourls'); - - if (empty($yourls_api_url)) { - return null; - } - - return file_get_contents( - $yourls_api_url, false, stream_context_create( + return array( + 'method' => 'POST', + 'header' => "Content-Type: application/x-www-form-urlencoded\r\n", + 'content' => http_build_query( array( - 'http' => array( - 'method' => 'POST', - 'header' => "Content-Type: application/x-www-form-urlencoded\r\n", - 'content' => http_build_query( - array( - 'signature' => $conf->getKey('signature', 'yourls'), - 'format' => 'json', - 'action' => 'shorturl', - 'url' => $link, - ) - ), - ), + 'signature' => $conf->getKey('signature', 'yourls'), + 'format' => 'json', + 'action' => 'shorturl', + 'url' => $link, ) - ) + ), ); } @@ -76,7 +66,6 @@ class YourlsProxy extends AbstractProxy protected function _extractShortUrl(array $data): ?string { if ( - !is_null($data) && array_key_exists('statusCode', $data) && $data['statusCode'] == 200 && array_key_exists('shorturl', $data) diff --git a/tst/YourlsProxyTest.php b/tst/YourlsProxyTest.php index 11eb6708..78821f47 100644 --- a/tst/YourlsProxyTest.php +++ b/tst/YourlsProxyTest.php @@ -2,7 +2,7 @@ use PHPUnit\Framework\TestCase; use PrivateBin\Configuration; -use PrivateBin\YourlsProxy; +use PrivateBin\Proxy\YourlsProxy; class YourlsProxyTest extends TestCase { diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index a89cb900..113f8533 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -66,7 +66,6 @@ return array( 'Jdenticon\\Shapes\\ShapeCategory' => $vendorDir . '/jdenticon/jdenticon/src/Shapes/ShapeCategory.php', 'Jdenticon\\Shapes\\ShapeDefinitions' => $vendorDir . '/jdenticon/jdenticon/src/Shapes/ShapeDefinitions.php', 'PhpToken' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php', - 'PrivateBin\\AbstractProxy' => $baseDir . '/lib/AbstractProxy.php', 'PrivateBin\\Configuration' => $baseDir . '/lib/Configuration.php', 'PrivateBin\\Controller' => $baseDir . '/lib/Controller.php', 'PrivateBin\\Data\\AbstractData' => $baseDir . '/lib/Data/AbstractData.php', @@ -86,12 +85,13 @@ return array( 'PrivateBin\\Persistence\\PurgeLimiter' => $baseDir . '/lib/Persistence/PurgeLimiter.php', 'PrivateBin\\Persistence\\ServerSalt' => $baseDir . '/lib/Persistence/ServerSalt.php', 'PrivateBin\\Persistence\\TrafficLimiter' => $baseDir . '/lib/Persistence/TrafficLimiter.php', + 'PrivateBin\\Proxy\\AbstractProxy' => $baseDir . '/lib/Proxy/AbstractProxy.php', + 'PrivateBin\\Proxy\\ShlinkProxy' => $baseDir . '/lib/Proxy/ShlinkProxy.php', + 'PrivateBin\\Proxy\\YourlsProxy' => $baseDir . '/lib/Proxy/YourlsProxy.php', 'PrivateBin\\Request' => $baseDir . '/lib/Request.php', - 'PrivateBin\\ShlinkProxy' => $baseDir . '/lib/ShlinkProxy.php', 'PrivateBin\\TemplateSwitcher' => $baseDir . '/lib/TemplateSwitcher.php', 'PrivateBin\\View' => $baseDir . '/lib/View.php', 'PrivateBin\\Vizhash16x16' => $baseDir . '/lib/Vizhash16x16.php', - 'PrivateBin\\YourlsProxy' => $baseDir . '/lib/YourlsProxy.php', 'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php', 'Symfony\\Polyfill\\Php80\\Php80' => $vendorDir . '/symfony/polyfill-php80/Php80.php', 'Symfony\\Polyfill\\Php80\\PhpToken' => $vendorDir . '/symfony/polyfill-php80/PhpToken.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 1d86d957..ef0e05a6 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -114,7 +114,6 @@ class ComposerStaticInitDontChange 'Jdenticon\\Shapes\\ShapeCategory' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Shapes/ShapeCategory.php', 'Jdenticon\\Shapes\\ShapeDefinitions' => __DIR__ . '/..' . '/jdenticon/jdenticon/src/Shapes/ShapeDefinitions.php', 'PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php', - 'PrivateBin\\AbstractProxy' => __DIR__ . '/../..' . '/lib/AbstractProxy.php', 'PrivateBin\\Configuration' => __DIR__ . '/../..' . '/lib/Configuration.php', 'PrivateBin\\Controller' => __DIR__ . '/../..' . '/lib/Controller.php', 'PrivateBin\\Data\\AbstractData' => __DIR__ . '/../..' . '/lib/Data/AbstractData.php', @@ -134,12 +133,13 @@ class ComposerStaticInitDontChange 'PrivateBin\\Persistence\\PurgeLimiter' => __DIR__ . '/../..' . '/lib/Persistence/PurgeLimiter.php', 'PrivateBin\\Persistence\\ServerSalt' => __DIR__ . '/../..' . '/lib/Persistence/ServerSalt.php', 'PrivateBin\\Persistence\\TrafficLimiter' => __DIR__ . '/../..' . '/lib/Persistence/TrafficLimiter.php', + 'PrivateBin\\Proxy\\AbstractProxy' => __DIR__ . '/../..' . '/lib/Proxy/AbstractProxy.php', + 'PrivateBin\\Proxy\\ShlinkProxy' => __DIR__ . '/../..' . '/lib/Proxy/ShlinkProxy.php', + 'PrivateBin\\Proxy\\YourlsProxy' => __DIR__ . '/../..' . '/lib/Proxy/YourlsProxy.php', 'PrivateBin\\Request' => __DIR__ . '/../..' . '/lib/Request.php', - 'PrivateBin\\ShlinkProxy' => __DIR__ . '/../..' . '/lib/ShlinkProxy.php', 'PrivateBin\\TemplateSwitcher' => __DIR__ . '/../..' . '/lib/TemplateSwitcher.php', 'PrivateBin\\View' => __DIR__ . '/../..' . '/lib/View.php', 'PrivateBin\\Vizhash16x16' => __DIR__ . '/../..' . '/lib/Vizhash16x16.php', - 'PrivateBin\\YourlsProxy' => __DIR__ . '/../..' . '/lib/YourlsProxy.php', 'Stringable' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Stringable.php', 'Symfony\\Polyfill\\Php80\\Php80' => __DIR__ . '/..' . '/symfony/polyfill-php80/Php80.php', 'Symfony\\Polyfill\\Php80\\PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/PhpToken.php',