diff --git a/src/Url.php b/src/Url.php index 08bad49..966a220 100644 --- a/src/Url.php +++ b/src/Url.php @@ -8,6 +8,9 @@ class Url { public const MODE_LEGACY = 'legacy'; public const MODE_ADVANCED = 'advanced'; + + public const SOURCE_URL_PLAIN = 'plain'; + public const SOURCE_URL_ENCODED = 'encoded'; /** * @var string */ @@ -40,6 +43,11 @@ class Url private $mode = self::MODE_LEGACY; + /** + * @var string + */ + private $sourceUrlType = self::SOURCE_URL_ENCODED; + /** * Url constructor. * @param string $imageUrl @@ -67,6 +75,18 @@ public function useAdvancedMode(): self return $this; } + public function usePlainSourceUrl(): self + { + $this->sourceUrlType = self::SOURCE_URL_PLAIN; + return $this; + } + + public function useEncodedSourceUrl(): self + { + $this->sourceUrlType = self::SOURCE_URL_ENCODED; + return $this; + } + public function options(): OptionSet { return $this->options; @@ -199,23 +219,45 @@ protected function resolveExtension(): string private function unsignedPathLegacy(): string { $enlarge = (string)(int)$this->enlarge; - $encodedUrl = rtrim(strtr(base64_encode($this->imageUrl), '+/', '-_'), '='); + $url = $this->generateSourceUrl(); $w = $this->options->width(); $h = $this->options->height(); - $path = "/{$this->fit}/{$w}/{$h}/{$this->gravity}/{$enlarge}/{$encodedUrl}"; + $path = "/{$this->fit}/{$w}/{$h}/{$this->gravity}/{$enlarge}/{$url}"; return $this->appendExtension($path); } private function unsignedPathAdvanced() { - $encodedUrl = rtrim(strtr(base64_encode($this->imageUrl), '+/', '-_'), '='); - $path = "/{$this->options->toString()}/{$encodedUrl}"; + $url = $this->generateSourceUrl(); + $path = "/{$this->options->toString()}/{$url}"; + return $this->appendExtension($path); } private function appendExtension(string $path): string { $ext = $this->extension ?: $this->resolveExtension(); + + if ($this->sourceUrlType === self::SOURCE_URL_PLAIN) { + return $this->appendPlainSourceUrlExtension($path, $ext); + } return $path . ($ext ? ".$ext" : ""); } -} \ No newline at end of file + + private function generateSourceUrl(): string + { + if ($this->sourceUrlType === self::SOURCE_URL_PLAIN) { + return sprintf('plain/%s', $this->imageUrl); + } + + return rtrim(strtr(base64_encode($this->imageUrl), '+/', '-_'), '='); + } + + private function appendPlainSourceUrlExtension(string $path, ?string $extension): string + { + if (preg_match('/[?&]([^=]+)(=([^&#]*))?/', $path)) { + return $path . ($extension ? "@$extension" : ""); + } + return $path; + } +} diff --git a/test/UrlTest.php b/test/UrlTest.php index ac97986..d848bc7 100644 --- a/test/UrlTest.php +++ b/test/UrlTest.php @@ -35,6 +35,25 @@ public function testUnsignedPathLegacyMode(string $url, string $fit, int $w, int $this->assertEquals($expected, $url->unsignedPath()); } + /** + * @param string $fit + * @param int $w + * @param int $h + * @param string $gravity + * @param bool $enlarge + * @param string $expected + * @dataProvider provideUnsignedPathLegacyModePlainSourceUrlInput + */ + public function testUnsignedPathLegacyModePlainSourceUrl(string $url, string $fit, int $w, int $h, string $gravity, bool $enlarge, string $expected) + { + $url = new Url($this->secureUrlBuilder(), $url, $w, $h); + $url->usePlainSourceUrl() + ->setFit($fit) + ->setGravity($gravity) + ->setEnlarge($enlarge); + $this->assertEquals($expected, $url->unsignedPath()); + } + /** * @param string $fit * @param int $w @@ -54,6 +73,26 @@ public function testUnsignedPathAnvancedMode(string $url, string $fit, int $w, i $this->assertEquals($expected, $url->unsignedPath()); } + /** + * @param string $fit + * @param int $w + * @param int $h + * @param string $gravity + * @param bool $enlarge + * @param string $expected + * @dataProvider provideUnsignedPathAdvancedModePlainSourceUrlInput + */ + public function testUnsignedPathAdvancedModePlainSourceUrl(string $url, string $fit, int $w, int $h, string $gravity, bool $enlarge, string $expected) + { + $url = new Url($this->secureUrlBuilder(), $url, $w, $h); + $url->useAdvancedMode() + ->usePlainSourceUrl() + ->setFit($fit) + ->setGravity($gravity) + ->setEnlarge($enlarge); + $this->assertEquals($expected, $url->unsignedPath()); + } + public function testToString() { $url = new Url($this->secureUrlBuilder(), self::IMAGE_URL, 300, 200); @@ -253,4 +292,142 @@ public function provideUnsignedPathAdvancedModeInput() ], ]; } + + public function provideUnsignedPathLegacyModePlainSourceUrlInput() + { + return [ + [ + self::IMAGE_URL, + "fit", + 300, + 200, + "sm", + false, + "/fit/300/200/sm/0/plain/local:///file.jpg" + ], + [ + self::IMAGE_URL, + "fill", + 300, + 200, + "sm", + false, + "/fill/300/200/sm/0/plain/local:///file.jpg" + ], + [ + self::IMAGE_URL, + "fit", + 400, + 200, + "sm", + false, + "/fit/400/200/sm/0/plain/local:///file.jpg" + ], + [ + self::IMAGE_URL, + "fit", + 300, + 300, + "sm", + false, + "/fit/300/300/sm/0/plain/local:///file.jpg" + ], + [ + self::IMAGE_URL, + "fit", + 300, + 200, + "no", + false, + "/fit/300/200/no/0/plain/local:///file.jpg" + ], + [ + self::IMAGE_URL, + "fit", + 300, + 200, + "sm", + true, + "/fit/300/200/sm/1/plain/local:///file.jpg" + ], + [ + self::IMAGE_URL_WITH_QUERY, + "fit", + 1200, + 900, + "sm", + false, + "/fit/1200/900/sm/0/plain/http://storage.recrm.ru/Static/13083_8483b9/11/WSIMG/1200_795_I_MC_jpg_W/resources/properties/1668/picture_0009.jpg?F80A64FF1B6E8585909336490F78A1E4@jpg" + ], + ]; + } + + public function provideUnsignedPathAdvancedModePlainSourceUrlInput() + { + return [ + [ + self::IMAGE_URL, + "fit", + 300, + 200, + "sm", + false, + "/w:300/h:200/rt:fit/g:sm/plain/local:///file.jpg" + ], + [ + self::IMAGE_URL, + "fill", + 300, + 200, + "sm", + false, + "/w:300/h:200/rt:fill/g:sm/plain/local:///file.jpg" + ], + [ + self::IMAGE_URL, + "fit", + 400, + 200, + "sm", + false, + "/w:400/h:200/rt:fit/g:sm/plain/local:///file.jpg" + ], + [ + self::IMAGE_URL, + "fit", + 300, + 300, + "sm", + false, + "/w:300/h:300/rt:fit/g:sm/plain/local:///file.jpg" + ], + [ + self::IMAGE_URL, + "fit", + 300, + 200, + "no", + false, + "/w:300/h:200/rt:fit/g:no:0:0/plain/local:///file.jpg" + ], + [ + self::IMAGE_URL, + "fit", + 300, + 200, + "sm", + true, + "/w:300/h:200/rt:fit/g:sm/el:1/plain/local:///file.jpg" + ], + [ + self::IMAGE_URL_WITH_QUERY, + "fit", + 1200, + 900, + "sm", + false, + "/w:1200/h:900/rt:fit/g:sm/plain/http://storage.recrm.ru/Static/13083_8483b9/11/WSIMG/1200_795_I_MC_jpg_W/resources/properties/1668/picture_0009.jpg?F80A64FF1B6E8585909336490F78A1E4@jpg" + ], + ]; + } }