Version Description
- added Danish translation. props phh
- updated Swedish translation. props EyesX
- fixed issue with multiple
parse_query
calls. props hezachenary - added
p2p_post_admin_column_link
andp2p_user_admin_column_link
filters. props PareshRadadiya
Download this release
Release Info
Developer | scribu |
Plugin | Posts 2 Posts |
Version | 1.6.4 |
Comparing to | |
See all releases |
Code changes from version 1.6.3 to 1.6.4
- CONTRIBUTING.md +14 -10
- admin/box.js +55 -3
- admin/column-post.php +3 -1
- admin/column-user.php +3 -1
- admin/mustache.php +7 -12
- composer.json +18 -0
- core/init.php +0 -18
- lang/posts-to-posts-da_DK.mo +0 -0
- lang/posts-to-posts-da_DK.po +156 -0
- lang/posts-to-posts-sv_SE.mo +0 -0
- lang/posts-to-posts-sv_SE.po +130 -55
- lang/posts-to-posts-zh_CN.mo +0 -0
- lang/posts-to-posts-zh_CN.po +155 -0
- mustache/LICENSE +0 -22
- mustache/Mustache.php +0 -910
- mustache/MustacheLoader.php +0 -85
- mustache/README.markdown +0 -98
- posts-to-posts.php +26 -9
- readme.txt +8 -2
- vendor/mustache/mustache/.travis.yml +12 -0
- vendor/mustache/mustache/CONTRIBUTING.md +33 -0
- vendor/mustache/mustache/LICENSE +21 -0
- vendor/mustache/mustache/README.md +71 -0
- vendor/mustache/mustache/composer.json +24 -0
- vendor/mustache/mustache/phpunit.xml.dist +17 -0
- vendor/mustache/mustache/src/Mustache/Autoloader.php +74 -0
- vendor/mustache/mustache/src/Mustache/Cache.php +38 -0
- vendor/mustache/mustache/src/Mustache/Cache/AbstractCache.php +60 -0
- vendor/mustache/mustache/src/Mustache/Cache/FilesystemCache.php +159 -0
- vendor/mustache/mustache/src/Mustache/Cache/NoopCache.php +49 -0
- vendor/mustache/mustache/src/Mustache/Compiler.php +493 -0
- vendor/mustache/mustache/src/Mustache/Context.php +154 -0
- vendor/mustache/mustache/src/Mustache/Engine.php +747 -0
- vendor/mustache/mustache/src/Mustache/Exception.php +18 -0
- vendor/mustache/mustache/src/Mustache/Exception/InvalidArgumentException.php +18 -0
- vendor/mustache/mustache/src/Mustache/Exception/LogicException.php +18 -0
- vendor/mustache/mustache/src/Mustache/Exception/RuntimeException.php +18 -0
- vendor/mustache/mustache/src/Mustache/Exception/SyntaxException.php +36 -0
- vendor/mustache/mustache/src/Mustache/Exception/UnknownFilterException.php +32 -0
- vendor/mustache/mustache/src/Mustache/Exception/UnknownHelperException.php +32 -0
- vendor/mustache/mustache/src/Mustache/Exception/UnknownTemplateException.php +32 -0
- vendor/mustache/mustache/src/Mustache/HelperCollection.php +172 -0
- vendor/mustache/mustache/src/Mustache/LambdaHelper.php +49 -0
- vendor/mustache/mustache/src/Mustache/Loader.php +27 -0
- vendor/mustache/mustache/src/Mustache/Loader/ArrayLoader.php +79 -0
- vendor/mustache/mustache/src/Mustache/Loader/CascadingLoader.php +69 -0
- vendor/mustache/mustache/src/Mustache/Loader/FilesystemLoader.php +124 -0
- vendor/mustache/mustache/src/Mustache/Loader/InlineLoader.php +123 -0
- vendor/mustache/mustache/src/Mustache/Loader/MutableLoader.php +35 -0
- vendor/mustache/mustache/src/Mustache/Loader/StringLoader.php +39 -0
- vendor/mustache/mustache/src/Mustache/Logger.php +144 -0
- vendor/mustache/mustache/src/Mustache/Logger/AbstractLogger.php +121 -0
- vendor/mustache/mustache/src/Mustache/Logger/StreamLogger.php +194 -0
- vendor/mustache/mustache/src/Mustache/Parser.php +206 -0
- vendor/mustache/mustache/src/Mustache/Template.php +176 -0
- vendor/mustache/mustache/src/Mustache/Tokenizer.php +327 -0
- {core → vendor/scribu/lib-posts-to-posts}/api.php +0 -0
- {core → vendor/scribu/lib-posts-to-posts}/autoload.php +6 -0
- vendor/scribu/lib-posts-to-posts/composer.json +13 -0
- {core → vendor/scribu/lib-posts-to-posts}/connection-type-factory.php +0 -0
- {core → vendor/scribu/lib-posts-to-posts}/connection-type.php +0 -0
- {core → vendor/scribu/lib-posts-to-posts}/determinate-connection-type.php +0 -0
- {core → vendor/scribu/lib-posts-to-posts}/directed-connection-type.php +0 -0
- {core → vendor/scribu/lib-posts-to-posts}/direction-strategy.php +0 -0
- {core → vendor/scribu/lib-posts-to-posts}/exception.php +0 -0
- {core → vendor/scribu/lib-posts-to-posts}/indeterminate-connection-type.php +0 -0
- {core → vendor/scribu/lib-posts-to-posts}/indeterminate-directed-connection-type.php +0 -0
- {core → vendor/scribu/lib-posts-to-posts}/item-any.php +0 -0
- {core → vendor/scribu/lib-posts-to-posts}/item-attachment.php +0 -0
- {core → vendor/scribu/lib-posts-to-posts}/item-post.php +0 -0
- {core → vendor/scribu/lib-posts-to-posts}/item-user.php +0 -0
- {core → vendor/scribu/lib-posts-to-posts}/item.php +0 -0
- {core → vendor/scribu/lib-posts-to-posts}/list-renderer.php +0 -0
- {core → vendor/scribu/lib-posts-to-posts}/list.php +0 -0
- {core → vendor/scribu/lib-posts-to-posts}/query-post.php +0 -0
- {core → vendor/scribu/lib-posts-to-posts}/query-user.php +0 -0
- {core → vendor/scribu/lib-posts-to-posts}/query.php +2 -2
- {core → vendor/scribu/lib-posts-to-posts}/reciprocal-connection-type.php +0 -0
- {core → vendor/scribu/lib-posts-to-posts}/shortcodes.php +0 -0
- {core → vendor/scribu/lib-posts-to-posts}/side-attachment.php +0 -0
- {core → vendor/scribu/lib-posts-to-posts}/side-post.php +0 -0
- {core → vendor/scribu/lib-posts-to-posts}/side-user.php +0 -0
- {core → vendor/scribu/lib-posts-to-posts}/side.php +0 -0
- {core → vendor/scribu/lib-posts-to-posts}/storage.php +0 -0
- {core → vendor/scribu/lib-posts-to-posts}/url-query.php +0 -0
- {core → vendor/scribu/lib-posts-to-posts}/util.php +0 -0
- {core → vendor/scribu/lib-posts-to-posts}/widget.php +0 -0
- {scb → vendor/scribu/scb-framework}/AdminPage.php +0 -0
- {scb → vendor/scribu/scb-framework}/BoxesPage.php +0 -0
- {scb → vendor/scribu/scb-framework}/Cron.php +0 -0
- {scb → vendor/scribu/scb-framework}/Forms.php +0 -0
- {scb → vendor/scribu/scb-framework}/Hooks.php +0 -0
- {scb → vendor/scribu/scb-framework}/Options.php +0 -0
- {scb → vendor/scribu/scb-framework}/PostMetabox.php +3 -3
- {scb → vendor/scribu/scb-framework}/Table.php +0 -0
- {scb → vendor/scribu/scb-framework}/Util.php +2 -0
- {scb → vendor/scribu/scb-framework}/Widget.php +0 -0
- {scb → vendor/scribu/scb-framework}/composer.json +0 -0
- {scb → vendor/scribu/scb-framework}/load-composer.php +0 -0
- {scb → vendor/scribu/scb-framework}/load.php +0 -0
CONTRIBUTING.md
CHANGED
@@ -2,14 +2,24 @@ This guide is meant for developers wanting to work on the plugin code.
|
|
2 |
|
3 |
### Setup
|
4 |
|
5 |
-
Make a fork and clone it:
|
6 |
|
7 |
```
|
8 |
-
git clone
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
```
|
10 |
|
11 |
You can now work on the PHP and CSS files. Please follow the [WordPress Coding Standards](http://make.wordpress.org/core/handbook/coding-standards/).
|
12 |
|
|
|
|
|
|
|
|
|
13 |
### Unit Tests
|
14 |
|
15 |
If you want to add a new feature, please consider adding a new test for it as well.
|
@@ -24,14 +34,8 @@ Step 1: Install and configure the official WordPress testing suite:
|
|
24 |
|
25 |
Note that all data in the test DB will be _deleted_ once you run the tests.
|
26 |
|
27 |
-
Step 2:
|
28 |
-
|
29 |
-
```bash
|
30 |
-
php composer.phar install --dev
|
31 |
-
```
|
32 |
-
|
33 |
-
Step 3: Run the tests:
|
34 |
|
35 |
```bash
|
36 |
-
|
37 |
```
|
2 |
|
3 |
### Setup
|
4 |
|
5 |
+
Step 1: Make a fork and clone it:
|
6 |
|
7 |
```
|
8 |
+
git clone git@github.com:{YOUR GITHUB USERNAME}/wp-posts-to-posts.git posts-to-posts
|
9 |
+
```
|
10 |
+
|
11 |
+
Step 2: Install the dependencies via [Composer](https://getcomposer.org):
|
12 |
+
|
13 |
+
```bash
|
14 |
+
php composer.phar install
|
15 |
```
|
16 |
|
17 |
You can now work on the PHP and CSS files. Please follow the [WordPress Coding Standards](http://make.wordpress.org/core/handbook/coding-standards/).
|
18 |
|
19 |
+
Step 3: Open a pull request.
|
20 |
+
|
21 |
+
**Note:** This repository only contains the admin UI; the core functionality is in [lib-posts-to-posts](https://github.com/scribu/wp-lib-posts-to-posts).
|
22 |
+
|
23 |
### Unit Tests
|
24 |
|
25 |
If you want to add a new feature, please consider adding a new test for it as well.
|
34 |
|
35 |
Note that all data in the test DB will be _deleted_ once you run the tests.
|
36 |
|
37 |
+
Step 2: Run the tests:
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
|
39 |
```bash
|
40 |
+
phpunit
|
41 |
```
|
admin/box.js
CHANGED
@@ -20,11 +20,16 @@
|
|
20 |
return jQuery('#p2p-template-' + name).html();
|
21 |
};
|
22 |
|
|
|
23 |
Candidate = Backbone.Model.extend({});
|
24 |
|
|
|
25 |
Connection = Backbone.Model.extend({});
|
26 |
|
|
|
27 |
Candidates = Backbone.Model.extend({
|
|
|
|
|
28 |
sync: function() {
|
29 |
var params, _this = this;
|
30 |
params = {
|
@@ -36,6 +41,8 @@
|
|
36 |
_this.trigger('sync', response);
|
37 |
});
|
38 |
},
|
|
|
|
|
39 |
validate: function(attrs) {
|
40 |
var _ref = attrs.paged;
|
41 |
if (0 < _ref && _ref <= this.total_pages) {
|
@@ -45,8 +52,11 @@
|
|
45 |
}
|
46 |
});
|
47 |
|
|
|
48 |
Connections = Backbone.Collection.extend({
|
49 |
model: Connection,
|
|
|
|
|
50 |
createItemAndConnect: function(title) {
|
51 |
var data, _this = this;
|
52 |
data = {
|
@@ -57,6 +67,8 @@
|
|
57 |
_this.trigger('create', response);
|
58 |
});
|
59 |
},
|
|
|
|
|
60 |
create: function(candidate) {
|
61 |
var data, _this = this;
|
62 |
data = {
|
@@ -67,6 +79,8 @@
|
|
67 |
_this.trigger('create', response);
|
68 |
});
|
69 |
},
|
|
|
|
|
70 |
"delete": function(connection) {
|
71 |
var data, _this = this;
|
72 |
data = {
|
@@ -77,6 +91,8 @@
|
|
77 |
_this.trigger('delete', response, connection);
|
78 |
});
|
79 |
},
|
|
|
|
|
80 |
clear: function() {
|
81 |
var data, _this = this;
|
82 |
data = {
|
@@ -88,17 +104,21 @@
|
|
88 |
}
|
89 |
});
|
90 |
|
|
|
91 |
ConnectionsView = Backbone.View.extend({
|
|
|
92 |
events: {
|
93 |
'click th.p2p-col-delete .p2p-icon': 'clear',
|
94 |
'click td.p2p-col-delete .p2p-icon': 'delete'
|
95 |
},
|
|
|
96 |
initialize: function(options) {
|
97 |
this.options = options;
|
98 |
this.maybe_make_sortable();
|
99 |
this.collection.on('create', this.afterCreate, this);
|
100 |
this.collection.on('clear', this.afterClear, this);
|
101 |
},
|
|
|
102 |
maybe_make_sortable: function() {
|
103 |
if (this.$('th.p2p-col-order').length) {
|
104 |
this.$('tbody').sortable({
|
@@ -114,6 +134,7 @@
|
|
114 |
});
|
115 |
}
|
116 |
},
|
|
|
117 |
clear: function(ev) {
|
118 |
var $td;
|
119 |
ev.preventDefault();
|
@@ -124,9 +145,11 @@
|
|
124 |
row_wait($td);
|
125 |
this.collection.clear();
|
126 |
},
|
|
|
127 |
afterClear: function() {
|
128 |
this.$el.hide().find('tbody').html('');
|
129 |
},
|
|
|
130 |
"delete": function(ev) {
|
131 |
var $td, req;
|
132 |
ev.preventDefault();
|
@@ -139,20 +162,25 @@
|
|
139 |
remove_row($td);
|
140 |
});
|
141 |
},
|
|
|
142 |
afterCreate: function(response) {
|
143 |
this.$el.show().find('tbody').append(response.row);
|
144 |
this.collection.trigger('append', response);
|
145 |
}
|
146 |
});
|
147 |
|
|
|
148 |
CandidatesView = Backbone.View.extend({
|
|
|
149 |
template: Mustache.compile(get_mustache_template('tab-list')),
|
|
|
150 |
events: {
|
151 |
'keypress :text': 'handleReturn',
|
152 |
'keyup :text': 'handleSearch',
|
153 |
'click .p2p-prev, .p2p-next': 'changePage',
|
154 |
'click td.p2p-col-create div': 'promote'
|
155 |
},
|
|
|
156 |
initialize: function(options) {
|
157 |
this.options = options;
|
158 |
this.spinner = options.spinner;
|
@@ -162,6 +190,7 @@
|
|
162 |
this.collection.on('error', this.afterInvalid, this);
|
163 |
this.collection.on('invalid', this.afterInvalid, this);
|
164 |
},
|
|
|
165 |
promote: function(ev) {
|
166 |
var $td, req, _this = this;
|
167 |
ev.preventDefault();
|
@@ -179,11 +208,13 @@
|
|
179 |
}
|
180 |
});
|
181 |
},
|
|
|
182 |
handleReturn: function(ev) {
|
183 |
if (ev.keyCode === ENTER_KEY) {
|
184 |
ev.preventDefault();
|
185 |
}
|
186 |
},
|
|
|
187 |
handleSearch: function(ev) {
|
188 |
var $searchInput, delayed,
|
189 |
_this = this;
|
@@ -204,6 +235,7 @@
|
|
204 |
});
|
205 |
}, 400);
|
206 |
},
|
|
|
207 |
changePage: function(ev) {
|
208 |
var $navButton, new_page;
|
209 |
$navButton = jQuery(ev.currentTarget);
|
@@ -216,6 +248,7 @@
|
|
216 |
this.spinner.appendTo(this.$('.p2p-navigation'));
|
217 |
this.collection.save('paged', new_page);
|
218 |
},
|
|
|
219 |
afterCandidatesRefreshed: function(response) {
|
220 |
this.spinner.remove();
|
221 |
this.$('button, .p2p-results, .p2p-navigation, .p2p-notice').remove();
|
@@ -229,22 +262,27 @@
|
|
229 |
}
|
230 |
});
|
231 |
|
|
|
232 |
CreatePostView = Backbone.View.extend({
|
|
|
233 |
events: {
|
234 |
'click button': 'createItem',
|
235 |
'keypress :text': 'handleReturn'
|
236 |
},
|
|
|
237 |
initialize: function(options) {
|
238 |
this.options = options;
|
239 |
this.createButton = this.$('button');
|
240 |
this.createInput = this.$(':text');
|
241 |
},
|
|
|
242 |
handleReturn: function(ev) {
|
243 |
if (ev.keyCode === ENTER_KEY) {
|
244 |
this.createButton.click();
|
245 |
ev.preventDefault();
|
246 |
}
|
247 |
},
|
|
|
248 |
createItem: function(ev) {
|
249 |
var req, title, _this = this;
|
250 |
ev.preventDefault();
|
@@ -265,11 +303,14 @@
|
|
265 |
}
|
266 |
});
|
267 |
|
|
|
268 |
MetaboxView = Backbone.View.extend({
|
|
|
269 |
events: {
|
270 |
'click .p2p-toggle-tabs': 'toggleTabs',
|
271 |
'click .wp-tab-bar li': 'setActiveTab'
|
272 |
},
|
|
|
273 |
initialize: function(options) {
|
274 |
this.options = options;
|
275 |
this.spinner = options.spinner;
|
@@ -278,6 +319,7 @@
|
|
278 |
options.connections.on('clear', this.afterConnectionDeleted, this);
|
279 |
options.connections.on('delete', this.afterConnectionDeleted, this);
|
280 |
},
|
|
|
281 |
toggleTabs: function(ev) {
|
282 |
var $tabs;
|
283 |
ev.preventDefault();
|
@@ -288,6 +330,7 @@
|
|
288 |
this.initializedCandidates = true;
|
289 |
}
|
290 |
},
|
|
|
291 |
setActiveTab: function(ev) {
|
292 |
var $tab;
|
293 |
ev.preventDefault();
|
@@ -296,11 +339,13 @@
|
|
296 |
$tab.addClass('wp-tab-active');
|
297 |
this.$el.find('.tabs-panel').hide().end().find($tab.data('ref')).show().find(':text').focus();
|
298 |
},
|
|
|
299 |
afterConnectionAppended: function(response) {
|
300 |
if ('one' === this.options.cardinality) {
|
301 |
this.$('.p2p-create-connections').hide();
|
302 |
}
|
303 |
},
|
|
|
304 |
afterConnectionDeleted: function(response) {
|
305 |
if ('one' === this.options.cardinality) {
|
306 |
this.$('.p2p-create-connections').show();
|
@@ -315,9 +360,9 @@
|
|
315 |
};
|
316 |
|
317 |
jQuery(function() {
|
318 |
-
|
319 |
if (!jQuery('<input placeholder="1" />')[0].placeholder) {
|
320 |
-
setVal
|
321 |
var $this;
|
322 |
$this = jQuery(this);
|
323 |
if (!$this.val()) {
|
@@ -325,7 +370,8 @@
|
|
325 |
$this.addClass('p2p-placeholder');
|
326 |
}
|
327 |
};
|
328 |
-
|
|
|
329 |
var $this;
|
330 |
$this = jQuery(this);
|
331 |
if ($this.hasClass('p2p-placeholder')) {
|
@@ -340,22 +386,27 @@
|
|
340 |
|
341 |
jQuery('.p2p-box').each(function() {
|
342 |
var $metabox, $spinner, candidates, candidatesView, connections, connectionsView, createPostView, ctype, metaboxView;
|
|
|
343 |
$metabox = jQuery(this);
|
|
|
344 |
$spinner = jQuery('<img>', {
|
345 |
'src': P2PAdminL10n.spinner,
|
346 |
'class': 'p2p-spinner'
|
347 |
});
|
|
|
348 |
candidates = new Candidates({
|
349 |
's': '',
|
350 |
'paged': 1
|
351 |
});
|
352 |
candidates.total_pages = $metabox.find('.p2p-total').data('num') || 1;
|
|
|
353 |
ctype = {
|
354 |
p2p_type: $metabox.data('p2p_type'),
|
355 |
direction: $metabox.data('direction'),
|
356 |
from: jQuery('#post_ID').val()
|
357 |
};
|
358 |
|
|
|
359 |
function ajax_request(options, callback) {
|
360 |
var params = _.extend({}, options, candidates.attributes, ctype, {
|
361 |
action: 'p2p_box',
|
@@ -385,6 +436,7 @@
|
|
385 |
|
386 |
connections = new Connections();
|
387 |
connections.ajax_request = ajax_request;
|
|
|
388 |
connectionsView = new ConnectionsView({
|
389 |
el: $metabox.find('.p2p-connections'),
|
390 |
collection: connections,
|
20 |
return jQuery('#p2p-template-' + name).html();
|
21 |
};
|
22 |
|
23 |
+
// Class for representing a single connection candidate
|
24 |
Candidate = Backbone.Model.extend({});
|
25 |
|
26 |
+
// Class for representing a single connection
|
27 |
Connection = Backbone.Model.extend({});
|
28 |
|
29 |
+
// Class for holding search parameters; not really a model
|
30 |
Candidates = Backbone.Model.extend({
|
31 |
+
|
32 |
+
// (Re)perform a search with the current parameters
|
33 |
sync: function() {
|
34 |
var params, _this = this;
|
35 |
params = {
|
41 |
_this.trigger('sync', response);
|
42 |
});
|
43 |
},
|
44 |
+
|
45 |
+
// Validation function, called by Backbone when parameters are changed
|
46 |
validate: function(attrs) {
|
47 |
var _ref = attrs.paged;
|
48 |
if (0 < _ref && _ref <= this.total_pages) {
|
52 |
}
|
53 |
});
|
54 |
|
55 |
+
// Class for holding a list of connections
|
56 |
Connections = Backbone.Collection.extend({
|
57 |
model: Connection,
|
58 |
+
|
59 |
+
// Create both a candidate item and a connection
|
60 |
createItemAndConnect: function(title) {
|
61 |
var data, _this = this;
|
62 |
data = {
|
67 |
_this.trigger('create', response);
|
68 |
});
|
69 |
},
|
70 |
+
|
71 |
+
// Create a connection from a candidate
|
72 |
create: function(candidate) {
|
73 |
var data, _this = this;
|
74 |
data = {
|
79 |
_this.trigger('create', response);
|
80 |
});
|
81 |
},
|
82 |
+
|
83 |
+
// Delete a connection
|
84 |
"delete": function(connection) {
|
85 |
var data, _this = this;
|
86 |
data = {
|
91 |
_this.trigger('delete', response, connection);
|
92 |
});
|
93 |
},
|
94 |
+
|
95 |
+
// Delete all connections
|
96 |
clear: function() {
|
97 |
var data, _this = this;
|
98 |
data = {
|
104 |
}
|
105 |
});
|
106 |
|
107 |
+
// View responsible for the connection list
|
108 |
ConnectionsView = Backbone.View.extend({
|
109 |
+
|
110 |
events: {
|
111 |
'click th.p2p-col-delete .p2p-icon': 'clear',
|
112 |
'click td.p2p-col-delete .p2p-icon': 'delete'
|
113 |
},
|
114 |
+
|
115 |
initialize: function(options) {
|
116 |
this.options = options;
|
117 |
this.maybe_make_sortable();
|
118 |
this.collection.on('create', this.afterCreate, this);
|
119 |
this.collection.on('clear', this.afterClear, this);
|
120 |
},
|
121 |
+
|
122 |
maybe_make_sortable: function() {
|
123 |
if (this.$('th.p2p-col-order').length) {
|
124 |
this.$('tbody').sortable({
|
134 |
});
|
135 |
}
|
136 |
},
|
137 |
+
|
138 |
clear: function(ev) {
|
139 |
var $td;
|
140 |
ev.preventDefault();
|
145 |
row_wait($td);
|
146 |
this.collection.clear();
|
147 |
},
|
148 |
+
|
149 |
afterClear: function() {
|
150 |
this.$el.hide().find('tbody').html('');
|
151 |
},
|
152 |
+
|
153 |
"delete": function(ev) {
|
154 |
var $td, req;
|
155 |
ev.preventDefault();
|
162 |
remove_row($td);
|
163 |
});
|
164 |
},
|
165 |
+
|
166 |
afterCreate: function(response) {
|
167 |
this.$el.show().find('tbody').append(response.row);
|
168 |
this.collection.trigger('append', response);
|
169 |
}
|
170 |
});
|
171 |
|
172 |
+
// View responsible for the candidate list
|
173 |
CandidatesView = Backbone.View.extend({
|
174 |
+
|
175 |
template: Mustache.compile(get_mustache_template('tab-list')),
|
176 |
+
|
177 |
events: {
|
178 |
'keypress :text': 'handleReturn',
|
179 |
'keyup :text': 'handleSearch',
|
180 |
'click .p2p-prev, .p2p-next': 'changePage',
|
181 |
'click td.p2p-col-create div': 'promote'
|
182 |
},
|
183 |
+
|
184 |
initialize: function(options) {
|
185 |
this.options = options;
|
186 |
this.spinner = options.spinner;
|
190 |
this.collection.on('error', this.afterInvalid, this);
|
191 |
this.collection.on('invalid', this.afterInvalid, this);
|
192 |
},
|
193 |
+
|
194 |
promote: function(ev) {
|
195 |
var $td, req, _this = this;
|
196 |
ev.preventDefault();
|
208 |
}
|
209 |
});
|
210 |
},
|
211 |
+
|
212 |
handleReturn: function(ev) {
|
213 |
if (ev.keyCode === ENTER_KEY) {
|
214 |
ev.preventDefault();
|
215 |
}
|
216 |
},
|
217 |
+
|
218 |
handleSearch: function(ev) {
|
219 |
var $searchInput, delayed,
|
220 |
_this = this;
|
235 |
});
|
236 |
}, 400);
|
237 |
},
|
238 |
+
|
239 |
changePage: function(ev) {
|
240 |
var $navButton, new_page;
|
241 |
$navButton = jQuery(ev.currentTarget);
|
248 |
this.spinner.appendTo(this.$('.p2p-navigation'));
|
249 |
this.collection.save('paged', new_page);
|
250 |
},
|
251 |
+
|
252 |
afterCandidatesRefreshed: function(response) {
|
253 |
this.spinner.remove();
|
254 |
this.$('button, .p2p-results, .p2p-navigation, .p2p-notice').remove();
|
262 |
}
|
263 |
});
|
264 |
|
265 |
+
// View responsible for the post creation UI
|
266 |
CreatePostView = Backbone.View.extend({
|
267 |
+
|
268 |
events: {
|
269 |
'click button': 'createItem',
|
270 |
'keypress :text': 'handleReturn'
|
271 |
},
|
272 |
+
|
273 |
initialize: function(options) {
|
274 |
this.options = options;
|
275 |
this.createButton = this.$('button');
|
276 |
this.createInput = this.$(':text');
|
277 |
},
|
278 |
+
|
279 |
handleReturn: function(ev) {
|
280 |
if (ev.keyCode === ENTER_KEY) {
|
281 |
this.createButton.click();
|
282 |
ev.preventDefault();
|
283 |
}
|
284 |
},
|
285 |
+
|
286 |
createItem: function(ev) {
|
287 |
var req, title, _this = this;
|
288 |
ev.preventDefault();
|
303 |
}
|
304 |
});
|
305 |
|
306 |
+
// View responsible for the entire metabox
|
307 |
MetaboxView = Backbone.View.extend({
|
308 |
+
|
309 |
events: {
|
310 |
'click .p2p-toggle-tabs': 'toggleTabs',
|
311 |
'click .wp-tab-bar li': 'setActiveTab'
|
312 |
},
|
313 |
+
|
314 |
initialize: function(options) {
|
315 |
this.options = options;
|
316 |
this.spinner = options.spinner;
|
319 |
options.connections.on('clear', this.afterConnectionDeleted, this);
|
320 |
options.connections.on('delete', this.afterConnectionDeleted, this);
|
321 |
},
|
322 |
+
|
323 |
toggleTabs: function(ev) {
|
324 |
var $tabs;
|
325 |
ev.preventDefault();
|
330 |
this.initializedCandidates = true;
|
331 |
}
|
332 |
},
|
333 |
+
|
334 |
setActiveTab: function(ev) {
|
335 |
var $tab;
|
336 |
ev.preventDefault();
|
339 |
$tab.addClass('wp-tab-active');
|
340 |
this.$el.find('.tabs-panel').hide().end().find($tab.data('ref')).show().find(':text').focus();
|
341 |
},
|
342 |
+
|
343 |
afterConnectionAppended: function(response) {
|
344 |
if ('one' === this.options.cardinality) {
|
345 |
this.$('.p2p-create-connections').hide();
|
346 |
}
|
347 |
},
|
348 |
+
|
349 |
afterConnectionDeleted: function(response) {
|
350 |
if ('one' === this.options.cardinality) {
|
351 |
this.$('.p2p-create-connections').show();
|
360 |
};
|
361 |
|
362 |
jQuery(function() {
|
363 |
+
// Polyfill for browsers that don't support the placeholder attribute
|
364 |
if (!jQuery('<input placeholder="1" />')[0].placeholder) {
|
365 |
+
function setVal() {
|
366 |
var $this;
|
367 |
$this = jQuery(this);
|
368 |
if (!$this.val()) {
|
370 |
$this.addClass('p2p-placeholder');
|
371 |
}
|
372 |
};
|
373 |
+
|
374 |
+
function clearVal() {
|
375 |
var $this;
|
376 |
$this = jQuery(this);
|
377 |
if ($this.hasClass('p2p-placeholder')) {
|
386 |
|
387 |
jQuery('.p2p-box').each(function() {
|
388 |
var $metabox, $spinner, candidates, candidatesView, connections, connectionsView, createPostView, ctype, metaboxView;
|
389 |
+
|
390 |
$metabox = jQuery(this);
|
391 |
+
|
392 |
$spinner = jQuery('<img>', {
|
393 |
'src': P2PAdminL10n.spinner,
|
394 |
'class': 'p2p-spinner'
|
395 |
});
|
396 |
+
|
397 |
candidates = new Candidates({
|
398 |
's': '',
|
399 |
'paged': 1
|
400 |
});
|
401 |
candidates.total_pages = $metabox.find('.p2p-total').data('num') || 1;
|
402 |
+
|
403 |
ctype = {
|
404 |
p2p_type: $metabox.data('p2p_type'),
|
405 |
direction: $metabox.data('direction'),
|
406 |
from: jQuery('#post_ID').val()
|
407 |
};
|
408 |
|
409 |
+
// All ajax requests should be done through this function
|
410 |
function ajax_request(options, callback) {
|
411 |
var params = _.extend({}, options, candidates.attributes, ctype, {
|
412 |
action: 'p2p_box',
|
436 |
|
437 |
connections = new Connections();
|
438 |
connections.ajax_request = ajax_request;
|
439 |
+
|
440 |
connectionsView = new ConnectionsView({
|
441 |
el: $metabox.find('.p2p-connections'),
|
442 |
collection: connections,
|
admin/column-post.php
CHANGED
@@ -24,7 +24,9 @@ class P2P_Column_Post extends P2P_Column {
|
|
24 |
'post_type' => get_current_screen()->post_type
|
25 |
);
|
26 |
|
27 |
-
|
|
|
|
|
28 |
}
|
29 |
|
30 |
function display_column( $column, $item_id ) {
|
24 |
'post_type' => get_current_screen()->post_type
|
25 |
);
|
26 |
|
27 |
+
$admin_link = apply_filters( "p2p_post_admin_column_link", add_query_arg( $args, admin_url( 'edit.php' ) ), $item );
|
28 |
+
|
29 |
+
return $admin_link;
|
30 |
}
|
31 |
|
32 |
function display_column( $column, $item_id ) {
|
admin/column-user.php
CHANGED
@@ -36,7 +36,9 @@ class P2P_Column_User extends P2P_Column {
|
|
36 |
'connected_items' => $item->get_id(),
|
37 |
);
|
38 |
|
39 |
-
|
|
|
|
|
40 |
}
|
41 |
|
42 |
function display_column( $content, $column, $item_id ) {
|
36 |
'connected_items' => $item->get_id(),
|
37 |
);
|
38 |
|
39 |
+
$admin_link = apply_filters( "p2p_user_admin_column_link", add_query_arg( $args, admin_url( 'users.php' ) ), $item );
|
40 |
+
|
41 |
+
return $admin_link;
|
42 |
}
|
43 |
|
44 |
function display_column( $content, $column, $item_id ) {
|
admin/mustache.php
CHANGED
@@ -5,25 +5,20 @@
|
|
5 |
*/
|
6 |
abstract class P2P_Mustache {
|
7 |
|
8 |
-
private static $loader;
|
9 |
private static $mustache;
|
10 |
|
11 |
public static function init() {
|
12 |
-
|
13 |
-
|
14 |
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
self::$mustache = new Mustache( null, null, self::$loader );
|
21 |
}
|
22 |
|
23 |
public static function render( $template, $data ) {
|
24 |
-
return self::$mustache->render(
|
25 |
}
|
26 |
}
|
27 |
|
28 |
-
P2P_Mustache::init();
|
29 |
-
|
5 |
*/
|
6 |
abstract class P2P_Mustache {
|
7 |
|
|
|
8 |
private static $mustache;
|
9 |
|
10 |
public static function init() {
|
11 |
+
$loader = new Mustache_Loader_FilesystemLoader(
|
12 |
+
dirname(__FILE__) . '/templates', array( 'extension' => 'html' ) );
|
13 |
|
14 |
+
self::$mustache = new Mustache_Engine( array(
|
15 |
+
'loader' => $loader,
|
16 |
+
'partials_loader' => $loader
|
17 |
+
) );
|
|
|
|
|
18 |
}
|
19 |
|
20 |
public static function render( $template, $data ) {
|
21 |
+
return self::$mustache->render( $template, $data );
|
22 |
}
|
23 |
}
|
24 |
|
|
|
|
composer.json
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "scribu/posts-to-posts",
|
3 |
+
"type": "wordpress-plugin",
|
4 |
+
"homepage": "http://wordpress.org/plugins/posts-to-posts",
|
5 |
+
"license": "GPL-2.0+",
|
6 |
+
"minimum-stability": "dev",
|
7 |
+
"require": {
|
8 |
+
"composer/installers": "~1.0",
|
9 |
+
"scribu/lib-posts-to-posts": "dev-master",
|
10 |
+
"mustache/mustache": "~2.6"
|
11 |
+
},
|
12 |
+
"repositories": [
|
13 |
+
{
|
14 |
+
"type": "vcs",
|
15 |
+
"url": "https://github.com/scribu/wp-lib-posts-to-posts"
|
16 |
+
}
|
17 |
+
]
|
18 |
+
}
|
core/init.php
DELETED
@@ -1,18 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
require_once dirname( __FILE__ ) . '/util.php';
|
4 |
-
require_once dirname( __FILE__ ) . '/api.php';
|
5 |
-
require_once dirname( __FILE__ ) . '/autoload.php';
|
6 |
-
|
7 |
-
P2P_Autoload::register( 'P2P_', dirname( __FILE__ ) );
|
8 |
-
|
9 |
-
P2P_Storage::init();
|
10 |
-
|
11 |
-
P2P_Query_Post::init();
|
12 |
-
P2P_Query_User::init();
|
13 |
-
|
14 |
-
P2P_URL_Query::init();
|
15 |
-
|
16 |
-
P2P_Widget::init();
|
17 |
-
P2P_Shortcodes::init();
|
18 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lang/posts-to-posts-da_DK.mo
ADDED
Binary file
|
lang/posts-to-posts-da_DK.po
ADDED
@@ -0,0 +1,156 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Copyright (C) 2013
|
2 |
+
# This file is distributed under the same license as the package.
|
3 |
+
msgid ""
|
4 |
+
msgstr ""
|
5 |
+
"Project-Id-Version: Posts 2 Posts\n"
|
6 |
+
"Report-Msgid-Bugs-To: http://wordpress.org/tag/p2p\n"
|
7 |
+
"POT-Creation-Date: 2013-02-17 08:06:11+00:00\n"
|
8 |
+
"MIME-Version: 1.0\n"
|
9 |
+
"Content-Type: text/plain; charset=UTF-8\n"
|
10 |
+
"Content-Transfer-Encoding: 8bit\n"
|
11 |
+
"PO-Revision-Date: 2014-10-07 15:48+0100\n"
|
12 |
+
"Last-Translator: Phh <phh@peytz.dk>\n"
|
13 |
+
"Language-Team: \n"
|
14 |
+
"X-Generator: Poedit 1.6.9\n"
|
15 |
+
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
16 |
+
"Language: da\n"
|
17 |
+
|
18 |
+
#: admin/box.php:45
|
19 |
+
msgid "Are you sure you want to delete all connections?"
|
20 |
+
msgstr "Er du sikker på du vil slette alle forbindelser?"
|
21 |
+
|
22 |
+
#: admin/box.php:136
|
23 |
+
msgid "Search"
|
24 |
+
msgstr "Søg"
|
25 |
+
|
26 |
+
#: admin/box.php:213
|
27 |
+
msgid "previous"
|
28 |
+
msgstr "forrige"
|
29 |
+
|
30 |
+
#: admin/box.php:214
|
31 |
+
msgid "next"
|
32 |
+
msgstr "næste"
|
33 |
+
|
34 |
+
#: admin/box.php:215
|
35 |
+
msgid "of"
|
36 |
+
msgstr "af"
|
37 |
+
|
38 |
+
#: admin/dropdown-user.php:32
|
39 |
+
msgid "Filter"
|
40 |
+
msgstr "Filter"
|
41 |
+
|
42 |
+
#: admin/factory.php:88
|
43 |
+
msgid " (from)"
|
44 |
+
msgstr " (fra)"
|
45 |
+
|
46 |
+
#: admin/factory.php:89
|
47 |
+
msgid " (to)"
|
48 |
+
msgstr " (til)"
|
49 |
+
|
50 |
+
#: admin/field-delete.php:7
|
51 |
+
msgid "Delete all connections"
|
52 |
+
msgstr "Slet alle forbindelser"
|
53 |
+
|
54 |
+
#: admin/field-delete.php:16
|
55 |
+
msgid "Delete connection"
|
56 |
+
msgstr "Slet forbindelse"
|
57 |
+
|
58 |
+
#: admin/tools-page.php:7
|
59 |
+
msgid "Connection Types"
|
60 |
+
msgstr "Forbindelsestyper"
|
61 |
+
|
62 |
+
#: admin/tools-page.php:41
|
63 |
+
msgid "<em>%s</em> is not a registered connection type."
|
64 |
+
msgstr "<em>%s</em> er ikke en registreret forbindelsestype."
|
65 |
+
|
66 |
+
#: admin/tools-page.php:50
|
67 |
+
msgid "Converted %1$s connections from <em>%2$s</em> to <em>%3$s</em>."
|
68 |
+
msgstr "Konverterede %1$s forbindelser from <em>%2$s</em> til <em>%3$s</em>."
|
69 |
+
|
70 |
+
#: admin/tools-page.php:64
|
71 |
+
msgid "Name"
|
72 |
+
msgstr "Navn"
|
73 |
+
|
74 |
+
#: admin/tools-page.php:65
|
75 |
+
msgid "Information"
|
76 |
+
msgstr "Information"
|
77 |
+
|
78 |
+
#: admin/tools-page.php:66
|
79 |
+
msgid "Connections"
|
80 |
+
msgstr "Forbindelser"
|
81 |
+
|
82 |
+
#: admin/tools-page.php:74
|
83 |
+
msgid "No connection types registered."
|
84 |
+
msgstr "Ingen forbindelsestyper registreret."
|
85 |
+
|
86 |
+
#: admin/tools-page.php:76
|
87 |
+
msgid "To register a connection type, see <a href=\"%s\">the wiki</a>."
|
88 |
+
msgstr "For at registrere en forbindelsestype, se <a href=\"%s\">wiki'en</a>."
|
89 |
+
|
90 |
+
#: admin/tools-page.php:93
|
91 |
+
msgid "Convert to registered connection type:"
|
92 |
+
msgstr "Konverter til registreret forbindelsestype:"
|
93 |
+
|
94 |
+
#: admin/tools-page.php:129
|
95 |
+
msgid "Go"
|
96 |
+
msgstr "Start"
|
97 |
+
|
98 |
+
#: core/connection-type.php:102
|
99 |
+
msgid "Create connections"
|
100 |
+
msgstr "Opret forbindelser"
|
101 |
+
|
102 |
+
#: core/connection-type.php:120
|
103 |
+
msgid "Connected %s"
|
104 |
+
msgstr "Forbandt %s"
|
105 |
+
|
106 |
+
#: core/side-user.php:16
|
107 |
+
msgid "Users"
|
108 |
+
msgstr "Brugere"
|
109 |
+
|
110 |
+
#: core/side-user.php:25
|
111 |
+
msgid "User"
|
112 |
+
msgstr "Bruger"
|
113 |
+
|
114 |
+
#: core/side-user.php:26
|
115 |
+
msgid "Search Users"
|
116 |
+
msgstr "Søg Brugere"
|
117 |
+
|
118 |
+
#: core/side-user.php:27
|
119 |
+
msgid "No users found."
|
120 |
+
msgstr "Ingen brugere fundet."
|
121 |
+
|
122 |
+
#: core/widget.php:16
|
123 |
+
msgid "Posts 2 Posts"
|
124 |
+
msgstr "Posts 2 Posts"
|
125 |
+
|
126 |
+
#: core/widget.php:17
|
127 |
+
msgid "A list of posts connected to the current post"
|
128 |
+
msgstr "En liste af indlæg forbundet med det nuværende indlæg"
|
129 |
+
|
130 |
+
#: core/widget.php:34
|
131 |
+
msgid "Title:"
|
132 |
+
msgstr "Titel:"
|
133 |
+
|
134 |
+
#: core/widget.php:41
|
135 |
+
msgid "Connection type:"
|
136 |
+
msgstr "Forbindelsestype:"
|
137 |
+
|
138 |
+
#: core/widget.php:46
|
139 |
+
msgid "Connection listing:"
|
140 |
+
msgstr "Forbindelsesliste:"
|
141 |
+
|
142 |
+
#: core/widget.php:52
|
143 |
+
msgid "connected"
|
144 |
+
msgstr "forbundet"
|
145 |
+
|
146 |
+
#: core/widget.php:53
|
147 |
+
msgid "related"
|
148 |
+
msgstr "relateret"
|
149 |
+
|
150 |
+
#: scb/AdminPage.php:227
|
151 |
+
msgid "Settings <strong>saved</strong>."
|
152 |
+
msgstr "Indstillinger <strong>gemt</strong>."
|
153 |
+
|
154 |
+
#: scb/AdminPage.php:466
|
155 |
+
msgid "Settings"
|
156 |
+
msgstr "Indstillinger"
|
lang/posts-to-posts-sv_SE.mo
CHANGED
Binary file
|
lang/posts-to-posts-sv_SE.po
CHANGED
@@ -2,89 +2,164 @@
|
|
2 |
# This file is distributed under the same license as the package.
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
-
"Project-Id-Version: Posts 2 Posts\n"
|
6 |
"Report-Msgid-Bugs-To: http://wordpress.org/tag/p2p\n"
|
7 |
-
"POT-Creation-Date:
|
|
|
|
|
|
|
|
|
8 |
"MIME-Version: 1.0\n"
|
9 |
-
"Content-Type: text/plain; charset=
|
10 |
"Content-Transfer-Encoding: 8bit\n"
|
11 |
-
"
|
12 |
-
"
|
13 |
-
"Language-Team: \n"
|
14 |
-
"X-Poedit-Language: Swedish\n"
|
15 |
-
"X-Poedit-Country: SWEDEN\n"
|
16 |
-
"X-Poedit-SourceCharset: utf-8\n"
|
17 |
-
|
18 |
-
#: scb/AdminPage.php:163
|
19 |
-
msgid "Settings <strong>saved</strong>."
|
20 |
-
msgstr "Inställningar <strong>sparade</strong>."
|
21 |
|
22 |
-
#:
|
23 |
-
|
24 |
-
|
25 |
-
msgstr "Spara ändringar"
|
26 |
|
27 |
-
#:
|
28 |
-
msgid "
|
29 |
-
msgstr "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
|
31 |
-
#: admin/
|
32 |
-
msgid "
|
33 |
-
msgstr "
|
34 |
|
35 |
-
#: admin/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
msgid "Delete all connections"
|
37 |
msgstr "Radera alla kopplingar"
|
38 |
|
39 |
-
#: admin/
|
40 |
msgid "Delete connection"
|
41 |
msgstr "Radera koppling"
|
42 |
|
43 |
-
#: admin/
|
44 |
-
msgid "
|
45 |
-
msgstr "
|
46 |
|
47 |
-
#: admin/
|
48 |
-
msgid "
|
49 |
-
msgstr "
|
50 |
|
51 |
-
#: admin/
|
52 |
-
msgid "
|
53 |
-
msgstr "
|
54 |
|
55 |
-
#: admin/
|
56 |
-
msgid "
|
57 |
-
msgstr "
|
58 |
|
59 |
-
#: admin/
|
60 |
-
msgid "
|
61 |
-
msgstr "
|
62 |
|
63 |
-
#: admin/
|
64 |
-
msgid "
|
65 |
-
msgstr "
|
66 |
|
67 |
-
#: admin/
|
68 |
-
msgid "
|
69 |
-
msgstr "
|
70 |
|
71 |
-
#: admin/
|
72 |
-
msgid "
|
73 |
-
msgstr "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
|
75 |
-
#: core/widget.php:
|
76 |
msgid "Posts 2 Posts"
|
77 |
-
msgstr ""
|
78 |
|
79 |
-
#: core/widget.php:
|
80 |
msgid "A list of posts connected to the current post"
|
81 |
msgstr "En lista över inlägg kopplade till aktuellt inlägg"
|
82 |
|
83 |
-
#: core/widget.php:
|
|
|
|
|
|
|
|
|
84 |
msgid "Connection type:"
|
85 |
msgstr "Kopplingstyp: "
|
86 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
#: core/widget.php:53
|
88 |
-
msgid "
|
89 |
-
msgstr "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
90 |
|
|
|
|
2 |
# This file is distributed under the same license as the package.
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
+
"Project-Id-Version: Posts 2 Posts sv_SE\n"
|
6 |
"Report-Msgid-Bugs-To: http://wordpress.org/tag/p2p\n"
|
7 |
+
"POT-Creation-Date: 2013-02-17 08:06:11+00:00\n"
|
8 |
+
"PO-Revision-Date: 2014-04-10 12:33+0100\n"
|
9 |
+
"Last-Translator: Mattias Tengblad <mst@eyesx.com>\n"
|
10 |
+
"Language-Team: WordPress Sverige <info@wpsv.se>\n"
|
11 |
+
"Language: sv_SE\n"
|
12 |
"MIME-Version: 1.0\n"
|
13 |
+
"Content-Type: text/plain; charset=UTF-8\n"
|
14 |
"Content-Transfer-Encoding: 8bit\n"
|
15 |
+
"X-Poedit-SourceCharset: UTF-8\n"
|
16 |
+
"X-Generator: Poedit 1.6.4\n"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
|
18 |
+
#: admin/box.php:45
|
19 |
+
msgid "Are you sure you want to delete all connections?"
|
20 |
+
msgstr "Är du säker på att du vill radera alla kopplingar?"
|
|
|
21 |
|
22 |
+
#: admin/box.php:136
|
23 |
+
msgid "Search"
|
24 |
+
msgstr "Sök"
|
25 |
+
|
26 |
+
#: admin/box.php:213
|
27 |
+
msgid "previous"
|
28 |
+
msgstr "föregående"
|
29 |
+
|
30 |
+
#: admin/box.php:214
|
31 |
+
msgid "next"
|
32 |
+
msgstr "nästa"
|
33 |
+
|
34 |
+
#: admin/box.php:215
|
35 |
+
msgid "of"
|
36 |
+
msgstr "av"
|
37 |
|
38 |
+
#: admin/dropdown-user.php:32
|
39 |
+
msgid "Filter"
|
40 |
+
msgstr "Filtrera"
|
41 |
|
42 |
+
#: admin/factory.php:88
|
43 |
+
msgid " (from)"
|
44 |
+
msgstr "(från)"
|
45 |
+
|
46 |
+
#: admin/factory.php:89
|
47 |
+
msgid " (to)"
|
48 |
+
msgstr " (till)"
|
49 |
+
|
50 |
+
#: admin/field-delete.php:7
|
51 |
msgid "Delete all connections"
|
52 |
msgstr "Radera alla kopplingar"
|
53 |
|
54 |
+
#: admin/field-delete.php:16
|
55 |
msgid "Delete connection"
|
56 |
msgstr "Radera koppling"
|
57 |
|
58 |
+
#: admin/tools-page.php:7
|
59 |
+
msgid "Connection Types"
|
60 |
+
msgstr "Kopplingstyper"
|
61 |
|
62 |
+
#: admin/tools-page.php:41
|
63 |
+
msgid "<em>%s</em> is not a registered connection type."
|
64 |
+
msgstr "<em>%s</em> är inte en registrerad kopplingstyp."
|
65 |
|
66 |
+
#: admin/tools-page.php:50
|
67 |
+
msgid "Converted %1$s connections from <em>%2$s</em> to <em>%3$s</em>."
|
68 |
+
msgstr "Konverterade %1$s kopplingar från <em>%2$s</em> till <em>%3$s</em>."
|
69 |
|
70 |
+
#: admin/tools-page.php:64
|
71 |
+
msgid "Name"
|
72 |
+
msgstr "Namn"
|
73 |
|
74 |
+
#: admin/tools-page.php:65
|
75 |
+
msgid "Information"
|
76 |
+
msgstr "Information"
|
77 |
|
78 |
+
#: admin/tools-page.php:66
|
79 |
+
msgid "Connections"
|
80 |
+
msgstr "Kopplingar"
|
81 |
|
82 |
+
#: admin/tools-page.php:74
|
83 |
+
msgid "No connection types registered."
|
84 |
+
msgstr "Inga kopplingstyper registrerade."
|
85 |
|
86 |
+
#: admin/tools-page.php:76
|
87 |
+
msgid "To register a connection type, see <a href=\"%s\">the wiki</a>."
|
88 |
+
msgstr "För att registrera en kopplingstyp, se <a href=\"%s\">wikin</a>."
|
89 |
+
|
90 |
+
#: admin/tools-page.php:93
|
91 |
+
msgid "Convert to registered connection type:"
|
92 |
+
msgstr "Konvertera till registrerad kopplingstyp:"
|
93 |
+
|
94 |
+
#: admin/tools-page.php:129
|
95 |
+
msgid "Go"
|
96 |
+
msgstr "Ok"
|
97 |
+
|
98 |
+
#: core/connection-type.php:102
|
99 |
+
msgid "Create connections"
|
100 |
+
msgstr "Skapa kopplingar"
|
101 |
+
|
102 |
+
#: core/connection-type.php:120
|
103 |
+
msgid "Connected %s"
|
104 |
+
msgstr "Kopplad till %s"
|
105 |
+
|
106 |
+
#: core/side-user.php:16
|
107 |
+
msgid "Users"
|
108 |
+
msgstr "Användare"
|
109 |
+
|
110 |
+
#: core/side-user.php:25
|
111 |
+
msgid "User"
|
112 |
+
msgstr "Användare"
|
113 |
+
|
114 |
+
#: core/side-user.php:26
|
115 |
+
msgid "Search Users"
|
116 |
+
msgstr "Sök efter användare"
|
117 |
+
|
118 |
+
#: core/side-user.php:27
|
119 |
+
msgid "No users found."
|
120 |
+
msgstr "Inga användare funna."
|
121 |
|
122 |
+
#: core/widget.php:16
|
123 |
msgid "Posts 2 Posts"
|
124 |
+
msgstr "Posts 2 Posts"
|
125 |
|
126 |
+
#: core/widget.php:17
|
127 |
msgid "A list of posts connected to the current post"
|
128 |
msgstr "En lista över inlägg kopplade till aktuellt inlägg"
|
129 |
|
130 |
+
#: core/widget.php:34
|
131 |
+
msgid "Title:"
|
132 |
+
msgstr "Titel:"
|
133 |
+
|
134 |
+
#: core/widget.php:41
|
135 |
msgid "Connection type:"
|
136 |
msgstr "Kopplingstyp: "
|
137 |
|
138 |
+
#: core/widget.php:46
|
139 |
+
msgid "Connection listing:"
|
140 |
+
msgstr "Kopplingslistning:"
|
141 |
+
|
142 |
+
#: core/widget.php:52
|
143 |
+
msgid "connected"
|
144 |
+
msgstr "kopplad"
|
145 |
+
|
146 |
#: core/widget.php:53
|
147 |
+
msgid "related"
|
148 |
+
msgstr "relaterad"
|
149 |
+
|
150 |
+
#: scb/AdminPage.php:227
|
151 |
+
msgid "Settings <strong>saved</strong>."
|
152 |
+
msgstr "Inställningar <strong>sparade</strong>."
|
153 |
+
|
154 |
+
#: scb/AdminPage.php:466
|
155 |
+
msgid "Settings"
|
156 |
+
msgstr "Inställningar"
|
157 |
+
|
158 |
+
#~ msgid "Save Changes"
|
159 |
+
#~ msgstr "Spara ändringar"
|
160 |
+
|
161 |
+
#~ msgid "Create connection"
|
162 |
+
#~ msgstr "Skapa koppling"
|
163 |
|
164 |
+
#~ msgid "View All"
|
165 |
+
#~ msgstr "Visa alla"
|
lang/posts-to-posts-zh_CN.mo
ADDED
Binary file
|
lang/posts-to-posts-zh_CN.po
ADDED
@@ -0,0 +1,155 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
msgid ""
|
2 |
+
msgstr ""
|
3 |
+
"Project-Id-Version: Posts 2 Posts\n"
|
4 |
+
"Report-Msgid-Bugs-To: http://wordpress.org/tag/p2p\n"
|
5 |
+
"POT-Creation-Date: 2013-02-17 08:06:11+00:00\n"
|
6 |
+
"PO-Revision-Date: \n"
|
7 |
+
"Last-Translator: Daniel Koskinen <daniel.koskinen@gmail.com>\n"
|
8 |
+
"Language-Team: Amos Lee <4626395@gmail.com>\n"
|
9 |
+
"MIME-Version: 1.0\n"
|
10 |
+
"Content-Type: text/plain; charset=UTF-8\n"
|
11 |
+
"Content-Transfer-Encoding: 8bit\n"
|
12 |
+
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
13 |
+
"X-Poedit-SourceCharset: UTF-8\n"
|
14 |
+
"Language: zh_CN\n"
|
15 |
+
"X-Generator: Poedit 1.7.5\n"
|
16 |
+
|
17 |
+
#: admin/box.php:45
|
18 |
+
msgid "Are you sure you want to delete all connections?"
|
19 |
+
msgstr "确定要删除所有连接吗?"
|
20 |
+
|
21 |
+
#: admin/box.php:136
|
22 |
+
msgid "Search"
|
23 |
+
msgstr "搜索."
|
24 |
+
|
25 |
+
#: admin/box.php:213
|
26 |
+
msgid "previous"
|
27 |
+
msgstr "上一个"
|
28 |
+
|
29 |
+
#: admin/box.php:214
|
30 |
+
msgid "next"
|
31 |
+
msgstr "下一个"
|
32 |
+
|
33 |
+
#: admin/box.php:215
|
34 |
+
msgid "of"
|
35 |
+
msgstr "/"
|
36 |
+
|
37 |
+
#: admin/dropdown-user.php:32
|
38 |
+
msgid "Filter"
|
39 |
+
msgstr "筛选"
|
40 |
+
|
41 |
+
#: admin/factory.php:88
|
42 |
+
msgid " (from)"
|
43 |
+
msgstr "从"
|
44 |
+
|
45 |
+
#: admin/factory.php:89
|
46 |
+
msgid " (to)"
|
47 |
+
msgstr "到"
|
48 |
+
|
49 |
+
#: admin/field-delete.php:7
|
50 |
+
msgid "Delete all connections"
|
51 |
+
msgstr "删除所有连接"
|
52 |
+
|
53 |
+
#: admin/field-delete.php:16
|
54 |
+
msgid "Delete connection"
|
55 |
+
msgstr "删除连接"
|
56 |
+
|
57 |
+
#: admin/tools-page.php:7
|
58 |
+
msgid "Connection Types"
|
59 |
+
msgstr "连接类型"
|
60 |
+
|
61 |
+
#: admin/tools-page.php:41
|
62 |
+
msgid "<em>%s</em> is not a registered connection type."
|
63 |
+
msgstr "<em>%s</em> 不是一个注册的连接类型"
|
64 |
+
|
65 |
+
#: admin/tools-page.php:50
|
66 |
+
msgid "Converted %1$s connections from <em>%2$s</em> to <em>%3$s</em>."
|
67 |
+
msgstr "从 <em>%2$s</em> 到 <em>%3$s</em>转换了 %1$s 个连接"
|
68 |
+
|
69 |
+
#: admin/tools-page.php:64
|
70 |
+
msgid "Name"
|
71 |
+
msgstr "名称"
|
72 |
+
|
73 |
+
#: admin/tools-page.php:65
|
74 |
+
msgid "Information"
|
75 |
+
msgstr "信息"
|
76 |
+
|
77 |
+
#: admin/tools-page.php:66
|
78 |
+
msgid "Connections"
|
79 |
+
msgstr "连接"
|
80 |
+
|
81 |
+
#: admin/tools-page.php:74
|
82 |
+
msgid "No connection types registered."
|
83 |
+
msgstr "没有注册连接类型"
|
84 |
+
|
85 |
+
#: admin/tools-page.php:76
|
86 |
+
msgid "To register a connection type, see <a href=\"%s\">the wiki</a>."
|
87 |
+
msgstr "需要注册连接类型,查看 <a href=\"%s\">wiki</a>."
|
88 |
+
|
89 |
+
#: admin/tools-page.php:93
|
90 |
+
msgid "Convert to registered connection type:"
|
91 |
+
msgstr "转换到已注册的连接类型:"
|
92 |
+
|
93 |
+
#: admin/tools-page.php:129
|
94 |
+
msgid "Go"
|
95 |
+
msgstr "转到"
|
96 |
+
|
97 |
+
#: core/connection-type.php:102
|
98 |
+
msgid "Create connections"
|
99 |
+
msgstr "创建连接"
|
100 |
+
|
101 |
+
#: core/connection-type.php:120
|
102 |
+
msgid "Connected %s"
|
103 |
+
msgstr "%s 已连接"
|
104 |
+
|
105 |
+
#: core/side-user.php:16
|
106 |
+
msgid "Users"
|
107 |
+
msgstr "用户"
|
108 |
+
|
109 |
+
#: core/side-user.php:25
|
110 |
+
msgid "User"
|
111 |
+
msgstr "用户"
|
112 |
+
|
113 |
+
#: core/side-user.php:26
|
114 |
+
msgid "Search Users"
|
115 |
+
msgstr "搜索用户"
|
116 |
+
|
117 |
+
#: core/side-user.php:27
|
118 |
+
msgid "No users found."
|
119 |
+
msgstr "没有找到用户"
|
120 |
+
|
121 |
+
#: core/widget.php:16
|
122 |
+
msgid "Posts 2 Posts"
|
123 |
+
msgstr "Posts 2 Posts"
|
124 |
+
|
125 |
+
#: core/widget.php:17
|
126 |
+
msgid "A list of posts connected to the current post"
|
127 |
+
msgstr "连接到本文的文章"
|
128 |
+
|
129 |
+
#: core/widget.php:34
|
130 |
+
msgid "Title:"
|
131 |
+
msgstr "标题:"
|
132 |
+
|
133 |
+
#: core/widget.php:41
|
134 |
+
msgid "Connection type:"
|
135 |
+
msgstr "连接类型:"
|
136 |
+
|
137 |
+
#: core/widget.php:46
|
138 |
+
msgid "Connection listing:"
|
139 |
+
msgstr "连接列表:"
|
140 |
+
|
141 |
+
#: core/widget.php:52
|
142 |
+
msgid "connected"
|
143 |
+
msgstr "已连接"
|
144 |
+
|
145 |
+
#: core/widget.php:53
|
146 |
+
msgid "related"
|
147 |
+
msgstr "相关"
|
148 |
+
|
149 |
+
#: scb/AdminPage.php:227
|
150 |
+
msgid "Settings <strong>saved</strong>."
|
151 |
+
msgstr "设置 <strong>已保存</strong>."
|
152 |
+
|
153 |
+
#: scb/AdminPage.php:466
|
154 |
+
msgid "Settings"
|
155 |
+
msgstr "设置"
|
mustache/LICENSE
DELETED
@@ -1,22 +0,0 @@
|
|
1 |
-
Copyright (c) 2010 Justin Hileman
|
2 |
-
|
3 |
-
Permission is hereby granted, free of charge, to any person
|
4 |
-
obtaining a copy of this software and associated documentation
|
5 |
-
files (the "Software"), to deal in the Software without
|
6 |
-
restriction, including without limitation the rights to use,
|
7 |
-
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8 |
-
copies of the Software, and to permit persons to whom the
|
9 |
-
Software is furnished to do so, subject to the following
|
10 |
-
conditions:
|
11 |
-
|
12 |
-
The above copyright notice and this permission notice shall be
|
13 |
-
included in all copies or substantial portions of the Software.
|
14 |
-
|
15 |
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16 |
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17 |
-
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18 |
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19 |
-
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20 |
-
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21 |
-
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22 |
-
OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mustache/Mustache.php
DELETED
@@ -1,910 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* A Mustache implementation in PHP.
|
5 |
-
*
|
6 |
-
* {@link http://defunkt.github.com/mustache}
|
7 |
-
*
|
8 |
-
* Mustache is a framework-agnostic logic-less templating language. It enforces separation of view
|
9 |
-
* logic from template files. In fact, it is not even possible to embed logic in the template.
|
10 |
-
*
|
11 |
-
* This is very, very rad.
|
12 |
-
*
|
13 |
-
* @author Justin Hileman {@link http://justinhileman.com}
|
14 |
-
*/
|
15 |
-
class Mustache {
|
16 |
-
|
17 |
-
const VERSION = '1.0.0';
|
18 |
-
const SPEC_VERSION = '1.1.2';
|
19 |
-
|
20 |
-
/**
|
21 |
-
* Should this Mustache throw exceptions when it finds unexpected tags?
|
22 |
-
*
|
23 |
-
* @see self::_throwsException()
|
24 |
-
*/
|
25 |
-
protected $_throwsExceptions = array(
|
26 |
-
MustacheException::UNKNOWN_VARIABLE => false,
|
27 |
-
MustacheException::UNCLOSED_SECTION => true,
|
28 |
-
MustacheException::UNEXPECTED_CLOSE_SECTION => true,
|
29 |
-
MustacheException::UNKNOWN_PARTIAL => false,
|
30 |
-
MustacheException::UNKNOWN_PRAGMA => true,
|
31 |
-
);
|
32 |
-
|
33 |
-
// Override charset passed to htmlentities() and htmlspecialchars(). Defaults to UTF-8.
|
34 |
-
protected $_charset = 'UTF-8';
|
35 |
-
|
36 |
-
/**
|
37 |
-
* Pragmas are macro-like directives that, when invoked, change the behavior or
|
38 |
-
* syntax of Mustache.
|
39 |
-
*
|
40 |
-
* They should be considered extremely experimental. Most likely their implementation
|
41 |
-
* will change in the future.
|
42 |
-
*/
|
43 |
-
|
44 |
-
/**
|
45 |
-
* The {{%UNESCAPED}} pragma swaps the meaning of the {{normal}} and {{{unescaped}}}
|
46 |
-
* Mustache tags. That is, once this pragma is activated the {{normal}} tag will not be
|
47 |
-
* escaped while the {{{unescaped}}} tag will be escaped.
|
48 |
-
*
|
49 |
-
* Pragmas apply only to the current template. Partials, even those included after the
|
50 |
-
* {{%UNESCAPED}} call, will need their own pragma declaration.
|
51 |
-
*
|
52 |
-
* This may be useful in non-HTML Mustache situations.
|
53 |
-
*/
|
54 |
-
const PRAGMA_UNESCAPED = 'UNESCAPED';
|
55 |
-
|
56 |
-
/**
|
57 |
-
* Constants used for section and tag RegEx
|
58 |
-
*/
|
59 |
-
const SECTION_TYPES = '\^#\/';
|
60 |
-
const TAG_TYPES = '#\^\/=!<>\\{&';
|
61 |
-
|
62 |
-
protected $_otag = '{{';
|
63 |
-
protected $_ctag = '}}';
|
64 |
-
|
65 |
-
protected $_tagRegEx;
|
66 |
-
|
67 |
-
protected $_template = '';
|
68 |
-
protected $_context = array();
|
69 |
-
protected $_partials = array();
|
70 |
-
protected $_pragmas = array();
|
71 |
-
|
72 |
-
protected $_pragmasImplemented = array(
|
73 |
-
self::PRAGMA_UNESCAPED
|
74 |
-
);
|
75 |
-
|
76 |
-
protected $_localPragmas = array();
|
77 |
-
|
78 |
-
/**
|
79 |
-
* Mustache class constructor.
|
80 |
-
*
|
81 |
-
* This method accepts a $template string and a $view object. Optionally, pass an associative
|
82 |
-
* array of partials as well.
|
83 |
-
*
|
84 |
-
* Passing an $options array allows overriding certain Mustache options during instantiation:
|
85 |
-
*
|
86 |
-
* $options = array(
|
87 |
-
* // `charset` -- must be supported by `htmlspecialentities()`. defaults to 'UTF-8'
|
88 |
-
* 'charset' => 'ISO-8859-1',
|
89 |
-
*
|
90 |
-
* // opening and closing delimiters, as an array or a space-separated string
|
91 |
-
* 'delimiters' => '<% %>',
|
92 |
-
*
|
93 |
-
* // an array of pragmas to enable/disable
|
94 |
-
* 'pragmas' => array(
|
95 |
-
* Mustache::PRAGMA_UNESCAPED => true
|
96 |
-
* ),
|
97 |
-
*
|
98 |
-
* // an array of thrown exceptions to enable/disable
|
99 |
-
* 'throws_exceptions' => array(
|
100 |
-
* MustacheException::UNKNOWN_VARIABLE => false,
|
101 |
-
* MustacheException::UNCLOSED_SECTION => true,
|
102 |
-
* MustacheException::UNEXPECTED_CLOSE_SECTION => true,
|
103 |
-
* MustacheException::UNKNOWN_PARTIAL => false,
|
104 |
-
* MustacheException::UNKNOWN_PRAGMA => true,
|
105 |
-
* ),
|
106 |
-
* );
|
107 |
-
*
|
108 |
-
* @access public
|
109 |
-
* @param string $template (default: null)
|
110 |
-
* @param mixed $view (default: null)
|
111 |
-
* @param array $partials (default: null)
|
112 |
-
* @param array $options (default: array())
|
113 |
-
* @return void
|
114 |
-
*/
|
115 |
-
public function __construct($template = null, $view = null, $partials = null, array $options = null) {
|
116 |
-
if ($template !== null) $this->_template = $template;
|
117 |
-
if ($partials !== null) $this->_partials = $partials;
|
118 |
-
if ($view !== null) $this->_context = array($view);
|
119 |
-
if ($options !== null) $this->_setOptions($options);
|
120 |
-
}
|
121 |
-
|
122 |
-
/**
|
123 |
-
* Helper function for setting options from constructor args.
|
124 |
-
*
|
125 |
-
* @access protected
|
126 |
-
* @param array $options
|
127 |
-
* @return void
|
128 |
-
*/
|
129 |
-
protected function _setOptions(array $options) {
|
130 |
-
if (isset($options['charset'])) {
|
131 |
-
$this->_charset = $options['charset'];
|
132 |
-
}
|
133 |
-
|
134 |
-
if (isset($options['delimiters'])) {
|
135 |
-
$delims = $options['delimiters'];
|
136 |
-
if (!is_array($delims)) {
|
137 |
-
$delims = array_map('trim', explode(' ', $delims, 2));
|
138 |
-
}
|
139 |
-
$this->_otag = $delims[0];
|
140 |
-
$this->_ctag = $delims[1];
|
141 |
-
}
|
142 |
-
|
143 |
-
if (isset($options['pragmas'])) {
|
144 |
-
foreach ($options['pragmas'] as $pragma_name => $pragma_value) {
|
145 |
-
if (!in_array($pragma_name, $this->_pragmasImplemented, true)) {
|
146 |
-
throw new MustacheException('Unknown pragma: ' . $pragma_name, MustacheException::UNKNOWN_PRAGMA);
|
147 |
-
}
|
148 |
-
}
|
149 |
-
$this->_pragmas = $options['pragmas'];
|
150 |
-
}
|
151 |
-
|
152 |
-
if (isset($options['throws_exceptions'])) {
|
153 |
-
foreach ($options['throws_exceptions'] as $exception => $value) {
|
154 |
-
$this->_throwsExceptions[$exception] = $value;
|
155 |
-
}
|
156 |
-
}
|
157 |
-
}
|
158 |
-
|
159 |
-
/**
|
160 |
-
* Mustache class clone method.
|
161 |
-
*
|
162 |
-
* A cloned Mustache instance should have pragmas, delimeters and root context
|
163 |
-
* reset to default values.
|
164 |
-
*
|
165 |
-
* @access public
|
166 |
-
* @return void
|
167 |
-
*/
|
168 |
-
public function __clone() {
|
169 |
-
$this->_otag = '{{';
|
170 |
-
$this->_ctag = '}}';
|
171 |
-
$this->_localPragmas = array();
|
172 |
-
|
173 |
-
if ($keys = array_keys($this->_context)) {
|
174 |
-
$last = array_pop($keys);
|
175 |
-
if ($this->_context[$last] instanceof Mustache) {
|
176 |
-
$this->_context[$last] =& $this;
|
177 |
-
}
|
178 |
-
}
|
179 |
-
}
|
180 |
-
|
181 |
-
/**
|
182 |
-
* Render the given template and view object.
|
183 |
-
*
|
184 |
-
* Defaults to the template and view passed to the class constructor unless a new one is provided.
|
185 |
-
* Optionally, pass an associative array of partials as well.
|
186 |
-
*
|
187 |
-
* @access public
|
188 |
-
* @param string $template (default: null)
|
189 |
-
* @param mixed $view (default: null)
|
190 |
-
* @param array $partials (default: null)
|
191 |
-
* @return string Rendered Mustache template.
|
192 |
-
*/
|
193 |
-
public function render($template = null, $view = null, $partials = null) {
|
194 |
-
if ($template === null) $template = $this->_template;
|
195 |
-
if ($partials !== null) $this->_partials = $partials;
|
196 |
-
|
197 |
-
$otag_orig = $this->_otag;
|
198 |
-
$ctag_orig = $this->_ctag;
|
199 |
-
|
200 |
-
if ($view) {
|
201 |
-
$this->_context = array($view);
|
202 |
-
} else if (empty($this->_context)) {
|
203 |
-
$this->_context = array($this);
|
204 |
-
}
|
205 |
-
|
206 |
-
$template = $this->_renderPragmas($template);
|
207 |
-
$template = $this->_renderTemplate($template);
|
208 |
-
|
209 |
-
$this->_otag = $otag_orig;
|
210 |
-
$this->_ctag = $ctag_orig;
|
211 |
-
|
212 |
-
return $template;
|
213 |
-
}
|
214 |
-
|
215 |
-
/**
|
216 |
-
* Wrap the render() function for string conversion.
|
217 |
-
*
|
218 |
-
* @access public
|
219 |
-
* @return string
|
220 |
-
*/
|
221 |
-
public function __toString() {
|
222 |
-
// PHP doesn't like exceptions in __toString.
|
223 |
-
// catch any exceptions and convert them to strings.
|
224 |
-
try {
|
225 |
-
$result = $this->render();
|
226 |
-
return $result;
|
227 |
-
} catch (Exception $e) {
|
228 |
-
return "Error rendering mustache: " . $e->getMessage();
|
229 |
-
}
|
230 |
-
}
|
231 |
-
|
232 |
-
/**
|
233 |
-
* Internal render function, used for recursive calls.
|
234 |
-
*
|
235 |
-
* @access protected
|
236 |
-
* @param string $template
|
237 |
-
* @return string Rendered Mustache template.
|
238 |
-
*/
|
239 |
-
protected function _renderTemplate($template) {
|
240 |
-
if ($section = $this->_findSection($template)) {
|
241 |
-
list($before, $type, $tag_name, $content, $after) = $section;
|
242 |
-
|
243 |
-
$rendered_before = $this->_renderTags($before);
|
244 |
-
|
245 |
-
$rendered_content = '';
|
246 |
-
$val = $this->_getVariable($tag_name);
|
247 |
-
switch($type) {
|
248 |
-
// inverted section
|
249 |
-
case '^':
|
250 |
-
if (empty($val)) {
|
251 |
-
$rendered_content = $this->_renderTemplate($content);
|
252 |
-
}
|
253 |
-
break;
|
254 |
-
|
255 |
-
// regular section
|
256 |
-
case '#':
|
257 |
-
// higher order sections
|
258 |
-
if ($this->_varIsCallable($val)) {
|
259 |
-
$rendered_content = $this->_renderTemplate(call_user_func($val, $content));
|
260 |
-
} else if ($this->_varIsIterable($val)) {
|
261 |
-
foreach ($val as $local_context) {
|
262 |
-
$this->_pushContext($local_context);
|
263 |
-
$rendered_content .= $this->_renderTemplate($content);
|
264 |
-
$this->_popContext();
|
265 |
-
}
|
266 |
-
} else if ($val) {
|
267 |
-
if (is_array($val) || is_object($val)) {
|
268 |
-
$this->_pushContext($val);
|
269 |
-
$rendered_content = $this->_renderTemplate($content);
|
270 |
-
$this->_popContext();
|
271 |
-
} else {
|
272 |
-
$rendered_content = $this->_renderTemplate($content);
|
273 |
-
}
|
274 |
-
}
|
275 |
-
break;
|
276 |
-
}
|
277 |
-
|
278 |
-
return $rendered_before . $rendered_content . $this->_renderTemplate($after);
|
279 |
-
}
|
280 |
-
|
281 |
-
return $this->_renderTags($template);
|
282 |
-
}
|
283 |
-
|
284 |
-
/**
|
285 |
-
* Prepare a section RegEx string for the given opening/closing tags.
|
286 |
-
*
|
287 |
-
* @access protected
|
288 |
-
* @param string $otag
|
289 |
-
* @param string $ctag
|
290 |
-
* @return string
|
291 |
-
*/
|
292 |
-
protected function _prepareSectionRegEx($otag, $ctag) {
|
293 |
-
return sprintf(
|
294 |
-
'/(?:(?<=\\n)[ \\t]*)?%s(?:(?P<type>[%s])(?P<tag_name>.+?)|=(?P<delims>.*?)=)%s\\n?/s',
|
295 |
-
preg_quote($otag, '/'),
|
296 |
-
self::SECTION_TYPES,
|
297 |
-
preg_quote($ctag, '/')
|
298 |
-
);
|
299 |
-
}
|
300 |
-
|
301 |
-
/**
|
302 |
-
* Extract the first section from $template.
|
303 |
-
*
|
304 |
-
* @access protected
|
305 |
-
* @param string $template
|
306 |
-
* @return array $before, $type, $tag_name, $content and $after
|
307 |
-
*/
|
308 |
-
protected function _findSection($template) {
|
309 |
-
$regEx = $this->_prepareSectionRegEx($this->_otag, $this->_ctag);
|
310 |
-
|
311 |
-
$section_start = null;
|
312 |
-
$section_type = null;
|
313 |
-
$content_start = null;
|
314 |
-
|
315 |
-
$search_offset = 0;
|
316 |
-
|
317 |
-
$section_stack = array();
|
318 |
-
$matches = array();
|
319 |
-
while (preg_match($regEx, $template, $matches, PREG_OFFSET_CAPTURE, $search_offset)) {
|
320 |
-
if (isset($matches['delims'][0])) {
|
321 |
-
list($otag, $ctag) = explode(' ', $matches['delims'][0]);
|
322 |
-
$regEx = $this->_prepareSectionRegEx($otag, $ctag);
|
323 |
-
$search_offset = $matches[0][1] + strlen($matches[0][0]);
|
324 |
-
continue;
|
325 |
-
}
|
326 |
-
|
327 |
-
$match = $matches[0][0];
|
328 |
-
$offset = $matches[0][1];
|
329 |
-
$type = $matches['type'][0];
|
330 |
-
$tag_name = trim($matches['tag_name'][0]);
|
331 |
-
|
332 |
-
$search_offset = $offset + strlen($match);
|
333 |
-
|
334 |
-
switch ($type) {
|
335 |
-
case '^':
|
336 |
-
case '#':
|
337 |
-
if (empty($section_stack)) {
|
338 |
-
$section_start = $offset;
|
339 |
-
$section_type = $type;
|
340 |
-
$content_start = $search_offset;
|
341 |
-
}
|
342 |
-
array_push($section_stack, $tag_name);
|
343 |
-
break;
|
344 |
-
case '/':
|
345 |
-
if (empty($section_stack) || ($tag_name !== array_pop($section_stack))) {
|
346 |
-
if ($this->_throwsException(MustacheException::UNEXPECTED_CLOSE_SECTION)) {
|
347 |
-
throw new MustacheException('Unexpected close section: ' . $tag_name, MustacheException::UNEXPECTED_CLOSE_SECTION);
|
348 |
-
}
|
349 |
-
}
|
350 |
-
|
351 |
-
if (empty($section_stack)) {
|
352 |
-
// $before, $type, $tag_name, $content, $after
|
353 |
-
return array(
|
354 |
-
substr($template, 0, $section_start),
|
355 |
-
$section_type,
|
356 |
-
$tag_name,
|
357 |
-
substr($template, $content_start, $offset - $content_start),
|
358 |
-
substr($template, $search_offset),
|
359 |
-
);
|
360 |
-
}
|
361 |
-
break;
|
362 |
-
}
|
363 |
-
}
|
364 |
-
|
365 |
-
if (!empty($section_stack)) {
|
366 |
-
if ($this->_throwsException(MustacheException::UNCLOSED_SECTION)) {
|
367 |
-
throw new MustacheException('Unclosed section: ' . $section_stack[0], MustacheException::UNCLOSED_SECTION);
|
368 |
-
}
|
369 |
-
}
|
370 |
-
}
|
371 |
-
|
372 |
-
/**
|
373 |
-
* Prepare a pragma RegEx for the given opening/closing tags.
|
374 |
-
*
|
375 |
-
* @access protected
|
376 |
-
* @param string $otag
|
377 |
-
* @param string $ctag
|
378 |
-
* @return string
|
379 |
-
*/
|
380 |
-
protected function _preparePragmaRegEx($otag, $ctag) {
|
381 |
-
return sprintf(
|
382 |
-
'/%s%%\\s*(?P<pragma_name>[\\w_-]+)(?P<options_string>(?: [\\w]+=[\\w]+)*)\\s*%s\\n?/s',
|
383 |
-
preg_quote($otag, '/'),
|
384 |
-
preg_quote($ctag, '/')
|
385 |
-
);
|
386 |
-
}
|
387 |
-
|
388 |
-
/**
|
389 |
-
* Initialize pragmas and remove all pragma tags.
|
390 |
-
*
|
391 |
-
* @access protected
|
392 |
-
* @param string $template
|
393 |
-
* @return string
|
394 |
-
*/
|
395 |
-
protected function _renderPragmas($template) {
|
396 |
-
$this->_localPragmas = $this->_pragmas;
|
397 |
-
|
398 |
-
// no pragmas
|
399 |
-
if (strpos($template, $this->_otag . '%') === false) {
|
400 |
-
return $template;
|
401 |
-
}
|
402 |
-
|
403 |
-
$regEx = $this->_preparePragmaRegEx($this->_otag, $this->_ctag);
|
404 |
-
return preg_replace_callback($regEx, array($this, '_renderPragma'), $template);
|
405 |
-
}
|
406 |
-
|
407 |
-
/**
|
408 |
-
* A preg_replace helper to remove {{%PRAGMA}} tags and enable requested pragma.
|
409 |
-
*
|
410 |
-
* @access protected
|
411 |
-
* @param mixed $matches
|
412 |
-
* @return void
|
413 |
-
* @throws MustacheException unknown pragma
|
414 |
-
*/
|
415 |
-
protected function _renderPragma($matches) {
|
416 |
-
$pragma = $matches[0];
|
417 |
-
$pragma_name = $matches['pragma_name'];
|
418 |
-
$options_string = $matches['options_string'];
|
419 |
-
|
420 |
-
if (!in_array($pragma_name, $this->_pragmasImplemented)) {
|
421 |
-
if ($this->_throwsException(MustacheException::UNKNOWN_PRAGMA)) {
|
422 |
-
throw new MustacheException('Unknown pragma: ' . $pragma_name, MustacheException::UNKNOWN_PRAGMA);
|
423 |
-
} else {
|
424 |
-
return '';
|
425 |
-
}
|
426 |
-
}
|
427 |
-
|
428 |
-
$options = array();
|
429 |
-
foreach (explode(' ', trim($options_string)) as $o) {
|
430 |
-
if ($p = trim($o)) {
|
431 |
-
$p = explode('=', $p);
|
432 |
-
$options[$p[0]] = $p[1];
|
433 |
-
}
|
434 |
-
}
|
435 |
-
|
436 |
-
if (empty($options)) {
|
437 |
-
$this->_localPragmas[$pragma_name] = true;
|
438 |
-
} else {
|
439 |
-
$this->_localPragmas[$pragma_name] = $options;
|
440 |
-
}
|
441 |
-
|
442 |
-
return '';
|
443 |
-
}
|
444 |
-
|
445 |
-
/**
|
446 |
-
* Check whether this Mustache has a specific pragma.
|
447 |
-
*
|
448 |
-
* @access protected
|
449 |
-
* @param string $pragma_name
|
450 |
-
* @return bool
|
451 |
-
*/
|
452 |
-
protected function _hasPragma($pragma_name) {
|
453 |
-
if (array_key_exists($pragma_name, $this->_localPragmas) && $this->_localPragmas[$pragma_name]) {
|
454 |
-
return true;
|
455 |
-
} else {
|
456 |
-
return false;
|
457 |
-
}
|
458 |
-
}
|
459 |
-
|
460 |
-
/**
|
461 |
-
* Return pragma options, if any.
|
462 |
-
*
|
463 |
-
* @access protected
|
464 |
-
* @param string $pragma_name
|
465 |
-
* @return mixed
|
466 |
-
* @throws MustacheException Unknown pragma
|
467 |
-
*/
|
468 |
-
protected function _getPragmaOptions($pragma_name) {
|
469 |
-
if (!$this->_hasPragma($pragma_name)) {
|
470 |
-
if ($this->_throwsException(MustacheException::UNKNOWN_PRAGMA)) {
|
471 |
-
throw new MustacheException('Unknown pragma: ' . $pragma_name, MustacheException::UNKNOWN_PRAGMA);
|
472 |
-
}
|
473 |
-
}
|
474 |
-
|
475 |
-
return (is_array($this->_localPragmas[$pragma_name])) ? $this->_localPragmas[$pragma_name] : array();
|
476 |
-
}
|
477 |
-
|
478 |
-
/**
|
479 |
-
* Check whether this Mustache instance throws a given exception.
|
480 |
-
*
|
481 |
-
* Expects exceptions to be MustacheException error codes (i.e. class constants).
|
482 |
-
*
|
483 |
-
* @access protected
|
484 |
-
* @param mixed $exception
|
485 |
-
* @return void
|
486 |
-
*/
|
487 |
-
protected function _throwsException($exception) {
|
488 |
-
return (isset($this->_throwsExceptions[$exception]) && $this->_throwsExceptions[$exception]);
|
489 |
-
}
|
490 |
-
|
491 |
-
/**
|
492 |
-
* Prepare a tag RegEx for the given opening/closing tags.
|
493 |
-
*
|
494 |
-
* @access protected
|
495 |
-
* @param string $otag
|
496 |
-
* @param string $ctag
|
497 |
-
* @return string
|
498 |
-
*/
|
499 |
-
protected function _prepareTagRegEx($otag, $ctag, $first = false) {
|
500 |
-
return sprintf(
|
501 |
-
'/(?P<leading>(?:%s\\r?\\n)[ \\t]*)?%s(?P<type>[%s]?)(?P<tag_name>.+?)(?:\\2|})?%s(?P<trailing>\\s*(?:\\r?\\n|\\Z))?/s',
|
502 |
-
($first ? '\\A|' : ''),
|
503 |
-
preg_quote($otag, '/'),
|
504 |
-
self::TAG_TYPES,
|
505 |
-
preg_quote($ctag, '/')
|
506 |
-
);
|
507 |
-
}
|
508 |
-
|
509 |
-
/**
|
510 |
-
* Loop through and render individual Mustache tags.
|
511 |
-
*
|
512 |
-
* @access protected
|
513 |
-
* @param string $template
|
514 |
-
* @return void
|
515 |
-
*/
|
516 |
-
protected function _renderTags($template) {
|
517 |
-
if (strpos($template, $this->_otag) === false) {
|
518 |
-
return $template;
|
519 |
-
}
|
520 |
-
|
521 |
-
$first = true;
|
522 |
-
$this->_tagRegEx = $this->_prepareTagRegEx($this->_otag, $this->_ctag, true);
|
523 |
-
|
524 |
-
$html = '';
|
525 |
-
$matches = array();
|
526 |
-
while (preg_match($this->_tagRegEx, $template, $matches, PREG_OFFSET_CAPTURE)) {
|
527 |
-
$tag = $matches[0][0];
|
528 |
-
$offset = $matches[0][1];
|
529 |
-
$modifier = $matches['type'][0];
|
530 |
-
$tag_name = trim($matches['tag_name'][0]);
|
531 |
-
|
532 |
-
if (isset($matches['leading']) && $matches['leading'][1] > -1) {
|
533 |
-
$leading = $matches['leading'][0];
|
534 |
-
} else {
|
535 |
-
$leading = null;
|
536 |
-
}
|
537 |
-
|
538 |
-
if (isset($matches['trailing']) && $matches['trailing'][1] > -1) {
|
539 |
-
$trailing = $matches['trailing'][0];
|
540 |
-
} else {
|
541 |
-
$trailing = null;
|
542 |
-
}
|
543 |
-
|
544 |
-
$html .= substr($template, 0, $offset);
|
545 |
-
|
546 |
-
$next_offset = $offset + strlen($tag);
|
547 |
-
if ((substr($html, -1) == "\n") && (substr($template, $next_offset, 1) == "\n")) {
|
548 |
-
$next_offset++;
|
549 |
-
}
|
550 |
-
$template = substr($template, $next_offset);
|
551 |
-
|
552 |
-
$html .= $this->_renderTag($modifier, $tag_name, $leading, $trailing);
|
553 |
-
|
554 |
-
if ($first == true) {
|
555 |
-
$first = false;
|
556 |
-
$this->_tagRegEx = $this->_prepareTagRegEx($this->_otag, $this->_ctag);
|
557 |
-
}
|
558 |
-
}
|
559 |
-
|
560 |
-
return $html . $template;
|
561 |
-
}
|
562 |
-
|
563 |
-
/**
|
564 |
-
* Render the named tag, given the specified modifier.
|
565 |
-
*
|
566 |
-
* Accepted modifiers are `=` (change delimiter), `!` (comment), `>` (partial)
|
567 |
-
* `{` or `&` (don't escape output), or none (render escaped output).
|
568 |
-
*
|
569 |
-
* @access protected
|
570 |
-
* @param string $modifier
|
571 |
-
* @param string $tag_name
|
572 |
-
* @param string $leading Whitespace
|
573 |
-
* @param string $trailing Whitespace
|
574 |
-
* @throws MustacheException Unmatched section tag encountered.
|
575 |
-
* @return string
|
576 |
-
*/
|
577 |
-
protected function _renderTag($modifier, $tag_name, $leading, $trailing) {
|
578 |
-
switch ($modifier) {
|
579 |
-
case '=':
|
580 |
-
return $this->_changeDelimiter($tag_name, $leading, $trailing);
|
581 |
-
break;
|
582 |
-
case '!':
|
583 |
-
return $this->_renderComment($tag_name, $leading, $trailing);
|
584 |
-
break;
|
585 |
-
case '>':
|
586 |
-
case '<':
|
587 |
-
return $this->_renderPartial($tag_name, $leading, $trailing);
|
588 |
-
break;
|
589 |
-
case '{':
|
590 |
-
// strip the trailing } ...
|
591 |
-
if ($tag_name[(strlen($tag_name) - 1)] == '}') {
|
592 |
-
$tag_name = substr($tag_name, 0, -1);
|
593 |
-
}
|
594 |
-
case '&':
|
595 |
-
if ($this->_hasPragma(self::PRAGMA_UNESCAPED)) {
|
596 |
-
return $this->_renderEscaped($tag_name, $leading, $trailing);
|
597 |
-
} else {
|
598 |
-
return $this->_renderUnescaped($tag_name, $leading, $trailing);
|
599 |
-
}
|
600 |
-
break;
|
601 |
-
case '#':
|
602 |
-
case '^':
|
603 |
-
case '/':
|
604 |
-
// remove any leftover section tags
|
605 |
-
return $leading . $trailing;
|
606 |
-
break;
|
607 |
-
default:
|
608 |
-
if ($this->_hasPragma(self::PRAGMA_UNESCAPED)) {
|
609 |
-
return $this->_renderUnescaped($modifier . $tag_name, $leading, $trailing);
|
610 |
-
} else {
|
611 |
-
return $this->_renderEscaped($modifier . $tag_name, $leading, $trailing);
|
612 |
-
}
|
613 |
-
break;
|
614 |
-
}
|
615 |
-
}
|
616 |
-
|
617 |
-
/**
|
618 |
-
* Returns true if any of its args contains the "\r" character.
|
619 |
-
*
|
620 |
-
* @access protected
|
621 |
-
* @param string $str
|
622 |
-
* @return boolean
|
623 |
-
*/
|
624 |
-
protected function _stringHasR($str) {
|
625 |
-
foreach (func_get_args() as $arg) {
|
626 |
-
if (strpos($arg, "\r") !== false) {
|
627 |
-
return true;
|
628 |
-
}
|
629 |
-
}
|
630 |
-
return false;
|
631 |
-
}
|
632 |
-
|
633 |
-
/**
|
634 |
-
* Escape and return the requested tag.
|
635 |
-
*
|
636 |
-
* @access protected
|
637 |
-
* @param string $tag_name
|
638 |
-
* @param string $leading Whitespace
|
639 |
-
* @param string $trailing Whitespace
|
640 |
-
* @return string
|
641 |
-
*/
|
642 |
-
protected function _renderEscaped($tag_name, $leading, $trailing) {
|
643 |
-
$rendered = htmlentities($this->_renderUnescaped($tag_name, '', ''), ENT_COMPAT, $this->_charset);
|
644 |
-
return $leading . $rendered . $trailing;
|
645 |
-
}
|
646 |
-
|
647 |
-
/**
|
648 |
-
* Render a comment (i.e. return an empty string).
|
649 |
-
*
|
650 |
-
* @access protected
|
651 |
-
* @param string $tag_name
|
652 |
-
* @param string $leading Whitespace
|
653 |
-
* @param string $trailing Whitespace
|
654 |
-
* @return string
|
655 |
-
*/
|
656 |
-
protected function _renderComment($tag_name, $leading, $trailing) {
|
657 |
-
if ($leading !== null && $trailing !== null) {
|
658 |
-
if (strpos($leading, "\n") === false) {
|
659 |
-
return '';
|
660 |
-
}
|
661 |
-
return $this->_stringHasR($leading, $trailing) ? "\r\n" : "\n";
|
662 |
-
}
|
663 |
-
return $leading . $trailing;
|
664 |
-
}
|
665 |
-
|
666 |
-
/**
|
667 |
-
* Return the requested tag unescaped.
|
668 |
-
*
|
669 |
-
* @access protected
|
670 |
-
* @param string $tag_name
|
671 |
-
* @param string $leading Whitespace
|
672 |
-
* @param string $trailing Whitespace
|
673 |
-
* @return string
|
674 |
-
*/
|
675 |
-
protected function _renderUnescaped($tag_name, $leading, $trailing) {
|
676 |
-
$val = $this->_getVariable($tag_name);
|
677 |
-
|
678 |
-
if ($this->_varIsCallable($val)) {
|
679 |
-
$val = $this->_renderTemplate(call_user_func($val));
|
680 |
-
}
|
681 |
-
|
682 |
-
return $leading . $val . $trailing;
|
683 |
-
}
|
684 |
-
|
685 |
-
/**
|
686 |
-
* Render the requested partial.
|
687 |
-
*
|
688 |
-
* @access protected
|
689 |
-
* @param string $tag_name
|
690 |
-
* @param string $leading Whitespace
|
691 |
-
* @param string $trailing Whitespace
|
692 |
-
* @return string
|
693 |
-
*/
|
694 |
-
protected function _renderPartial($tag_name, $leading, $trailing) {
|
695 |
-
$partial = $this->_getPartial($tag_name);
|
696 |
-
if ($leading !== null && $trailing !== null) {
|
697 |
-
$whitespace = trim($leading, "\r\n");
|
698 |
-
$partial = preg_replace('/(\\r?\\n)(?!$)/s', "\\1" . $whitespace, $partial);
|
699 |
-
}
|
700 |
-
|
701 |
-
$view = clone($this);
|
702 |
-
|
703 |
-
if ($leading !== null && $trailing !== null) {
|
704 |
-
return $leading . $view->render($partial);
|
705 |
-
} else {
|
706 |
-
return $leading . $view->render($partial) . $trailing;
|
707 |
-
}
|
708 |
-
}
|
709 |
-
|
710 |
-
/**
|
711 |
-
* Change the Mustache tag delimiter. This method also replaces this object's current
|
712 |
-
* tag RegEx with one using the new delimiters.
|
713 |
-
*
|
714 |
-
* @access protected
|
715 |
-
* @param string $tag_name
|
716 |
-
* @param string $leading Whitespace
|
717 |
-
* @param string $trailing Whitespace
|
718 |
-
* @return string
|
719 |
-
*/
|
720 |
-
protected function _changeDelimiter($tag_name, $leading, $trailing) {
|
721 |
-
list($otag, $ctag) = explode(' ', $tag_name);
|
722 |
-
$this->_otag = $otag;
|
723 |
-
$this->_ctag = $ctag;
|
724 |
-
|
725 |
-
$this->_tagRegEx = $this->_prepareTagRegEx($this->_otag, $this->_ctag);
|
726 |
-
|
727 |
-
if ($leading !== null && $trailing !== null) {
|
728 |
-
if (strpos($leading, "\n") === false) {
|
729 |
-
return '';
|
730 |
-
}
|
731 |
-
return $this->_stringHasR($leading, $trailing) ? "\r\n" : "\n";
|
732 |
-
}
|
733 |
-
return $leading . $trailing;
|
734 |
-
}
|
735 |
-
|
736 |
-
/**
|
737 |
-
* Push a local context onto the stack.
|
738 |
-
*
|
739 |
-
* @access protected
|
740 |
-
* @param array &$local_context
|
741 |
-
* @return void
|
742 |
-
*/
|
743 |
-
protected function _pushContext(&$local_context) {
|
744 |
-
$new = array();
|
745 |
-
$new[] =& $local_context;
|
746 |
-
foreach (array_keys($this->_context) as $key) {
|
747 |
-
$new[] =& $this->_context[$key];
|
748 |
-
}
|
749 |
-
$this->_context = $new;
|
750 |
-
}
|
751 |
-
|
752 |
-
/**
|
753 |
-
* Remove the latest context from the stack.
|
754 |
-
*
|
755 |
-
* @access protected
|
756 |
-
* @return void
|
757 |
-
*/
|
758 |
-
protected function _popContext() {
|
759 |
-
$new = array();
|
760 |
-
|
761 |
-
$keys = array_keys($this->_context);
|
762 |
-
array_shift($keys);
|
763 |
-
foreach ($keys as $key) {
|
764 |
-
$new[] =& $this->_context[$key];
|
765 |
-
}
|
766 |
-
$this->_context = $new;
|
767 |
-
}
|
768 |
-
|
769 |
-
/**
|
770 |
-
* Get a variable from the context array.
|
771 |
-
*
|
772 |
-
* If the view is an array, returns the value with array key $tag_name.
|
773 |
-
* If the view is an object, this will check for a public member variable
|
774 |
-
* named $tag_name. If none is available, this method will execute and return
|
775 |
-
* any class method named $tag_name. Failing all of the above, this method will
|
776 |
-
* return an empty string.
|
777 |
-
*
|
778 |
-
* @access protected
|
779 |
-
* @param string $tag_name
|
780 |
-
* @throws MustacheException Unknown variable name.
|
781 |
-
* @return string
|
782 |
-
*/
|
783 |
-
protected function _getVariable($tag_name) {
|
784 |
-
if ($tag_name === '.') {
|
785 |
-
return $this->_context[0];
|
786 |
-
} else if (strpos($tag_name, '.') !== false) {
|
787 |
-
$chunks = explode('.', $tag_name);
|
788 |
-
$first = array_shift($chunks);
|
789 |
-
|
790 |
-
$ret = $this->_findVariableInContext($first, $this->_context);
|
791 |
-
foreach ($chunks as $next) {
|
792 |
-
// Slice off a chunk of context for dot notation traversal.
|
793 |
-
$c = array($ret);
|
794 |
-
$ret = $this->_findVariableInContext($next, $c);
|
795 |
-
}
|
796 |
-
return $ret;
|
797 |
-
} else {
|
798 |
-
return $this->_findVariableInContext($tag_name, $this->_context);
|
799 |
-
}
|
800 |
-
}
|
801 |
-
|
802 |
-
/**
|
803 |
-
* Get a variable from the context array. Internal helper used by getVariable() to abstract
|
804 |
-
* variable traversal for dot notation.
|
805 |
-
*
|
806 |
-
* @access protected
|
807 |
-
* @param string $tag_name
|
808 |
-
* @param array $context
|
809 |
-
* @throws MustacheException Unknown variable name.
|
810 |
-
* @return string
|
811 |
-
*/
|
812 |
-
protected function _findVariableInContext($tag_name, $context) {
|
813 |
-
foreach ($context as $view) {
|
814 |
-
if (is_object($view)) {
|
815 |
-
if (method_exists($view, $tag_name)) {
|
816 |
-
return $view->$tag_name();
|
817 |
-
} else if (isset($view->$tag_name)) {
|
818 |
-
return $view->$tag_name;
|
819 |
-
}
|
820 |
-
} else if (is_array($view) && array_key_exists($tag_name, $view)) {
|
821 |
-
return $view[$tag_name];
|
822 |
-
}
|
823 |
-
}
|
824 |
-
|
825 |
-
if ($this->_throwsException(MustacheException::UNKNOWN_VARIABLE)) {
|
826 |
-
throw new MustacheException("Unknown variable: " . $tag_name, MustacheException::UNKNOWN_VARIABLE);
|
827 |
-
} else {
|
828 |
-
return '';
|
829 |
-
}
|
830 |
-
}
|
831 |
-
|
832 |
-
/**
|
833 |
-
* Retrieve the partial corresponding to the requested tag name.
|
834 |
-
*
|
835 |
-
* Silently fails (i.e. returns '') when the requested partial is not found.
|
836 |
-
*
|
837 |
-
* @access protected
|
838 |
-
* @param string $tag_name
|
839 |
-
* @throws MustacheException Unknown partial name.
|
840 |
-
* @return string
|
841 |
-
*/
|
842 |
-
protected function _getPartial($tag_name) {
|
843 |
-
if ((is_array($this->_partials) || $this->_partials instanceof ArrayAccess) && isset($this->_partials[$tag_name])) {
|
844 |
-
return $this->_partials[$tag_name];
|
845 |
-
}
|
846 |
-
|
847 |
-
if ($this->_throwsException(MustacheException::UNKNOWN_PARTIAL)) {
|
848 |
-
throw new MustacheException('Unknown partial: ' . $tag_name, MustacheException::UNKNOWN_PARTIAL);
|
849 |
-
} else {
|
850 |
-
return '';
|
851 |
-
}
|
852 |
-
}
|
853 |
-
|
854 |
-
/**
|
855 |
-
* Check whether the given $var should be iterated (i.e. in a section context).
|
856 |
-
*
|
857 |
-
* @access protected
|
858 |
-
* @param mixed $var
|
859 |
-
* @return bool
|
860 |
-
*/
|
861 |
-
protected function _varIsIterable($var) {
|
862 |
-
return $var instanceof Traversable || (is_array($var) && !array_diff_key($var, array_keys(array_keys($var))));
|
863 |
-
}
|
864 |
-
|
865 |
-
/**
|
866 |
-
* Higher order sections helper: tests whether the section $var is a valid callback.
|
867 |
-
*
|
868 |
-
* In Mustache.php, a variable is considered 'callable' if the variable is:
|
869 |
-
*
|
870 |
-
* 1. an anonymous function.
|
871 |
-
* 2. an object and the name of a public function, i.e. `array($SomeObject, 'methodName')`
|
872 |
-
* 3. a class name and the name of a public static function, i.e. `array('SomeClass', 'methodName')`
|
873 |
-
*
|
874 |
-
* @access protected
|
875 |
-
* @param mixed $var
|
876 |
-
* @return bool
|
877 |
-
*/
|
878 |
-
protected function _varIsCallable($var) {
|
879 |
-
return !is_string($var) && is_callable($var);
|
880 |
-
}
|
881 |
-
}
|
882 |
-
|
883 |
-
|
884 |
-
/**
|
885 |
-
* MustacheException class.
|
886 |
-
*
|
887 |
-
* @extends Exception
|
888 |
-
*/
|
889 |
-
class MustacheException extends Exception {
|
890 |
-
|
891 |
-
// An UNKNOWN_VARIABLE exception is thrown when a {{variable}} is not found
|
892 |
-
// in the current context.
|
893 |
-
const UNKNOWN_VARIABLE = 0;
|
894 |
-
|
895 |
-
// An UNCLOSED_SECTION exception is thrown when a {{#section}} is not closed.
|
896 |
-
const UNCLOSED_SECTION = 1;
|
897 |
-
|
898 |
-
// An UNEXPECTED_CLOSE_SECTION exception is thrown when {{/section}} appears
|
899 |
-
// without a corresponding {{#section}} or {{^section}}.
|
900 |
-
const UNEXPECTED_CLOSE_SECTION = 2;
|
901 |
-
|
902 |
-
// An UNKNOWN_PARTIAL exception is thrown whenever a {{>partial}} tag appears
|
903 |
-
// with no associated partial.
|
904 |
-
const UNKNOWN_PARTIAL = 3;
|
905 |
-
|
906 |
-
// An UNKNOWN_PRAGMA exception is thrown whenever a {{%PRAGMA}} tag appears
|
907 |
-
// which can't be handled by this Mustache instance.
|
908 |
-
const UNKNOWN_PRAGMA = 4;
|
909 |
-
|
910 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mustache/MustacheLoader.php
DELETED
@@ -1,85 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* A Mustache Partial filesystem loader.
|
5 |
-
*
|
6 |
-
* @author Justin Hileman {@link http://justinhileman.com}
|
7 |
-
*/
|
8 |
-
class MustacheLoader implements ArrayAccess {
|
9 |
-
|
10 |
-
protected $baseDir;
|
11 |
-
protected $partialsCache = array();
|
12 |
-
protected $extension;
|
13 |
-
|
14 |
-
/**
|
15 |
-
* MustacheLoader constructor.
|
16 |
-
*
|
17 |
-
* @access public
|
18 |
-
* @param string $baseDir Base template directory.
|
19 |
-
* @param string $extension File extension for Mustache files (default: 'mustache')
|
20 |
-
* @return void
|
21 |
-
*/
|
22 |
-
public function __construct($baseDir, $extension = 'mustache') {
|
23 |
-
if (!is_dir($baseDir)) {
|
24 |
-
throw new InvalidArgumentException('$baseDir must be a valid directory, ' . $baseDir . ' given.');
|
25 |
-
}
|
26 |
-
|
27 |
-
$this->baseDir = $baseDir;
|
28 |
-
$this->extension = $extension;
|
29 |
-
}
|
30 |
-
|
31 |
-
/**
|
32 |
-
* @param string $offset Name of partial
|
33 |
-
* @return boolean
|
34 |
-
*/
|
35 |
-
public function offsetExists($offset) {
|
36 |
-
return (isset($this->partialsCache[$offset]) || file_exists($this->pathName($offset)));
|
37 |
-
}
|
38 |
-
|
39 |
-
/**
|
40 |
-
* @throws InvalidArgumentException if the given partial doesn't exist
|
41 |
-
* @param string $offset Name of partial
|
42 |
-
* @return string Partial template contents
|
43 |
-
*/
|
44 |
-
public function offsetGet($offset) {
|
45 |
-
if (!$this->offsetExists($offset)) {
|
46 |
-
throw new InvalidArgumentException('Partial does not exist: ' . $offset);
|
47 |
-
}
|
48 |
-
|
49 |
-
if (!isset($this->partialsCache[$offset])) {
|
50 |
-
$this->partialsCache[$offset] = file_get_contents($this->pathName($offset));
|
51 |
-
}
|
52 |
-
|
53 |
-
return $this->partialsCache[$offset];
|
54 |
-
}
|
55 |
-
|
56 |
-
/**
|
57 |
-
* MustacheLoader is an immutable filesystem loader. offsetSet throws a LogicException if called.
|
58 |
-
*
|
59 |
-
* @throws LogicException
|
60 |
-
* @return void
|
61 |
-
*/
|
62 |
-
public function offsetSet($offset, $value) {
|
63 |
-
throw new LogicException('Unable to set offset: MustacheLoader is an immutable ArrayAccess object.');
|
64 |
-
}
|
65 |
-
|
66 |
-
/**
|
67 |
-
* MustacheLoader is an immutable filesystem loader. offsetUnset throws a LogicException if called.
|
68 |
-
*
|
69 |
-
* @throws LogicException
|
70 |
-
* @return void
|
71 |
-
*/
|
72 |
-
public function offsetUnset($offset) {
|
73 |
-
throw new LogicException('Unable to unset offset: MustacheLoader is an immutable ArrayAccess object.');
|
74 |
-
}
|
75 |
-
|
76 |
-
/**
|
77 |
-
* An internal helper for generating path names.
|
78 |
-
*
|
79 |
-
* @param string $file Partial name
|
80 |
-
* @return string File path
|
81 |
-
*/
|
82 |
-
protected function pathName($file) {
|
83 |
-
return $this->baseDir . '/' . $file . '.' . $this->extension;
|
84 |
-
}
|
85 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mustache/README.markdown
DELETED
@@ -1,98 +0,0 @@
|
|
1 |
-
Mustache.php
|
2 |
-
============
|
3 |
-
|
4 |
-
A [Mustache](http://defunkt.github.com/mustache/) implementation in PHP.
|
5 |
-
|
6 |
-
|
7 |
-
Usage
|
8 |
-
-----
|
9 |
-
|
10 |
-
A quick example:
|
11 |
-
|
12 |
-
```php
|
13 |
-
<?php
|
14 |
-
include('Mustache.php');
|
15 |
-
$m = new Mustache;
|
16 |
-
echo $m->render('Hello {{planet}}', array('planet' => 'World!'));
|
17 |
-
// "Hello World!"
|
18 |
-
```
|
19 |
-
|
20 |
-
|
21 |
-
And a more in-depth example--this is the canonical Mustache template:
|
22 |
-
|
23 |
-
```
|
24 |
-
Hello {{name}}
|
25 |
-
You have just won ${{value}}!
|
26 |
-
{{#in_ca}}
|
27 |
-
Well, ${{taxed_value}}, after taxes.
|
28 |
-
{{/in_ca}}
|
29 |
-
```
|
30 |
-
|
31 |
-
|
32 |
-
Along with the associated Mustache class:
|
33 |
-
|
34 |
-
```php
|
35 |
-
<?php
|
36 |
-
class Chris extends Mustache {
|
37 |
-
public $name = "Chris";
|
38 |
-
public $value = 10000;
|
39 |
-
|
40 |
-
public function taxed_value() {
|
41 |
-
return $this->value - ($this->value * 0.4);
|
42 |
-
}
|
43 |
-
|
44 |
-
public $in_ca = true;
|
45 |
-
}
|
46 |
-
```
|
47 |
-
|
48 |
-
|
49 |
-
Render it like so:
|
50 |
-
|
51 |
-
```php
|
52 |
-
<?php
|
53 |
-
$chris = new Chris;
|
54 |
-
echo $chris->render($template);
|
55 |
-
```
|
56 |
-
|
57 |
-
|
58 |
-
Here's the same thing, a different way:
|
59 |
-
|
60 |
-
Create a view object--which could also be an associative array, but those don't do functions quite as well:
|
61 |
-
|
62 |
-
```php
|
63 |
-
<?php
|
64 |
-
class Chris {
|
65 |
-
public $name = "Chris";
|
66 |
-
public $value = 10000;
|
67 |
-
|
68 |
-
public function taxed_value() {
|
69 |
-
return $this->value - ($this->value * 0.4);
|
70 |
-
}
|
71 |
-
|
72 |
-
public $in_ca = true;
|
73 |
-
}
|
74 |
-
```
|
75 |
-
|
76 |
-
|
77 |
-
And render it:
|
78 |
-
|
79 |
-
```php
|
80 |
-
<?php
|
81 |
-
$chris = new Chris;
|
82 |
-
$m = new Mustache;
|
83 |
-
echo $m->render($template, $chris);
|
84 |
-
```
|
85 |
-
|
86 |
-
|
87 |
-
Known Issues
|
88 |
-
------------
|
89 |
-
|
90 |
-
* As of Mustache spec v1.1.2, there are a couple of whitespace bugs around section tags... Despite these failing tests, this
|
91 |
-
version is actually *closer* to correct than previous releases.
|
92 |
-
|
93 |
-
|
94 |
-
See Also
|
95 |
-
--------
|
96 |
-
|
97 |
-
* [Readme for the Ruby Mustache implementation](http://github.com/defunkt/mustache/blob/master/README.md).
|
98 |
-
* [mustache(1)](http://mustache.github.com/mustache.1.html) and [mustache(5)](http://mustache.github.com/mustache.5.html) man pages.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
posts-to-posts.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
/*
|
3 |
Plugin Name: Posts 2 Posts
|
4 |
Description: Create many-to-many relationships between all types of posts.
|
5 |
-
Version: 1.6.
|
6 |
Author: scribu
|
7 |
Author URI: http://scribu.net/
|
8 |
Plugin URI: http://scribu.net/wordpress/posts-to-posts
|
@@ -10,32 +10,38 @@ Text Domain: posts-to-posts
|
|
10 |
Domain Path: /lang
|
11 |
*/
|
12 |
|
13 |
-
define( 'P2P_PLUGIN_VERSION', '1.6.
|
14 |
|
15 |
define( 'P2P_TEXTDOMAIN', 'posts-to-posts' );
|
16 |
|
17 |
-
require_once dirname( __FILE__ ) . '/scb/load.php';
|
18 |
-
|
19 |
function _p2p_load() {
|
20 |
load_plugin_textdomain( P2P_TEXTDOMAIN, '', basename( dirname( __FILE__ ) ) . '/lang' );
|
21 |
|
22 |
-
|
23 |
-
|
24 |
-
return;
|
25 |
}
|
26 |
|
27 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
|
29 |
register_uninstall_hook( __FILE__, array( 'P2P_Storage', 'uninstall' ) );
|
30 |
|
31 |
if ( is_admin() )
|
32 |
_p2p_load_admin();
|
33 |
}
|
34 |
-
scb_init( '_p2p_load' );
|
35 |
|
36 |
function _p2p_load_admin() {
|
37 |
P2P_Autoload::register( 'P2P_', dirname( __FILE__ ) . '/admin' );
|
38 |
|
|
|
|
|
39 |
new P2P_Box_Factory;
|
40 |
new P2P_Column_Factory;
|
41 |
new P2P_Dropdown_Factory;
|
@@ -47,5 +53,16 @@ function _p2p_init() {
|
|
47 |
// Safe hook for calling p2p_register_connection_type()
|
48 |
do_action( 'p2p_init' );
|
49 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
add_action( 'wp_loaded', '_p2p_init' );
|
51 |
|
2 |
/*
|
3 |
Plugin Name: Posts 2 Posts
|
4 |
Description: Create many-to-many relationships between all types of posts.
|
5 |
+
Version: 1.6.4
|
6 |
Author: scribu
|
7 |
Author URI: http://scribu.net/
|
8 |
Plugin URI: http://scribu.net/wordpress/posts-to-posts
|
10 |
Domain Path: /lang
|
11 |
*/
|
12 |
|
13 |
+
define( 'P2P_PLUGIN_VERSION', '1.6.4' );
|
14 |
|
15 |
define( 'P2P_TEXTDOMAIN', 'posts-to-posts' );
|
16 |
|
|
|
|
|
17 |
function _p2p_load() {
|
18 |
load_plugin_textdomain( P2P_TEXTDOMAIN, '', basename( dirname( __FILE__ ) ) . '/lang' );
|
19 |
|
20 |
+
if ( !function_exists( 'p2p_register_connection_type' ) ) {
|
21 |
+
require_once dirname( __FILE__ ) . '/vendor/scribu/lib-posts-to-posts/autoload.php';
|
|
|
22 |
}
|
23 |
|
24 |
+
P2P_Storage::init();
|
25 |
+
|
26 |
+
P2P_Query_Post::init();
|
27 |
+
P2P_Query_User::init();
|
28 |
+
|
29 |
+
P2P_URL_Query::init();
|
30 |
+
|
31 |
+
P2P_Widget::init();
|
32 |
+
P2P_Shortcodes::init();
|
33 |
|
34 |
register_uninstall_hook( __FILE__, array( 'P2P_Storage', 'uninstall' ) );
|
35 |
|
36 |
if ( is_admin() )
|
37 |
_p2p_load_admin();
|
38 |
}
|
|
|
39 |
|
40 |
function _p2p_load_admin() {
|
41 |
P2P_Autoload::register( 'P2P_', dirname( __FILE__ ) . '/admin' );
|
42 |
|
43 |
+
P2P_Mustache::init();
|
44 |
+
|
45 |
new P2P_Box_Factory;
|
46 |
new P2P_Column_Factory;
|
47 |
new P2P_Dropdown_Factory;
|
53 |
// Safe hook for calling p2p_register_connection_type()
|
54 |
do_action( 'p2p_init' );
|
55 |
}
|
56 |
+
|
57 |
+
if ( is_dir( dirname( __FILE__ ) . '/vendor' ) ) {
|
58 |
+
// Not using vendor/autload.php because scb-framework/load.php has better compatibility
|
59 |
+
|
60 |
+
require_once dirname( __FILE__ ) . '/vendor/mustache/mustache/src/Mustache/Autoloader.php';
|
61 |
+
Mustache_Autoloader::register();
|
62 |
+
|
63 |
+
require_once dirname( __FILE__ ) . '/vendor/scribu/scb-framework/load.php';
|
64 |
+
}
|
65 |
+
|
66 |
+
scb_init( '_p2p_load' );
|
67 |
add_action( 'wp_loaded', '_p2p_init' );
|
68 |
|
readme.txt
CHANGED
@@ -3,8 +3,8 @@
|
|
3 |
Contributors: scribu, ciobi
|
4 |
Tags: connections, custom post types, relationships, many-to-many, users
|
5 |
Requires at least: 3.5
|
6 |
-
Tested up to:
|
7 |
-
Stable tag: 1.6.
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
@@ -57,6 +57,12 @@ Additional info can be found on the [wiki](http://github.com/scribu/wp-posts-to-
|
|
57 |
|
58 |
== Changelog ==
|
59 |
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
= 1.6.3 =
|
61 |
* added Serbian translation. props Borisa Djuraskovic
|
62 |
* fixed spinner in admin box. props yamablam
|
3 |
Contributors: scribu, ciobi
|
4 |
Tags: connections, custom post types, relationships, many-to-many, users
|
5 |
Requires at least: 3.5
|
6 |
+
Tested up to: 4.2
|
7 |
+
Stable tag: 1.6.4
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
57 |
|
58 |
== Changelog ==
|
59 |
|
60 |
+
= 1.6.4 =
|
61 |
+
* added Danish translation. props phh
|
62 |
+
* updated Swedish translation. props EyesX
|
63 |
+
* fixed issue with multiple `parse_query` calls. props hezachenary
|
64 |
+
* added `p2p_post_admin_column_link` and `p2p_user_admin_column_link` filters. props PareshRadadiya
|
65 |
+
|
66 |
= 1.6.3 =
|
67 |
* added Serbian translation. props Borisa Djuraskovic
|
68 |
* fixed spinner in admin box. props yamablam
|
vendor/mustache/mustache/.travis.yml
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
language: php
|
2 |
+
php:
|
3 |
+
- 5.2
|
4 |
+
- 5.3
|
5 |
+
- 5.4
|
6 |
+
- 5.5
|
7 |
+
- 5.6
|
8 |
+
- hhvm
|
9 |
+
|
10 |
+
matrix:
|
11 |
+
allow_failures:
|
12 |
+
- php: hhvm # See https://github.com/facebook/hhvm/pull/1860
|
vendor/mustache/mustache/CONTRIBUTING.md
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Contributions welcome!
|
2 |
+
|
3 |
+
|
4 |
+
### Here's a quick guide:
|
5 |
+
|
6 |
+
1. [Fork the repo on GitHub](https://github.com/bobthecow/mustache.php).
|
7 |
+
|
8 |
+
2. Run the test suite. We only take pull requests with passing tests, and it's great to know that you have a clean slate. Make sure you have PHPUnit 3.5+, then run `phpunit` from the project directory.
|
9 |
+
|
10 |
+
3. Add tests for your change. Only refactoring and documentation changes require no new tests. If you are adding functionality or fixing a bug, add a test!
|
11 |
+
|
12 |
+
4. Make the tests pass.
|
13 |
+
|
14 |
+
5. Push your fork to GitHub and submit a pull request against the `dev` branch.
|
15 |
+
|
16 |
+
|
17 |
+
### You can do some things to increase the chance that your pull request is accepted the first time:
|
18 |
+
|
19 |
+
* Submit one pull request per fix or feature.
|
20 |
+
* To help with that, do all your work in a feature branch (e.g. `feature/my-alsome-feature`).
|
21 |
+
* Follow the conventions you see used in the project.
|
22 |
+
* Use `phpcs --standard=PSR2` to check your changes against the coding standard.
|
23 |
+
* Write tests that fail without your code, and pass with it.
|
24 |
+
* Don't bump version numbers. Those will be updated — per [semver](http://semver.org) — once your change is merged into `master`.
|
25 |
+
* Update any documentation: docblocks, README, examples, etc.
|
26 |
+
* ... Don't update the wiki until your change is merged and released, but make a note in your pull request so we don't forget.
|
27 |
+
|
28 |
+
|
29 |
+
### Mustache.php follows the PSR-* coding standards:
|
30 |
+
|
31 |
+
* [PSR-0: Class and file naming conventions](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md)
|
32 |
+
* [PSR-1: Basic coding standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md)
|
33 |
+
* [PSR-2: Coding style guide](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)
|
vendor/mustache/mustache/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
The MIT License (MIT)
|
2 |
+
|
3 |
+
Copyright (c) 2010-2014 Justin Hileman
|
4 |
+
|
5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6 |
+
of this software and associated documentation files (the "Software"), to deal
|
7 |
+
in the Software without restriction, including without limitation the rights
|
8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9 |
+
copies of the Software, and to permit persons to whom the Software is
|
10 |
+
furnished to do so, subject to the following conditions:
|
11 |
+
|
12 |
+
The above copyright notice and this permission notice shall be included in all
|
13 |
+
copies or substantial portions of the Software.
|
14 |
+
|
15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16 |
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17 |
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
18 |
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
19 |
+
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
20 |
+
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
21 |
+
OR OTHER DEALINGS IN THE SOFTWARE.
|
vendor/mustache/mustache/README.md
ADDED
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Mustache.php
|
2 |
+
============
|
3 |
+
|
4 |
+
A [Mustache](http://mustache.github.com/) implementation in PHP.
|
5 |
+
|
6 |
+
[![Package version](http://img.shields.io/packagist/v/mustache/mustache.svg)](https://packagist.org/packages/mustache/mustache)
|
7 |
+
[![Build status](http://img.shields.io/travis/bobthecow/mustache.php/dev.svg)](http://travis-ci.org/bobthecow/mustache.php)
|
8 |
+
[![Monthly downloads](http://img.shields.io/packagist/dm/mustache/mustache.svg)](https://packagist.org/packages/mustache/mustache)
|
9 |
+
|
10 |
+
|
11 |
+
Usage
|
12 |
+
-----
|
13 |
+
|
14 |
+
A quick example:
|
15 |
+
|
16 |
+
```php
|
17 |
+
<?php
|
18 |
+
$m = new Mustache_Engine;
|
19 |
+
echo $m->render('Hello {{planet}}', array('planet' => 'World!')); // "Hello World!"
|
20 |
+
```
|
21 |
+
|
22 |
+
|
23 |
+
And a more in-depth example -- this is the canonical Mustache template:
|
24 |
+
|
25 |
+
```html+jinja
|
26 |
+
Hello {{name}}
|
27 |
+
You have just won ${{value}}!
|
28 |
+
{{#in_ca}}
|
29 |
+
Well, ${{taxed_value}}, after taxes.
|
30 |
+
{{/in_ca}}
|
31 |
+
```
|
32 |
+
|
33 |
+
|
34 |
+
Create a view "context" object -- which could also be an associative array, but those don't do functions quite as well:
|
35 |
+
|
36 |
+
```php
|
37 |
+
<?php
|
38 |
+
class Chris {
|
39 |
+
public $name = "Chris";
|
40 |
+
public $value = 10000;
|
41 |
+
|
42 |
+
public function taxed_value() {
|
43 |
+
return $this->value - ($this->value * 0.4);
|
44 |
+
}
|
45 |
+
|
46 |
+
public $in_ca = true;
|
47 |
+
}
|
48 |
+
```
|
49 |
+
|
50 |
+
|
51 |
+
And render it:
|
52 |
+
|
53 |
+
```php
|
54 |
+
<?php
|
55 |
+
$m = new Mustache_Engine;
|
56 |
+
$chris = new Chris;
|
57 |
+
echo $m->render($template, $chris);
|
58 |
+
```
|
59 |
+
|
60 |
+
|
61 |
+
And That's Not All!
|
62 |
+
-------------------
|
63 |
+
|
64 |
+
Read [the Mustache.php documentation](https://github.com/bobthecow/mustache.php/wiki/Home) for more information.
|
65 |
+
|
66 |
+
|
67 |
+
See Also
|
68 |
+
--------
|
69 |
+
|
70 |
+
* [Readme for the Ruby Mustache implementation](http://github.com/defunkt/mustache/blob/master/README.md).
|
71 |
+
* [mustache(5)](http://mustache.github.com/mustache.5.html) man page.
|
vendor/mustache/mustache/composer.json
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "mustache/mustache",
|
3 |
+
"description": "A Mustache implementation in PHP.",
|
4 |
+
"keywords": ["templating", "mustache"],
|
5 |
+
"homepage": "https://github.com/bobthecow/mustache.php",
|
6 |
+
"type": "library",
|
7 |
+
"license": "MIT",
|
8 |
+
"authors": [
|
9 |
+
{
|
10 |
+
"name": "Justin Hileman",
|
11 |
+
"email": "justin@justinhileman.info",
|
12 |
+
"homepage": "http://justinhileman.com"
|
13 |
+
}
|
14 |
+
],
|
15 |
+
"require": {
|
16 |
+
"php": ">=5.2.4"
|
17 |
+
},
|
18 |
+
"require-dev": {
|
19 |
+
"phpunit/phpunit": "*"
|
20 |
+
},
|
21 |
+
"autoload": {
|
22 |
+
"psr-0": { "Mustache": "src/" }
|
23 |
+
}
|
24 |
+
}
|
vendor/mustache/mustache/phpunit.xml.dist
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<phpunit backupGlobals="false" colors="true" bootstrap="./test/bootstrap.php">
|
3 |
+
<testsuite name="Mustache">
|
4 |
+
<directory suffix="Test.php">./test</directory>
|
5 |
+
<exclude>./test/Mustache/Test/FiveThree</exclude>
|
6 |
+
</testsuite>
|
7 |
+
|
8 |
+
<testsuite name="Mustache FiveThree">
|
9 |
+
<directory suffix="Test.php" phpVersion="5.3.0" phpVersionOperator=">=">./test/Mustache/Test/FiveThree</directory>
|
10 |
+
</testsuite>
|
11 |
+
|
12 |
+
<filter>
|
13 |
+
<whitelist>
|
14 |
+
<directory suffix=".php">./src/Mustache</directory>
|
15 |
+
</whitelist>
|
16 |
+
</filter>
|
17 |
+
</phpunit>
|
vendor/mustache/mustache/src/Mustache/Autoloader.php
ADDED
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Mustache.php.
|
5 |
+
*
|
6 |
+
* (c) 2010-2014 Justin Hileman
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Mustache class autoloader.
|
14 |
+
*/
|
15 |
+
class Mustache_Autoloader
|
16 |
+
{
|
17 |
+
private $baseDir;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Autoloader constructor.
|
21 |
+
*
|
22 |
+
* @param string $baseDir Mustache library base directory (default: dirname(__FILE__).'/..')
|
23 |
+
*/
|
24 |
+
public function __construct($baseDir = null)
|
25 |
+
{
|
26 |
+
if ($baseDir === null) {
|
27 |
+
$baseDir = dirname(__FILE__).'/..';
|
28 |
+
}
|
29 |
+
|
30 |
+
// realpath doesn't always work, for example, with stream URIs
|
31 |
+
$realDir = realpath($baseDir);
|
32 |
+
if (is_dir($realDir)) {
|
33 |
+
$this->baseDir = $realDir;
|
34 |
+
} else {
|
35 |
+
$this->baseDir = $baseDir;
|
36 |
+
}
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Register a new instance as an SPL autoloader.
|
41 |
+
*
|
42 |
+
* @param string $baseDir Mustache library base directory (default: dirname(__FILE__).'/..')
|
43 |
+
*
|
44 |
+
* @return Mustache_Autoloader Registered Autoloader instance
|
45 |
+
*/
|
46 |
+
public static function register($baseDir = null)
|
47 |
+
{
|
48 |
+
$loader = new self($baseDir);
|
49 |
+
spl_autoload_register(array($loader, 'autoload'));
|
50 |
+
|
51 |
+
return $loader;
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Autoload Mustache classes.
|
56 |
+
*
|
57 |
+
* @param string $class
|
58 |
+
*/
|
59 |
+
public function autoload($class)
|
60 |
+
{
|
61 |
+
if ($class[0] === '\\') {
|
62 |
+
$class = substr($class, 1);
|
63 |
+
}
|
64 |
+
|
65 |
+
if (strpos($class, 'Mustache') !== 0) {
|
66 |
+
return;
|
67 |
+
}
|
68 |
+
|
69 |
+
$file = sprintf('%s/%s.php', $this->baseDir, str_replace('_', '/', $class));
|
70 |
+
if (is_file($file)) {
|
71 |
+
require $file;
|
72 |
+
}
|
73 |
+
}
|
74 |
+
}
|
vendor/mustache/mustache/src/Mustache/Cache.php
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Mustache.php.
|
5 |
+
*
|
6 |
+
* (c) 2010-2014 Justin Hileman
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Mustache Cache interface.
|
14 |
+
*
|
15 |
+
* Interface for caching and loading Mustache_Template classes
|
16 |
+
* generated by the Mustache_Compiler.
|
17 |
+
*/
|
18 |
+
interface Mustache_Cache
|
19 |
+
{
|
20 |
+
/**
|
21 |
+
* Load a compiled Mustache_Template class from cache.
|
22 |
+
*
|
23 |
+
* @param string $key
|
24 |
+
*
|
25 |
+
* @return boolean indicates successfully class load
|
26 |
+
*/
|
27 |
+
public function load($key);
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Cache and load a compiled Mustache_Template class.
|
31 |
+
*
|
32 |
+
* @param string $key
|
33 |
+
* @param string $value
|
34 |
+
*
|
35 |
+
* @return void
|
36 |
+
*/
|
37 |
+
public function cache($key, $value);
|
38 |
+
}
|
vendor/mustache/mustache/src/Mustache/Cache/AbstractCache.php
ADDED
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Mustache.php.
|
5 |
+
*
|
6 |
+
* (c) 2010-2014 Justin Hileman
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Abstract Mustache Cache class.
|
14 |
+
*
|
15 |
+
* Provides logging support to child implementations.
|
16 |
+
*
|
17 |
+
* @abstract
|
18 |
+
*/
|
19 |
+
abstract class Mustache_Cache_AbstractCache implements Mustache_Cache
|
20 |
+
{
|
21 |
+
private $logger = null;
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Get the current logger instance.
|
25 |
+
*
|
26 |
+
* @return Mustache_Logger|Psr\Log\LoggerInterface
|
27 |
+
*/
|
28 |
+
public function getLogger()
|
29 |
+
{
|
30 |
+
return $this->logger;
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Set a logger instance.
|
35 |
+
*
|
36 |
+
* @param Mustache_Logger|Psr\Log\LoggerInterface $logger
|
37 |
+
*/
|
38 |
+
public function setLogger($logger = null)
|
39 |
+
{
|
40 |
+
if ($logger !== null && !($logger instanceof Mustache_Logger || is_a($logger, 'Psr\\Log\\LoggerInterface'))) {
|
41 |
+
throw new Mustache_Exception_InvalidArgumentException('Expected an instance of Mustache_Logger or Psr\\Log\\LoggerInterface.');
|
42 |
+
}
|
43 |
+
|
44 |
+
$this->logger = $logger;
|
45 |
+
}
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Add a log record if logging is enabled.
|
49 |
+
*
|
50 |
+
* @param integer $level The logging level
|
51 |
+
* @param string $message The log message
|
52 |
+
* @param array $context The log context
|
53 |
+
*/
|
54 |
+
protected function log($level, $message, array $context = array())
|
55 |
+
{
|
56 |
+
if (isset($this->logger)) {
|
57 |
+
$this->logger->log($level, $message, $context);
|
58 |
+
}
|
59 |
+
}
|
60 |
+
}
|
vendor/mustache/mustache/src/Mustache/Cache/FilesystemCache.php
ADDED
@@ -0,0 +1,159 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Mustache.php.
|
5 |
+
*
|
6 |
+
* (c) 2010-2014 Justin Hileman
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Mustache Cache filesystem implementation.
|
14 |
+
*
|
15 |
+
* A FilesystemCache instance caches Mustache Template classes from the filesystem by name:
|
16 |
+
*
|
17 |
+
* $cache = new Mustache_Cache_FilesystemCache(dirname(__FILE__).'/cache');
|
18 |
+
* $cache->cache($className, $compiledSource);
|
19 |
+
*
|
20 |
+
* The FilesystemCache benefits from any opcode caching that may be setup in your environment. So do that, k?
|
21 |
+
*/
|
22 |
+
class Mustache_Cache_FilesystemCache extends Mustache_Cache_AbstractCache
|
23 |
+
{
|
24 |
+
private $baseDir;
|
25 |
+
private $fileMode;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Filesystem cache constructor.
|
29 |
+
*
|
30 |
+
* @param string $baseDir Directory for compiled templates.
|
31 |
+
* @param int $fileMode Override default permissions for cache files. Defaults to using the system-defined umask.
|
32 |
+
*/
|
33 |
+
public function __construct($baseDir, $fileMode = null)
|
34 |
+
{
|
35 |
+
$this->baseDir = $baseDir;
|
36 |
+
$this->fileMode = $fileMode;
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Load the class from cache using `require_once`.
|
41 |
+
*
|
42 |
+
* @param string $key
|
43 |
+
*
|
44 |
+
* @return boolean
|
45 |
+
*/
|
46 |
+
public function load($key)
|
47 |
+
{
|
48 |
+
$fileName = $this->getCacheFilename($key);
|
49 |
+
if (!is_file($fileName)) {
|
50 |
+
return false;
|
51 |
+
}
|
52 |
+
|
53 |
+
require_once $fileName;
|
54 |
+
|
55 |
+
return true;
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Cache and load the compiled class
|
60 |
+
*
|
61 |
+
* @param string $key
|
62 |
+
* @param string $value
|
63 |
+
*
|
64 |
+
* @return void
|
65 |
+
*/
|
66 |
+
public function cache($key, $value)
|
67 |
+
{
|
68 |
+
$fileName = $this->getCacheFilename($key);
|
69 |
+
|
70 |
+
$this->log(
|
71 |
+
Mustache_Logger::DEBUG,
|
72 |
+
'Writing to template cache: "{fileName}"',
|
73 |
+
array('fileName' => $fileName)
|
74 |
+
);
|
75 |
+
|
76 |
+
$this->writeFile($fileName, $value);
|
77 |
+
$this->load($key);
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Build the cache filename.
|
82 |
+
* Subclasses should override for custom cache directory structures.
|
83 |
+
*
|
84 |
+
* @param string $name
|
85 |
+
*
|
86 |
+
* @return string
|
87 |
+
*/
|
88 |
+
protected function getCacheFilename($name)
|
89 |
+
{
|
90 |
+
return sprintf('%s/%s.php', $this->baseDir, $name);
|
91 |
+
}
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Create cache directory
|
95 |
+
*
|
96 |
+
* @throws Mustache_Exception_RuntimeException If unable to create directory
|
97 |
+
*
|
98 |
+
* @param string $fileName
|
99 |
+
*
|
100 |
+
* @return string
|
101 |
+
*/
|
102 |
+
private function buildDirectoryForFilename($fileName)
|
103 |
+
{
|
104 |
+
$dirName = dirname($fileName);
|
105 |
+
if (!is_dir($dirName)) {
|
106 |
+
$this->log(
|
107 |
+
Mustache_Logger::INFO,
|
108 |
+
'Creating Mustache template cache directory: "{dirName}"',
|
109 |
+
array('dirName' => $dirName)
|
110 |
+
);
|
111 |
+
|
112 |
+
@mkdir($dirName, 0777, true);
|
113 |
+
if (!is_dir($dirName)) {
|
114 |
+
throw new Mustache_Exception_RuntimeException(sprintf('Failed to create cache directory "%s".', $dirName));
|
115 |
+
}
|
116 |
+
}
|
117 |
+
|
118 |
+
return $dirName;
|
119 |
+
}
|
120 |
+
|
121 |
+
/**
|
122 |
+
* Write cache file
|
123 |
+
*
|
124 |
+
* @throws Mustache_Exception_RuntimeException If unable to write file
|
125 |
+
*
|
126 |
+
* @param string $fileName
|
127 |
+
* @param string $value
|
128 |
+
*
|
129 |
+
* @return void
|
130 |
+
*/
|
131 |
+
private function writeFile($fileName, $value)
|
132 |
+
{
|
133 |
+
$dirName = $this->buildDirectoryForFilename($fileName);
|
134 |
+
|
135 |
+
$this->log(
|
136 |
+
Mustache_Logger::DEBUG,
|
137 |
+
'Caching compiled template to "{fileName}"',
|
138 |
+
array('fileName' => $fileName)
|
139 |
+
);
|
140 |
+
|
141 |
+
$tempFile = tempnam($dirName, basename($fileName));
|
142 |
+
if (false !== @file_put_contents($tempFile, $value)) {
|
143 |
+
if (@rename($tempFile, $fileName)) {
|
144 |
+
$mode = isset($this->fileMode) ? $this->fileMode : (0666 & ~umask());
|
145 |
+
@chmod($fileName, $mode);
|
146 |
+
|
147 |
+
return;
|
148 |
+
}
|
149 |
+
|
150 |
+
$this->log(
|
151 |
+
Mustache_Logger::ERROR,
|
152 |
+
'Unable to rename Mustache temp cache file: "{tempName}" -> "{fileName}"',
|
153 |
+
array('tempName' => $tempFile, 'fileName' => $fileName)
|
154 |
+
);
|
155 |
+
}
|
156 |
+
|
157 |
+
throw new Mustache_Exception_RuntimeException(sprintf('Failed to write cache file "%s".', $fileName));
|
158 |
+
}
|
159 |
+
}
|
vendor/mustache/mustache/src/Mustache/Cache/NoopCache.php
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Mustache.php.
|
5 |
+
*
|
6 |
+
* (c) 2010-2014 Justin Hileman
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Mustache Cache in-memory implementation.
|
14 |
+
*
|
15 |
+
* The in-memory cache is used for uncached lambda section templates. It's also useful during development, but is not
|
16 |
+
* recommended for production use.
|
17 |
+
*/
|
18 |
+
class Mustache_Cache_NoopCache extends Mustache_Cache_AbstractCache
|
19 |
+
{
|
20 |
+
/**
|
21 |
+
* Loads nothing. Move along.
|
22 |
+
*
|
23 |
+
* @param string $key
|
24 |
+
*
|
25 |
+
* @return boolean
|
26 |
+
*/
|
27 |
+
public function load($key)
|
28 |
+
{
|
29 |
+
return false;
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Loads the compiled Mustache Template class without caching.
|
34 |
+
*
|
35 |
+
* @param string $key
|
36 |
+
* @param string $value
|
37 |
+
*
|
38 |
+
* @return void
|
39 |
+
*/
|
40 |
+
public function cache($key, $value)
|
41 |
+
{
|
42 |
+
$this->log(
|
43 |
+
Mustache_Logger::WARNING,
|
44 |
+
'Template cache disabled, evaluating "{className}" class at runtime',
|
45 |
+
array('className' => $key)
|
46 |
+
);
|
47 |
+
eval('?>' . $value);
|
48 |
+
}
|
49 |
+
}
|
vendor/mustache/mustache/src/Mustache/Compiler.php
ADDED
@@ -0,0 +1,493 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Mustache.php.
|
5 |
+
*
|
6 |
+
* (c) 2010-2014 Justin Hileman
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Mustache Compiler class.
|
14 |
+
*
|
15 |
+
* This class is responsible for turning a Mustache token parse tree into normal PHP source code.
|
16 |
+
*/
|
17 |
+
class Mustache_Compiler
|
18 |
+
{
|
19 |
+
private $sections;
|
20 |
+
private $source;
|
21 |
+
private $indentNextLine;
|
22 |
+
private $customEscape;
|
23 |
+
private $entityFlags;
|
24 |
+
private $charset;
|
25 |
+
private $strictCallables;
|
26 |
+
private $pragmas;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Compile a Mustache token parse tree into PHP source code.
|
30 |
+
*
|
31 |
+
* @param string $source Mustache Template source code
|
32 |
+
* @param string $tree Parse tree of Mustache tokens
|
33 |
+
* @param string $name Mustache Template class name
|
34 |
+
* @param bool $customEscape (default: false)
|
35 |
+
* @param string $charset (default: 'UTF-8')
|
36 |
+
* @param bool $strictCallables (default: false)
|
37 |
+
* @param int $entityFlags (default: ENT_COMPAT)
|
38 |
+
*
|
39 |
+
* @return string Generated PHP source code
|
40 |
+
*/
|
41 |
+
public function compile($source, array $tree, $name, $customEscape = false, $charset = 'UTF-8', $strictCallables = false, $entityFlags = ENT_COMPAT)
|
42 |
+
{
|
43 |
+
$this->pragmas = array();
|
44 |
+
$this->sections = array();
|
45 |
+
$this->source = $source;
|
46 |
+
$this->indentNextLine = true;
|
47 |
+
$this->customEscape = $customEscape;
|
48 |
+
$this->entityFlags = $entityFlags;
|
49 |
+
$this->charset = $charset;
|
50 |
+
$this->strictCallables = $strictCallables;
|
51 |
+
|
52 |
+
return $this->writeCode($tree, $name);
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Helper function for walking the Mustache token parse tree.
|
57 |
+
*
|
58 |
+
* @throws Mustache_Exception_SyntaxException upon encountering unknown token types.
|
59 |
+
*
|
60 |
+
* @param array $tree Parse tree of Mustache tokens
|
61 |
+
* @param int $level (default: 0)
|
62 |
+
*
|
63 |
+
* @return string Generated PHP source code
|
64 |
+
*/
|
65 |
+
private function walk(array $tree, $level = 0)
|
66 |
+
{
|
67 |
+
$code = '';
|
68 |
+
$level++;
|
69 |
+
foreach ($tree as $node) {
|
70 |
+
switch ($node[Mustache_Tokenizer::TYPE]) {
|
71 |
+
case Mustache_Tokenizer::T_PRAGMA:
|
72 |
+
$this->pragmas[$node[Mustache_Tokenizer::NAME]] = true;
|
73 |
+
break;
|
74 |
+
|
75 |
+
case Mustache_Tokenizer::T_SECTION:
|
76 |
+
$code .= $this->section(
|
77 |
+
$node[Mustache_Tokenizer::NODES],
|
78 |
+
$node[Mustache_Tokenizer::NAME],
|
79 |
+
$node[Mustache_Tokenizer::INDEX],
|
80 |
+
$node[Mustache_Tokenizer::END],
|
81 |
+
$node[Mustache_Tokenizer::OTAG],
|
82 |
+
$node[Mustache_Tokenizer::CTAG],
|
83 |
+
$level
|
84 |
+
);
|
85 |
+
break;
|
86 |
+
|
87 |
+
case Mustache_Tokenizer::T_INVERTED:
|
88 |
+
$code .= $this->invertedSection(
|
89 |
+
$node[Mustache_Tokenizer::NODES],
|
90 |
+
$node[Mustache_Tokenizer::NAME],
|
91 |
+
$level
|
92 |
+
);
|
93 |
+
break;
|
94 |
+
|
95 |
+
case Mustache_Tokenizer::T_PARTIAL:
|
96 |
+
case Mustache_Tokenizer::T_PARTIAL_2:
|
97 |
+
$code .= $this->partial(
|
98 |
+
$node[Mustache_Tokenizer::NAME],
|
99 |
+
isset($node[Mustache_Tokenizer::INDENT]) ? $node[Mustache_Tokenizer::INDENT] : '',
|
100 |
+
$level
|
101 |
+
);
|
102 |
+
break;
|
103 |
+
|
104 |
+
case Mustache_Tokenizer::T_UNESCAPED:
|
105 |
+
case Mustache_Tokenizer::T_UNESCAPED_2:
|
106 |
+
$code .= $this->variable($node[Mustache_Tokenizer::NAME], false, $level);
|
107 |
+
break;
|
108 |
+
|
109 |
+
case Mustache_Tokenizer::T_COMMENT:
|
110 |
+
break;
|
111 |
+
|
112 |
+
case Mustache_Tokenizer::T_ESCAPED:
|
113 |
+
$code .= $this->variable($node[Mustache_Tokenizer::NAME], true, $level);
|
114 |
+
break;
|
115 |
+
|
116 |
+
case Mustache_Tokenizer::T_TEXT:
|
117 |
+
$code .= $this->text($node[Mustache_Tokenizer::VALUE], $level);
|
118 |
+
break;
|
119 |
+
|
120 |
+
default:
|
121 |
+
throw new Mustache_Exception_SyntaxException(sprintf('Unknown token type: %s', $node[Mustache_Tokenizer::TYPE]), $node);
|
122 |
+
}
|
123 |
+
}
|
124 |
+
|
125 |
+
return $code;
|
126 |
+
}
|
127 |
+
|
128 |
+
const KLASS = '<?php
|
129 |
+
|
130 |
+
class %s extends Mustache_Template
|
131 |
+
{
|
132 |
+
private $lambdaHelper;%s
|
133 |
+
|
134 |
+
public function renderInternal(Mustache_Context $context, $indent = \'\')
|
135 |
+
{
|
136 |
+
$this->lambdaHelper = new Mustache_LambdaHelper($this->mustache, $context);
|
137 |
+
$buffer = \'\';
|
138 |
+
%s
|
139 |
+
|
140 |
+
return $buffer;
|
141 |
+
}
|
142 |
+
%s
|
143 |
+
}';
|
144 |
+
|
145 |
+
const KLASS_NO_LAMBDAS = '<?php
|
146 |
+
|
147 |
+
class %s extends Mustache_Template
|
148 |
+
{%s
|
149 |
+
public function renderInternal(Mustache_Context $context, $indent = \'\')
|
150 |
+
{
|
151 |
+
$buffer = \'\';
|
152 |
+
%s
|
153 |
+
|
154 |
+
return $buffer;
|
155 |
+
}
|
156 |
+
}';
|
157 |
+
|
158 |
+
const STRICT_CALLABLE = 'protected $strictCallables = true;';
|
159 |
+
|
160 |
+
/**
|
161 |
+
* Generate Mustache Template class PHP source.
|
162 |
+
*
|
163 |
+
* @param array $tree Parse tree of Mustache tokens
|
164 |
+
* @param string $name Mustache Template class name
|
165 |
+
*
|
166 |
+
* @return string Generated PHP source code
|
167 |
+
*/
|
168 |
+
private function writeCode($tree, $name)
|
169 |
+
{
|
170 |
+
$code = $this->walk($tree);
|
171 |
+
$sections = implode("\n", $this->sections);
|
172 |
+
$klass = empty($this->sections) ? self::KLASS_NO_LAMBDAS : self::KLASS;
|
173 |
+
$callable = $this->strictCallables ? $this->prepare(self::STRICT_CALLABLE) : '';
|
174 |
+
|
175 |
+
return sprintf($this->prepare($klass, 0, false, true), $name, $callable, $code, $sections);
|
176 |
+
}
|
177 |
+
|
178 |
+
const SECTION_CALL = '
|
179 |
+
// %s section
|
180 |
+
$value = $context->%s(%s);%s
|
181 |
+
$buffer .= $this->section%s($context, $indent, $value);
|
182 |
+
';
|
183 |
+
|
184 |
+
const SECTION = '
|
185 |
+
private function section%s(Mustache_Context $context, $indent, $value)
|
186 |
+
{
|
187 |
+
$buffer = \'\';
|
188 |
+
if (%s) {
|
189 |
+
$source = %s;
|
190 |
+
$result = call_user_func($value, $source, $this->lambdaHelper);
|
191 |
+
if (strpos($result, \'{{\') === false) {
|
192 |
+
$buffer .= $result;
|
193 |
+
} else {
|
194 |
+
$buffer .= $this->mustache
|
195 |
+
->loadLambda((string) $result%s)
|
196 |
+
->renderInternal($context);
|
197 |
+
}
|
198 |
+
} elseif (!empty($value)) {
|
199 |
+
$values = $this->isIterable($value) ? $value : array($value);
|
200 |
+
foreach ($values as $value) {
|
201 |
+
$context->push($value);%s
|
202 |
+
$context->pop();
|
203 |
+
}
|
204 |
+
}
|
205 |
+
|
206 |
+
return $buffer;
|
207 |
+
}';
|
208 |
+
|
209 |
+
/**
|
210 |
+
* Generate Mustache Template section PHP source.
|
211 |
+
*
|
212 |
+
* @param array $nodes Array of child tokens
|
213 |
+
* @param string $id Section name
|
214 |
+
* @param int $start Section start offset
|
215 |
+
* @param int $end Section end offset
|
216 |
+
* @param string $otag Current Mustache opening tag
|
217 |
+
* @param string $ctag Current Mustache closing tag
|
218 |
+
* @param int $level
|
219 |
+
*
|
220 |
+
* @return string Generated section PHP source code
|
221 |
+
*/
|
222 |
+
private function section($nodes, $id, $start, $end, $otag, $ctag, $level)
|
223 |
+
{
|
224 |
+
$filters = '';
|
225 |
+
|
226 |
+
if (isset($this->pragmas[Mustache_Engine::PRAGMA_FILTERS])) {
|
227 |
+
list($id, $filters) = $this->getFilters($id, $level);
|
228 |
+
}
|
229 |
+
|
230 |
+
$method = $this->getFindMethod($id);
|
231 |
+
$id = var_export($id, true);
|
232 |
+
$source = var_export(substr($this->source, $start, $end - $start), true);
|
233 |
+
$callable = $this->getCallable();
|
234 |
+
|
235 |
+
if ($otag !== '{{' || $ctag !== '}}') {
|
236 |
+
$delims = ', '.var_export(sprintf('{{= %s %s =}}', $otag, $ctag), true);
|
237 |
+
} else {
|
238 |
+
$delims = '';
|
239 |
+
}
|
240 |
+
|
241 |
+
$key = ucfirst(md5($delims."\n".$source));
|
242 |
+
|
243 |
+
if (!isset($this->sections[$key])) {
|
244 |
+
$this->sections[$key] = sprintf($this->prepare(self::SECTION), $key, $callable, $source, $delims, $this->walk($nodes, 2));
|
245 |
+
}
|
246 |
+
|
247 |
+
return sprintf($this->prepare(self::SECTION_CALL, $level), $id, $method, $id, $filters, $key);
|
248 |
+
}
|
249 |
+
|
250 |
+
const INVERTED_SECTION = '
|
251 |
+
// %s inverted section
|
252 |
+
$value = $context->%s(%s);%s
|
253 |
+
if (empty($value)) {
|
254 |
+
%s
|
255 |
+
}';
|
256 |
+
|
257 |
+
/**
|
258 |
+
* Generate Mustache Template inverted section PHP source.
|
259 |
+
*
|
260 |
+
* @param array $nodes Array of child tokens
|
261 |
+
* @param string $id Section name
|
262 |
+
* @param int $level
|
263 |
+
*
|
264 |
+
* @return string Generated inverted section PHP source code
|
265 |
+
*/
|
266 |
+
private function invertedSection($nodes, $id, $level)
|
267 |
+
{
|
268 |
+
$filters = '';
|
269 |
+
|
270 |
+
if (isset($this->pragmas[Mustache_Engine::PRAGMA_FILTERS])) {
|
271 |
+
list($id, $filters) = $this->getFilters($id, $level);
|
272 |
+
}
|
273 |
+
|
274 |
+
$method = $this->getFindMethod($id);
|
275 |
+
$id = var_export($id, true);
|
276 |
+
|
277 |
+
return sprintf($this->prepare(self::INVERTED_SECTION, $level), $id, $method, $id, $filters, $this->walk($nodes, $level));
|
278 |
+
}
|
279 |
+
|
280 |
+
const PARTIAL = '
|
281 |
+
if ($partial = $this->mustache->loadPartial(%s)) {
|
282 |
+
$buffer .= $partial->renderInternal($context, $indent . %s);
|
283 |
+
}
|
284 |
+
';
|
285 |
+
|
286 |
+
/**
|
287 |
+
* Generate Mustache Template partial call PHP source.
|
288 |
+
*
|
289 |
+
* @param string $id Partial name
|
290 |
+
* @param string $indent Whitespace indent to apply to partial
|
291 |
+
* @param int $level
|
292 |
+
*
|
293 |
+
* @return string Generated partial call PHP source code
|
294 |
+
*/
|
295 |
+
private function partial($id, $indent, $level)
|
296 |
+
{
|
297 |
+
return sprintf(
|
298 |
+
$this->prepare(self::PARTIAL, $level),
|
299 |
+
var_export($id, true),
|
300 |
+
var_export($indent, true)
|
301 |
+
);
|
302 |
+
}
|
303 |
+
|
304 |
+
const VARIABLE = '
|
305 |
+
$value = $this->resolveValue($context->%s(%s), $context, $indent);%s
|
306 |
+
$buffer .= %s%s;
|
307 |
+
';
|
308 |
+
|
309 |
+
/**
|
310 |
+
* Generate Mustache Template variable interpolation PHP source.
|
311 |
+
*
|
312 |
+
* @param string $id Variable name
|
313 |
+
* @param boolean $escape Escape the variable value for output?
|
314 |
+
* @param int $level
|
315 |
+
*
|
316 |
+
* @return string Generated variable interpolation PHP source
|
317 |
+
*/
|
318 |
+
private function variable($id, $escape, $level)
|
319 |
+
{
|
320 |
+
$filters = '';
|
321 |
+
|
322 |
+
if (isset($this->pragmas[Mustache_Engine::PRAGMA_FILTERS])) {
|
323 |
+
list($id, $filters) = $this->getFilters($id, $level);
|
324 |
+
}
|
325 |
+
|
326 |
+
$method = $this->getFindMethod($id);
|
327 |
+
$id = ($method !== 'last') ? var_export($id, true) : '';
|
328 |
+
$value = $escape ? $this->getEscape() : '$value';
|
329 |
+
|
330 |
+
return sprintf($this->prepare(self::VARIABLE, $level), $method, $id, $filters, $this->flushIndent(), $value);
|
331 |
+
}
|
332 |
+
|
333 |
+
/**
|
334 |
+
* Generate Mustache Template variable filtering PHP source.
|
335 |
+
*
|
336 |
+
* @param string $id Variable name
|
337 |
+
* @param int $level
|
338 |
+
*
|
339 |
+
* @return string Generated variable filtering PHP source
|
340 |
+
*/
|
341 |
+
private function getFilters($id, $level)
|
342 |
+
{
|
343 |
+
$filters = array_map('trim', explode('|', $id));
|
344 |
+
$id = array_shift($filters);
|
345 |
+
|
346 |
+
return array($id, $this->getFilter($filters, $level));
|
347 |
+
}
|
348 |
+
|
349 |
+
const FILTER = '
|
350 |
+
$filter = $context->%s(%s);
|
351 |
+
if (!(%s)) {
|
352 |
+
throw new Mustache_Exception_UnknownFilterException(%s);
|
353 |
+
}
|
354 |
+
$value = call_user_func($filter, $value);%s
|
355 |
+
';
|
356 |
+
|
357 |
+
/**
|
358 |
+
* Generate PHP source for a single filter.
|
359 |
+
*
|
360 |
+
* @param array $filters
|
361 |
+
* @param int $level
|
362 |
+
*
|
363 |
+
* @return string Generated filter PHP source
|
364 |
+
*/
|
365 |
+
private function getFilter(array $filters, $level)
|
366 |
+
{
|
367 |
+
if (empty($filters)) {
|
368 |
+
return '';
|
369 |
+
}
|
370 |
+
|
371 |
+
$name = array_shift($filters);
|
372 |
+
$method = $this->getFindMethod($name);
|
373 |
+
$filter = ($method !== 'last') ? var_export($name, true) : '';
|
374 |
+
$callable = $this->getCallable('$filter');
|
375 |
+
$msg = var_export($name, true);
|
376 |
+
|
377 |
+
return sprintf($this->prepare(self::FILTER, $level), $method, $filter, $callable, $msg, $this->getFilter($filters, $level));
|
378 |
+
}
|
379 |
+
|
380 |
+
const LINE = '$buffer .= "\n";';
|
381 |
+
const TEXT = '$buffer .= %s%s;';
|
382 |
+
|
383 |
+
/**
|
384 |
+
* Generate Mustache Template output Buffer call PHP source.
|
385 |
+
*
|
386 |
+
* @param string $text
|
387 |
+
* @param int $level
|
388 |
+
*
|
389 |
+
* @return string Generated output Buffer call PHP source
|
390 |
+
*/
|
391 |
+
private function text($text, $level)
|
392 |
+
{
|
393 |
+
$indentNextLine = (substr($text, -1) === "\n");
|
394 |
+
$code = sprintf($this->prepare(self::TEXT, $level), $this->flushIndent(), var_export($text, true));
|
395 |
+
$this->indentNextLine = $indentNextLine;
|
396 |
+
|
397 |
+
return $code;
|
398 |
+
}
|
399 |
+
|
400 |
+
/**
|
401 |
+
* Prepare PHP source code snippet for output.
|
402 |
+
*
|
403 |
+
* @param string $text
|
404 |
+
* @param int $bonus Additional indent level (default: 0)
|
405 |
+
* @param boolean $prependNewline Prepend a newline to the snippet? (default: true)
|
406 |
+
* @param boolean $appendNewline Append a newline to the snippet? (default: false)
|
407 |
+
*
|
408 |
+
* @return string PHP source code snippet
|
409 |
+
*/
|
410 |
+
private function prepare($text, $bonus = 0, $prependNewline = true, $appendNewline = false)
|
411 |
+
{
|
412 |
+
$text = ($prependNewline ? "\n" : '').trim($text);
|
413 |
+
if ($prependNewline) {
|
414 |
+
$bonus++;
|
415 |
+
}
|
416 |
+
if ($appendNewline) {
|
417 |
+
$text .= "\n";
|
418 |
+
}
|
419 |
+
|
420 |
+
return preg_replace("/\n( {8})?/", "\n".str_repeat(" ", $bonus * 4), $text);
|
421 |
+
}
|
422 |
+
|
423 |
+
const DEFAULT_ESCAPE = 'htmlspecialchars(%s, %s, %s)';
|
424 |
+
const CUSTOM_ESCAPE = 'call_user_func($this->mustache->getEscape(), %s)';
|
425 |
+
|
426 |
+
/**
|
427 |
+
* Get the current escaper.
|
428 |
+
*
|
429 |
+
* @param string $value (default: '$value')
|
430 |
+
*
|
431 |
+
* @return string Either a custom callback, or an inline call to `htmlspecialchars`
|
432 |
+
*/
|
433 |
+
private function getEscape($value = '$value')
|
434 |
+
{
|
435 |
+
if ($this->customEscape) {
|
436 |
+
return sprintf(self::CUSTOM_ESCAPE, $value);
|
437 |
+
} else {
|
438 |
+
return sprintf(self::DEFAULT_ESCAPE, $value, var_export($this->entityFlags, true), var_export($this->charset, true));
|
439 |
+
}
|
440 |
+
}
|
441 |
+
|
442 |
+
/**
|
443 |
+
* Select the appropriate Context `find` method for a given $id.
|
444 |
+
*
|
445 |
+
* The return value will be one of `find`, `findDot` or `last`.
|
446 |
+
*
|
447 |
+
* @see Mustache_Context::find
|
448 |
+
* @see Mustache_Context::findDot
|
449 |
+
* @see Mustache_Context::last
|
450 |
+
*
|
451 |
+
* @param string $id Variable name
|
452 |
+
*
|
453 |
+
* @return string `find` method name
|
454 |
+
*/
|
455 |
+
private function getFindMethod($id)
|
456 |
+
{
|
457 |
+
if ($id === '.') {
|
458 |
+
return 'last';
|
459 |
+
} elseif (strpos($id, '.') === false) {
|
460 |
+
return 'find';
|
461 |
+
} else {
|
462 |
+
return 'findDot';
|
463 |
+
}
|
464 |
+
}
|
465 |
+
|
466 |
+
const IS_CALLABLE = '!is_string(%s) && is_callable(%s)';
|
467 |
+
const STRICT_IS_CALLABLE = 'is_object(%s) && is_callable(%s)';
|
468 |
+
|
469 |
+
private function getCallable($variable = '$value')
|
470 |
+
{
|
471 |
+
$tpl = $this->strictCallables ? self::STRICT_IS_CALLABLE : self::IS_CALLABLE;
|
472 |
+
|
473 |
+
return sprintf($tpl, $variable, $variable);
|
474 |
+
}
|
475 |
+
|
476 |
+
const LINE_INDENT = '$indent . ';
|
477 |
+
|
478 |
+
/**
|
479 |
+
* Get the current $indent prefix to write to the buffer.
|
480 |
+
*
|
481 |
+
* @return string "$indent . " or ""
|
482 |
+
*/
|
483 |
+
private function flushIndent()
|
484 |
+
{
|
485 |
+
if (!$this->indentNextLine) {
|
486 |
+
return '';
|
487 |
+
}
|
488 |
+
|
489 |
+
$this->indentNextLine = false;
|
490 |
+
|
491 |
+
return self::LINE_INDENT;
|
492 |
+
}
|
493 |
+
}
|
vendor/mustache/mustache/src/Mustache/Context.php
ADDED
@@ -0,0 +1,154 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Mustache.php.
|
5 |
+
*
|
6 |
+
* (c) 2010-2014 Justin Hileman
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Mustache Template rendering Context.
|
14 |
+
*/
|
15 |
+
class Mustache_Context
|
16 |
+
{
|
17 |
+
private $stack = array();
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Mustache rendering Context constructor.
|
21 |
+
*
|
22 |
+
* @param mixed $context Default rendering context (default: null)
|
23 |
+
*/
|
24 |
+
public function __construct($context = null)
|
25 |
+
{
|
26 |
+
if ($context !== null) {
|
27 |
+
$this->stack = array($context);
|
28 |
+
}
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Push a new Context frame onto the stack.
|
33 |
+
*
|
34 |
+
* @param mixed $value Object or array to use for context
|
35 |
+
*/
|
36 |
+
public function push($value)
|
37 |
+
{
|
38 |
+
array_push($this->stack, $value);
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Pop the last Context frame from the stack.
|
43 |
+
*
|
44 |
+
* @return mixed Last Context frame (object or array)
|
45 |
+
*/
|
46 |
+
public function pop()
|
47 |
+
{
|
48 |
+
return array_pop($this->stack);
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Get the last Context frame.
|
53 |
+
*
|
54 |
+
* @return mixed Last Context frame (object or array)
|
55 |
+
*/
|
56 |
+
public function last()
|
57 |
+
{
|
58 |
+
return end($this->stack);
|
59 |
+
}
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Find a variable in the Context stack.
|
63 |
+
*
|
64 |
+
* Starting with the last Context frame (the context of the innermost section), and working back to the top-level
|
65 |
+
* rendering context, look for a variable with the given name:
|
66 |
+
*
|
67 |
+
* * If the Context frame is an associative array which contains the key $id, returns the value of that element.
|
68 |
+
* * If the Context frame is an object, this will check first for a public method, then a public property named
|
69 |
+
* $id. Failing both of these, it will try `__isset` and `__get` magic methods.
|
70 |
+
* * If a value named $id is not found in any Context frame, returns an empty string.
|
71 |
+
*
|
72 |
+
* @param string $id Variable name
|
73 |
+
*
|
74 |
+
* @return mixed Variable value, or '' if not found
|
75 |
+
*/
|
76 |
+
public function find($id)
|
77 |
+
{
|
78 |
+
return $this->findVariableInStack($id, $this->stack);
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Find a 'dot notation' variable in the Context stack.
|
83 |
+
*
|
84 |
+
* Note that dot notation traversal bubbles through scope differently than the regular find method. After finding
|
85 |
+
* the initial chunk of the dotted name, each subsequent chunk is searched for only within the value of the previous
|
86 |
+
* result. For example, given the following context stack:
|
87 |
+
*
|
88 |
+
* $data = array(
|
89 |
+
* 'name' => 'Fred',
|
90 |
+
* 'child' => array(
|
91 |
+
* 'name' => 'Bob'
|
92 |
+
* ),
|
93 |
+
* );
|
94 |
+
*
|
95 |
+
* ... and the Mustache following template:
|
96 |
+
*
|
97 |
+
* {{ child.name }}
|
98 |
+
*
|
99 |
+
* ... the `name` value is only searched for within the `child` value of the global Context, not within parent
|
100 |
+
* Context frames.
|
101 |
+
*
|
102 |
+
* @param string $id Dotted variable selector
|
103 |
+
*
|
104 |
+
* @return mixed Variable value, or '' if not found
|
105 |
+
*/
|
106 |
+
public function findDot($id)
|
107 |
+
{
|
108 |
+
$chunks = explode('.', $id);
|
109 |
+
$first = array_shift($chunks);
|
110 |
+
$value = $this->findVariableInStack($first, $this->stack);
|
111 |
+
|
112 |
+
foreach ($chunks as $chunk) {
|
113 |
+
if ($value === '') {
|
114 |
+
return $value;
|
115 |
+
}
|
116 |
+
|
117 |
+
$value = $this->findVariableInStack($chunk, array($value));
|
118 |
+
}
|
119 |
+
|
120 |
+
return $value;
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Helper function to find a variable in the Context stack.
|
125 |
+
*
|
126 |
+
* @see Mustache_Context::find
|
127 |
+
*
|
128 |
+
* @param string $id Variable name
|
129 |
+
* @param array $stack Context stack
|
130 |
+
*
|
131 |
+
* @return mixed Variable value, or '' if not found
|
132 |
+
*/
|
133 |
+
private function findVariableInStack($id, array $stack)
|
134 |
+
{
|
135 |
+
for ($i = count($stack) - 1; $i >= 0; $i--) {
|
136 |
+
if (is_object($stack[$i]) && !($stack[$i] instanceof Closure)) {
|
137 |
+
|
138 |
+
// Note that is_callable() *will not work here*
|
139 |
+
// See https://github.com/bobthecow/mustache.php/wiki/Magic-Methods
|
140 |
+
if (method_exists($stack[$i], $id)) {
|
141 |
+
return $stack[$i]->$id();
|
142 |
+
} elseif (isset($stack[$i]->$id)) {
|
143 |
+
return $stack[$i]->$id;
|
144 |
+
} elseif ($stack[$i] instanceof ArrayAccess && isset($stack[$i][$id])) {
|
145 |
+
return $stack[$i][$id];
|
146 |
+
}
|
147 |
+
} elseif (is_array($stack[$i]) && array_key_exists($id, $stack[$i])) {
|
148 |
+
return $stack[$i][$id];
|
149 |
+
}
|
150 |
+
}
|
151 |
+
|
152 |
+
return '';
|
153 |
+
}
|
154 |
+
}
|
vendor/mustache/mustache/src/Mustache/Engine.php
ADDED
@@ -0,0 +1,747 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Mustache.php.
|
5 |
+
*
|
6 |
+
* (c) 2010-2014 Justin Hileman
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* A Mustache implementation in PHP.
|
14 |
+
*
|
15 |
+
* {@link http://defunkt.github.com/mustache}
|
16 |
+
*
|
17 |
+
* Mustache is a framework-agnostic logic-less templating language. It enforces separation of view
|
18 |
+
* logic from template files. In fact, it is not even possible to embed logic in the template.
|
19 |
+
*
|
20 |
+
* This is very, very rad.
|
21 |
+
*
|
22 |
+
* @author Justin Hileman {@link http://justinhileman.com}
|
23 |
+
*/
|
24 |
+
class Mustache_Engine
|
25 |
+
{
|
26 |
+
const VERSION = '2.6.1';
|
27 |
+
const SPEC_VERSION = '1.1.2';
|
28 |
+
|
29 |
+
const PRAGMA_FILTERS = 'FILTERS';
|
30 |
+
|
31 |
+
// Template cache
|
32 |
+
private $templates = array();
|
33 |
+
|
34 |
+
// Environment
|
35 |
+
private $templateClassPrefix = '__Mustache_';
|
36 |
+
private $cache;
|
37 |
+
private $lambdaCache;
|
38 |
+
private $cacheLambdaTemplates = false;
|
39 |
+
private $loader;
|
40 |
+
private $partialsLoader;
|
41 |
+
private $helpers;
|
42 |
+
private $escape;
|
43 |
+
private $entityFlags = ENT_COMPAT;
|
44 |
+
private $charset = 'UTF-8';
|
45 |
+
private $logger;
|
46 |
+
private $strictCallables = false;
|
47 |
+
|
48 |
+
// Services
|
49 |
+
private $tokenizer;
|
50 |
+
private $parser;
|
51 |
+
private $compiler;
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Mustache class constructor.
|
55 |
+
*
|
56 |
+
* Passing an $options array allows overriding certain Mustache options during instantiation:
|
57 |
+
*
|
58 |
+
* $options = array(
|
59 |
+
* // The class prefix for compiled templates. Defaults to '__Mustache_'.
|
60 |
+
* 'template_class_prefix' => '__MyTemplates_',
|
61 |
+
*
|
62 |
+
* // A Mustache cache instance or a cache directory string for compiled templates.
|
63 |
+
* // Mustache will not cache templates unless this is set.
|
64 |
+
* 'cache' => dirname(__FILE__).'/tmp/cache/mustache',
|
65 |
+
*
|
66 |
+
* // Override default permissions for cache files. Defaults to using the system-defined umask. It is
|
67 |
+
* // *strongly* recommended that you configure your umask properly rather than overriding permissions here.
|
68 |
+
* 'cache_file_mode' => 0666,
|
69 |
+
*
|
70 |
+
* // Optionally, enable caching for lambda section templates. This is generally not recommended, as lambda
|
71 |
+
* // sections are often too dynamic to benefit from caching.
|
72 |
+
* 'cache_lambda_templates' => true,
|
73 |
+
*
|
74 |
+
* // A Mustache template loader instance. Uses a StringLoader if not specified.
|
75 |
+
* 'loader' => new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views'),
|
76 |
+
*
|
77 |
+
* // A Mustache loader instance for partials.
|
78 |
+
* 'partials_loader' => new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views/partials'),
|
79 |
+
*
|
80 |
+
* // An array of Mustache partials. Useful for quick-and-dirty string template loading, but not as
|
81 |
+
* // efficient or lazy as a Filesystem (or database) loader.
|
82 |
+
* 'partials' => array('foo' => file_get_contents(dirname(__FILE__).'/views/partials/foo.mustache')),
|
83 |
+
*
|
84 |
+
* // An array of 'helpers'. Helpers can be global variables or objects, closures (e.g. for higher order
|
85 |
+
* // sections), or any other valid Mustache context value. They will be prepended to the context stack,
|
86 |
+
* // so they will be available in any template loaded by this Mustache instance.
|
87 |
+
* 'helpers' => array('i18n' => function ($text) {
|
88 |
+
* // do something translatey here...
|
89 |
+
* }),
|
90 |
+
*
|
91 |
+
* // An 'escape' callback, responsible for escaping double-mustache variables.
|
92 |
+
* 'escape' => function ($value) {
|
93 |
+
* return htmlspecialchars($buffer, ENT_COMPAT, 'UTF-8');
|
94 |
+
* },
|
95 |
+
*
|
96 |
+
* // Type argument for `htmlspecialchars`. Defaults to ENT_COMPAT. You may prefer ENT_QUOTES.
|
97 |
+
* 'entity_flags' => ENT_QUOTES,
|
98 |
+
*
|
99 |
+
* // Character set for `htmlspecialchars`. Defaults to 'UTF-8'. Use 'UTF-8'.
|
100 |
+
* 'charset' => 'ISO-8859-1',
|
101 |
+
*
|
102 |
+
* // A Mustache Logger instance. No logging will occur unless this is set. Using a PSR-3 compatible
|
103 |
+
* // logging library -- such as Monolog -- is highly recommended. A simple stream logger implementation is
|
104 |
+
* // available as well:
|
105 |
+
* 'logger' => new Mustache_Logger_StreamLogger('php://stderr'),
|
106 |
+
*
|
107 |
+
* // Only treat Closure instances and invokable classes as callable. If true, values like
|
108 |
+
* // `array('ClassName', 'methodName')` and `array($classInstance, 'methodName')`, which are traditionally
|
109 |
+
* // "callable" in PHP, are not called to resolve variables for interpolation or section contexts. This
|
110 |
+
* // helps protect against arbitrary code execution when user input is passed directly into the template.
|
111 |
+
* // This currently defaults to false, but will default to true in v3.0.
|
112 |
+
* 'strict_callables' => true,
|
113 |
+
* );
|
114 |
+
*
|
115 |
+
* @throws Mustache_Exception_InvalidArgumentException If `escape` option is not callable.
|
116 |
+
*
|
117 |
+
* @param array $options (default: array())
|
118 |
+
*/
|
119 |
+
public function __construct(array $options = array())
|
120 |
+
{
|
121 |
+
if (isset($options['template_class_prefix'])) {
|
122 |
+
$this->templateClassPrefix = $options['template_class_prefix'];
|
123 |
+
}
|
124 |
+
|
125 |
+
if (isset($options['cache'])) {
|
126 |
+
$cache = $options['cache'];
|
127 |
+
|
128 |
+
if (is_string($cache)) {
|
129 |
+
$mode = isset($options['cache_file_mode']) ? $options['cache_file_mode'] : null;
|
130 |
+
$cache = new Mustache_Cache_FilesystemCache($cache, $mode);
|
131 |
+
}
|
132 |
+
|
133 |
+
$this->setCache($cache);
|
134 |
+
}
|
135 |
+
|
136 |
+
if (isset($options['cache_lambda_templates'])) {
|
137 |
+
$this->cacheLambdaTemplates = (bool) $options['cache_lambda_templates'];
|
138 |
+
}
|
139 |
+
|
140 |
+
if (isset($options['loader'])) {
|
141 |
+
$this->setLoader($options['loader']);
|
142 |
+
}
|
143 |
+
|
144 |
+
if (isset($options['partials_loader'])) {
|
145 |
+
$this->setPartialsLoader($options['partials_loader']);
|
146 |
+
}
|
147 |
+
|
148 |
+
if (isset($options['partials'])) {
|
149 |
+
$this->setPartials($options['partials']);
|
150 |
+
}
|
151 |
+
|
152 |
+
if (isset($options['helpers'])) {
|
153 |
+
$this->setHelpers($options['helpers']);
|
154 |
+
}
|
155 |
+
|
156 |
+
if (isset($options['escape'])) {
|
157 |
+
if (!is_callable($options['escape'])) {
|
158 |
+
throw new Mustache_Exception_InvalidArgumentException('Mustache Constructor "escape" option must be callable');
|
159 |
+
}
|
160 |
+
|
161 |
+
$this->escape = $options['escape'];
|
162 |
+
}
|
163 |
+
|
164 |
+
if (isset($options['entity_flags'])) {
|
165 |
+
$this->entityFlags = $options['entity_flags'];
|
166 |
+
}
|
167 |
+
|
168 |
+
if (isset($options['charset'])) {
|
169 |
+
$this->charset = $options['charset'];
|
170 |
+
}
|
171 |
+
|
172 |
+
if (isset($options['logger'])) {
|
173 |
+
$this->setLogger($options['logger']);
|
174 |
+
}
|
175 |
+
|
176 |
+
if (isset($options['strict_callables'])) {
|
177 |
+
$this->strictCallables = $options['strict_callables'];
|
178 |
+
}
|
179 |
+
}
|
180 |
+
|
181 |
+
/**
|
182 |
+
* Shortcut 'render' invocation.
|
183 |
+
*
|
184 |
+
* Equivalent to calling `$mustache->loadTemplate($template)->render($context);`
|
185 |
+
*
|
186 |
+
* @see Mustache_Engine::loadTemplate
|
187 |
+
* @see Mustache_Template::render
|
188 |
+
*
|
189 |
+
* @param string $template
|
190 |
+
* @param mixed $context (default: array())
|
191 |
+
*
|
192 |
+
* @return string Rendered template
|
193 |
+
*/
|
194 |
+
public function render($template, $context = array())
|
195 |
+
{
|
196 |
+
return $this->loadTemplate($template)->render($context);
|
197 |
+
}
|
198 |
+
|
199 |
+
/**
|
200 |
+
* Get the current Mustache escape callback.
|
201 |
+
*
|
202 |
+
* @return callable|null
|
203 |
+
*/
|
204 |
+
public function getEscape()
|
205 |
+
{
|
206 |
+
return $this->escape;
|
207 |
+
}
|
208 |
+
|
209 |
+
/**
|
210 |
+
* Get the current Mustache entitity type to escape.
|
211 |
+
*
|
212 |
+
* @return int
|
213 |
+
*/
|
214 |
+
public function getEntityFlags()
|
215 |
+
{
|
216 |
+
return $this->entityFlags;
|
217 |
+
}
|
218 |
+
|
219 |
+
/**
|
220 |
+
* Get the current Mustache character set.
|
221 |
+
*
|
222 |
+
* @return string
|
223 |
+
*/
|
224 |
+
public function getCharset()
|
225 |
+
{
|
226 |
+
return $this->charset;
|
227 |
+
}
|
228 |
+
|
229 |
+
/**
|
230 |
+
* Set the Mustache template Loader instance.
|
231 |
+
*
|
232 |
+
* @param Mustache_Loader $loader
|
233 |
+
*/
|
234 |
+
public function setLoader(Mustache_Loader $loader)
|
235 |
+
{
|
236 |
+
$this->loader = $loader;
|
237 |
+
}
|
238 |
+
|
239 |
+
/**
|
240 |
+
* Get the current Mustache template Loader instance.
|
241 |
+
*
|
242 |
+
* If no Loader instance has been explicitly specified, this method will instantiate and return
|
243 |
+
* a StringLoader instance.
|
244 |
+
*
|
245 |
+
* @return Mustache_Loader
|
246 |
+
*/
|
247 |
+
public function getLoader()
|
248 |
+
{
|
249 |
+
if (!isset($this->loader)) {
|
250 |
+
$this->loader = new Mustache_Loader_StringLoader;
|
251 |
+
}
|
252 |
+
|
253 |
+
return $this->loader;
|
254 |
+
}
|
255 |
+
|
256 |
+
/**
|
257 |
+
* Set the Mustache partials Loader instance.
|
258 |
+
*
|
259 |
+
* @param Mustache_Loader $partialsLoader
|
260 |
+
*/
|
261 |
+
public function setPartialsLoader(Mustache_Loader $partialsLoader)
|
262 |
+
{
|
263 |
+
$this->partialsLoader = $partialsLoader;
|
264 |
+
}
|
265 |
+
|
266 |
+
/**
|
267 |
+
* Get the current Mustache partials Loader instance.
|
268 |
+
*
|
269 |
+
* If no Loader instance has been explicitly specified, this method will instantiate and return
|
270 |
+
* an ArrayLoader instance.
|
271 |
+
*
|
272 |
+
* @return Mustache_Loader
|
273 |
+
*/
|
274 |
+
public function getPartialsLoader()
|
275 |
+
{
|
276 |
+
if (!isset($this->partialsLoader)) {
|
277 |
+
$this->partialsLoader = new Mustache_Loader_ArrayLoader;
|
278 |
+
}
|
279 |
+
|
280 |
+
return $this->partialsLoader;
|
281 |
+
}
|
282 |
+
|
283 |
+
/**
|
284 |
+
* Set partials for the current partials Loader instance.
|
285 |
+
*
|
286 |
+
* @throws Mustache_Exception_RuntimeException If the current Loader instance is immutable
|
287 |
+
*
|
288 |
+
* @param array $partials (default: array())
|
289 |
+
*/
|
290 |
+
public function setPartials(array $partials = array())
|
291 |
+
{
|
292 |
+
if (!isset($this->partialsLoader)) {
|
293 |
+
$this->partialsLoader = new Mustache_Loader_ArrayLoader;
|
294 |
+
}
|
295 |
+
|
296 |
+
if (!$this->partialsLoader instanceof Mustache_Loader_MutableLoader) {
|
297 |
+
throw new Mustache_Exception_RuntimeException('Unable to set partials on an immutable Mustache Loader instance');
|
298 |
+
}
|
299 |
+
|
300 |
+
$this->partialsLoader->setTemplates($partials);
|
301 |
+
}
|
302 |
+
|
303 |
+
/**
|
304 |
+
* Set an array of Mustache helpers.
|
305 |
+
*
|
306 |
+
* An array of 'helpers'. Helpers can be global variables or objects, closures (e.g. for higher order sections), or
|
307 |
+
* any other valid Mustache context value. They will be prepended to the context stack, so they will be available in
|
308 |
+
* any template loaded by this Mustache instance.
|
309 |
+
*
|
310 |
+
* @throws Mustache_Exception_InvalidArgumentException if $helpers is not an array or Traversable
|
311 |
+
*
|
312 |
+
* @param array|Traversable $helpers
|
313 |
+
*/
|
314 |
+
public function setHelpers($helpers)
|
315 |
+
{
|
316 |
+
if (!is_array($helpers) && !$helpers instanceof Traversable) {
|
317 |
+
throw new Mustache_Exception_InvalidArgumentException('setHelpers expects an array of helpers');
|
318 |
+
}
|
319 |
+
|
320 |
+
$this->getHelpers()->clear();
|
321 |
+
|
322 |
+
foreach ($helpers as $name => $helper) {
|
323 |
+
$this->addHelper($name, $helper);
|
324 |
+
}
|
325 |
+
}
|
326 |
+
|
327 |
+
/**
|
328 |
+
* Get the current set of Mustache helpers.
|
329 |
+
*
|
330 |
+
* @see Mustache_Engine::setHelpers
|
331 |
+
*
|
332 |
+
* @return Mustache_HelperCollection
|
333 |
+
*/
|
334 |
+
public function getHelpers()
|
335 |
+
{
|
336 |
+
if (!isset($this->helpers)) {
|
337 |
+
$this->helpers = new Mustache_HelperCollection;
|
338 |
+
}
|
339 |
+
|
340 |
+
return $this->helpers;
|
341 |
+
}
|
342 |
+
|
343 |
+
/**
|
344 |
+
* Add a new Mustache helper.
|
345 |
+
*
|
346 |
+
* @see Mustache_Engine::setHelpers
|
347 |
+
*
|
348 |
+
* @param string $name
|
349 |
+
* @param mixed $helper
|
350 |
+
*/
|
351 |
+
public function addHelper($name, $helper)
|
352 |
+
{
|
353 |
+
$this->getHelpers()->add($name, $helper);
|
354 |
+
}
|
355 |
+
|
356 |
+
/**
|
357 |
+
* Get a Mustache helper by name.
|
358 |
+
*
|
359 |
+
* @see Mustache_Engine::setHelpers
|
360 |
+
*
|
361 |
+
* @param string $name
|
362 |
+
*
|
363 |
+
* @return mixed Helper
|
364 |
+
*/
|
365 |
+
public function getHelper($name)
|
366 |
+
{
|
367 |
+
return $this->getHelpers()->get($name);
|
368 |
+
}
|
369 |
+
|
370 |
+
/**
|
371 |
+
* Check whether this Mustache instance has a helper.
|
372 |
+
*
|
373 |
+
* @see Mustache_Engine::setHelpers
|
374 |
+
*
|
375 |
+
* @param string $name
|
376 |
+
*
|
377 |
+
* @return boolean True if the helper is present
|
378 |
+
*/
|
379 |
+
public function hasHelper($name)
|
380 |
+
{
|
381 |
+
return $this->getHelpers()->has($name);
|
382 |
+
}
|
383 |
+
|
384 |
+
/**
|
385 |
+
* Remove a helper by name.
|
386 |
+
*
|
387 |
+
* @see Mustache_Engine::setHelpers
|
388 |
+
*
|
389 |
+
* @param string $name
|
390 |
+
*/
|
391 |
+
public function removeHelper($name)
|
392 |
+
{
|
393 |
+
$this->getHelpers()->remove($name);
|
394 |
+
}
|
395 |
+
|
396 |
+
/**
|
397 |
+
* Set the Mustache Logger instance.
|
398 |
+
*
|
399 |
+
* @throws Mustache_Exception_InvalidArgumentException If logger is not an instance of Mustache_Logger or Psr\Log\LoggerInterface.
|
400 |
+
*
|
401 |
+
* @param Mustache_Logger|Psr\Log\LoggerInterface $logger
|
402 |
+
*/
|
403 |
+
public function setLogger($logger = null)
|
404 |
+
{
|
405 |
+
if ($logger !== null && !($logger instanceof Mustache_Logger || is_a($logger, 'Psr\\Log\\LoggerInterface'))) {
|
406 |
+
throw new Mustache_Exception_InvalidArgumentException('Expected an instance of Mustache_Logger or Psr\\Log\\LoggerInterface.');
|
407 |
+
}
|
408 |
+
|
409 |
+
if ($this->getCache()->getLogger() === null) {
|
410 |
+
$this->getCache()->setLogger($logger);
|
411 |
+
}
|
412 |
+
|
413 |
+
$this->logger = $logger;
|
414 |
+
}
|
415 |
+
|
416 |
+
/**
|
417 |
+
* Get the current Mustache Logger instance.
|
418 |
+
*
|
419 |
+
* @return Mustache_Logger|Psr\Log\LoggerInterface
|
420 |
+
*/
|
421 |
+
public function getLogger()
|
422 |
+
{
|
423 |
+
return $this->logger;
|
424 |
+
}
|
425 |
+
|
426 |
+
/**
|
427 |
+
* Set the Mustache Tokenizer instance.
|
428 |
+
*
|
429 |
+
* @param Mustache_Tokenizer $tokenizer
|
430 |
+
*/
|
431 |
+
public function setTokenizer(Mustache_Tokenizer $tokenizer)
|
432 |
+
{
|
433 |
+
$this->tokenizer = $tokenizer;
|
434 |
+
}
|
435 |
+
|
436 |
+
/**
|
437 |
+
* Get the current Mustache Tokenizer instance.
|
438 |
+
*
|
439 |
+
* If no Tokenizer instance has been explicitly specified, this method will instantiate and return a new one.
|
440 |
+
*
|
441 |
+
* @return Mustache_Tokenizer
|
442 |
+
*/
|
443 |
+
public function getTokenizer()
|
444 |
+
{
|
445 |
+
if (!isset($this->tokenizer)) {
|
446 |
+
$this->tokenizer = new Mustache_Tokenizer;
|
447 |
+
}
|
448 |
+
|
449 |
+
return $this->tokenizer;
|
450 |
+
}
|
451 |
+
|
452 |
+
/**
|
453 |
+
* Set the Mustache Parser instance.
|
454 |
+
*
|
455 |
+
* @param Mustache_Parser $parser
|
456 |
+
*/
|
457 |
+
public function setParser(Mustache_Parser $parser)
|
458 |
+
{
|
459 |
+
$this->parser = $parser;
|
460 |
+
}
|
461 |
+
|
462 |
+
/**
|
463 |
+
* Get the current Mustache Parser instance.
|
464 |
+
*
|
465 |
+
* If no Parser instance has been explicitly specified, this method will instantiate and return a new one.
|
466 |
+
*
|
467 |
+
* @return Mustache_Parser
|
468 |
+
*/
|
469 |
+
public function getParser()
|
470 |
+
{
|
471 |
+
if (!isset($this->parser)) {
|
472 |
+
$this->parser = new Mustache_Parser;
|
473 |
+
}
|
474 |
+
|
475 |
+
return $this->parser;
|
476 |
+
}
|
477 |
+
|
478 |
+
/**
|
479 |
+
* Set the Mustache Compiler instance.
|
480 |
+
*
|
481 |
+
* @param Mustache_Compiler $compiler
|
482 |
+
*/
|
483 |
+
public function setCompiler(Mustache_Compiler $compiler)
|
484 |
+
{
|
485 |
+
$this->compiler = $compiler;
|
486 |
+
}
|
487 |
+
|
488 |
+
/**
|
489 |
+
* Get the current Mustache Compiler instance.
|
490 |
+
*
|
491 |
+
* If no Compiler instance has been explicitly specified, this method will instantiate and return a new one.
|
492 |
+
*
|
493 |
+
* @return Mustache_Compiler
|
494 |
+
*/
|
495 |
+
public function getCompiler()
|
496 |
+
{
|
497 |
+
if (!isset($this->compiler)) {
|
498 |
+
$this->compiler = new Mustache_Compiler;
|
499 |
+
}
|
500 |
+
|
501 |
+
return $this->compiler;
|
502 |
+
}
|
503 |
+
|
504 |
+
/**
|
505 |
+
* Set the Mustache Cache instance.
|
506 |
+
*
|
507 |
+
* @param Mustache_Cache $cache
|
508 |
+
*/
|
509 |
+
public function setCache(Mustache_Cache $cache)
|
510 |
+
{
|
511 |
+
if (isset($this->logger) && $cache->getLogger() === null) {
|
512 |
+
$cache->setLogger($this->getLogger());
|
513 |
+
}
|
514 |
+
|
515 |
+
$this->cache = $cache;
|
516 |
+
}
|
517 |
+
|
518 |
+
/**
|
519 |
+
* Get the current Mustache Cache instance.
|
520 |
+
*
|
521 |
+
* If no Cache instance has been explicitly specified, this method will instantiate and return a new one.
|
522 |
+
*
|
523 |
+
* @return Mustache_Cache
|
524 |
+
*/
|
525 |
+
public function getCache()
|
526 |
+
{
|
527 |
+
if (!isset($this->cache)) {
|
528 |
+
$this->setCache(new Mustache_Cache_NoopCache());
|
529 |
+
}
|
530 |
+
|
531 |
+
return $this->cache;
|
532 |
+
}
|
533 |
+
|
534 |
+
/**
|
535 |
+
* Get the current Lambda Cache instance.
|
536 |
+
*
|
537 |
+
* If 'cache_lambda_templates' is enabled, this is the default cache instance. Otherwise, it is a NoopCache.
|
538 |
+
*
|
539 |
+
* @see Mustache_Engine::getCache
|
540 |
+
*
|
541 |
+
* @return Mustache_Cache
|
542 |
+
*/
|
543 |
+
protected function getLambdaCache()
|
544 |
+
{
|
545 |
+
if ($this->cacheLambdaTemplates) {
|
546 |
+
return $this->getCache();
|
547 |
+
}
|
548 |
+
|
549 |
+
if (!isset($this->lambdaCache)) {
|
550 |
+
$this->lambdaCache = new Mustache_Cache_NoopCache();
|
551 |
+
}
|
552 |
+
|
553 |
+
return $this->lambdaCache;
|
554 |
+
}
|
555 |
+
|
556 |
+
/**
|
557 |
+
* Helper method to generate a Mustache template class.
|
558 |
+
*
|
559 |
+
* @param string $source
|
560 |
+
*
|
561 |
+
* @return string Mustache Template class name
|
562 |
+
*/
|
563 |
+
public function getTemplateClassName($source)
|
564 |
+
{
|
565 |
+
return $this->templateClassPrefix . md5(sprintf(
|
566 |
+
'version:%s,escape:%s,entity_flags:%i,charset:%s,strict_callables:%s,source:%s',
|
567 |
+
self::VERSION,
|
568 |
+
isset($this->escape) ? 'custom' : 'default',
|
569 |
+
$this->entityFlags,
|
570 |
+
$this->charset,
|
571 |
+
$this->strictCallables ? 'true' : 'false',
|
572 |
+
$source
|
573 |
+
));
|
574 |
+
}
|
575 |
+
|
576 |
+
/**
|
577 |
+
* Load a Mustache Template by name.
|
578 |
+
*
|
579 |
+
* @param string $name
|
580 |
+
*
|
581 |
+
* @return Mustache_Template
|
582 |
+
*/
|
583 |
+
public function loadTemplate($name)
|
584 |
+
{
|
585 |
+
return $this->loadSource($this->getLoader()->load($name));
|
586 |
+
}
|
587 |
+
|
588 |
+
/**
|
589 |
+
* Load a Mustache partial Template by name.
|
590 |
+
*
|
591 |
+
* This is a helper method used internally by Template instances for loading partial templates. You can most likely
|
592 |
+
* ignore it completely.
|
593 |
+
*
|
594 |
+
* @param string $name
|
595 |
+
*
|
596 |
+
* @return Mustache_Template
|
597 |
+
*/
|
598 |
+
public function loadPartial($name)
|
599 |
+
{
|
600 |
+
try {
|
601 |
+
if (isset($this->partialsLoader)) {
|
602 |
+
$loader = $this->partialsLoader;
|
603 |
+
} elseif (isset($this->loader) && !$this->loader instanceof Mustache_Loader_StringLoader) {
|
604 |
+
$loader = $this->loader;
|
605 |
+
} else {
|
606 |
+
throw new Mustache_Exception_UnknownTemplateException($name);
|
607 |
+
}
|
608 |
+
|
609 |
+
return $this->loadSource($loader->load($name));
|
610 |
+
} catch (Mustache_Exception_UnknownTemplateException $e) {
|
611 |
+
// If the named partial cannot be found, log then return null.
|
612 |
+
$this->log(
|
613 |
+
Mustache_Logger::WARNING,
|
614 |
+
'Partial not found: "{name}"',
|
615 |
+
array('name' => $e->getTemplateName())
|
616 |
+
);
|
617 |
+
}
|
618 |
+
}
|
619 |
+
|
620 |
+
/**
|
621 |
+
* Load a Mustache lambda Template by source.
|
622 |
+
*
|
623 |
+
* This is a helper method used by Template instances to generate subtemplates for Lambda sections. You can most
|
624 |
+
* likely ignore it completely.
|
625 |
+
*
|
626 |
+
* @param string $source
|
627 |
+
* @param string $delims (default: null)
|
628 |
+
*
|
629 |
+
* @return Mustache_Template
|
630 |
+
*/
|
631 |
+
public function loadLambda($source, $delims = null)
|
632 |
+
{
|
633 |
+
if ($delims !== null) {
|
634 |
+
$source = $delims . "\n" . $source;
|
635 |
+
}
|
636 |
+
|
637 |
+
return $this->loadSource($source, $this->getLambdaCache());
|
638 |
+
}
|
639 |
+
|
640 |
+
/**
|
641 |
+
* Instantiate and return a Mustache Template instance by source.
|
642 |
+
*
|
643 |
+
* Optionally provide a Mustache_Cache instance. This is used internally by Mustache_Engine::loadLambda to respect
|
644 |
+
* the 'cache_lambda_templates' configuration option.
|
645 |
+
*
|
646 |
+
* @see Mustache_Engine::loadTemplate
|
647 |
+
* @see Mustache_Engine::loadPartial
|
648 |
+
* @see Mustache_Engine::loadLambda
|
649 |
+
*
|
650 |
+
* @param string $source
|
651 |
+
* @param Mustache_Cache $cache (default: null)
|
652 |
+
*
|
653 |
+
* @return Mustache_Template
|
654 |
+
*/
|
655 |
+
private function loadSource($source, Mustache_Cache $cache = null)
|
656 |
+
{
|
657 |
+
$className = $this->getTemplateClassName($source);
|
658 |
+
|
659 |
+
if (!isset($this->templates[$className])) {
|
660 |
+
if ($cache === null) {
|
661 |
+
$cache = $this->getCache();
|
662 |
+
}
|
663 |
+
|
664 |
+
if (!class_exists($className, false)) {
|
665 |
+
if (!$cache->load($className)) {
|
666 |
+
$compiled = $this->compile($source);
|
667 |
+
$cache->cache($className, $compiled);
|
668 |
+
}
|
669 |
+
}
|
670 |
+
|
671 |
+
$this->log(
|
672 |
+
Mustache_Logger::DEBUG,
|
673 |
+
'Instantiating template: "{className}"',
|
674 |
+
array('className' => $className)
|
675 |
+
);
|
676 |
+
|
677 |
+
$this->templates[$className] = new $className($this);
|
678 |
+
}
|
679 |
+
|
680 |
+
return $this->templates[$className];
|
681 |
+
}
|
682 |
+
|
683 |
+
/**
|
684 |
+
* Helper method to tokenize a Mustache template.
|
685 |
+
*
|
686 |
+
* @see Mustache_Tokenizer::scan
|
687 |
+
*
|
688 |
+
* @param string $source
|
689 |
+
*
|
690 |
+
* @return array Tokens
|
691 |
+
*/
|
692 |
+
private function tokenize($source)
|
693 |
+
{
|
694 |
+
return $this->getTokenizer()->scan($source);
|
695 |
+
}
|
696 |
+
|
697 |
+
/**
|
698 |
+
* Helper method to parse a Mustache template.
|
699 |
+
*
|
700 |
+
* @see Mustache_Parser::parse
|
701 |
+
*
|
702 |
+
* @param string $source
|
703 |
+
*
|
704 |
+
* @return array Token tree
|
705 |
+
*/
|
706 |
+
private function parse($source)
|
707 |
+
{
|
708 |
+
return $this->getParser()->parse($this->tokenize($source));
|
709 |
+
}
|
710 |
+
|
711 |
+
/**
|
712 |
+
* Helper method to compile a Mustache template.
|
713 |
+
*
|
714 |
+
* @see Mustache_Compiler::compile
|
715 |
+
*
|
716 |
+
* @param string $source
|
717 |
+
*
|
718 |
+
* @return string generated Mustache template class code
|
719 |
+
*/
|
720 |
+
private function compile($source)
|
721 |
+
{
|
722 |
+
$tree = $this->parse($source);
|
723 |
+
$name = $this->getTemplateClassName($source);
|
724 |
+
|
725 |
+
$this->log(
|
726 |
+
Mustache_Logger::INFO,
|
727 |
+
'Compiling template to "{className}" class',
|
728 |
+
array('className' => $name)
|
729 |
+
);
|
730 |
+
|
731 |
+
return $this->getCompiler()->compile($source, $tree, $name, isset($this->escape), $this->charset, $this->strictCallables, $this->entityFlags);
|
732 |
+
}
|
733 |
+
|
734 |
+
/**
|
735 |
+
* Add a log record if logging is enabled.
|
736 |
+
*
|
737 |
+
* @param integer $level The logging level
|
738 |
+
* @param string $message The log message
|
739 |
+
* @param array $context The log context
|
740 |
+
*/
|
741 |
+
private function log($level, $message, array $context = array())
|
742 |
+
{
|
743 |
+
if (isset($this->logger)) {
|
744 |
+
$this->logger->log($level, $message, $context);
|
745 |
+
}
|
746 |
+
}
|
747 |
+
}
|
vendor/mustache/mustache/src/Mustache/Exception.php
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Mustache.php.
|
5 |
+
*
|
6 |
+
* (c) 2010-2014 Justin Hileman
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* A Mustache Exception interface.
|
14 |
+
*/
|
15 |
+
interface Mustache_Exception
|
16 |
+
{
|
17 |
+
// This space intentionally left blank.
|
18 |
+
}
|
vendor/mustache/mustache/src/Mustache/Exception/InvalidArgumentException.php
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Mustache.php.
|
5 |
+
*
|
6 |
+
* (c) 2010-2014 Justin Hileman
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Invalid argument exception.
|
14 |
+
*/
|
15 |
+
class Mustache_Exception_InvalidArgumentException extends InvalidArgumentException implements Mustache_Exception
|
16 |
+
{
|
17 |
+
// This space intentionally left blank.
|
18 |
+
}
|
vendor/mustache/mustache/src/Mustache/Exception/LogicException.php
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Mustache.php.
|
5 |
+
*
|
6 |
+
* (c) 2010-2014 Justin Hileman
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Logic exception.
|
14 |
+
*/
|
15 |
+
class Mustache_Exception_LogicException extends LogicException implements Mustache_Exception
|
16 |
+
{
|
17 |
+
// This space intentionally left blank.
|
18 |
+
}
|
vendor/mustache/mustache/src/Mustache/Exception/RuntimeException.php
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Mustache.php.
|
5 |
+
*
|
6 |
+
* (c) 2010-2014 Justin Hileman
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Runtime exception.
|
14 |
+
*/
|
15 |
+
class Mustache_Exception_RuntimeException extends RuntimeException implements Mustache_Exception
|
16 |
+
{
|
17 |
+
// This space intentionally left blank.
|
18 |
+
}
|
vendor/mustache/mustache/src/Mustache/Exception/SyntaxException.php
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Mustache.php.
|
5 |
+
*
|
6 |
+
* (c) 2010-2014 Justin Hileman
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Mustache syntax exception.
|
14 |
+
*/
|
15 |
+
class Mustache_Exception_SyntaxException extends LogicException implements Mustache_Exception
|
16 |
+
{
|
17 |
+
protected $token;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @param string $msg
|
21 |
+
* @param array $token
|
22 |
+
*/
|
23 |
+
public function __construct($msg, array $token)
|
24 |
+
{
|
25 |
+
$this->token = $token;
|
26 |
+
parent::__construct($msg);
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* @return array
|
31 |
+
*/
|
32 |
+
public function getToken()
|
33 |
+
{
|
34 |
+
return $this->token;
|
35 |
+
}
|
36 |
+
}
|
vendor/mustache/mustache/src/Mustache/Exception/UnknownFilterException.php
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Mustache.php.
|
5 |
+
*
|
6 |
+
* (c) 2010-2014 Justin Hileman
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Unknown filter exception.
|
14 |
+
*/
|
15 |
+
class Mustache_Exception_UnknownFilterException extends UnexpectedValueException implements Mustache_Exception
|
16 |
+
{
|
17 |
+
protected $filterName;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @param string $filterName
|
21 |
+
*/
|
22 |
+
public function __construct($filterName)
|
23 |
+
{
|
24 |
+
$this->filterName = $filterName;
|
25 |
+
parent::__construct(sprintf('Unknown filter: %s', $filterName));
|
26 |
+
}
|
27 |
+
|
28 |
+
public function getFilterName()
|
29 |
+
{
|
30 |
+
return $this->filterName;
|
31 |
+
}
|
32 |
+
}
|
vendor/mustache/mustache/src/Mustache/Exception/UnknownHelperException.php
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Mustache.php.
|
5 |
+
*
|
6 |
+
* (c) 2010-2014 Justin Hileman
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Unknown helper exception.
|
14 |
+
*/
|
15 |
+
class Mustache_Exception_UnknownHelperException extends InvalidArgumentException implements Mustache_Exception
|
16 |
+
{
|
17 |
+
protected $helperName;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @param string $helperName
|
21 |
+
*/
|
22 |
+
public function __construct($helperName)
|
23 |
+
{
|
24 |
+
$this->helperName = $helperName;
|
25 |
+
parent::__construct(sprintf('Unknown helper: %s', $helperName));
|
26 |
+
}
|
27 |
+
|
28 |
+
public function getHelperName()
|
29 |
+
{
|
30 |
+
return $this->helperName;
|
31 |
+
}
|
32 |
+
}
|
vendor/mustache/mustache/src/Mustache/Exception/UnknownTemplateException.php
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Mustache.php.
|
5 |
+
*
|
6 |
+
* (c) 2010-2014 Justin Hileman
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Unknown template exception.
|
14 |
+
*/
|
15 |
+
class Mustache_Exception_UnknownTemplateException extends InvalidArgumentException implements Mustache_Exception
|
16 |
+
{
|
17 |
+
protected $templateName;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @param string $templateName
|
21 |
+
*/
|
22 |
+
public function __construct($templateName)
|
23 |
+
{
|
24 |
+
$this->templateName = $templateName;
|
25 |
+
parent::__construct(sprintf('Unknown template: %s', $templateName));
|
26 |
+
}
|
27 |
+
|
28 |
+
public function getTemplateName()
|
29 |
+
{
|
30 |
+
return $this->templateName;
|
31 |
+
}
|
32 |
+
}
|
vendor/mustache/mustache/src/Mustache/HelperCollection.php
ADDED
@@ -0,0 +1,172 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Mustache.php.
|
5 |
+
*
|
6 |
+
* (c) 2010-2014 Justin Hileman
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* A collection of helpers for a Mustache instance.
|
14 |
+
*/
|
15 |
+
class Mustache_HelperCollection
|
16 |
+
{
|
17 |
+
private $helpers = array();
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Helper Collection constructor.
|
21 |
+
*
|
22 |
+
* Optionally accepts an array (or Traversable) of `$name => $helper` pairs.
|
23 |
+
*
|
24 |
+
* @throws Mustache_Exception_InvalidArgumentException if the $helpers argument isn't an array or Traversable
|
25 |
+
*
|
26 |
+
* @param array|Traversable $helpers (default: null)
|
27 |
+
*/
|
28 |
+
public function __construct($helpers = null)
|
29 |
+
{
|
30 |
+
if ($helpers === null) {
|
31 |
+
return;
|
32 |
+
}
|
33 |
+
|
34 |
+
if (!is_array($helpers) && !$helpers instanceof Traversable) {
|
35 |
+
throw new Mustache_Exception_InvalidArgumentException('HelperCollection constructor expects an array of helpers');
|
36 |
+
}
|
37 |
+
|
38 |
+
foreach ($helpers as $name => $helper) {
|
39 |
+
$this->add($name, $helper);
|
40 |
+
}
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Magic mutator.
|
45 |
+
*
|
46 |
+
* @see Mustache_HelperCollection::add
|
47 |
+
*
|
48 |
+
* @param string $name
|
49 |
+
* @param mixed $helper
|
50 |
+
*/
|
51 |
+
public function __set($name, $helper)
|
52 |
+
{
|
53 |
+
$this->add($name, $helper);
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Add a helper to this collection.
|
58 |
+
*
|
59 |
+
* @param string $name
|
60 |
+
* @param mixed $helper
|
61 |
+
*/
|
62 |
+
public function add($name, $helper)
|
63 |
+
{
|
64 |
+
$this->helpers[$name] = $helper;
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Magic accessor.
|
69 |
+
*
|
70 |
+
* @see Mustache_HelperCollection::get
|
71 |
+
*
|
72 |
+
* @param string $name
|
73 |
+
*
|
74 |
+
* @return mixed Helper
|
75 |
+
*/
|
76 |
+
public function __get($name)
|
77 |
+
{
|
78 |
+
return $this->get($name);
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Get a helper by name.
|
83 |
+
*
|
84 |
+
* @throws Mustache_Exception_UnknownHelperException If helper does not exist.
|
85 |
+
*
|
86 |
+
* @param string $name
|
87 |
+
*
|
88 |
+
* @return mixed Helper
|
89 |
+
*/
|
90 |
+
public function get($name)
|
91 |
+
{
|
92 |
+
if (!$this->has($name)) {
|
93 |
+
throw new Mustache_Exception_UnknownHelperException($name);
|
94 |
+
}
|
95 |
+
|
96 |
+
return $this->helpers[$name];
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Magic isset().
|
101 |
+
*
|
102 |
+
* @see Mustache_HelperCollection::has
|
103 |
+
*
|
104 |
+
* @param string $name
|
105 |
+
*
|
106 |
+
* @return boolean True if helper is present
|
107 |
+
*/
|
108 |
+
public function __isset($name)
|
109 |
+
{
|
110 |
+
return $this->has($name);
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Check whether a given helper is present in the collection.
|
115 |
+
*
|
116 |
+
* @param string $name
|
117 |
+
*
|
118 |
+
* @return boolean True if helper is present
|
119 |
+
*/
|
120 |
+
public function has($name)
|
121 |
+
{
|
122 |
+
return array_key_exists($name, $this->helpers);
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Magic unset().
|
127 |
+
*
|
128 |
+
* @see Mustache_HelperCollection::remove
|
129 |
+
*
|
130 |
+
* @param string $name
|
131 |
+
*/
|
132 |
+
public function __unset($name)
|
133 |
+
{
|
134 |
+
$this->remove($name);
|
135 |
+
}
|
136 |
+
|
137 |
+
/**
|
138 |
+
* Check whether a given helper is present in the collection.
|
139 |
+
*
|
140 |
+
* @throws Mustache_Exception_UnknownHelperException if the requested helper is not present.
|
141 |
+
*
|
142 |
+
* @param string $name
|
143 |
+
*/
|
144 |
+
public function remove($name)
|
145 |
+
{
|
146 |
+
if (!$this->has($name)) {
|
147 |
+
throw new Mustache_Exception_UnknownHelperException($name);
|
148 |
+
}
|
149 |
+
|
150 |
+
unset($this->helpers[$name]);
|
151 |
+
}
|
152 |
+
|
153 |
+
/**
|
154 |
+
* Clear the helper collection.
|
155 |
+
*
|
156 |
+
* Removes all helpers from this collection
|
157 |
+
*/
|
158 |
+
public function clear()
|
159 |
+
{
|
160 |
+
$this->helpers = array();
|
161 |
+
}
|
162 |
+
|
163 |
+
/**
|
164 |
+
* Check whether the helper collection is empty.
|
165 |
+
*
|
166 |
+
* @return boolean True if the collection is empty
|
167 |
+
*/
|
168 |
+
public function isEmpty()
|
169 |
+
{
|
170 |
+
return empty($this->helpers);
|
171 |
+
}
|
172 |
+
}
|
vendor/mustache/mustache/src/Mustache/LambdaHelper.php
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Mustache.php.
|
5 |
+
*
|
6 |
+
* (c) 2010-2014 Justin Hileman
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Mustache Lambda Helper.
|
14 |
+
*
|
15 |
+
* Passed as the second argument to section lambdas (higher order sections),
|
16 |
+
* giving them access to a `render` method for rendering a string with the
|
17 |
+
* current context.
|
18 |
+
*/
|
19 |
+
class Mustache_LambdaHelper
|
20 |
+
{
|
21 |
+
private $mustache;
|
22 |
+
private $context;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Mustache Lambda Helper constructor.
|
26 |
+
*
|
27 |
+
* @param Mustache_Engine $mustache Mustache engine instance.
|
28 |
+
* @param Mustache_Context $context Rendering context.
|
29 |
+
*/
|
30 |
+
public function __construct(Mustache_Engine $mustache, Mustache_Context $context)
|
31 |
+
{
|
32 |
+
$this->mustache = $mustache;
|
33 |
+
$this->context = $context;
|
34 |
+
}
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Render a string as a Mustache template with the current rendering context.
|
38 |
+
*
|
39 |
+
* @param string $string
|
40 |
+
*
|
41 |
+
* @return string Rendered template.
|
42 |
+
*/
|
43 |
+
public function render($string)
|
44 |
+
{
|
45 |
+
return $this->mustache
|
46 |
+
->loadLambda((string) $string)
|
47 |
+
->renderInternal($this->context);
|
48 |
+
}
|
49 |
+
}
|
vendor/mustache/mustache/src/Mustache/Loader.php
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Mustache.php.
|
5 |
+
*
|
6 |
+
* (c) 2010-2014 Justin Hileman
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Mustache Template Loader interface.
|
14 |
+
*/
|
15 |
+
interface Mustache_Loader
|
16 |
+
{
|
17 |
+
/**
|
18 |
+
* Load a Template by name.
|
19 |
+
*
|
20 |
+
* @throws Mustache_Exception_UnknownTemplateException If a template file is not found.
|
21 |
+
*
|
22 |
+
* @param string $name
|
23 |
+
*
|
24 |
+
* @return string Mustache Template source
|
25 |
+
*/
|
26 |
+
public function load($name);
|
27 |
+
}
|
vendor/mustache/mustache/src/Mustache/Loader/ArrayLoader.php
ADDED
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Mustache.php.
|
5 |
+
*
|
6 |
+
* (c) 2010-2014 Justin Hileman
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Mustache Template array Loader implementation.
|
14 |
+
*
|
15 |
+
* An ArrayLoader instance loads Mustache Template source by name from an initial array:
|
16 |
+
*
|
17 |
+
* $loader = new ArrayLoader(
|
18 |
+
* 'foo' => '{{ bar }}',
|
19 |
+
* 'baz' => 'Hey {{ qux }}!'
|
20 |
+
* );
|
21 |
+
*
|
22 |
+
* $tpl = $loader->load('foo'); // '{{ bar }}'
|
23 |
+
*
|
24 |
+
* The ArrayLoader is used internally as a partials loader by Mustache_Engine instance when an array of partials
|
25 |
+
* is set. It can also be used as a quick-and-dirty Template loader.
|
26 |
+
*/
|
27 |
+
class Mustache_Loader_ArrayLoader implements Mustache_Loader, Mustache_Loader_MutableLoader
|
28 |
+
{
|
29 |
+
private $templates;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* ArrayLoader constructor.
|
33 |
+
*
|
34 |
+
* @param array $templates Associative array of Template source (default: array())
|
35 |
+
*/
|
36 |
+
public function __construct(array $templates = array())
|
37 |
+
{
|
38 |
+
$this->templates = $templates;
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Load a Template.
|
43 |
+
*
|
44 |
+
* @throws Mustache_Exception_UnknownTemplateException If a template file is not found.
|
45 |
+
*
|
46 |
+
* @param string $name
|
47 |
+
*
|
48 |
+
* @return string Mustache Template source
|
49 |
+
*/
|
50 |
+
public function load($name)
|
51 |
+
{
|
52 |
+
if (!isset($this->templates[$name])) {
|
53 |
+
throw new Mustache_Exception_UnknownTemplateException($name);
|
54 |
+
}
|
55 |
+
|
56 |
+
return $this->templates[$name];
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Set an associative array of Template sources for this loader.
|
61 |
+
*
|
62 |
+
* @param array $templates
|
63 |
+
*/
|
64 |
+
public function setTemplates(array $templates)
|
65 |
+
{
|
66 |
+
$this->templates = $templates;
|
67 |
+
}
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Set a Template source by name.
|
71 |
+
*
|
72 |
+
* @param string $name
|
73 |
+
* @param string $template Mustache Template source
|
74 |
+
*/
|
75 |
+
public function setTemplate($name, $template)
|
76 |
+
{
|
77 |
+
$this->templates[$name] = $template;
|
78 |
+
}
|
79 |
+
}
|
vendor/mustache/mustache/src/Mustache/Loader/CascadingLoader.php
ADDED
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Mustache.php.
|
5 |
+
*
|
6 |
+
* (c) 2010-2014 Justin Hileman
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* A Mustache Template cascading loader implementation, which delegates to other
|
14 |
+
* Loader instances.
|
15 |
+
*/
|
16 |
+
class Mustache_Loader_CascadingLoader implements Mustache_Loader
|
17 |
+
{
|
18 |
+
private $loaders;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Construct a CascadingLoader with an array of loaders:
|
22 |
+
*
|
23 |
+
* $loader = new Mustache_Loader_CascadingLoader(array(
|
24 |
+
* new Mustache_Loader_InlineLoader(__FILE__, __COMPILER_HALT_OFFSET__),
|
25 |
+
* new Mustache_Loader_FilesystemLoader(__DIR__.'/templates')
|
26 |
+
* ));
|
27 |
+
*
|
28 |
+
* @param Mustache_Loader[] $loaders
|
29 |
+
*/
|
30 |
+
public function __construct(array $loaders = array())
|
31 |
+
{
|
32 |
+
$this->loaders = array();
|
33 |
+
foreach ($loaders as $loader) {
|
34 |
+
$this->addLoader($loader);
|
35 |
+
}
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Add a Loader instance.
|
40 |
+
*
|
41 |
+
* @param Mustache_Loader $loader
|
42 |
+
*/
|
43 |
+
public function addLoader(Mustache_Loader $loader)
|
44 |
+
{
|
45 |
+
$this->loaders[] = $loader;
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Load a Template by name.
|
50 |
+
*
|
51 |
+
* @throws Mustache_Exception_UnknownTemplateException If a template file is not found.
|
52 |
+
*
|
53 |
+
* @param string $name
|
54 |
+
*
|
55 |
+
* @return string Mustache Template source
|
56 |
+
*/
|
57 |
+
public function load($name)
|
58 |
+
{
|
59 |
+
foreach ($this->loaders as $loader) {
|
60 |
+
try {
|
61 |
+
return $loader->load($name);
|
62 |
+
} catch (Mustache_Exception_UnknownTemplateException $e) {
|
63 |
+
// do nothing, check the next loader.
|
64 |
+
}
|
65 |
+
}
|
66 |
+
|
67 |
+
throw new Mustache_Exception_UnknownTemplateException($name);
|
68 |
+
}
|
69 |
+
}
|
vendor/mustache/mustache/src/Mustache/Loader/FilesystemLoader.php
ADDED
@@ -0,0 +1,124 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Mustache.php.
|
5 |
+
*
|
6 |
+
* (c) 2010-2014 Justin Hileman
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Mustache Template filesystem Loader implementation.
|
14 |
+
*
|
15 |
+
* A FilesystemLoader instance loads Mustache Template source from the filesystem by name:
|
16 |
+
*
|
17 |
+
* $loader = new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views');
|
18 |
+
* $tpl = $loader->load('foo'); // equivalent to `file_get_contents(dirname(__FILE__).'/views/foo.mustache');
|
19 |
+
*
|
20 |
+
* This is probably the most useful Mustache Loader implementation. It can be used for partials and normal Templates:
|
21 |
+
*
|
22 |
+
* $m = new Mustache(array(
|
23 |
+
* 'loader' => new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views'),
|
24 |
+
* 'partials_loader' => new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views/partials'),
|
25 |
+
* ));
|
26 |
+
*/
|
27 |
+
class Mustache_Loader_FilesystemLoader implements Mustache_Loader
|
28 |
+
{
|
29 |
+
private $baseDir;
|
30 |
+
private $extension = '.mustache';
|
31 |
+
private $templates = array();
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Mustache filesystem Loader constructor.
|
35 |
+
*
|
36 |
+
* Passing an $options array allows overriding certain Loader options during instantiation:
|
37 |
+
*
|
38 |
+
* $options = array(
|
39 |
+
* // The filename extension used for Mustache templates. Defaults to '.mustache'
|
40 |
+
* 'extension' => '.ms',
|
41 |
+
* );
|
42 |
+
*
|
43 |
+
* @throws Mustache_Exception_RuntimeException if $baseDir does not exist.
|
44 |
+
*
|
45 |
+
* @param string $baseDir Base directory containing Mustache template files.
|
46 |
+
* @param array $options Array of Loader options (default: array())
|
47 |
+
*/
|
48 |
+
public function __construct($baseDir, array $options = array())
|
49 |
+
{
|
50 |
+
$this->baseDir = $baseDir;
|
51 |
+
|
52 |
+
if (strpos($this->baseDir, '://') === -1) {
|
53 |
+
$this->baseDir = realpath($this->baseDir);
|
54 |
+
}
|
55 |
+
|
56 |
+
if (!is_dir($this->baseDir)) {
|
57 |
+
throw new Mustache_Exception_RuntimeException(sprintf('FilesystemLoader baseDir must be a directory: %s', $baseDir));
|
58 |
+
}
|
59 |
+
|
60 |
+
if (array_key_exists('extension', $options)) {
|
61 |
+
if (empty($options['extension'])) {
|
62 |
+
$this->extension = '';
|
63 |
+
} else {
|
64 |
+
$this->extension = '.' . ltrim($options['extension'], '.');
|
65 |
+
}
|
66 |
+
}
|
67 |
+
}
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Load a Template by name.
|
71 |
+
*
|
72 |
+
* $loader = new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/views');
|
73 |
+
* $loader->load('admin/dashboard'); // loads "./views/admin/dashboard.mustache";
|
74 |
+
*
|
75 |
+
* @param string $name
|
76 |
+
*
|
77 |
+
* @return string Mustache Template source
|
78 |
+
*/
|
79 |
+
public function load($name)
|
80 |
+
{
|
81 |
+
if (!isset($this->templates[$name])) {
|
82 |
+
$this->templates[$name] = $this->loadFile($name);
|
83 |
+
}
|
84 |
+
|
85 |
+
return $this->templates[$name];
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Helper function for loading a Mustache file by name.
|
90 |
+
*
|
91 |
+
* @throws Mustache_Exception_UnknownTemplateException If a template file is not found.
|
92 |
+
*
|
93 |
+
* @param string $name
|
94 |
+
*
|
95 |
+
* @return string Mustache Template source
|
96 |
+
*/
|
97 |
+
protected function loadFile($name)
|
98 |
+
{
|
99 |
+
$fileName = $this->getFileName($name);
|
100 |
+
|
101 |
+
if (!file_exists($fileName)) {
|
102 |
+
throw new Mustache_Exception_UnknownTemplateException($name);
|
103 |
+
}
|
104 |
+
|
105 |
+
return file_get_contents($fileName);
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Helper function for getting a Mustache template file name.
|
110 |
+
*
|
111 |
+
* @param string $name
|
112 |
+
*
|
113 |
+
* @return string Template file name
|
114 |
+
*/
|
115 |
+
protected function getFileName($name)
|
116 |
+
{
|
117 |
+
$fileName = $this->baseDir . '/' . $name;
|
118 |
+
if (substr($fileName, 0 - strlen($this->extension)) !== $this->extension) {
|
119 |
+
$fileName .= $this->extension;
|
120 |
+
}
|
121 |
+
|
122 |
+
return $fileName;
|
123 |
+
}
|
124 |
+
}
|
vendor/mustache/mustache/src/Mustache/Loader/InlineLoader.php
ADDED
@@ -0,0 +1,123 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Mustache.php.
|
5 |
+
*
|
6 |
+
* (c) 2010-2014 Justin Hileman
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* A Mustache Template loader for inline templates.
|
14 |
+
*
|
15 |
+
* With the InlineLoader, templates can be defined at the end of any PHP source
|
16 |
+
* file:
|
17 |
+
*
|
18 |
+
* $loader = new Mustache_Loader_InlineLoader(__FILE__, __COMPILER_HALT_OFFSET__);
|
19 |
+
* $hello = $loader->load('hello');
|
20 |
+
* $goodbye = $loader->load('goodbye');
|
21 |
+
*
|
22 |
+
* __halt_compiler();
|
23 |
+
*
|
24 |
+
* @@ hello
|
25 |
+
* Hello, {{ planet }}!
|
26 |
+
*
|
27 |
+
* @@ goodbye
|
28 |
+
* Goodbye, cruel {{ planet }}
|
29 |
+
*
|
30 |
+
* Templates are deliniated by lines containing only `@@ name`.
|
31 |
+
*
|
32 |
+
* The InlineLoader is well-suited to micro-frameworks such as Silex:
|
33 |
+
*
|
34 |
+
* $app->register(new MustacheServiceProvider, array(
|
35 |
+
* 'mustache.loader' => new Mustache_Loader_InlineLoader(__FILE__, __COMPILER_HALT_OFFSET__)
|
36 |
+
* ));
|
37 |
+
*
|
38 |
+
* $app->get('/{name}', function ($name) use ($app) {
|
39 |
+
* return $app['mustache']->render('hello', compact('name'));
|
40 |
+
* })
|
41 |
+
* ->value('name', 'world');
|
42 |
+
*
|
43 |
+
* // ...
|
44 |
+
*
|
45 |
+
* __halt_compiler();
|
46 |
+
*
|
47 |
+
* @@ hello
|
48 |
+
* Hello, {{ name }}!
|
49 |
+
*
|
50 |
+
*/
|
51 |
+
class Mustache_Loader_InlineLoader implements Mustache_Loader
|
52 |
+
{
|
53 |
+
protected $fileName;
|
54 |
+
protected $offset;
|
55 |
+
protected $templates;
|
56 |
+
|
57 |
+
/**
|
58 |
+
* The InlineLoader requires a filename and offset to process templates.
|
59 |
+
* The magic constants `__FILE__` and `__COMPILER_HALT_OFFSET__` are usually
|
60 |
+
* perfectly suited to the job:
|
61 |
+
*
|
62 |
+
* $loader = new Mustache_Loader_InlineLoader(__FILE__, __COMPILER_HALT_OFFSET__);
|
63 |
+
*
|
64 |
+
* Note that this only works if the loader is instantiated inside the same
|
65 |
+
* file as the inline templates. If the templates are located in another
|
66 |
+
* file, it would be necessary to manually specify the filename and offset.
|
67 |
+
*
|
68 |
+
* @param string $fileName The file to parse for inline templates
|
69 |
+
* @param int $offset A string offset for the start of the templates.
|
70 |
+
* This usually coincides with the `__halt_compiler`
|
71 |
+
* call, and the `__COMPILER_HALT_OFFSET__`.
|
72 |
+
*/
|
73 |
+
public function __construct($fileName, $offset)
|
74 |
+
{
|
75 |
+
if (!is_file($fileName)) {
|
76 |
+
throw new Mustache_Exception_InvalidArgumentException('InlineLoader expects a valid filename.');
|
77 |
+
}
|
78 |
+
|
79 |
+
if (!is_int($offset) || $offset < 0) {
|
80 |
+
throw new Mustache_Exception_InvalidArgumentException('InlineLoader expects a valid file offset.');
|
81 |
+
}
|
82 |
+
|
83 |
+
$this->fileName = $fileName;
|
84 |
+
$this->offset = $offset;
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Load a Template by name.
|
89 |
+
*
|
90 |
+
* @throws Mustache_Exception_UnknownTemplateException If a template file is not found.
|
91 |
+
*
|
92 |
+
* @param string $name
|
93 |
+
*
|
94 |
+
* @return string Mustache Template source
|
95 |
+
*/
|
96 |
+
public function load($name)
|
97 |
+
{
|
98 |
+
$this->loadTemplates();
|
99 |
+
|
100 |
+
if (!array_key_exists($name, $this->templates)) {
|
101 |
+
throw new Mustache_Exception_UnknownTemplateException($name);
|
102 |
+
}
|
103 |
+
|
104 |
+
return $this->templates[$name];
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Parse and load templates from the end of a source file.
|
109 |
+
*/
|
110 |
+
protected function loadTemplates()
|
111 |
+
{
|
112 |
+
if ($this->templates === null) {
|
113 |
+
$this->templates = array();
|
114 |
+
$data = file_get_contents($this->fileName, false, null, $this->offset);
|
115 |
+
foreach (preg_split("/^@@(?= [\w\d\.]+$)/m", $data, -1) as $chunk) {
|
116 |
+
if (trim($chunk)) {
|
117 |
+
list($name, $content) = explode("\n", $chunk, 2);
|
118 |
+
$this->templates[trim($name)] = trim($content);
|
119 |
+
}
|
120 |
+
}
|
121 |
+
}
|
122 |
+
}
|
123 |
+
}
|
vendor/mustache/mustache/src/Mustache/Loader/MutableLoader.php
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Mustache.php.
|
5 |
+
*
|
6 |
+
* (c) 2010-2014 Justin Hileman
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Mustache Template mutable Loader interface.
|
14 |
+
*/
|
15 |
+
interface Mustache_Loader_MutableLoader
|
16 |
+
{
|
17 |
+
/**
|
18 |
+
* Set an associative array of Template sources for this loader.
|
19 |
+
*
|
20 |
+
* @param array $templates
|
21 |
+
*
|
22 |
+
* @return void
|
23 |
+
*/
|
24 |
+
public function setTemplates(array $templates);
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Set a Template source by name.
|
28 |
+
*
|
29 |
+
* @param string $name
|
30 |
+
* @param string $template Mustache Template source
|
31 |
+
*
|
32 |
+
* @return void
|
33 |
+
*/
|
34 |
+
public function setTemplate($name, $template);
|
35 |
+
}
|
vendor/mustache/mustache/src/Mustache/Loader/StringLoader.php
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Mustache.php.
|
5 |
+
*
|
6 |
+
* (c) 2010-2014 Justin Hileman
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Mustache Template string Loader implementation.
|
14 |
+
*
|
15 |
+
* A StringLoader instance is essentially a noop. It simply passes the 'name' argument straight through:
|
16 |
+
*
|
17 |
+
* $loader = new StringLoader;
|
18 |
+
* $tpl = $loader->load('{{ foo }}'); // '{{ foo }}'
|
19 |
+
*
|
20 |
+
* This is the default Template Loader instance used by Mustache:
|
21 |
+
*
|
22 |
+
* $m = new Mustache;
|
23 |
+
* $tpl = $m->loadTemplate('{{ foo }}');
|
24 |
+
* echo $tpl->render(array('foo' => 'bar')); // "bar"
|
25 |
+
*/
|
26 |
+
class Mustache_Loader_StringLoader implements Mustache_Loader
|
27 |
+
{
|
28 |
+
/**
|
29 |
+
* Load a Template by source.
|
30 |
+
*
|
31 |
+
* @param string $name Mustache Template source
|
32 |
+
*
|
33 |
+
* @return string Mustache Template source
|
34 |
+
*/
|
35 |
+
public function load($name)
|
36 |
+
{
|
37 |
+
return $name;
|
38 |
+
}
|
39 |
+
}
|
vendor/mustache/mustache/src/Mustache/Logger.php
ADDED
@@ -0,0 +1,144 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Mustache.php.
|
5 |
+
*
|
6 |
+
* (c) 2010-2014 Justin Hileman
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Describes a Mustache logger instance
|
14 |
+
*
|
15 |
+
* This is identical to the Psr\Log\LoggerInterface.
|
16 |
+
*
|
17 |
+
* The message MUST be a string or object implementing __toString().
|
18 |
+
*
|
19 |
+
* The message MAY contain placeholders in the form: {foo} where foo
|
20 |
+
* will be replaced by the context data in key "foo".
|
21 |
+
*
|
22 |
+
* The context array can contain arbitrary data, the only assumption that
|
23 |
+
* can be made by implementors is that if an Exception instance is given
|
24 |
+
* to produce a stack trace, it MUST be in a key named "exception".
|
25 |
+
*
|
26 |
+
* See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md
|
27 |
+
* for the full interface specification.
|
28 |
+
*/
|
29 |
+
interface Mustache_Logger
|
30 |
+
{
|
31 |
+
/**
|
32 |
+
* Psr\Log compatible log levels
|
33 |
+
*/
|
34 |
+
const EMERGENCY = 'emergency';
|
35 |
+
const ALERT = 'alert';
|
36 |
+
const CRITICAL = 'critical';
|
37 |
+
const ERROR = 'error';
|
38 |
+
const WARNING = 'warning';
|
39 |
+
const NOTICE = 'notice';
|
40 |
+
const INFO = 'info';
|
41 |
+
const DEBUG = 'debug';
|
42 |
+
|
43 |
+
/**
|
44 |
+
* System is unusable.
|
45 |
+
*
|
46 |
+
* @param string $message
|
47 |
+
* @param array $context
|
48 |
+
*
|
49 |
+
* @return null
|
50 |
+
*/
|
51 |
+
public function emergency($message, array $context = array());
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Action must be taken immediately.
|
55 |
+
*
|
56 |
+
* Example: Entire website down, database unavailable, etc. This should
|
57 |
+
* trigger the SMS alerts and wake you up.
|
58 |
+
*
|
59 |
+
* @param string $message
|
60 |
+
* @param array $context
|
61 |
+
*
|
62 |
+
* @return null
|
63 |
+
*/
|
64 |
+
public function alert($message, array $context = array());
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Critical conditions.
|
68 |
+
*
|
69 |
+
* Example: Application component unavailable, unexpected exception.
|
70 |
+
*
|
71 |
+
* @param string $message
|
72 |
+
* @param array $context
|
73 |
+
*
|
74 |
+
* @return null
|
75 |
+
*/
|
76 |
+
public function critical($message, array $context = array());
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Runtime errors that do not require immediate action but should typically
|
80 |
+
* be logged and monitored.
|
81 |
+
*
|
82 |
+
* @param string $message
|
83 |
+
* @param array $context
|
84 |
+
*
|
85 |
+
* @return null
|
86 |
+
*/
|
87 |
+
public function error($message, array $context = array());
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Exceptional occurrences that are not errors.
|
91 |
+
*
|
92 |
+
* Example: Use of deprecated APIs, poor use of an API, undesirable things
|
93 |
+
* that are not necessarily wrong.
|
94 |
+
*
|
95 |
+
* @param string $message
|
96 |
+
* @param array $context
|
97 |
+
*
|
98 |
+
* @return null
|
99 |
+
*/
|
100 |
+
public function warning($message, array $context = array());
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Normal but significant events.
|
104 |
+
*
|
105 |
+
* @param string $message
|
106 |
+
* @param array $context
|
107 |
+
*
|
108 |
+
* @return null
|
109 |
+
*/
|
110 |
+
public function notice($message, array $context = array());
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Interesting events.
|
114 |
+
*
|
115 |
+
* Example: User logs in, SQL logs.
|
116 |
+
*
|
117 |
+
* @param string $message
|
118 |
+
* @param array $context
|
119 |
+
*
|
120 |
+
* @return null
|
121 |
+
*/
|
122 |
+
public function info($message, array $context = array());
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Detailed debug information.
|
126 |
+
*
|
127 |
+
* @param string $message
|
128 |
+
* @param array $context
|
129 |
+
*
|
130 |
+
* @return null
|
131 |
+
*/
|
132 |
+
public function debug($message, array $context = array());
|
133 |
+
|
134 |
+
/**
|
135 |
+
* Logs with an arbitrary level.
|
136 |
+
*
|
137 |
+
* @param mixed $level
|
138 |
+
* @param string $message
|
139 |
+
* @param array $context
|
140 |
+
*
|
141 |
+
* @return null
|
142 |
+
*/
|
143 |
+
public function log($level, $message, array $context = array());
|
144 |
+
}
|
vendor/mustache/mustache/src/Mustache/Logger/AbstractLogger.php
ADDED
@@ -0,0 +1,121 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Mustache.php.
|
5 |
+
*
|
6 |
+
* (c) 2010-2014 Justin Hileman
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* This is a simple Logger implementation that other Loggers can inherit from.
|
14 |
+
*
|
15 |
+
* This is identical to the Psr\Log\AbstractLogger.
|
16 |
+
*
|
17 |
+
* It simply delegates all log-level-specific methods to the `log` method to
|
18 |
+
* reduce boilerplate code that a simple Logger that does the same thing with
|
19 |
+
* messages regardless of the error level has to implement.
|
20 |
+
*/
|
21 |
+
abstract class Mustache_Logger_AbstractLogger implements Mustache_Logger
|
22 |
+
{
|
23 |
+
/**
|
24 |
+
* System is unusable.
|
25 |
+
*
|
26 |
+
* @param string $message
|
27 |
+
* @param array $context
|
28 |
+
*/
|
29 |
+
public function emergency($message, array $context = array())
|
30 |
+
{
|
31 |
+
$this->log(Mustache_Logger::EMERGENCY, $message, $context);
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Action must be taken immediately.
|
36 |
+
*
|
37 |
+
* Example: Entire website down, database unavailable, etc. This should
|
38 |
+
* trigger the SMS alerts and wake you up.
|
39 |
+
*
|
40 |
+
* @param string $message
|
41 |
+
* @param array $context
|
42 |
+
*/
|
43 |
+
public function alert($message, array $context = array())
|
44 |
+
{
|
45 |
+
$this->log(Mustache_Logger::ALERT, $message, $context);
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Critical conditions.
|
50 |
+
*
|
51 |
+
* Example: Application component unavailable, unexpected exception.
|
52 |
+
*
|
53 |
+
* @param string $message
|
54 |
+
* @param array $context
|
55 |
+
*/
|
56 |
+
public function critical($message, array $context = array())
|
57 |
+
{
|
58 |
+
$this->log(Mustache_Logger::CRITICAL, $message, $context);
|
59 |
+
}
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Runtime errors that do not require immediate action but should typically
|
63 |
+
* be logged and monitored.
|
64 |
+
*
|
65 |
+
* @param string $message
|
66 |
+
* @param array $context
|
67 |
+
*/
|
68 |
+
public function error($message, array $context = array())
|
69 |
+
{
|
70 |
+
$this->log(Mustache_Logger::ERROR, $message, $context);
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Exceptional occurrences that are not errors.
|
75 |
+
*
|
76 |
+
* Example: Use of deprecated APIs, poor use of an API, undesirable things
|
77 |
+
* that are not necessarily wrong.
|
78 |
+
*
|
79 |
+
* @param string $message
|
80 |
+
* @param array $context
|
81 |
+
*/
|
82 |
+
public function warning($message, array $context = array())
|
83 |
+
{
|
84 |
+
$this->log(Mustache_Logger::WARNING, $message, $context);
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Normal but significant events.
|
89 |
+
*
|
90 |
+
* @param string $message
|
91 |
+
* @param array $context
|
92 |
+
*/
|
93 |
+
public function notice($message, array $context = array())
|
94 |
+
{
|
95 |
+
$this->log(Mustache_Logger::NOTICE, $message, $context);
|
96 |
+
}
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Interesting events.
|
100 |
+
*
|
101 |
+
* Example: User logs in, SQL logs.
|
102 |
+
*
|
103 |
+
* @param string $message
|
104 |
+
* @param array $context
|
105 |
+
*/
|
106 |
+
public function info($message, array $context = array())
|
107 |
+
{
|
108 |
+
$this->log(Mustache_Logger::INFO, $message, $context);
|
109 |
+
}
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Detailed debug information.
|
113 |
+
*
|
114 |
+
* @param string $message
|
115 |
+
* @param array $context
|
116 |
+
*/
|
117 |
+
public function debug($message, array $context = array())
|
118 |
+
{
|
119 |
+
$this->log(Mustache_Logger::DEBUG, $message, $context);
|
120 |
+
}
|
121 |
+
}
|
vendor/mustache/mustache/src/Mustache/Logger/StreamLogger.php
ADDED
@@ -0,0 +1,194 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Mustache.php.
|
5 |
+
*
|
6 |
+
* (c) 2010-2014 Justin Hileman
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* A Mustache Stream Logger.
|
14 |
+
*
|
15 |
+
* The Stream Logger wraps a file resource instance (such as a stream) or a
|
16 |
+
* stream URL. All log messages over the threshold level will be appended to
|
17 |
+
* this stream.
|
18 |
+
*
|
19 |
+
* Hint: Try `php://stderr` for your stream URL.
|
20 |
+
*/
|
21 |
+
class Mustache_Logger_StreamLogger extends Mustache_Logger_AbstractLogger
|
22 |
+
{
|
23 |
+
protected static $levels = array(
|
24 |
+
self::DEBUG => 100,
|
25 |
+
self::INFO => 200,
|
26 |
+
self::NOTICE => 250,
|
27 |
+
self::WARNING => 300,
|
28 |
+
self::ERROR => 400,
|
29 |
+
self::CRITICAL => 500,
|
30 |
+
self::ALERT => 550,
|
31 |
+
self::EMERGENCY => 600,
|
32 |
+
);
|
33 |
+
|
34 |
+
protected $level;
|
35 |
+
protected $stream = null;
|
36 |
+
protected $url = null;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* @throws InvalidArgumentException if the logging level is unknown.
|
40 |
+
*
|
41 |
+
* @param resource|string $stream Resource instance or URL
|
42 |
+
* @param integer $level The minimum logging level at which this handler will be triggered
|
43 |
+
*/
|
44 |
+
public function __construct($stream, $level = Mustache_Logger::ERROR)
|
45 |
+
{
|
46 |
+
$this->setLevel($level);
|
47 |
+
|
48 |
+
if (is_resource($stream)) {
|
49 |
+
$this->stream = $stream;
|
50 |
+
} else {
|
51 |
+
$this->url = $stream;
|
52 |
+
}
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Close stream resources.
|
57 |
+
*/
|
58 |
+
public function __destruct()
|
59 |
+
{
|
60 |
+
if (is_resource($this->stream)) {
|
61 |
+
fclose($this->stream);
|
62 |
+
}
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Set the minimum logging level.
|
67 |
+
*
|
68 |
+
* @throws Mustache_Exception_InvalidArgumentException if the logging level is unknown.
|
69 |
+
*
|
70 |
+
* @param integer $level The minimum logging level which will be written
|
71 |
+
*/
|
72 |
+
public function setLevel($level)
|
73 |
+
{
|
74 |
+
if (!array_key_exists($level, self::$levels)) {
|
75 |
+
throw new Mustache_Exception_InvalidArgumentException(sprintf('Unexpected logging level: %s', $level));
|
76 |
+
}
|
77 |
+
|
78 |
+
$this->level = $level;
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Get the current minimum logging level.
|
83 |
+
*
|
84 |
+
* @return integer
|
85 |
+
*/
|
86 |
+
public function getLevel()
|
87 |
+
{
|
88 |
+
return $this->level;
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Logs with an arbitrary level.
|
93 |
+
*
|
94 |
+
* @throws Mustache_Exception_InvalidArgumentException if the logging level is unknown.
|
95 |
+
*
|
96 |
+
* @param mixed $level
|
97 |
+
* @param string $message
|
98 |
+
* @param array $context
|
99 |
+
*/
|
100 |
+
public function log($level, $message, array $context = array())
|
101 |
+
{
|
102 |
+
if (!array_key_exists($level, self::$levels)) {
|
103 |
+
throw new Mustache_Exception_InvalidArgumentException(sprintf('Unexpected logging level: %s', $level));
|
104 |
+
}
|
105 |
+
|
106 |
+
if (self::$levels[$level] >= self::$levels[$this->level]) {
|
107 |
+
$this->writeLog($level, $message, $context);
|
108 |
+
}
|
109 |
+
}
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Write a record to the log.
|
113 |
+
*
|
114 |
+
* @throws Mustache_Exception_LogicException If neither a stream resource nor url is present.
|
115 |
+
* @throws Mustache_Exception_RuntimeException If the stream url cannot be opened.
|
116 |
+
*
|
117 |
+
* @param integer $level The logging level
|
118 |
+
* @param string $message The log message
|
119 |
+
* @param array $context The log context
|
120 |
+
*/
|
121 |
+
protected function writeLog($level, $message, array $context = array())
|
122 |
+
{
|
123 |
+
if (!is_resource($this->stream)) {
|
124 |
+
if (!isset($this->url)) {
|
125 |
+
throw new Mustache_Exception_LogicException('Missing stream url, the stream can not be opened. This may be caused by a premature call to close().');
|
126 |
+
}
|
127 |
+
|
128 |
+
$this->stream = fopen($this->url, 'a');
|
129 |
+
if (!is_resource($this->stream)) {
|
130 |
+
// @codeCoverageIgnoreStart
|
131 |
+
throw new Mustache_Exception_RuntimeException(sprintf('The stream or file "%s" could not be opened.', $this->url));
|
132 |
+
// @codeCoverageIgnoreEnd
|
133 |
+
}
|
134 |
+
}
|
135 |
+
|
136 |
+
fwrite($this->stream, self::formatLine($level, $message, $context));
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* Gets the name of the logging level.
|
141 |
+
*
|
142 |
+
* @throws InvalidArgumentException if the logging level is unknown.
|
143 |
+
*
|
144 |
+
* @param integer $level
|
145 |
+
*
|
146 |
+
* @return string
|
147 |
+
*/
|
148 |
+
protected static function getLevelName($level)
|
149 |
+
{
|
150 |
+
return strtoupper($level);
|
151 |
+
}
|
152 |
+
|
153 |
+
/**
|
154 |
+
* Format a log line for output.
|
155 |
+
*
|
156 |
+
* @param integer $level The logging level
|
157 |
+
* @param string $message The log message
|
158 |
+
* @param array $context The log context
|
159 |
+
*
|
160 |
+
* @return string
|
161 |
+
*/
|
162 |
+
protected static function formatLine($level, $message, array $context = array())
|
163 |
+
{
|
164 |
+
return sprintf(
|
165 |
+
"%s: %s\n",
|
166 |
+
self::getLevelName($level),
|
167 |
+
self::interpolateMessage($message, $context)
|
168 |
+
);
|
169 |
+
}
|
170 |
+
|
171 |
+
/**
|
172 |
+
* Interpolate context values into the message placeholders.
|
173 |
+
*
|
174 |
+
* @param string $message
|
175 |
+
* @param array $context
|
176 |
+
*
|
177 |
+
* @return string
|
178 |
+
*/
|
179 |
+
protected static function interpolateMessage($message, array $context = array())
|
180 |
+
{
|
181 |
+
if (strpos($message, '{') === false) {
|
182 |
+
return $message;
|
183 |
+
}
|
184 |
+
|
185 |
+
// build a replacement array with braces around the context keys
|
186 |
+
$replace = array();
|
187 |
+
foreach ($context as $key => $val) {
|
188 |
+
$replace['{' . $key . '}'] = $val;
|
189 |
+
}
|
190 |
+
|
191 |
+
// interpolate replacement values into the the message and return
|
192 |
+
return strtr($message, $replace);
|
193 |
+
}
|
194 |
+
}
|
vendor/mustache/mustache/src/Mustache/Parser.php
ADDED
@@ -0,0 +1,206 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Mustache.php.
|
5 |
+
*
|
6 |
+
* (c) 2010-2014 Justin Hileman
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Mustache Parser class.
|
14 |
+
*
|
15 |
+
* This class is responsible for turning a set of Mustache tokens into a parse tree.
|
16 |
+
*/
|
17 |
+
class Mustache_Parser
|
18 |
+
{
|
19 |
+
private $lineNum;
|
20 |
+
private $lineTokens;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Process an array of Mustache tokens and convert them into a parse tree.
|
24 |
+
*
|
25 |
+
* @param array $tokens Set of Mustache tokens
|
26 |
+
*
|
27 |
+
* @return array Mustache token parse tree
|
28 |
+
*/
|
29 |
+
public function parse(array $tokens = array())
|
30 |
+
{
|
31 |
+
$this->lineNum = -1;
|
32 |
+
$this->lineTokens = 0;
|
33 |
+
|
34 |
+
return $this->buildTree($tokens);
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Helper method for recursively building a parse tree.
|
39 |
+
*
|
40 |
+
* @throws Mustache_Exception_SyntaxException when nesting errors or mismatched section tags are encountered.
|
41 |
+
*
|
42 |
+
* @param array &$tokens Set of Mustache tokens
|
43 |
+
* @param array $parent Parent token (default: null)
|
44 |
+
*
|
45 |
+
* @return array Mustache Token parse tree
|
46 |
+
*/
|
47 |
+
private function buildTree(array &$tokens, array $parent = null)
|
48 |
+
{
|
49 |
+
$nodes = array();
|
50 |
+
|
51 |
+
while (!empty($tokens)) {
|
52 |
+
$token = array_shift($tokens);
|
53 |
+
|
54 |
+
if ($token[Mustache_Tokenizer::LINE] === $this->lineNum) {
|
55 |
+
$this->lineTokens++;
|
56 |
+
} else {
|
57 |
+
$this->lineNum = $token[Mustache_Tokenizer::LINE];
|
58 |
+
$this->lineTokens = 0;
|
59 |
+
}
|
60 |
+
|
61 |
+
switch ($token[Mustache_Tokenizer::TYPE]) {
|
62 |
+
case Mustache_Tokenizer::T_DELIM_CHANGE:
|
63 |
+
$this->clearStandaloneLines($nodes, $tokens);
|
64 |
+
break;
|
65 |
+
|
66 |
+
case Mustache_Tokenizer::T_SECTION:
|
67 |
+
case Mustache_Tokenizer::T_INVERTED:
|
68 |
+
$this->clearStandaloneLines($nodes, $tokens);
|
69 |
+
$nodes[] = $this->buildTree($tokens, $token);
|
70 |
+
break;
|
71 |
+
|
72 |
+
case Mustache_Tokenizer::T_END_SECTION:
|
73 |
+
if (!isset($parent)) {
|
74 |
+
$msg = sprintf(
|
75 |
+
'Unexpected closing tag: /%s on line %d',
|
76 |
+
$token[Mustache_Tokenizer::NAME],
|
77 |
+
$token[Mustache_Tokenizer::LINE]
|
78 |
+
);
|
79 |
+
throw new Mustache_Exception_SyntaxException($msg, $token);
|
80 |
+
}
|
81 |
+
|
82 |
+
if ($token[Mustache_Tokenizer::NAME] !== $parent[Mustache_Tokenizer::NAME]) {
|
83 |
+
$msg = sprintf(
|
84 |
+
'Nesting error: %s (on line %d) vs. %s (on line %d)',
|
85 |
+
$parent[Mustache_Tokenizer::NAME],
|
86 |
+
$parent[Mustache_Tokenizer::LINE],
|
87 |
+
$token[Mustache_Tokenizer::NAME],
|
88 |
+
$token[Mustache_Tokenizer::LINE]
|
89 |
+
);
|
90 |
+
throw new Mustache_Exception_SyntaxException($msg, $token);
|
91 |
+
}
|
92 |
+
|
93 |
+
$this->clearStandaloneLines($nodes, $tokens);
|
94 |
+
$parent[Mustache_Tokenizer::END] = $token[Mustache_Tokenizer::INDEX];
|
95 |
+
$parent[Mustache_Tokenizer::NODES] = $nodes;
|
96 |
+
|
97 |
+
return $parent;
|
98 |
+
|
99 |
+
case Mustache_Tokenizer::T_PARTIAL:
|
100 |
+
case Mustache_Tokenizer::T_PARTIAL_2:
|
101 |
+
// store the whitespace prefix for laters!
|
102 |
+
if ($indent = $this->clearStandaloneLines($nodes, $tokens)) {
|
103 |
+
$token[Mustache_Tokenizer::INDENT] = $indent[Mustache_Tokenizer::VALUE];
|
104 |
+
}
|
105 |
+
$nodes[] = $token;
|
106 |
+
break;
|
107 |
+
|
108 |
+
case Mustache_Tokenizer::T_PRAGMA:
|
109 |
+
case Mustache_Tokenizer::T_COMMENT:
|
110 |
+
$this->clearStandaloneLines($nodes, $tokens);
|
111 |
+
$nodes[] = $token;
|
112 |
+
break;
|
113 |
+
|
114 |
+
default:
|
115 |
+
$nodes[] = $token;
|
116 |
+
break;
|
117 |
+
}
|
118 |
+
}
|
119 |
+
|
120 |
+
if (isset($parent)) {
|
121 |
+
$msg = sprintf(
|
122 |
+
'Missing closing tag: %s opened on line %d',
|
123 |
+
$parent[Mustache_Tokenizer::NAME],
|
124 |
+
$parent[Mustache_Tokenizer::LINE]
|
125 |
+
);
|
126 |
+
throw new Mustache_Exception_SyntaxException($msg, $parent);
|
127 |
+
}
|
128 |
+
|
129 |
+
return $nodes;
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Clear standalone line tokens.
|
134 |
+
*
|
135 |
+
* Returns a whitespace token for indenting partials, if applicable.
|
136 |
+
*
|
137 |
+
* @param array $nodes Parsed nodes.
|
138 |
+
* @param array $tokens Tokens to be parsed.
|
139 |
+
*
|
140 |
+
* @return array Resulting indent token, if any.
|
141 |
+
*/
|
142 |
+
private function clearStandaloneLines(array &$nodes, array &$tokens)
|
143 |
+
{
|
144 |
+
if ($this->lineTokens > 1) {
|
145 |
+
// this is the third or later node on this line, so it can't be standalone
|
146 |
+
return;
|
147 |
+
}
|
148 |
+
|
149 |
+
$prev = null;
|
150 |
+
if ($this->lineTokens === 1) {
|
151 |
+
// this is the second node on this line, so it can't be standalone
|
152 |
+
// unless the previous node is whitespace.
|
153 |
+
if ($prev = end($nodes)) {
|
154 |
+
if (!$this->tokenIsWhitespace($prev)) {
|
155 |
+
return;
|
156 |
+
}
|
157 |
+
}
|
158 |
+
}
|
159 |
+
|
160 |
+
if ($next = reset($tokens)) {
|
161 |
+
// If we're on a new line, bail.
|
162 |
+
if ($next[Mustache_Tokenizer::LINE] !== $this->lineNum) {
|
163 |
+
return;
|
164 |
+
}
|
165 |
+
|
166 |
+
// If the next token isn't whitespace, bail.
|
167 |
+
if (!$this->tokenIsWhitespace($next)) {
|
168 |
+
return;
|
169 |
+
}
|
170 |
+
|
171 |
+
if (count($tokens) !== 1) {
|
172 |
+
// Unless it's the last token in the template, the next token
|
173 |
+
// must end in newline for this to be standalone.
|
174 |
+
if (substr($next[Mustache_Tokenizer::VALUE], -1) !== "\n") {
|
175 |
+
return;
|
176 |
+
}
|
177 |
+
}
|
178 |
+
|
179 |
+
// Discard the whitespace suffix
|
180 |
+
array_shift($tokens);
|
181 |
+
}
|
182 |
+
|
183 |
+
if ($prev) {
|
184 |
+
// Return the whitespace prefix, if any
|
185 |
+
return array_pop($nodes);
|
186 |
+
}
|
187 |
+
}
|
188 |
+
|
189 |
+
/**
|
190 |
+
* Check whether token is a whitespace token.
|
191 |
+
*
|
192 |
+
* True if token type is T_TEXT and value is all whitespace characters.
|
193 |
+
*
|
194 |
+
* @param array $token
|
195 |
+
*
|
196 |
+
* @return boolean True if token is a whitespace token
|
197 |
+
*/
|
198 |
+
private function tokenIsWhitespace(array $token)
|
199 |
+
{
|
200 |
+
if ($token[Mustache_Tokenizer::TYPE] == Mustache_Tokenizer::T_TEXT) {
|
201 |
+
return preg_match('/^\s*$/', $token[Mustache_Tokenizer::VALUE]);
|
202 |
+
}
|
203 |
+
|
204 |
+
return false;
|
205 |
+
}
|
206 |
+
}
|
vendor/mustache/mustache/src/Mustache/Template.php
ADDED
@@ -0,0 +1,176 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Mustache.php.
|
5 |
+
*
|
6 |
+
* (c) 2010-2014 Justin Hileman
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Abstract Mustache Template class.
|
14 |
+
*
|
15 |
+
* @abstract
|
16 |
+
*/
|
17 |
+
abstract class Mustache_Template
|
18 |
+
{
|
19 |
+
/**
|
20 |
+
* @var Mustache_Engine
|
21 |
+
*/
|
22 |
+
protected $mustache;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @var boolean
|
26 |
+
*/
|
27 |
+
protected $strictCallables = false;
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Mustache Template constructor.
|
31 |
+
*
|
32 |
+
* @param Mustache_Engine $mustache
|
33 |
+
*/
|
34 |
+
public function __construct(Mustache_Engine $mustache)
|
35 |
+
{
|
36 |
+
$this->mustache = $mustache;
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Mustache Template instances can be treated as a function and rendered by simply calling them:
|
41 |
+
*
|
42 |
+
* $m = new Mustache_Engine;
|
43 |
+
* $tpl = $m->loadTemplate('Hello, {{ name }}!');
|
44 |
+
* echo $tpl(array('name' => 'World')); // "Hello, World!"
|
45 |
+
*
|
46 |
+
* @see Mustache_Template::render
|
47 |
+
*
|
48 |
+
* @param mixed $context Array or object rendering context (default: array())
|
49 |
+
*
|
50 |
+
* @return string Rendered template
|
51 |
+
*/
|
52 |
+
public function __invoke($context = array())
|
53 |
+
{
|
54 |
+
return $this->render($context);
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Render this template given the rendering context.
|
59 |
+
*
|
60 |
+
* @param mixed $context Array or object rendering context (default: array())
|
61 |
+
*
|
62 |
+
* @return string Rendered template
|
63 |
+
*/
|
64 |
+
public function render($context = array())
|
65 |
+
{
|
66 |
+
return $this->renderInternal($this->prepareContextStack($context));
|
67 |
+
}
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Internal rendering method implemented by Mustache Template concrete subclasses.
|
71 |
+
*
|
72 |
+
* This is where the magic happens :)
|
73 |
+
*
|
74 |
+
* NOTE: This method is not part of the Mustache.php public API.
|
75 |
+
*
|
76 |
+
* @param Mustache_Context $context
|
77 |
+
* @param string $indent (default: '')
|
78 |
+
*
|
79 |
+
* @return string Rendered template
|
80 |
+
*/
|
81 |
+
abstract public function renderInternal(Mustache_Context $context, $indent = '');
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Tests whether a value should be iterated over (e.g. in a section context).
|
85 |
+
*
|
86 |
+
* In most languages there are two distinct array types: list and hash (or whatever you want to call them). Lists
|
87 |
+
* should be iterated, hashes should be treated as objects. Mustache follows this paradigm for Ruby, Javascript,
|
88 |
+
* Java, Python, etc.
|
89 |
+
*
|
90 |
+
* PHP, however, treats lists and hashes as one primitive type: array. So Mustache.php needs a way to distinguish
|
91 |
+
* between between a list of things (numeric, normalized array) and a set of variables to be used as section context
|
92 |
+
* (associative array). In other words, this will be iterated over:
|
93 |
+
*
|
94 |
+
* $items = array(
|
95 |
+
* array('name' => 'foo'),
|
96 |
+
* array('name' => 'bar'),
|
97 |
+
* array('name' => 'baz'),
|
98 |
+
* );
|
99 |
+
*
|
100 |
+
* ... but this will be used as a section context block:
|
101 |
+
*
|
102 |
+
* $items = array(
|
103 |
+
* 1 => array('name' => 'foo'),
|
104 |
+
* 'banana' => array('name' => 'bar'),
|
105 |
+
* 42 => array('name' => 'baz'),
|
106 |
+
* );
|
107 |
+
*
|
108 |
+
* @param mixed $value
|
109 |
+
*
|
110 |
+
* @return boolean True if the value is 'iterable'
|
111 |
+
*/
|
112 |
+
protected function isIterable($value)
|
113 |
+
{
|
114 |
+
if (is_object($value)) {
|
115 |
+
return $value instanceof Traversable;
|
116 |
+
} elseif (is_array($value)) {
|
117 |
+
$i = 0;
|
118 |
+
foreach ($value as $k => $v) {
|
119 |
+
if ($k !== $i++) {
|
120 |
+
return false;
|
121 |
+
}
|
122 |
+
}
|
123 |
+
|
124 |
+
return true;
|
125 |
+
} else {
|
126 |
+
return false;
|
127 |
+
}
|
128 |
+
}
|
129 |
+
|
130 |
+
/**
|
131 |
+
* Helper method to prepare the Context stack.
|
132 |
+
*
|
133 |
+
* Adds the Mustache HelperCollection to the stack's top context frame if helpers are present.
|
134 |
+
*
|
135 |
+
* @param mixed $context Optional first context frame (default: null)
|
136 |
+
*
|
137 |
+
* @return Mustache_Context
|
138 |
+
*/
|
139 |
+
protected function prepareContextStack($context = null)
|
140 |
+
{
|
141 |
+
$stack = new Mustache_Context;
|
142 |
+
|
143 |
+
$helpers = $this->mustache->getHelpers();
|
144 |
+
if (!$helpers->isEmpty()) {
|
145 |
+
$stack->push($helpers);
|
146 |
+
}
|
147 |
+
|
148 |
+
if (!empty($context)) {
|
149 |
+
$stack->push($context);
|
150 |
+
}
|
151 |
+
|
152 |
+
return $stack;
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Resolve a context value.
|
157 |
+
*
|
158 |
+
* Invoke the value if it is callable, otherwise return the value.
|
159 |
+
*
|
160 |
+
* @param mixed $value
|
161 |
+
* @param Mustache_Context $context
|
162 |
+
* @param string $indent
|
163 |
+
*
|
164 |
+
* @return string
|
165 |
+
*/
|
166 |
+
protected function resolveValue($value, Mustache_Context $context, $indent = '')
|
167 |
+
{
|
168 |
+
if (($this->strictCallables ? is_object($value) : !is_string($value)) && is_callable($value)) {
|
169 |
+
return $this->mustache
|
170 |
+
->loadLambda((string) call_user_func($value))
|
171 |
+
->renderInternal($context, $indent);
|
172 |
+
}
|
173 |
+
|
174 |
+
return $value;
|
175 |
+
}
|
176 |
+
}
|
vendor/mustache/mustache/src/Mustache/Tokenizer.php
ADDED
@@ -0,0 +1,327 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Mustache.php.
|
5 |
+
*
|
6 |
+
* (c) 2010-2014 Justin Hileman
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Mustache Tokenizer class.
|
14 |
+
*
|
15 |
+
* This class is responsible for turning raw template source into a set of Mustache tokens.
|
16 |
+
*/
|
17 |
+
class Mustache_Tokenizer
|
18 |
+
{
|
19 |
+
// Finite state machine states
|
20 |
+
const IN_TEXT = 0;
|
21 |
+
const IN_TAG_TYPE = 1;
|
22 |
+
const IN_TAG = 2;
|
23 |
+
|
24 |
+
// Token types
|
25 |
+
const T_SECTION = '#';
|
26 |
+
const T_INVERTED = '^';
|
27 |
+
const T_END_SECTION = '/';
|
28 |
+
const T_COMMENT = '!';
|
29 |
+
const T_PARTIAL = '>';
|
30 |
+
const T_PARTIAL_2 = '<';
|
31 |
+
const T_DELIM_CHANGE = '=';
|
32 |
+
const T_ESCAPED = '_v';
|
33 |
+
const T_UNESCAPED = '{';
|
34 |
+
const T_UNESCAPED_2 = '&';
|
35 |
+
const T_TEXT = '_t';
|
36 |
+
const T_PRAGMA = '%';
|
37 |
+
|
38 |
+
// Valid token types
|
39 |
+
private static $tagTypes = array(
|
40 |
+
self::T_SECTION => true,
|
41 |
+
self::T_INVERTED => true,
|
42 |
+
self::T_END_SECTION => true,
|
43 |
+
self::T_COMMENT => true,
|
44 |
+
self::T_PARTIAL => true,
|
45 |
+
self::T_PARTIAL_2 => true,
|
46 |
+
self::T_DELIM_CHANGE => true,
|
47 |
+
self::T_ESCAPED => true,
|
48 |
+
self::T_UNESCAPED => true,
|
49 |
+
self::T_UNESCAPED_2 => true,
|
50 |
+
self::T_PRAGMA => true,
|
51 |
+
);
|
52 |
+
|
53 |
+
// Interpolated tags
|
54 |
+
private static $interpolatedTags = array(
|
55 |
+
self::T_ESCAPED => true,
|
56 |
+
self::T_UNESCAPED => true,
|
57 |
+
self::T_UNESCAPED_2 => true,
|
58 |
+
);
|
59 |
+
|
60 |
+
// Token properties
|
61 |
+
const TYPE = 'type';
|
62 |
+
const NAME = 'name';
|
63 |
+
const OTAG = 'otag';
|
64 |
+
const CTAG = 'ctag';
|
65 |
+
const LINE = 'line';
|
66 |
+
const INDEX = 'index';
|
67 |
+
const END = 'end';
|
68 |
+
const INDENT = 'indent';
|
69 |
+
const NODES = 'nodes';
|
70 |
+
const VALUE = 'value';
|
71 |
+
|
72 |
+
private $state;
|
73 |
+
private $tagType;
|
74 |
+
private $tag;
|
75 |
+
private $buffer;
|
76 |
+
private $tokens;
|
77 |
+
private $seenTag;
|
78 |
+
private $line;
|
79 |
+
private $otag;
|
80 |
+
private $ctag;
|
81 |
+
private $otagLen;
|
82 |
+
private $ctagLen;
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Scan and tokenize template source.
|
86 |
+
*
|
87 |
+
* @throws Mustache_Exception_SyntaxException when mismatched section tags are encountered.
|
88 |
+
*
|
89 |
+
* @param string $text Mustache template source to tokenize
|
90 |
+
* @param string $delimiters Optionally, pass initial opening and closing delimiters (default: null)
|
91 |
+
*
|
92 |
+
* @return array Set of Mustache tokens
|
93 |
+
*/
|
94 |
+
public function scan($text, $delimiters = null)
|
95 |
+
{
|
96 |
+
// Setting mbstring.func_overload makes things *really* slow.
|
97 |
+
// Let's do everyone a favor and scan this string as ASCII instead.
|
98 |
+
$encoding = null;
|
99 |
+
if (function_exists('mb_internal_encoding') && ini_get('mbstring.func_overload') & 2) {
|
100 |
+
$encoding = mb_internal_encoding();
|
101 |
+
mb_internal_encoding('ASCII');
|
102 |
+
}
|
103 |
+
|
104 |
+
$this->reset();
|
105 |
+
|
106 |
+
if ($delimiters = trim($delimiters)) {
|
107 |
+
$this->setDelimiters($delimiters);
|
108 |
+
}
|
109 |
+
|
110 |
+
$len = strlen($text);
|
111 |
+
for ($i = 0; $i < $len; $i++) {
|
112 |
+
switch ($this->state) {
|
113 |
+
case self::IN_TEXT:
|
114 |
+
if ($this->tagChange($this->otag, $this->otagLen, $text, $i)) {
|
115 |
+
$i--;
|
116 |
+
$this->flushBuffer();
|
117 |
+
$this->state = self::IN_TAG_TYPE;
|
118 |
+
} else {
|
119 |
+
$char = $text[$i];
|
120 |
+
$this->buffer .= $char;
|
121 |
+
if ($char === "\n") {
|
122 |
+
$this->flushBuffer();
|
123 |
+
$this->line++;
|
124 |
+
}
|
125 |
+
}
|
126 |
+
break;
|
127 |
+
|
128 |
+
case self::IN_TAG_TYPE:
|
129 |
+
$i += $this->otagLen - 1;
|
130 |
+
$char = $text[$i + 1];
|
131 |
+
if (isset(self::$tagTypes[$char])) {
|
132 |
+
$tag = $char;
|
133 |
+
$this->tagType = $tag;
|
134 |
+
} else {
|
135 |
+
$tag = null;
|
136 |
+
$this->tagType = self::T_ESCAPED;
|
137 |
+
}
|
138 |
+
|
139 |
+
if ($this->tagType === self::T_DELIM_CHANGE) {
|
140 |
+
$i = $this->changeDelimiters($text, $i);
|
141 |
+
$this->state = self::IN_TEXT;
|
142 |
+
} elseif ($this->tagType === self::T_PRAGMA) {
|
143 |
+
$i = $this->addPragma($text, $i);
|
144 |
+
$this->state = self::IN_TEXT;
|
145 |
+
} else {
|
146 |
+
if ($tag !== null) {
|
147 |
+
$i++;
|
148 |
+
}
|
149 |
+
$this->state = self::IN_TAG;
|
150 |
+
}
|
151 |
+
$this->seenTag = $i;
|
152 |
+
break;
|
153 |
+
|
154 |
+
default:
|
155 |
+
if ($this->tagChange($this->ctag, $this->ctagLen, $text, $i)) {
|
156 |
+
$token = array(
|
157 |
+
self::TYPE => $this->tagType,
|
158 |
+
self::NAME => trim($this->buffer),
|
159 |
+
self::OTAG => $this->otag,
|
160 |
+
self::CTAG => $this->ctag,
|
161 |
+
self::LINE => $this->line,
|
162 |
+
self::INDEX => ($this->tagType === self::T_END_SECTION) ? $this->seenTag - $this->otagLen : $i + $this->ctagLen
|
163 |
+
);
|
164 |
+
|
165 |
+
if ($this->tagType === self::T_UNESCAPED) {
|
166 |
+
// Clean up `{{{ tripleStache }}}` style tokens.
|
167 |
+
if ($this->ctag === '}}') {
|
168 |
+
if (($i + 2 < $len) && $text[$i + 2] === '}') {
|
169 |
+
$i++;
|
170 |
+
} else {
|
171 |
+
$msg = sprintf(
|
172 |
+
'Mismatched tag delimiters: %s on line %d',
|
173 |
+
$token[self::NAME],
|
174 |
+
$token[self::LINE]
|
175 |
+
);
|
176 |
+
|
177 |
+
throw new Mustache_Exception_SyntaxException($msg, $token);
|
178 |
+
}
|
179 |
+
} else {
|
180 |
+
$lastName = $token[self::NAME];
|
181 |
+
if (substr($lastName, -1) === '}') {
|
182 |
+
$token[self::NAME] = trim(substr($lastName, 0, -1));
|
183 |
+
} else {
|
184 |
+
$msg = sprintf(
|
185 |
+
'Mismatched tag delimiters: %s on line %d',
|
186 |
+
$token[self::NAME],
|
187 |
+
$token[self::LINE]
|
188 |
+
);
|
189 |
+
|
190 |
+
throw new Mustache_Exception_SyntaxException($msg, $token);
|
191 |
+
}
|
192 |
+
}
|
193 |
+
}
|
194 |
+
|
195 |
+
$this->buffer = '';
|
196 |
+
$i += $this->ctagLen - 1;
|
197 |
+
$this->state = self::IN_TEXT;
|
198 |
+
$this->tokens[] = $token;
|
199 |
+
} else {
|
200 |
+
$this->buffer .= $text[$i];
|
201 |
+
}
|
202 |
+
break;
|
203 |
+
}
|
204 |
+
}
|
205 |
+
|
206 |
+
$this->flushBuffer();
|
207 |
+
|
208 |
+
// Restore the user's encoding...
|
209 |
+
if ($encoding) {
|
210 |
+
mb_internal_encoding($encoding);
|
211 |
+
}
|
212 |
+
|
213 |
+
return $this->tokens;
|
214 |
+
}
|
215 |
+
|
216 |
+
/**
|
217 |
+
* Helper function to reset tokenizer internal state.
|
218 |
+
*/
|
219 |
+
private function reset()
|
220 |
+
{
|
221 |
+
$this->state = self::IN_TEXT;
|
222 |
+
$this->tagType = null;
|
223 |
+
$this->tag = null;
|
224 |
+
$this->buffer = '';
|
225 |
+
$this->tokens = array();
|
226 |
+
$this->seenTag = false;
|
227 |
+
$this->line = 0;
|
228 |
+
$this->otag = '{{';
|
229 |
+
$this->ctag = '}}';
|
230 |
+
$this->otagLen = 2;
|
231 |
+
$this->ctagLen = 2;
|
232 |
+
}
|
233 |
+
|
234 |
+
/**
|
235 |
+
* Flush the current buffer to a token.
|
236 |
+
*/
|
237 |
+
private function flushBuffer()
|
238 |
+
{
|
239 |
+
if (strlen($this->buffer) > 0) {
|
240 |
+
$this->tokens[] = array(
|
241 |
+
self::TYPE => self::T_TEXT,
|
242 |
+
self::LINE => $this->line,
|
243 |
+
self::VALUE => $this->buffer
|
244 |
+
);
|
245 |
+
$this->buffer = '';
|
246 |
+
}
|
247 |
+
}
|
248 |
+
|
249 |
+
/**
|
250 |
+
* Change the current Mustache delimiters. Set new `otag` and `ctag` values.
|
251 |
+
*
|
252 |
+
* @param string $text Mustache template source
|
253 |
+
* @param int $index Current tokenizer index
|
254 |
+
*
|
255 |
+
* @return int New index value
|
256 |
+
*/
|
257 |
+
private function changeDelimiters($text, $index)
|
258 |
+
{
|
259 |
+
$startIndex = strpos($text, '=', $index) + 1;
|
260 |
+
$close = '='.$this->ctag;
|
261 |
+
$closeIndex = strpos($text, $close, $index);
|
262 |
+
|
263 |
+
$this->setDelimiters(trim(substr($text, $startIndex, $closeIndex - $startIndex)));
|
264 |
+
|
265 |
+
$this->tokens[] = array(
|
266 |
+
self::TYPE => self::T_DELIM_CHANGE,
|
267 |
+
self::LINE => $this->line,
|
268 |
+
);
|
269 |
+
|
270 |
+
return $closeIndex + strlen($close) - 1;
|
271 |
+
}
|
272 |
+
|
273 |
+
/**
|
274 |
+
* Set the current Mustache `otag` and `ctag` delimiters.
|
275 |
+
*
|
276 |
+
* @param string $delimiters
|
277 |
+
*/
|
278 |
+
private function setDelimiters($delimiters)
|
279 |
+
{
|
280 |
+
list($otag, $ctag) = explode(' ', $delimiters);
|
281 |
+
$this->otag = $otag;
|
282 |
+
$this->ctag = $ctag;
|
283 |
+
$this->otagLen = strlen($otag);
|
284 |
+
$this->ctagLen = strlen($ctag);
|
285 |
+
}
|
286 |
+
|
287 |
+
/**
|
288 |
+
* Add pragma token.
|
289 |
+
*
|
290 |
+
* Pragmas are hoisted to the front of the template, so all pragma tokens
|
291 |
+
* will appear at the front of the token list.
|
292 |
+
*
|
293 |
+
* @param string $text
|
294 |
+
* @param int $index
|
295 |
+
*
|
296 |
+
* @return int New index value
|
297 |
+
*/
|
298 |
+
private function addPragma($text, $index)
|
299 |
+
{
|
300 |
+
$end = strpos($text, $this->ctag, $index);
|
301 |
+
$pragma = trim(substr($text, $index + 2, $end - $index - 2));
|
302 |
+
|
303 |
+
// Pragmas are hoisted to the front of the template.
|
304 |
+
array_unshift($this->tokens, array(
|
305 |
+
self::TYPE => self::T_PRAGMA,
|
306 |
+
self::NAME => $pragma,
|
307 |
+
self::LINE => 0,
|
308 |
+
));
|
309 |
+
|
310 |
+
return $end + $this->ctagLen - 1;
|
311 |
+
}
|
312 |
+
|
313 |
+
/**
|
314 |
+
* Test whether it's time to change tags.
|
315 |
+
*
|
316 |
+
* @param string $tag Current tag name
|
317 |
+
* @param int $tagLen Current tag name length
|
318 |
+
* @param string $text Mustache template source
|
319 |
+
* @param int $index Current tokenizer index
|
320 |
+
*
|
321 |
+
* @return boolean True if this is a closing section tag
|
322 |
+
*/
|
323 |
+
private function tagChange($tag, $tagLen, $text, $index)
|
324 |
+
{
|
325 |
+
return substr($text, $index, $tagLen) === $tag;
|
326 |
+
}
|
327 |
+
}
|
{core → vendor/scribu/lib-posts-to-posts}/api.php
RENAMED
File without changes
|
{core → vendor/scribu/lib-posts-to-posts}/autoload.php
RENAMED
@@ -33,3 +33,9 @@ class P2P_Autoload {
|
|
33 |
}
|
34 |
}
|
35 |
|
|
|
|
|
|
|
|
|
|
|
|
33 |
}
|
34 |
}
|
35 |
|
36 |
+
|
37 |
+
P2P_Autoload::register( 'P2P_', dirname( __FILE__ ) );
|
38 |
+
|
39 |
+
require_once dirname( __FILE__ ) . '/util.php';
|
40 |
+
require_once dirname( __FILE__ ) . '/api.php';
|
41 |
+
|
vendor/scribu/lib-posts-to-posts/composer.json
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "scribu/lib-posts-to-posts",
|
3 |
+
"description": "A library for many-to-many relationships in WordPress",
|
4 |
+
"homepage": "https://github.com/scribu/wp-lib-posts-to-posts",
|
5 |
+
"license": "GPL-2.0+",
|
6 |
+
"minimum-stability": "dev",
|
7 |
+
"require": {
|
8 |
+
"scribu/scb-framework": "dev-master"
|
9 |
+
},
|
10 |
+
"autoload": {
|
11 |
+
"files": ["autoload.php"]
|
12 |
+
}
|
13 |
+
}
|
{core → vendor/scribu/lib-posts-to-posts}/connection-type-factory.php
RENAMED
File without changes
|
{core → vendor/scribu/lib-posts-to-posts}/connection-type.php
RENAMED
File without changes
|
{core → vendor/scribu/lib-posts-to-posts}/determinate-connection-type.php
RENAMED
File without changes
|
{core → vendor/scribu/lib-posts-to-posts}/directed-connection-type.php
RENAMED
File without changes
|
{core → vendor/scribu/lib-posts-to-posts}/direction-strategy.php
RENAMED
File without changes
|
{core → vendor/scribu/lib-posts-to-posts}/exception.php
RENAMED
File without changes
|
{core → vendor/scribu/lib-posts-to-posts}/indeterminate-connection-type.php
RENAMED
File without changes
|
{core → vendor/scribu/lib-posts-to-posts}/indeterminate-directed-connection-type.php
RENAMED
File without changes
|
{core → vendor/scribu/lib-posts-to-posts}/item-any.php
RENAMED
File without changes
|
{core → vendor/scribu/lib-posts-to-posts}/item-attachment.php
RENAMED
File without changes
|
{core → vendor/scribu/lib-posts-to-posts}/item-post.php
RENAMED
File without changes
|
{core → vendor/scribu/lib-posts-to-posts}/item-user.php
RENAMED
File without changes
|
{core → vendor/scribu/lib-posts-to-posts}/item.php
RENAMED
File without changes
|
{core → vendor/scribu/lib-posts-to-posts}/list-renderer.php
RENAMED
File without changes
|
{core → vendor/scribu/lib-posts-to-posts}/list.php
RENAMED
File without changes
|
{core → vendor/scribu/lib-posts-to-posts}/query-post.php
RENAMED
File without changes
|
{core → vendor/scribu/lib-posts-to-posts}/query-user.php
RENAMED
File without changes
|
{core → vendor/scribu/lib-posts-to-posts}/query.php
RENAMED
@@ -85,13 +85,13 @@ class P2P_Query {
|
|
85 |
}
|
86 |
|
87 |
if ( isset( $q['connected_direction'] ) )
|
88 |
-
$directions = (array)
|
89 |
else
|
90 |
$directions = array();
|
91 |
|
92 |
$item = isset( $q['connected_items'] ) ? $q['connected_items'] : 'any';
|
93 |
|
94 |
-
$ctypes = (array)
|
95 |
|
96 |
$p2p_types = self::expand_ctypes( $item, $directions, $object_type, $ctypes );
|
97 |
|
85 |
}
|
86 |
|
87 |
if ( isset( $q['connected_direction'] ) )
|
88 |
+
$directions = (array) $q['connected_direction'];
|
89 |
else
|
90 |
$directions = array();
|
91 |
|
92 |
$item = isset( $q['connected_items'] ) ? $q['connected_items'] : 'any';
|
93 |
|
94 |
+
$ctypes = (array) $q['connected_type'];
|
95 |
|
96 |
$p2p_types = self::expand_ctypes( $item, $directions, $object_type, $ctypes );
|
97 |
|
{core → vendor/scribu/lib-posts-to-posts}/reciprocal-connection-type.php
RENAMED
File without changes
|
{core → vendor/scribu/lib-posts-to-posts}/shortcodes.php
RENAMED
File without changes
|
{core → vendor/scribu/lib-posts-to-posts}/side-attachment.php
RENAMED
File without changes
|
{core → vendor/scribu/lib-posts-to-posts}/side-post.php
RENAMED
File without changes
|
{core → vendor/scribu/lib-posts-to-posts}/side-user.php
RENAMED
File without changes
|
{core → vendor/scribu/lib-posts-to-posts}/side.php
RENAMED
File without changes
|
{core → vendor/scribu/lib-posts-to-posts}/storage.php
RENAMED
File without changes
|
{core → vendor/scribu/lib-posts-to-posts}/url-query.php
RENAMED
File without changes
|
{core → vendor/scribu/lib-posts-to-posts}/util.php
RENAMED
File without changes
|
{core → vendor/scribu/lib-posts-to-posts}/widget.php
RENAMED
File without changes
|
{scb → vendor/scribu/scb-framework}/AdminPage.php
RENAMED
File without changes
|
{scb → vendor/scribu/scb-framework}/BoxesPage.php
RENAMED
File without changes
|
{scb → vendor/scribu/scb-framework}/Cron.php
RENAMED
File without changes
|
{scb → vendor/scribu/scb-framework}/Forms.php
RENAMED
File without changes
|
{scb → vendor/scribu/scb-framework}/Hooks.php
RENAMED
File without changes
|
{scb → vendor/scribu/scb-framework}/Options.php
RENAMED
File without changes
|
{scb → vendor/scribu/scb-framework}/PostMetabox.php
RENAMED
@@ -72,7 +72,7 @@ class scbPostMetabox {
|
|
72 |
$error_fields = array();
|
73 |
|
74 |
if ( isset( $form_data['_error_data_' . $this->id ] ) ) {
|
75 |
-
$data =
|
76 |
|
77 |
$error_fields = $data['fields'];
|
78 |
$form_data = $data['data'];
|
@@ -167,14 +167,14 @@ class scbPostMetabox {
|
|
167 |
return $post_data;
|
168 |
}
|
169 |
|
170 |
-
protected function validate_post_data( $post_data ) {
|
171 |
return false;
|
172 |
}
|
173 |
|
174 |
private function get_meta( $post_id ) {
|
175 |
$meta = get_post_custom( $post_id );
|
176 |
foreach ( $meta as $key => $values )
|
177 |
-
$meta[$key] = $meta[$key][0];
|
178 |
|
179 |
return $meta;
|
180 |
}
|
72 |
$error_fields = array();
|
73 |
|
74 |
if ( isset( $form_data['_error_data_' . $this->id ] ) ) {
|
75 |
+
$data = maybe_unserialize( $form_data['_error_data_' . $this->id ] );
|
76 |
|
77 |
$error_fields = $data['fields'];
|
78 |
$form_data = $data['data'];
|
167 |
return $post_data;
|
168 |
}
|
169 |
|
170 |
+
protected function validate_post_data( $post_data, $post_id ) {
|
171 |
return false;
|
172 |
}
|
173 |
|
174 |
private function get_meta( $post_id ) {
|
175 |
$meta = get_post_custom( $post_id );
|
176 |
foreach ( $meta as $key => $values )
|
177 |
+
$meta[ $key ] = maybe_unserialize( $meta[ $key ][0] );
|
178 |
|
179 |
return $meta;
|
180 |
}
|
{scb → vendor/scribu/scb-framework}/Table.php
RENAMED
File without changes
|
{scb → vendor/scribu/scb-framework}/Util.php
RENAMED
@@ -28,7 +28,9 @@ class scbUtil {
|
|
28 |
$content = str_replace( array( "'", "\n" ), array( '"', '' ), ob_get_clean() );
|
29 |
|
30 |
echo "<script type='text/javascript'>\n";
|
|
|
31 |
echo "jQuery(function ($) { $('head').prepend('$content'); });\n";
|
|
|
32 |
echo "</script>";
|
33 |
}
|
34 |
|
28 |
$content = str_replace( array( "'", "\n" ), array( '"', '' ), ob_get_clean() );
|
29 |
|
30 |
echo "<script type='text/javascript'>\n";
|
31 |
+
echo "//<![CDATA[";
|
32 |
echo "jQuery(function ($) { $('head').prepend('$content'); });\n";
|
33 |
+
echo "//]]>";
|
34 |
echo "</script>";
|
35 |
}
|
36 |
|
{scb → vendor/scribu/scb-framework}/Widget.php
RENAMED
File without changes
|
{scb → vendor/scribu/scb-framework}/composer.json
RENAMED
File without changes
|
{scb → vendor/scribu/scb-framework}/load-composer.php
RENAMED
File without changes
|
{scb → vendor/scribu/scb-framework}/load.php
RENAMED
File without changes
|