Skip to content

Commit b9b7951

Browse files
authored
Merge pull request #176 from laminas/2.23.x-merge-up-into-3.0.x_WZrNdKUo
Merge release 2.23.0 into 3.0.x
2 parents 620774e + 69ea122 commit b9b7951

File tree

7 files changed

+157
-39
lines changed

7 files changed

+157
-39
lines changed

psalm-baseline.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,9 +618,15 @@
618618
</PropertyNotSetInConstructor>
619619
</file>
620620
<file src="src/Helper/Layout.php">
621+
<PossiblyNullReference occurrences="1">
622+
<code>plugin</code>
623+
</PossiblyNullReference>
621624
<RedundantCastGivenDocblockType occurrences="1">
622625
<code>(string) $template</code>
623626
</RedundantCastGivenDocblockType>
627+
<UndefinedInterfaceMethod occurrences="1">
628+
<code>plugin</code>
629+
</UndefinedInterfaceMethod>
624630
</file>
625631
<file src="src/Helper/Navigation.php">
626632
<InvalidFunctionCall occurrences="1">

src/Helper/BasePath.php

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,43 +4,55 @@
44

55
namespace Laminas\View\Helper;
66

7-
use Laminas\View\Exception;
7+
use Laminas\View\Exception\RuntimeException;
88

99
use function ltrim;
1010
use function rtrim;
11+
use function sprintf;
1112

