Completed
Push — master ( d2e043...09ed12 )
by Changwan
12:25
created

Template::layout()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 2
dl 0
loc 7
ccs 5
cts 5
cp 1
crap 1
rs 9.4285
c 0
b 0
f 0
1
<?php
2
namespace Wandu\View\Phiew;
3
4
use Exception;
5
use SplFileObject;
6
use Throwable;
7
use Closure;
8
use Wandu\View\Phiew\Contracts\ResolverInterface;
9
10
class Template
11
{
12
    /** @var \SplFileObject */
13
    protected $file;
14
    
15
    /** @var \Wandu\View\Phiew\Contracts\ResolverInterface */
16
    protected $resolver;
17
18
    /** @var int */
19
    protected $level;
20
    
21
    /** @var \Wandu\View\Phiew\Buffer */
22
    protected $buffer;
23
    
24 5
    public function __construct(SplFileObject $file, ResolverInterface $resolver)
25
    {
26 5
        $this->file = $file;
27 5
        $this->resolver = $resolver;
28 5
    }
29
30
    /**
31
     * @internal
32
     * @param array $attributes
33
     * @param array $contents
34
     * @return string
35
     * @throws \Exception
36
     * @throws \Throwable
37
     */
38 4
    public function execute(array $attributes = [], array $contents = [])
39
    {
40 4
        if ($this->buffer !== null) {
41
            throw new PhiewException('this template already rendering!', PhiewException::CODE_ALREADY_RENDERING);
42
        }
43 4
        $this->buffer = new Buffer($attributes, $contents);
44
45 4
        $this->level = ob_get_level();
46 4
        ob_start();
47 4
        extract($attributes);
48
49
        try {
50 4
            require $this->file->getRealPath();
51 3
            $this->buffer->resolveLayout();
52 1
        } catch (Exception $e) {
53 1
            while (ob_get_level() > $this->level) ob_end_clean();
54 1
            throw $e;
55
        } catch (Throwable $e) {
56
            while (ob_get_level() > $this->level) ob_end_clean();
57
            throw $e;
58
        }
59
        
60 3
        $this->buffer->write($this->clean());
61 3
        $buffer = $this->buffer->__toString();
62 3
        $this->buffer = null;
63 3
        return $buffer;
64
    }
65
66
    /**
67
     * @param string $name
68
     * @param array $attributes
69
     * @return string
70
     */
71 1
    public function render(string $name, array $attributes = [])
72
    {
73 1
        return $this->buffer->resolveRequire($this->resolver->resolve($name), $attributes);
74
    }
75
76
    /**
77
     * @param string $name
78
     * @param array $attributes
79
     */
80 1
    public function layout(string $name, array $attributes = [])
81
    {
82
        $this->syntax(function ($buffer) use ($name, $attributes) {
83 1
            $this->buffer->write($buffer);
84 1
            $this->buffer->setLayout($this->resolver->resolve($name), $attributes);
85 1
        });
86 1
    }
87
    
88
    public function endlayout()
89
    {
90
        $this->syntax(function () {
91
            $this->buffer->resolveLayout();
92
        });
93
    }
94
95
    /**
96
     * @param string $name
97
     */
98 1
    protected function push(string $name)
99
    {
100
        $this->syntax(function () use ($name) {
101 1
            $this->buffer->startPush($name);
102 1
        });
103 1
    }
104
    
105 1
    public function endpush()
106
    {
107
        $this->syntax(function ($buffer) {
108 1
            $this->buffer->resolvePush($buffer);
109 1
        });
110 1
    }
111
    
112 1
    public function section(string $name)
113
    {
114
        $this->syntax(function () use ($name) {
115 1
            $this->buffer->startSection($name);
116 1
        });
117 1
    }
118
    
119
    public function endsection()
120
    {
121 1
        $this->syntax(function ($buffer) {
122 1
            $this->buffer->resolveSection($buffer);
123 1
        });
124 1
    }
125
    
126 1
    public function content(string $name): string
127
    {
128 1
        return $this->buffer->getContent($name);
129
    }
130
131
    /**
132
     * @internal
133
     * @param \Closure $handle
134
     */
135 1
    protected function syntax(Closure $handle)
136
    {
137 1
        $handle($this->clean());
138 1
        ob_start();
139 1
    }
140
    
141
    /**
142
     * @internal
143
     * @return string
144
     */
145 3
    protected function clean()
146
    {
147 3
        $contents = '';
148 3
        while (ob_get_level() - $this->level > 0) {
149 3
            $contents = ob_get_contents() . $contents;
150 3
            ob_end_clean();
151
        }
152 3
        return $contents;
153
    }
154
}
155