Skip to content

Commit

Permalink
Document root provider
Browse files Browse the repository at this point in the history
  • Loading branch information
gocom committed Jan 24, 2020
1 parent 101651d commit f8fd0f3
Show file tree
Hide file tree
Showing 9 changed files with 341 additions and 9 deletions.
7 changes: 7 additions & 0 deletions src/Api/Provider/DocumentRootProviderInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@
*/
interface DocumentRootProviderInterface
{
/**
* Whether the provided document root is available.
*
* @return bool
*/
public function isAvailable(): bool;

/**
* Gets document root path.
*
Expand Down
65 changes: 65 additions & 0 deletions src/Provider/DocumentRoot/CommandLineProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

/**
* Textile - A Humane Web Text Generator.
*
* @link https://github.com/textile/php-textile
*/

declare(strict_types=1);

/*
* Copyright (c) 2019, PHP-Textile Team
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name Textile nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

namespace Netcarver\Textile\Provider\DocumentRoot;

use Netcarver\Textile\Api\Provider\DocumentRootProviderInterface;

/**
* Command line document root provider.
*/
class CommandLineProvider implements DocumentRootProviderInterface
{
/**
* {@inheritdoc}
*/
public function isAvailable(): bool
{
return \PHP_SAPI === 'cli';
}

/**
* {@inheritdoc}
*/
public function getPath(): string
{
return \getcwd() ?: '';
}
}
65 changes: 65 additions & 0 deletions src/Provider/DocumentRoot/PathTranslatedProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

/**
* Textile - A Humane Web Text Generator.
*
* @link https://github.com/textile/php-textile
*/

declare(strict_types=1);

/*
* Copyright (c) 2019, PHP-Textile Team
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name Textile nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

namespace Netcarver\Textile\Provider\DocumentRoot;

use Netcarver\Textile\Api\Provider\DocumentRootProviderInterface;

/**
* Document root provider.
*/
class PathTranslatedProvider implements DocumentRootProviderInterface
{
/**
* {@inheritdoc}
*/
public function isAvailable(): bool
{
return !empty($_SERVER['PATH_TRANSLATED']);
}

/**
* {@inheritdoc}
*/
public function getPath(): string
{
return $_SERVER['PATH_TRANSLATED'] ?? '';
}
}
65 changes: 65 additions & 0 deletions src/Provider/DocumentRoot/ServerDocumentRootProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

/**
* Textile - A Humane Web Text Generator.
*
* @link https://github.com/textile/php-textile
*/

declare(strict_types=1);

/*
* Copyright (c) 2019, PHP-Textile Team
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name Textile nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

namespace Netcarver\Textile\Provider\DocumentRoot;

use Netcarver\Textile\Api\Provider\DocumentRootProviderInterface;

/**
* Document root provider.
*/
class ServerDocumentRootProvider implements DocumentRootProviderInterface
{
/**
* {@inheritdoc}
*/
public function isAvailable(): bool
{
return !empty($_SERVER['DOCUMENT_ROOT']);
}

/**
* {@inheritdoc}
*/
public function getPath(): string
{
return $_SERVER['DOCUMENT_ROOT'] ?? '';
}
}
59 changes: 50 additions & 9 deletions src/Provider/DocumentRootProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,36 +41,77 @@
namespace Netcarver\Textile\Provider;

use Netcarver\Textile\Api\Provider\DocumentRootProviderInterface;
use Netcarver\Textile\Provider\DocumentRoot\CommandLineProvider;
use Netcarver\Textile\Provider\DocumentRoot\PathTranslatedProvider;
use Netcarver\Textile\Provider\DocumentRoot\ServerDocumentRootProvider;

/**
* Document root provider.
*/
class DocumentRootProvider implements DocumentRootProviderInterface
{
/**
* Document root providers.
*
* @var DocumentRootProviderInterface[]
*/
private $providers;

/**
* Document root path.
*
* @var string
*/
private $path;

/**
* Constructor.
*
* @param DocumentRootProviderInterface[]|null $providers
*/
public function __construct(
?array $providers = null
) {
$this->providers = $providers ?? [
new CommandLineProvider(),
new ServerDocumentRootProvider(),
new PathTranslatedProvider(),
];
}

/**
* {@inheritdoc}
*/
public function isAvailable(): bool
{
return $this->getPath() !== '';
}

/**
* {@inheritdoc}
*/
public function getPath(): string
{
if ($this->path !== null) {
return $this->path;
if ($this->path === null) {
$this->path = $this->getProvidedPath() ?? '';
}

if (\PHP_SAPI === 'cli') {
$this->path = \getcwd() ?: '';
} elseif (!empty($_SERVER['DOCUMENT_ROOT'])) {
$this->path = $_SERVER['DOCUMENT_ROOT'];
} elseif (!empty($_SERVER['PATH_TRANSLATED'])) {
$this->path = $_SERVER['PATH_TRANSLATED'];
return $this->path;
}

/**
* Gets a matching provided path.
*
* @return string|null
*/
private function getProvidedPath(): ?string
{
foreach ($this->providers as $provider) {
if ($provider->isAvailable()) {
return $provider->getPath();
}
}

return $this->path;
return null;
}
}
20 changes: 20 additions & 0 deletions test/Unit/Provider/DocumentRoot/CommandLineProviderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace Netcarver\Textile\Test\Unit\Provider\DocumentRoot;

use Netcarver\Textile\Provider\DocumentRoot\CommandLineProvider;
use PHPUnit\Framework\TestCase;

final class CommandLineProviderTest extends TestCase
{
public function testDocumentRootAlwaysProvided(): void
{
$documentRootProvider = new CommandLineProvider();

$this->assertIsString($documentRootProvider->getPath());

$this->assertIsBool($documentRootProvider->isAvailable());
}
}
20 changes: 20 additions & 0 deletions test/Unit/Provider/DocumentRoot/PathTranslatedProviderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace Netcarver\Textile\Test\Unit\Provider\DocumentRoot;

use Netcarver\Textile\Provider\DocumentRoot\PathTranslatedProvider;
use PHPUnit\Framework\TestCase;

final class PathTranslatedProviderTest extends TestCase
{
public function testDocumentRootAlwaysProvided(): void
{
$documentRootProvider = new PathTranslatedProvider();

$this->assertIsString($documentRootProvider->getPath());

$this->assertIsBool($documentRootProvider->isAvailable());
}
}
20 changes: 20 additions & 0 deletions test/Unit/Provider/DocumentRoot/ServerDocumentRootProviderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace Netcarver\Textile\Test\Unit\Provider\DocumentRoot;

use Netcarver\Textile\Provider\DocumentRoot\ServerDocumentRootProvider;
use PHPUnit\Framework\TestCase;

final class ServerDocumentRootProviderTest extends TestCase
{
public function testDocumentRootAlwaysProvided(): void
{
$documentRootProvider = new ServerDocumentRootProvider();

$this->assertIsString($documentRootProvider->getPath());

$this->assertIsBool($documentRootProvider->isAvailable());
}
}
29 changes: 29 additions & 0 deletions test/Unit/Provider/DocumentRootProviderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace Netcarver\Textile\Test\Unit\Provider;

use Netcarver\Textile\Provider\DocumentRootProvider;
use PHPUnit\Framework\TestCase;

final class DocumentRootProviderTest extends TestCase
{
public function testDocumentRootAlwaysProvided(): void
{
$documentRootProvider = new DocumentRootProvider();

$this->assertNotEmpty($documentRootProvider->getPath());

$this->assertTrue($documentRootProvider->isAvailable());
}

public function testNoProvidersAvailable(): void
{
$documentRootProvider = new DocumentRootProvider([]);

$this->assertSame('', $documentRootProvider->getPath());

$this->assertFalse($documentRootProvider->isAvailable());
}
}

0 comments on commit f8fd0f3

Please sign in to comment.