1213
/**
1314
* Helper for retrieving the base path.
15+
*
16+
* @final
1417
*/
1518
class BasePath extends AbstractHelper
1619
{
17-
/**
18-
* Base path
19-
*
20-
* @var string
21-
*/
20+
use DeprecatedAbstractHelperHierarchyTrait;
21+
22+
/** @var string|null */
2223
protected $basePath;
2324

25+
public function __construct(?string $basePath = null)
26+
{
27+
if ($basePath !== null) {
28+
$this->setBasePath($basePath);
29+
}
30+
}
31+
2432
/**
2533
* Returns site's base path, or file with base path prepended.
2634
*
2735
* $file is appended to the base path for simplicity.
2836
*
2937
* @param string|null $file
30-
* @throws Exception\RuntimeException
38+
* @throws RuntimeException
3139
* @return string
3240
*/
3341
public function __invoke($file = null)
3442
{
35-
if (null === $this->basePath) {
36-
throw new Exception\RuntimeException('No base path provided');
43+
if ($this->basePath === null) {
44+
throw new RuntimeException('No base path provided');
3745
}
3846

39-
if (null !== $file) {
40-
$file = '/' . ltrim($file, '/');
47+
if ($file !== null && $file !== '') {
48+
return sprintf(
49+
'%s/%s',
50+
$this->basePath,
51+
ltrim($file, '/')
52+
);
4153
}
4254

43-
return $this->basePath . $file;
55+
return $this->basePath;
4456
}
4557

4658
/**

src/Helper/Layout.php

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
use Laminas\View\Exception;
88
use Laminas\View\Model\ModelInterface as Model;
9-
use Laminas\View\Renderer\PhpRenderer;
109

1110
use function assert;
1211
use function sprintf;
@@ -99,12 +98,8 @@ public function setTemplate($template)
9998
protected function getViewModelHelper()
10099
{
101100
if (! $this->viewModelHelper) {
102-
/**
103-
* @psalm-suppress DeprecatedMethod
104-
*/
105101
$renderer = $this->getView();
106-
assert($renderer instanceof PhpRenderer);
107-
$helper = $renderer->plugin('view_model');
102+
$helper = $renderer->plugin('view_model');
108103
assert($helper instanceof ViewModel);
109104
$this->viewModelHelper = $helper;
110105
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Laminas\View\Helper\Service;
6+
7+
use ArrayAccess;
8+
use Laminas\View\Helper\BasePath;
9+
use Psr\Container\ContainerInterface;
10+
11+
use function assert;
12+
use function is_array;
13+
use function is_string;
14+
15+
final class BasePathFactory
16+
{
17+
public function __invoke(ContainerInterface $container): BasePath
18+
{
19+
$config = $container->has('config')
20+
? $container->get('config')
21+
: [];
22+
23+
assert(is_array($config) || $config instanceof ArrayAccess);
24+
25+
// The expected location in config for the base path in an MVC application
26+
// is config.view_manager.base_path
27+
// @link https://docs.laminas.dev/laminas-mvc/services/#viewmanager
28+
29+
$viewConfig = $config['view_manager'] ?? [];
30+
assert(is_array($viewConfig));
31+
32+
$basePath = $viewConfig['base_path'] ?? null;
33+
assert(is_string($basePath) || $basePath === null);
34+
35+
return new BasePath($basePath);
36+
}
37+
}

src/HelperPluginManager.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ class HelperPluginManager extends AbstractPluginManager
160160
Helper\Asset::class => Helper\Service\AssetFactory::class,
161161
Helper\HtmlAttributes::class => Helper\Service\HtmlAttributesFactory::class,
162162
Helper\Identity::class => Helper\Service\IdentityFactory::class,
163-
Helper\BasePath::class => InvokableFactory::class,
163+
Helper\BasePath::class => Helper\Service\BasePathFactory::class,
164164
Helper\Cycle::class => InvokableFactory::class,
165165
Helper\DeclareVars::class => InvokableFactory::class,
166166
// overridden in ViewHelperManagerFactory

test/Helper/BasePathTest.php

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,40 +4,53 @@
44

55
namespace LaminasTest\View\Helper;
66

7+
use Laminas\View\Exception\RuntimeException;
78
use Laminas\View\Helper\BasePath;
89
use PHPUnit\Framework\TestCase;
910

1011
class BasePathTest extends TestCase
1112
{
12-
public function testBasePathWithoutFile(): void
13+
/** @return array<array-key, array{0: string, 1: string|null, 2: string}> */
14+
public function basePathDataProvider(): array
1315
{
14-
$helper = new BasePath();
15-
$helper->setBasePath('/foo');
16-
17-
$this->assertEquals('/foo', $helper());
16+
return [
17+
['/foo', null, '/foo'],
18+
['/foo', 'bar', '/foo/bar'],
19+
['/foo', 'bar/', '/foo/bar/'],
20+
['/foo', '/bar/', '/foo/bar/'],
21+
['/foo/', null, '/foo'],
22+
['/foo/', 'bar', '/foo/bar'],
23+
['/foo/', 'bar/', '/foo/bar/'],
24+
['/foo/', '/bar/', '/foo/bar/'],
25+
['/foo//', '//bar', '/foo/bar'],
26+
['', null, ''],
27+
['', '', ''],
28+
['', 'bar', '/bar'],
29+
['', 'bar/', '/bar/'],
30+
['', '/bar/', '/bar/'],
31+
['', '//bar', '/bar'],
32+
];
1833
}
1934

20-
public function testBasePathWithFile(): void
35+
/** @dataProvider basePathDataProvider */
36+
public function testBasePathHelperYieldsExpectedOutput(string $basePath, ?string $argument, string $expect): void
2137
{
22-
$helper = new BasePath();
23-
$helper->setBasePath('/foo');
24-
25-
$this->assertEquals('/foo/bar', $helper('bar'));
38+
$helper = new BasePath($basePath);
39+
self::assertEquals($expect, $helper->__invoke($argument));
2640
}
2741

28-
public function testBasePathNoDoubleSlashes(): void
42+
public function testThatAnExceptionIsThrownWhenTheBasePathIsNull(): void
2943
{
30-
$helper = new BasePath();
31-
$helper->setBasePath('/');
32-
33-
$this->assertEquals('/', $helper('/'));
44+
$helper = new BasePath(null);
45+
$this->expectException(RuntimeException::class);
46+
$this->expectExceptionMessage('No base path provided');
47+
$helper->__invoke();
3448
}
3549

36-
public function testBasePathWithFilePrefixedBySlash(): void
50+
public function testThatTheBasePathCanBeChanged(): void
3751
{
38-
$helper = new BasePath();
39-
$helper->setBasePath('/foo');
40-
41-
$this->assertEquals('/foo/bar', $helper('/bar'));
52+
$helper = new BasePath(null);
53+
$helper->setBasePath('something');
54+
self::assertEquals('something/else', $helper->__invoke('else'));
4255
}
4356
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace LaminasTest\View\Helper\Service;
6+
7+
use Laminas\ServiceManager\ServiceManager;
8+
use Laminas\View\Helper\BasePath;
9+
use Laminas\View\Helper\Service\BasePathFactory;
10+
use Laminas\View\HelperPluginManager;
11+
use PHPUnit\Framework\TestCase;
12+
13+
class BasePathFactoryTest extends TestCase
14+
{
15+
private ServiceManager $container;
16+
17+
protected function setUp(): void
18+
{
19+
parent::setUp();
20+
$this->container = new ServiceManager();
21+
}
22+
23+
/** @return array<string, array{0: array}> */
24+
public function configDataProvider(): array
25+
{
26+
return [
27+
'Empty Config' => [[]],
28+
'Base Path Config Missing' => [['view_manager' => []]],
29+
'Base Path Config Null' => [['view_manager' => ['base_path' => null]]],
30+
'Base Path Config Set' => [['view_manager' => ['base_path' => '/foo']]],
31+
];
32+
}
33+
34+
/** @dataProvider configDataProvider */
35+
public function testFactoryWithVariousConfigurationSetups(array $config): void
36+
{
37+
$this->container->setService('config', $config);
38+
39+
$helper = (new BasePathFactory())($this->container);
40+
self::assertInstanceOf(BasePath::class, $helper);
41+
}
42+
43+
public function testHelperWillBeReturnedWhenThereIsNoConfigurationAtAll(): void
44+
{
45+
self::assertFalse($this->container->has('config'));
46+
$helper = (new BasePathFactory())($this->container);
47+
self::assertInstanceOf(BasePath::class, $helper);
48+
}
49+
50+
public function testThatTheBasePathFactoryIsWiredUpByDefault(): void
51+
{
52+
$manager = new HelperPluginManager(new ServiceManager());
53+
self::assertInstanceOf(BasePath::class, $manager->get(BasePath::class));
54+
}
55+
}

0 commit comments

Comments
 (0)