Skip to content

Commit

Permalink
Refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexMasterov committed Sep 24, 2016
1 parent b86bda3 commit ffcf09f
Show file tree
Hide file tree
Showing 6 changed files with 197 additions and 215 deletions.
32 changes: 32 additions & 0 deletions src/AbsoluteUrlGenerator.php
@@ -0,0 +1,32 @@
<?php

namespace AlexMasterov\TwigExtension;

use Psr\Http\Message\UriInterface;

final class AbsoluteUrlGenerator
{
/**
* @param UriInterface $uri
*
* @return string
*/
public function __invoke(UriInterface $uri)
{
$host = $uri->getHost();
$path = $uri->getPath();

if (empty($host)) {
return $path;
}

$port = $uri->getPort();
if (!empty($port)) {
$host .= ":{$port}";
}

$scheme = $uri->getScheme();

return "{$scheme}://{$host}{$path}";
}
}
100 changes: 55 additions & 45 deletions src/Psr7UriExtension.php
Expand Up @@ -2,12 +2,27 @@

namespace AlexMasterov\TwigExtension;

use AlexMasterov\TwigExtension\Traits\ServerRequestTrait;
use AlexMasterov\TwigExtension\AbsoluteUrlGenerator;
use AlexMasterov\TwigExtension\RelativePathGenerator;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\UriInterface;
use Twig_Extension;
use Twig_SimpleFunction;

