Passed
Branch feature/php-layouts (77346e)
by Atanas
02:58
created

PhpViewEngine::make()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 3
nop 1
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace WPEmerge\View;
4
5
use WPEmerge\Exceptions\ViewException;
6
7
/**
8
 * Render view files with php.
9
 */
10
class PhpViewEngine implements ViewEngineInterface {
11
	/**
12
	 * {@inheritDoc}
13
	 */
14
	public function exists( $view ) {
15
		$file = $this->resolveFilepath( $view );
16
		return strlen( $file ) > 0;
17
	}
18
19
	/**
20
	 * {@inheritDoc}
21
	 */
22
	public function canonical( $view ) {
23
		$file = $this->resolveFilepath( $view );
24
		return $file;
25
	}
26
27
	/**
28
	 * {@inheritDoc}
29
	 */
30
	public function make( $views ) {
31
		foreach ( $views as $view ) {
32
			if ( $this->exists( $view ) ) {
33
				$filepath = $this->resolveFilepath( $view );
34
				return $this->makeView( $view, $filepath );
35
			}
36
		}
37
38
		throw new ViewException( 'View not found for "' . implode( ', ', $views ) . '"' );
39
	}
40
41
	/**
42
	 * Create a view instance.
43
	 *
44
	 * @param  string        $name
45
	 * @param  string        $filepath
46
	 * @return ViewInterface
47
	 */
48
	protected function makeView( $name, $filepath ) {
49
		$view = (new PhpView())
50
			->setName( $name )
51
			->setFilepath( $filepath );
52
53
		$layout = $this->getViewLayout( $view );
54
55
		if ( $layout !== null ) {
56
			$view->setLayout( $layout );
57
		}
58
59
		return $view;
60
	}
61
62
	/**
63
	 * Create a view instance for the given view's layout header, if any.
64
	 *
65
	 * @param  PhpView       $view
66
	 * @return ViewInterface
67
	 */
68
	protected function getViewLayout( PhpView $view ) {
69
		$layout_headers = array_filter( get_file_data(
70
			$view->getFilepath(),
71
			['App Layout']
72
		) );
73
74
		if ( empty( $layout_headers ) ) {
75
			return null;
76
		}
77
78
		$layout_file = trim( $layout_headers[0] );
79
80
		if ( ! $this->exists( $layout_file ) ) {
81
			throw new ViewException( 'View layout not found for "' . $layout_file . '"' );
82
		}
83
84
		return $this->makeView( $this->canonical( $layout_file ), $this->resolveFilepath( $layout_file ) );
85
	}
86
87
	/**
88
	 * Resolve a view name to an absolute filepath.
89
	 *
90
	 * @param  string $view
91
	 * @return string
92
	 */
93
	protected function resolveFilepath( $view ) {
94
		$file = locate_template( $view, false );
95
96
		if ( ! $file ) {
97
			// locate_template failed to find the view - try adding a .php extension.
98
			$file = locate_template( $view . '.php', false );
99
		}
100
101
		if ( ! $file ) {
102
			// locate_template failed to find the view - test if a valid absolute path was passed.
103
			$file = $this->resolveFilepathFromFilesystem( $view );
104
		}
105
106
		if ( $file ) {
107
			$file = realpath( $file );
108
		}
109
110
		return $file;
111
	}
112
113
	/**
114
	 * Resolve a view if it exists on the filesystem.
115
	 *
116
	 * @param  string $view
117
	 * @return string
118
	 */
119
	protected function resolveFilepathFromFilesystem( $view ) {
120
		return file_exists( $view ) ? $view : '';
121
	}
122
}
123