1<?php
2/**
3 * Zend Framework (http://framework.zend.com/)
4 *
5 * @link      http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license   http://framework.zend.com/license/new-bsd New BSD License
8 */
9
10namespace Zend\View\Resolver;
11
12use Zend\View\Helper\ViewModel as ViewModelHelper;
13use Zend\View\Model\ModelInterface;
14use Zend\View\Renderer\RendererInterface;
15
16/**
17 * Relative fallback resolver - resolves to view templates in a sub-path of the
18 * currently set view model's template (if the current renderer has the `view_model` plugin set).
19 *
20 * This allows for usage of partial template paths such as `some/partial`, resolving to
21 * `my/module/script/path/some/partial.phtml`, while rendering template `my/module/script/path/my-view`
22 */
23class RelativeFallbackResolver implements ResolverInterface
24{
25    const NS_SEPARATOR = '/';
26
27    /**
28     * @var ResolverInterface
29     */
30    private $resolver;
31
32    /**
33     * Constructor
34     *
35     * @param ResolverInterface $resolver
36     */
37    public function __construct(ResolverInterface $resolver)
38    {
39        $this->resolver = $resolver;
40    }
41
42    /**
43     * {@inheritDoc}
44     */
45    public function resolve($name, RendererInterface $renderer = null)
46    {
47        $plugin = array($renderer, 'plugin');
48
49        if (! is_callable($plugin)) {
50            return false;
51        }
52
53        $helper = call_user_func($plugin, 'view_model');
54
55        if (! $helper instanceof ViewModelHelper) {
56            return false;
57        }
58
59        $currentModel = $helper->getCurrent();
60
61        if (! $currentModel instanceof ModelInterface) {
62            return false;
63        }
64
65        $currentTemplate = $currentModel->getTemplate();
66        $position        = strrpos($currentTemplate, self::NS_SEPARATOR);
67
68        if (! $position) {
69            return false;
70        }
71
72        return $this->resolver->resolve(substr($currentTemplate, 0, $position) . self::NS_SEPARATOR . $name, $renderer);
73    }
74}
75