added in vendor for prod
This commit is contained in:
7
vendor/salesforce/handlebars-php/.gitignore
vendored
Normal file
7
vendor/salesforce/handlebars-php/.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
vendor
|
||||
*.swp
|
||||
*.swo
|
||||
composer.phar
|
||||
composer.lock
|
||||
*.iml
|
||||
.idea
|
||||
3
vendor/salesforce/handlebars-php/.scrutinizer.yml
vendored
Normal file
3
vendor/salesforce/handlebars-php/.scrutinizer.yml
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
inherit: true
|
||||
tools:
|
||||
php_code_coverage: true
|
||||
4
vendor/salesforce/handlebars-php/.travis.yml
vendored
Normal file
4
vendor/salesforce/handlebars-php/.travis.yml
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
language: php
|
||||
php:
|
||||
- 5.4
|
||||
- 5.5
|
||||
105
vendor/salesforce/handlebars-php/CODE_OF_CONDUCT.md
vendored
Normal file
105
vendor/salesforce/handlebars-php/CODE_OF_CONDUCT.md
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
# Salesforce Open Source Community Code of Conduct
|
||||
|
||||
## About the Code of Conduct
|
||||
|
||||
Equality is a core value at Salesforce. We believe a diverse and inclusive
|
||||
community fosters innovation and creativity, and are committed to building a
|
||||
culture where everyone feels included.
|
||||
|
||||
Salesforce open-source projects are committed to providing a friendly, safe, and
|
||||
welcoming environment for all, regardless of gender identity and expression,
|
||||
sexual orientation, disability, physical appearance, body size, ethnicity, nationality,
|
||||
race, age, religion, level of experience, education, socioeconomic status, or
|
||||
other similar personal characteristics.
|
||||
|
||||
The goal of this code of conduct is to specify a baseline standard of behavior so
|
||||
that people with different social values and communication styles can work
|
||||
together effectively, productively, and respectfully in our open source community.
|
||||
It also establishes a mechanism for reporting issues and resolving conflicts.
|
||||
|
||||
All questions and reports of abusive, harassing, or otherwise unacceptable behavior
|
||||
in a Salesforce open-source project may be reported by contacting the Salesforce
|
||||
Open Source Conduct Committee at ossconduct@salesforce.com.
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of gender
|
||||
identity and expression, sexual orientation, disability, physical appearance,
|
||||
body size, ethnicity, nationality, race, age, religion, level of experience, education,
|
||||
socioeconomic status, or other similar personal characteristics.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy toward other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Personal attacks, insulting/derogatory comments, or trolling
|
||||
* Public or private harassment
|
||||
* Publishing, or threatening to publish, others' private information—such as
|
||||
a physical or electronic address—without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
* Advocating for or encouraging any of the above behaviors
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned with this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project email
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the Salesforce Open Source Conduct Committee
|
||||
at ossconduct@salesforce.com. All complaints will be reviewed and investigated
|
||||
and will result in a response that is deemed necessary and appropriate to the
|
||||
circumstances. The committee is obligated to maintain confidentiality with
|
||||
regard to the reporter of an incident. Further details of specific enforcement
|
||||
policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership and the Salesforce Open Source Conduct
|
||||
Committee.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][contributor-covenant-home],
|
||||
version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html.
|
||||
It includes adaptions and additions from [Go Community Code of Conduct][golang-coc],
|
||||
[CNCF Code of Conduct][cncf-coc], and [Microsoft Open Source Code of Conduct][microsoft-coc].
|
||||
|
||||
This Code of Conduct is licensed under the [Creative Commons Attribution 3.0 License][cc-by-3-us].
|
||||
|
||||
[contributor-covenant-home]: https://www.contributor-covenant.org (https://www.contributor-covenant.org/)
|
||||
[golang-coc]: https://golang.org/conduct
|
||||
[cncf-coc]: https://github.com/cncf/foundation/blob/master/code-of-conduct.md
|
||||
[microsoft-coc]: https://opensource.microsoft.com/codeofconduct/
|
||||
[cc-by-3-us]: https://creativecommons.org/licenses/by/3.0/us/
|
||||
1
vendor/salesforce/handlebars-php/Contributors.md
vendored
Normal file
1
vendor/salesforce/handlebars-php/Contributors.md
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[Joey Rivera](https://github.com/joeyrivera)
|
||||
8
vendor/salesforce/handlebars-php/LICENSE
vendored
Normal file
8
vendor/salesforce/handlebars-php/LICENSE
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
Copyright (C) 2012-2013 Xamin Project and contributors
|
||||
Copyright (c) 2019 Salesforce.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
769
vendor/salesforce/handlebars-php/README.md
vendored
Normal file
769
vendor/salesforce/handlebars-php/README.md
vendored
Normal file
@@ -0,0 +1,769 @@
|
||||
---
|
||||
|
||||
#handlebars-php
|
||||
|
||||
---
|
||||
|
||||
#### A simple, logic-less, yet powerful templating engine for PHP
|
||||
|
||||
---
|
||||
|
||||
Name: **handlebars-php**
|
||||
|
||||
License: MIT
|
||||
|
||||
Requirements: PHP >= 5.4
|
||||
|
||||
---
|
||||
|
||||
|
||||
## About Handlebars
|
||||
|
||||
Handlebars provides the power necessary to let you build semantic templates effectively with no frustration,
|
||||
that keep the view and the code separated like we all know they should be.
|
||||
|
||||
|
||||
Fork of: [Handlebars.php by XaminProject](https://github.com/mardix/Handlebars)
|
||||
|
||||
Handlebars, is the PHP port of [Handlebars.js](http://handlebarsjs.com/)
|
||||
|
||||
---
|
||||
|
||||
## Install Handlebars
|
||||
|
||||
|
||||
You can just download Handlebars.php as is, or with Composer.
|
||||
|
||||
To install with composer, add the following in the require key in your **composer.json** file
|
||||
|
||||
`"salesforce/handlebars-php": "1.*"`
|
||||
|
||||
composer.json
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "myapp/name",
|
||||
"description": "My awesome app name",
|
||||
"require": {
|
||||
"salesforce/handlebars-php": "1.*"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
-----
|
||||
|
||||
## Getting Started
|
||||
|
||||
At the minimum, we are required to have an array model and a template string. Alternatively we can have a file containing handlebars (or html, text, etc) expression.
|
||||
|
||||
|
||||
|
||||
#### Template
|
||||
|
||||
Handlebars templates look like regular HTML, with embedded handlebars expressions.
|
||||
|
||||
Handlebars HTML-escapes values returned by a {{expression}}.
|
||||
|
||||
```html
|
||||
<div class="entry">
|
||||
<h1>{{title}}</h1>
|
||||
<div class="body">
|
||||
Hello, my name is {{name}}
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
The string above can be used as is in your PHP file, or be put in a file (ie: */templates/main.tpl*), to be called upon rendering.
|
||||
|
||||
#### PHP file
|
||||
|
||||
Now the we've created our template file, in a php file (index.php) we'll create the data to passed to the model. The model is a key/value array.
|
||||
|
||||
Below we are going to create the Handlebars object, set the partials loader, and put some data in the model.
|
||||
|
||||
**/index.php**
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
# With composer we can autoload the Handlebars package
|
||||
require_once ("./vendor/autoload.php");
|
||||
|
||||
# If not using composer, you can still load it manually.
|
||||
# require 'src/Handlebars/Autoloader.php';
|
||||
# Handlebars\Autoloader::register();
|
||||
|
||||
use Handlebars\Handlebars;
|
||||
use Handlebars\Loader\FilesystemLoader;
|
||||
|
||||
# Set the partials files
|
||||
$partialsDir = __DIR__."/templates";
|
||||
$partialsLoader = new FilesystemLoader($partialsDir,
|
||||
[
|
||||
"extension" => "html"
|
||||
]
|
||||
);
|
||||
|
||||
# We'll use $handlebars throughout this the examples, assuming the will be all set this way
|
||||
$handlebars = new Handlebars([
|
||||
"loader" => $partialsLoader,
|
||||
"partials_loader" => $partialsLoader
|
||||
]);
|
||||
|
||||
# Will render the model to the templates/main.tpl template
|
||||
$model = [...];
|
||||
echo $handlebars->render("main", $model);
|
||||
```
|
||||
|
||||
#### Assign Data
|
||||
|
||||
The simplest way to assign data is to create an Array model. The model will contain all the data that will be passed to the template.
|
||||
```php
|
||||
<?php
|
||||
|
||||
$model = [
|
||||
"name" => "Yolo Baggins",
|
||||
"title" => "I'm Title",
|
||||
"permalink" => "blog/",
|
||||
"foo" => "bar",
|
||||
"article" => [
|
||||
"title" => "My Article Title"
|
||||
],
|
||||
"posts" => [
|
||||
[
|
||||
"title" => "Post #1",
|
||||
"id" => 1,
|
||||
"content" => "Content"
|
||||
],
|
||||
[
|
||||
"title" => "Post 2",
|
||||
"id" => 2,
|
||||
"content" => "Content"
|
||||
]
|
||||
]
|
||||
];
|
||||
```
|
||||
|
||||
#### Render Template
|
||||
|
||||
Use the method `Handlebars\Handlebars::render($template, $model)` to render you template once everything is created.
|
||||
|
||||
***$template*** : Template can be the name of the file or a string containing the handlebars/html.
|
||||
|
||||
***$model*** : Is the array that we will pass into the template
|
||||
|
||||
The code below will render the model to the *templates/main.tpl* template
|
||||
|
||||
```php
|
||||
echo $handlebars->render("main", $model);
|
||||
```
|
||||
|
||||
|
||||
Alternatively you can use $handlebars itself without invoking the render method
|
||||
|
||||
```php
|
||||
echo $handlebars("main", $model);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Expressions
|
||||
|
||||
Let's use this simple model for the following examples, assuming everything is already set like above.
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
$model = [
|
||||
"title" => "I'm Title",
|
||||
"permalink" => "/blog/",
|
||||
"foo" => "bar",
|
||||
"article" => [
|
||||
"title" => "My Article Title"
|
||||
],
|
||||
"posts" => [
|
||||
[
|
||||
"title" => "Post #1",
|
||||
"id" => 1,
|
||||
"content" => "Content"
|
||||
],
|
||||
[
|
||||
"title" => "Post 2",
|
||||
"id" => 2,
|
||||
"content" => "Content"
|
||||
]
|
||||
]
|
||||
];
|
||||
```
|
||||
|
||||
Let's work with the template.
|
||||
|
||||
Handlebars expressions are the basic unit of a Handlebars template. You can use them alone in a {{mustache}}, pass them to a Handlebars helper, or use them as values in hash arguments.
|
||||
|
||||
|
||||
The simplest Handlebars expression is a simple identifier:
|
||||
|
||||
```html
|
||||
{{title}}
|
||||
|
||||
-> I'm Title
|
||||
```
|
||||
|
||||
Handlebars nested expressions which are dot-separated paths.
|
||||
|
||||
```html
|
||||
{{article.title}}
|
||||
|
||||
-> My Article Title
|
||||
```
|
||||
|
||||
Handlebars nested expressions in an array.
|
||||
|
||||
```html
|
||||
{{posts.0.title}}
|
||||
|
||||
-> Post #1
|
||||
```
|
||||
|
||||
Handlebars also allows for name conflict resolution between helpers and data fields via a this reference:
|
||||
|
||||
```html
|
||||
{{./name}} or {{this/name}} or {{this.name}}
|
||||
```
|
||||
|
||||
Handlebars expressions with a helper. In this case we're using the upper helper
|
||||
|
||||
```html
|
||||
{{#upper title}}
|
||||
|
||||
-> I'M TITLE
|
||||
```
|
||||
|
||||
Nested handlebars paths can also include ../ segments, which evaluate their paths against a parent context.
|
||||
|
||||
```html
|
||||
{{#each posts}}
|
||||
<a href="/posts/{{../permalink}}/{{id}}">{{title}}</a>
|
||||
{{content}}
|
||||
{{/each}}
|
||||
```
|
||||
|
||||
Handlebars HTML-escapes values returned by a {{expression}}. If you don't want Handlebars to escape a value, use the "triple-stash", {{{ }}}
|
||||
|
||||
```html
|
||||
{{{foo}}}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
|
||||
## Control Structures
|
||||
|
||||
`if/else` and `unless` control structures are implemented as regular Handlebars helpers
|
||||
|
||||
### IF/ELSE
|
||||
|
||||
You can use the if helper to conditionally render a block. If its argument returns false, null, "" or [] (a "falsy" value), Handlebars will not render the block.
|
||||
|
||||
**Example**
|
||||
|
||||
```html
|
||||
{{#if isActive}}
|
||||
This part will be shown if it is active
|
||||
{{else}}
|
||||
This part will not show if isActive is true
|
||||
{{/if}}
|
||||
```
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
$model = [
|
||||
"isActive" => true
|
||||
];
|
||||
|
||||
echo $handlebars->render($template, $model);
|
||||
```
|
||||
|
||||
### UNLESS
|
||||
|
||||
You can use the unless helper as the inverse of the if helper. Its block will be rendered if the expression returns a falsy value.
|
||||
|
||||
```html
|
||||
{{#unless isActive}}
|
||||
This part will not show if isActive is true
|
||||
{{/unless}}
|
||||
```
|
||||
|
||||
---
|
||||
##Iterators: EACH
|
||||
|
||||
You can iterate over a list using the built-in each helper. Inside the block, you can use {{this}} or {{.}} to reference the element being iterated over.
|
||||
|
||||
**Example**
|
||||
|
||||
```html
|
||||
<h2>All genres:</h2>
|
||||
{{#each genres}}
|
||||
{{.}}
|
||||
{{/each}}
|
||||
|
||||
|
||||
{{#each cars}}
|
||||
<h3>{{category}}</h3>
|
||||
Total: {{count}}
|
||||
<ul>
|
||||
{{#each list}}
|
||||
{{.}}
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{/each}}
|
||||
```
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
$model = [
|
||||
"genres" => [
|
||||
"Hip-Hop",
|
||||
"Rap",
|
||||
"Techno",
|
||||
"Country"
|
||||
],
|
||||
"cars" => [
|
||||
"category" => "Foreign",
|
||||
"count" => 4,
|
||||
"list" => [
|
||||
"Toyota",
|
||||
"Kia",
|
||||
"Honda",
|
||||
"Mazda"
|
||||
],
|
||||
"category" => "WTF",
|
||||
"count" => 1,
|
||||
"list" => [
|
||||
"Fiat"
|
||||
],
|
||||
"category" => "Luxury",
|
||||
"count" => 2,
|
||||
"list" => [
|
||||
"Mercedes Benz",
|
||||
"BMW"
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
echo $engine->render($template, $model);
|
||||
```
|
||||
|
||||
### EACH/ELSE
|
||||
|
||||
You can optionally provide an {{else}} section which will display only when the list is empty.
|
||||
|
||||
```html
|
||||
<h2>All genres:</h2>
|
||||
{{#each genres}}
|
||||
{{.}}
|
||||
{{else}}
|
||||
No genres found!
|
||||
{{/each}}
|
||||
```
|
||||
|
||||
### Slice EACH Array[start:end]
|
||||
|
||||
The #each helper (php only) also has the ability to slice the data
|
||||
|
||||
* {{#each Array[start:end]}} = starts at start through end -1
|
||||
* {{#each Array[start:]}} = Starts at start though the rest of the array
|
||||
* {{#each Array[:end]}} = Starts at the beginning through end -1
|
||||
* {{#each Array[:]}} = A copy of the whole array
|
||||
* {{#each Array[-1]}}
|
||||
* {{#each Array[-2:]}} = Last two items
|
||||
* {{#each Array[:-2]}} = Everything except last two items
|
||||
|
||||
```html
|
||||
<h2>All genres:</h2>
|
||||
{{#each genres[0:10]}}
|
||||
{{.}}
|
||||
{{else}}
|
||||
No genres found!
|
||||
{{/each}}
|
||||
```
|
||||
|
||||
#### {{@INDEX}} and {{@KEY}}
|
||||
|
||||
When looping through items in each, you can optionally reference the current loop index via {{@index}}
|
||||
|
||||
```html
|
||||
{{#each array}}
|
||||
{{@index}}: {{this}}
|
||||
{{/each}}
|
||||
|
||||
|
||||
{{#each object}}
|
||||
{{@key}}: {{this}}
|
||||
{{/each}}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Change Context: WITH
|
||||
|
||||
You can shift the context for a section of a template by using the built-in with block helper.
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
$model = [
|
||||
"genres" => [
|
||||
"Hip-Hop",
|
||||
"Rap",
|
||||
"Techno",
|
||||
"Country"
|
||||
],
|
||||
"other_genres" => [
|
||||
"genres" => [
|
||||
"Hip-Hop",
|
||||
"Rap",
|
||||
"Techno",
|
||||
"Country"
|
||||
]
|
||||
]
|
||||
];
|
||||
```
|
||||
|
||||
```html
|
||||
<h2>All genres:</h2>
|
||||
{{#with other_genres}}
|
||||
{{#each genres}}
|
||||
{{.}}
|
||||
{{/each}}
|
||||
{{/with}}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Handlebars Built-in Helpers
|
||||
|
||||
### If
|
||||
```html
|
||||
{{#if isActive}}
|
||||
This part will be shown if it is active
|
||||
{{else}}
|
||||
This part will not show if isActive is true
|
||||
{{/if}}
|
||||
```
|
||||
|
||||
### Unless
|
||||
```html
|
||||
{{#unless isActive}}
|
||||
This part will show when isActive is false
|
||||
{{else}}
|
||||
Otherwise this one will show
|
||||
{{/unless}}
|
||||
```
|
||||
|
||||
### Each
|
||||
```html
|
||||
{{#each genres[0:10]}}
|
||||
{{.}}
|
||||
{{else}}
|
||||
No genres found!
|
||||
{{/each}}
|
||||
```
|
||||
|
||||
### With
|
||||
```html
|
||||
{{#with other_genres}}
|
||||
{{#each genres}}
|
||||
{{.}}
|
||||
{{/each}}
|
||||
{{/with}}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Other Helpers
|
||||
|
||||
#### For convenience, Voodoo\Handlebars added some extra helpers.
|
||||
|
||||
---
|
||||
|
||||
### Upper
|
||||
|
||||
To format string to uppercase
|
||||
```html
|
||||
{{#upper title}}
|
||||
```
|
||||
|
||||
### Lower
|
||||
|
||||
To format string to lowercase
|
||||
```html
|
||||
{{#lower title}}
|
||||
```
|
||||
|
||||
|
||||
### Capitalize
|
||||
|
||||
To capitalize the first letter
|
||||
```html
|
||||
{{#capitalize title}}
|
||||
```
|
||||
|
||||
### Capitalize_Words
|
||||
|
||||
To capitalize each words in a string
|
||||
```html
|
||||
{{#capitalize_words title}}
|
||||
```
|
||||
|
||||
### Reverse
|
||||
|
||||
To reverse the order of string
|
||||
```html
|
||||
{{#reverse title}}
|
||||
```
|
||||
|
||||
### Format_Date
|
||||
|
||||
To format date: `{{#format_date date '$format'}}`
|
||||
```html
|
||||
{{#format_date date 'Y-m-d H:i:s'}}
|
||||
```
|
||||
|
||||
### Inflect
|
||||
|
||||
To singularize or plurialize words based on count `{{#inflect count $singular $plurial}}`
|
||||
```html
|
||||
{{#inflect count '%d book' '%d books'}}
|
||||
```
|
||||
|
||||
### Truncate
|
||||
|
||||
To truncate a string: `{{#truncate title $length $ellipsis}}`
|
||||
```html
|
||||
{{#truncate title 21 '...'}}
|
||||
```
|
||||
|
||||
### Default
|
||||
|
||||
To use a default value if the string is empty: `{{#default title $defaultValue}}`
|
||||
```html
|
||||
{{#default title 'No title'}}
|
||||
```
|
||||
|
||||
### Raw
|
||||
|
||||
This helper return handlebars expression as is. The expression will not be parsed
|
||||
```html
|
||||
{{#raw}}
|
||||
{{#each cars}}
|
||||
{{model}}
|
||||
{{/each}}
|
||||
{{/raw}}
|
||||
|
||||
->
|
||||
|
||||
{{#each cars}}
|
||||
{{model}}
|
||||
{{/each}}
|
||||
```
|
||||
|
||||
|
||||
### Repeat
|
||||
|
||||
To truncate a string: `{{#repeat $count}}{{/repeat}}`
|
||||
```html
|
||||
{{#repeat 5}}
|
||||
Hello World!
|
||||
{{/repeat}}
|
||||
```
|
||||
|
||||
Variable and blocks can still be used
|
||||
```html
|
||||
{{#repeat 5}}
|
||||
Hello {{name}}!
|
||||
{{/repeat}}
|
||||
```
|
||||
|
||||
|
||||
### Define/Invoke
|
||||
|
||||
Allow to define a block of content and use it later. It helps follow the DRY (Don't repeat yourself) principle.
|
||||
|
||||
|
||||
Define
|
||||
```html
|
||||
{{#define $definedName}}
|
||||
content
|
||||
{{/define}}
|
||||
```
|
||||
|
||||
Invoke
|
||||
```html
|
||||
{{#invoke $definedName}}
|
||||
```
|
||||
|
||||
|
||||
Example:
|
||||
```html
|
||||
{{#define hello}}
|
||||
Hello World! How do you do?
|
||||
{{/define}}
|
||||
|
||||
{{#invoke hello}}
|
||||
|
||||
->
|
||||
|
||||
Hello World! How do you do?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Template Comments
|
||||
You can use comments in your handlebars code just as you would in your code. Since there is generally some level of logic, this is a good practice.
|
||||
|
||||
```html
|
||||
{{!-- only output this author names if an author exists --}}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Partials
|
||||
|
||||
Partials are other templates you can include inside of the main template.
|
||||
|
||||
To do so:
|
||||
|
||||
```html
|
||||
{{> my_partial}}
|
||||
```
|
||||
|
||||
which is a file under /templates/my_partial.html
|
||||
|
||||
---
|
||||
|
||||
## Writing your own helpers
|
||||
|
||||
Block helpers make it possible to define custom iterators and other helpers that can invoke the passed block with a new context.
|
||||
|
||||
To create your own helper, use the method: `Handlebars::addHelper($name, $callback)`
|
||||
|
||||
The following helper will UPPERCASE a string
|
||||
|
||||
```php
|
||||
$handlebars->addHelper("upper",
|
||||
function($template, $context, $args, $source){
|
||||
return strtoupper($context->get($args));
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
And now we can use the helper like this:
|
||||
|
||||
```html
|
||||
{{#upper title}}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Data Variables for #each
|
||||
|
||||
In Handlebars JS v1.1, data variables `@first` and `@last` were added for the #each helper. Due to the these variables
|
||||
not being backwards compatible, these data variables are disabled by default and must be enabled manually.
|
||||
|
||||
To enable the new data variables, set the `enableDataVariables` option to `true` when instantiating the Handlebars
|
||||
instance.
|
||||
|
||||
```php
|
||||
$handlebars = new Handlebars([
|
||||
"loader" => $partialsLoader,
|
||||
"partials_loader" => $partialsLoader,
|
||||
"enableDataVariables" => true
|
||||
]);
|
||||
```
|
||||
|
||||
Given the following template and data:
|
||||
```
|
||||
{{#each data}}{{#if @first}}FIRST: {{/if}}{{this}}<br>{{/each}}
|
||||
```
|
||||
```php
|
||||
'data' => ['apple', 'banana', 'carrot', 'zucchini']
|
||||
```
|
||||
The output will be
|
||||
```html
|
||||
FIRST: apple<br>banana<br>carrot<br>zucchini<br>
|
||||
```
|
||||
|
||||
Given the following template and the data above:
|
||||
```
|
||||
{{#each data}}{{@first}}: {{this}}<br>{{/each}}
|
||||
```
|
||||
The output will be
|
||||
```html
|
||||
true: apple<br>banana<br>carrot<br>zucchini<br>
|
||||
```
|
||||
|
||||
Data variables also support relative referencing within multiple #each statements.
|
||||
Given
|
||||
```
|
||||
{{#each data}}{{#each this}}outer: {{@../first}},inner: {{@first}};{{/each}}{{/each}}
|
||||
```
|
||||
```php
|
||||
'data' => [['apple', 'banana'], ['carrot', 'zucchini']]
|
||||
```
|
||||
The output will be
|
||||
```
|
||||
outer: true,inner: true;outer: true,inner: false;outer: false,inner: true;outer: false,inner: false;
|
||||
```
|
||||
|
||||
Be aware that when data variables are enabled, variables starting with `@` are considered restricted and will override
|
||||
values specified in the data.
|
||||
|
||||
For example, given the following template and the following data, the output will be different depending on if data
|
||||
variables are enabled.
|
||||
|
||||
```
|
||||
{{#each objects}}{{@first}}, {{@last}}, {{@index}}, {{@unknown}}{{/each}}
|
||||
```
|
||||
|
||||
```php
|
||||
$object = new stdClass;
|
||||
$object->{'@first'} = 'apple';
|
||||
$object->{'@last'} = 'banana';
|
||||
$object->{'@index'} = 'carrot';
|
||||
$object->{'@unknown'} = 'zucchini';
|
||||
$data = ['objects' => [$object]];
|
||||
|
||||
$engine = new \Handlebars\Handlebars(array(
|
||||
'loader' => new \Handlebars\Loader\StringLoader(),
|
||||
'helpers' => new \Handlebars\Helpers(),
|
||||
'enableDataVariables'=> $enabled,
|
||||
));
|
||||
$engine->render($template, $data)
|
||||
```
|
||||
|
||||
When `enableDataVariables` is `false`, existing behavior is not changed where some variables will be return.
|
||||
|
||||
```
|
||||
apple, banana, 0, zucchini
|
||||
```
|
||||
|
||||
|
||||
When `enableDataVariables` is `true`, the behavior matches HandlebarsJS 1.1 behavior, where all data variables replace
|
||||
variables defined in the data and any data variable prefixed with `@` that is unknown will be blank.
|
||||
|
||||
```
|
||||
true, true, 0,
|
||||
```
|
||||
|
||||
|
||||
#### Credits
|
||||
|
||||
* Fork of [Handlebars.php by XaminProject](https://github.com/XaminProject/handlebars.php)
|
||||
* The documentation was edited by [Mardix](http://github.com/mardix).
|
||||
|
||||
#### Contribution
|
||||
|
||||
Contributions are more than welcome!
|
||||
33
vendor/salesforce/handlebars-php/composer.json
vendored
Normal file
33
vendor/salesforce/handlebars-php/composer.json
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"name": "salesforce/handlebars-php",
|
||||
"description": "Handlebars processor for php",
|
||||
"homepage": "http://www.github.com/salesforce/handlebars-php",
|
||||
"keywords": ["templating", "mustache", "handlebars"],
|
||||
"type": "library",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "fzerorubigd",
|
||||
"email": "fzerorubigd@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Behrooz Shabani (everplays)",
|
||||
"email": "everplays@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Mardix",
|
||||
"homepage": "https://github.com/mardix"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Handlebars": "src/"
|
||||
}
|
||||
}
|
||||
}
|
||||
15
vendor/salesforce/handlebars-php/phpunit.xml.dist
vendored
Normal file
15
vendor/salesforce/handlebars-php/phpunit.xml.dist
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<phpunit bootstrap="tests/bootstrap.php" colors="true">
|
||||
<testsuites>
|
||||
<testsuite name="Handlebars Test suite">
|
||||
<directory>tests/Handlebars/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory suffix=".php">src/</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
||||
77
vendor/salesforce/handlebars-php/src/Handlebars/Autoloader.php
vendored
Executable file
77
vendor/salesforce/handlebars-php/src/Handlebars/Autoloader.php
vendored
Executable file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* @category Xamin
|
||||
* @package Handlebars
|
||||
* @author fzerorubigd <fzerorubigd@gmail.com>
|
||||
* @author Behrooz Shabani <everplays@gmail.com>
|
||||
* @copyright 2012 (c) ParsPooyesh Co
|
||||
* @copyright 2013 (c) Behrooz Shabani
|
||||
* @copyright 2014 (c) Mardix
|
||||
* @license MIT
|
||||
* @link http://voodoophp.org/docs/handlebars
|
||||
*/
|
||||
|
||||
namespace Handlebars;
|
||||
|
||||
class Autoloader
|
||||
{
|
||||
|
||||
private $_baseDir;
|
||||
|
||||
/**
|
||||
* Autoloader constructor.
|
||||
*
|
||||
* @param string $baseDir Handlebars library base directory default is
|
||||
* __DIR__.'/..'
|
||||
*/
|
||||
protected function __construct($baseDir = null)
|
||||
{
|
||||
if ($baseDir === null) {
|
||||
$this->_baseDir = realpath(__DIR__ . '/..');
|
||||
} else {
|
||||
$this->_baseDir = rtrim($baseDir, '/');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new instance as an SPL autoloader.
|
||||
*
|
||||
* @param string $baseDir Handlebars library base directory, default is
|
||||
* __DIR__.'/..'
|
||||
*
|
||||
* @return \Handlebars\Autoloader Registered Autoloader instance
|
||||
*/
|
||||
public static function register($baseDir = null)
|
||||
{
|
||||
$loader = new self($baseDir);
|
||||
spl_autoload_register(array($loader, 'autoload'));
|
||||
|
||||
return $loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Autoload Handlebars classes.
|
||||
*
|
||||
* @param string $class class to load
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function autoload($class)
|
||||
{
|
||||
if ($class[0] === '\\') {
|
||||
$class = substr($class, 1);
|
||||
}
|
||||
|
||||
if (strpos($class, 'Handlebars') !== 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$file = sprintf('%s/%s.php', $this->_baseDir, str_replace('\\', '/', $class));
|
||||
|
||||
if (is_file($file)) {
|
||||
include $file;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
49
vendor/salesforce/handlebars-php/src/Handlebars/Cache.php
vendored
Executable file
49
vendor/salesforce/handlebars-php/src/Handlebars/Cache.php
vendored
Executable file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/**
|
||||
* Cache Interface
|
||||
*
|
||||
* @category Xamin
|
||||
* @package Handlebars
|
||||
* @author fzerorubigd <fzerorubigd@gmail.com>
|
||||
* @author Behrooz Shabani <everplays@gmail.com>
|
||||
* @copyright 2012 (c) ParsPooyesh Co
|
||||
* @copyright 2013 (c) Behrooz Shabani
|
||||
* @license MIT
|
||||
* @link http://voodoophp.org/docs/handlebars
|
||||
*/
|
||||
|
||||
|
||||
namespace Handlebars;
|
||||
|
||||
interface Cache
|
||||
{
|
||||
|
||||
/**
|
||||
* Get cache for $name if exist.
|
||||
*
|
||||
* @param string $name Cache id
|
||||
*
|
||||
* @return mixed data on hit, boolean false on cache not found
|
||||
*/
|
||||
public function get($name);
|
||||
|
||||
/**
|
||||
* Set a cache
|
||||
*
|
||||
* @param string $name cache id
|
||||
* @param mixed $value data to store
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set($name, $value);
|
||||
|
||||
/**
|
||||
* Remove cache
|
||||
*
|
||||
* @param string $name Cache id
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function remove($name);
|
||||
|
||||
}
|
||||
60
vendor/salesforce/handlebars-php/src/Handlebars/Cache/APC.php
vendored
Executable file
60
vendor/salesforce/handlebars-php/src/Handlebars/Cache/APC.php
vendored
Executable file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* @category Xamin
|
||||
* @package Handlebars
|
||||
* @author Joey Baker <joey@byjoeybaker.com>
|
||||
* @author Behrooz Shabani <everplays@gmail.com>
|
||||
* @copyright 2013 (c) Meraki, LLP
|
||||
* @copyright 2013 (c) Behrooz Shabani
|
||||
* @license MIT
|
||||
* @link http://voodoophp.org/docs/handlebars
|
||||
*/
|
||||
|
||||
namespace Handlebars\Cache;
|
||||
use Handlebars\Cache;
|
||||
|
||||
class APC implements Cache
|
||||
{
|
||||
|
||||
/**
|
||||
* Get cache for $name if exist.
|
||||
*
|
||||
* @param string $name Cache id
|
||||
*
|
||||
* @return mixed data on hit, boolean false on cache not found
|
||||
*/
|
||||
public function get($name)
|
||||
{
|
||||
if (apc_exists($name)) {
|
||||
return apc_fetch($name);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a cache
|
||||
*
|
||||
* @param string $name cache id
|
||||
* @param mixed $value data to store
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set($name, $value)
|
||||
{
|
||||
apc_store($name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove cache
|
||||
*
|
||||
* @param string $name Cache id
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function remove($name)
|
||||
{
|
||||
apc_delete($name);
|
||||
}
|
||||
|
||||
}
|
||||
115
vendor/salesforce/handlebars-php/src/Handlebars/Cache/Disk.php
vendored
Normal file
115
vendor/salesforce/handlebars-php/src/Handlebars/Cache/Disk.php
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
/**
|
||||
* A flat-file filesystem cache.
|
||||
*
|
||||
* @category Xamin
|
||||
* @package Handlebars
|
||||
* @author Alex Soncodi <alex@brokerloop.com>
|
||||
* @author Behrooz Shabani <everplays@gmail.com>
|
||||
* @author Mardix <https://github.com/mardix>
|
||||
* @copyright 2013 (c) Brokerloop, Inc.
|
||||
* @copyright 2013 (c) Behrooz Shabani
|
||||
* @copyright 2013 (c) Mardix
|
||||
* @license MIT
|
||||
* @link http://voodoophp.org/docs/handlebars
|
||||
*/
|
||||
|
||||
namespace Handlebars\Cache;
|
||||
use Handlebars\Cache;
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
|
||||
class Disk implements Cache
|
||||
{
|
||||
|
||||
private $path = '';
|
||||
private $prefix = '';
|
||||
private $suffix = '';
|
||||
|
||||
/**
|
||||
* Construct the disk cache.
|
||||
*
|
||||
* @param string $path Filesystem path to the disk cache location
|
||||
* @param string $prefix optional file prefix, defaults to empty string
|
||||
* @param string $suffix optional file extension, defaults to empty string
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct($path, $prefix = '', $suffix = '')
|
||||
{
|
||||
if (empty($path)) {
|
||||
throw new InvalidArgumentException('Must specify disk cache path');
|
||||
} elseif (!is_dir($path)) {
|
||||
@mkdir($path, 0777, true);
|
||||
|
||||
if (!is_dir($path)) {
|
||||
throw new RuntimeException('Could not create cache file path');
|
||||
}
|
||||
}
|
||||
|
||||
$this->path = $path;
|
||||
$this->prefix = $prefix;
|
||||
$this->suffix = $suffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the full disk path for a given cache item's file,
|
||||
* taking into account the cache path, optional prefix,
|
||||
* and optional extension.
|
||||
*
|
||||
* @param string $name Name of the cache item
|
||||
*
|
||||
* @return string full disk path of cached item
|
||||
*/
|
||||
private function getPath($name)
|
||||
{
|
||||
return $this->path . DIRECTORY_SEPARATOR .
|
||||
$this->prefix . $name . $this->suffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cache for $name if it exists.
|
||||
*
|
||||
* @param string $name Cache id
|
||||
*
|
||||
* @return mixed data on hit, boolean false on cache not found
|
||||
*/
|
||||
public function get($name)
|
||||
{
|
||||
$path = $this->getPath($name);
|
||||
|
||||
return (file_exists($path)) ?
|
||||
unserialize(file_get_contents($path)) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a cache
|
||||
*
|
||||
* @param string $name cache id
|
||||
* @param mixed $value data to store
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set($name, $value)
|
||||
{
|
||||
$path = $this->getPath($name);
|
||||
|
||||
file_put_contents($path, serialize($value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove cache
|
||||
*
|
||||
* @param string $name Cache id
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function remove($name)
|
||||
{
|
||||
$path = $this->getPath($name);
|
||||
|
||||
unlink($path);
|
||||
}
|
||||
|
||||
}
|
||||
62
vendor/salesforce/handlebars-php/src/Handlebars/Cache/Dummy.php
vendored
Executable file
62
vendor/salesforce/handlebars-php/src/Handlebars/Cache/Dummy.php
vendored
Executable file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/**
|
||||
* A dummy array cache
|
||||
*
|
||||
* @category Xamin
|
||||
* @package Handlebars
|
||||
* @author fzerorubigd <fzerorubigd@gmail.com>
|
||||
* @author Behrooz Shabani <everplays@gmail.com>
|
||||
* @copyright 2012 (c) ParsPooyesh Co
|
||||
* @copyright 2013 (c) Behrooz Shabani
|
||||
* @license MIT
|
||||
* @link http://voodoophp.org/docs/handlebars
|
||||
*/
|
||||
|
||||
namespace Handlebars\Cache;
|
||||
use Handlebars\Cache;
|
||||
|
||||
class Dummy implements Cache
|
||||
{
|
||||
private $cache = [];
|
||||
|
||||
/**
|
||||
* Get cache for $name if exist.
|
||||
*
|
||||
* @param string $name Cache id
|
||||
*
|
||||
* @return mixed data on hit, boolean false on cache not found
|
||||
*/
|
||||
public function get($name)
|
||||
{
|
||||
if (array_key_exists($name, $this->cache)) {
|
||||
return $this->cache[$name];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a cache
|
||||
*
|
||||
* @param string $name cache id
|
||||
* @param mixed $value data to store
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set($name, $value)
|
||||
{
|
||||
$this->cache[$name] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove cache
|
||||
*
|
||||
* @param string $name Cache id
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function remove($name)
|
||||
{
|
||||
unset($this->cache[$name]);
|
||||
}
|
||||
|
||||
}
|
||||
382
vendor/salesforce/handlebars-php/src/Handlebars/Context.php
vendored
Executable file
382
vendor/salesforce/handlebars-php/src/Handlebars/Context.php
vendored
Executable file
@@ -0,0 +1,382 @@
|
||||
<?php
|
||||
/**
|
||||
* Handlebars context
|
||||
* Context for a template
|
||||
*
|
||||
* @category Xamin
|
||||
* @package Handlebars
|
||||
* @author fzerorubigd <fzerorubigd@gmail.com>
|
||||
* @author Behrooz Shabani <everplays@gmail.com>
|
||||
* @author Mardix <https://github.com/mardix>
|
||||
* @copyright 2012 (c) ParsPooyesh Co
|
||||
* @copyright 2013 (c) Behrooz Shabani
|
||||
* @copyright 2013 (c) Mardix
|
||||
* @license MIT
|
||||
* @link http://voodoophp.org/docs/handlebars
|
||||
*/
|
||||
|
||||
namespace Handlebars;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use LogicException;
|
||||
|
||||
class Context
|
||||
{
|
||||
const DATA_KEY = 'key';
|
||||
const DATA_INDEX = 'index';
|
||||
const DATA_FIRST = 'first';
|
||||
const DATA_LAST = 'last';
|
||||
|
||||
/**
|
||||
* @var array stack for context only top stack is available
|
||||
*/
|
||||
protected $stack = [];
|
||||
|
||||
/**
|
||||
* @var array index stack for sections
|
||||
*/
|
||||
protected $index = [];
|
||||
|
||||
/**
|
||||
* @var array dataStack stack for data within sections
|
||||
*/
|
||||
protected $dataStack = [];
|
||||
|
||||
/**
|
||||
* @var array key stack for objects
|
||||
*/
|
||||
protected $key = [];
|
||||
|
||||
/**
|
||||
* @var bool enableDataVariables true if @data variables should be used.
|
||||
*/
|
||||
protected $enableDataVariables = false;
|
||||
|
||||
/**
|
||||
* Mustache rendering Context constructor.
|
||||
*
|
||||
* @param mixed $context Default rendering context (default: null)
|
||||
* @param array $options Options for the context. It may contain the following: (default: empty array)
|
||||
* enableDataVariables => Boolean, Enables @data variables (default: false)
|
||||
*
|
||||
* @throws InvalidArgumentException when calling this method when enableDataVariables is not a boolean.
|
||||
*/
|
||||
public function __construct($context = null, $options = [])
|
||||
{
|
||||
if ($context !== null) {
|
||||
$this->stack = [$context];
|
||||
}
|
||||
|
||||
if (isset($options[Handlebars::OPTION_ENABLE_DATA_VARIABLES])) {
|
||||
if (!is_bool($options[Handlebars::OPTION_ENABLE_DATA_VARIABLES])) {
|
||||
throw new InvalidArgumentException(
|
||||
'Context Constructor "' . Handlebars::OPTION_ENABLE_DATA_VARIABLES . '" option must be a boolean'
|
||||
);
|
||||
}
|
||||
$this->enableDataVariables = $options[Handlebars::OPTION_ENABLE_DATA_VARIABLES];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Push a new Context frame onto the stack.
|
||||
*
|
||||
* @param mixed $value Object or array to use for context
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function push($value)
|
||||
{
|
||||
array_push($this->stack, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Push an Index onto the index stack
|
||||
*
|
||||
* @param integer $index Index of the current section item.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function pushIndex($index)
|
||||
{
|
||||
array_push($this->index, $index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pushes data variables onto the stack. This is used to support @data variables.
|
||||
* @param array $data Associative array where key is the name of the @data variable and value is the value.
|
||||
* @throws LogicException when calling this method without having enableDataVariables.
|
||||
*/
|
||||
public function pushData($data)
|
||||
{
|
||||
if (!$this->enableDataVariables) {
|
||||
throw new LogicException('Data variables are not supported due to the enableDataVariables configuration. Remove the call to data variables or change the setting.');
|
||||
}
|
||||
array_push($this->dataStack, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Push a Key onto the key stack
|
||||
*
|
||||
* @param string $key Key of the current object property.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function pushKey($key)
|
||||
{
|
||||
array_push($this->key, $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pop the last Context frame from the stack.
|
||||
*
|
||||
* @return mixed Last Context frame (object or array)
|
||||
*/
|
||||
public function pop()
|
||||
{
|
||||
return array_pop($this->stack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pop the last index from the stack.
|
||||
*
|
||||
* @return int Last index
|
||||
*/
|
||||
public function popIndex()
|
||||
{
|
||||
return array_pop($this->index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pop the last section data from the stack.
|
||||
*
|
||||
* @return array Last data
|
||||
* @throws LogicException when calling this method without having enableDataVariables.
|
||||
*/
|
||||
public function popData()
|
||||
{
|
||||
if (!$this->enableDataVariables) {
|
||||
throw new LogicException('Data variables are not supported due to the enableDataVariables configuration. Remove the call to data variables or change the setting.');
|
||||
}
|
||||
return array_pop($this->dataStack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pop the last key from the stack.
|
||||
*
|
||||
* @return string Last key
|
||||
*/
|
||||
public function popKey()
|
||||
{
|
||||
return array_pop($this->key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last Context frame.
|
||||
*
|
||||
* @return mixed Last Context frame (object or array)
|
||||
*/
|
||||
public function last()
|
||||
{
|
||||
return end($this->stack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the index of current section item.
|
||||
*
|
||||
* @return mixed Last index
|
||||
*/
|
||||
public function lastIndex()
|
||||
{
|
||||
return end($this->index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the key of current object property.
|
||||
*
|
||||
* @return mixed Last key
|
||||
*/
|
||||
public function lastKey()
|
||||
{
|
||||
return end($this->key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the current context to one of current context members
|
||||
*
|
||||
* @param string $variableName name of variable or a callable on current context
|
||||
*
|
||||
* @return mixed actual value
|
||||
*/
|
||||
public function with($variableName)
|
||||
{
|
||||
$value = $this->get($variableName);
|
||||
$this->push($value);
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a avariable from current context
|
||||
* Supported types :
|
||||
* variable , ../variable , variable.variable , .
|
||||
*
|
||||
* @param string $variableName variavle name to get from current context
|
||||
* @param boolean $strict strict search? if not found then throw exception
|
||||
*
|
||||
* @throws InvalidArgumentException in strict mode and variable not found
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($variableName, $strict = false)
|
||||
{
|
||||
//Need to clean up
|
||||
$variableName = trim($variableName);
|
||||
|
||||
//Handle data variables (@index, @first, @last, etc)
|
||||
if ($this->enableDataVariables && substr($variableName, 0, 1) == '@') {
|
||||
return $this->getDataVariable($variableName, $strict);
|
||||
}
|
||||
|
||||
$level = 0;
|
||||
while (substr($variableName, 0, 3) == '../') {
|
||||
$variableName = trim(substr($variableName, 3));
|
||||
$level++;
|
||||
}
|
||||
if (count($this->stack) < $level) {
|
||||
if ($strict) {
|
||||
throw new InvalidArgumentException(
|
||||
'can not find variable in context'
|
||||
);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
end($this->stack);
|
||||
while ($level) {
|
||||
prev($this->stack);
|
||||
$level--;
|
||||
}
|
||||
$current = current($this->stack);
|
||||
if (!$variableName) {
|
||||
if ($strict) {
|
||||
throw new InvalidArgumentException(
|
||||
'can not find variable in context'
|
||||
);
|
||||
}
|
||||
return '';
|
||||
} elseif ($variableName == '.' || $variableName == 'this') {
|
||||
return $current;
|
||||
} else {
|
||||
$chunks = explode('.', $variableName);
|
||||
foreach ($chunks as $chunk) {
|
||||
if (is_string($current) and $current == '') {
|
||||
return $current;
|
||||
}
|
||||
$current = $this->findVariableInContext($current, $chunk, $strict);
|
||||
}
|
||||
}
|
||||
return $current;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a data variable, retrieves the value associated.
|
||||
*
|
||||
* @param $variableName
|
||||
* @param bool $strict
|
||||
* @return mixed
|
||||
* @throws LogicException when calling this method without having enableDataVariables.
|
||||
*/
|
||||
public function getDataVariable($variableName, $strict = false)
|
||||
{
|
||||
if (!$this->enableDataVariables) {
|
||||
throw new LogicException('Data variables are not supported due to the enableDataVariables configuration. Remove the call to data variables or change the setting.');
|
||||
}
|
||||
|
||||
$variableName = trim($variableName);
|
||||
|
||||
// make sure we get an at-symbol prefix
|
||||
if (substr($variableName, 0, 1) != '@') {
|
||||
if ($strict) {
|
||||
throw new InvalidArgumentException(
|
||||
'Can not find variable in context'
|
||||
);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
// Remove the at-symbol prefix
|
||||
$variableName = substr($variableName, 1);
|
||||
|
||||
// determine the level of relative @data variables
|
||||
$level = 0;
|
||||
while (substr($variableName, 0, 3) == '../') {
|
||||
$variableName = trim(substr($variableName, 3));
|
||||
$level++;
|
||||
}
|
||||
|
||||
// make sure the stack actually has the specified number of levels
|
||||
if (count($this->dataStack) < $level) {
|
||||
if ($strict) {
|
||||
throw new InvalidArgumentException(
|
||||
'Can not find variable in context'
|
||||
);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
// going from the top of the stack to the bottom, traverse the number of levels specified
|
||||
end($this->dataStack);
|
||||
while ($level) {
|
||||
prev($this->dataStack);
|
||||
$level--;
|
||||
}
|
||||
|
||||
/** @var array $current */
|
||||
$current = current($this->dataStack);
|
||||
|
||||
if (!array_key_exists($variableName, $current)) {
|
||||
if ($strict) {
|
||||
throw new InvalidArgumentException(
|
||||
'Can not find variable in context'
|
||||
);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
return $current[$variableName];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if $variable->$inside is available
|
||||
*
|
||||
* @param mixed $variable variable to check
|
||||
* @param string $inside property/method to check
|
||||
* @param boolean $strict strict search? if not found then throw exception
|
||||
*
|
||||
* @throws \InvalidArgumentException in strict mode and variable not found
|
||||
* @return boolean true if exist
|
||||
*/
|
||||
private function findVariableInContext($variable, $inside, $strict = false)
|
||||
{
|
||||
$value = '';
|
||||
if (($inside !== '0' && empty($inside)) || ($inside == 'this')) {
|
||||
return $variable;
|
||||
} elseif (is_array($variable)) {
|
||||
if (isset($variable[$inside])) {
|
||||
$value = $variable[$inside];
|
||||
}
|
||||
} elseif (is_object($variable)) {
|
||||
if (isset($variable->$inside)) {
|
||||
$value = $variable->$inside;
|
||||
} elseif (is_callable(array($variable, $inside))) {
|
||||
$value = call_user_func(array($variable, $inside));
|
||||
}
|
||||
} elseif ($inside === '.') {
|
||||
$value = $variable;
|
||||
} elseif ($strict) {
|
||||
throw new InvalidArgumentException('can not find variable in context');
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
533
vendor/salesforce/handlebars-php/src/Handlebars/Handlebars.php
vendored
Executable file
533
vendor/salesforce/handlebars-php/src/Handlebars/Handlebars.php
vendored
Executable file
@@ -0,0 +1,533 @@
|
||||
<?php
|
||||
/**
|
||||
* Handlebars
|
||||
*
|
||||
* @category Xamin
|
||||
* @package Handlebars
|
||||
* @author fzerorubigd <fzerorubigd@gmail.com>
|
||||
* @author Behrooz Shabani <everplays@gmail.com>
|
||||
* @author Mardix <https://github.com/mardix>
|
||||
* @copyright 2012 (c) ParsPooyesh Co
|
||||
* @copyright 2013 (c) Behrooz Shabani
|
||||
* @copyright 2014 (c) Mardix
|
||||
* @license MIT
|
||||
* @link http://voodoophp.org/docs/handlebars
|
||||
*/
|
||||
|
||||
namespace Handlebars;
|
||||
use Handlebars\Loader\StringLoader;
|
||||
use Handlebars\Cache\Dummy;
|
||||
use InvalidArgumentException;
|
||||
|
||||
|
||||
class Handlebars
|
||||
{
|
||||
private static $instance = null;
|
||||
const VERSION = '2.2';
|
||||
|
||||
const OPTION_ENABLE_DATA_VARIABLES = 'enableDataVariables';
|
||||
|
||||
/**
|
||||
* factory method
|
||||
*
|
||||
* @param array $options see __construct's options parameter
|
||||
*
|
||||
* @return Handlebars
|
||||
*/
|
||||
public static function factory($options = array())
|
||||
{
|
||||
if (! self::$instance) {
|
||||
self::$instance = new self($options);
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @var Tokenizer
|
||||
*/
|
||||
private $tokenizer;
|
||||
|
||||
/**
|
||||
* @var Parser
|
||||
*/
|
||||
private $parser;
|
||||
|
||||
/**
|
||||
* @var Helpers
|
||||
*/
|
||||
private $helpers;
|
||||
|
||||
/**
|
||||
* @var Loader
|
||||
*/
|
||||
private $loader;
|
||||
|
||||
/**
|
||||
* @var Loader
|
||||
*/
|
||||
private $partialsLoader;
|
||||
|
||||
/**
|
||||
* @var Cache
|
||||
*/
|
||||
private $cache;
|
||||
|
||||
/**
|
||||
* @var callable escape function to use
|
||||
*/
|
||||
private $escape = 'htmlspecialchars';
|
||||
|
||||
/**
|
||||
* @var array parametes to pass to escape function
|
||||
*/
|
||||
private $escapeArgs = array(
|
||||
ENT_COMPAT,
|
||||
'UTF-8'
|
||||
);
|
||||
|
||||
private $aliases = array();
|
||||
|
||||
/**
|
||||
* @var bool Enable @data variables
|
||||
*/
|
||||
private $enableDataVariables = false;
|
||||
|
||||
/**
|
||||
* Handlebars engine constructor
|
||||
* $options array can contain :
|
||||
* helpers => Helpers object
|
||||
* escape => a callable function to escape values
|
||||
* escapeArgs => array to pass as extra parameter to escape function
|
||||
* loader => Loader object
|
||||
* partials_loader => Loader object
|
||||
* cache => Cache object
|
||||
* enableDataVariables => boolean. Enables @data variables (default: false)
|
||||
*
|
||||
* @param array $options array of options to set
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(Array $options = [])
|
||||
{
|
||||
if (isset($options['helpers'])) {
|
||||
$this->setHelpers($options['helpers']);
|
||||
}
|
||||
|
||||
if (isset($options['loader'])) {
|
||||
$this->setLoader($options['loader']);
|
||||
}
|
||||
|
||||
if (isset($options['partials_loader'])) {
|
||||
$this->setPartialsLoader($options['partials_loader']);
|
||||
}
|
||||
|
||||
if (isset($options['cache'])) {
|
||||
$this->setCache($options['cache']);
|
||||
}
|
||||
|
||||
if (isset($options['escape'])) {
|
||||
if (!is_callable($options['escape'])) {
|
||||
throw new InvalidArgumentException(
|
||||
'Handlebars Constructor "escape" option must be callable'
|
||||
);
|
||||
}
|
||||
$this->escape = $options['escape'];
|
||||
}
|
||||
|
||||
if (isset($options['escapeArgs'])) {
|
||||
if (!is_array($options['escapeArgs'])) {
|
||||
$options['escapeArgs'] = array($options['escapeArgs']);
|
||||
}
|
||||
$this->escapeArgs = $options['escapeArgs'];
|
||||
}
|
||||
|
||||
if (isset($options['partials_alias'])
|
||||
&& is_array($options['partials_alias'])
|
||||
) {
|
||||
$this->aliases = $options['partials_alias'];
|
||||
}
|
||||
|
||||
if (isset($options[self::OPTION_ENABLE_DATA_VARIABLES])) {
|
||||
if (!is_bool($options[self::OPTION_ENABLE_DATA_VARIABLES])) {
|
||||
throw new InvalidArgumentException(
|
||||
'Handlebars Constructor "' . self::OPTION_ENABLE_DATA_VARIABLES . '" option must be a boolean'
|
||||
);
|
||||
}
|
||||
$this->enableDataVariables = $options[self::OPTION_ENABLE_DATA_VARIABLES];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Shortcut 'render' invocation.
|
||||
*
|
||||
* Equivalent to calling `$handlebars->loadTemplate($template)->render($data);`
|
||||
*
|
||||
* @param string $template template name
|
||||
* @param mixed $data data to use as context
|
||||
* @return string Rendered template
|
||||
*/
|
||||
public function render($template, $data)
|
||||
{
|
||||
return $this->loadTemplate($template)->render($data);
|
||||
}
|
||||
/**
|
||||
* To invoke when this object is called as a function
|
||||
*
|
||||
* @param string $template template name
|
||||
* @param mixed $data data to use as context
|
||||
* @return string Rendered template
|
||||
*/
|
||||
public function __invoke($template, $data)
|
||||
{
|
||||
return $this->render($template, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set helpers for current enfine
|
||||
*
|
||||
* @param Helpers $helpers handlebars helper
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setHelpers(Helpers $helpers)
|
||||
{
|
||||
$this->helpers = $helpers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get helpers, or create new one if ther is no helper
|
||||
*
|
||||
* @return Helpers
|
||||
*/
|
||||
public function getHelpers()
|
||||
{
|
||||
if (!isset($this->helpers)) {
|
||||
$this->helpers = new Helpers();
|
||||
}
|
||||
return $this->helpers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new helper.
|
||||
*
|
||||
* @param string $name helper name
|
||||
* @param mixed $helper helper callable
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addHelper($name, $helper)
|
||||
{
|
||||
$this->getHelpers()->add($name, $helper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a helper by name.
|
||||
*
|
||||
* @param string $name helper name
|
||||
* @return callable Helper
|
||||
*/
|
||||
public function getHelper($name)
|
||||
{
|
||||
return $this->getHelpers()->__get($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this instance has a helper.
|
||||
*
|
||||
* @param string $name helper name
|
||||
* @return boolean True if the helper is present
|
||||
*/
|
||||
public function hasHelper($name)
|
||||
{
|
||||
return $this->getHelpers()->has($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a helper by name.
|
||||
*
|
||||
* @param string $name helper name
|
||||
* @return void
|
||||
*/
|
||||
public function removeHelper($name)
|
||||
{
|
||||
$this->getHelpers()->remove($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set current loader
|
||||
*
|
||||
* @param Loader $loader handlebars loader
|
||||
* @return void
|
||||
*/
|
||||
public function setLoader(Loader $loader)
|
||||
{
|
||||
$this->loader = $loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* get current loader
|
||||
*
|
||||
* @return Loader
|
||||
*/
|
||||
public function getLoader()
|
||||
{
|
||||
if (! isset($this->loader)) {
|
||||
$this->loader = new StringLoader();
|
||||
}
|
||||
return $this->loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set current partials loader
|
||||
*
|
||||
* @param Loader $loader handlebars loader
|
||||
* @return void
|
||||
*/
|
||||
public function setPartialsLoader(Loader $loader)
|
||||
{
|
||||
$this->partialsLoader = $loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* get current partials loader
|
||||
*
|
||||
* @return Loader
|
||||
*/
|
||||
public function getPartialsLoader()
|
||||
{
|
||||
if (!isset($this->partialsLoader)) {
|
||||
$this->partialsLoader = new StringLoader();
|
||||
}
|
||||
return $this->partialsLoader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cache for current engine
|
||||
*
|
||||
* @param Cache $cache handlebars cache
|
||||
* @return void
|
||||
*/
|
||||
public function setCache(Cache $cache)
|
||||
{
|
||||
$this->cache = $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cache
|
||||
*
|
||||
* @return Cache
|
||||
*/
|
||||
public function getCache()
|
||||
{
|
||||
if (!isset($this->cache)) {
|
||||
$this->cache = new Dummy();
|
||||
}
|
||||
return $this->cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current escape function
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
public function getEscape()
|
||||
{
|
||||
return $this->escape;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set current escape function
|
||||
*
|
||||
* @param callable $escape function
|
||||
* @throws \InvalidArgumentException
|
||||
* @return void
|
||||
*/
|
||||
public function setEscape($escape)
|
||||
{
|
||||
if (!is_callable($escape)) {
|
||||
throw new InvalidArgumentException(
|
||||
'Escape function must be a callable'
|
||||
);
|
||||
}
|
||||
$this->escape = $escape;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current escape function
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getEscapeArgs()
|
||||
{
|
||||
return $this->escapeArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set current escape function
|
||||
*
|
||||
* @param array $escapeArgs arguments to pass as extra arg to function
|
||||
* @return void
|
||||
*/
|
||||
public function setEscapeArgs($escapeArgs)
|
||||
{
|
||||
if (! is_array($escapeArgs)) {
|
||||
$escapeArgs = array($escapeArgs);
|
||||
}
|
||||
$this->escapeArgs = $escapeArgs;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the Handlebars Tokenizer instance.
|
||||
*
|
||||
* @param Tokenizer $tokenizer tokenizer
|
||||
* @return void
|
||||
*/
|
||||
public function setTokenizer(Tokenizer $tokenizer)
|
||||
{
|
||||
$this->tokenizer = $tokenizer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current Handlebars Tokenizer instance.
|
||||
*
|
||||
* If no Tokenizer instance has been explicitly specified, this method will
|
||||
* instantiate and return a new one.
|
||||
*
|
||||
* @return Tokenizer
|
||||
*/
|
||||
public function getTokenizer()
|
||||
{
|
||||
if (! isset($this->tokenizer)) {
|
||||
$this->tokenizer = new Tokenizer();
|
||||
}
|
||||
|
||||
return $this->tokenizer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Handlebars Parser instance.
|
||||
*
|
||||
* @param Parser $parser parser object
|
||||
* @return void
|
||||
*/
|
||||
public function setParser(Parser $parser)
|
||||
{
|
||||
$this->parser = $parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current Handlebars Parser instance.
|
||||
*
|
||||
* If no Parser instance has been explicitly specified, this method will
|
||||
* instantiate and return a new one.
|
||||
*
|
||||
* @return Parser
|
||||
*/
|
||||
public function getParser()
|
||||
{
|
||||
if (! isset($this->parser)) {
|
||||
$this->parser = new Parser();
|
||||
}
|
||||
return $this->parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the @data variables are enabled.
|
||||
* @return bool
|
||||
*/
|
||||
public function isDataVariablesEnabled()
|
||||
{
|
||||
return $this->enableDataVariables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a template by name with current template loader
|
||||
*
|
||||
* @param string $name template name
|
||||
*
|
||||
* @return Template
|
||||
*/
|
||||
public function loadTemplate($name)
|
||||
{
|
||||
$source = $this->getLoader()->load($name);
|
||||
$tree = $this->tokenize($source);
|
||||
return new Template($this, $tree, $source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a partial by name with current partial loader
|
||||
*
|
||||
* @param string $name partial name
|
||||
*
|
||||
* @return Template
|
||||
*/
|
||||
public function loadPartial($name)
|
||||
{
|
||||
if (isset($this->aliases[$name])) {
|
||||
$name = $this->aliases[$name];
|
||||
}
|
||||
$source = $this->getPartialsLoader()->load($name);
|
||||
$tree = $this->tokenize($source);
|
||||
return new Template($this, $tree, $source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register partial alias
|
||||
*
|
||||
* @param string $alias Partial alias
|
||||
* @param string $content The real value
|
||||
* @return void
|
||||
*/
|
||||
public function registerPartial($alias, $content)
|
||||
{
|
||||
$this->aliases[$alias] = $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Un-register partial alias
|
||||
*
|
||||
* @param string $alias Partial alias
|
||||
* @return void
|
||||
*/
|
||||
public function unRegisterPartial($alias)
|
||||
{
|
||||
if (isset($this->aliases[$alias])) {
|
||||
unset($this->aliases[$alias]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load string into a template object
|
||||
*
|
||||
* @param string $source string to load
|
||||
* @return Template
|
||||
*/
|
||||
public function loadString($source)
|
||||
{
|
||||
$tree = $this->tokenize($source);
|
||||
return new Template($this, $tree, $source);
|
||||
}
|
||||
|
||||
/**
|
||||
* try to tokenize source, or get them from cache if available
|
||||
*
|
||||
* @param string $source handlebars source code
|
||||
* @return array handlebars parsed data into array
|
||||
*/
|
||||
private function tokenize($source)
|
||||
{
|
||||
$hash = md5(sprintf('version: %s, data : %s', self::VERSION, $source));
|
||||
$tree = $this->getCache()->get($hash);
|
||||
if ($tree === false) {
|
||||
$tokens = $this->getTokenizer()->scan($source);
|
||||
$tree = $this->getParser()->parse($tokens);
|
||||
$this->getCache()->set($hash, $tree);
|
||||
}
|
||||
return $tree;
|
||||
}
|
||||
|
||||
}
|
||||
65
vendor/salesforce/handlebars-php/src/Handlebars/HandlebarsString.php
vendored
Normal file
65
vendor/salesforce/handlebars-php/src/Handlebars/HandlebarsString.php
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/**
|
||||
* Handlebars string
|
||||
*
|
||||
* @category Xamin
|
||||
* @package Handlebars
|
||||
* @author fzerorubigd <fzerorubigd@gmail.com>
|
||||
* @author Behrooz Shabani <everplays@gmail.com>
|
||||
* @author Mardix <https://github.com/mardix>
|
||||
* @copyright 2012 (c) ParsPooyesh Co
|
||||
* @copyright 2013 (c) Behrooz Shabani
|
||||
* @copyright 2013 (c) Mardix
|
||||
* @license MIT
|
||||
* @link http://voodoophp.org/docs/handlebars
|
||||
*/
|
||||
|
||||
namespace Handlebars;
|
||||
|
||||
class HandlebarsString
|
||||
{
|
||||
private $string = "";
|
||||
|
||||
/**
|
||||
* Create new string
|
||||
*
|
||||
* @param string $string input source
|
||||
*/
|
||||
public function __construct($string)
|
||||
{
|
||||
$this->setString($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* To String
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getString()
|
||||
{
|
||||
return $this->string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new string
|
||||
*
|
||||
* @param string $string input source
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setString($string)
|
||||
{
|
||||
$this->string = $string;
|
||||
}
|
||||
|
||||
}
|
||||
733
vendor/salesforce/handlebars-php/src/Handlebars/Helpers.php
vendored
Executable file
733
vendor/salesforce/handlebars-php/src/Handlebars/Helpers.php
vendored
Executable file
@@ -0,0 +1,733 @@
|
||||
<?php
|
||||
/**
|
||||
* Helpers
|
||||
*
|
||||
* a collection of helper function. normally a function like
|
||||
* function ($sender, $name, $arguments) $arguments is unscaped arguments and
|
||||
* is a string, not array
|
||||
*
|
||||
* @category Xamin
|
||||
* @package Handlebars
|
||||
* @author fzerorubigd <fzerorubigd@gmail.com>
|
||||
* @author Behrooz Shabani <everplays@gmail.com>
|
||||
* @author Mardix <https://github.com/mardix>
|
||||
* @copyright 2012 (c) ParsPooyesh Co
|
||||
* @copyright 2013 (c) Behrooz Shabani
|
||||
* @copyright 2014 (c) Mardix
|
||||
* @license MIT
|
||||
* @link http://voodoophp.org/docs/handlebars
|
||||
*/
|
||||
|
||||
namespace Handlebars;
|
||||
|
||||
use DateTime;
|
||||
use InvalidArgumentException;
|
||||
use Traversable;
|
||||
use LogicException;
|
||||
|
||||
class Helpers
|
||||
{
|
||||
/**
|
||||
* @var array array of helpers
|
||||
*/
|
||||
protected $helpers = [];
|
||||
private $tpl = [];
|
||||
protected $builtinHelpers = [
|
||||
"if",
|
||||
"each",
|
||||
"with",
|
||||
"unless",
|
||||
"bindAttr",
|
||||
"upper", // Put all chars in uppercase
|
||||
"lower", // Put all chars in lowercase
|
||||
"capitalize", // Capitalize just the first word
|
||||
"capitalize_words", // Capitalize each words
|
||||
"reverse", // Reverse a string
|
||||
"format_date", // Format a date
|
||||
"inflect", // Inflect the wording based on count ie. 1 album, 10 albums
|
||||
"default", // If a variable is null, it will use the default instead
|
||||
"truncate", // Truncate section
|
||||
"raw", // Return the source as is without converting
|
||||
"repeat", // Repeat a section
|
||||
"define", // Define a block to be used using "invoke"
|
||||
"invoke", // Invoke a block that was defined with "define"
|
||||
];
|
||||
|
||||
/**
|
||||
* Create new helper container class
|
||||
*
|
||||
* @param array $helpers array of name=>$value helpers
|
||||
* @throws \InvalidArgumentException when $helpers is not an array
|
||||
* (or traversable) or helper is not a callable
|
||||
*/
|
||||
public function __construct($helpers = null)
|
||||
{
|
||||
foreach($this->builtinHelpers as $helper) {
|
||||
$helperName = $this->underscoreToCamelCase($helper);
|
||||
$this->add($helper, [$this, "helper{$helperName}"]);
|
||||
}
|
||||
|
||||
if ($helpers != null) {
|
||||
if (!is_array($helpers) && !$helpers instanceof Traversable) {
|
||||
throw new InvalidArgumentException(
|
||||
'HelperCollection constructor expects an array of helpers'
|
||||
);
|
||||
}
|
||||
foreach ($helpers as $name => $helper) {
|
||||
$this->add($name, $helper);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new helper to helpers
|
||||
*
|
||||
* @param string $name helper name
|
||||
* @param callable $helper a function as a helper
|
||||
*
|
||||
* @throws \InvalidArgumentException if $helper is not a callable
|
||||
* @return void
|
||||
*/
|
||||
public function add($name, $helper)
|
||||
{
|
||||
if (!is_callable($helper)) {
|
||||
throw new InvalidArgumentException("$name Helper is not a callable.");
|
||||
}
|
||||
$this->helpers[$name] = $helper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if $name helper is available
|
||||
*
|
||||
* @param string $name helper name
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function has($name)
|
||||
{
|
||||
return array_key_exists($name, $this->helpers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a helper. __magic__ method :)
|
||||
*
|
||||
* @param string $name helper name
|
||||
*
|
||||
* @throws \InvalidArgumentException if $name is not available
|
||||
* @return callable helper function
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
if (!$this->has($name)) {
|
||||
throw new InvalidArgumentException('Unknown helper :' . $name);
|
||||
}
|
||||
return $this->helpers[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if $name helper is available __magic__ method :)
|
||||
*
|
||||
* @param string $name helper name
|
||||
*
|
||||
* @return boolean
|
||||
* @see Handlebras_Helpers::has
|
||||
*/
|
||||
public function __isset($name)
|
||||
{
|
||||
return $this->has($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new helper to helpers __magic__ method :)
|
||||
*
|
||||
* @param string $name helper name
|
||||
* @param callable $helper a function as a helper
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __set($name, $helper)
|
||||
{
|
||||
$this->add($name, $helper);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Unset a helper
|
||||
*
|
||||
* @param string $name helper name to remove
|
||||
* @return void
|
||||
*/
|
||||
public function __unset($name)
|
||||
{
|
||||
unset($this->helpers[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a given helper is present in the collection.
|
||||
*
|
||||
* @param string $name helper name
|
||||
* @throws \InvalidArgumentException if the requested helper is not present.
|
||||
* @return void
|
||||
*/
|
||||
public function remove($name)
|
||||
{
|
||||
if (!$this->has($name)) {
|
||||
throw new InvalidArgumentException('Unknown helper: ' . $name);
|
||||
}
|
||||
unset($this->helpers[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the helper collection.
|
||||
*
|
||||
* Removes all helpers from this collection
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->helpers = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the helper collection is empty.
|
||||
*
|
||||
* @return boolean True if the collection is empty
|
||||
*/
|
||||
public function isEmpty()
|
||||
{
|
||||
return empty($this->helpers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create handler for the 'if' helper.
|
||||
*
|
||||
* {{#if condition}}
|
||||
* Something here
|
||||
* {{else}}
|
||||
* something else here
|
||||
* {{/if}}
|
||||
*
|
||||
* @param \Handlebars\Template $template template that is being rendered
|
||||
* @param \Handlebars\Context $context context object
|
||||
* @param array $args passed arguments to helper
|
||||
* @param string $source part of template that is wrapped
|
||||
* within helper
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function helperIf($template, $context, $args, $source)
|
||||
{
|
||||
$tmp = $context->get($args);
|
||||
if ($tmp) {
|
||||
$template->setStopToken('else');
|
||||
$buffer = $template->render($context);
|
||||
$template->setStopToken(false);
|
||||
$template->discard();
|
||||
return $buffer;
|
||||
} else {
|
||||
return $this->renderElse($template, $context);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create handler for the 'each' helper.
|
||||
* example {{#each people}} {{name}} {{/each}}
|
||||
* example with slice: {{#each people[0:10]}} {{name}} {{/each}}
|
||||
* example with else
|
||||
* {{#each Array}}
|
||||
* {{.}}
|
||||
* {{else}}
|
||||
* Nothing found
|
||||
* {{/each}}
|
||||
*
|
||||
* @param \Handlebars\Template $template template that is being rendered
|
||||
* @param \Handlebars\Context $context context object
|
||||
* @param array $args passed arguments to helper
|
||||
* @param string $source part of template that is wrapped
|
||||
* within helper
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function helperEach($template, $context, $args, $source)
|
||||
{
|
||||
list($keyname, $slice_start, $slice_end) = $this->extractSlice($args);
|
||||
$tmp = $context->get($keyname);
|
||||
|
||||
if (is_array($tmp) || $tmp instanceof Traversable) {
|
||||
$tmp = array_slice($tmp, $slice_start, $slice_end);
|
||||
$buffer = '';
|
||||
$islist = array_values($tmp) === $tmp;
|
||||
|
||||
if (is_array($tmp) && ! count($tmp)) {
|
||||
return $this->renderElse($template, $context);
|
||||
} else {
|
||||
|
||||
$itemCount = -1;
|
||||
if ($islist) {
|
||||
$itemCount = count($tmp);
|
||||
}
|
||||
|
||||
foreach ($tmp as $key => $var) {
|
||||
$tpl = clone $template;
|
||||
if ($islist) {
|
||||
$context->pushIndex($key);
|
||||
|
||||
// If data variables are enabled, push the data related to this #each context
|
||||
if ($template->getEngine()->isDataVariablesEnabled()) {
|
||||
$context->pushData([
|
||||
Context::DATA_KEY => $key,
|
||||
Context::DATA_INDEX => $key,
|
||||
Context::DATA_LAST => $key == ($itemCount - 1),
|
||||
Context::DATA_FIRST => $key == 0,
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
$context->pushKey($key);
|
||||
|
||||
// If data variables are enabled, push the data related to this #each context
|
||||
if ($template->getEngine()->isDataVariablesEnabled()) {
|
||||
$context->pushData([
|
||||
Context::DATA_KEY => $key,
|
||||
]);
|
||||
}
|
||||
}
|
||||
$context->push($var);
|
||||
$tpl->setStopToken('else');
|
||||
$buffer .= $tpl->render($context);
|
||||
$context->pop();
|
||||
if ($islist) {
|
||||
$context->popIndex();
|
||||
} else {
|
||||
$context->popKey();
|
||||
}
|
||||
|
||||
if ($template->getEngine()->isDataVariablesEnabled()) {
|
||||
$context->popData();
|
||||
}
|
||||
}
|
||||
return $buffer;
|
||||
}
|
||||
} else {
|
||||
return $this->renderElse($template, $context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applying the DRY principle here.
|
||||
* This method help us render {{else}} portion of a block
|
||||
* @param \Handlebars\Template $template
|
||||
* @param \Handlebars\Context $context
|
||||
* @return string
|
||||
*/
|
||||
private function renderElse($template, $context)
|
||||
{
|
||||
$template->setStopToken('else');
|
||||
$template->discard();
|
||||
$template->setStopToken(false);
|
||||
return $template->render($context);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create handler for the 'unless' helper.
|
||||
* {{#unless condition}}
|
||||
* Something here
|
||||
* {{else}}
|
||||
* something else here
|
||||
* {{/unless}}
|
||||
* @param \Handlebars\Template $template template that is being rendered
|
||||
* @param \Handlebars\Context $context context object
|
||||
* @param array $args passed arguments to helper
|
||||
* @param string $source part of template that is wrapped
|
||||
* within helper
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function helperUnless($template, $context, $args, $source)
|
||||
{
|
||||
$tmp = $context->get($args);
|
||||
if (!$tmp) {
|
||||
$template->setStopToken('else');
|
||||
$buffer = $template->render($context);
|
||||
$template->setStopToken(false);
|
||||
$template->discard();
|
||||
return $buffer;
|
||||
} else {
|
||||
return $this->renderElse($template, $context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create handler for the 'with' helper.
|
||||
* Needed for compatibility with PHP 5.2 since it doesn't support anonymous
|
||||
* functions.
|
||||
*
|
||||
* @param \Handlebars\Template $template template that is being rendered
|
||||
* @param \Handlebars\Context $context context object
|
||||
* @param array $args passed arguments to helper
|
||||
* @param string $source part of template that is wrapped
|
||||
* within helper
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function helperWith($template, $context, $args, $source)
|
||||
{
|
||||
$tmp = $context->get($args);
|
||||
$context->push($tmp);
|
||||
$buffer = $template->render($context);
|
||||
$context->pop();
|
||||
|
||||
return $buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create handler for the 'bindAttr' helper.
|
||||
* Needed for compatibility with PHP 5.2 since it doesn't support anonymous
|
||||
* functions.
|
||||
*
|
||||
* @param \Handlebars\Template $template template that is being rendered
|
||||
* @param \Handlebars\Context $context context object
|
||||
* @param array $args passed arguments to helper
|
||||
* @param string $source part of template that is wrapped
|
||||
* within helper
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function helperBindAttr($template, $context, $args, $source)
|
||||
{
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* To uppercase string
|
||||
*
|
||||
* {{#upper data}}
|
||||
*
|
||||
* @param \Handlebars\Template $template template that is being rendered
|
||||
* @param \Handlebars\Context $context context object
|
||||
* @param array $args passed arguments to helper
|
||||
* @param string $source part of template that is wrapped
|
||||
* within helper
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function helperUpper($template, $context, $args, $source)
|
||||
{
|
||||
return strtoupper($context->get($args));
|
||||
}
|
||||
|
||||
/**
|
||||
* To lowercase string
|
||||
*
|
||||
* {{#lower data}}
|
||||
*
|
||||
* @param \Handlebars\Template $template template that is being rendered
|
||||
* @param \Handlebars\Context $context context object
|
||||
* @param array $args passed arguments to helper
|
||||
* @param string $source part of template that is wrapped
|
||||
* within helper
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function helperLower($template, $context, $args, $source)
|
||||
{
|
||||
return strtolower($context->get($args));
|
||||
}
|
||||
|
||||
/**
|
||||
* to capitalize first letter
|
||||
*
|
||||
* {{#capitalize}}
|
||||
*
|
||||
* @param \Handlebars\Template $template template that is being rendered
|
||||
* @param \Handlebars\Context $context context object
|
||||
* @param array $args passed arguments to helper
|
||||
* @param string $source part of template that is wrapped
|
||||
* within helper
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function helperCapitalize($template, $context, $args, $source)
|
||||
{
|
||||
return ucfirst($context->get($args));
|
||||
}
|
||||
|
||||
/**
|
||||
* To capitalize first letter in each word
|
||||
*
|
||||
* {{#capitalize_words data}}
|
||||
*
|
||||
* @param \Handlebars\Template $template template that is being rendered
|
||||
* @param \Handlebars\Context $context context object
|
||||
* @param array $args passed arguments to helper
|
||||
* @param string $source part of template that is wrapped
|
||||
* within helper
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function helperCapitalizeWords($template, $context, $args, $source)
|
||||
{
|
||||
return ucwords($context->get($args));
|
||||
}
|
||||
|
||||
/**
|
||||
* To reverse a string
|
||||
*
|
||||
* {{#reverse data}}
|
||||
*
|
||||
* @param \Handlebars\Template $template template that is being rendered
|
||||
* @param \Handlebars\Context $context context object
|
||||
* @param array $args passed arguments to helper
|
||||
* @param string $source part of template that is wrapped
|
||||
* within helper
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function helperReverse($template, $context, $args, $source)
|
||||
{
|
||||
return strrev($context->get($args));
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a date
|
||||
*
|
||||
* {{#format_date date 'Y-m-d @h:i:s'}}
|
||||
*
|
||||
* @param \Handlebars\Template $template template that is being rendered
|
||||
* @param \Handlebars\Context $context context object
|
||||
* @param array $args passed arguments to helper
|
||||
* @param string $source part of template that is wrapped
|
||||
* within helper
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function helperFormatDate($template, $context, $args, $source)
|
||||
{
|
||||
preg_match("/(.*?)\s+(?:(?:\"|\')(.*?)(?:\"|\'))/", $args, $m);
|
||||
$keyname = $m[1];
|
||||
$format = $m[2];
|
||||
|
||||
$date = $context->get($keyname);
|
||||
if ($format) {
|
||||
$dt = new DateTime;
|
||||
if (is_numeric($date)) {
|
||||
$dt = (new DateTime)->setTimestamp($date);
|
||||
} else {
|
||||
$dt = new DateTime($date);
|
||||
}
|
||||
return $dt->format($format);
|
||||
} else {
|
||||
return $date;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {{inflect count 'album' 'albums'}}
|
||||
* {{inflect count '%d album' '%d albums'}}
|
||||
*
|
||||
* @param \Handlebars\Template $template template that is being rendered
|
||||
* @param \Handlebars\Context $context context object
|
||||
* @param array $args passed arguments to helper
|
||||
* @param string $source part of template that is wrapped
|
||||
* within helper
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function helperInflect($template, $context, $args, $source)
|
||||
{
|
||||
preg_match("/(.*?)\s+(?:(?:\"|\')(.*?)(?:\"|\'))\s+(?:(?:\"|\')(.*?)(?:\"|\'))/", $args, $m);
|
||||
$keyname = $m[1];
|
||||
$singular = $m[2];
|
||||
$plurial = $m[3];
|
||||
$value = $context->get($keyname);
|
||||
$inflect = ($value <= 1) ? $singular : $plurial;
|
||||
return sprintf($inflect, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a default fallback
|
||||
*
|
||||
* {{default title "No title available"}}
|
||||
*
|
||||
* @param \Handlebars\Template $template template that is being rendered
|
||||
* @param \Handlebars\Context $context context object
|
||||
* @param array $args passed arguments to helper
|
||||
* @param string $source part of template that is wrapped
|
||||
* within helper
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function helperDefault($template, $context, $args, $source)
|
||||
{
|
||||
preg_match("/(.*?)\s+(?:(?:\"|\')(.*?)(?:\"|\'))/", trim($args), $m);
|
||||
$keyname = $m[1];
|
||||
$default = $m[2];
|
||||
$value = $context->get($keyname);
|
||||
return ($value) ?: $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncate a string to a length, and append and ellipsis if provided
|
||||
* {{#truncate content 5 "..."}}
|
||||
*
|
||||
*
|
||||
* @param \Handlebars\Template $template template that is being rendered
|
||||
* @param \Handlebars\Context $context context object
|
||||
* @param array $args passed arguments to helper
|
||||
* @param string $source part of template that is wrapped
|
||||
* within helper
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function helperTruncate($template, $context, $args, $source)
|
||||
{
|
||||
preg_match("/(.*?)\s+(.*?)\s+(?:(?:\"|\')(.*?)(?:\"|\'))/", trim($args), $m);
|
||||
$keyname = $m[1];
|
||||
$limit = $m[2];
|
||||
$ellipsis = $m[3];
|
||||
$value = substr($context->get($keyname), 0, $limit);
|
||||
if ($ellipsis && strlen($context->get($keyname)) > $limit) {
|
||||
$value .= $ellipsis;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the data source as is
|
||||
*
|
||||
* {{#raw}} {{/raw}}
|
||||
*
|
||||
* @param \Handlebars\Template $template template that is being rendered
|
||||
* @param \Handlebars\Context $context context object
|
||||
* @param array $args passed arguments to helper
|
||||
* @param string $source part of template that is wrapped
|
||||
* within helper
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function helperRaw($template, $context, $args, $source)
|
||||
{
|
||||
return $source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Repeat section $x times.
|
||||
*
|
||||
* {{#repeat 10}}
|
||||
* This section will be repeated 10 times
|
||||
* {{/repeat}}
|
||||
*
|
||||
*
|
||||
* @param \Handlebars\Template $template template that is being rendered
|
||||
* @param \Handlebars\Context $context context object
|
||||
* @param array $args passed arguments to helper
|
||||
* @param string $source part of template that is wrapped
|
||||
* within helper
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function helperRepeat($template, $context, $args, $source)
|
||||
{
|
||||
$buffer = $template->render($context);
|
||||
return str_repeat($buffer, intval($args));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Define a section to be used later by using 'invoke'
|
||||
*
|
||||
* --> Define a section: hello
|
||||
* {{#define hello}}
|
||||
* Hello World!
|
||||
*
|
||||
* How is everything?
|
||||
* {{/define}}
|
||||
*
|
||||
* --> This is how it is called
|
||||
* {{#invoke hello}}
|
||||
*
|
||||
*
|
||||
* @param \Handlebars\Template $template template that is being rendered
|
||||
* @param \Handlebars\Context $context context object
|
||||
* @param array $args passed arguments to helper
|
||||
* @param string $source part of template that is wrapped
|
||||
* within helper
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function helperDefine($template, $context, $args, $source)
|
||||
{
|
||||
$this->tpl["DEFINE"][$args] = clone($template);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke a section that was created using 'define'
|
||||
*
|
||||
* --> Define a section: hello
|
||||
* {{#define hello}}
|
||||
* Hello World!
|
||||
*
|
||||
* How is everything?
|
||||
* {{/define}}
|
||||
*
|
||||
* --> This is how it is called
|
||||
* {{#invoke hello}}
|
||||
*
|
||||
*
|
||||
* @param \Handlebars\Template $template template that is being rendered
|
||||
* @param \Handlebars\Context $context context object
|
||||
* @param array $args passed arguments to helper
|
||||
* @param string $source part of template that is wrapped
|
||||
* within helper
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function helperInvoke($template, $context, $args, $source)
|
||||
{
|
||||
if (! isset($this->tpl["DEFINE"][$args])) {
|
||||
throw new LogicException("Can't INVOKE '{$args}'. '{$args}' was not DEFINE ");
|
||||
}
|
||||
return $this->tpl["DEFINE"][$args]->render($context);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Change underscore helper name to CamelCase
|
||||
*
|
||||
* @param string $string
|
||||
* @return string
|
||||
*/
|
||||
private function underscoreToCamelCase($string)
|
||||
{
|
||||
return str_replace(' ', '', ucwords(str_replace('_', ' ', $string)));
|
||||
}
|
||||
|
||||
/**
|
||||
* slice
|
||||
* Allow to split the data that will be returned
|
||||
* #loop[start:end] => starts at start trhough end -1
|
||||
* #loop[start:] = Starts at start though the rest of the array
|
||||
* #loop[:end] = Starts at the beginning through end -1
|
||||
* #loop[:] = A copy of the whole array
|
||||
*
|
||||
* #loop[-1]
|
||||
* #loop[-2:] = Last two items
|
||||
* #loop[:-2] = Everything except last two items
|
||||
*
|
||||
* @param string $string
|
||||
* @return Array [tag_name, slice_start, slice_end]
|
||||
*/
|
||||
private function extractSlice($string)
|
||||
{
|
||||
preg_match("/^([\w\._\-]+)(?:\[([\-0-9]*?:[\-0-9]*?)\])?/i", $string, $m);
|
||||
$slice_start = $slice_end = null;
|
||||
if (isset($m[2])) {
|
||||
list($slice_start, $slice_end) = explode(":", $m[2]);
|
||||
$slice_start = (int) $slice_start;
|
||||
$slice_end = $slice_end ? (int) $slice_end : null;
|
||||
}
|
||||
return [$m[1], $slice_start, $slice_end];
|
||||
}
|
||||
}
|
||||
29
vendor/salesforce/handlebars-php/src/Handlebars/Loader.php
vendored
Executable file
29
vendor/salesforce/handlebars-php/src/Handlebars/Loader.php
vendored
Executable file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
/**
|
||||
* Handlebars loader interface
|
||||
*
|
||||
* @category Xamin
|
||||
* @package Handlebars
|
||||
* @author fzerorubigd <fzerorubigd@gmail.com>
|
||||
* @author Behrooz Shabani <everplays@gmail.com>
|
||||
* @copyright 2012 (c) ParsPooyesh Co
|
||||
* @copyright 2013 (c) Behrooz Shabani
|
||||
* @license MIT
|
||||
* @link http://voodoophp.org/docs/handlebars
|
||||
*/
|
||||
|
||||
namespace Handlebars;
|
||||
|
||||
interface Loader
|
||||
{
|
||||
|
||||
/**
|
||||
* Load a Template by name.
|
||||
*
|
||||
* @param string $name template name to load
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public function load($name);
|
||||
|
||||
}
|
||||
144
vendor/salesforce/handlebars-php/src/Handlebars/Loader/FilesystemLoader.php
vendored
Executable file
144
vendor/salesforce/handlebars-php/src/Handlebars/Loader/FilesystemLoader.php
vendored
Executable file
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* @category Xamin
|
||||
* @package Handlebars
|
||||
* @author fzerorubigd <fzerorubigd@gmail.com>
|
||||
* @author Behrooz Shabani <everplays@gmail.com>
|
||||
* @author Craig Bass <craig@clearbooks.co.uk>
|
||||
* @author ^^ <craig@devls.co.uk>
|
||||
* @copyright 2012 (c) ParsPooyesh Co
|
||||
* @copyright 2013 (c) Behrooz Shabani
|
||||
* @license MIT
|
||||
* @link http://voodoophp.org/docs/handlebars
|
||||
*/
|
||||
|
||||
namespace Handlebars\Loader;
|
||||
use Handlebars\Loader;
|
||||
use Handlebars\HandlebarsString;
|
||||
|
||||
|
||||
class FilesystemLoader implements Loader
|
||||
{
|
||||
private $_baseDir;
|
||||
private $_extension = '.handlebars';
|
||||
private $_prefix = '';
|
||||
private $_templates = array();
|
||||
|
||||
/**
|
||||
* Handlebars filesystem Loader constructor.
|
||||
*
|
||||
* $options array allows overriding certain Loader options during instantiation:
|
||||
*
|
||||
* $options = array(
|
||||
* // extension used for Handlebars templates. Defaults to '.handlebars'
|
||||
* 'extension' => '.other',
|
||||
* );
|
||||
*
|
||||
* @param string|array $baseDirs A path contain template files or array of paths
|
||||
* @param array $options Array of Loader options (default: array())
|
||||
*
|
||||
* @throws \RuntimeException if $baseDir does not exist.
|
||||
*/
|
||||
public function __construct($baseDirs, Array $options = [])
|
||||
{
|
||||
if (is_string($baseDirs)) {
|
||||
$baseDirs = array(rtrim(realpath($baseDirs), '/'));
|
||||
} else {
|
||||
foreach ($baseDirs as &$dir) {
|
||||
$dir = rtrim(realpath($dir), '/');
|
||||
} unset( $dir );
|
||||
}
|
||||
|
||||
$this->_baseDir = $baseDirs;
|
||||
|
||||
foreach ($this->_baseDir as $dir) {
|
||||
if (!is_dir($dir)) {
|
||||
throw new \RuntimeException(
|
||||
'FilesystemLoader baseDir must be a directory: ' . $dir
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($options['extension'])) {
|
||||
$this->_extension = '.' . ltrim($options['extension'], '.');
|
||||
}
|
||||
|
||||
if (isset($options['prefix'])) {
|
||||
$this->_prefix = $options['prefix'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a Template by name.
|
||||
*
|
||||
* $loader = new FilesystemLoader(dirname(__FILE__).'/views');
|
||||
* // loads "./views/admin/dashboard.handlebars";
|
||||
* $loader->load('admin/dashboard');
|
||||
*
|
||||
* @param string $name template name
|
||||
*
|
||||
* @return HandlebarsString Handlebars Template source
|
||||
*/
|
||||
public function load($name)
|
||||
{
|
||||
if (!isset($this->_templates[$name])) {
|
||||
$this->_templates[$name] = $this->loadFile($name);
|
||||
}
|
||||
|
||||
return new HandlebarsString($this->_templates[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for loading a Handlebars file by name.
|
||||
*
|
||||
* @param string $name template name
|
||||
*
|
||||
* @throws \InvalidArgumentException if a template file is not found.
|
||||
* @return string Handlebars Template source
|
||||
*/
|
||||
protected function loadFile($name)
|
||||
{
|
||||
$fileName = $this->getFileName($name);
|
||||
|
||||
if ($fileName === false) {
|
||||
throw new \InvalidArgumentException('Template ' . $name . ' not found.');
|
||||
}
|
||||
|
||||
return file_get_contents($fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for getting a Handlebars template file name.
|
||||
*
|
||||
* @param string $name template name
|
||||
*
|
||||
* @return string Template file name
|
||||
*/
|
||||
protected function getFileName($name)
|
||||
{
|
||||
foreach ($this->_baseDir as $baseDir) {
|
||||
$fileName = $baseDir . '/';
|
||||
$fileParts = explode('/', $name);
|
||||
$file = array_pop($fileParts);
|
||||
|
||||
if (substr($file, strlen($this->_prefix)) !== $this->_prefix) {
|
||||
$file = $this->_prefix . $file;
|
||||
}
|
||||
|
||||
$fileParts[] = $file;
|
||||
$fileName .= implode('/', $fileParts);
|
||||
$lastCharacters = substr($fileName, 0 - strlen($this->_extension));
|
||||
|
||||
if ($lastCharacters !== $this->_extension) {
|
||||
$fileName .= $this->_extension;
|
||||
}
|
||||
if (file_exists($fileName)) {
|
||||
return $fileName;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
36
vendor/salesforce/handlebars-php/src/Handlebars/Loader/StringLoader.php
vendored
Executable file
36
vendor/salesforce/handlebars-php/src/Handlebars/Loader/StringLoader.php
vendored
Executable file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* Handlebars Template string Loader implementation.
|
||||
*
|
||||
* @category Xamin
|
||||
* @package Handlebars
|
||||
* @author fzerorubigd <fzerorubigd@gmail.com>
|
||||
* @author Behrooz Shabani <everplays@gmail.com>
|
||||
* @author Mardix <https://github.com/mardix>
|
||||
* @copyright 2012 (c) ParsPooyesh Co
|
||||
* @copyright 2013 (c) Behrooz Shabani
|
||||
* @copyright 2013 (c) Mardix
|
||||
* @license MIT
|
||||
* @link http://voodoophp.org/docs/handlebars
|
||||
*/
|
||||
|
||||
namespace Handlebars\Loader;
|
||||
use Handlebars\Loader;
|
||||
use Handlebars\HandlebarsString;
|
||||
|
||||
class StringLoader implements Loader
|
||||
{
|
||||
|
||||
/**
|
||||
* Load a Template by source.
|
||||
*
|
||||
* @param string $name Handlebars Template source
|
||||
*
|
||||
* @return HandlebarsString Handlebars Template source
|
||||
*/
|
||||
public function load($name)
|
||||
{
|
||||
return new HandlebarsString($name);
|
||||
}
|
||||
|
||||
}
|
||||
94
vendor/salesforce/handlebars-php/src/Handlebars/Parser.php
vendored
Executable file
94
vendor/salesforce/handlebars-php/src/Handlebars/Parser.php
vendored
Executable file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
/**
|
||||
* Handlebars parser (based on mustache)
|
||||
*
|
||||
* This class is responsible for turning raw template source into a set of
|
||||
* Handlebars tokens.
|
||||
*
|
||||
* @category Xamin
|
||||
* @package Handlebars
|
||||
* @author fzerorubigd <fzerorubigd@gmail.com>
|
||||
* @author Behrooz Shabani <everplays@gmail.com>
|
||||
* @author Mardix <https://github.com/mardix>
|
||||
* @copyright 2012 (c) ParsPooyesh Co
|
||||
* @copyright 2013 (c) Behrooz Shabani
|
||||
* @copyright 2013 (c) Mardix
|
||||
* @license MIT
|
||||
* @link http://voodoophp.org/docs/handlebars
|
||||
*/
|
||||
|
||||
namespace Handlebars;
|
||||
use ArrayIterator;
|
||||
use LogicException;
|
||||
|
||||
class Parser
|
||||
{
|
||||
/**
|
||||
* Process array of tokens and convert them into parse tree
|
||||
*
|
||||
* @param array $tokens Set of
|
||||
*
|
||||
* @return array Token parse tree
|
||||
*/
|
||||
public function parse(Array $tokens = [])
|
||||
{
|
||||
return $this->buildTree(new ArrayIterator($tokens));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for recursively building a parse tree.
|
||||
*
|
||||
* @param \ArrayIterator $tokens Stream of tokens
|
||||
*
|
||||
* @throws \LogicException when nesting errors or mismatched section tags
|
||||
* are encountered.
|
||||
* @return array Token parse tree
|
||||
*
|
||||
*/
|
||||
private function buildTree(ArrayIterator $tokens)
|
||||
{
|
||||
$stack = [];
|
||||
|
||||
do {
|
||||
$token = $tokens->current();
|
||||
$tokens->next();
|
||||
|
||||
if ($token === null) {
|
||||
continue;
|
||||
} else {
|
||||
switch ($token[Tokenizer::TYPE]) {
|
||||
case Tokenizer::T_END_SECTION:
|
||||
$newNodes = [];
|
||||
do {
|
||||
$result = array_pop($stack);
|
||||
if ($result === null) {
|
||||
throw new LogicException(
|
||||
'Unexpected closing tag: /' . $token[Tokenizer::NAME]
|
||||
);
|
||||
}
|
||||
|
||||
if (!array_key_exists(Tokenizer::NODES, $result)
|
||||
&& isset($result[Tokenizer::NAME])
|
||||
&& $result[Tokenizer::NAME] == $token[Tokenizer::NAME]
|
||||
) {
|
||||
$result[Tokenizer::NODES] = $newNodes;
|
||||
$result[Tokenizer::END] = $token[Tokenizer::INDEX];
|
||||
array_push($stack, $result);
|
||||
break 2;
|
||||
} else {
|
||||
array_unshift($newNodes, $result);
|
||||
}
|
||||
} while (true);
|
||||
break;
|
||||
default:
|
||||
array_push($stack, $token);
|
||||
}
|
||||
}
|
||||
|
||||
} while ($tokens->valid());
|
||||
|
||||
return $stack;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
386
vendor/salesforce/handlebars-php/src/Handlebars/Template.php
vendored
Executable file
386
vendor/salesforce/handlebars-php/src/Handlebars/Template.php
vendored
Executable file
@@ -0,0 +1,386 @@
|
||||
<?php
|
||||
/**
|
||||
* Handlebars base template
|
||||
* contain some utility method to get context and helpers
|
||||
*
|
||||
* @category Xamin
|
||||
* @package Handlebars
|
||||
* @author fzerorubigd <fzerorubigd@gmail.com>
|
||||
* @author Behrooz Shabani <everplays@gmail.com>
|
||||
* @author Mardix <https://github.com/mardix>
|
||||
* @copyright 2012 (c) ParsPooyesh Co
|
||||
* @copyright 2013 (c) Behrooz Shabani
|
||||
* @copyright 2013 (c) Mardix
|
||||
* @license MIT
|
||||
* @link http://voodoophp.org/docs/handlebars
|
||||
*/
|
||||
|
||||
namespace Handlebars;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
|
||||
class Template
|
||||
{
|
||||
/**
|
||||
* @var Handlebars
|
||||
*/
|
||||
protected $handlebars;
|
||||
|
||||
|
||||
protected $tree = [];
|
||||
|
||||
protected $source = '';
|
||||
|
||||
/**
|
||||
* @var array Run stack
|
||||
*/
|
||||
private $stack = [];
|
||||
private $_stack = [];
|
||||
|
||||
/**
|
||||
* Handlebars template constructor
|
||||
*
|
||||
* @param Handlebars $engine handlebar engine
|
||||
* @param array $tree Parsed tree
|
||||
* @param string $source Handlebars source
|
||||
*/
|
||||
public function __construct(Handlebars $engine, $tree, $source)
|
||||
{
|
||||
$this->handlebars = $engine;
|
||||
$this->tree = $tree;
|
||||
$this->source = $source;
|
||||
array_push($this->stack, [0, $this->getTree(), false]);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current tree
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTree()
|
||||
{
|
||||
return $this->tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current source
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSource()
|
||||
{
|
||||
return $this->source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current engine associated with this object
|
||||
*
|
||||
* @return Handlebars
|
||||
*/
|
||||
public function getEngine()
|
||||
{
|
||||
return $this->handlebars;
|
||||
}
|
||||
|
||||
/**
|
||||
* set stop token for render and discard method
|
||||
*
|
||||
* @param string $token token to set as stop token or false to remove
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
public function setStopToken($token)
|
||||
{
|
||||
$this->_stack = $this->stack;
|
||||
$topStack = array_pop($this->stack);
|
||||
$topStack[2] = $token;
|
||||
array_push($this->stack, $topStack);
|
||||
}
|
||||
|
||||
/**
|
||||
* get current stop token
|
||||
*
|
||||
* @return string|bool
|
||||
*/
|
||||
|
||||
public function getStopToken()
|
||||
{
|
||||
return end($this->stack)[2];
|
||||
}
|
||||
|
||||
/**
|
||||
* Render top tree
|
||||
*
|
||||
* @param mixed $context current context
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
* @return string
|
||||
*/
|
||||
public function render($context)
|
||||
{
|
||||
if (!$context instanceof Context) {
|
||||
$context = new Context($context, [
|
||||
'enableDataVariables' => $this->handlebars->isDataVariablesEnabled(),
|
||||
]);
|
||||
}
|
||||
$topTree = end($this->stack); // never pop a value from stack
|
||||
list($index, $tree, $stop) = $topTree;
|
||||
|
||||
$buffer = '';
|
||||
while (array_key_exists($index, $tree)) {
|
||||
$current = $tree[$index];
|
||||
$index++;
|
||||
//if the section is exactly like waitFor
|
||||
if (is_string($stop)
|
||||
&& $current[Tokenizer::TYPE] == Tokenizer::T_ESCAPED
|
||||
&& $current[Tokenizer::NAME] === $stop
|
||||
) {
|
||||
break;
|
||||
}
|
||||
switch ($current[Tokenizer::TYPE]) {
|
||||
case Tokenizer::T_SECTION :
|
||||
$newStack = isset($current[Tokenizer::NODES])
|
||||
? $current[Tokenizer::NODES] : [];
|
||||
array_push($this->stack, [0, $newStack, false]);
|
||||
$buffer .= $this->section($context, $current);
|
||||
array_pop($this->stack);
|
||||
break;
|
||||
case Tokenizer::T_INVERTED :
|
||||
$newStack = isset($current[Tokenizer::NODES]) ?
|
||||
$current[Tokenizer::NODES] : [];
|
||||
array_push($this->stack, [0, $newStack, false]);
|
||||
$buffer .= $this->inverted($context, $current);
|
||||
array_pop($this->stack);
|
||||
break;
|
||||
case Tokenizer::T_COMMENT :
|
||||
$buffer .= '';
|
||||
break;
|
||||
case Tokenizer::T_PARTIAL:
|
||||
case Tokenizer::T_PARTIAL_2:
|
||||
$buffer .= $this->partial($context, $current);
|
||||
break;
|
||||
case Tokenizer::T_UNESCAPED:
|
||||
case Tokenizer::T_UNESCAPED_2:
|
||||
$buffer .= $this->variables($context, $current, false);
|
||||
break;
|
||||
case Tokenizer::T_ESCAPED:
|
||||
$buffer .= $this->variables($context, $current, true);
|
||||
break;
|
||||
case Tokenizer::T_TEXT:
|
||||
$buffer .= $current[Tokenizer::VALUE];
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(
|
||||
'Invalid node type : ' . json_encode($current)
|
||||
);
|
||||
}
|
||||
}
|
||||
if ($stop) {
|
||||
//Ok break here, the helper should be aware of this.
|
||||
$newStack = array_pop($this->stack);
|
||||
$newStack[0] = $index;
|
||||
$newStack[2] = false; //No stop token from now on
|
||||
array_push($this->stack, $newStack);
|
||||
}
|
||||
|
||||
return $buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Discard top tree
|
||||
*
|
||||
* @param mixed $context current context
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function discard()
|
||||
{
|
||||
$topTree = end($this->stack); //This method never pop a value from stack
|
||||
list($index, $tree, $stop) = $topTree;
|
||||
while (array_key_exists($index, $tree)) {
|
||||
$current = $tree[$index];
|
||||
$index++;
|
||||
//if the section is exactly like waitFor
|
||||
if (is_string($stop)
|
||||
&& $current[Tokenizer::TYPE] == Tokenizer::T_ESCAPED
|
||||
&& $current[Tokenizer::NAME] === $stop
|
||||
) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($stop) {
|
||||
//Ok break here, the helper should be aware of this.
|
||||
$newStack = array_pop($this->stack);
|
||||
$newStack[0] = $index;
|
||||
$newStack[2] = false;
|
||||
array_push($this->stack, $newStack);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Process section nodes
|
||||
*
|
||||
* @param Context $context current context
|
||||
* @param array $current section node data
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
* @return string the result
|
||||
*/
|
||||
private function section(Context $context, $current)
|
||||
{
|
||||
$helpers = $this->handlebars->getHelpers();
|
||||
$sectionName = $current[Tokenizer::NAME];
|
||||
if ($helpers->has($sectionName)) {
|
||||
if (isset($current[Tokenizer::END])) {
|
||||
$source = substr(
|
||||
$this->getSource(),
|
||||
$current[Tokenizer::INDEX],
|
||||
$current[Tokenizer::END] - $current[Tokenizer::INDEX]
|
||||
);
|
||||
} else {
|
||||
$source = '';
|
||||
}
|
||||
$params = [
|
||||
$this, //First argument is this template
|
||||
$context, //Second is current context
|
||||
$current[Tokenizer::ARGS], //Arguments
|
||||
$source
|
||||
];
|
||||
|
||||
$return = call_user_func_array($helpers->$sectionName, $params);
|
||||
if ($return instanceof String) {
|
||||
return $this->handlebars->loadString($return)->render($context);
|
||||
} else {
|
||||
return $return;
|
||||
}
|
||||
} elseif (trim($current[Tokenizer::ARGS]) == '') {
|
||||
// fallback to mustache style each/with/for just if there is
|
||||
// no argument at all.
|
||||
try {
|
||||
$sectionVar = $context->get($sectionName, true);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
throw new RuntimeException(
|
||||
$sectionName . ' is not registered as a helper'
|
||||
);
|
||||
}
|
||||
$buffer = '';
|
||||
if (is_array($sectionVar) || $sectionVar instanceof \Traversable) {
|
||||
foreach ($sectionVar as $index => $d) {
|
||||
$context->pushIndex($index);
|
||||
$context->push($d);
|
||||
$buffer .= $this->render($context);
|
||||
$context->pop();
|
||||
$context->popIndex();
|
||||
}
|
||||
} elseif (is_object($sectionVar)) {
|
||||
//Act like with
|
||||
$context->push($sectionVar);
|
||||
$buffer = $this->render($context);
|
||||
$context->pop();
|
||||
} elseif ($sectionVar) {
|
||||
$buffer = $this->render($context);
|
||||
}
|
||||
|
||||
return $buffer;
|
||||
} else {
|
||||
throw new RuntimeException(
|
||||
$sectionName . ' is not registered as a helper'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process inverted section
|
||||
*
|
||||
* @param Context $context current context
|
||||
* @param array $current section node data
|
||||
*
|
||||
* @return string the result
|
||||
*/
|
||||
private function inverted(Context $context, $current)
|
||||
{
|
||||
$sectionName = $current[Tokenizer::NAME];
|
||||
$data = $context->get($sectionName);
|
||||
if (!$data) {
|
||||
return $this->render($context);
|
||||
} else {
|
||||
//No need to discard here, since it has no else
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process partial section
|
||||
*
|
||||
* @param Context $context current context
|
||||
* @param array $current section node data
|
||||
*
|
||||
* @return string the result
|
||||
*/
|
||||
private function partial(Context $context, $current)
|
||||
{
|
||||
$partial = $this->handlebars->loadPartial($current[Tokenizer::NAME]);
|
||||
|
||||
if ($current[Tokenizer::ARGS]) {
|
||||
$context = $context->get($current[Tokenizer::ARGS]);
|
||||
}
|
||||
|
||||
return $partial->render($context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process partial section
|
||||
*
|
||||
* @param Context $context current context
|
||||
* @param array $current section node data
|
||||
* @param boolean $escaped escape result or not
|
||||
*
|
||||
* @return string the result
|
||||
*/
|
||||
private function variables(Context $context, $current, $escaped)
|
||||
{
|
||||
$name = $current[Tokenizer::NAME];
|
||||
$value = $context->get($name);
|
||||
|
||||
// If @data variables are enabled, use the more complex algorithm for handling the the variables otherwise
|
||||
// use the previous version.
|
||||
if ($this->handlebars->isDataVariablesEnabled()) {
|
||||
if (substr(trim($name), 0, 1) == '@') {
|
||||
$variable = $context->getDataVariable($name);
|
||||
if (is_bool($variable)) {
|
||||
return $variable ? 'true' : 'false';
|
||||
}
|
||||
return $variable;
|
||||
}
|
||||
} else {
|
||||
// If @data variables are not enabled, then revert back to legacy behavior
|
||||
if ($name == '@index') {
|
||||
return $context->lastIndex();
|
||||
}
|
||||
if ($name == '@key') {
|
||||
return $context->lastKey();
|
||||
}
|
||||
}
|
||||
|
||||
if ($escaped) {
|
||||
$args = $this->handlebars->getEscapeArgs();
|
||||
array_unshift($args, $value);
|
||||
$value = call_user_func_array(
|
||||
$this->handlebars->getEscape(),
|
||||
array_values($args)
|
||||
);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function __clone()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
353
vendor/salesforce/handlebars-php/src/Handlebars/Tokenizer.php
vendored
Normal file
353
vendor/salesforce/handlebars-php/src/Handlebars/Tokenizer.php
vendored
Normal file
@@ -0,0 +1,353 @@
|
||||
<?php
|
||||
/**
|
||||
* Handlebars tokenizer (based on mustache)
|
||||
*
|
||||
* @category Xamin
|
||||
* @package Handlebars
|
||||
* @author Justin Hileman <dontknow@example.org>
|
||||
* @author fzerorubigd <fzerorubigd@gmail.com>
|
||||
* @author Behrooz Shabani <everplays@gmail.com>
|
||||
* @author Mardix <https://github.com/mardix>
|
||||
* @copyright 2012 (c) ParsPooyesh Co
|
||||
* @copyright 2013 (c) Behrooz Shabani
|
||||
* @copyright 2013 (c) Mardix
|
||||
* @license MIT
|
||||
* @link http://voodoophp.org/docs/handlebars
|
||||
*/
|
||||
|
||||
namespace Handlebars;
|
||||
|
||||
class Tokenizer
|
||||
{
|
||||
|
||||
// Finite state machine states
|
||||
const IN_TEXT = 0;
|
||||
const IN_TAG_TYPE = 1;
|
||||
const IN_TAG = 2;
|
||||
|
||||
// Token types
|
||||
const T_SECTION = '#';
|
||||
const T_INVERTED = '^';
|
||||
const T_END_SECTION = '/';
|
||||
const T_COMMENT = '!';
|
||||
// XXX: remove partials support from tokenizer and make it a helper?
|
||||
const T_PARTIAL = '>';
|
||||
const T_PARTIAL_2 = '<';
|
||||
const T_DELIM_CHANGE = '=';
|
||||
const T_ESCAPED = '_v';
|
||||
const T_UNESCAPED = '{';
|
||||
const T_UNESCAPED_2 = '&';
|
||||
const T_TEXT = '_t';
|
||||
|
||||
// Valid token types
|
||||
private $tagTypes = [
|
||||
self::T_SECTION => true,
|
||||
self::T_INVERTED => true,
|
||||
self::T_END_SECTION => true,
|
||||
self::T_COMMENT => true,
|
||||
self::T_PARTIAL => true,
|
||||
self::T_PARTIAL_2 => true,
|
||||
self::T_DELIM_CHANGE => true,
|
||||
self::T_ESCAPED => true,
|
||||
self::T_UNESCAPED => true,
|
||||
self::T_UNESCAPED_2 => true,
|
||||
];
|
||||
|
||||
// Interpolated tags
|
||||
private $interpolatedTags = [
|
||||
self::T_ESCAPED => true,
|
||||
self::T_UNESCAPED => true,
|
||||
self::T_UNESCAPED_2 => true,
|
||||
];
|
||||
|
||||
// Token properties
|
||||
const TYPE = 'type';
|
||||
const NAME = 'name';
|
||||
const OTAG = 'otag';
|
||||
const CTAG = 'ctag';
|
||||
const INDEX = 'index';
|
||||
const END = 'end';
|
||||
const INDENT = 'indent';
|
||||
const NODES = 'nodes';
|
||||
const VALUE = 'value';
|
||||
const ARGS = 'args';
|
||||
|
||||
protected $state;
|
||||
protected $tagType;
|
||||
protected $tag;
|
||||
protected $buffer;
|
||||
protected $tokens;
|
||||
protected $seenTag;
|
||||
protected $lineStart;
|
||||
protected $otag;
|
||||
protected $ctag;
|
||||
|
||||
/**
|
||||
* Scan and tokenize template source.
|
||||
*
|
||||
* @param string $text Mustache template source to tokenize
|
||||
* @param string $delimiters Optional, pass opening and closing delimiters
|
||||
*
|
||||
* @return array Set of Mustache tokens
|
||||
*/
|
||||
public function scan($text, $delimiters = null)
|
||||
{
|
||||
if ($text instanceof HandlebarsString) {
|
||||
$text = $text->getString();
|
||||
}
|
||||
|
||||
$this->reset();
|
||||
|
||||
if ($delimiters = trim($delimiters)) {
|
||||
list($otag, $ctag) = explode(' ', $delimiters);
|
||||
$this->otag = $otag;
|
||||
$this->ctag = $ctag;
|
||||
}
|
||||
|
||||
$openingTagLength = strlen($this->otag);
|
||||
$closingTagLength = strlen($this->ctag);
|
||||
$firstOpeningTagCharacter = $this->otag[0];
|
||||
$firstClosingTagCharacter = $this->ctag[0];
|
||||
|
||||
$len = strlen($text);
|
||||
|
||||
for ($i = 0; $i < $len; $i++) {
|
||||
|
||||
$character = $text[$i];
|
||||
|
||||
switch ($this->state) {
|
||||
|
||||
case self::IN_TEXT:
|
||||
if ($character === $firstOpeningTagCharacter && $this->tagChange($this->otag, $text, $i, $openingTagLength)
|
||||
) {
|
||||
$i--;
|
||||
$this->flushBuffer();
|
||||
$this->state = self::IN_TAG_TYPE;
|
||||
} else {
|
||||
if ($character == "\n") {
|
||||
$this->filterLine();
|
||||
} else {
|
||||
$this->buffer .= $character;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case self::IN_TAG_TYPE:
|
||||
|
||||
$i += $openingTagLength - 1;
|
||||
if (isset($this->tagTypes[$text[$i + 1]])) {
|
||||
$tag = $text[$i + 1];
|
||||
$this->tagType = $tag;
|
||||
} else {
|
||||
$tag = null;
|
||||
$this->tagType = self::T_ESCAPED;
|
||||
}
|
||||
|
||||
if ($this->tagType === self::T_DELIM_CHANGE) {
|
||||
$i = $this->changeDelimiters($text, $i);
|
||||
$openingTagLength = strlen($this->otag);
|
||||
$closingTagLength = strlen($this->ctag);
|
||||
$firstOpeningTagCharacter = $this->otag[0];
|
||||
$firstClosingTagCharacter = $this->ctag[0];
|
||||
|
||||
$this->state = self::IN_TEXT;
|
||||
} else {
|
||||
if ($tag !== null) {
|
||||
$i++;
|
||||
}
|
||||
$this->state = self::IN_TAG;
|
||||
}
|
||||
$this->seenTag = $i;
|
||||
break;
|
||||
|
||||
default:
|
||||
if ($character === $firstClosingTagCharacter && $this->tagChange($this->ctag, $text, $i, $closingTagLength)) {
|
||||
// Sections (Helpers) can accept parameters
|
||||
// Same thing for Partials (little known fact)
|
||||
if (in_array($this->tagType, [
|
||||
self::T_SECTION,
|
||||
self::T_PARTIAL,
|
||||
self::T_PARTIAL_2]
|
||||
)) {
|
||||
$newBuffer = explode(' ', trim($this->buffer), 2);
|
||||
$args = '';
|
||||
if (count($newBuffer) == 2) {
|
||||
$args = $newBuffer[1];
|
||||
}
|
||||
$this->buffer = $newBuffer[0];
|
||||
}
|
||||
$t = [
|
||||
self::TYPE => $this->tagType,
|
||||
self::NAME => trim($this->buffer),
|
||||
self::OTAG => $this->otag,
|
||||
self::CTAG => $this->ctag,
|
||||
self::INDEX => ($this->tagType == self::T_END_SECTION) ?
|
||||
$this->seenTag - $openingTagLength :
|
||||
$i + strlen($this->ctag),
|
||||
];
|
||||
if (isset($args)) {
|
||||
$t[self::ARGS] = $args;
|
||||
}
|
||||
$this->tokens[] = $t;
|
||||
unset($t);
|
||||
unset($args);
|
||||
$this->buffer = '';
|
||||
$i += strlen($this->ctag) - 1;
|
||||
$this->state = self::IN_TEXT;
|
||||
if ($this->tagType == self::T_UNESCAPED) {
|
||||
if ($this->ctag == '}}') {
|
||||
$i++;
|
||||
} else {
|
||||
// Clean up `{{{ tripleStache }}}` style tokens.
|
||||
$lastIndex = count($this->tokens) - 1;
|
||||
$lastName = $this->tokens[$lastIndex][self::NAME];
|
||||
if (substr($lastName, -1) === '}') {
|
||||
$this->tokens[$lastIndex][self::NAME] = trim(
|
||||
substr($lastName, 0, -1)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->buffer .= $character;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$this->filterLine(true);
|
||||
|
||||
return $this->tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to reset tokenizer internal state.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function reset()
|
||||
{
|
||||
$this->state = self::IN_TEXT;
|
||||
$this->tagType = null;
|
||||
$this->tag = null;
|
||||
$this->buffer = '';
|
||||
$this->tokens = [];
|
||||
$this->seenTag = false;
|
||||
$this->lineStart = 0;
|
||||
$this->otag = '{{';
|
||||
$this->ctag = '}}';
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush the current buffer to a token.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function flushBuffer()
|
||||
{
|
||||
if (!empty($this->buffer)) {
|
||||
$this->tokens[] = [
|
||||
self::TYPE => self::T_TEXT,
|
||||
self::VALUE => $this->buffer
|
||||
];
|
||||
$this->buffer = '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether the current line is entirely made up of whitespace.
|
||||
*
|
||||
* @return boolean True if the current line is all whitespace
|
||||
*/
|
||||
protected function lineIsWhitespace()
|
||||
{
|
||||
$tokensCount = count($this->tokens);
|
||||
for ($j = $this->lineStart; $j < $tokensCount; $j++) {
|
||||
$token = $this->tokens[$j];
|
||||
if (isset($this->tagTypes[$token[self::TYPE]])) {
|
||||
if (isset($this->interpolatedTags[$token[self::TYPE]])) {
|
||||
return false;
|
||||
}
|
||||
} elseif ($token[self::TYPE] == self::T_TEXT) {
|
||||
if (preg_match('/\S/', $token[self::VALUE])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter out whitespace-only lines and store indent levels for partials.
|
||||
*
|
||||
* @param bool $noNewLine Suppress the newline? (default: false)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function filterLine($noNewLine = false)
|
||||
{
|
||||
$this->flushBuffer();
|
||||
if ($this->seenTag && $this->lineIsWhitespace()) {
|
||||
$tokensCount = count($this->tokens);
|
||||
for ($j = $this->lineStart; $j < $tokensCount; $j++) {
|
||||
if ($this->tokens[$j][self::TYPE] == self::T_TEXT) {
|
||||
if (isset($this->tokens[$j + 1])
|
||||
&& $this->tokens[$j + 1][self::TYPE] == self::T_PARTIAL
|
||||
) {
|
||||
$this->tokens[$j + 1][self::INDENT]
|
||||
= $this->tokens[$j][self::VALUE];
|
||||
}
|
||||
|
||||
$this->tokens[$j] = null;
|
||||
}
|
||||
}
|
||||
} elseif (!$noNewLine) {
|
||||
$this->tokens[] = [self::TYPE => self::T_TEXT, self::VALUE => "\n"];
|
||||
}
|
||||
|
||||
$this->seenTag = false;
|
||||
$this->lineStart = count($this->tokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the current Mustache delimiters. Set new `otag` and `ctag` values.
|
||||
*
|
||||
* @param string $text Mustache template source
|
||||
* @param int $index Current tokenizer index
|
||||
*
|
||||
* @return int New index value
|
||||
*/
|
||||
protected function changeDelimiters($text, $index)
|
||||
{
|
||||
$startIndex = strpos($text, '=', $index) + 1;
|
||||
$close = '=' . $this->ctag;
|
||||
$closeIndex = strpos($text, $close, $index);
|
||||
|
||||
list($otag, $ctag) = explode(
|
||||
' ',
|
||||
trim(substr($text, $startIndex, $closeIndex - $startIndex))
|
||||
);
|
||||
$this->otag = $otag;
|
||||
$this->ctag = $ctag;
|
||||
|
||||
return $closeIndex + strlen($close) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether it's time to change tags.
|
||||
*
|
||||
* @param string $tag Current tag name
|
||||
* @param string $text Mustache template source
|
||||
* @param int $index Current tokenizer index
|
||||
* @param int $tagLength Length of the opening/closing tag string
|
||||
*
|
||||
* @return boolean True if this is a closing section tag
|
||||
*/
|
||||
protected function tagChange($tag, $text, $index, $tagLength)
|
||||
{
|
||||
return substr($text, $index, $tagLength) === $tag;
|
||||
}
|
||||
|
||||
}
|
||||
448
vendor/salesforce/handlebars-php/tests/Handlebars/HandlebarsTest.php
vendored
Normal file
448
vendor/salesforce/handlebars-php/tests/Handlebars/HandlebarsTest.php
vendored
Normal file
@@ -0,0 +1,448 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class AutoloaderTest
|
||||
*/
|
||||
class HandlebarsTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* Test handlebars autoloader
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testAutoLoad()
|
||||
{
|
||||
Handlebars\Autoloader::register(realpath(__DIR__ . '/../fixture/'));
|
||||
|
||||
$this->assertTrue(class_exists('Handlebars\\Test'));
|
||||
$this->assertTrue(class_exists('Handlebars\\Example\\Test'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test basic tags
|
||||
*
|
||||
* @param string $src handlebars source
|
||||
* @param array $data data
|
||||
* @param string $result expected data
|
||||
*
|
||||
* @dataProvider simpleTagdataProvider
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testBasicTags($src, $data, $result)
|
||||
{
|
||||
$loader = new \Handlebars\Loader\StringLoader();
|
||||
$engine = new \Handlebars\Handlebars(array('loader' => $loader));
|
||||
$this->assertEquals($result, $engine->render($src, $data));
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple tag provider
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function simpleTagdataProvider()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
'{{! This is comment}}',
|
||||
array(),
|
||||
''
|
||||
),
|
||||
array(
|
||||
'{{data}}',
|
||||
array('data' => 'result'),
|
||||
'result'
|
||||
),
|
||||
array(
|
||||
'{{data.key}}',
|
||||
array('data' => array('key' => 'result')),
|
||||
'result'
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test helpers (internal helpers)
|
||||
*
|
||||
* @param string $src handlebars source
|
||||
* @param array $data data
|
||||
* @param string $result expected data
|
||||
*
|
||||
* @dataProvider internalHelpersdataProvider
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSimpleHelpers($src, $data, $result)
|
||||
{
|
||||
$loader = new \Handlebars\Loader\StringLoader();
|
||||
$helpers = new \Handlebars\Helpers();
|
||||
$engine = new \Handlebars\Handlebars(array('loader' => $loader, 'helpers' => $helpers));
|
||||
|
||||
$this->assertEquals($result, $engine->render($src, $data));
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple helpers provider
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function internalHelpersdataProvider()
|
||||
{
|
||||
return [
|
||||
[
|
||||
'{{#if data}}Yes{{/if}}',
|
||||
['data' => true],
|
||||
'Yes'
|
||||
],
|
||||
[
|
||||
'{{#if data}}Yes{{/if}}',
|
||||
['data' => false],
|
||||
''
|
||||
],
|
||||
[
|
||||
'{{#unless data}}OK{{/unless}}',
|
||||
['data' => false],
|
||||
'OK'
|
||||
],
|
||||
[
|
||||
'{{#unless data}}OK {{else}}I believe{{/unless}}',
|
||||
['data' => true],
|
||||
'I believe'
|
||||
],
|
||||
[
|
||||
'{{#with data}}{{key}}{{/with}}',
|
||||
['data' => ['key' => 'result']],
|
||||
'result'
|
||||
],
|
||||
[
|
||||
'{{#each data}}{{this}}{{/each}}',
|
||||
['data' => [1, 2, 3, 4]],
|
||||
'1234'
|
||||
],
|
||||
[
|
||||
'{{#each data[0:2]}}{{this}}{{/each}}',
|
||||
['data' => [1, 2, 3, 4]],
|
||||
'12'
|
||||
],
|
||||
[
|
||||
'{{#each data[1:2]}}{{this}}{{/each}}',
|
||||
['data' => [1, 2, 3, 4]],
|
||||
'23'
|
||||
],
|
||||
[
|
||||
'{{#upper data}}',
|
||||
['data' => "hello"],
|
||||
'HELLO'
|
||||
],
|
||||
[
|
||||
'{{#lower data}}',
|
||||
['data' => "HELlO"],
|
||||
'hello'
|
||||
],
|
||||
[
|
||||
'{{#capitalize data}}',
|
||||
['data' => "hello"],
|
||||
'Hello'
|
||||
],
|
||||
[
|
||||
'{{#capitalize_words data}}',
|
||||
['data' => "hello world"],
|
||||
'Hello World'
|
||||
],
|
||||
[
|
||||
'{{#reverse data}}',
|
||||
['data' => "hello"],
|
||||
'olleh'
|
||||
],
|
||||
[
|
||||
"{{#inflect count 'album' 'albums' }}",
|
||||
["count" => 1],
|
||||
'album'
|
||||
],
|
||||
[
|
||||
"{{#inflect count 'album' 'albums' }}",
|
||||
["count" => 10],
|
||||
'albums'
|
||||
],
|
||||
[
|
||||
"{{#inflect count '%d album' '%d albums' }}",
|
||||
["count" => 1],
|
||||
'1 album'
|
||||
],
|
||||
[
|
||||
"{{#inflect count '%d album' '%d albums' }}",
|
||||
["count" => 10],
|
||||
'10 albums'
|
||||
],
|
||||
[
|
||||
"{{#default data 'OK' }}",
|
||||
["data" => "hello"],
|
||||
'hello'
|
||||
],
|
||||
[
|
||||
"{{#default data 'OK' }}",
|
||||
[],
|
||||
'OK'
|
||||
],
|
||||
[
|
||||
"{{#truncate data 8 '...'}}",
|
||||
["data" => "Hello World! How are you?"],
|
||||
'Hello Wo...'
|
||||
],
|
||||
[
|
||||
"{{#raw}}I'm raw {{data}}{{/raw}}",
|
||||
["data" => "raw to be included, but won't :)"],
|
||||
"I'm raw {{data}}"
|
||||
],
|
||||
[
|
||||
"{{#repeat 3}}Yes {{/repeat}}",
|
||||
[],
|
||||
"Yes Yes Yes "
|
||||
],
|
||||
[
|
||||
"{{#repeat 4}}Nice {{data}} {{/repeat}}",
|
||||
["data" => "Daddy!"],
|
||||
"Nice Daddy! Nice Daddy! Nice Daddy! Nice Daddy! "
|
||||
],
|
||||
[
|
||||
"{{#define test}}I'm Defined and Invoked{{/define}}{{#invoke test}}",
|
||||
[],
|
||||
"I'm Defined and Invoked"
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $src
|
||||
* @param array $data
|
||||
* @param string $result
|
||||
* @param bool $enableDataVariables
|
||||
* @dataProvider internalDataVariablesDataProvider
|
||||
*/
|
||||
public function testDataVariables($src, $data, $result, $enableDataVariables)
|
||||
{
|
||||
$loader = new \Handlebars\Loader\StringLoader();
|
||||
$helpers = new \Handlebars\Helpers();
|
||||
$engine = new \Handlebars\Handlebars(array(
|
||||
'loader' => $loader,
|
||||
'helpers' => $helpers,
|
||||
'enableDataVariables'=> $enableDataVariables,
|
||||
));
|
||||
|
||||
$this->assertEquals($result, $engine->render($src, $data));
|
||||
}
|
||||
|
||||
public function testDataVariables1()
|
||||
{
|
||||
$object = new stdClass;
|
||||
$object->{'@first'} = 'apple';
|
||||
$object->{'@last'} = 'banana';
|
||||
$object->{'@index'} = 'carrot';
|
||||
$object->{'@unknown'} = 'zucchini';
|
||||
$data = ['data' => [$object]];
|
||||
$engine = new \Handlebars\Handlebars(array(
|
||||
'loader' => new \Handlebars\Loader\StringLoader(),
|
||||
'helpers' => new \Handlebars\Helpers(),
|
||||
'enableDataVariables'=> false,
|
||||
));
|
||||
$template = "{{#each data}}{{@first}}, {{@last}}, {{@index}}, {{@unknown}}{{/each}}";
|
||||
|
||||
$this->assertEquals("", $engine->render($template, $data));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for data variables
|
||||
* @return array
|
||||
*/
|
||||
public function internalDataVariablesDataProvider()
|
||||
{
|
||||
// Build a standard set of objects to test against
|
||||
$keyPropertyName = '@key';
|
||||
$firstPropertyName = '@first';
|
||||
$lastPropertyName = '@last';
|
||||
$unknownPropertyName = '@unknown';
|
||||
$objects = [];
|
||||
foreach (['apple', 'banana', 'carrot', 'zucchini'] as $itemValue) {
|
||||
$object = new stdClass();
|
||||
$object->$keyPropertyName = $itemValue;
|
||||
$object->$firstPropertyName = $itemValue;
|
||||
$object->$lastPropertyName = $itemValue;
|
||||
$object->$unknownPropertyName = $itemValue;
|
||||
$objects[] = $object;
|
||||
}
|
||||
|
||||
// Build a list of scenarios. These will be used later to build fanned out scenarios that will be used against
|
||||
// the test. Each entry represents two different tests: (1) when enableDataVariables is enabled and (2) not enabled.
|
||||
$scenarios = [
|
||||
[
|
||||
'src' => '{{#each data}}{{@index}}{{/each}}',
|
||||
'data' => ['data' => ['apple', 'banana', 'carrot', 'zucchini']],
|
||||
// @index should work the same regardless of the feature flag
|
||||
'outputNotEnabled' => '0123',
|
||||
'outputEnabled' => '0123',
|
||||
],
|
||||
[
|
||||
'src' => '{{#each data}}{{@key}}{{/each}}',
|
||||
'data' => ['data' => ['apple', 'banana', 'carrot', 'zucchini']],
|
||||
'outputNotEnabled' => '',
|
||||
'outputEnabled' => '0123'
|
||||
],
|
||||
[
|
||||
'src' => '{{#each data}}{{#each this}}outer: {{@../key}},inner: {{@key}};{{/each}}{{/each}}',
|
||||
'data' => ['data' => [['apple', 'banana'], ['carrot', 'zucchini']]],
|
||||
'outputNotEnabled' => 'outer: ,inner: ;outer: ,inner: ;outer: ,inner: ;outer: ,inner: ;',
|
||||
'outputEnabled' => 'outer: 0,inner: 0;outer: 0,inner: 1;outer: 1,inner: 0;outer: 1,inner: 1;',
|
||||
],
|
||||
[
|
||||
'src' => '{{#each data}}{{#if @first}}true{{else}}false{{/if}}{{/each}}',
|
||||
'data' => ['data' => ['apple', 'banana', 'carrot', 'zucchini']],
|
||||
'outputNotEnabled' => 'falsefalsefalsefalse',
|
||||
'outputEnabled' => 'truefalsefalsefalse',
|
||||
],
|
||||
[
|
||||
'src' => '{{#each data}}{{@first}}{{/each}}',
|
||||
'data' => ['data' => ['apple', 'banana', 'carrot', 'zucchini']],
|
||||
'outputNotEnabled' => '',
|
||||
'outputEnabled' => 'truefalsefalsefalse',
|
||||
],
|
||||
[
|
||||
'src' => '{{#each data}}{{#each this}}outer: {{@../first}},inner: {{@first}};{{/each}}{{/each}}',
|
||||
'data' => ['data' => [['apple', 'banana'], ['carrot', 'zucchini']]],
|
||||
'outputNotEnabled' => 'outer: ,inner: ;outer: ,inner: ;outer: ,inner: ;outer: ,inner: ;',
|
||||
'outputEnabled' => 'outer: true,inner: true;outer: true,inner: false;outer: false,inner: true;outer: false,inner: false;',
|
||||
],
|
||||
[
|
||||
'src' => '{{#each data}}{{#if @last}}true{{else}}false{{/if}}{{/each}}',
|
||||
'data' => ['data' => ['apple', 'banana', 'carrot', 'zucchini']],
|
||||
'outputNotEnabled' => 'falsefalsefalsefalse',
|
||||
'outputEnabled' => 'falsefalsefalsetrue'
|
||||
],
|
||||
[
|
||||
'src' => '{{#each data}}{{@last}}{{/each}}',
|
||||
'data' => ['data' => ['apple', 'banana', 'carrot', 'zucchini']],
|
||||
'outputNotEnabled' => '',
|
||||
'outputEnabled' => 'falsefalsefalsetrue'
|
||||
],
|
||||
[
|
||||
'src' => '{{#each data}}{{#each this}}outer: {{@../last}},inner: {{@last}};{{/each}}{{/each}}',
|
||||
'data' => ['data' => [['apple', 'banana'], ['carrot', 'zucchini']]],
|
||||
'outputNotEnabled' => 'outer: ,inner: ;outer: ,inner: ;outer: ,inner: ;outer: ,inner: ;',
|
||||
'outputEnabled' => 'outer: false,inner: false;outer: false,inner: true;outer: true,inner: false;outer: true,inner: true;'
|
||||
],
|
||||
[
|
||||
// @index variables are ignored and the data variable is used
|
||||
'src' => '{{#each data}}{{@index}}{{/each}}',
|
||||
'data' => ['data' => [['@index' => 'apple'], ['@index' => 'banana'], ['@index' => 'carrot'], ['@index' => 'zucchini']]],
|
||||
'outputNotEnabled' => '0123',
|
||||
'outputEnabled' => '0123'
|
||||
],
|
||||
[
|
||||
// @key variables are ignored and the data variable is used
|
||||
'src' => '{{#each data}}{{@index}}{{/each}}',
|
||||
'data' => ['data' => $objects],
|
||||
'outputNotEnabled' => '0123',
|
||||
'outputEnabled' => '0123'
|
||||
],
|
||||
[
|
||||
// @first variables are used when data variables are not enabled.
|
||||
'src' => '{{#each data}}{{@first}}{{/each}}',
|
||||
'data' => ['data' => $objects],
|
||||
'outputNotEnabled' => 'applebananacarrotzucchini',
|
||||
'outputEnabled' => 'truefalsefalsefalse'
|
||||
],
|
||||
[
|
||||
// @last variables are used when data variables are not enabled.
|
||||
'src' => '{{#each data}}{{@last}}{{/each}}',
|
||||
'data' => ['data' => $objects],
|
||||
'outputNotEnabled' => 'applebananacarrotzucchini',
|
||||
'outputEnabled' => 'falsefalsefalsetrue'
|
||||
],
|
||||
[
|
||||
// @unknown variables are used when data variables are not enabled however since "unknown" is not a valid
|
||||
// value it should ignored.
|
||||
'src' => '{{#each data}}{{@unknown}}{{/each}}',
|
||||
'data' => ['data' => $objects],
|
||||
'outputNotEnabled' => 'applebananacarrotzucchini',
|
||||
'outputEnabled' => ''
|
||||
],
|
||||
];
|
||||
|
||||
// Build out a test case for when the enableDataVariables feature is enabled and when it's not
|
||||
$fannedOutScenarios = [];
|
||||
foreach ($scenarios as $scenario) {
|
||||
$fannedOutScenarios['not enabled: ' . $scenario['src']] = [
|
||||
$scenario['src'],
|
||||
$scenario['data'],
|
||||
$scenario['outputNotEnabled'],
|
||||
false,
|
||||
];
|
||||
$fannedOutScenarios['enabled: ' . $scenario['src']] = [
|
||||
$scenario['src'],
|
||||
$scenario['data'],
|
||||
$scenario['outputEnabled'],
|
||||
true,
|
||||
];
|
||||
}
|
||||
return $fannedOutScenarios;
|
||||
}
|
||||
|
||||
/**
|
||||
* Management helpers
|
||||
*/
|
||||
public function testHelpersManagement()
|
||||
{
|
||||
$helpers = new \Handlebars\Helpers(array('test' => function () {
|
||||
}), false);
|
||||
$engine = new \Handlebars\Handlebars(array('helpers' => $helpers));
|
||||
$this->assertTrue(is_callable($engine->getHelper('test')));
|
||||
$this->assertTrue($engine->hasHelper('test'));
|
||||
$engine->removeHelper('test');
|
||||
$this->assertFalse($engine->hasHelper('test'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom helper test
|
||||
*/
|
||||
public function testCustomHelper()
|
||||
{
|
||||
$loader = new \Handlebars\Loader\StringLoader();
|
||||
$engine = new \Handlebars\Handlebars(array('loader' => $loader));
|
||||
$engine->addHelper('test', function () {
|
||||
return 'Test helper is called';
|
||||
});
|
||||
$this->assertEquals('Test helper is called', $engine->render('{{#test}}', []));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $dir
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function delTree($dir)
|
||||
{
|
||||
$files = array_diff(scandir($dir), array('.', '..'));
|
||||
foreach ($files as $file) {
|
||||
(is_dir("$dir/$file")) ? delTree("$dir/$file") : unlink("$dir/$file");
|
||||
}
|
||||
|
||||
return rmdir($dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Its not a good test :) but ok
|
||||
*/
|
||||
public function testCacheSystem()
|
||||
{
|
||||
$path = sys_get_temp_dir() . '/__cache__handlebars';
|
||||
|
||||
@$this->delTree($path);
|
||||
|
||||
$dummy = new \Handlebars\Cache\Disk($path);
|
||||
$engine = new \Handlebars\Handlebars(array('cache' => $dummy));
|
||||
$this->assertEquals(0, count(glob($path . '/*')));
|
||||
$engine->render('test', array());
|
||||
$this->assertEquals(1, count(glob($path . '/*')));
|
||||
}
|
||||
}
|
||||
4
vendor/salesforce/handlebars-php/tests/bootstrap.php
vendored
Normal file
4
vendor/salesforce/handlebars-php/tests/bootstrap.php
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
include __DIR__ . "/../src/Handlebars/Autoloader.php";
|
||||
$base = __DIR__ . "/../src";
|
||||
$loader = \Handlebars\Autoloader::register();
|
||||
10
vendor/salesforce/handlebars-php/tests/fixture/Handlebars/Example/Test.php
vendored
Normal file
10
vendor/salesforce/handlebars-php/tests/fixture/Handlebars/Example/Test.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Handlebars\Example;
|
||||
/**
|
||||
* Class Handlebars_Example_Class
|
||||
*/
|
||||
class Test
|
||||
{
|
||||
|
||||
}
|
||||
11
vendor/salesforce/handlebars-php/tests/fixture/Handlebars/Test.php
vendored
Normal file
11
vendor/salesforce/handlebars-php/tests/fixture/Handlebars/Test.php
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace Handlebars;
|
||||
/**
|
||||
* Class Handlebars_Class
|
||||
*/
|
||||
|
||||
class Test
|
||||
{
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user