class Psr7UriExtension extends Twig_Extension
final class Psr7UriExtension extends Twig_Extension
{
use ServerRequestTrait;
/**
* @var ServerRequestInterface
*/
private $request;

/**
* @param ServerRequestInterface $request
*/
public function __construct(ServerRequestInterface $request)
{
$this->request = $request;
}

/**
* @return string The extension name
Expand All @@ -20,8 +35,8 @@ public function getName()
public function getFunctions()
{
return [
new \Twig_SimpleFunction('absolute_url', [$this, 'generateAbsoluteUrl']),
new \Twig_SimpleFunction('relative_path', [$this, 'generateRelativePath'])
new Twig_SimpleFunction('absolute_url', [$this, 'generateAbsoluteUrl']),
new Twig_SimpleFunction('relative_path', [$this, 'generateRelativePath'])
];
}

Expand All @@ -30,28 +45,24 @@ public function getFunctions()
*
* @return string
*/
public function generateAbsoluteUrl($path)
public function generateAbsoluteUrl($path = null)
{
if ($this->isNetworkPath($path)) {
return $path;
}

$uri = $this->request->getUri();
$requestUri = $this->request->getUri();
$url = $this->absoluteUrl($requestUri);

$host = $uri->getHost();
if (empty($host)) {
return $path;
if (null === $path) {
return $url;
}

if (null !== $uri->getPort()) {
$host .= ':' . $uri->getPort();
if ($this->isNetworkPath($path)) {
return $path;
}

if (!$this->hasLeadingSlash($path)) {
$path = rtrim($uri->getPath(), '/') . '/' . $path;
if (!$this->hasLeadingSlash($url)) {
$url = rtrim($url, '/') . "/{$path}";
}

return $uri->getScheme() . '://' . $host . $path;
return $url;
}

/**
Expand All @@ -65,43 +76,42 @@ public function generateRelativePath($path)
return $path;
}

$uri = $this->request->getUri();

$basePath = $uri->getPath();
if ($path === $basePath) {
return '';
}

$baseParts = explode('/', $basePath, -1);
$pathParts = explode('/', $path);
$requestUri = $this->request->getUri();
$path = $this->relativePath($requestUri);

foreach ($baseParts as $i => $segment) {
if (isset($pathParts[$i]) && $segment === $pathParts[$i]) {
unset($baseParts[$i], $pathParts[$i]);
} else {
break;
}
}
return $path;
}

$path = str_repeat('../', count($baseParts)) . implode('/', $pathParts);
/**
* @param UriInterface $uri
*
* @return string
*/
private function relativePath()
{
$generator = new AbsoluteUrlGenerator();

if (empty($path)) {
return './';
}
return $generator();
}

if (empty($baseParts) && false !== strpos(current($pathParts), ':')) {
$path = './' . $path;
}
/**
* @param UriInterface $uri
*
* @return string
*/
private function absoluteUrl()
{
$generator = new RelativePathGenerator();

return $path;
return $generator();
}

/**
* @param string $path
*
* @return bool
*/
protected function isNetworkPath($path)
private function isNetworkPath($path)
{
return false !== strpos($path, '://')
|| '//' === substr($path, 0, 2);
Expand All @@ -112,7 +122,7 @@ protected function isNetworkPath($path)
*
* @return bool
*/
protected function hasLeadingSlash($path)
private function hasLeadingSlash($path)
{
return isset($path[0]) && '/' === $path[0];
}
Expand Down
44 changes: 44 additions & 0 deletions src/RelativePathGenerator.php
@@ -0,0 +1,44 @@
<?php

namespace AlexMasterov\TwigExtension;

use Psr\Http\Message\UriInterface;

final class RelativePathGenerator
{
/**
* @param UriInterface $uri
*
* @return string
*/
public function __invoke(UriInterface $uri)
{
$basePath = $uri->getPath();
if ($path === $basePath) {
return '';
}

$baseParts = explode('/', $basePath, -1);
$pathParts = explode('/', $path);

foreach ($baseParts as $i => $segment) {
if (isset($pathParts[$i]) && $segment === $pathParts[$i]) {
unset($baseParts[$i], $pathParts[$i]);
} else {
break;
}
}

$path = str_repeat('../', count($baseParts)) . implode('/', $pathParts);

if (empty($path)) {
return './';
}

if (empty($baseParts) && false !== strpos(current($pathParts), ':')) {
$path = "./{$path}";
}

return $path;
}
}
21 changes: 0 additions & 21 deletions src/Traits/ServerRequestTrait.php

This file was deleted.

66 changes: 66 additions & 0 deletions tests/AbsoluteUrlGeneratorTest.php
@@ -0,0 +1,66 @@
<?php

namespace AlexMasterov\TwigExtension\Tests;

use AlexMasterov\TwigExtension\AbsoluteUrlGenerator;
use PHPUnit_Framework_TestCase as TestCase;
use Psr\Http\Message\UriInterface;

class AbsoluteUrlGeneratorTest extends TestCase
{
public function testThenHostIsMissing()
{
$output = '/';

$uri = $this->createMockUri('http', '', '/', '');

$generator = new AbsoluteUrlGenerator();
$url = $generator($uri);

$this->assertEquals($output, $url);
}

public function testThenPortExists()
{
$output = 'http://localhost:80';

$uri = $this->createMockUri('http', 'localhost', '', 80);

$generator = new AbsoluteUrlGenerator();
$url = $generator($uri);

$this->assertEquals($output, $url);
}

public function testGenerateAbsoluteUrl()
{
$output = 'http://localhost:80/test';

$uri = $this->createMockUri('http', 'localhost', '/test', 80);

$generator = new AbsoluteUrlGenerator();
$url = $generator($uri);

$this->assertEquals($output, $url);
}

/**
* @param array $partsUrl
*
* @return UriInterface
*/
protected function createMockUri(
$scheme = null,
$host = null,
$path = null,
$port = null
) {
$uri = $this->createMock(UriInterface::class);
$uri->expects($this->any())->method('getScheme')->willReturn($scheme);
$uri->expects($this->any())->method('getHost')->willReturn($host);
$uri->expects($this->any())->method('getPath')->willReturn($path);
$uri->expects($this->any())->method('getPort')->willReturn($port);

return $uri;
}
}

0 comments on commit ffcf09f

Please sign in to comment.