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

PhpView::toString()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 10
nc 4
nop 0
dl 0
loc 18
rs 9.9332
c 0
b 0
f 0
1
<?php
2
3
namespace WPEmerge\View;
4
5
use GuzzleHttp\Psr7;
6
use GuzzleHttp\Psr7\Response;
7
use WPEmerge\Exceptions\ViewException;
8
use WPEmerge\Facades\View;
9
10
/**
11
 * Render a view file with php.
12
 */
13
class PhpView implements ViewInterface {
14
	use HasNameTrait, HasContextTrait;
15
16
	/**
17
	 * Stack of rendered layout contents.
18
	 *
19
	 * @var array<string>
20
	 */
21
	protected static $layout_content_stack = [];
22
23
	/**
24
	 * Filepath to view.
25
	 *
26
	 * @var string
27
	 */
28
	protected $filepath = '';
29
30
	/**
31
	 * Layout to use.
32
	 *
33
	 * @var ViewInterface|null
34
	 */
35
	protected $layout = null;
36
37
	/**
38
	 * Get the top-most layout content from the stack.
39
	 *
40
	 * @codeCoverageIgnore
41
	 * @return string
42
	 */
43
	public static function getLayoutContent() {
44
		$stack = static::$layout_content_stack;
45
46
		if ( empty( $stack ) ) {
47
			return '';
48
		}
49
50
		return $stack[ count( $stack ) - 1 ];
51
	}
52
53
	/**
54
	 * Get filepath.
55
	 *
56
	 * @return string
57
	 */
58
	public function getFilepath() {
59
		return $this->filepath;
60
	}
61
62
	/**
63
	 * Set filepath.
64
	 *
65
	 * @param  string $filepath
66
	 * @return self   $this
67
	 */
68
	public function setFilepath( $filepath ) {
69
		$this->filepath = $filepath;
70
		return $this;
71
	}
72
73
	/**
74
	 * Get layout.
75
	 *
76
	 * @return ViewInterface|null
77
	 */
78
	public function getLayout() {
79
		return $this->layout;
80
	}
81
82
	/**
83
	 * Set layout.
84
	 *
85
	 * @param  ViewInterface|null $layout
86
	 * @return self               $this
87
	 */
88
	public function setLayout( ViewInterface $layout ) {
89
		$this->layout = $layout;
90
		return $this;
91
	}
92
93
	/**
94
	 * {@inheritDoc}
95
	 */
96
	public function toString() {
97
		if ( empty( $this->getName() ) ) {
98
			throw new ViewException( 'View must have a name.' );
99
		}
100
101
		if ( empty( $this->getFilepath() ) ) {
102
			throw new ViewException( 'View must have a filepath.' );
103
		}
104
105
		$html = (clone $this)->compose()->render();
106
107
		if ( $this->getLayout() !== null ) {
108
			static::$layout_content_stack[] = $html;
109
			$html = $this->getLayout()->toString();
110
			array_pop( static::$layout_content_stack );
111
		}
112
113
		return $html;
114
	}
115
116
	/**
117
	 * Compose the context.
118
	 *
119
	 * @return self $this
120
	 */
121
	protected function compose() {
122
		$context = $this->getContext();
123
		$this->with( ['global' => View::getGlobals()] );
124
		View::compose( $this );
125
		$this->with( $context );
126
		return $this;
127
	}
128
129
	/**
130
	 * Render the view to a string.
131
	 *
132
	 * @return string
133
	 */
134
	protected function render() {
135
		$__context = $this->getContext();
136
		ob_start();
137
		extract( $__context, EXTR_OVERWRITE );
138
		include( $this->getFilepath() );
139
		return ob_get_clean();
140
	}
141
142
	/**
143
	 * {@inheritDoc}
144
	 */
145
	public function toResponse() {
146
		return (new Response())
147
			->withHeader( 'Content-Type', 'text/html' )
148
			->withBody( Psr7\stream_for( $this->toString() ) );
149
	}
150
}
151