Completed
Push — extensions ( 84a6ae )
by
unknown
22:00 queued 07:01
created

func.php ➔ componentFunc()   B

Complexity

Conditions 4
Paths 2

Size

Total Lines 23
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 14
nc 2
nop 1
dl 0
loc 23
rs 8.7972
c 0
b 0
f 0
1
<?php
2
3
namespace League\Plates\Extension\RenderContext;
4
5
use League\Plates;
6
use League\Plates\Exception\FuncException;
7
8
function layoutFunc() {
9
    return function(FuncArgs $args) {
10
        list($name, $data) = $args->args;
11
12
        $layout = $args->template()->fork($name, $data ?: []);
13
        $args->template()->with('layout', $layout->reference);
14
15
        return $layout;
16
    };
17
}
18
19
function sectionFunc() {
20
    return function(FuncArgs $args) {
21
        list($name) = $args->args;
22
        return $args->template()->get('sections')->get($name);
23
    };
24
}
25
26
const START_APPEND = 0;
27
const START_PREPEND = 1;
28
const START_REPLACE = 2;
29
30
/** Starts the output buffering for a section, update of 0 = replace, 1 = append, 2 = prepend */
31
function startFunc($update = START_REPLACE) {
32
    return startBufferFunc(function(FuncArgs $args) use ($update) {
33
        return function($contents) use ($update, $args) {
34
            $name = $args->args[0];
35
            $sections = $args->template()->get('sections');
36
37
            if ($update === START_APPEND) {
38
                $sections->append($name, $contents);
39
            } else if ($update === START_PREPEND) {
40
                $sections->prepend($name, $contents);
41
            } else {
42
                $sections->add($name, $contents);
43
            }
44
        };
45
    });
46
}
47
48
function componentFunc($insert = null) {
49
    $insert = $insert ?: insertFunc();
50
    return startBufferFunc(function(FuncArgs $args) use ($insert) {
51
        if ($args->template()->get('component_slot_data') !== null) {
52
            throw new FuncException('Cannot nest component func calls.');
53
        }
54
55
        $args->template()->with('component_slot_data', []);
56
        return function($contents) use ($insert, $args) {
57
            list($name, $data) = $args->args;
58
59
            $data = array_merge(
60
                $data ?: [],
61
                ['slot' => $contents],
62
                $args->template()->get('component_slot_data')
63
            );
64
65
            $insert($args->withArgs([$name, $data]));
66
67
            $args->template()->with('component_slot_data', null);
68
        };
69
    });
70
}
71
72
function slotFunc() {
73
    return startBufferFunc(function(FuncArgs $args) {
74
        if ($args->template()->get('component_slot_data') === null) {
75
            throw new FuncException('Cannot call slot func outside of component definition.');
76
        }
77
78
        return function($contents) use ($args) {
79
            $slot_data = $args->template()->get('component_slot_data');
80
            $slot_data[$args->args[0]] = $contents;
81
            $args->template()->with('component_slot_data', $slot_data);
82
        };
83
    });
84
}
85
86
function startBufferFunc(callable $create_callback) {
87
    return function(FuncArgs $args) use ($create_callback) {
88
        $buffer_stack = $args->template()->get('buffer_stack') ?: [];
89
90
        ob_start();
91
        $buffer_stack[] = [ob_get_level(), $create_callback($args)];
92
93
        $args->template()->with('buffer_stack', $buffer_stack);
94
    };
95
}
96
97
function endFunc() {
98
    return function(FuncArgs $args) {
99
        $buffer_stack = $args->template()->get('buffer_stack') ?: [];
100
        if (!count($buffer_stack)) {
101
            throw new FuncException('Cannot end a section definition because no section has been started.');
102
        }
103
104
        list($ob_level, $callback) = array_pop($buffer_stack);
105
106
        if ($ob_level != ob_get_level()) {
107
            throw new FuncException('Output buffering level does not match when section was started.');
108
        }
109
110
        $contents = ob_get_clean();
111
112
        $callback($contents);
113
114
        $args->template()->with('buffer_stack', $buffer_stack);
115
    };
116
}
117
118
function insertFunc($echo = null) {
119
    $echo = $echo ?: Plates\Util\phpEcho();
120
121
    return function(FuncArgs $args) use ($echo) {
122
        list($name, $data) = $args->args;
123
        $child = $args->template()->fork($name, $data ?: []);
124
        $echo($args->render->renderTemplate($child));
125
    };
126
}
127
128
function accessTemplatePropFunc($prop) {
129
    return function(FuncArgs $args) use ($prop) {
130
        return $args->template()->{$prop};
131
    };
132
}
133
134
function escapeFunc($flags = ENT_COMPAT | ENT_HTML401, $encoding = 'UTF-8') {
135
    return function(FuncArgs $args) use ($flags, $encoding) {
136
        return htmlspecialchars($args->args[0], $flags, $encoding);
137
    };
138
}
139
140
function assertArgsFunc($num_required, $num_default = 0) {
141
    return function(FuncArgs $args, $next) use ($num_required, $num_default) {
142
        if (count($args->args) < $num_required) {
143
            throw new FuncException("Func {$args->func_name} has {$num_required} argument(s).");
144
        }
145
146
        if (count($args->args) >= $num_required + $num_default) {
147
            return $next($args);
148
        }
149
150
        $args = $args->withArgs(array_merge($args->args, array_fill(
151
            0,
152
            $num_required + $num_default - count($args->args),
153
            null
154
        )));
155
156
        return $next($args);
157
    };
158
}
159
160
function assertTemplateArgsFunc() {
161
    return assertArgsFunc(1, 2);
162
}
163
164
/** Creates aliases for certain functions */
165
function aliasNameFunc(array $aliases) {
166
    return function(FuncArgs $args, $next) use ($aliases) {
167
        if (!isset($aliases[$args->func_name])) {
168
            return $next($args);
169
        }
170
171
        while (isset($aliases[$args->func_name])) {
172
            $args = $args->withName($aliases[$args->func_name]);
173
        }
174
175
        return $next($args);
176
    };
177
}
178
179
/** Allows splitting of the handlers from the args name */
180
function splitByNameFunc(array $handlers) {
181
    return function(FuncArgs $args, $next) use ($handlers) {
182
        $name = $args->func_name;
183
        if (isset($handlers[$name])) {
184
            $handler = Plates\Util\stackGroup($handlers[$name]);
185
            return $handler($args, $next);
186
        }
187
188
        return $next($args);
189
    };
190
}
191