upload 28/5
This commit is contained in:
5
package/vendor/liquid/liquid/.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
5
package/vendor/liquid/liquid/.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
- [ ] I've run the tests with `vendor/bin/phpunit`
|
||||
- [ ] None of the tests were found failing
|
||||
- [ ] I've seen the coverage report at `build/coverage/index.html`
|
||||
- [ ] Not a single line left uncovered by tests
|
||||
- [ ] Any coding standards issues were fixed with `vendor/bin/php-cs-fixer fix`
|
||||
46
package/vendor/liquid/liquid/.github/workflows/cs.yaml
vendored
Normal file
46
package/vendor/liquid/liquid/.github/workflows/cs.yaml
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
name: Code Style
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-version: ['7.3']
|
||||
|
||||
name: PHP ${{ matrix.php-version }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-version }}
|
||||
extensions:
|
||||
coverage: pcov
|
||||
tools: composer:v1
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.cache/composer
|
||||
key: composer-${{ matrix.php-version }}-${{ hashFiles('**/composer.*') }}
|
||||
restore-keys: |
|
||||
composer-${{ matrix.php-version }}-
|
||||
composer-
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
composer update --prefer-dist --no-interaction --no-progress ${{ matrix.dependencies }}
|
||||
|
||||
- name: Check code style
|
||||
run: |
|
||||
php vendor/bin/php-cs-fixer --using-cache=no --diff --dry-run --stop-on-violation --verbose fix
|
||||
|
||||
48
package/vendor/liquid/liquid/.github/workflows/mt.yaml
vendored
Normal file
48
package/vendor/liquid/liquid/.github/workflows/mt.yaml
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
name: Mutation Testing
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-version: ['7.4']
|
||||
dependencies: ['']
|
||||
|
||||
name: PHP ${{ matrix.php-version }} ${{ matrix.dependencies }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-version }}
|
||||
extensions:
|
||||
coverage: pcov
|
||||
tools: composer:v2
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.cache/composer
|
||||
key: composer-${{ matrix.php-version }}-${{ hashFiles('**/composer.*') }}
|
||||
restore-keys: |
|
||||
composer-${{ matrix.php-version }}-
|
||||
composer-
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
composer update --prefer-dist --no-interaction --no-progress ${{ matrix.dependencies }}
|
||||
|
||||
- name: Run mutation testing
|
||||
run: |
|
||||
php vendor/bin/infection --min-msi=80 --min-covered-msi=80 --show-mutations --threads=$(nproc)
|
||||
|
||||
56
package/vendor/liquid/liquid/.github/workflows/tests.yaml
vendored
Normal file
56
package/vendor/liquid/liquid/.github/workflows/tests.yaml
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
# yamllint disable rule:line-length
|
||||
# yamllint disable rule:braces
|
||||
|
||||
name: CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- main
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-version: ['7.3', '7.4', '8.0', '8.1']
|
||||
include:
|
||||
- { php-version: '7.3', dependencies: '--prefer-lowest', legend: 'with lowest dependencies' }
|
||||
|
||||
name: PHP ${{ matrix.php-version }} ${{ matrix.legend }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-version }}
|
||||
coverage: pcov
|
||||
tools: composer:v2
|
||||
|
||||
- name: Get composer cache directory
|
||||
id: composer-cache
|
||||
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: composer-${{ runner.os }}-${{ matrix.php-version }}-${{ hashFiles('composer.*') }}-${{ matrix.composer-flags }}
|
||||
restore-keys: |
|
||||
composer-${{ runner.os }}-${{ matrix.php-version }}-${{ hashFiles('composer.*') }}-
|
||||
composer-${{ runner.os }}-${{ matrix.php-version }}-
|
||||
composer-${{ runner.os }}-
|
||||
composer-
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
composer update --prefer-dist --no-interaction --no-progress ${{ matrix.dependencies }}
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
php vendor/bin/phpunit
|
||||
3
package/vendor/liquid/liquid/.gitignore
vendored
Normal file
3
package/vendor/liquid/liquid/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
.idea/
|
||||
vendor/
|
||||
composer.lock
|
||||
42
package/vendor/liquid/liquid/.php_cs.dist
vendored
Normal file
42
package/vendor/liquid/liquid/.php_cs.dist
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
$header = <<<'EOF'
|
||||
This file is part of the Liquid package.
|
||||
|
||||
For the full copyright and license information, please view the LICENSE
|
||||
file that was distributed with this source code.
|
||||
|
||||
@package Liquid
|
||||
EOF;
|
||||
|
||||
return PhpCsFixer\Config::create()
|
||||
->setRiskyAllowed(true)
|
||||
->setRules([
|
||||
'@PSR2' => true,
|
||||
'psr4' => true,
|
||||
'no_unreachable_default_argument_value' => true,
|
||||
'no_useless_else' => true,
|
||||
'no_useless_return' => true,
|
||||
'phpdoc_add_missing_param_annotation' => true,
|
||||
'phpdoc_order' => true,
|
||||
'semicolon_after_instruction' => true,
|
||||
'whitespace_after_comma_in_array' => true,
|
||||
'header_comment' => ['header' => $header],
|
||||
'php_unit_construct' => true,
|
||||
'php_unit_dedicate_assert' => true,
|
||||
'php_unit_dedicate_assert_internal_type' => true,
|
||||
'php_unit_expectation' => true,
|
||||
'php_unit_mock_short_will_return' => true,
|
||||
'php_unit_mock' => true,
|
||||
'php_unit_namespaced' => true,
|
||||
'php_unit_no_expectation_annotation' => true,
|
||||
'php_unit_ordered_covers' => true,
|
||||
'php_unit_set_up_tear_down_visibility' => true,
|
||||
'php_unit_test_case_static_method_calls' => ['call_type' => 'this'],
|
||||
])
|
||||
->setIndent("\t")
|
||||
->setFinder(
|
||||
PhpCsFixer\Finder::create()
|
||||
->in(__DIR__)
|
||||
)
|
||||
;
|
||||
107
package/vendor/liquid/liquid/CHANGELOG.md
vendored
Normal file
107
package/vendor/liquid/liquid/CHANGELOG.md
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
## master
|
||||
|
||||
## 1.4.8 (2018-03-22)
|
||||
|
||||
* Now we return null for missing properties, like we do for missing keys for arrays.
|
||||
|
||||
## 1.4.7 (2018-02-09)
|
||||
|
||||
* Paginate tag shall now respect request parameters.
|
||||
* It is now possible to set a custom query param for the paginate tag.
|
||||
* Page number will now never go overboard.
|
||||
|
||||
## 1.4.6 (2018-02-07)
|
||||
|
||||
* TagPaginate shall not pollute the global scope, but work in own scope.
|
||||
* TagPaginate errors if no collection present instead of vague warning.
|
||||
|
||||
## 1.4.5 (2017-12-12)
|
||||
|
||||
* Capture tag shall save a variable in the global context.
|
||||
|
||||
## 1.4.4 (2017-11-03)
|
||||
|
||||
* TagUnless is an inverted TagIf: simplified implementation
|
||||
* Allow dashes in filenames
|
||||
|
||||
## 1.4.3 (2017-10-10)
|
||||
|
||||
* `escape` and `escape_once` filters now escape everything, but arrays
|
||||
* New standard filter for explicit string conversion
|
||||
|
||||
## 1.4.2 (2017-10-09)
|
||||
|
||||
* Better caching for non-extending templates
|
||||
* Simplified 'assign' tag to use rules for variables
|
||||
* Now supporting PHP 7.2
|
||||
* Different types of exception depending on the case
|
||||
* Filterbank will not call instance methods statically
|
||||
* Callback-type filters
|
||||
|
||||
## 1.4.1 (2017-09-28)
|
||||
|
||||
* Unquoted template names in 'include' tag, as in Jekyll
|
||||
* Caching now works correctly with 'extends' tag
|
||||
|
||||
## 1.4.0 (2017-09-25)
|
||||
|
||||
* Dropped support for EOL'ed versions of PHP (< 5.6)
|
||||
* Arrays won't be silently cast to string as 'Array' anymore
|
||||
* Complex objects could now be passed between templates and to filters
|
||||
* Additional test coverage
|
||||
|
||||
## 1.3.1 (2017-09-23)
|
||||
|
||||
* Support for numeric and variable array indicies
|
||||
* Support loop break and continue
|
||||
* Allow looping over extended ranges
|
||||
* Math filters now work with floats
|
||||
* Fixed 'default' filter
|
||||
* Local cache with data stored in a private variable
|
||||
* Virtual file system to get inversion of control and DI
|
||||
* Lots of tests with the coverage upped to 97%
|
||||
* Small bug fixes and various enhancements
|
||||
|
||||
## 1.3.0 (2017-07-17)
|
||||
|
||||
* Support Traversable loops and filters
|
||||
* Fix date filter for format with colon
|
||||
* Various minor improvements and bugs fixes
|
||||
|
||||
## 1.2.1 (2016-12-12)
|
||||
|
||||
* Remove content injection from $_GET.
|
||||
* Add PHP 5.6, 7.0, 7.1 to Travis file.
|
||||
|
||||
## 1.2 (2016-06-11)
|
||||
|
||||
* Added "ESCAPE_BY_DEFAULT" setting for context-aware auto-escaping.
|
||||
* Made "Context" work with plain objects.
|
||||
* "escape" now uses "htmlentities".
|
||||
* Fixed "escape_now".
|
||||
|
||||
## 1.1 (2015-06-01)
|
||||
|
||||
* New tags: "paginate", "unless", "ifchanged" were added
|
||||
* Added support for "for in (range)" syntax
|
||||
* Added support for multiple conditions in if statements
|
||||
* Added support for hashes/objects in for loops
|
||||
|
||||
## 1.0 (2014-09-07)
|
||||
|
||||
* Add namespaces
|
||||
* Add composer support
|
||||
* Implement new standard filters
|
||||
* Add 'raw' tag
|
||||
|
||||
## 0.9.2 (2012-08-15)
|
||||
|
||||
* context->set allows now global vars
|
||||
* Allow Templatenames with Fileextension
|
||||
* Tag 'extends' supports now multiple inheritance
|
||||
* Clean up code, change all variables and methods to camelCase
|
||||
|
||||
## 0.9.1 (2012-05-12)
|
||||
|
||||
* added the extends and block filter
|
||||
* Initial release
|
||||
22
package/vendor/liquid/liquid/LICENSE
vendored
Normal file
22
package/vendor/liquid/liquid/LICENSE
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
Copyright (c) 2014 Guz Alexander, http://guzalexander.com
|
||||
Copyright (c) 2011, 2012 Harald Hanek, http://www.delacap.com
|
||||
Copyright (c) 2006 Mateo Murphy
|
||||
|
||||
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.
|
||||
139
package/vendor/liquid/liquid/README.md
vendored
Normal file
139
package/vendor/liquid/liquid/README.md
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
# Liquid template engine for PHP [](https://github.com/kalimatas/php-liquid/actions/workflows/tests.yaml) [](https://coveralls.io/github/kalimatas/php-liquid?branch=master) [](https://packagist.org/packages/liquid/liquid)
|
||||
|
||||
Liquid is a PHP port of the [Liquid template engine for Ruby](https://github.com/Shopify/liquid), which was written by Tobias Lutke. Although there are many other templating engines for PHP, including Smarty (from which Liquid was partially inspired), Liquid had some advantages that made porting worthwhile:
|
||||
|
||||
* Readable and human friendly syntax, that is usable in any type of document, not just html, without need for escaping.
|
||||
* Quick and easy to use and maintain.
|
||||
* 100% secure, no possibility of embedding PHP code.
|
||||
* Clean OO design, rather than the mix of OO and procedural found in other templating engines.
|
||||
* Seperate compiling and rendering stages for improved performance.
|
||||
* Easy to extend with your own "tags and filters":https://github.com/harrydeluxe/php-liquid/wiki/Liquid-for-programmers.
|
||||
* 100% Markup compatibility with a Ruby templating engine, making templates usable for either.
|
||||
* Unit tested: Liquid is fully unit-tested. The library is stable and ready to be used in large projects.
|
||||
|
||||
## Why Liquid?
|
||||
|
||||
Why another templating library?
|
||||
|
||||
Liquid was written to meet three templating library requirements: good performance, easy to extend, and simply to use.
|
||||
|
||||
## Installing
|
||||
|
||||
You can install this lib via [composer](https://getcomposer.org/):
|
||||
|
||||
composer require liquid/liquid
|
||||
|
||||
## Example template
|
||||
|
||||
{% if products %}
|
||||
<ul id="products">
|
||||
{% for product in products %}
|
||||
<li>
|
||||
<h2>{{ product.name }}</h2>
|
||||
Only {{ product.price | price }}
|
||||
|
||||
{{ product.description | prettyprint | paragraph }}
|
||||
|
||||
{{ 'it rocks!' | paragraph }}
|
||||
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
## How to use Liquid
|
||||
|
||||
The main class is `Liquid::Template` class. There are two separate stages of working with Liquid templates: parsing and rendering. Here is a simple example:
|
||||
|
||||
use Liquid\Template;
|
||||
|
||||
$template = new Template();
|
||||
$template->parse("Hello, {{ name }}!");
|
||||
echo $template->render(array('name' => 'Alex'));
|
||||
|
||||
// Will echo
|
||||
// Hello, Alex!
|
||||
|
||||
To find more examples have a look at the `examples` directory or at the original Ruby implementation repository's [wiki page](https://github.com/Shopify/liquid/wiki).
|
||||
|
||||
## Advanced usage
|
||||
|
||||
You would probably want to add a caching layer (at very least a request-wide one), enable context-aware automatic escaping, and do load includes from disk with full file names.
|
||||
|
||||
use Liquid\Liquid;
|
||||
use Liquid\Template;
|
||||
use Liquid\Cache\Local;
|
||||
|
||||
Liquid::set('INCLUDE_SUFFIX', '');
|
||||
Liquid::set('INCLUDE_PREFIX', '');
|
||||
Liquid::set('INCLUDE_ALLOW_EXT', true);
|
||||
Liquid::set('ESCAPE_BY_DEFAULT', true);
|
||||
|
||||
$template = new Template(__DIR__.'/protected/templates/');
|
||||
|
||||
$template->parse("Hello, {% include 'honorific.html' %}{{ plain-html | raw }} {{ comment-with-xss }}");
|
||||
$template->setCache(new Local());
|
||||
|
||||
echo $template->render([
|
||||
'name' => 'Alex',
|
||||
'plain-html' => '<b>Your comment was:</b>',
|
||||
'comment-with-xss' => '<script>alert();</script>',
|
||||
]);
|
||||
|
||||
Will output:
|
||||
|
||||
Hello, Mx. Alex
|
||||
<b>Your comment was:</b> <script>alert();</script>
|
||||
|
||||
Note that automatic escaping is not a standard Liquid feature: use with care.
|
||||
|
||||
Similarly, the following snippet will parse and render `templates/home.liquid` while storing parsing results in a class-local cache:
|
||||
|
||||
\Liquid\Liquid::set('INCLUDE_PREFIX', '');
|
||||
|
||||
$template = new \Liquid\Template(__DIR__ . '/protected/templates');
|
||||
$template->setCache(new \Liquid\Cache\Local());
|
||||
echo $template->parseFile('home')->render();
|
||||
|
||||
If you render the same template over and over for at least a dozen of times, the class-local cache will give you a slight speed up in range of some milliseconds per render depending on a complexity of your template.
|
||||
|
||||
You should probably extend `Liquid\Template` to initialize everything you do with `Liquid::set` in one place.
|
||||
|
||||
### Custom filters
|
||||
|
||||
Adding filters has never been easier.
|
||||
|
||||
$template = new Template();
|
||||
$template->registerFilter('absolute_url', function ($arg) {
|
||||
return "https://www.example.com$arg";
|
||||
});
|
||||
$template->parse("{{ my_url | absolute_url }}");
|
||||
echo $template->render(array(
|
||||
'my_url' => '/test'
|
||||
));
|
||||
// expect: https://www.example.com/test
|
||||
|
||||
## Requirements
|
||||
|
||||
* PHP 7.0+
|
||||
|
||||
Some earlier versions could be used with PHP 5.3/5.4/5.5/5.6, though they're not supported anymore.
|
||||
|
||||
## Issues
|
||||
|
||||
Have a bug? Please create an issue here on GitHub!
|
||||
|
||||
[https://github.com/kalimatas/php-liquid/issues](https://github.com/kalimatas/php-liquid/issues)
|
||||
|
||||
## Fork notes
|
||||
|
||||
This fork is based on [php-liquid](https://github.com/harrydeluxe/php-liquid) by Harald Hanek.
|
||||
|
||||
It contains several improvements:
|
||||
|
||||
* namespaces
|
||||
* installing via composer
|
||||
* new standard filters
|
||||
* `raw` tag added
|
||||
|
||||
Any help is appreciated!
|
||||
58
package/vendor/liquid/liquid/composer.json
vendored
Normal file
58
package/vendor/liquid/liquid/composer.json
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"name": "liquid/liquid",
|
||||
"type": "library",
|
||||
"description": "Liquid template engine for PHP",
|
||||
"keywords": [
|
||||
"liquid",
|
||||
"template"
|
||||
],
|
||||
"homepage": "https://github.com/kalimatas/php-liquid",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Guz Alexander",
|
||||
"email": "kalimatas@gmail.com",
|
||||
"homepage": "http://guzalexander.com"
|
||||
},
|
||||
{
|
||||
"name": "Harald Hanek"
|
||||
},
|
||||
{
|
||||
"name": "Mateo Murphy"
|
||||
},
|
||||
{
|
||||
"name": "Alexey Kopytko",
|
||||
"email": "alexey@kopytko.com",
|
||||
"homepage": "https://www.alexeykopytko.com/"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.3 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ergebnis/composer-normalize": "^2.8",
|
||||
"friendsofphp/php-cs-fixer": "^2.16.4",
|
||||
"infection/infection": ">=0.17.6",
|
||||
"php-coveralls/php-coveralls": "^2.2",
|
||||
"phpunit/phpunit": "^9.2.6"
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true,
|
||||
"allow-plugins": true
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Liquid\\": "src/Liquid"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Liquid\\": "tests/Liquid"
|
||||
}
|
||||
}
|
||||
}
|
||||
32
package/vendor/liquid/liquid/examples/advanced.php
vendored
Normal file
32
package/vendor/liquid/liquid/examples/advanced.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
use Liquid\Liquid;
|
||||
use Liquid\Template;
|
||||
use Liquid\Cache\Local;
|
||||
|
||||
Liquid::set('INCLUDE_SUFFIX', '');
|
||||
Liquid::set('INCLUDE_PREFIX', '');
|
||||
Liquid::set('INCLUDE_ALLOW_EXT', true);
|
||||
Liquid::set('ESCAPE_BY_DEFAULT', true);
|
||||
|
||||
$template = new Template(__DIR__.'/protected/templates/');
|
||||
|
||||
$template->parse("Hello, {% include 'honorific.html' %}{{ plain-html | raw }} {{ comment-with-xss }}\n");
|
||||
$template->setCache(new Local());
|
||||
|
||||
echo $template->render([
|
||||
'name' => 'Alex',
|
||||
'plain-html' => '<b>Your comment was:</b>',
|
||||
'comment-with-xss' => '<script>alert();</script>',
|
||||
]);
|
||||
39
package/vendor/liquid/liquid/examples/block.php
vendored
Normal file
39
package/vendor/liquid/liquid/examples/block.php
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
use Liquid\Liquid;
|
||||
use Liquid\Template;
|
||||
|
||||
Liquid::set('INCLUDE_ALLOW_EXT', true);
|
||||
|
||||
$protectedPath = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'protected' . DIRECTORY_SEPARATOR;
|
||||
|
||||
$liquid = new Template($protectedPath . 'templates' . DIRECTORY_SEPARATOR);
|
||||
|
||||
// Uncomment the following lines to enable cache
|
||||
//$cache = array('cache' => 'file', 'cache_dir' => $protectedPath . 'cache' . DIRECTORY_SEPARATOR);
|
||||
// or if you have APC installed
|
||||
//$cache = array('cache' => 'apc');
|
||||
//$liquid->setCache($cache);
|
||||
|
||||
$liquid->parse(file_get_contents($protectedPath . 'templates' . DIRECTORY_SEPARATOR . 'child.tpl'));
|
||||
|
||||
$assigns = array(
|
||||
'document' => array(
|
||||
'title' => 'This is php-liquid',
|
||||
'content' => 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.',
|
||||
'copyright' => '© Copyright 2014 Guz Alexander - All rights reserved.',
|
||||
),
|
||||
);
|
||||
|
||||
echo $liquid->render($assigns);
|
||||
25
package/vendor/liquid/liquid/examples/filters.php
vendored
Normal file
25
package/vendor/liquid/liquid/examples/filters.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
use Liquid\Liquid;
|
||||
use Liquid\Template;
|
||||
|
||||
$template = new Template();
|
||||
$template->registerFilter('absolute_url', function ($arg) {
|
||||
return "https://www.example.com$arg";
|
||||
});
|
||||
$template->parse("{{ my_url | absolute_url }}");
|
||||
echo $template->render(array(
|
||||
'my_url' => '/test'
|
||||
));
|
||||
// expect: https://www.example.com/test
|
||||
70
package/vendor/liquid/liquid/examples/index.php
vendored
Normal file
70
package/vendor/liquid/liquid/examples/index.php
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
use Liquid\Liquid;
|
||||
use Liquid\Template;
|
||||
|
||||
Liquid::set('INCLUDE_SUFFIX', 'tpl');
|
||||
Liquid::set('INCLUDE_PREFIX', '');
|
||||
|
||||
$protectedPath = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'protected' . DIRECTORY_SEPARATOR;
|
||||
|
||||
$liquid = new Template($protectedPath . 'templates' . DIRECTORY_SEPARATOR);
|
||||
|
||||
// Uncomment the following lines to enable cache
|
||||
//$cache = array('cache' => 'file', 'cache_dir' => $protectedPath . 'cache' . DIRECTORY_SEPARATOR);
|
||||
// or if you have APC installed
|
||||
//$cache = array('cache' => 'apc');
|
||||
//$liquid->setCache($cache);
|
||||
|
||||
$liquid->parse(file_get_contents($protectedPath . 'templates' . DIRECTORY_SEPARATOR . 'index.tpl'));
|
||||
|
||||
$assigns = array(
|
||||
'document' => array(
|
||||
'title' => 'This is php-liquid',
|
||||
'content' => 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.',
|
||||
'copyright' => 'Guz Alexander - All rights reserved.',
|
||||
),
|
||||
'blog' => array(
|
||||
array(
|
||||
'title' => 'Blog Title 1',
|
||||
'content' => 'Nunc putamus parum claram',
|
||||
'tags' => array('claram', 'parum'),
|
||||
'comments' => array(
|
||||
array(
|
||||
'title' => 'First Comment',
|
||||
'message' => 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr',
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'title' => 'Blog Title 2',
|
||||
'content' => 'Nunc putamus parum claram',
|
||||
'tags' => array('claram', 'parum', 'freestyle'),
|
||||
'comments' => array(
|
||||
array(
|
||||
'title' => 'First Comment',
|
||||
'message' => 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr',
|
||||
),
|
||||
array(
|
||||
'title' => 'Second Comment',
|
||||
'message' => 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr',
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
),
|
||||
'array' => array('one', 'two', 'three', 'four'),
|
||||
);
|
||||
|
||||
echo $liquid->render($assigns);
|
||||
2
package/vendor/liquid/liquid/examples/protected/cache/.gitignore
vendored
Normal file
2
package/vendor/liquid/liquid/examples/protected/cache/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
!.gitignore
|
||||
liquid_*
|
||||
15
package/vendor/liquid/liquid/examples/protected/templates/base.tpl
vendored
Normal file
15
package/vendor/liquid/liquid/examples/protected/templates/base.tpl
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
{% comment %} This is the base template. {% endcomment %}
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
{% include 'header.tpl' %}
|
||||
</head>
|
||||
<body>
|
||||
<div id="content">{% block content %}{% endblock %}</div>
|
||||
<div id="footer">
|
||||
{% block footer %}
|
||||
© Copyright 2014 by <a href="http://guzalexander.com/">Guz Alexander</a>.
|
||||
{% endblock %}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
6
package/vendor/liquid/liquid/examples/protected/templates/blocks/child.tpl
vendored
Normal file
6
package/vendor/liquid/liquid/examples/protected/templates/blocks/child.tpl
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
{% comment %} This is the child template. {% endcomment %}
|
||||
{% extends "base.tpl" %}
|
||||
|
||||
{% block footer %}
|
||||
{{ document.copyright }}
|
||||
{% endblock %}
|
||||
7
package/vendor/liquid/liquid/examples/protected/templates/child.tpl
vendored
Normal file
7
package/vendor/liquid/liquid/examples/protected/templates/child.tpl
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{% comment %} This is the child template. {% endcomment %}
|
||||
{% extends "blocks/child.tpl" %}
|
||||
|
||||
{% block content %}
|
||||
<h2>Entry one</h2>
|
||||
<p>This is my first entry.</p>
|
||||
{% endblock %}
|
||||
3
package/vendor/liquid/liquid/examples/protected/templates/footer.tpl
vendored
Normal file
3
package/vendor/liquid/liquid/examples/protected/templates/footer.tpl
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<div id="footer">
|
||||
© {{ 'now' | date: "%Y" }} {% include 'subfooter' %}
|
||||
</div>
|
||||
2
package/vendor/liquid/liquid/examples/protected/templates/header.tpl
vendored
Normal file
2
package/vendor/liquid/liquid/examples/protected/templates/header.tpl
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>{{ document.title }}</title>
|
||||
1
package/vendor/liquid/liquid/examples/protected/templates/honorific.html
vendored
Normal file
1
package/vendor/liquid/liquid/examples/protected/templates/honorific.html
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Mx. {{ name }}
|
||||
44
package/vendor/liquid/liquid/examples/protected/templates/index.tpl
vendored
Normal file
44
package/vendor/liquid/liquid/examples/protected/templates/index.tpl
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
{% comment %}
|
||||
|
||||
This is a comment block
|
||||
(c) 2014 Guz Alexander
|
||||
|
||||
{% endcomment %}
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
{% include 'header' %}
|
||||
</head>
|
||||
<body>
|
||||
<h1>{{ document.title }}</h1>
|
||||
<p>{{ document.content }}</p>
|
||||
<p><a href="simple.php">Link to simple.php</a></p>
|
||||
{% if blog %}
|
||||
Total Blogentrys: {{ blog | size }}
|
||||
<ul id="products">
|
||||
{% for entry in blog %}
|
||||
<li>
|
||||
<h3>{{ entry.title | upcase }}</h3>
|
||||
<p>{{ entry.content }}</p>
|
||||
Comments: {{ entry.comments | size }}
|
||||
{% assign uzu = 'dudu2' %}
|
||||
{% assign freestyle = false %}
|
||||
|
||||
{% for t in entry.tags %}
|
||||
{% if t == 'freestyle' %}
|
||||
{% assign freestyle = true %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if freestyle %}
|
||||
<p>Blogentry has tag: freestyle</p>
|
||||
{% endif %}
|
||||
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
{% include 'footer' %}
|
||||
</body>
|
||||
</html>
|
||||
1
package/vendor/liquid/liquid/examples/protected/templates/subfooter.tpl
vendored
Normal file
1
package/vendor/liquid/liquid/examples/protected/templates/subfooter.tpl
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{{ document.copyright }}
|
||||
23
package/vendor/liquid/liquid/examples/simple.php
vendored
Normal file
23
package/vendor/liquid/liquid/examples/simple.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
use Liquid\Liquid;
|
||||
use Liquid\Template;
|
||||
|
||||
Liquid::set('INCLUDE_SUFFIX', 'tpl');
|
||||
Liquid::set('INCLUDE_PREFIX', '');
|
||||
|
||||
$liquid = new Template();
|
||||
$liquid->parse('{{ hello }} {{ goback }}');
|
||||
|
||||
echo $liquid->render(array('hello' => 'hello world', 'goback' => '<a href=".">index</a>'));
|
||||
8
package/vendor/liquid/liquid/infection.json.dist
vendored
Normal file
8
package/vendor/liquid/liquid/infection.json.dist
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"timeout": 2,
|
||||
"source": {
|
||||
"directories": [
|
||||
"src"
|
||||
]
|
||||
}
|
||||
}
|
||||
23
package/vendor/liquid/liquid/phpunit.xml.dist
vendored
Normal file
23
package/vendor/liquid/liquid/phpunit.xml.dist
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<phpunit bootstrap="vendor/autoload.php"
|
||||
colors="true"
|
||||
verbose="true"
|
||||
executionOrder="random"
|
||||
resolveDependencies="true"
|
||||
failOnRisky="true"
|
||||
failOnWarning="true"
|
||||
backupStaticAttributes="true"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="Main">
|
||||
<directory>tests/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory suffix=".php">src/</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
||||
264
package/vendor/liquid/liquid/src/Liquid/AbstractBlock.php
vendored
Normal file
264
package/vendor/liquid/liquid/src/Liquid/AbstractBlock.php
vendored
Normal file
@@ -0,0 +1,264 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid;
|
||||
|
||||
use Liquid\Exception\ParseException;
|
||||
use Liquid\Exception\RenderException;
|
||||
|
||||
/**
|
||||
* Base class for blocks.
|
||||
*/
|
||||
class AbstractBlock extends AbstractTag
|
||||
{
|
||||
const TAG_PREFIX = '\Liquid\Tag\Tag';
|
||||
|
||||
/**
|
||||
* @var AbstractTag[]|Variable[]|string[]
|
||||
*/
|
||||
protected $nodelist = array();
|
||||
|
||||
/**
|
||||
* Whenever next token should be ltrim'med.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected static $trimWhitespace = false;
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getNodelist()
|
||||
{
|
||||
return $this->nodelist;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given tokens
|
||||
*
|
||||
* @param array $tokens
|
||||
*
|
||||
* @throws \Liquid\LiquidException
|
||||
* @return void
|
||||
*/
|
||||
public function parse(array &$tokens)
|
||||
{
|
||||
$startRegexp = new Regexp('/^' . Liquid::get('TAG_START') . '/');
|
||||
$tagRegexp = new Regexp('/^' . Liquid::get('TAG_START') . Liquid::get('WHITESPACE_CONTROL') . '?\s*(\w+)\s*(.*?)' . Liquid::get('WHITESPACE_CONTROL') . '?' . Liquid::get('TAG_END') . '$/s');
|
||||
$variableStartRegexp = new Regexp('/^' . Liquid::get('VARIABLE_START') . '/');
|
||||
|
||||
$this->nodelist = array();
|
||||
|
||||
$tags = Template::getTags();
|
||||
|
||||
while (count($tokens)) {
|
||||
$token = array_shift($tokens);
|
||||
|
||||
if ($startRegexp->match($token)) {
|
||||
$this->whitespaceHandler($token);
|
||||
if ($tagRegexp->match($token)) {
|
||||
// If we found the proper block delimitor just end parsing here and let the outer block proceed
|
||||
if ($tagRegexp->matches[1] == $this->blockDelimiter()) {
|
||||
$this->endTag();
|
||||
return;
|
||||
}
|
||||
|
||||
$tagName = null;
|
||||
if (array_key_exists($tagRegexp->matches[1], $tags)) {
|
||||
$tagName = $tags[$tagRegexp->matches[1]];
|
||||
} else {
|
||||
$tagName = self::TAG_PREFIX . ucwords($tagRegexp->matches[1]);
|
||||
$tagName = (class_exists($tagName) === true) ? $tagName : null;
|
||||
}
|
||||
|
||||
if ($tagName !== null) {
|
||||
$this->nodelist[] = new $tagName($tagRegexp->matches[2], $tokens, $this->fileSystem);
|
||||
if ($tagRegexp->matches[1] == 'extends') {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
$this->unknownTag($tagRegexp->matches[1], $tagRegexp->matches[2], $tokens);
|
||||
}
|
||||
} else {
|
||||
throw new ParseException("Tag $token was not properly terminated (won't match $tagRegexp)");
|
||||
}
|
||||
} elseif ($variableStartRegexp->match($token)) {
|
||||
$this->whitespaceHandler($token);
|
||||
$this->nodelist[] = $this->createVariable($token);
|
||||
} else {
|
||||
// This is neither a tag or a variable, proceed with an ltrim
|
||||
if (self::$trimWhitespace) {
|
||||
$token = ltrim($token);
|
||||
}
|
||||
|
||||
self::$trimWhitespace = false;
|
||||
$this->nodelist[] = $token;
|
||||
}
|
||||
}
|
||||
|
||||
$this->assertMissingDelimitation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the whitespace.
|
||||
*
|
||||
* @param string $token
|
||||
*/
|
||||
protected function whitespaceHandler($token)
|
||||
{
|
||||
/*
|
||||
* This assumes that TAG_START is always '{%', and a whitespace control indicator
|
||||
* is exactly one character long, on a third position.
|
||||
*/
|
||||
if (mb_substr($token, 2, 1) === Liquid::get('WHITESPACE_CONTROL')) {
|
||||
$previousToken = end($this->nodelist);
|
||||
if (is_string($previousToken)) { // this can also be a tag or a variable
|
||||
$this->nodelist[key($this->nodelist)] = rtrim($previousToken);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This assumes that TAG_END is always '%}', and a whitespace control indicator
|
||||
* is exactly one character long, on a third position from the end.
|
||||
*/
|
||||
self::$trimWhitespace = mb_substr($token, -3, 1) === Liquid::get('WHITESPACE_CONTROL');
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the block.
|
||||
*
|
||||
* @param Context $context
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render(Context $context)
|
||||
{
|
||||
return $this->renderAll($this->nodelist, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders all the given nodelist's nodes
|
||||
*
|
||||
* @param array $list
|
||||
* @param Context $context
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function renderAll(array $list, Context $context)
|
||||
{
|
||||
$result = '';
|
||||
|
||||
foreach ($list as $token) {
|
||||
if (is_object($token) && method_exists($token, 'render')) {
|
||||
$value = $token->render($context);
|
||||
} else {
|
||||
$value = $token;
|
||||
}
|
||||
|
||||
if (is_array($value)) {
|
||||
$value = htmlspecialchars(print_r($value, true));
|
||||
}
|
||||
|
||||
$result .= $value;
|
||||
|
||||
if (isset($context->registers['break'])) {
|
||||
break;
|
||||
}
|
||||
if (isset($context->registers['continue'])) {
|
||||
break;
|
||||
}
|
||||
|
||||
$context->tick();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* An action to execute when the end tag is reached
|
||||
*/
|
||||
protected function endTag()
|
||||
{
|
||||
// Do nothing by default
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for unknown tags
|
||||
*
|
||||
* @param string $tag
|
||||
* @param string $params
|
||||
* @param array $tokens
|
||||
*
|
||||
* @throws \Liquid\Exception\ParseException
|
||||
*/
|
||||
protected function unknownTag($tag, $params, array $tokens)
|
||||
{
|
||||
switch ($tag) {
|
||||
case 'else':
|
||||
throw new ParseException($this->blockName() . " does not expect else tag");
|
||||
case 'end':
|
||||
throw new ParseException("'end' is not a valid delimiter for " . $this->blockName() . " tags. Use " . $this->blockDelimiter());
|
||||
default:
|
||||
throw new ParseException("Unknown tag $tag");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called at the end of parsing, and will throw an error unless
|
||||
* this method is subclassed, like it is for Document
|
||||
*
|
||||
* @throws \Liquid\Exception\ParseException
|
||||
* @return bool
|
||||
*/
|
||||
protected function assertMissingDelimitation()
|
||||
{
|
||||
throw new ParseException($this->blockName() . " tag was never closed");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string that delimits the end of the block
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function blockDelimiter()
|
||||
{
|
||||
return "end" . $this->blockName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the block
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function blockName()
|
||||
{
|
||||
$reflection = new \ReflectionClass($this);
|
||||
return str_replace('tag', '', strtolower($reflection->getShortName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a variable for the given token
|
||||
*
|
||||
* @param string $token
|
||||
*
|
||||
* @throws \Liquid\Exception\ParseException
|
||||
* @return Variable
|
||||
*/
|
||||
private function createVariable($token)
|
||||
{
|
||||
$variableRegexp = new Regexp('/^' . Liquid::get('VARIABLE_START') . Liquid::get('WHITESPACE_CONTROL') . '?(.*?)' . Liquid::get('WHITESPACE_CONTROL') . '?' . Liquid::get('VARIABLE_END') . '$/s');
|
||||
if ($variableRegexp->match($token)) {
|
||||
return new Variable($variableRegexp->matches[1]);
|
||||
}
|
||||
|
||||
throw new ParseException("Variable $token was not properly terminated");
|
||||
}
|
||||
}
|
||||
100
package/vendor/liquid/liquid/src/Liquid/AbstractTag.php
vendored
Normal file
100
package/vendor/liquid/liquid/src/Liquid/AbstractTag.php
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid;
|
||||
|
||||
/**
|
||||
* Base class for tags.
|
||||
*/
|
||||
abstract class AbstractTag
|
||||
{
|
||||
/**
|
||||
* The markup for the tag
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $markup;
|
||||
|
||||
/**
|
||||
* Filesystem object is used to load included template files
|
||||
*
|
||||
* @var FileSystem
|
||||
*/
|
||||
protected $fileSystem;
|
||||
|
||||
/**
|
||||
* Additional attributes
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $attributes = array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $markup
|
||||
* @param array $tokens
|
||||
* @param FileSystem $fileSystem
|
||||
*/
|
||||
public function __construct($markup, array &$tokens, FileSystem $fileSystem = null)
|
||||
{
|
||||
$this->markup = $markup;
|
||||
$this->fileSystem = $fileSystem;
|
||||
$this->parse($tokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given tokens.
|
||||
*
|
||||
* @param array $tokens
|
||||
*/
|
||||
public function parse(array &$tokens)
|
||||
{
|
||||
// Do nothing by default
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the tag with the given context.
|
||||
*
|
||||
* @param Context $context
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function render(Context $context);
|
||||
|
||||
/**
|
||||
* Extracts tag attributes from a markup string.
|
||||
*
|
||||
* @param string $markup
|
||||
*/
|
||||
protected function extractAttributes($markup)
|
||||
{
|
||||
$this->attributes = array();
|
||||
|
||||
$attributeRegexp = new Regexp(Liquid::get('TAG_ATTRIBUTES'));
|
||||
|
||||
$matches = $attributeRegexp->scan($markup);
|
||||
|
||||
foreach ($matches as $match) {
|
||||
$this->attributes[$match[0]] = $match[1];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the tag.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function name()
|
||||
{
|
||||
return strtolower(get_class($this));
|
||||
}
|
||||
}
|
||||
78
package/vendor/liquid/liquid/src/Liquid/Cache.php
vendored
Normal file
78
package/vendor/liquid/liquid/src/Liquid/Cache.php
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid;
|
||||
|
||||
/**
|
||||
* Base class for Cache.
|
||||
*/
|
||||
abstract class Cache
|
||||
{
|
||||
/** @var int */
|
||||
protected $expire = 3600;
|
||||
/** @var string */
|
||||
protected $prefix = 'liquid_';
|
||||
/** @var string */
|
||||
protected $path;
|
||||
|
||||
/**
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct(array $options = array())
|
||||
{
|
||||
if (isset($options['cache_expire'])) {
|
||||
$this->expire = $options['cache_expire'];
|
||||
}
|
||||
|
||||
if (isset($options['cache_prefix'])) {
|
||||
$this->prefix = $options['cache_prefix'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a value from cache with a specified key.
|
||||
*
|
||||
* @param string $key a unique key identifying the cached value
|
||||
* @param bool $unserialize
|
||||
*
|
||||
* @return mixed|boolean the value stored in cache, false if the value is not in the cache or expired.
|
||||
*/
|
||||
abstract public function read($key, $unserialize = true);
|
||||
|
||||
/**
|
||||
* Check if specified key exists in cache.
|
||||
*
|
||||
* @param string $key a unique key identifying the cached value
|
||||
*
|
||||
* @return boolean true if the key is in cache, false otherwise
|
||||
*/
|
||||
abstract public function exists($key);
|
||||
|
||||
/**
|
||||
* Stores a value identified by a key in cache.
|
||||
*
|
||||
* @param string $key the key identifying the value to be cached
|
||||
* @param mixed $value the value to be cached
|
||||
* @param bool $serialize
|
||||
*
|
||||
* @return boolean true if the value is successfully stored into cache, false otherwise
|
||||
*/
|
||||
abstract public function write($key, $value, $serialize = true);
|
||||
|
||||
/**
|
||||
* Deletes all values from cache.
|
||||
*
|
||||
* @param bool $expiredOnly
|
||||
*
|
||||
* @return boolean whether the flush operation was successful.
|
||||
*/
|
||||
abstract public function flush($expiredOnly = false);
|
||||
}
|
||||
74
package/vendor/liquid/liquid/src/Liquid/Cache/Apc.php
vendored
Normal file
74
package/vendor/liquid/liquid/src/Liquid/Cache/Apc.php
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Cache;
|
||||
|
||||
use Liquid\Cache;
|
||||
use Liquid\LiquidException;
|
||||
|
||||
/**
|
||||
* Implements cache stored in Apc.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class Apc extends Cache
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* It checks the availability of apccache.
|
||||
*
|
||||
* @param array $options
|
||||
*
|
||||
* @throws LiquidException if APC cache extension is not loaded or is disabled.
|
||||
*/
|
||||
public function __construct(array $options = array())
|
||||
{
|
||||
parent::__construct($options);
|
||||
|
||||
if (!function_exists('apc_fetch')) {
|
||||
throw new LiquidException(get_class($this).' requires PHP apc extension or similar to be loaded.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function read($key, $unserialize = true)
|
||||
{
|
||||
return apc_fetch($this->prefix . $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function exists($key)
|
||||
{
|
||||
apc_fetch($this->prefix . $key, $success);
|
||||
return (bool) $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function write($key, $value, $serialize = true)
|
||||
{
|
||||
return apc_store($this->prefix . $key, $value, $this->expire);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function flush($expiredOnly = false)
|
||||
{
|
||||
return apc_clear_cache('user');
|
||||
}
|
||||
}
|
||||
106
package/vendor/liquid/liquid/src/Liquid/Cache/File.php
vendored
Normal file
106
package/vendor/liquid/liquid/src/Liquid/Cache/File.php
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Cache;
|
||||
|
||||
use Liquid\Cache;
|
||||
use Liquid\Exception\NotFoundException;
|
||||
|
||||
/**
|
||||
* Implements cache stored in files.
|
||||
*/
|
||||
class File extends Cache
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* It checks the availability of cache directory.
|
||||
*
|
||||
* @param array $options
|
||||
*
|
||||
* @throws NotFoundException if Cachedir not exists.
|
||||
*/
|
||||
public function __construct(array $options = array())
|
||||
{
|
||||
parent::__construct($options);
|
||||
|
||||
if (isset($options['cache_dir']) && is_writable($options['cache_dir'])) {
|
||||
$this->path = realpath($options['cache_dir']) . DIRECTORY_SEPARATOR;
|
||||
} else {
|
||||
throw new NotFoundException('Cachedir not exists or not writable');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function read($key, $unserialize = true)
|
||||
{
|
||||
if (!$this->exists($key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($unserialize) {
|
||||
return unserialize(file_get_contents($this->path . $this->prefix . $key));
|
||||
}
|
||||
|
||||
return file_get_contents($this->path . $this->prefix . $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function exists($key)
|
||||
{
|
||||
$cacheFile = $this->path . $this->prefix . $key;
|
||||
|
||||
if (!file_exists($cacheFile) || filemtime($cacheFile) + $this->expire < time()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function write($key, $value, $serialize = true)
|
||||
{
|
||||
$bytes = file_put_contents($this->path . $this->prefix . $key, $serialize ? serialize($value) : $value);
|
||||
$this->gc();
|
||||
|
||||
return $bytes !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function flush($expiredOnly = false)
|
||||
{
|
||||
foreach (glob($this->path . $this->prefix . '*') as $file) {
|
||||
if ($expiredOnly) {
|
||||
if (filemtime($file) + $this->expire < time()) {
|
||||
unlink($file);
|
||||
}
|
||||
} else {
|
||||
unlink($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function gc()
|
||||
{
|
||||
$this->flush(true);
|
||||
}
|
||||
}
|
||||
60
package/vendor/liquid/liquid/src/Liquid/Cache/Local.php
vendored
Normal file
60
package/vendor/liquid/liquid/src/Liquid/Cache/Local.php
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Cache;
|
||||
|
||||
use Liquid\Cache;
|
||||
|
||||
/**
|
||||
* Implements cache with data stored in an embedded variable with no handling of expiration dates for simplicity
|
||||
*/
|
||||
class Local extends Cache
|
||||
{
|
||||
private $cache = array();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function read($key, $unserialize = true)
|
||||
{
|
||||
if (isset($this->cache[$key])) {
|
||||
return $this->cache[$key];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function exists($key)
|
||||
{
|
||||
return isset($this->cache[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function write($key, $value, $serialize = true)
|
||||
{
|
||||
$this->cache[$key] = $value;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function flush($expiredOnly = false)
|
||||
{
|
||||
$this->cache = array();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
458
package/vendor/liquid/liquid/src/Liquid/Context.php
vendored
Normal file
458
package/vendor/liquid/liquid/src/Liquid/Context.php
vendored
Normal file
@@ -0,0 +1,458 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid;
|
||||
|
||||
/**
|
||||
* Context keeps the variable stack and resolves variables, as well as keywords.
|
||||
*/
|
||||
class Context
|
||||
{
|
||||
/**
|
||||
* Local scopes
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $assigns;
|
||||
|
||||
/**
|
||||
* Registers for non-variable state data
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $registers;
|
||||
|
||||
/**
|
||||
* The filterbank holds all the filters
|
||||
*
|
||||
* @var Filterbank
|
||||
*/
|
||||
protected $filterbank;
|
||||
|
||||
/**
|
||||
* Global scopes
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $environments = array();
|
||||
|
||||
/**
|
||||
* Called "sometimes" while rendering. For example to abort the execution of a rendering.
|
||||
*
|
||||
* @var null|callable
|
||||
*/
|
||||
private $tickFunction = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $assigns
|
||||
* @param array $registers
|
||||
*/
|
||||
public function __construct(array $assigns = array(), array $registers = array())
|
||||
{
|
||||
$this->assigns = array($assigns);
|
||||
$this->registers = $registers;
|
||||
$this->filterbank = new Filterbank($this);
|
||||
|
||||
// first empty array serves as source for overrides, e.g. as in TagDecrement
|
||||
$this->environments = array(array(), array());
|
||||
|
||||
if (Liquid::get('EXPOSE_SERVER')) {
|
||||
$this->environments[1] = $_SERVER;
|
||||
} else {
|
||||
$this->environments[1] = array_filter(
|
||||
$_SERVER,
|
||||
function ($key) {
|
||||
return in_array(
|
||||
$key,
|
||||
(array)Liquid::get('SERVER_SUPERGLOBAL_WHITELIST')
|
||||
);
|
||||
},
|
||||
ARRAY_FILTER_USE_KEY
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a tick function, this function is called sometimes while liquid is rendering a template.
|
||||
*
|
||||
* @param callable $tickFunction
|
||||
*/
|
||||
public function setTickFunction(callable $tickFunction)
|
||||
{
|
||||
$this->tickFunction = $tickFunction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a filter to the context
|
||||
*
|
||||
* @param mixed $filter
|
||||
*/
|
||||
public function addFilters($filter, callable $callback = null)
|
||||
{
|
||||
$this->filterbank->addFilter($filter, $callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke the filter that matches given name
|
||||
*
|
||||
* @param string $name The name of the filter
|
||||
* @param mixed $value The value to filter
|
||||
* @param array $args Additional arguments for the filter
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function invoke($name, $value, array $args = array())
|
||||
{
|
||||
try {
|
||||
return $this->filterbank->invoke($name, $value, $args);
|
||||
} catch (\TypeError $typeError) {
|
||||
throw new LiquidException($typeError->getMessage(), 0, $typeError);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges the given assigns into the current assigns
|
||||
*
|
||||
* @param array $newAssigns
|
||||
*/
|
||||
public function merge($newAssigns)
|
||||
{
|
||||
$this->assigns[0] = array_merge($this->assigns[0], $newAssigns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Push new local scope on the stack.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function push()
|
||||
{
|
||||
array_unshift($this->assigns, array());
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pops the current scope from the stack.
|
||||
*
|
||||
* @throws LiquidException
|
||||
* @return bool
|
||||
*/
|
||||
public function pop()
|
||||
{
|
||||
if (count($this->assigns) == 1) {
|
||||
throw new LiquidException('No elements to pop');
|
||||
}
|
||||
|
||||
array_shift($this->assigns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces []
|
||||
*
|
||||
* @param string
|
||||
* @param mixed $key
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($key)
|
||||
{
|
||||
return $this->resolve($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces []=
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param bool $global
|
||||
*/
|
||||
public function set($key, $value, $global = false)
|
||||
{
|
||||
if ($global) {
|
||||
for ($i = 0; $i < count($this->assigns); $i++) {
|
||||
$this->assigns[$i][$key] = $value;
|
||||
}
|
||||
} else {
|
||||
$this->assigns[0][$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given key will properly resolve
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasKey($key)
|
||||
{
|
||||
return (!is_null($this->resolve($key)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a key by either returning the appropriate literal or by looking up the appropriate variable
|
||||
*
|
||||
* Test for empty has been moved to interpret condition, in Decision
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @throws LiquidException
|
||||
* @return mixed
|
||||
*/
|
||||
private function resolve($key)
|
||||
{
|
||||
// This shouldn't happen
|
||||
if (is_array($key)) {
|
||||
throw new LiquidException("Cannot resolve arrays as key");
|
||||
}
|
||||
|
||||
if (is_null($key) || $key == 'null') {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($key == 'true') {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($key == 'false') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (preg_match('/^\'(.*)\'$/', $key, $matches)) {
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
if (preg_match('/^"(.*)"$/', $key, $matches)) {
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
if (preg_match('/^(-?\d+)$/', $key, $matches)) {
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
if (preg_match('/^(-?\d[\d\.]+)$/', $key, $matches)) {
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
return $this->variable($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the current key in all the scopes
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function fetch($key)
|
||||
{
|
||||
// TagDecrement depends on environments being checked before assigns
|
||||
foreach ($this->environments as $environment) {
|
||||
if (array_key_exists($key, $environment)) {
|
||||
return $environment[$key];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->assigns as $scope) {
|
||||
if (array_key_exists($key, $scope)) {
|
||||
$obj = $scope[$key];
|
||||
|
||||
if ($obj instanceof Drop) {
|
||||
$obj->setContext($this);
|
||||
}
|
||||
|
||||
return $obj;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolved the namespaced queries gracefully.
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @see Decision::stringValue
|
||||
* @see AbstractBlock::renderAll
|
||||
*
|
||||
* @throws LiquidException
|
||||
* @return mixed
|
||||
*/
|
||||
private function variable($key)
|
||||
{
|
||||
// Support numeric and variable array indicies
|
||||
if (preg_match("|\[[0-9]+\]|", $key)) {
|
||||
$key = preg_replace("|\[([0-9]+)\]|", ".$1", $key);
|
||||
} elseif (preg_match("|\[[0-9a-z._]+\]|", $key, $matches)) {
|
||||
$index = $this->get(str_replace(array("[", "]"), "", $matches[0]));
|
||||
if (strlen($index)) {
|
||||
$key = preg_replace("|\[([0-9a-z._]+)\]|", ".$index", $key);
|
||||
}
|
||||
}
|
||||
|
||||
$parts = explode(Liquid::get('VARIABLE_ATTRIBUTE_SEPARATOR'), $key);
|
||||
|
||||
$object = $this->fetch(array_shift($parts));
|
||||
|
||||
while (count($parts) > 0) {
|
||||
// since we still have a part to consider
|
||||
// and since we can't dig deeper into plain values
|
||||
// it can be thought as if it has a property with a null value
|
||||
if (!is_object($object) && !is_array($object) && !is_string($object)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// first try to cast an object to an array or value
|
||||
if (is_object($object)) {
|
||||
if (method_exists($object, 'toLiquid')) {
|
||||
$object = $object->toLiquid();
|
||||
} elseif (method_exists($object, 'toArray')) {
|
||||
$object = $object->toArray();
|
||||
}
|
||||
}
|
||||
|
||||
if (is_null($object)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($object instanceof Drop) {
|
||||
$object->setContext($this);
|
||||
}
|
||||
|
||||
$nextPartName = array_shift($parts);
|
||||
|
||||
if (is_string($object)) {
|
||||
if ($nextPartName == 'size') {
|
||||
// if the last part of the context variable is .size we return the string length
|
||||
return mb_strlen($object);
|
||||
}
|
||||
|
||||
// no other special properties for strings, yet
|
||||
return null;
|
||||
}
|
||||
|
||||
if (is_array($object)) {
|
||||
// if the last part of the context variable is .first we return the first array element
|
||||
if ($nextPartName == 'first' && count($parts) == 0 && !array_key_exists('first', $object)) {
|
||||
return StandardFilters::first($object);
|
||||
}
|
||||
|
||||
// if the last part of the context variable is .last we return the last array element
|
||||
if ($nextPartName == 'last' && count($parts) == 0 && !array_key_exists('last', $object)) {
|
||||
return StandardFilters::last($object);
|
||||
}
|
||||
|
||||
// if the last part of the context variable is .size we just return the count
|
||||
if ($nextPartName == 'size' && count($parts) == 0 && !array_key_exists('size', $object)) {
|
||||
return count($object);
|
||||
}
|
||||
|
||||
// no key - no value
|
||||
if (!array_key_exists($nextPartName, $object)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$object = $object[$nextPartName];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!is_object($object)) {
|
||||
// we got plain value, yet asked to resolve a part
|
||||
// think plain values have a null part with any name
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($object instanceof \Countable) {
|
||||
// if the last part of the context variable is .size we just return the count
|
||||
if ($nextPartName == 'size' && count($parts) == 0) {
|
||||
return count($object);
|
||||
}
|
||||
}
|
||||
|
||||
if ($object instanceof Drop) {
|
||||
// if the object is a drop, make sure it supports the given method
|
||||
if (!$object->hasKey($nextPartName)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$object = $object->invokeDrop($nextPartName);
|
||||
continue;
|
||||
}
|
||||
|
||||
// if it has `get` or `field_exists` methods
|
||||
if (method_exists($object, Liquid::get('HAS_PROPERTY_METHOD'))) {
|
||||
if (!call_user_func(array($object, Liquid::get('HAS_PROPERTY_METHOD')), $nextPartName)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$object = call_user_func(array($object, Liquid::get('GET_PROPERTY_METHOD')), $nextPartName);
|
||||
continue;
|
||||
}
|
||||
|
||||
// if it's just a regular object, attempt to access a public method
|
||||
if (is_callable(array($object, $nextPartName))) {
|
||||
$object = call_user_func(array($object, $nextPartName));
|
||||
continue;
|
||||
}
|
||||
|
||||
// if a magic accessor method present...
|
||||
if (is_object($object) && method_exists($object, '__get')) {
|
||||
$object = $object->$nextPartName;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Inexistent property is a null, PHP-speak
|
||||
if (!property_exists($object, $nextPartName)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// then try a property (independent of accessibility)
|
||||
if (property_exists($object, $nextPartName)) {
|
||||
$object = $object->$nextPartName;
|
||||
continue;
|
||||
}
|
||||
|
||||
// we'll try casting this object in the next iteration
|
||||
}
|
||||
|
||||
// lastly, try to get an embedded value of an object
|
||||
// value could be of any type, not just string, so we have to do this
|
||||
// conversion here, not later in AbstractBlock::renderAll
|
||||
if (is_object($object) && method_exists($object, 'toLiquid')) {
|
||||
$object = $object->toLiquid();
|
||||
}
|
||||
|
||||
/*
|
||||
* Before here were checks for object types and object to string conversion.
|
||||
*
|
||||
* Now we just return what we have:
|
||||
* - Traversable objects are taken care of inside filters
|
||||
* - Object-to-string conversion is handled at the last moment in Decision::stringValue, and in AbstractBlock::renderAll
|
||||
*
|
||||
* This way complex objects could be passed between templates and to filters
|
||||
*/
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
public function tick()
|
||||
{
|
||||
if ($this->tickFunction === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$tickFunction = $this->tickFunction;
|
||||
$tickFunction($this);
|
||||
}
|
||||
}
|
||||
32
package/vendor/liquid/liquid/src/Liquid/CustomFilters.php
vendored
Normal file
32
package/vendor/liquid/liquid/src/Liquid/CustomFilters.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid;
|
||||
|
||||
/**
|
||||
* A selection of custom filters.
|
||||
*/
|
||||
class CustomFilters
|
||||
{
|
||||
|
||||
/**
|
||||
* Sort an array by key.
|
||||
*
|
||||
* @param array $input
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function sort_key(array $input)
|
||||
{
|
||||
ksort($input);
|
||||
return $input;
|
||||
}
|
||||
}
|
||||
161
package/vendor/liquid/liquid/src/Liquid/Decision.php
vendored
Normal file
161
package/vendor/liquid/liquid/src/Liquid/Decision.php
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid;
|
||||
|
||||
use Liquid\Exception\RenderException;
|
||||
|
||||
/**
|
||||
* Base class for blocks that make logical decisions.
|
||||
*/
|
||||
class Decision extends AbstractBlock
|
||||
{
|
||||
/**
|
||||
* The current left variable to compare
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $left;
|
||||
|
||||
/**
|
||||
* The current right variable to compare
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $right;
|
||||
|
||||
/**
|
||||
* Returns a string value of an array for comparisons
|
||||
*
|
||||
* @param mixed $value
|
||||
*
|
||||
* @throws \Liquid\Exception\RenderException
|
||||
* @return string
|
||||
*/
|
||||
private function stringValue($value)
|
||||
{
|
||||
// Objects should have a __toString method to get a value to compare to
|
||||
if (is_object($value)) {
|
||||
if (method_exists($value, '__toString')) {
|
||||
return (string) $value;
|
||||
}
|
||||
|
||||
if ($value instanceof \Generator) {
|
||||
return (string) $value->valid();
|
||||
}
|
||||
|
||||
// toLiquid is handled in Context::variable
|
||||
$class = get_class($value);
|
||||
throw new RenderException("Value of type $class has no `toLiquid` nor `__toString` methods");
|
||||
}
|
||||
|
||||
// Arrays simply return true
|
||||
if (is_array($value)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if to variables are equal in a given context
|
||||
*
|
||||
* @param string $left
|
||||
* @param string $right
|
||||
* @param Context $context
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function equalVariables($left, $right, Context $context)
|
||||
{
|
||||
$left = $this->stringValue($context->get($left));
|
||||
$right = $this->stringValue($context->get($right));
|
||||
|
||||
return ($left == $right);
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpret a comparison
|
||||
*
|
||||
* @param string $left
|
||||
* @param string $right
|
||||
* @param string $op
|
||||
* @param Context $context
|
||||
*
|
||||
* @throws \Liquid\Exception\RenderException
|
||||
* @return bool
|
||||
*/
|
||||
protected function interpretCondition($left, $right, $op, Context $context)
|
||||
{
|
||||
if (is_null($op)) {
|
||||
$value = $this->stringValue($context->get($left));
|
||||
return $value;
|
||||
}
|
||||
|
||||
// values of 'empty' have a special meaning in array comparisons
|
||||
if ($right == 'empty' && is_array($context->get($left))) {
|
||||
$left = count($context->get($left));
|
||||
$right = 0;
|
||||
} elseif ($left == 'empty' && is_array($context->get($right))) {
|
||||
$right = count($context->get($right));
|
||||
$left = 0;
|
||||
} else {
|
||||
$left = $context->get($left);
|
||||
$right = $context->get($right);
|
||||
|
||||
$left = $this->stringValue($left);
|
||||
$right = $this->stringValue($right);
|
||||
}
|
||||
|
||||
// special rules for null values
|
||||
if (is_null($left) || is_null($right)) {
|
||||
// null == null returns true
|
||||
if ($op == '==' && is_null($left) && is_null($right)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// null != anything other than null return true
|
||||
if ($op == '!=' && (!is_null($left) || !is_null($right))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// everything else, return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// regular rules
|
||||
switch ($op) {
|
||||
case '==':
|
||||
return ($left == $right);
|
||||
|
||||
case '!=':
|
||||
return ($left != $right);
|
||||
|
||||
case '>':
|
||||
return ($left > $right);
|
||||
|
||||
case '<':
|
||||
return ($left < $right);
|
||||
|
||||
case '>=':
|
||||
return ($left >= $right);
|
||||
|
||||
case '<=':
|
||||
return ($left <= $right);
|
||||
|
||||
case 'contains':
|
||||
return is_array($left) ? in_array($right, $left) : (strpos($left, $right) !== false);
|
||||
|
||||
default:
|
||||
throw new RenderException("Error in tag '" . $this->name() . "' - Unknown operator $op");
|
||||
}
|
||||
}
|
||||
}
|
||||
95
package/vendor/liquid/liquid/src/Liquid/Document.php
vendored
Normal file
95
package/vendor/liquid/liquid/src/Liquid/Document.php
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid;
|
||||
|
||||
use Liquid\Tag\TagInclude;
|
||||
use Liquid\Tag\TagExtends;
|
||||
use Liquid\Tag\TagBlock;
|
||||
|
||||
/**
|
||||
* This class represents the entire template document.
|
||||
*/
|
||||
class Document extends AbstractBlock
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $tokens
|
||||
* @param FileSystem $fileSystem
|
||||
*/
|
||||
public function __construct(array &$tokens, FileSystem $fileSystem = null)
|
||||
{
|
||||
$this->fileSystem = $fileSystem;
|
||||
$this->parse($tokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for cached includes; if there are - do not use cache
|
||||
*
|
||||
* @see \Liquid\Tag\TagInclude::hasIncludes()
|
||||
* @see \Liquid\Tag\TagExtends::hasIncludes()
|
||||
* @return bool if need to discard cache
|
||||
*/
|
||||
public function hasIncludes()
|
||||
{
|
||||
$seenExtends = false;
|
||||
$seenBlock = false;
|
||||
|
||||
foreach ($this->nodelist as $token) {
|
||||
if ($token instanceof TagExtends) {
|
||||
$seenExtends = true;
|
||||
} elseif ($token instanceof TagBlock) {
|
||||
$seenBlock = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We try to keep the base templates in cache (that not extend anything).
|
||||
*
|
||||
* At the same time if we re-render all other blocks we see, we avoid most
|
||||
* if not all related caching quirks. This may be suboptimal.
|
||||
*/
|
||||
if ($seenBlock && !$seenExtends) {
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach ($this->nodelist as $token) {
|
||||
// check any of the tokens for includes
|
||||
if ($token instanceof TagInclude && $token->hasIncludes()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($token instanceof TagExtends && $token->hasIncludes()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* There isn't a real delimiter
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function blockDelimiter()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Document blocks don't need to be terminated since they are not actually opened
|
||||
*/
|
||||
protected function assertMissingDelimitation()
|
||||
{
|
||||
}
|
||||
}
|
||||
107
package/vendor/liquid/liquid/src/Liquid/Drop.php
vendored
Normal file
107
package/vendor/liquid/liquid/src/Liquid/Drop.php
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid;
|
||||
|
||||
/**
|
||||
* A drop in liquid is a class which allows you to to export DOM like things to liquid.
|
||||
* Methods of drops are callable.
|
||||
* The main use for liquid drops is the implement lazy loaded objects.
|
||||
* If you would like to make data available to the web designers which you don't want loaded unless needed then
|
||||
* a drop is a great way to do that
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* class ProductDrop extends LiquidDrop {
|
||||
* public function topSales() {
|
||||
* Products::find('all', array('order' => 'sales', 'limit' => 10 ));
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* tmpl = Liquid::Template.parse( ' {% for product in product.top_sales %} {{ product.name }} {%endfor%} ' )
|
||||
* tmpl.render('product' => ProductDrop.new ) // will invoke topSales query.
|
||||
*
|
||||
* Your drop can either implement the methods sans any parameters or implement the beforeMethod(name) method which is a
|
||||
* catch all.
|
||||
*/
|
||||
abstract class Drop
|
||||
{
|
||||
/**
|
||||
* @var Context
|
||||
*/
|
||||
protected $context;
|
||||
|
||||
/**
|
||||
* Catch all method that is invoked before a specific method
|
||||
*
|
||||
* @param string $method
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
protected function beforeMethod($method)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Context $context
|
||||
*/
|
||||
public function setContext(Context $context)
|
||||
{
|
||||
$this->context = $context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke a specific method
|
||||
*
|
||||
* @param string $method
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function invokeDrop($method)
|
||||
{
|
||||
$result = $this->beforeMethod($method);
|
||||
|
||||
if (is_null($result) && is_callable(array($this, $method))) {
|
||||
$result = $this->$method();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the drop supports the given method
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasKey($name)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Drop
|
||||
*/
|
||||
public function toLiquid()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return get_class($this);
|
||||
}
|
||||
}
|
||||
21
package/vendor/liquid/liquid/src/Liquid/Exception/CacheException.php
vendored
Normal file
21
package/vendor/liquid/liquid/src/Liquid/Exception/CacheException.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Exception;
|
||||
|
||||
use Liquid\LiquidException;
|
||||
|
||||
/**
|
||||
* CacheException class.
|
||||
*/
|
||||
class CacheException extends LiquidException
|
||||
{
|
||||
}
|
||||
21
package/vendor/liquid/liquid/src/Liquid/Exception/FilesystemException.php
vendored
Normal file
21
package/vendor/liquid/liquid/src/Liquid/Exception/FilesystemException.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Exception;
|
||||
|
||||
use Liquid\LiquidException;
|
||||
|
||||
/**
|
||||
* FilesystemException class.
|
||||
*/
|
||||
class FilesystemException extends LiquidException
|
||||
{
|
||||
}
|
||||
22
package/vendor/liquid/liquid/src/Liquid/Exception/MissingFilesystemException.php
vendored
Normal file
22
package/vendor/liquid/liquid/src/Liquid/Exception/MissingFilesystemException.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Exception;
|
||||
|
||||
use Liquid\Exception\ParseException;
|
||||
|
||||
/**
|
||||
* Class MissingFilesystemException
|
||||
* @package Liquid\Exception
|
||||
*/
|
||||
class MissingFilesystemException extends ParseException
|
||||
{
|
||||
}
|
||||
21
package/vendor/liquid/liquid/src/Liquid/Exception/NotFoundException.php
vendored
Normal file
21
package/vendor/liquid/liquid/src/Liquid/Exception/NotFoundException.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Exception;
|
||||
|
||||
use Liquid\Exception\FilesystemException;
|
||||
|
||||
/**
|
||||
* NotFoundException class.
|
||||
*/
|
||||
class NotFoundException extends FilesystemException
|
||||
{
|
||||
}
|
||||
21
package/vendor/liquid/liquid/src/Liquid/Exception/ParseException.php
vendored
Normal file
21
package/vendor/liquid/liquid/src/Liquid/Exception/ParseException.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Exception;
|
||||
|
||||
use Liquid\LiquidException;
|
||||
|
||||
/**
|
||||
* ParseException class.
|
||||
*/
|
||||
class ParseException extends LiquidException
|
||||
{
|
||||
}
|
||||
21
package/vendor/liquid/liquid/src/Liquid/Exception/RenderException.php
vendored
Normal file
21
package/vendor/liquid/liquid/src/Liquid/Exception/RenderException.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Exception;
|
||||
|
||||
use Liquid\LiquidException;
|
||||
|
||||
/**
|
||||
* RenderException class.
|
||||
*/
|
||||
class RenderException extends LiquidException
|
||||
{
|
||||
}
|
||||
21
package/vendor/liquid/liquid/src/Liquid/Exception/WrongArgumentException.php
vendored
Normal file
21
package/vendor/liquid/liquid/src/Liquid/Exception/WrongArgumentException.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Exception;
|
||||
|
||||
use Liquid\LiquidException;
|
||||
|
||||
/**
|
||||
* WrongArgumentException class.
|
||||
*/
|
||||
class WrongArgumentException extends LiquidException
|
||||
{
|
||||
}
|
||||
32
package/vendor/liquid/liquid/src/Liquid/FileSystem.php
vendored
Normal file
32
package/vendor/liquid/liquid/src/Liquid/FileSystem.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid;
|
||||
|
||||
/**
|
||||
* A Liquid file system is way to let your templates retrieve other templates for use with the include tag.
|
||||
*
|
||||
* You can implement subclasses that retrieve templates from the database, from the file system using a different
|
||||
* path structure, you can provide them as hard-coded inline strings, or any manner that you see fit.
|
||||
*
|
||||
* You can add additional instance variables, arguments, or methods as needed.
|
||||
*/
|
||||
interface FileSystem
|
||||
{
|
||||
/**
|
||||
* Retrieve a template file.
|
||||
*
|
||||
* @param string $templatePath
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function readTemplateFile($templatePath);
|
||||
}
|
||||
110
package/vendor/liquid/liquid/src/Liquid/FileSystem/Local.php
vendored
Normal file
110
package/vendor/liquid/liquid/src/Liquid/FileSystem/Local.php
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\FileSystem;
|
||||
|
||||
use Liquid\Exception\NotFoundException;
|
||||
use Liquid\Exception\ParseException;
|
||||
use Liquid\FileSystem;
|
||||
use Liquid\Regexp;
|
||||
use Liquid\Liquid;
|
||||
|
||||
/**
|
||||
* This implements an abstract file system which retrieves template files named in a manner similar to Rails partials,
|
||||
* ie. with the template name prefixed with an underscore. The extension ".liquid" is also added.
|
||||
*
|
||||
* For security reasons, template paths are only allowed to contain letters, numbers, and underscore.
|
||||
*/
|
||||
class Local implements FileSystem
|
||||
{
|
||||
/**
|
||||
* The root path
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $root;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $root The root path for templates
|
||||
* @throws \Liquid\Exception\NotFoundException
|
||||
*/
|
||||
public function __construct($root)
|
||||
{
|
||||
// since root path can only be set from constructor, we check it once right here
|
||||
if (!empty($root)) {
|
||||
$realRoot = realpath($root);
|
||||
if ($realRoot === false) {
|
||||
throw new NotFoundException("Root path could not be found: '$root'");
|
||||
}
|
||||
$root = $realRoot;
|
||||
}
|
||||
|
||||
$this->root = $root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a template file
|
||||
*
|
||||
* @param string $templatePath
|
||||
*
|
||||
* @return string template content
|
||||
*/
|
||||
public function readTemplateFile($templatePath)
|
||||
{
|
||||
return file_get_contents($this->fullPath($templatePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a given path to a full template file path, making sure it's valid
|
||||
*
|
||||
* @param string $templatePath
|
||||
*
|
||||
* @throws \Liquid\Exception\ParseException
|
||||
* @throws \Liquid\Exception\NotFoundException
|
||||
* @return string
|
||||
*/
|
||||
public function fullPath($templatePath)
|
||||
{
|
||||
if (empty($templatePath)) {
|
||||
throw new ParseException("Empty template name");
|
||||
}
|
||||
|
||||
$nameRegex = Liquid::get('INCLUDE_ALLOW_EXT')
|
||||
? new Regexp('/^[^.\/][a-zA-Z0-9_\.\/-]+$/')
|
||||
: new Regexp('/^[^.\/][a-zA-Z0-9_\/-]+$/');
|
||||
|
||||
if (!$nameRegex->match($templatePath)) {
|
||||
throw new ParseException("Illegal template name '$templatePath'");
|
||||
}
|
||||
|
||||
$templateDir = dirname($templatePath);
|
||||
$templateFile = basename($templatePath);
|
||||
|
||||
if (!Liquid::get('INCLUDE_ALLOW_EXT')) {
|
||||
$templateFile = Liquid::get('INCLUDE_PREFIX') . $templateFile . '.' . Liquid::get('INCLUDE_SUFFIX');
|
||||
}
|
||||
|
||||
$fullPath = join(DIRECTORY_SEPARATOR, array($this->root, $templateDir, $templateFile));
|
||||
|
||||
$realFullPath = realpath($fullPath);
|
||||
if ($realFullPath === false) {
|
||||
throw new NotFoundException("File not found: $fullPath");
|
||||
}
|
||||
|
||||
if (strpos($realFullPath, $this->root) !== 0) {
|
||||
throw new NotFoundException("Illegal template full path: {$realFullPath} not under {$this->root}");
|
||||
}
|
||||
|
||||
return $realFullPath;
|
||||
}
|
||||
}
|
||||
64
package/vendor/liquid/liquid/src/Liquid/FileSystem/Virtual.php
vendored
Normal file
64
package/vendor/liquid/liquid/src/Liquid/FileSystem/Virtual.php
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\FileSystem;
|
||||
|
||||
use Liquid\Exception\FilesystemException;
|
||||
use Liquid\FileSystem;
|
||||
|
||||
/**
|
||||
* This implements a virtual file system with actual code used to find files injected from outside thus achieving inversion of control.
|
||||
*/
|
||||
class Virtual implements FileSystem
|
||||
{
|
||||
/**
|
||||
* @var callable
|
||||
*/
|
||||
private $callback;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param callable $callback Callback is responsible for providing content of requested templates. Should return template's text.
|
||||
* @throws \Liquid\Exception\FilesystemException
|
||||
*/
|
||||
public function __construct($callback)
|
||||
{
|
||||
// Since a callback can only be set from the constructor, we check it once right here.
|
||||
if (!is_callable($callback)) {
|
||||
throw new FilesystemException("Not a callback provided");
|
||||
}
|
||||
|
||||
$this->callback = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a template file
|
||||
*
|
||||
* @param string $templatePath
|
||||
*
|
||||
* @return string template content
|
||||
*/
|
||||
public function readTemplateFile($templatePath)
|
||||
{
|
||||
return call_user_func($this->callback, $templatePath);
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
// we cannot serialize a closure
|
||||
if ($this->callback instanceof \Closure) {
|
||||
throw new FilesystemException("Virtual file system with a Closure as a callback cannot be used with a serializing cache");
|
||||
}
|
||||
|
||||
return array_keys(get_object_vars($this));
|
||||
}
|
||||
}
|
||||
153
package/vendor/liquid/liquid/src/Liquid/Filterbank.php
vendored
Normal file
153
package/vendor/liquid/liquid/src/Liquid/Filterbank.php
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid;
|
||||
|
||||
use Liquid\Exception\WrongArgumentException;
|
||||
|
||||
/**
|
||||
* The filter bank is where all registered filters are stored, and where filter invocation is handled
|
||||
* it supports a variety of different filter types; objects, class, and simple methods.
|
||||
*/
|
||||
class Filterbank
|
||||
{
|
||||
/**
|
||||
* The registered filter objects
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $filters;
|
||||
|
||||
/**
|
||||
* A map of all filters and the class that contain them (in the case of methods)
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $methodMap;
|
||||
|
||||
/**
|
||||
* Reference to the current context object
|
||||
*
|
||||
* @var Context
|
||||
*/
|
||||
private $context;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param $context
|
||||
*/
|
||||
public function __construct(Context $context)
|
||||
{
|
||||
$this->context = $context;
|
||||
|
||||
$this->addFilter(\Liquid\StandardFilters::class);
|
||||
$this->addFilter(\Liquid\CustomFilters::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a filter to the bank
|
||||
*
|
||||
* @param mixed $filter Can either be an object, the name of a class (in which case the
|
||||
* filters will be called statically) or the name of a function.
|
||||
*
|
||||
* @throws \Liquid\Exception\WrongArgumentException
|
||||
* @return bool
|
||||
*/
|
||||
public function addFilter($filter, callable $callback = null)
|
||||
{
|
||||
// If it is a callback, save it as it is
|
||||
if (is_string($filter) && $callback) {
|
||||
$this->methodMap[$filter] = $callback;
|
||||
return true;
|
||||
}
|
||||
|
||||
// If the filter is a class, register all its static methods
|
||||
if (is_string($filter) && class_exists($filter)) {
|
||||
$reflection = new \ReflectionClass($filter);
|
||||
foreach ($reflection->getMethods(\ReflectionMethod::IS_STATIC) as $method) {
|
||||
$this->methodMap[$method->name] = $method->class;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// If it's a global function, register it simply
|
||||
if (is_string($filter) && function_exists($filter)) {
|
||||
$this->methodMap[$filter] = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// If it isn't an object an isn't a string either, it's a bad parameter
|
||||
if (!is_object($filter)) {
|
||||
throw new WrongArgumentException("Parameter passed to addFilter must be an object or a string");
|
||||
}
|
||||
|
||||
// If the passed filter was an object, store the object for future reference.
|
||||
$filter->context = $this->context;
|
||||
$className = get_class($filter);
|
||||
$this->filters[$className] = $filter;
|
||||
|
||||
// Then register all public static and not methods as filters
|
||||
foreach (get_class_methods($filter) as $method) {
|
||||
if (strtolower($method) === '__construct') {
|
||||
continue;
|
||||
}
|
||||
$this->methodMap[$method] = $className;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the filter with the given name
|
||||
*
|
||||
* @param string $name The name of the filter
|
||||
* @param string $value The value to filter
|
||||
* @param array $args The additional arguments for the filter
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function invoke($name, $value, array $args = array())
|
||||
{
|
||||
// workaround for a single standard filter being a reserved keyword - we can't use overloading for static calls
|
||||
if ($name == 'default') {
|
||||
$name = '_default';
|
||||
}
|
||||
|
||||
array_unshift($args, $value);
|
||||
|
||||
// Consult the mapping
|
||||
if (!isset($this->methodMap[$name])) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$class = $this->methodMap[$name];
|
||||
|
||||
// If we have a callback
|
||||
if (is_callable($class)) {
|
||||
return call_user_func_array($class, $args);
|
||||
}
|
||||
|
||||
// If we have a registered object for the class, use that instead
|
||||
if (isset($this->filters[$class])) {
|
||||
$class = $this->filters[$class];
|
||||
}
|
||||
|
||||
// If we're calling a function
|
||||
if ($class === false) {
|
||||
return call_user_func_array($name, $args);
|
||||
}
|
||||
|
||||
// Call a class or an instance method
|
||||
return call_user_func_array(array($class, $name), $args);
|
||||
}
|
||||
}
|
||||
170
package/vendor/liquid/liquid/src/Liquid/Liquid.php
vendored
Normal file
170
package/vendor/liquid/liquid/src/Liquid/Liquid.php
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid;
|
||||
|
||||
/**
|
||||
* Liquid for PHP.
|
||||
*/
|
||||
class Liquid
|
||||
{
|
||||
/**
|
||||
* We cannot make settings constants, because we cannot create compound
|
||||
* constants in PHP (before 5.6).
|
||||
*
|
||||
* @var array configuration array
|
||||
*/
|
||||
public static $config = array(
|
||||
// The method is called on objects when resolving variables to see
|
||||
// if a given property exists.
|
||||
'HAS_PROPERTY_METHOD' => 'field_exists',
|
||||
|
||||
// This method is called on object when resolving variables when
|
||||
// a given property exists.
|
||||
'GET_PROPERTY_METHOD' => 'get',
|
||||
|
||||
// Separator between filters.
|
||||
'FILTER_SEPARATOR' => '\|',
|
||||
|
||||
// Separator for arguments.
|
||||
'ARGUMENT_SEPARATOR' => ',',
|
||||
|
||||
// Separator for argument names and values.
|
||||
'FILTER_ARGUMENT_SEPARATOR' => ':',
|
||||
|
||||
// Separator for variable attributes.
|
||||
'VARIABLE_ATTRIBUTE_SEPARATOR' => '.',
|
||||
|
||||
// Allow template names with extension in include and extends tags.
|
||||
'INCLUDE_ALLOW_EXT' => false,
|
||||
|
||||
// Suffix for include files.
|
||||
'INCLUDE_SUFFIX' => 'liquid',
|
||||
|
||||
// Prefix for include files.
|
||||
'INCLUDE_PREFIX' => '_',
|
||||
|
||||
// Whitespace control.
|
||||
'WHITESPACE_CONTROL' => '-',
|
||||
|
||||
// Tag start.
|
||||
'TAG_START' => '{%',
|
||||
|
||||
// Tag end.
|
||||
'TAG_END' => '%}',
|
||||
|
||||
// Variable start.
|
||||
'VARIABLE_START' => '{{',
|
||||
|
||||
// Variable end.
|
||||
'VARIABLE_END' => '}}',
|
||||
|
||||
// Variable name.
|
||||
'VARIABLE_NAME' => '[a-zA-Z_][a-zA-Z_0-9.-]*',
|
||||
|
||||
'QUOTED_STRING' => '(?:"[^"]*"|\'[^\']*\')',
|
||||
'QUOTED_STRING_FILTER_ARGUMENT' => '"[^"]*"|\'[^\']*\'',
|
||||
|
||||
// Automatically escape any variables unless told otherwise by a "raw" filter
|
||||
'ESCAPE_BY_DEFAULT' => false,
|
||||
|
||||
// The name of the key to use when building pagination query strings e.g. ?page=1
|
||||
'PAGINATION_REQUEST_KEY' => 'page',
|
||||
|
||||
// The name of the context key used to denote the current page number
|
||||
'PAGINATION_CONTEXT_KEY' => 'page',
|
||||
|
||||
// Whenever variables from $_SERVER should be directly available to templates
|
||||
'EXPOSE_SERVER' => false,
|
||||
|
||||
// $_SERVER variables whitelist - exposed even when EXPOSE_SERVER is false
|
||||
'SERVER_SUPERGLOBAL_WHITELIST' => [
|
||||
'HTTP_ACCEPT',
|
||||
'HTTP_ACCEPT_CHARSET',
|
||||
'HTTP_ACCEPT_ENCODING',
|
||||
'HTTP_ACCEPT_LANGUAGE',
|
||||
'HTTP_CONNECTION',
|
||||
'HTTP_HOST',
|
||||
'HTTP_REFERER',
|
||||
'HTTP_USER_AGENT',
|
||||
'HTTPS',
|
||||
'REQUEST_METHOD',
|
||||
'REQUEST_URI',
|
||||
'SERVER_NAME',
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* Get a configuration setting.
|
||||
*
|
||||
* @param string $key setting key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get($key)
|
||||
{
|
||||
// backward compatibility
|
||||
if ($key === 'ALLOWED_VARIABLE_CHARS') {
|
||||
return substr(self::$config['VARIABLE_NAME'], 0, -1);
|
||||
}
|
||||
if (array_key_exists($key, self::$config)) {
|
||||
return self::$config[$key];
|
||||
}
|
||||
// This case is needed for compound settings
|
||||
switch ($key) {
|
||||
case 'QUOTED_FRAGMENT':
|
||||
return '(?:' . self::get('QUOTED_STRING') . '|(?:[^\s,\|\'"]|' . self::get('QUOTED_STRING') . ')+)';
|
||||
case 'TAG_ATTRIBUTES':
|
||||
return '/(\w+)\s*\:\s*(' . self::get('QUOTED_FRAGMENT') . ')/';
|
||||
case 'TOKENIZATION_REGEXP':
|
||||
return '/(' . self::$config['TAG_START'] . '.*?' . self::$config['TAG_END'] . '|' . self::$config['VARIABLE_START'] . '.*?' . self::$config['VARIABLE_END'] . ')/s';
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes/creates a setting.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
*/
|
||||
public static function set($key, $value)
|
||||
{
|
||||
// backward compatibility
|
||||
if ($key === 'ALLOWED_VARIABLE_CHARS') {
|
||||
$key = 'VARIABLE_NAME';
|
||||
$value .= '+';
|
||||
}
|
||||
self::$config[$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flatten a multidimensional array into a single array. Does not maintain keys.
|
||||
*
|
||||
* @param array $array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function arrayFlatten($array)
|
||||
{
|
||||
$return = array();
|
||||
|
||||
foreach ($array as $element) {
|
||||
if (is_array($element)) {
|
||||
$return = array_merge($return, self::arrayFlatten($element));
|
||||
} else {
|
||||
$return[] = $element;
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
19
package/vendor/liquid/liquid/src/Liquid/LiquidException.php
vendored
Normal file
19
package/vendor/liquid/liquid/src/Liquid/LiquidException.php
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid;
|
||||
|
||||
/**
|
||||
* LiquidException class.
|
||||
*/
|
||||
class LiquidException extends \Exception
|
||||
{
|
||||
}
|
||||
19
package/vendor/liquid/liquid/src/Liquid/LocalFileSystem.php
vendored
Normal file
19
package/vendor/liquid/liquid/src/Liquid/LocalFileSystem.php
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid;
|
||||
|
||||
/**
|
||||
* @deprecated Left for backward compatibility reasons. Use \Liquid\FileSystem\Local instead.
|
||||
*/
|
||||
class LocalFileSystem extends \Liquid\FileSystem\Local
|
||||
{
|
||||
}
|
||||
134
package/vendor/liquid/liquid/src/Liquid/Regexp.php
vendored
Normal file
134
package/vendor/liquid/liquid/src/Liquid/Regexp.php
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid;
|
||||
|
||||
/**
|
||||
* A support class for regular expressions and
|
||||
* non liquid specific support classes and functions.
|
||||
*/
|
||||
class Regexp
|
||||
{
|
||||
/**
|
||||
* The regexp pattern
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $pattern;
|
||||
|
||||
/**
|
||||
* The matches from the last method called
|
||||
*
|
||||
* @var array;
|
||||
*/
|
||||
public $matches;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $pattern
|
||||
*
|
||||
* @return Regexp
|
||||
*/
|
||||
public function __construct($pattern)
|
||||
{
|
||||
$this->pattern = (substr($pattern, 0, 1) != '/')
|
||||
? '/' . $this->quote($pattern) . '/'
|
||||
: $pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Quotes regular expression characters
|
||||
*
|
||||
* @param string $string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function quote($string)
|
||||
{
|
||||
return preg_quote($string, '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of matches for the string in the same way as Ruby's scan method
|
||||
*
|
||||
* @param string $string
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function scan($string)
|
||||
{
|
||||
preg_match_all($this->pattern, $string, $matches);
|
||||
|
||||
if (count($matches) == 1) {
|
||||
return $matches[0];
|
||||
}
|
||||
|
||||
array_shift($matches);
|
||||
|
||||
$result = array();
|
||||
|
||||
foreach ($matches as $matchKey => $subMatches) {
|
||||
foreach ($subMatches as $subMatchKey => $subMatch) {
|
||||
$result[$subMatchKey][$matchKey] = $subMatch;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches the given string. Only matches once.
|
||||
*
|
||||
* @param string $string
|
||||
*
|
||||
* @return int 1 if there was a match, 0 if there wasn't
|
||||
*/
|
||||
public function match($string)
|
||||
{
|
||||
return preg_match($this->pattern, $string, $this->matches);
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches the given string. Matches all.
|
||||
*
|
||||
* @param string $string
|
||||
*
|
||||
* @return int The number of matches
|
||||
*/
|
||||
public function matchAll($string)
|
||||
{
|
||||
return preg_match_all($this->pattern, $string, $this->matches);
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits the given string
|
||||
*
|
||||
* @param string $string
|
||||
* @param int $limit Limits the amount of results returned
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function split($string, $limit = -1)
|
||||
{
|
||||
return preg_split($this->pattern, $string, $limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the original pattern primarily for debugging purposes
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->pattern;
|
||||
}
|
||||
}
|
||||
727
package/vendor/liquid/liquid/src/Liquid/StandardFilters.php
vendored
Normal file
727
package/vendor/liquid/liquid/src/Liquid/StandardFilters.php
vendored
Normal file
@@ -0,0 +1,727 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid;
|
||||
|
||||
use Liquid\Exception\RenderException;
|
||||
|
||||
/**
|
||||
* A selection of standard filters.
|
||||
*/
|
||||
class StandardFilters
|
||||
{
|
||||
|
||||
/**
|
||||
* Add one string to another
|
||||
*
|
||||
* @param string $input
|
||||
* @param string $string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function append($input, $string)
|
||||
{
|
||||
return $input . $string;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Capitalize words in the input sentence
|
||||
*
|
||||
* @param string $input
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function capitalize($input)
|
||||
{
|
||||
return preg_replace_callback("/(^|[^\p{L}'])([\p{Ll}])/u", function ($matches) {
|
||||
$first_char = mb_substr($matches[2], 0, 1);
|
||||
return $matches[1] . mb_strtoupper($first_char) . mb_substr($matches[2], 1);
|
||||
}, ucwords($input));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param mixed $input number
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function ceil($input)
|
||||
{
|
||||
return (int) ceil((float)$input);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Formats a date using strftime
|
||||
*
|
||||
* @param mixed $input
|
||||
* @param string $format
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function date($input, $format)
|
||||
{
|
||||
if (!is_numeric($input)) {
|
||||
$input = strtotime($input);
|
||||
}
|
||||
|
||||
if ($format == 'r') {
|
||||
return date($format, $input);
|
||||
}
|
||||
|
||||
return strftime($format, $input);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default
|
||||
*
|
||||
* @param string $input
|
||||
* @param string $default_value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function _default($input, $default_value)
|
||||
{
|
||||
$isBlank = $input == '' || $input === false || $input === null;
|
||||
return $isBlank ? $default_value : $input;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* division
|
||||
*
|
||||
* @param float $input
|
||||
* @param float $operand
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public static function divided_by($input, $operand)
|
||||
{
|
||||
return (float)$input / (float)$operand;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert an input to lowercase
|
||||
*
|
||||
* @param string $input
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function downcase($input)
|
||||
{
|
||||
return is_string($input) ? mb_strtolower($input) : $input;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pseudo-filter: negates auto-added escape filter
|
||||
*
|
||||
* @param string $input
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function raw($input)
|
||||
{
|
||||
return $input;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Escape a string
|
||||
*
|
||||
* @param string $input
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function escape($input)
|
||||
{
|
||||
// Arrays are taken care down the stack with an error
|
||||
if (is_array($input)) {
|
||||
return $input;
|
||||
}
|
||||
|
||||
return htmlentities($input, ENT_QUOTES);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Escape a string once, keeping all previous HTML entities intact
|
||||
*
|
||||
* @param string $input
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function escape_once($input)
|
||||
{
|
||||
// Arrays are taken care down the stack with an error
|
||||
if (is_array($input)) {
|
||||
return $input;
|
||||
}
|
||||
|
||||
return htmlentities($input, ENT_QUOTES, null, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the first element of an array
|
||||
*
|
||||
* @param array|\Iterator $input
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function first($input)
|
||||
{
|
||||
if ($input instanceof \Iterator) {
|
||||
$input->rewind();
|
||||
return $input->current();
|
||||
}
|
||||
return is_array($input) ? reset($input) : $input;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param mixed $input number
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function floor($input)
|
||||
{
|
||||
return (int) floor((float)$input);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Joins elements of an array with a given character between them
|
||||
*
|
||||
* @param array|\Traversable $input
|
||||
* @param string $glue
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function join($input, $glue = ' ')
|
||||
{
|
||||
if ($input instanceof \Traversable) {
|
||||
$str = '';
|
||||
foreach ($input as $elem) {
|
||||
if ($str) {
|
||||
$str .= $glue;
|
||||
}
|
||||
$str .= $elem;
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
return is_array($input) ? implode($glue, $input) : $input;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the last element of an array
|
||||
*
|
||||
* @param array|\Traversable $input
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function last($input)
|
||||
{
|
||||
if ($input instanceof \Traversable) {
|
||||
$last = null;
|
||||
foreach ($input as $elem) {
|
||||
$last = $elem;
|
||||
}
|
||||
return $last;
|
||||
}
|
||||
return is_array($input) ? end($input) : $input;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $input
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function lstrip($input)
|
||||
{
|
||||
return ltrim($input);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Map/collect on a given property
|
||||
*
|
||||
* @param array|\Traversable $input
|
||||
* @param string $property
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function map($input, $property)
|
||||
{
|
||||
if ($input instanceof \Traversable) {
|
||||
$input = iterator_to_array($input);
|
||||
}
|
||||
if (!is_array($input)) {
|
||||
return $input;
|
||||
}
|
||||
return array_map(function ($elem) use ($property) {
|
||||
if (is_callable($elem)) {
|
||||
return $elem();
|
||||
} elseif (is_array($elem) && array_key_exists($property, $elem)) {
|
||||
return $elem[$property];
|
||||
}
|
||||
return null;
|
||||
}, $input);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* subtraction
|
||||
*
|
||||
* @param float $input
|
||||
* @param float $operand
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public static function minus($input, $operand)
|
||||
{
|
||||
return (float)$input - (float)$operand;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* modulo
|
||||
*
|
||||
* @param float $input
|
||||
* @param float $operand
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public static function modulo($input, $operand)
|
||||
{
|
||||
return fmod((float)$input, (float)$operand);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Replace each newline (\n) with html break
|
||||
*
|
||||
* @param string $input
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function newline_to_br($input)
|
||||
{
|
||||
return is_string($input) ? str_replace("\n", "<br />\n", $input) : $input;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* addition
|
||||
*
|
||||
* @param float $input
|
||||
* @param float $operand
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public static function plus($input, $operand)
|
||||
{
|
||||
return (float)$input + (float)$operand;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prepend a string to another
|
||||
*
|
||||
* @param string $input
|
||||
* @param string $string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function prepend($input, $string)
|
||||
{
|
||||
return $string . $input;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove a substring
|
||||
*
|
||||
* @param string $input
|
||||
* @param string $string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function remove($input, $string)
|
||||
{
|
||||
return str_replace($string, '', $input);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove the first occurrences of a substring
|
||||
*
|
||||
* @param string $input
|
||||
* @param string $string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function remove_first($input, $string)
|
||||
{
|
||||
if (($pos = strpos($input, $string)) !== false) {
|
||||
$input = substr_replace($input, '', $pos, strlen($string));
|
||||
}
|
||||
|
||||
return $input;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Replace occurrences of a string with another
|
||||
*
|
||||
* @param string $input
|
||||
* @param string $string
|
||||
* @param string $replacement
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function replace($input, $string, $replacement = '')
|
||||
{
|
||||
return str_replace($string, $replacement, $input);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Replace the first occurrences of a string with another
|
||||
*
|
||||
* @param string $input
|
||||
* @param string $string
|
||||
* @param string $replacement
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function replace_first($input, $string, $replacement = '')
|
||||
{
|
||||
if (($pos = strpos($input, $string)) !== false) {
|
||||
$input = substr_replace($input, $replacement, $pos, strlen($string));
|
||||
}
|
||||
|
||||
return $input;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reverse the elements of an array
|
||||
*
|
||||
* @param array|\Traversable $input
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function reverse($input)
|
||||
{
|
||||
if ($input instanceof \Traversable) {
|
||||
$input = iterator_to_array($input);
|
||||
}
|
||||
return array_reverse($input);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Round a number
|
||||
*
|
||||
* @param float $input
|
||||
* @param int $n precision
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public static function round($input, $n = 0)
|
||||
{
|
||||
return round((float)$input, (int)$n);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $input
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function rstrip($input)
|
||||
{
|
||||
return rtrim($input);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the size of an array or of an string
|
||||
*
|
||||
* @param mixed $input
|
||||
* @throws RenderException
|
||||
* @return int
|
||||
*/
|
||||
public static function size($input)
|
||||
{
|
||||
if ($input instanceof \Iterator) {
|
||||
return iterator_count($input);
|
||||
}
|
||||
|
||||
if (is_array($input)) {
|
||||
return count($input);
|
||||
}
|
||||
|
||||
if (is_object($input)) {
|
||||
if (method_exists($input, 'size')) {
|
||||
return $input->size();
|
||||
}
|
||||
|
||||
if (!method_exists($input, '__toString')) {
|
||||
$class = get_class($input);
|
||||
throw new RenderException("Size of $class cannot be estimated: it has no method 'size' nor can be converted to a string");
|
||||
}
|
||||
}
|
||||
|
||||
// only plain values and stringable objects left at this point
|
||||
return strlen($input);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array|\Iterator|string $input
|
||||
* @param int $offset
|
||||
* @param int $length
|
||||
*
|
||||
* @return array|\Iterator|string
|
||||
*/
|
||||
public static function slice($input, $offset, $length = null)
|
||||
{
|
||||
if ($input instanceof \Iterator) {
|
||||
$input = iterator_to_array($input);
|
||||
}
|
||||
if (is_array($input)) {
|
||||
$input = array_slice($input, $offset, $length);
|
||||
} elseif (is_string($input)) {
|
||||
$input = mb_substr($input, $offset, $length);
|
||||
}
|
||||
|
||||
return $input;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sort the elements of an array
|
||||
*
|
||||
* @param array|\Traversable $input
|
||||
* @param string $property use this property of an array element
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function sort($input, $property = null)
|
||||
{
|
||||
if ($input instanceof \Traversable) {
|
||||
$input = iterator_to_array($input);
|
||||
}
|
||||
if ($property === null) {
|
||||
asort($input);
|
||||
} else {
|
||||
$first = reset($input);
|
||||
if ($first !== false && is_array($first) && array_key_exists($property, $first)) {
|
||||
uasort($input, function ($a, $b) use ($property) {
|
||||
if ($a[$property] == $b[$property]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $a[$property] < $b[$property] ? -1 : 1;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Explicit string conversion.
|
||||
*
|
||||
* @param mixed $input
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function string($input)
|
||||
{
|
||||
return strval($input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Split input string into an array of substrings separated by given pattern.
|
||||
*
|
||||
* @param string $input
|
||||
* @param string $pattern
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function split($input, $pattern)
|
||||
{
|
||||
if ($input === '' || $input === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return explode($pattern, $input);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $input
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function strip($input)
|
||||
{
|
||||
return trim($input);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes html tags from text
|
||||
*
|
||||
* @param string $input
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function strip_html($input)
|
||||
{
|
||||
return is_string($input) ? strip_tags($input) : $input;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Strip all newlines (\n, \r) from string
|
||||
*
|
||||
* @param string $input
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function strip_newlines($input)
|
||||
{
|
||||
return is_string($input) ? str_replace(array(
|
||||
"\n", "\r"
|
||||
), '', $input) : $input;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* multiplication
|
||||
*
|
||||
* @param float $input
|
||||
* @param float $operand
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public static function times($input, $operand)
|
||||
{
|
||||
return (float)$input * (float)$operand;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Truncate a string down to x characters
|
||||
*
|
||||
* @param string $input
|
||||
* @param int $characters
|
||||
* @param string $ending string to append if truncated
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function truncate($input, $characters = 100, $ending = '...')
|
||||
{
|
||||
if (is_string($input) || is_numeric($input)) {
|
||||
if (strlen($input) > $characters) {
|
||||
return mb_substr($input, 0, $characters) . $ending;
|
||||
}
|
||||
}
|
||||
|
||||
return $input;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Truncate string down to x words
|
||||
*
|
||||
* @param string $input
|
||||
* @param int $words
|
||||
* @param string $ending string to append if truncated
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function truncatewords($input, $words = 3, $ending = '...')
|
||||
{
|
||||
if (is_string($input)) {
|
||||
$wordlist = explode(" ", $input);
|
||||
|
||||
if (count($wordlist) > $words) {
|
||||
return implode(" ", array_slice($wordlist, 0, $words)) . $ending;
|
||||
}
|
||||
}
|
||||
|
||||
return $input;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove duplicate elements from an array
|
||||
*
|
||||
* @param array|\Traversable $input
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function uniq($input)
|
||||
{
|
||||
if ($input instanceof \Traversable) {
|
||||
$input = iterator_to_array($input);
|
||||
}
|
||||
return array_unique($input);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert an input to uppercase
|
||||
*
|
||||
* @param string $input
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function upcase($input)
|
||||
{
|
||||
return is_string($input) ? mb_strtoupper($input) : $input;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* URL encodes a string
|
||||
*
|
||||
* @param string $input
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function url_encode($input)
|
||||
{
|
||||
return urlencode($input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes a URL-encoded string
|
||||
*
|
||||
* @param string $input
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function url_decode($input)
|
||||
{
|
||||
return urldecode($input);
|
||||
}
|
||||
}
|
||||
76
package/vendor/liquid/liquid/src/Liquid/Tag/TagAssign.php
vendored
Normal file
76
package/vendor/liquid/liquid/src/Liquid/Tag/TagAssign.php
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Tag;
|
||||
|
||||
use Liquid\AbstractTag;
|
||||
use Liquid\Exception\ParseException;
|
||||
use Liquid\Liquid;
|
||||
use Liquid\FileSystem;
|
||||
use Liquid\Regexp;
|
||||
use Liquid\Context;
|
||||
use Liquid\Variable;
|
||||
|
||||
/**
|
||||
* Performs an assignment of one variable to another
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* {% assign var = var %}
|
||||
* {% assign var = "hello" | upcase %}
|
||||
*/
|
||||
class TagAssign extends AbstractTag
|
||||
{
|
||||
/**
|
||||
* @var string The variable to assign from
|
||||
*/
|
||||
private $from;
|
||||
|
||||
/**
|
||||
* @var string The variable to assign to
|
||||
*/
|
||||
private $to;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $markup
|
||||
* @param array $tokens
|
||||
* @param FileSystem $fileSystem
|
||||
*
|
||||
* @throws \Liquid\Exception\ParseException
|
||||
*/
|
||||
public function __construct($markup, array &$tokens, FileSystem $fileSystem = null)
|
||||
{
|
||||
$syntaxRegexp = new Regexp('/(\w+)\s*=\s*(.*)\s*/');
|
||||
|
||||
if ($syntaxRegexp->match($markup)) {
|
||||
$this->to = $syntaxRegexp->matches[1];
|
||||
$this->from = new Variable($syntaxRegexp->matches[2]);
|
||||
} else {
|
||||
throw new ParseException("Syntax Error in 'assign' - Valid syntax: assign [var] = [source]");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the tag
|
||||
*
|
||||
* @param Context $context
|
||||
*
|
||||
* @return string|void
|
||||
*/
|
||||
public function render(Context $context)
|
||||
{
|
||||
$output = $this->from->render($context);
|
||||
|
||||
$context->set($this->to, $output, true);
|
||||
}
|
||||
}
|
||||
56
package/vendor/liquid/liquid/src/Liquid/Tag/TagBlock.php
vendored
Normal file
56
package/vendor/liquid/liquid/src/Liquid/Tag/TagBlock.php
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Tag;
|
||||
|
||||
use Liquid\AbstractBlock;
|
||||
use Liquid\Exception\ParseException;
|
||||
use Liquid\FileSystem;
|
||||
use Liquid\Regexp;
|
||||
|
||||
/**
|
||||
* Marks a section of a template as being reusable.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* {% block foo %} bar {% endblock %}
|
||||
*/
|
||||
class TagBlock extends AbstractBlock
|
||||
{
|
||||
/**
|
||||
* The variable to assign to
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $block;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $markup
|
||||
* @param array $tokens
|
||||
* @param FileSystem $fileSystem
|
||||
*
|
||||
* @throws \Liquid\Exception\ParseException
|
||||
* @return \Liquid\Tag\TagBlock
|
||||
*/
|
||||
public function __construct($markup, array &$tokens, FileSystem $fileSystem = null)
|
||||
{
|
||||
$syntaxRegexp = new Regexp('/(\w+)/');
|
||||
|
||||
if ($syntaxRegexp->match($markup)) {
|
||||
$this->block = $syntaxRegexp->matches[1];
|
||||
parent::__construct($markup, $tokens, $fileSystem);
|
||||
} else {
|
||||
throw new ParseException("Syntax Error in 'block' - Valid syntax: block [name]");
|
||||
}
|
||||
}
|
||||
}
|
||||
42
package/vendor/liquid/liquid/src/Liquid/Tag/TagBreak.php
vendored
Normal file
42
package/vendor/liquid/liquid/src/Liquid/Tag/TagBreak.php
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Tag;
|
||||
|
||||
use Liquid\AbstractTag;
|
||||
use Liquid\Context;
|
||||
|
||||
/**
|
||||
* Break iteration of the current loop
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* {% for i in (1..5) %}
|
||||
* {% if i == 4 %}
|
||||
* {% break %}
|
||||
* {% endif %}
|
||||
* {{ i }}
|
||||
* {% endfor %}
|
||||
*/
|
||||
class TagBreak extends AbstractTag
|
||||
{
|
||||
/**
|
||||
* Renders the tag
|
||||
*
|
||||
* @param Context $context
|
||||
*
|
||||
* @return string|void
|
||||
*/
|
||||
public function render(Context $context)
|
||||
{
|
||||
$context->registers['break'] = true;
|
||||
}
|
||||
}
|
||||
71
package/vendor/liquid/liquid/src/Liquid/Tag/TagCapture.php
vendored
Normal file
71
package/vendor/liquid/liquid/src/Liquid/Tag/TagCapture.php
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Tag;
|
||||
|
||||
use Liquid\AbstractBlock;
|
||||
use Liquid\Context;
|
||||
use Liquid\Exception\ParseException;
|
||||
use Liquid\FileSystem;
|
||||
use Liquid\Regexp;
|
||||
|
||||
/**
|
||||
* Captures the output inside a block and assigns it to a variable
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* {% capture foo %} bar {% endcapture %}
|
||||
*/
|
||||
class TagCapture extends AbstractBlock
|
||||
{
|
||||
/**
|
||||
* The variable to assign to
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $to;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $markup
|
||||
* @param array $tokens
|
||||
* @param FileSystem $fileSystem
|
||||
*
|
||||
* @throws \Liquid\Exception\ParseException
|
||||
*/
|
||||
public function __construct($markup, array &$tokens, FileSystem $fileSystem = null)
|
||||
{
|
||||
$syntaxRegexp = new Regexp('/(\w+)/');
|
||||
|
||||
if ($syntaxRegexp->match($markup)) {
|
||||
$this->to = $syntaxRegexp->matches[1];
|
||||
parent::__construct($markup, $tokens, $fileSystem);
|
||||
} else {
|
||||
throw new ParseException("Syntax Error in 'capture' - Valid syntax: capture [var] [value]");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the block
|
||||
*
|
||||
* @param Context $context
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render(Context $context)
|
||||
{
|
||||
$output = parent::render($context);
|
||||
|
||||
$context->set($this->to, $output, true);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
171
package/vendor/liquid/liquid/src/Liquid/Tag/TagCase.php
vendored
Normal file
171
package/vendor/liquid/liquid/src/Liquid/Tag/TagCase.php
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Tag;
|
||||
|
||||
use Liquid\Decision;
|
||||
use Liquid\Context;
|
||||
use Liquid\Exception\ParseException;
|
||||
use Liquid\Liquid;
|
||||
use Liquid\FileSystem;
|
||||
use Liquid\Regexp;
|
||||
|
||||
/**
|
||||
* A switch statement
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* {% case condition %}{% when foo %} foo {% else %} bar {% endcase %}
|
||||
*/
|
||||
class TagCase extends Decision
|
||||
{
|
||||
/**
|
||||
* Stack of nodelists
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $nodelists;
|
||||
|
||||
/**
|
||||
* The nodelist for the else (default) nodelist
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $elseNodelist;
|
||||
|
||||
/**
|
||||
* The left value to compare
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $left;
|
||||
|
||||
/**
|
||||
* The current right value to compare
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
public $right;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $markup
|
||||
* @param array $tokens
|
||||
* @param FileSystem $fileSystem
|
||||
*
|
||||
* @throws \Liquid\Exception\ParseException
|
||||
*/
|
||||
public function __construct($markup, array &$tokens, FileSystem $fileSystem = null)
|
||||
{
|
||||
$this->nodelists = array();
|
||||
$this->elseNodelist = array();
|
||||
|
||||
parent::__construct($markup, $tokens, $fileSystem);
|
||||
|
||||
$syntaxRegexp = new Regexp('/' . Liquid::get('QUOTED_FRAGMENT') . '/');
|
||||
|
||||
if ($syntaxRegexp->match($markup)) {
|
||||
$this->left = $syntaxRegexp->matches[0];
|
||||
} else {
|
||||
throw new ParseException("Syntax Error in tag 'case' - Valid syntax: case [condition]"); // harry
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pushes the last nodelist onto the stack
|
||||
*/
|
||||
public function endTag()
|
||||
{
|
||||
$this->pushNodelist();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unknown tag handler
|
||||
*
|
||||
* @param string $tag
|
||||
* @param string $params
|
||||
* @param array $tokens
|
||||
*
|
||||
* @throws \Liquid\Exception\ParseException
|
||||
*/
|
||||
public function unknownTag($tag, $params, array $tokens)
|
||||
{
|
||||
$whenSyntaxRegexp = new Regexp('/' . Liquid::get('QUOTED_FRAGMENT') . '/');
|
||||
|
||||
switch ($tag) {
|
||||
case 'when':
|
||||
// push the current nodelist onto the stack and prepare for a new one
|
||||
if ($whenSyntaxRegexp->match($params)) {
|
||||
$this->pushNodelist();
|
||||
$this->right = $whenSyntaxRegexp->matches[0];
|
||||
$this->nodelist = array();
|
||||
} else {
|
||||
throw new ParseException("Syntax Error in tag 'case' - Valid when condition: when [condition]"); // harry
|
||||
}
|
||||
break;
|
||||
|
||||
case 'else':
|
||||
// push the last nodelist onto the stack and prepare to receive the else nodes
|
||||
$this->pushNodelist();
|
||||
$this->right = null;
|
||||
$this->elseNodelist = &$this->nodelist;
|
||||
$this->nodelist = array();
|
||||
break;
|
||||
|
||||
default:
|
||||
parent::unknownTag($tag, $params, $tokens);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pushes the current right value and nodelist into the nodelist stack
|
||||
*/
|
||||
public function pushNodelist()
|
||||
{
|
||||
if (!is_null($this->right)) {
|
||||
$this->nodelists[] = array($this->right, $this->nodelist);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the node
|
||||
*
|
||||
* @param Context $context
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render(Context $context)
|
||||
{
|
||||
$output = ''; // array();
|
||||
$runElseBlock = true;
|
||||
|
||||
foreach ($this->nodelists as $data) {
|
||||
list($right, $nodelist) = $data;
|
||||
|
||||
if ($this->equalVariables($this->left, $right, $context)) {
|
||||
$runElseBlock = false;
|
||||
|
||||
$context->push();
|
||||
$output .= $this->renderAll($nodelist, $context);
|
||||
$context->pop();
|
||||
}
|
||||
}
|
||||
|
||||
if ($runElseBlock) {
|
||||
$context->push();
|
||||
$output .= $this->renderAll($this->elseNodelist, $context);
|
||||
$context->pop();
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
37
package/vendor/liquid/liquid/src/Liquid/Tag/TagComment.php
vendored
Normal file
37
package/vendor/liquid/liquid/src/Liquid/Tag/TagComment.php
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Tag;
|
||||
|
||||
use Liquid\AbstractBlock;
|
||||
use Liquid\Context;
|
||||
|
||||
/**
|
||||
* Creates a comment; everything inside will be ignored
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* {% comment %} This will be ignored {% endcomment %}
|
||||
*/
|
||||
class TagComment extends AbstractBlock
|
||||
{
|
||||
/**
|
||||
* Renders the block
|
||||
*
|
||||
* @param Context $context
|
||||
*
|
||||
* @return string empty string
|
||||
*/
|
||||
public function render(Context $context)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
||||
42
package/vendor/liquid/liquid/src/Liquid/Tag/TagContinue.php
vendored
Normal file
42
package/vendor/liquid/liquid/src/Liquid/Tag/TagContinue.php
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Tag;
|
||||
|
||||
use Liquid\AbstractTag;
|
||||
use Liquid\Context;
|
||||
|
||||
/**
|
||||
* Skips the current iteration of the current loop
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* {% for i in (1..5) %}
|
||||
* {% if i == 4 %}
|
||||
* {% continue %}
|
||||
* {% endif %}
|
||||
* {{ i }}
|
||||
* {% endfor %}
|
||||
*/
|
||||
class TagContinue extends AbstractTag
|
||||
{
|
||||
/**
|
||||
* Renders the tag
|
||||
*
|
||||
* @param Context $context
|
||||
*
|
||||
* @return string|void
|
||||
*/
|
||||
public function render(Context $context)
|
||||
{
|
||||
$context->registers['continue'] = true;
|
||||
}
|
||||
}
|
||||
130
package/vendor/liquid/liquid/src/Liquid/Tag/TagCycle.php
vendored
Normal file
130
package/vendor/liquid/liquid/src/Liquid/Tag/TagCycle.php
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Tag;
|
||||
|
||||
use Liquid\AbstractTag;
|
||||
use Liquid\Exception\ParseException;
|
||||
use Liquid\Liquid;
|
||||
use Liquid\Context;
|
||||
use Liquid\Regexp;
|
||||
use Liquid\Variable;
|
||||
use Liquid\FileSystem;
|
||||
|
||||
/**
|
||||
* Cycles between a list of values; calls to the tag will return each value in turn
|
||||
*
|
||||
* Example:
|
||||
* {%cycle "one", "two"%} {%cycle "one", "two"%} {%cycle "one", "two"%}
|
||||
*
|
||||
* this will return:
|
||||
* one two one
|
||||
*
|
||||
* Cycles can also be named, to differentiate between multiple cycle with the same values:
|
||||
* {%cycle 1: "one", "two" %} {%cycle 2: "one", "two" %} {%cycle 1: "one", "two" %} {%cycle 2: "one", "two" %}
|
||||
*
|
||||
* will return
|
||||
* one one two two
|
||||
*/
|
||||
class TagCycle extends AbstractTag
|
||||
{
|
||||
/**
|
||||
* @var string The name of the cycle; if none is given one is created using the value list
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* @var Variable[] The variables to cycle between
|
||||
*/
|
||||
private $variables = array();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $markup
|
||||
* @param array $tokens
|
||||
* @param FileSystem $fileSystem
|
||||
*
|
||||
* @throws \Liquid\Exception\ParseException
|
||||
*/
|
||||
public function __construct($markup, array &$tokens, FileSystem $fileSystem = null)
|
||||
{
|
||||
$simpleSyntax = new Regexp("/" . Liquid::get('QUOTED_FRAGMENT') . "/");
|
||||
$namedSyntax = new Regexp("/(" . Liquid::get('QUOTED_FRAGMENT') . ")\s*\:\s*(.*)/");
|
||||
|
||||
if ($namedSyntax->match($markup)) {
|
||||
$this->variables = $this->variablesFromString($namedSyntax->matches[2]);
|
||||
$this->name = $namedSyntax->matches[1];
|
||||
} elseif ($simpleSyntax->match($markup)) {
|
||||
$this->variables = $this->variablesFromString($markup);
|
||||
$this->name = "'" . implode($this->variables) . "'";
|
||||
} else {
|
||||
throw new ParseException("Syntax Error in 'cycle' - Valid syntax: cycle [name :] var [, var2, var3 ...]");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the tag
|
||||
*
|
||||
* @var Context $context
|
||||
* @return string
|
||||
*/
|
||||
public function render(Context $context)
|
||||
{
|
||||
$context->push();
|
||||
|
||||
$key = $context->get($this->name);
|
||||
|
||||
if (isset($context->registers['cycle'][$key])) {
|
||||
$iteration = $context->registers['cycle'][$key];
|
||||
} else {
|
||||
$iteration = 0;
|
||||
}
|
||||
|
||||
$result = $context->get($this->variables[$iteration]);
|
||||
|
||||
$iteration += 1;
|
||||
|
||||
if ($iteration >= count($this->variables)) {
|
||||
$iteration = 0;
|
||||
}
|
||||
|
||||
$context->registers['cycle'][$key] = $iteration;
|
||||
|
||||
$context->pop();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract variables from a string of markup
|
||||
*
|
||||
* @param string $markup
|
||||
*
|
||||
* @return array;
|
||||
*/
|
||||
private function variablesFromString($markup)
|
||||
{
|
||||
$regexp = new Regexp('/\s*(' . Liquid::get('QUOTED_FRAGMENT') . ')\s*/');
|
||||
$parts = explode(',', $markup);
|
||||
$result = array();
|
||||
|
||||
foreach ($parts as $part) {
|
||||
$regexp->match($part);
|
||||
|
||||
if (!empty($regexp->matches[1])) {
|
||||
$result[] = $regexp->matches[1];
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
83
package/vendor/liquid/liquid/src/Liquid/Tag/TagDecrement.php
vendored
Normal file
83
package/vendor/liquid/liquid/src/Liquid/Tag/TagDecrement.php
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Tag;
|
||||
|
||||
use Liquid\AbstractTag;
|
||||
use Liquid\Exception\ParseException;
|
||||
use Liquid\Liquid;
|
||||
use Liquid\Context;
|
||||
use Liquid\FileSystem;
|
||||
use Liquid\Regexp;
|
||||
|
||||
/**
|
||||
* Used to decrement a counter into a template
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* {% decrement value %}
|
||||
*
|
||||
* @author Viorel Dram
|
||||
*/
|
||||
class TagDecrement extends AbstractTag
|
||||
{
|
||||
/**
|
||||
* Name of the variable to decrement
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $toDecrement;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $markup
|
||||
* @param array $tokens
|
||||
* @param FileSystem $fileSystem
|
||||
*
|
||||
* @throws \Liquid\Exception\ParseException
|
||||
*/
|
||||
public function __construct($markup, array &$tokens, FileSystem $fileSystem = null)
|
||||
{
|
||||
$syntax = new Regexp('/(' . Liquid::get('VARIABLE_NAME') . ')/');
|
||||
|
||||
if ($syntax->match($markup)) {
|
||||
$this->toDecrement = $syntax->matches[0];
|
||||
} else {
|
||||
throw new ParseException("Syntax Error in 'decrement' - Valid syntax: decrement [var]");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the tag
|
||||
*
|
||||
* @param Context $context
|
||||
*
|
||||
* @return string|void
|
||||
*/
|
||||
public function render(Context $context)
|
||||
{
|
||||
// if the value is not set in the environment check to see if it
|
||||
// exists in the context, and if not set it to 0
|
||||
if (!isset($context->environments[0][$this->toDecrement])) {
|
||||
// check for a context value
|
||||
$fromContext = $context->get($this->toDecrement);
|
||||
|
||||
// we already have a value in the context
|
||||
$context->environments[0][$this->toDecrement] = (null !== $fromContext) ? $fromContext : 0;
|
||||
}
|
||||
|
||||
// decrement the environment value
|
||||
$context->environments[0][$this->toDecrement]--;
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
214
package/vendor/liquid/liquid/src/Liquid/Tag/TagExtends.php
vendored
Normal file
214
package/vendor/liquid/liquid/src/Liquid/Tag/TagExtends.php
vendored
Normal file
@@ -0,0 +1,214 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Tag;
|
||||
|
||||
use Liquid\AbstractTag;
|
||||
use Liquid\Document;
|
||||
use Liquid\Exception\MissingFilesystemException;
|
||||
use Liquid\Exception\ParseException;
|
||||
use Liquid\Liquid;
|
||||
use Liquid\Context;
|
||||
use Liquid\FileSystem;
|
||||
use Liquid\Regexp;
|
||||
use Liquid\Template;
|
||||
|
||||
/**
|
||||
* Extends a template by another one.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* {% extends "base" %}
|
||||
*/
|
||||
class TagExtends extends AbstractTag
|
||||
{
|
||||
/**
|
||||
* @var string The name of the template
|
||||
*/
|
||||
private $templateName;
|
||||
|
||||
/**
|
||||
* @var Document The Document that represents the included template
|
||||
*/
|
||||
private $document;
|
||||
|
||||
/**
|
||||
* @var string The Source Hash
|
||||
*/
|
||||
protected $hash;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $markup
|
||||
* @param array $tokens
|
||||
* @param FileSystem $fileSystem
|
||||
*
|
||||
* @throws \Liquid\Exception\ParseException
|
||||
*/
|
||||
public function __construct($markup, array &$tokens, FileSystem $fileSystem = null)
|
||||
{
|
||||
$regex = new Regexp('/("[^"]+"|\'[^\']+\')?/');
|
||||
|
||||
if ($regex->match($markup) && isset($regex->matches[1])) {
|
||||
$this->templateName = substr($regex->matches[1], 1, strlen($regex->matches[1]) - 2);
|
||||
} else {
|
||||
throw new ParseException("Error in tag 'extends' - Valid syntax: extends '[template name]'");
|
||||
}
|
||||
|
||||
parent::__construct($markup, $tokens, $fileSystem);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $tokens
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function findBlocks(array $tokens)
|
||||
{
|
||||
$blockstartRegexp = new Regexp('/^' . Liquid::get('TAG_START') . '\s*block (\w+)\s*(.*)?' . Liquid::get('TAG_END') . '$/');
|
||||
$blockendRegexp = new Regexp('/^' . Liquid::get('TAG_START') . '\s*endblock\s*?' . Liquid::get('TAG_END') . '$/');
|
||||
|
||||
$b = array();
|
||||
$name = null;
|
||||
|
||||
foreach ($tokens as $token) {
|
||||
if ($blockstartRegexp->match($token)) {
|
||||
$name = $blockstartRegexp->matches[1];
|
||||
$b[$name] = array();
|
||||
} elseif ($blockendRegexp->match($token)) {
|
||||
$name = null;
|
||||
} else {
|
||||
if ($name !== null) {
|
||||
array_push($b[$name], $token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the tokens
|
||||
*
|
||||
* @param array $tokens
|
||||
*
|
||||
* @throws \Liquid\Exception\MissingFilesystemException
|
||||
*/
|
||||
public function parse(array &$tokens)
|
||||
{
|
||||
if ($this->fileSystem === null) {
|
||||
throw new MissingFilesystemException("No file system");
|
||||
}
|
||||
|
||||
// read the source of the template and create a new sub document
|
||||
$source = $this->fileSystem->readTemplateFile($this->templateName);
|
||||
|
||||
// tokens in this new document
|
||||
$maintokens = Template::tokenize($source);
|
||||
|
||||
$eRegexp = new Regexp('/^' . Liquid::get('TAG_START') . '\s*extends (.*)?' . Liquid::get('TAG_END') . '$/');
|
||||
foreach ($maintokens as $maintoken) {
|
||||
if ($eRegexp->match($maintoken)) {
|
||||
$m = $eRegexp->matches[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($m)) {
|
||||
$rest = array_merge($maintokens, $tokens);
|
||||
} else {
|
||||
$childtokens = $this->findBlocks($tokens);
|
||||
|
||||
$blockstartRegexp = new Regexp('/^' . Liquid::get('TAG_START') . '\s*block (\w+)\s*(.*)?' . Liquid::get('TAG_END') . '$/');
|
||||
$blockendRegexp = new Regexp('/^' . Liquid::get('TAG_START') . '\s*endblock\s*?' . Liquid::get('TAG_END') . '$/');
|
||||
|
||||
$name = null;
|
||||
|
||||
$rest = array();
|
||||
$keep = false;
|
||||
|
||||
for ($i = 0; $i < count($maintokens); $i++) {
|
||||
if ($blockstartRegexp->match($maintokens[$i])) {
|
||||
$name = $blockstartRegexp->matches[1];
|
||||
|
||||
if (isset($childtokens[$name])) {
|
||||
$keep = true;
|
||||
array_push($rest, $maintokens[$i]);
|
||||
foreach ($childtokens[$name] as $item) {
|
||||
array_push($rest, $item);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$keep) {
|
||||
array_push($rest, $maintokens[$i]);
|
||||
}
|
||||
|
||||
if ($blockendRegexp->match($maintokens[$i]) && $keep === true) {
|
||||
$keep = false;
|
||||
array_push($rest, $maintokens[$i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$cache = Template::getCache();
|
||||
|
||||
if (!$cache) {
|
||||
$this->document = new Document($rest, $this->fileSystem);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->hash = md5($source);
|
||||
|
||||
$this->document = $cache->read($this->hash);
|
||||
|
||||
if ($this->document == false || $this->document->hasIncludes() == true) {
|
||||
$this->document = new Document($rest, $this->fileSystem);
|
||||
$cache->write($this->hash, $this->document);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for cached includes; if there are - do not use cache
|
||||
*
|
||||
* @see Document::hasIncludes()
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasIncludes()
|
||||
{
|
||||
if ($this->document->hasIncludes() == true) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$source = $this->fileSystem->readTemplateFile($this->templateName);
|
||||
|
||||
if (Template::getCache()->exists(md5($source)) && $this->hash === md5($source)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the node
|
||||
*
|
||||
* @param Context $context
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render(Context $context)
|
||||
{
|
||||
$context->push();
|
||||
$result = $this->document->render($context);
|
||||
$context->pop();
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
236
package/vendor/liquid/liquid/src/Liquid/Tag/TagFor.php
vendored
Normal file
236
package/vendor/liquid/liquid/src/Liquid/Tag/TagFor.php
vendored
Normal file
@@ -0,0 +1,236 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Tag;
|
||||
|
||||
use Liquid\AbstractBlock;
|
||||
use Liquid\Exception\ParseException;
|
||||
use Liquid\Liquid;
|
||||
use Liquid\Context;
|
||||
use Liquid\FileSystem;
|
||||
use Liquid\Regexp;
|
||||
|
||||
/**
|
||||
* Loops over an array, assigning the current value to a given variable
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* {%for item in array%} {{item}} {%endfor%}
|
||||
*
|
||||
* With an array of 1, 2, 3, 4, will return 1 2 3 4
|
||||
*
|
||||
* or
|
||||
*
|
||||
* {%for i in (1..10)%} {{i}} {%endfor%}
|
||||
* {%for i in (1..variable)%} {{i}} {%endfor%}
|
||||
*
|
||||
*/
|
||||
class TagFor extends AbstractBlock
|
||||
{
|
||||
/**
|
||||
* @var array The collection to loop over
|
||||
*/
|
||||
private $collectionName;
|
||||
|
||||
/**
|
||||
* @var string The variable name to assign collection elements to
|
||||
*/
|
||||
private $variableName;
|
||||
|
||||
/**
|
||||
* @var string The name of the loop, which is a compound of the collection and variable names
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* @var string The type of the loop (collection or digit)
|
||||
*/
|
||||
private $type = 'collection';
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $markup
|
||||
* @param array $tokens
|
||||
* @param FileSystem $fileSystem
|
||||
*
|
||||
* @throws \Liquid\Exception\ParseException
|
||||
*/
|
||||
public function __construct($markup, array &$tokens, FileSystem $fileSystem = null)
|
||||
{
|
||||
parent::__construct($markup, $tokens, $fileSystem);
|
||||
|
||||
$syntaxRegexp = new Regexp('/(\w+)\s+in\s+(' . Liquid::get('VARIABLE_NAME') . ')/');
|
||||
|
||||
if ($syntaxRegexp->match($markup)) {
|
||||
$this->variableName = $syntaxRegexp->matches[1];
|
||||
$this->collectionName = $syntaxRegexp->matches[2];
|
||||
$this->name = $syntaxRegexp->matches[1] . '-' . $syntaxRegexp->matches[2];
|
||||
$this->extractAttributes($markup);
|
||||
} else {
|
||||
$syntaxRegexp = new Regexp('/(\w+)\s+in\s+\((\d+|' . Liquid::get('VARIABLE_NAME') . ')\s*\.\.\s*(\d+|' . Liquid::get('VARIABLE_NAME') . ')\)/');
|
||||
if ($syntaxRegexp->match($markup)) {
|
||||
$this->type = 'digit';
|
||||
$this->variableName = $syntaxRegexp->matches[1];
|
||||
$this->start = $syntaxRegexp->matches[2];
|
||||
$this->collectionName = $syntaxRegexp->matches[3];
|
||||
$this->name = $syntaxRegexp->matches[1].'-digit';
|
||||
$this->extractAttributes($markup);
|
||||
} else {
|
||||
throw new ParseException("Syntax Error in 'for loop' - Valid syntax: for [item] in [collection]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the tag
|
||||
*
|
||||
* @param Context $context
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function render(Context $context)
|
||||
{
|
||||
if (!isset($context->registers['for'])) {
|
||||
$context->registers['for'] = array();
|
||||
}
|
||||
|
||||
if ($this->type == 'digit') {
|
||||
return $this->renderDigit($context);
|
||||
}
|
||||
|
||||
// that's the default
|
||||
return $this->renderCollection($context);
|
||||
}
|
||||
|
||||
private function renderCollection(Context $context)
|
||||
{
|
||||
$collection = $context->get($this->collectionName);
|
||||
|
||||
if ($collection instanceof \Generator && !$collection->valid()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($collection instanceof \Traversable) {
|
||||
$collection = iterator_to_array($collection);
|
||||
}
|
||||
|
||||
if (is_null($collection) || !is_array($collection) || count($collection) == 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$range = array(0, count($collection));
|
||||
|
||||
if (isset($this->attributes['limit']) || isset($this->attributes['offset'])) {
|
||||
$offset = 0;
|
||||
|
||||
if (isset($this->attributes['offset'])) {
|
||||
$offset = ($this->attributes['offset'] == 'continue') ? $context->registers['for'][$this->name] : $context->get($this->attributes['offset']);
|
||||
}
|
||||
|
||||
$limit = (isset($this->attributes['limit'])) ? $context->get($this->attributes['limit']) : null;
|
||||
$rangeEnd = $limit ? $limit : count($collection) - $offset;
|
||||
$range = array($offset, $rangeEnd);
|
||||
|
||||
$context->registers['for'][$this->name] = $rangeEnd + $offset;
|
||||
}
|
||||
|
||||
$result = '';
|
||||
$segment = array_slice($collection, $range[0], $range[1]);
|
||||
if (!count($segment)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$context->push();
|
||||
$length = count($segment);
|
||||
|
||||
$index = 0;
|
||||
foreach ($segment as $key => $item) {
|
||||
$value = is_numeric($key) ? $item : array($key, $item);
|
||||
$context->set($this->variableName, $value);
|
||||
$context->set('forloop', array(
|
||||
'name' => $this->name,
|
||||
'length' => $length,
|
||||
'index' => $index + 1,
|
||||
'index0' => $index,
|
||||
'rindex' => $length - $index,
|
||||
'rindex0' => $length - $index - 1,
|
||||
'first' => (int)($index == 0),
|
||||
'last' => (int)($index == $length - 1)
|
||||
));
|
||||
|
||||
$result .= $this->renderAll($this->nodelist, $context);
|
||||
|
||||
$index++;
|
||||
|
||||
if (isset($context->registers['break'])) {
|
||||
unset($context->registers['break']);
|
||||
break;
|
||||
}
|
||||
if (isset($context->registers['continue'])) {
|
||||
unset($context->registers['continue']);
|
||||
}
|
||||
}
|
||||
|
||||
$context->pop();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function renderDigit(Context $context)
|
||||
{
|
||||
$start = $this->start;
|
||||
if (!is_integer($this->start)) {
|
||||
$start = $context->get($this->start);
|
||||
}
|
||||
|
||||
$end = $this->collectionName;
|
||||
if (!is_integer($this->collectionName)) {
|
||||
$end = $context->get($this->collectionName);
|
||||
}
|
||||
|
||||
$range = array($start, $end);
|
||||
|
||||
$context->push();
|
||||
$result = '';
|
||||
$index = 0;
|
||||
$length = $range[1] - $range[0];
|
||||
for ($i = $range[0]; $i <= $range[1]; $i++) {
|
||||
$context->set($this->variableName, $i);
|
||||
$context->set('forloop', array(
|
||||
'name' => $this->name,
|
||||
'length' => $length,
|
||||
'index' => $index + 1,
|
||||
'index0' => $index,
|
||||
'rindex' => $length - $index,
|
||||
'rindex0' => $length - $index - 1,
|
||||
'first' => (int)($index == 0),
|
||||
'last' => (int)($index == $length - 1)
|
||||
));
|
||||
|
||||
$result .= $this->renderAll($this->nodelist, $context);
|
||||
|
||||
$index++;
|
||||
|
||||
if (isset($context->registers['break'])) {
|
||||
unset($context->registers['break']);
|
||||
break;
|
||||
}
|
||||
if (isset($context->registers['continue'])) {
|
||||
unset($context->registers['continue']);
|
||||
}
|
||||
}
|
||||
|
||||
$context->pop();
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
168
package/vendor/liquid/liquid/src/Liquid/Tag/TagIf.php
vendored
Normal file
168
package/vendor/liquid/liquid/src/Liquid/Tag/TagIf.php
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Tag;
|
||||
|
||||
use Liquid\Decision;
|
||||
use Liquid\Context;
|
||||
use Liquid\Exception\ParseException;
|
||||
use Liquid\Liquid;
|
||||
use Liquid\FileSystem;
|
||||
use Liquid\Regexp;
|
||||
|
||||
/**
|
||||
* An if statement
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* {% if true %} YES {% else %} NO {% endif %}
|
||||
*
|
||||
* will return:
|
||||
* YES
|
||||
*/
|
||||
class TagIf extends Decision
|
||||
{
|
||||
/**
|
||||
* Array holding the nodes to render for each logical block
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $nodelistHolders = array();
|
||||
|
||||
/**
|
||||
* Array holding the block type, block markup (conditions) and block nodelist
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $blocks = array();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $markup
|
||||
* @param array $tokens
|
||||
* @param FileSystem $fileSystem
|
||||
*/
|
||||
public function __construct($markup, array &$tokens, FileSystem $fileSystem = null)
|
||||
{
|
||||
$this->nodelist = & $this->nodelistHolders[count($this->blocks)];
|
||||
|
||||
array_push($this->blocks, array('if', $markup, &$this->nodelist));
|
||||
|
||||
parent::__construct($markup, $tokens, $fileSystem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for unknown tags, handle else tags
|
||||
*
|
||||
* @param string $tag
|
||||
* @param array $params
|
||||
* @param array $tokens
|
||||
*/
|
||||
public function unknownTag($tag, $params, array $tokens)
|
||||
{
|
||||
if ($tag == 'else' || $tag == 'elsif') {
|
||||
// Update reference to nodelistHolder for this block
|
||||
$this->nodelist = & $this->nodelistHolders[count($this->blocks) + 1];
|
||||
$this->nodelistHolders[count($this->blocks) + 1] = array();
|
||||
|
||||
array_push($this->blocks, array($tag, $params, &$this->nodelist));
|
||||
} else {
|
||||
parent::unknownTag($tag, $params, $tokens);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the tag
|
||||
*
|
||||
* @param Context $context
|
||||
*
|
||||
* @throws \Liquid\Exception\ParseException
|
||||
* @return string
|
||||
*/
|
||||
public function render(Context $context)
|
||||
{
|
||||
$context->push();
|
||||
|
||||
$logicalRegex = new Regexp('/\s+(and|or)\s+/');
|
||||
$conditionalRegex = new Regexp('/(' . Liquid::get('QUOTED_FRAGMENT') . ')\s*([=!<>a-z_]+)?\s*(' . Liquid::get('QUOTED_FRAGMENT') . ')?/');
|
||||
|
||||
$result = '';
|
||||
foreach ($this->blocks as $block) {
|
||||
if ($block[0] == 'else') {
|
||||
$result = $this->renderAll($block[2], $context);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if ($block[0] == 'if' || $block[0] == 'elsif') {
|
||||
// Extract logical operators
|
||||
$logicalRegex->matchAll($block[1]);
|
||||
|
||||
$logicalOperators = $logicalRegex->matches;
|
||||
$logicalOperators = $logicalOperators[1];
|
||||
// Extract individual conditions
|
||||
$temp = $logicalRegex->split($block[1]);
|
||||
|
||||
$conditions = array();
|
||||
|
||||
foreach ($temp as $condition) {
|
||||
if ($conditionalRegex->match($condition)) {
|
||||
$left = (isset($conditionalRegex->matches[1])) ? $conditionalRegex->matches[1] : null;
|
||||
$operator = (isset($conditionalRegex->matches[2])) ? $conditionalRegex->matches[2] : null;
|
||||
$right = (isset($conditionalRegex->matches[3])) ? $conditionalRegex->matches[3] : null;
|
||||
|
||||
array_push($conditions, array(
|
||||
'left' => $left,
|
||||
'operator' => $operator,
|
||||
'right' => $right
|
||||
));
|
||||
} else {
|
||||
throw new ParseException("Syntax Error in tag 'if' - Valid syntax: if [condition]");
|
||||
}
|
||||
}
|
||||
if (count($logicalOperators)) {
|
||||
// If statement contains and/or
|
||||
$display = $this->interpretCondition($conditions[0]['left'], $conditions[0]['right'], $conditions[0]['operator'], $context);
|
||||
foreach ($logicalOperators as $k => $logicalOperator) {
|
||||
if ($logicalOperator == 'and') {
|
||||
$display = ($display && $this->interpretCondition($conditions[$k + 1]['left'], $conditions[$k + 1]['right'], $conditions[$k + 1]['operator'], $context));
|
||||
} else {
|
||||
$display = ($display || $this->interpretCondition($conditions[$k + 1]['left'], $conditions[$k + 1]['right'], $conditions[$k + 1]['operator'], $context));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If statement is a single condition
|
||||
$display = $this->interpretCondition($conditions[0]['left'], $conditions[0]['right'], $conditions[0]['operator'], $context);
|
||||
}
|
||||
|
||||
// hook for unless tag
|
||||
$display = $this->negateIfUnless($display);
|
||||
|
||||
if ($display) {
|
||||
$result = $this->renderAll($block[2], $context);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$context->pop();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function negateIfUnless($display)
|
||||
{
|
||||
// no need to negate a condition in a regular `if` tag (will do that in `unless` tag)
|
||||
return $display;
|
||||
}
|
||||
}
|
||||
61
package/vendor/liquid/liquid/src/Liquid/Tag/TagIfchanged.php
vendored
Normal file
61
package/vendor/liquid/liquid/src/Liquid/Tag/TagIfchanged.php
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Tag;
|
||||
|
||||
use Liquid\AbstractBlock;
|
||||
use Liquid\Context;
|
||||
use Liquid\FileSystem;
|
||||
|
||||
/**
|
||||
* Quickly create a table from a collection
|
||||
*/
|
||||
class TagIfchanged extends AbstractBlock
|
||||
{
|
||||
/**
|
||||
* The last value
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $lastValue = '';
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $markup
|
||||
* @param array $tokens
|
||||
* @param FileSystem $fileSystem
|
||||
*
|
||||
* @throws \Liquid\LiquidException
|
||||
*/
|
||||
public function __construct($markup, array &$tokens, FileSystem $fileSystem = null)
|
||||
{
|
||||
parent::__construct($markup, $tokens, $fileSystem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the block
|
||||
*
|
||||
* @param Context $context
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render(Context $context)
|
||||
{
|
||||
$output = parent::render($context);
|
||||
|
||||
if ($this->lastValue == $output) {
|
||||
return '';
|
||||
}
|
||||
$this->lastValue = $output;
|
||||
return $this->lastValue;
|
||||
}
|
||||
}
|
||||
200
package/vendor/liquid/liquid/src/Liquid/Tag/TagInclude.php
vendored
Normal file
200
package/vendor/liquid/liquid/src/Liquid/Tag/TagInclude.php
vendored
Normal file
@@ -0,0 +1,200 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Tag;
|
||||
|
||||
use Liquid\AbstractTag;
|
||||
use Liquid\Document;
|
||||
use Liquid\Context;
|
||||
use Liquid\Exception\MissingFilesystemException;
|
||||
use Liquid\Exception\ParseException;
|
||||
use Liquid\Liquid;
|
||||
use Liquid\LiquidException;
|
||||
use Liquid\FileSystem;
|
||||
use Liquid\Regexp;
|
||||
use Liquid\Template;
|
||||
|
||||
/**
|
||||
* Includes another, partial, template
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* {% include 'foo' %}
|
||||
*
|
||||
* Will include the template called 'foo'
|
||||
*
|
||||
* {% include 'foo' with 'bar' %}
|
||||
*
|
||||
* Will include the template called 'foo', with a variable called foo that will have the value of 'bar'
|
||||
*
|
||||
* {% include 'foo' for 'bar' %}
|
||||
*
|
||||
* Will loop over all the values of bar, including the template foo, passing a variable called foo
|
||||
* with each value of bar
|
||||
*/
|
||||
class TagInclude extends AbstractTag
|
||||
{
|
||||
/**
|
||||
* @var string The name of the template
|
||||
*/
|
||||
private $templateName;
|
||||
|
||||
/**
|
||||
* @var bool True if the variable is a collection
|
||||
*/
|
||||
private $collection;
|
||||
|
||||
/**
|
||||
* @var mixed The value to pass to the child template as the template name
|
||||
*/
|
||||
private $variable;
|
||||
|
||||
/**
|
||||
* @var Document The Document that represents the included template
|
||||
*/
|
||||
private $document;
|
||||
|
||||
/**
|
||||
* @var string The Source Hash
|
||||
*/
|
||||
protected $hash;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $markup
|
||||
* @param array $tokens
|
||||
* @param FileSystem $fileSystem
|
||||
*
|
||||
* @throws \Liquid\Exception\ParseException
|
||||
*/
|
||||
public function __construct($markup, array &$tokens, FileSystem $fileSystem = null)
|
||||
{
|
||||
$regex = new Regexp('/("[^"]+"|\'[^\']+\'|[^\'"\s]+)(\s+(with|for)\s+(' . Liquid::get('QUOTED_FRAGMENT') . '+))?/');
|
||||
|
||||
if (!$regex->match($markup)) {
|
||||
throw new ParseException("Error in tag 'include' - Valid syntax: include '[template]' (with|for) [object|collection]");
|
||||
}
|
||||
|
||||
$unquoted = (strpos($regex->matches[1], '"') === false && strpos($regex->matches[1], "'") === false);
|
||||
|
||||
$start = 1;
|
||||
$len = strlen($regex->matches[1]) - 2;
|
||||
|
||||
if ($unquoted) {
|
||||
$start = 0;
|
||||
$len = strlen($regex->matches[1]);
|
||||
}
|
||||
|
||||
$this->templateName = substr($regex->matches[1], $start, $len);
|
||||
|
||||
if (isset($regex->matches[1])) {
|
||||
$this->collection = (isset($regex->matches[3])) ? ($regex->matches[3] == "for") : null;
|
||||
$this->variable = (isset($regex->matches[4])) ? $regex->matches[4] : null;
|
||||
}
|
||||
|
||||
$this->extractAttributes($markup);
|
||||
|
||||
parent::__construct($markup, $tokens, $fileSystem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the tokens
|
||||
*
|
||||
* @param array $tokens
|
||||
*
|
||||
* @throws \Liquid\Exception\MissingFilesystemException
|
||||
*/
|
||||
public function parse(array &$tokens)
|
||||
{
|
||||
if ($this->fileSystem === null) {
|
||||
throw new MissingFilesystemException("No file system");
|
||||
}
|
||||
|
||||
// read the source of the template and create a new sub document
|
||||
$source = $this->fileSystem->readTemplateFile($this->templateName);
|
||||
|
||||
$cache = Template::getCache();
|
||||
|
||||
if (!$cache) {
|
||||
// tokens in this new document
|
||||
$templateTokens = Template::tokenize($source);
|
||||
$this->document = new Document($templateTokens, $this->fileSystem);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->hash = md5($source);
|
||||
$this->document = $cache->read($this->hash);
|
||||
|
||||
if ($this->document == false || $this->document->hasIncludes() == true) {
|
||||
$templateTokens = Template::tokenize($source);
|
||||
$this->document = new Document($templateTokens, $this->fileSystem);
|
||||
$cache->write($this->hash, $this->document);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for cached includes; if there are - do not use cache
|
||||
*
|
||||
* @see Document::hasIncludes()
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasIncludes()
|
||||
{
|
||||
if ($this->document->hasIncludes() == true) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$source = $this->fileSystem->readTemplateFile($this->templateName);
|
||||
|
||||
if (Template::getCache()->exists(md5($source)) && $this->hash === md5($source)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the node
|
||||
*
|
||||
* @param Context $context
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render(Context $context)
|
||||
{
|
||||
$result = '';
|
||||
$variable = $context->get($this->variable);
|
||||
|
||||
$context->push();
|
||||
|
||||
foreach ($this->attributes as $key => $value) {
|
||||
$context->set($key, $context->get($value));
|
||||
}
|
||||
|
||||
if ($this->collection) {
|
||||
foreach ($variable as $item) {
|
||||
$context->set($this->templateName, $item);
|
||||
$result .= $this->document->render($context);
|
||||
}
|
||||
} else {
|
||||
if (!is_null($this->variable)) {
|
||||
$context->set($this->templateName, $variable);
|
||||
}
|
||||
|
||||
$result .= $this->document->render($context);
|
||||
}
|
||||
|
||||
$context->pop();
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
83
package/vendor/liquid/liquid/src/Liquid/Tag/TagIncrement.php
vendored
Normal file
83
package/vendor/liquid/liquid/src/Liquid/Tag/TagIncrement.php
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Tag;
|
||||
|
||||
use Liquid\AbstractTag;
|
||||
use Liquid\Exception\ParseException;
|
||||
use Liquid\Liquid;
|
||||
use Liquid\Context;
|
||||
use Liquid\FileSystem;
|
||||
use Liquid\Regexp;
|
||||
|
||||
/**
|
||||
* Used to increment a counter into a template
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* {% increment value %}
|
||||
*
|
||||
* @author Viorel Dram
|
||||
*/
|
||||
class TagIncrement extends AbstractTag
|
||||
{
|
||||
/**
|
||||
* Name of the variable to increment
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $toIncrement;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $markup
|
||||
* @param array $tokens
|
||||
* @param FileSystem $fileSystem
|
||||
*
|
||||
* @throws \Liquid\Exception\ParseException
|
||||
*/
|
||||
public function __construct($markup, array &$tokens, FileSystem $fileSystem = null)
|
||||
{
|
||||
$syntax = new Regexp('/(' . Liquid::get('VARIABLE_NAME') . ')/');
|
||||
|
||||
if ($syntax->match($markup)) {
|
||||
$this->toIncrement = $syntax->matches[0];
|
||||
} else {
|
||||
throw new ParseException("Syntax Error in 'increment' - Valid syntax: increment [var]");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the tag
|
||||
*
|
||||
* @param Context $context
|
||||
*
|
||||
* @return string|void
|
||||
*/
|
||||
public function render(Context $context)
|
||||
{
|
||||
// If the value is not set in the environment check to see if it
|
||||
// exists in the context, and if not set it to -1
|
||||
if (!isset($context->environments[0][$this->toIncrement])) {
|
||||
// check for a context value
|
||||
$from_context = $context->get($this->toIncrement);
|
||||
|
||||
// we already have a value in the context
|
||||
$context->environments[0][$this->toIncrement] = (null !== $from_context) ? $from_context : -1;
|
||||
}
|
||||
|
||||
// Increment the value
|
||||
$context->environments[0][$this->toIncrement]++;
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
206
package/vendor/liquid/liquid/src/Liquid/Tag/TagPaginate.php
vendored
Normal file
206
package/vendor/liquid/liquid/src/Liquid/Tag/TagPaginate.php
vendored
Normal file
@@ -0,0 +1,206 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Tag;
|
||||
|
||||
use Liquid\AbstractBlock;
|
||||
use Liquid\Exception\ParseException;
|
||||
use Liquid\Liquid;
|
||||
use Liquid\Context;
|
||||
use Liquid\FileSystem;
|
||||
use Liquid\Regexp;
|
||||
use Liquid\Exception\RenderException;
|
||||
|
||||
/**
|
||||
* The paginate tag works in conjunction with the for tag to split content into numerous pages.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* {% paginate collection.products by 5 %}
|
||||
* {% for product in collection.products %}
|
||||
* <!--show product details here -->
|
||||
* {% endfor %}
|
||||
* {% endpaginate %}
|
||||
*
|
||||
*/
|
||||
|
||||
class TagPaginate extends AbstractBlock
|
||||
{
|
||||
/**
|
||||
* @var array The collection to paginate
|
||||
*/
|
||||
private $collectionName;
|
||||
|
||||
/**
|
||||
* @var array The collection object
|
||||
*/
|
||||
private $collection;
|
||||
|
||||
/**
|
||||
* @var int The size of the collection
|
||||
*/
|
||||
private $collectionSize;
|
||||
|
||||
/**
|
||||
* @var int The number of items to paginate by
|
||||
*/
|
||||
private $numberItems;
|
||||
|
||||
/**
|
||||
* @var int The current page
|
||||
*/
|
||||
private $currentPage;
|
||||
|
||||
/**
|
||||
* @var int The current offset (no of pages times no of items)
|
||||
*/
|
||||
private $currentOffset;
|
||||
|
||||
/**
|
||||
* @var int Total pages
|
||||
*/
|
||||
private $totalPages;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $markup
|
||||
* @param array $tokens
|
||||
* @param FileSystem $fileSystem
|
||||
*
|
||||
* @throws \Liquid\Exception\ParseException
|
||||
*
|
||||
*/
|
||||
public function __construct($markup, array &$tokens, FileSystem $fileSystem = null)
|
||||
{
|
||||
parent::__construct($markup, $tokens, $fileSystem);
|
||||
|
||||
$syntax = new Regexp('/(' . Liquid::get('VARIABLE_NAME') . ')\s+by\s+(\w+)/');
|
||||
|
||||
if ($syntax->match($markup)) {
|
||||
$this->collectionName = $syntax->matches[1];
|
||||
$this->numberItems = $syntax->matches[2];
|
||||
$this->extractAttributes($markup);
|
||||
} else {
|
||||
throw new ParseException("Syntax Error - Valid syntax: paginate [collection] by [items]");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the tag
|
||||
*
|
||||
* @param Context $context
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
public function render(Context $context)
|
||||
{
|
||||
$this->collection = $context->get($this->collectionName);
|
||||
|
||||
if ($this->collection instanceof \Traversable) {
|
||||
$this->collection = iterator_to_array($this->collection);
|
||||
}
|
||||
|
||||
if (!is_array($this->collection)) {
|
||||
// TODO do not throw up if error mode allows, see #83
|
||||
throw new RenderException("Missing collection with name '{$this->collectionName}'");
|
||||
}
|
||||
|
||||
// How many pages are there?
|
||||
$this->collectionSize = count($this->collection);
|
||||
$this->totalPages = ceil($this->collectionSize / $this->numberItems);
|
||||
|
||||
// Whatever there is in the context, we need a number
|
||||
$this->currentPage = intval($context->get(Liquid::get('PAGINATION_CONTEXT_KEY')));
|
||||
|
||||
// Page number can only be between 1 and a number of pages
|
||||
$this->currentPage = max(1, min($this->currentPage, $this->totalPages));
|
||||
|
||||
// Find the offset and select that part
|
||||
$this->currentOffset = ($this->currentPage - 1) * $this->numberItems;
|
||||
$paginatedCollection = array_slice($this->collection, $this->currentOffset, $this->numberItems);
|
||||
|
||||
// We must work in a new scope so we won't pollute a global scope
|
||||
$context->push();
|
||||
|
||||
// Sets the collection if it's a key of another collection (ie search.results, collection.products, blog.articles)
|
||||
$segments = explode('.', $this->collectionName);
|
||||
if (count($segments) == 2) {
|
||||
$context->set($segments[0], array($segments[1] => $paginatedCollection));
|
||||
} else {
|
||||
$context->set($this->collectionName, $paginatedCollection);
|
||||
}
|
||||
|
||||
$paginate = array(
|
||||
'page_size' => $this->numberItems,
|
||||
'current_page' => $this->currentPage,
|
||||
'current_offset' => $this->currentOffset,
|
||||
'pages' => $this->totalPages,
|
||||
'items' => $this->collectionSize
|
||||
);
|
||||
|
||||
// Get the name of the request field to use in URLs
|
||||
$pageRequestKey = Liquid::get('PAGINATION_REQUEST_KEY');
|
||||
|
||||
if ($this->currentPage > 1) {
|
||||
$paginate['previous']['title'] = 'Previous';
|
||||
$paginate['previous']['url'] = $this->currentUrl($context, [
|
||||
$pageRequestKey => $this->currentPage - 1,
|
||||
]);
|
||||
}
|
||||
|
||||
if ($this->currentPage < $this->totalPages) {
|
||||
$paginate['next']['title'] = 'Next';
|
||||
$paginate['next']['url'] = $this->currentUrl($context, [
|
||||
$pageRequestKey => $this->currentPage + 1,
|
||||
]);
|
||||
}
|
||||
|
||||
$context->set('paginate', $paginate);
|
||||
|
||||
$result = parent::render($context);
|
||||
|
||||
$context->pop();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current page URL
|
||||
*
|
||||
* @param Context $context
|
||||
* @param array $queryPart
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
public function currentUrl($context, $queryPart = [])
|
||||
{
|
||||
// From here we have $url->path and $url->query
|
||||
$url = (object) parse_url($context->get('REQUEST_URI'));
|
||||
|
||||
// Let's merge the query part
|
||||
if (isset($url->query)) {
|
||||
parse_str($url->query, $url->query);
|
||||
$url->query = array_merge($url->query, $queryPart);
|
||||
} else {
|
||||
$url->query = $queryPart;
|
||||
}
|
||||
|
||||
$url->query = http_build_query($url->query);
|
||||
|
||||
$scheme = $context->get('HTTPS') == 'on' ? 'https' : 'http';
|
||||
|
||||
return "$scheme://{$context->get('HTTP_HOST')}{$url->path}?{$url->query}";
|
||||
}
|
||||
}
|
||||
52
package/vendor/liquid/liquid/src/Liquid/Tag/TagRaw.php
vendored
Normal file
52
package/vendor/liquid/liquid/src/Liquid/Tag/TagRaw.php
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Tag;
|
||||
|
||||
use Liquid\Liquid;
|
||||
use Liquid\AbstractBlock;
|
||||
use Liquid\Regexp;
|
||||
|
||||
/**
|
||||
* Allows output of Liquid code on a page without being parsed.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* {% raw %}{{ 5 | plus: 6 }}{% endraw %} is equal to 11.
|
||||
*
|
||||
* will return:
|
||||
* {{ 5 | plus: 6 }} is equal to 11.
|
||||
*/
|
||||
class TagRaw extends AbstractBlock
|
||||
{
|
||||
/**
|
||||
* @param array $tokens
|
||||
*/
|
||||
public function parse(array &$tokens)
|
||||
{
|
||||
$tagRegexp = new Regexp('/^' . Liquid::get('TAG_START') . '\s*(\w+)\s*(.*)?' . Liquid::get('TAG_END') . '$/');
|
||||
|
||||
$this->nodelist = array();
|
||||
|
||||
while (count($tokens)) {
|
||||
$token = array_shift($tokens);
|
||||
|
||||
if ($tagRegexp->match($token)) {
|
||||
// If we found the proper block delimiter just end parsing here and let the outer block proceed
|
||||
if ($tagRegexp->matches[1] == $this->blockDelimiter()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$this->nodelist[] = $token;
|
||||
}
|
||||
}
|
||||
}
|
||||
152
package/vendor/liquid/liquid/src/Liquid/Tag/TagTablerow.php
vendored
Normal file
152
package/vendor/liquid/liquid/src/Liquid/Tag/TagTablerow.php
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Tag;
|
||||
|
||||
use Liquid\AbstractBlock;
|
||||
use Liquid\Exception\ParseException;
|
||||
use Liquid\Exception\RenderException;
|
||||
use Liquid\Liquid;
|
||||
use Liquid\Context;
|
||||
use Liquid\FileSystem;
|
||||
use Liquid\Regexp;
|
||||
|
||||
/**
|
||||
* Quickly create a table from a collection
|
||||
*/
|
||||
class TagTablerow extends AbstractBlock
|
||||
{
|
||||
/**
|
||||
* The variable name of the table tag
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $variableName;
|
||||
|
||||
/**
|
||||
* The collection name of the table tags
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $collectionName;
|
||||
|
||||
/**
|
||||
* Additional attributes
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $attributes;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $markup
|
||||
* @param array $tokens
|
||||
* @param FileSystem $fileSystem
|
||||
*
|
||||
* @throws \Liquid\Exception\ParseException
|
||||
*/
|
||||
public function __construct($markup, array &$tokens, FileSystem $fileSystem = null)
|
||||
{
|
||||
parent::__construct($markup, $tokens, $fileSystem);
|
||||
|
||||
$syntax = new Regexp('/(\w+)\s+in\s+(' . Liquid::get('VARIABLE_NAME') . ')/');
|
||||
|
||||
if ($syntax->match($markup)) {
|
||||
$this->variableName = $syntax->matches[1];
|
||||
$this->collectionName = $syntax->matches[2];
|
||||
|
||||
$this->extractAttributes($markup);
|
||||
} else {
|
||||
throw new ParseException("Syntax Error in 'table_row loop' - Valid syntax: table_row [item] in [collection] cols:3");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the current node
|
||||
*
|
||||
* @param Context $context
|
||||
* @throws \Liquid\Exception\RenderException
|
||||
* @return string
|
||||
*/
|
||||
public function render(Context $context)
|
||||
{
|
||||
$collection = $context->get($this->collectionName);
|
||||
|
||||
if ($collection instanceof \Traversable) {
|
||||
$collection = iterator_to_array($collection);
|
||||
}
|
||||
|
||||
if (!is_array($collection)) {
|
||||
throw new RenderException("Not an array");
|
||||
}
|
||||
|
||||
// discard keys
|
||||
$collection = array_values($collection);
|
||||
|
||||
if (isset($this->attributes['limit']) || isset($this->attributes['offset'])) {
|
||||
$limit = $context->get($this->attributes['limit']);
|
||||
$offset = $context->get($this->attributes['offset']);
|
||||
$collection = array_slice($collection, $offset, $limit);
|
||||
}
|
||||
|
||||
$length = count($collection);
|
||||
|
||||
$cols = isset($this->attributes['cols']) ? $context->get($this->attributes['cols']) : PHP_INT_MAX;
|
||||
|
||||
$row = 1;
|
||||
$col = 0;
|
||||
|
||||
$result = "<tr class=\"row1\">\n";
|
||||
|
||||
$context->push();
|
||||
|
||||
foreach ($collection as $index => $item) {
|
||||
$context->set($this->variableName, $item);
|
||||
$context->set('tablerowloop', array(
|
||||
'length' => $length,
|
||||
'index' => $index + 1,
|
||||
'index0' => $index,
|
||||
'rindex' => $length - $index,
|
||||
'rindex0' => $length - $index - 1,
|
||||
'first' => (int)($index == 0),
|
||||
'last' => (int)($index == $length - 1)
|
||||
));
|
||||
|
||||
$text = $this->renderAll($this->nodelist, $context);
|
||||
$break = isset($context->registers['break']);
|
||||
$continue = isset($context->registers['continue']);
|
||||
|
||||
if ((!$break && !$continue) || strlen(trim($text)) > 0) {
|
||||
$result .= "<td class=\"col" . (++$col) . "\">$text</td>";
|
||||
}
|
||||
|
||||
if ($col == $cols && !($index == $length - 1)) {
|
||||
$col = 0;
|
||||
$result .= "</tr>\n<tr class=\"row" . (++$row) . "\">\n";
|
||||
}
|
||||
|
||||
if ($break) {
|
||||
unset($context->registers['break']);
|
||||
break;
|
||||
}
|
||||
if ($continue) {
|
||||
unset($context->registers['continue']);
|
||||
}
|
||||
}
|
||||
|
||||
$context->pop();
|
||||
|
||||
$result .= "</tr>\n";
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
31
package/vendor/liquid/liquid/src/Liquid/Tag/TagUnless.php
vendored
Normal file
31
package/vendor/liquid/liquid/src/Liquid/Tag/TagUnless.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Tag;
|
||||
|
||||
/**
|
||||
* An if statement
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* {% unless true %} YES {% else %} NO {% endunless %}
|
||||
*
|
||||
* will return:
|
||||
* NO
|
||||
*/
|
||||
|
||||
class TagUnless extends TagIf
|
||||
{
|
||||
protected function negateIfUnless($display)
|
||||
{
|
||||
return !$display;
|
||||
}
|
||||
}
|
||||
270
package/vendor/liquid/liquid/src/Liquid/Template.php
vendored
Normal file
270
package/vendor/liquid/liquid/src/Liquid/Template.php
vendored
Normal file
@@ -0,0 +1,270 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid;
|
||||
|
||||
use Liquid\Exception\CacheException;
|
||||
use Liquid\Exception\MissingFilesystemException;
|
||||
|
||||
/**
|
||||
* The Template class.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* $tpl = new \Liquid\Template();
|
||||
* $tpl->parse(template_source);
|
||||
* $tpl->render(array('foo'=>1, 'bar'=>2);
|
||||
*/
|
||||
class Template
|
||||
{
|
||||
const CLASS_PREFIX = '\Liquid\Cache\\';
|
||||
|
||||
/**
|
||||
* @var Document The root of the node tree
|
||||
*/
|
||||
private $root;
|
||||
|
||||
/**
|
||||
* @var FileSystem The file system to use for includes
|
||||
*/
|
||||
private $fileSystem;
|
||||
|
||||
/**
|
||||
* @var array Globally included filters
|
||||
*/
|
||||
private $filters = array();
|
||||
|
||||
/**
|
||||
* @var callable|null Called "sometimes" while rendering. For example to abort the execution of a rendering.
|
||||
*/
|
||||
private $tickFunction = null;
|
||||
|
||||
/**
|
||||
* @var array Custom tags
|
||||
*/
|
||||
private static $tags = array();
|
||||
|
||||
/**
|
||||
* @var Cache
|
||||
*/
|
||||
private static $cache;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $path
|
||||
* @param array|Cache $cache
|
||||
*
|
||||
* @return Template
|
||||
*/
|
||||
public function __construct($path = null, $cache = null)
|
||||
{
|
||||
$this->fileSystem = $path !== null
|
||||
? new LocalFileSystem($path)
|
||||
: null;
|
||||
|
||||
$this->setCache($cache);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FileSystem $fileSystem
|
||||
*/
|
||||
public function setFileSystem(FileSystem $fileSystem)
|
||||
{
|
||||
$this->fileSystem = $fileSystem;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|Cache $cache
|
||||
*
|
||||
* @throws \Liquid\Exception\CacheException
|
||||
*/
|
||||
public static function setCache($cache)
|
||||
{
|
||||
if (is_array($cache)) {
|
||||
if (isset($cache['cache']) && class_exists($classname = self::CLASS_PREFIX . ucwords($cache['cache']))) {
|
||||
self::$cache = new $classname($cache);
|
||||
} else {
|
||||
throw new CacheException('Invalid cache options!');
|
||||
}
|
||||
}
|
||||
|
||||
if ($cache instanceof Cache) {
|
||||
self::$cache = $cache;
|
||||
}
|
||||
|
||||
if (is_null($cache)) {
|
||||
self::$cache = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Cache
|
||||
*/
|
||||
public static function getCache()
|
||||
{
|
||||
return self::$cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Document
|
||||
*/
|
||||
public function getRoot()
|
||||
{
|
||||
return $this->root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register custom Tags
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $class
|
||||
*/
|
||||
public static function registerTag($name, $class)
|
||||
{
|
||||
self::$tags[$name] = $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getTags()
|
||||
{
|
||||
return self::$tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the filter
|
||||
*
|
||||
* @param string $filter
|
||||
*/
|
||||
public function registerFilter($filter, callable $callback = null)
|
||||
{
|
||||
// Store callback for later use
|
||||
if ($callback) {
|
||||
$this->filters[] = [$filter, $callback];
|
||||
} else {
|
||||
$this->filters[] = $filter;
|
||||
}
|
||||
}
|
||||
|
||||
public function setTickFunction(callable $tickFunction)
|
||||
{
|
||||
$this->tickFunction = $tickFunction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tokenizes the given source string
|
||||
*
|
||||
* @param string $source
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function tokenize($source)
|
||||
{
|
||||
return empty($source)
|
||||
? array()
|
||||
: preg_split(Liquid::get('TOKENIZATION_REGEXP'), $source, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given source string
|
||||
*
|
||||
* @param string $source
|
||||
*
|
||||
* @return Template
|
||||
*/
|
||||
public function parse($source)
|
||||
{
|
||||
if (!self::$cache) {
|
||||
return $this->parseAlways($source);
|
||||
}
|
||||
|
||||
$hash = md5($source);
|
||||
$this->root = self::$cache->read($hash);
|
||||
|
||||
// if no cached version exists, or if it checks for includes
|
||||
if ($this->root == false || $this->root->hasIncludes() == true) {
|
||||
$this->parseAlways($source);
|
||||
self::$cache->write($hash, $this->root);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given source string regardless of caching
|
||||
*
|
||||
* @param string $source
|
||||
*
|
||||
* @return Template
|
||||
*/
|
||||
private function parseAlways($source)
|
||||
{
|
||||
$tokens = Template::tokenize($source);
|
||||
$this->root = new Document($tokens, $this->fileSystem);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given template file
|
||||
*
|
||||
* @param string $templatePath
|
||||
* @throws \Liquid\Exception\MissingFilesystemException
|
||||
* @return Template
|
||||
*/
|
||||
public function parseFile($templatePath)
|
||||
{
|
||||
if (!$this->fileSystem) {
|
||||
throw new MissingFilesystemException("Could not load a template without an initialized file system");
|
||||
}
|
||||
|
||||
return $this->parse($this->fileSystem->readTemplateFile($templatePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the current template
|
||||
*
|
||||
* @param array $assigns an array of values for the template
|
||||
* @param array $filters additional filters for the template
|
||||
* @param array $registers additional registers for the template
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render(array $assigns = array(), $filters = null, array $registers = array())
|
||||
{
|
||||
$context = new Context($assigns, $registers);
|
||||
|
||||
if ($this->tickFunction) {
|
||||
$context->setTickFunction($this->tickFunction);
|
||||
}
|
||||
|
||||
if (!is_null($filters)) {
|
||||
if (is_array($filters)) {
|
||||
$this->filters = array_merge($this->filters, $filters);
|
||||
} else {
|
||||
$this->filters[] = $filters;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->filters as $filter) {
|
||||
if (is_array($filter)) {
|
||||
// Unpack a callback saved as second argument
|
||||
$context->addFilters(...$filter);
|
||||
} else {
|
||||
$context->addFilters($filter);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->root->render($context);
|
||||
}
|
||||
}
|
||||
173
package/vendor/liquid/liquid/src/Liquid/Variable.php
vendored
Normal file
173
package/vendor/liquid/liquid/src/Liquid/Variable.php
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid;
|
||||
|
||||
/**
|
||||
* Implements a template variable.
|
||||
*/
|
||||
class Variable
|
||||
{
|
||||
/**
|
||||
* @var array The filters to execute on the variable
|
||||
*/
|
||||
private $filters;
|
||||
|
||||
/**
|
||||
* @var string The name of the variable
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* @var string The markup of the variable
|
||||
*/
|
||||
private $markup;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $markup
|
||||
*/
|
||||
public function __construct($markup)
|
||||
{
|
||||
$this->markup = $markup;
|
||||
|
||||
$filterSep = new Regexp('/' . Liquid::get('FILTER_SEPARATOR') . '\s*(.*)/m');
|
||||
$syntaxParser = new Regexp('/(' . Liquid::get('QUOTED_FRAGMENT') . ')(.*)/ms');
|
||||
$filterParser = new Regexp('/(?:\s+|' . Liquid::get('QUOTED_FRAGMENT') . '|' . Liquid::get('ARGUMENT_SEPARATOR') . ')+/');
|
||||
$filterArgsRegex = new Regexp('/(?:' . Liquid::get('FILTER_ARGUMENT_SEPARATOR') . '|' . Liquid::get('ARGUMENT_SEPARATOR') . ')\s*((?:\w+\s*\:\s*)?' . Liquid::get('QUOTED_FRAGMENT') . ')/');
|
||||
|
||||
$this->filters = [];
|
||||
if ($syntaxParser->match($markup)) {
|
||||
$nameMarkup = $syntaxParser->matches[1];
|
||||
$this->name = $nameMarkup;
|
||||
$filterMarkup = $syntaxParser->matches[2];
|
||||
|
||||
if ($filterSep->match($filterMarkup)) {
|
||||
$filterParser->matchAll($filterSep->matches[1]);
|
||||
|
||||
foreach ($filterParser->matches[0] as $filter) {
|
||||
$filter = trim($filter);
|
||||
if (preg_match('/\w+/', $filter, $matches)) {
|
||||
$filterName = $matches[0];
|
||||
$filterArgsRegex->matchAll($filter);
|
||||
$matches = Liquid::arrayFlatten($filterArgsRegex->matches[1]);
|
||||
$this->filters[] = $this->parseFilterExpressions($filterName, $matches);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Liquid::get('ESCAPE_BY_DEFAULT')) {
|
||||
// if auto_escape is enabled, and
|
||||
// - there's no raw filter, and
|
||||
// - no escape filter
|
||||
// - no other standard html-adding filter
|
||||
// then
|
||||
// - add a mandatory escape filter
|
||||
|
||||
$addEscapeFilter = true;
|
||||
|
||||
foreach ($this->filters as $filter) {
|
||||
// with empty filters set we would just move along
|
||||
if (in_array($filter[0], array('escape', 'escape_once', 'raw', 'newline_to_br'))) {
|
||||
// if we have any raw-like filter, stop
|
||||
$addEscapeFilter = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($addEscapeFilter) {
|
||||
$this->filters[] = array('escape', array());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filterName
|
||||
* @param array $unparsedArgs
|
||||
* @return array
|
||||
*/
|
||||
private static function parseFilterExpressions($filterName, array $unparsedArgs)
|
||||
{
|
||||
$filterArgs = array();
|
||||
$keywordArgs = array();
|
||||
|
||||
$justTagAttributes = new Regexp('/\A' . trim(Liquid::get('TAG_ATTRIBUTES'), '/') . '\z/');
|
||||
|
||||
foreach ($unparsedArgs as $a) {
|
||||
if ($justTagAttributes->match($a)) {
|
||||
$keywordArgs[$justTagAttributes->matches[1]] = $justTagAttributes->matches[2];
|
||||
} else {
|
||||
$filterArgs[] = $a;
|
||||
}
|
||||
}
|
||||
|
||||
if (count($keywordArgs)) {
|
||||
$filterArgs[] = $keywordArgs;
|
||||
}
|
||||
|
||||
return array($filterName, $filterArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the variable name
|
||||
*
|
||||
* @return string The name of the variable
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all Filters
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFilters()
|
||||
{
|
||||
return $this->filters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the variable with the data in the context
|
||||
*
|
||||
* @param Context $context
|
||||
*
|
||||
* @return mixed|string
|
||||
*/
|
||||
public function render(Context $context)
|
||||
{
|
||||
$output = $context->get($this->name);
|
||||
foreach ($this->filters as $filter) {
|
||||
list($filtername, $filterArgKeys) = $filter;
|
||||
|
||||
$filterArgValues = array();
|
||||
$keywordArgValues = array();
|
||||
|
||||
foreach ($filterArgKeys as $arg_key) {
|
||||
if (is_array($arg_key)) {
|
||||
foreach ($arg_key as $keywordArgName => $keywordArgKey) {
|
||||
$keywordArgValues[$keywordArgName] = $context->get($keywordArgKey);
|
||||
}
|
||||
|
||||
$filterArgValues[] = $keywordArgValues;
|
||||
} else {
|
||||
$filterArgValues[] = $context->get($arg_key);
|
||||
}
|
||||
}
|
||||
|
||||
$output = $context->invoke($filtername, $output, $filterArgValues);
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
38
package/vendor/liquid/liquid/tests/Liquid/AbstractBlockTest.php
vendored
Normal file
38
package/vendor/liquid/liquid/tests/Liquid/AbstractBlockTest.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Tag;
|
||||
|
||||
use Liquid\TestCase;
|
||||
|
||||
class AbstractBlockTest extends TestCase
|
||||
{
|
||||
public function testUnterminatedBlockError()
|
||||
{
|
||||
$this->expectException(\Liquid\Exception\ParseException::class);
|
||||
|
||||
$this->assertTemplateResult('', '{% block }');
|
||||
}
|
||||
|
||||
public function testWhitespaceHandler()
|
||||
{
|
||||
$this->assertTemplateResult('foo', '{% if true %}foo{% endif %}');
|
||||
$this->assertTemplateResult(' foo ', '{% if true %} foo {% endif %}');
|
||||
$this->assertTemplateResult(' foo ', ' {% if true %} foo {% endif %} ');
|
||||
$this->assertTemplateResult('foo ', '{% if true -%} foo {% endif %}');
|
||||
$this->assertTemplateResult('foo', '{% if true -%} foo {%- endif %}');
|
||||
$this->assertTemplateResult('foo', ' {%- if true -%} foo {%- endif %}');
|
||||
$this->assertTemplateResult('foo', ' {%- if true -%} foo {%- endif -%} ');
|
||||
$this->assertTemplateResult('foo', ' {%- if true -%} foo {%- endif -%} {%- if false -%} bar {%- endif -%} ');
|
||||
$this->assertTemplateResult('foobar', ' {%- if true -%} foo {%- endif -%} {%- if true -%} bar {%- endif -%} ');
|
||||
$this->assertTemplateResult('-> foo', '{% if true %}-> {% endif %} {%- if true -%} foo {%- endif -%}');
|
||||
}
|
||||
}
|
||||
53
package/vendor/liquid/liquid/tests/Liquid/Cache/ApcTest.php
vendored
Normal file
53
package/vendor/liquid/liquid/tests/Liquid/Cache/ApcTest.php
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Cache;
|
||||
|
||||
use Liquid\TestCase;
|
||||
|
||||
class ApcTest extends TestCase
|
||||
{
|
||||
/** @var \Liquid\Cache\Apc */
|
||||
protected $cache;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
if (!function_exists('apc_fetch')) {
|
||||
$this->markTestSkipped("Alternative PHP Cache (APC) not available");
|
||||
}
|
||||
|
||||
if (!ini_get('apc.enable_cli')) {
|
||||
$this->markTestSkipped("APC not enabled with cli. Run with: php -d apc.enable_cli=1");
|
||||
}
|
||||
|
||||
$this->cache = new Apc();
|
||||
}
|
||||
|
||||
public function testNotExists()
|
||||
{
|
||||
$this->assertFalse($this->cache->exists('no_such_key'));
|
||||
}
|
||||
|
||||
public function testReadNotExisting()
|
||||
{
|
||||
$this->assertFalse($this->cache->read('no_such_key'));
|
||||
}
|
||||
|
||||
public function testSetGetFlush()
|
||||
{
|
||||
$this->assertTrue($this->cache->write('test', 'example'), "Failed to set value.");
|
||||
$this->assertSame('example', $this->cache->read('test'));
|
||||
$this->assertTrue($this->cache->flush());
|
||||
$this->assertFalse($this->cache->read('test'));
|
||||
}
|
||||
}
|
||||
173
package/vendor/liquid/liquid/tests/Liquid/Cache/FileTest.php
vendored
Normal file
173
package/vendor/liquid/liquid/tests/Liquid/Cache/FileTest.php
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Cache;
|
||||
|
||||
use Liquid\TestCase;
|
||||
|
||||
class FileTest extends TestCase
|
||||
{
|
||||
/** @var \Liquid\Cache\File */
|
||||
protected $cache;
|
||||
protected $cacheDir;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->cacheDir = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'cache_dir';
|
||||
|
||||
// Remove tmp cache files because they may remain after a failed test run
|
||||
$this->removeOldCachedFiles();
|
||||
|
||||
$this->cache = new File(array(
|
||||
'cache_dir' => $this->cacheDir,
|
||||
'cache_expire' => 3600,
|
||||
'cache_prefix' => 'liquid_',
|
||||
));
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
$this->removeOldCachedFiles();
|
||||
}
|
||||
|
||||
private function removeOldCachedFiles(): void
|
||||
{
|
||||
if ($files = glob($this->cacheDir . DIRECTORY_SEPARATOR . '*')) {
|
||||
array_map('unlink', $files);
|
||||
}
|
||||
}
|
||||
|
||||
public function testConstructInvalidOptions()
|
||||
{
|
||||
$this->expectException(\Liquid\Exception\FilesystemException::class);
|
||||
|
||||
new File();
|
||||
}
|
||||
|
||||
public function testConstructNoSuchDirOrNotWritable()
|
||||
{
|
||||
$this->expectException(\Liquid\Exception\FilesystemException::class);
|
||||
|
||||
new File(array('cache_dir' => '/no/such/dir/liquid/cache'));
|
||||
}
|
||||
|
||||
public function testGetExistsNoFile()
|
||||
{
|
||||
$this->assertFalse($this->cache->exists('no_key'));
|
||||
}
|
||||
|
||||
public function testGetExistsExpired()
|
||||
{
|
||||
$key = 'test';
|
||||
$cacheFile = $this->cacheDir . DIRECTORY_SEPARATOR . 'liquid_' . $key;
|
||||
touch($cacheFile, time() - 1000000); // long ago
|
||||
$this->assertFalse($this->cache->exists($key));
|
||||
}
|
||||
|
||||
public function testGetExistsNotExpired()
|
||||
{
|
||||
$key = 'test';
|
||||
$cacheFile = $this->cacheDir . DIRECTORY_SEPARATOR . 'liquid_' . $key;
|
||||
touch($cacheFile);
|
||||
$this->assertTrue($this->cache->exists($key));
|
||||
}
|
||||
|
||||
public function testFlushAll()
|
||||
{
|
||||
touch($this->cacheDir . DIRECTORY_SEPARATOR . 'liquid_test');
|
||||
touch($this->cacheDir . DIRECTORY_SEPARATOR . 'liquid_test_two');
|
||||
|
||||
$this->assertGreaterThanOrEqual(2, count(glob($this->cacheDir . DIRECTORY_SEPARATOR . '*')));
|
||||
|
||||
$this->cache->flush();
|
||||
|
||||
$this->assertCount(0, glob($this->cacheDir . DIRECTORY_SEPARATOR . '*'));
|
||||
}
|
||||
|
||||
public function testFlushExpired()
|
||||
{
|
||||
touch($this->cacheDir . DIRECTORY_SEPARATOR . 'liquid_test');
|
||||
touch($this->cacheDir . DIRECTORY_SEPARATOR . 'liquid_test_two', time() - 1000000);
|
||||
|
||||
$files = join(', ', glob($this->cacheDir . DIRECTORY_SEPARATOR . '*'));
|
||||
|
||||
$this->assertGreaterThanOrEqual(2, count(glob($this->cacheDir . DIRECTORY_SEPARATOR . '*')), "Found more than two files: $files");
|
||||
|
||||
$this->cache->flush(true);
|
||||
|
||||
$this->assertCount(1, glob($this->cacheDir . DIRECTORY_SEPARATOR . '*'));
|
||||
}
|
||||
|
||||
public function testWriteNoSerialize()
|
||||
{
|
||||
$key = 'test';
|
||||
$value = 'test_value';
|
||||
|
||||
$this->assertTrue($this->cache->write($key, $value, false));
|
||||
|
||||
$this->assertEquals($value, file_get_contents($this->cacheDir . DIRECTORY_SEPARATOR . 'liquid_' . $key));
|
||||
}
|
||||
|
||||
public function testWriteSerialized()
|
||||
{
|
||||
$key = 'test';
|
||||
$value = 'test_value';
|
||||
|
||||
$this->assertTrue($this->cache->write($key, $value));
|
||||
|
||||
$this->assertEquals(serialize($value), file_get_contents($this->cacheDir . DIRECTORY_SEPARATOR . 'liquid_' . $key));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testWriteSerialized
|
||||
*/
|
||||
public function testWriteGc()
|
||||
{
|
||||
$key = 'test';
|
||||
$value = 'test_value';
|
||||
|
||||
// This cache file must be removed by GC
|
||||
touch($this->cacheDir . DIRECTORY_SEPARATOR . 'liquid_test_two', time() - 1000000);
|
||||
|
||||
$this->assertTrue($this->cache->write($key, $value, false));
|
||||
|
||||
$this->assertCount(1, glob($this->cacheDir . DIRECTORY_SEPARATOR . '*'));
|
||||
}
|
||||
|
||||
public function testReadNonExisting()
|
||||
{
|
||||
$this->assertFalse($this->cache->read('no_such_key'));
|
||||
}
|
||||
|
||||
public function testReadNoUnserialize()
|
||||
{
|
||||
$key = 'test';
|
||||
$value = 'test_value';
|
||||
|
||||
file_put_contents($this->cacheDir . DIRECTORY_SEPARATOR . 'liquid_' . $key, $value);
|
||||
|
||||
$this->assertSame($value, $this->cache->read($key, false));
|
||||
}
|
||||
|
||||
public function testReadSerialize()
|
||||
{
|
||||
$key = 'test';
|
||||
$value = 'test_value';
|
||||
|
||||
file_put_contents($this->cacheDir . DIRECTORY_SEPARATOR . 'liquid_' . $key, serialize($value));
|
||||
|
||||
$this->assertSame($value, $this->cache->read($key));
|
||||
}
|
||||
}
|
||||
45
package/vendor/liquid/liquid/tests/Liquid/Cache/LocalTest.php
vendored
Normal file
45
package/vendor/liquid/liquid/tests/Liquid/Cache/LocalTest.php
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Cache;
|
||||
|
||||
use Liquid\TestCase;
|
||||
|
||||
class LocalTest extends TestCase
|
||||
{
|
||||
/** @var \Liquid\Cache\Local */
|
||||
protected $cache;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->cache = new Local();
|
||||
}
|
||||
|
||||
public function testNotExists()
|
||||
{
|
||||
$this->assertFalse($this->cache->exists('no_such_key'));
|
||||
}
|
||||
|
||||
public function testReadNotExisting()
|
||||
{
|
||||
$this->assertFalse($this->cache->read('no_such_key'));
|
||||
}
|
||||
|
||||
public function testSetGetFlush()
|
||||
{
|
||||
$this->assertTrue($this->cache->write('test', 'example'));
|
||||
$this->assertSame('example', $this->cache->read('test'));
|
||||
$this->assertTrue($this->cache->flush());
|
||||
$this->assertFalse($this->cache->read('test'));
|
||||
}
|
||||
}
|
||||
503
package/vendor/liquid/liquid/tests/Liquid/ContextTest.php
vendored
Normal file
503
package/vendor/liquid/liquid/tests/Liquid/ContextTest.php
vendored
Normal file
@@ -0,0 +1,503 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid;
|
||||
|
||||
class HundredCentes
|
||||
{
|
||||
public function toLiquid()
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
}
|
||||
|
||||
class ToLiquidNotObject
|
||||
{
|
||||
public function toLiquid()
|
||||
{
|
||||
return STDIN;
|
||||
}
|
||||
}
|
||||
|
||||
class CentsDrop extends Drop
|
||||
{
|
||||
public function amount()
|
||||
{
|
||||
return new HundredCentes();
|
||||
}
|
||||
}
|
||||
|
||||
class NoToLiquid
|
||||
{
|
||||
public $answer = 42;
|
||||
|
||||
private $name = null;
|
||||
|
||||
public function name()
|
||||
{
|
||||
return 'example';
|
||||
}
|
||||
|
||||
public function count()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return "forty two";
|
||||
}
|
||||
}
|
||||
|
||||
class ToLiquidWrapper
|
||||
{
|
||||
public $value = null;
|
||||
|
||||
public function toLiquid()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
}
|
||||
|
||||
class NestedObject
|
||||
{
|
||||
public $property;
|
||||
public $value = -1;
|
||||
|
||||
public function toLiquid()
|
||||
{
|
||||
// we intentionally made the value different so
|
||||
// that we could see where it is coming from
|
||||
return array(
|
||||
'property' => $this->property,
|
||||
'value' => 42,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class CountableObject implements \Countable
|
||||
{
|
||||
public function count()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
class ToArrayObject
|
||||
{
|
||||
public $property;
|
||||
public $value = -1;
|
||||
|
||||
public function toArray()
|
||||
{
|
||||
// we intentionally made the value different so
|
||||
// that we could see where it is coming from
|
||||
return array(
|
||||
'property' => $this->property,
|
||||
'value' => 42,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class GetSetObject
|
||||
{
|
||||
public function field_exists($name)
|
||||
{
|
||||
return $name == 'answer';
|
||||
}
|
||||
|
||||
public function get($prop)
|
||||
{
|
||||
if ($prop == 'answer') {
|
||||
return 42;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GetSetMagic
|
||||
{
|
||||
public function __get($prop)
|
||||
{
|
||||
if ($prop == 'prime') {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class HiFilter
|
||||
{
|
||||
public function hi($value)
|
||||
{
|
||||
return $value . ' hi!';
|
||||
}
|
||||
}
|
||||
|
||||
class GlobalFilter
|
||||
{
|
||||
public function notice($value)
|
||||
{
|
||||
return "Global $value";
|
||||
}
|
||||
}
|
||||
|
||||
class LocalFilter
|
||||
{
|
||||
public function notice($value)
|
||||
{
|
||||
return "Local $value";
|
||||
}
|
||||
}
|
||||
|
||||
class ContextTest extends TestCase
|
||||
{
|
||||
/** @var Context */
|
||||
public $context;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->context = new Context();
|
||||
}
|
||||
|
||||
public function testScoping()
|
||||
{
|
||||
$this->context->push();
|
||||
$this->assertNull($this->context->pop());
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function testNoScopeToPop()
|
||||
{
|
||||
$this->expectException(\Liquid\LiquidException::class);
|
||||
|
||||
$this->context->pop();
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function testGetArray()
|
||||
{
|
||||
$this->expectException(\Liquid\LiquidException::class);
|
||||
|
||||
$this->context->get(array());
|
||||
}
|
||||
|
||||
public function testGetNotVariable()
|
||||
{
|
||||
$data = array(
|
||||
null => null,
|
||||
'null' => null,
|
||||
'true' => true,
|
||||
'false' => false,
|
||||
"'quoted_string'" => 'quoted_string',
|
||||
'"double_quoted_string"' => "double_quoted_string",
|
||||
);
|
||||
|
||||
foreach ($data as $key => $expected) {
|
||||
$this->assertEquals($expected, $this->context->get($key));
|
||||
}
|
||||
|
||||
$this->assertEquals(42.00, $this->context->get(42.00));
|
||||
}
|
||||
|
||||
public function testVariablesNotExisting()
|
||||
{
|
||||
$this->assertNull($this->context->get('test'));
|
||||
}
|
||||
|
||||
public function testVariableIsObjectWithNoToLiquid()
|
||||
{
|
||||
$this->context->set('test', new NoToLiquid());
|
||||
$this->assertEquals(42, $this->context->get('test.answer'));
|
||||
$this->assertEquals(1, $this->context->get('test.count'));
|
||||
$this->assertNull($this->context->get('test.invalid'));
|
||||
$this->assertEquals("forty two", $this->context->get('test'));
|
||||
$this->assertEquals("example", $this->context->get('test.name'));
|
||||
}
|
||||
|
||||
public function testToLiquidNull()
|
||||
{
|
||||
$object = new ToLiquidWrapper();
|
||||
$this->context->set('object', $object);
|
||||
$this->assertNull($this->context->get('object.key'));
|
||||
}
|
||||
|
||||
public function testToLiquidStringKeyMustBeNull()
|
||||
{
|
||||
$object = new ToLiquidWrapper();
|
||||
$object->value = 'foo';
|
||||
$this->context->set('object', $object);
|
||||
$this->assertNull($this->context->get('object.foo'));
|
||||
$this->assertNull($this->context->get('object.foo.bar'));
|
||||
}
|
||||
|
||||
public function testNestedObject()
|
||||
{
|
||||
$object = new NestedObject();
|
||||
$object->property = new NestedObject();
|
||||
$this->context->set('object', $object);
|
||||
$this->assertEquals(42, $this->context->get('object.value'));
|
||||
$this->assertEquals(42, $this->context->get('object.property.value'));
|
||||
$this->assertNull($this->context->get('object.property.value.invalid'));
|
||||
}
|
||||
|
||||
public function testToArrayObject()
|
||||
{
|
||||
$object = new ToArrayObject();
|
||||
$object->property = new ToArrayObject();
|
||||
$this->context->set('object', $object);
|
||||
$this->assertEquals(42, $this->context->get('object.value'));
|
||||
$this->assertEquals(42, $this->context->get('object.property.value'));
|
||||
$this->assertNull($this->context->get('object.property.value.invalid'));
|
||||
}
|
||||
|
||||
public function testGetSetObject()
|
||||
{
|
||||
$this->context->set('object', new GetSetObject());
|
||||
$this->assertEquals(42, $this->context->get('object.answer'));
|
||||
$this->assertNull($this->context->get('object.invalid'));
|
||||
}
|
||||
|
||||
public function testGetSetMagic()
|
||||
{
|
||||
$this->context->set('object', new GetSetMagic());
|
||||
$this->assertEquals(2, $this->context->get('object.prime'));
|
||||
$this->assertNull($this->context->get('object.invalid'));
|
||||
}
|
||||
|
||||
public function testFinalVariableCanBeObject()
|
||||
{
|
||||
$this->context->set('test', (object) array('value' => (object) array()));
|
||||
$this->assertInstanceOf(\stdClass::class, $this->context->get('test.value'));
|
||||
}
|
||||
|
||||
public function testVariables()
|
||||
{
|
||||
$this->context->set('test', 'test');
|
||||
$this->assertTrue($this->context->hasKey('test'));
|
||||
$this->assertFalse($this->context->hasKey('test.foo'));
|
||||
$this->assertEquals('test', $this->context->get('test'));
|
||||
|
||||
// We add this text to make sure we can return values that evaluate to false properly
|
||||
$this->context->set('test_0', 0);
|
||||
$this->assertEquals('0', $this->context->get('test_0'));
|
||||
}
|
||||
|
||||
public function testLengthQuery()
|
||||
{
|
||||
$this->context->set('numbers', array(1, 2, 3, 4));
|
||||
$this->assertEquals(4, $this->context->get('numbers.size'));
|
||||
}
|
||||
|
||||
public function testStringLength()
|
||||
{
|
||||
$this->context->set('name', 'Foo Bar');
|
||||
$this->assertEquals(7, $this->context->get('name.size'));
|
||||
|
||||
$this->context->set('name', 'テスト');
|
||||
$this->assertEquals(3, $this->context->get('name.size'));
|
||||
}
|
||||
|
||||
public function testCountableLength()
|
||||
{
|
||||
$this->context->set('countable', new CountableObject());
|
||||
$this->assertEquals(2, $this->context->get('countable.size'));
|
||||
}
|
||||
|
||||
public function testOverrideSize()
|
||||
{
|
||||
$this->context->set('hash', array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'size' => '5000'));
|
||||
$this->assertEquals(5000, $this->context->get('hash.size'));
|
||||
}
|
||||
|
||||
public function testArrayFirst()
|
||||
{
|
||||
$this->context->set('array', array(11, 'jack', 43, 74, 5, 'tom'));
|
||||
$this->assertEquals(11, $this->context->get('array.first'));
|
||||
}
|
||||
|
||||
public function testOverrideFirst()
|
||||
{
|
||||
$this->context->set('array', array(11, 'jack', 43, 'first' => 74, 5, 'tom'));
|
||||
$this->assertEquals(74, $this->context->get('array.first'));
|
||||
}
|
||||
|
||||
public function testArrayLast()
|
||||
{
|
||||
$this->context->set('array', array(11, 'jack', 43, 74, 5, 'tom'));
|
||||
$this->assertEquals('tom', $this->context->get('array.last'));
|
||||
}
|
||||
|
||||
public function testOverrideLast()
|
||||
{
|
||||
$this->context->set('array', array(11, 'jack', 43, 'last' => 74, 5, 'tom'));
|
||||
$this->assertEquals(74, $this->context->get('array.last'));
|
||||
}
|
||||
|
||||
public function testDeepValueNotObject()
|
||||
{
|
||||
$this->context->set('example', array('foo' => new ToLiquidNotObject()));
|
||||
$this->assertNull($this->context->get('example.foo.bar'));
|
||||
}
|
||||
|
||||
public function testHierchalData()
|
||||
{
|
||||
$this->context->set('hash', array('name' => 'tobi'));
|
||||
$this->assertEquals('tobi', $this->context->get('hash.name'));
|
||||
}
|
||||
|
||||
public function testHierchalDataNoKey()
|
||||
{
|
||||
$this->context->set('hash', array('name' => 'tobi'));
|
||||
$this->assertNull($this->context->get('hash.no_key'));
|
||||
}
|
||||
|
||||
public function testAddFilter()
|
||||
{
|
||||
$context = new Context();
|
||||
$context->addFilters(new HiFilter());
|
||||
$this->assertEquals('hi? hi!', $context->invoke('hi', 'hi?'));
|
||||
|
||||
$context = new Context();
|
||||
$this->assertEquals('hi?', $context->invoke('hi', 'hi?'));
|
||||
|
||||
$context->addFilters(new HiFilter());
|
||||
$this->assertEquals('hi? hi!', $context->invoke('hi', 'hi?'));
|
||||
}
|
||||
|
||||
public function testOverrideGlobalFilter()
|
||||
{
|
||||
$template = new Template();
|
||||
$template->registerFilter(new GlobalFilter());
|
||||
|
||||
$template->parse("{{'test' | notice }}");
|
||||
$this->assertEquals('Global test', $template->render());
|
||||
$this->assertEquals('Local test', $template->render(array(), new LocalFilter()));
|
||||
}
|
||||
|
||||
public function testCallbackFilter()
|
||||
{
|
||||
$template = new Template();
|
||||
$template->registerFilter('foo', function ($arg) {
|
||||
return "Foo $arg";
|
||||
});
|
||||
|
||||
$template->parse("{{'test' | foo }}");
|
||||
$this->assertEquals('Foo test', $template->render());
|
||||
}
|
||||
|
||||
public function testAddItemInOuterScope()
|
||||
{
|
||||
$this->context->set('test', 'test');
|
||||
$this->context->push();
|
||||
$this->assertEquals('test', $this->context->get('test'));
|
||||
$this->context->pop();
|
||||
$this->assertEquals('test', $this->context->get('test'));
|
||||
}
|
||||
|
||||
public function testAddItemInInnerScope()
|
||||
{
|
||||
$this->context->push();
|
||||
$this->context->set('test', 'test');
|
||||
$this->assertEquals('test', $this->context->get('test'));
|
||||
$this->context->pop();
|
||||
$this->assertNull($this->context->get('test'));
|
||||
}
|
||||
|
||||
public function testMerge()
|
||||
{
|
||||
$this->context->merge(array('test' => 'test'));
|
||||
$this->assertEquals('test', $this->context->get('test'));
|
||||
|
||||
$this->context->merge(array('test' => 'newvalue', 'foo' => 'bar'));
|
||||
$this->assertEquals('newvalue', $this->context->get('test'));
|
||||
$this->assertEquals('bar', $this->context->get('foo'));
|
||||
}
|
||||
|
||||
public function testCents()
|
||||
{
|
||||
$this->context->merge(array('cents' => new HundredCentes()));
|
||||
$this->assertEquals(100, $this->context->get('cents'));
|
||||
}
|
||||
|
||||
public function testNestedCents()
|
||||
{
|
||||
$this->context->merge(array('cents' => array('amount' => new HundredCentes())));
|
||||
$this->assertEquals(100, $this->context->get('cents.amount'));
|
||||
|
||||
$this->context->merge(array('cents' => array('cents' => array('amount' => new HundredCentes()))));
|
||||
$this->assertEquals(100, $this->context->get('cents.cents.amount'));
|
||||
}
|
||||
|
||||
public function testCentsThroughDrop()
|
||||
{
|
||||
$this->context->merge(array('cents' => new CentsDrop()));
|
||||
$this->assertEquals(100, $this->context->get('cents.amount'));
|
||||
}
|
||||
|
||||
public function testCentsThroughDropNestedly()
|
||||
{
|
||||
$this->context->merge(array('cents' => array('cents' => new CentsDrop())));
|
||||
$this->assertEquals(100, $this->context->get('cents.cents.amount'));
|
||||
|
||||
$this->context->merge(array('cents' => array('cents' => array('cents' => new CentsDrop()))));
|
||||
$this->assertEquals(100, $this->context->get('cents.cents.cents.amount'));
|
||||
}
|
||||
|
||||
public function testGetNoOverride()
|
||||
{
|
||||
$_GET['test'] = '<script>alert()</script>';
|
||||
// Previously $_GET would override directly set values
|
||||
// It happend during class construction - we need to create a brand new instance right here
|
||||
$context = new Context();
|
||||
$context->set('test', 'test');
|
||||
$this->assertEquals('test', $context->get('test'));
|
||||
}
|
||||
|
||||
public function testServerOnlyExposeWhitelistByDefault()
|
||||
{
|
||||
$_SERVER['AWS_SECRET_ACCESS_KEY'] = 'super_secret';
|
||||
|
||||
$context = new Context();
|
||||
$this->assertNull($context->get('AWS_SECRET_ACCESS_KEY'));
|
||||
|
||||
$context->set('AWS_SECRET_ACCESS_KEY', 'test');
|
||||
$this->assertEquals('test', $context->get('AWS_SECRET_ACCESS_KEY'));
|
||||
|
||||
$_SERVER['FOO'] = 'foo';
|
||||
$_SERVER['BAR'] = 'bar';
|
||||
|
||||
Liquid::set('SERVER_SUPERGLOBAL_WHITELIST', ['FOO']);
|
||||
|
||||
$context = new Context();
|
||||
$this->assertEquals('foo', $context->get('FOO'));
|
||||
$this->assertNull($context->get('BAR'));
|
||||
|
||||
$context->set('BAR', 'bar');
|
||||
$this->assertEquals('bar', $context->get('BAR'));
|
||||
}
|
||||
|
||||
public function testServerExposedWhenRequested()
|
||||
{
|
||||
Liquid::set('EXPOSE_SERVER', true);
|
||||
|
||||
$_SERVER['AWS_SECRET_ACCESS_KEY'] = 'super_secret';
|
||||
|
||||
$context = new Context();
|
||||
$this->assertEquals('super_secret', $context->get('AWS_SECRET_ACCESS_KEY'));
|
||||
|
||||
$context->set('AWS_SECRET_ACCESS_KEY', 'test');
|
||||
$this->assertEquals('super_secret', $context->get('AWS_SECRET_ACCESS_KEY'), '$_SERVER should take precedence in this case');
|
||||
}
|
||||
}
|
||||
47
package/vendor/liquid/liquid/tests/Liquid/CustomFiltersTest.php
vendored
Normal file
47
package/vendor/liquid/liquid/tests/Liquid/CustomFiltersTest.php
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid;
|
||||
|
||||
class CustomFiltersTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* The current context
|
||||
*
|
||||
* @var Context
|
||||
*/
|
||||
public $context;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->context = new Context();
|
||||
}
|
||||
|
||||
public function testSortKey()
|
||||
{
|
||||
$data = array(
|
||||
array(
|
||||
array(),
|
||||
array(),
|
||||
),
|
||||
array(
|
||||
array('b' => 1, 'c' => 5, 'a' => 3, 'z' => 4, 'h' => 2),
|
||||
array('a' => 3, 'b' => 1, 'c' => 5, 'h' => 2, 'z' => 4),
|
||||
),
|
||||
);
|
||||
|
||||
foreach ($data as $item) {
|
||||
$this->assertEquals($item[1], CustomFilters::sort_key($item[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
47
package/vendor/liquid/liquid/tests/Liquid/CustomTagTest.php
vendored
Normal file
47
package/vendor/liquid/liquid/tests/Liquid/CustomTagTest.php
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid;
|
||||
|
||||
use Liquid\Tag\TagComment;
|
||||
|
||||
class TagFoo extends TagComment
|
||||
{
|
||||
}
|
||||
|
||||
class CustomTagTest extends TestCase
|
||||
{
|
||||
public function testUnknownTag()
|
||||
{
|
||||
$template = new Template();
|
||||
|
||||
if (array_key_exists('foo', $template->getTags())) {
|
||||
$this->markTestIncomplete("Test tag already registered. Are you missing @depends?");
|
||||
}
|
||||
|
||||
$this->expectException(\Liquid\Exception\ParseException::class);
|
||||
$this->expectExceptionMessage('Unknown tag foo');
|
||||
|
||||
$template->parse('[ba{% foo %} Comment {% endfoo %}r]');
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testUnknownTag
|
||||
*/
|
||||
public function testCustomTag()
|
||||
{
|
||||
$template = new Template();
|
||||
$template->registerTag('foo', TagFoo::class);
|
||||
|
||||
$template->parse('[ba{% foo %} Comment {% endfoo %}r]');
|
||||
$this->assertEquals('[bar]', $template->render());
|
||||
}
|
||||
}
|
||||
140
package/vendor/liquid/liquid/tests/Liquid/DropTest.php
vendored
Normal file
140
package/vendor/liquid/liquid/tests/Liquid/DropTest.php
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid;
|
||||
|
||||
class ContextDrop extends Drop
|
||||
{
|
||||
public function beforeMethod($method)
|
||||
{
|
||||
return $this->context->get($method);
|
||||
}
|
||||
}
|
||||
|
||||
class TextDrop extends Drop
|
||||
{
|
||||
public function get_array()
|
||||
{
|
||||
return array('text1', 'text2');
|
||||
}
|
||||
|
||||
public function text()
|
||||
{
|
||||
return 'text1';
|
||||
}
|
||||
}
|
||||
|
||||
class CatchallDrop extends Drop
|
||||
{
|
||||
public function beforeMethod($method)
|
||||
{
|
||||
return 'method: ' . $method;
|
||||
}
|
||||
}
|
||||
|
||||
class ProductDrop extends Drop
|
||||
{
|
||||
public function top_sales()
|
||||
{
|
||||
throw new \Exception("worked");
|
||||
}
|
||||
|
||||
public function texts()
|
||||
{
|
||||
return new TextDrop();
|
||||
}
|
||||
|
||||
public function catchall()
|
||||
{
|
||||
return new CatchallDrop();
|
||||
}
|
||||
|
||||
public function context()
|
||||
{
|
||||
return new ContextDrop();
|
||||
}
|
||||
|
||||
public function callmenot()
|
||||
{
|
||||
return "protected";
|
||||
}
|
||||
|
||||
public function hasKey($name)
|
||||
{
|
||||
return $name != 'unknown' && $name != 'false';
|
||||
}
|
||||
}
|
||||
|
||||
class DropTest extends TestCase
|
||||
{
|
||||
/**
|
||||
*/
|
||||
public function testProductDrop()
|
||||
{
|
||||
$this->expectException(\Exception::class);
|
||||
$this->expectExceptionMessage('worked');
|
||||
|
||||
$template = new Template();
|
||||
$template->parse(' {{ product.top_sales }} ');
|
||||
$template->render(array('product' => new ProductDrop));
|
||||
}
|
||||
|
||||
public function testNoKeyDrop()
|
||||
{
|
||||
$template = new Template();
|
||||
$template->parse(' {{ product.invalid.unknown }}{{ product.false }} ');
|
||||
$output = $template->render(array('product' => new ProductDrop));
|
||||
$this->assertEquals(' ', $output);
|
||||
}
|
||||
|
||||
public function testTextDrop()
|
||||
{
|
||||
$template = new Template();
|
||||
$template->parse(' {{ product.texts.text }} ');
|
||||
$output = $template->render(array('product' => new ProductDrop()));
|
||||
$this->assertEquals(' text1 ', $output);
|
||||
|
||||
$template = new Template();
|
||||
$template->parse(' {{ product.catchall.unknown }} ');
|
||||
$output = $template->render(array('product' => new ProductDrop()));
|
||||
$this->assertEquals(' method: unknown ', $output);
|
||||
}
|
||||
|
||||
public function testTextArrayDrop()
|
||||
{
|
||||
$template = new Template();
|
||||
$template->parse('{% for text in product.texts.get_array %} {{text}} {% endfor %}');
|
||||
$output = $template->render(array('product' => new ProductDrop()));
|
||||
|
||||
$this->assertEquals(' text1 text2 ', $output);
|
||||
}
|
||||
|
||||
public function testContextDrop()
|
||||
{
|
||||
$template = new Template();
|
||||
$template->parse(' {{ context.bar }} ');
|
||||
$output = $template->render(array('context' => new ContextDrop(), 'bar' => 'carrot'));
|
||||
$this->assertEquals(' carrot ', $output);
|
||||
}
|
||||
|
||||
public function testNestedContextDrop()
|
||||
{
|
||||
$template = new Template();
|
||||
$template->parse(' {{ product.context.foo }} ');
|
||||
$output = $template->render(array('product' => new ProductDrop(), 'foo' => 'monkey'));
|
||||
$this->assertEquals(' monkey ', $output);
|
||||
}
|
||||
|
||||
public function testToString()
|
||||
{
|
||||
$this->assertEquals(ProductDrop::class, strval(new ProductDrop()));
|
||||
}
|
||||
}
|
||||
127
package/vendor/liquid/liquid/tests/Liquid/EscapeByDefaultTest.php
vendored
Normal file
127
package/vendor/liquid/liquid/tests/Liquid/EscapeByDefaultTest.php
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid;
|
||||
|
||||
class ObjectWithToString
|
||||
{
|
||||
private $string = '';
|
||||
|
||||
public function __construct($string)
|
||||
{
|
||||
$this->string = $string;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->string;
|
||||
}
|
||||
}
|
||||
|
||||
class EscapeByDefaultTest extends TestCase
|
||||
{
|
||||
const XSS = "<script>alert()</script>";
|
||||
const XSS_FAILED = "<script>alert()</script>";
|
||||
|
||||
protected $assigns = array();
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->assigns = array(
|
||||
'xss' => self::XSS,
|
||||
);
|
||||
}
|
||||
|
||||
public function testUnescaped()
|
||||
{
|
||||
$text = "{{ xss }}";
|
||||
$expected = self::XSS;
|
||||
$this->assertTemplateResult($expected, $text, $this->assigns);
|
||||
}
|
||||
|
||||
public function testEscapedManually()
|
||||
{
|
||||
$text = "{{ xss | escape }}";
|
||||
$expected = self::XSS_FAILED;
|
||||
$this->assertTemplateResult($expected, $text, $this->assigns);
|
||||
}
|
||||
|
||||
public function testRawWithoutAutoEscape()
|
||||
{
|
||||
$text = "{{ xss | raw }}";
|
||||
$expected = self::XSS;
|
||||
$this->assertTemplateResult($expected, $text, $this->assigns);
|
||||
}
|
||||
|
||||
public function testEscapedAutomatically()
|
||||
{
|
||||
Liquid::set('ESCAPE_BY_DEFAULT', true);
|
||||
|
||||
$text = "{{ xss }}";
|
||||
$expected = self::XSS_FAILED;
|
||||
$this->assertTemplateResult($expected, $text, $this->assigns);
|
||||
}
|
||||
|
||||
public function testEscapedManuallyInAutoMode()
|
||||
{
|
||||
Liquid::set('ESCAPE_BY_DEFAULT', true);
|
||||
|
||||
// text should only be escaped once
|
||||
$text = "{{ xss | escape }}";
|
||||
$expected = self::XSS_FAILED;
|
||||
$this->assertTemplateResult($expected, $text, $this->assigns);
|
||||
}
|
||||
|
||||
public function testRawInAutoMode()
|
||||
{
|
||||
Liquid::set('ESCAPE_BY_DEFAULT', true);
|
||||
|
||||
$text = "{{ xss | raw }}";
|
||||
$expected = self::XSS;
|
||||
$this->assertTemplateResult($expected, $text, $this->assigns);
|
||||
}
|
||||
|
||||
public function testNlToBr()
|
||||
{
|
||||
Liquid::set('ESCAPE_BY_DEFAULT', true);
|
||||
$text = "{{ xss | newline_to_br }}";
|
||||
$expected = self::XSS."<br />\n".self::XSS;
|
||||
$this->assertTemplateResult($expected, $text, array('xss' => self::XSS."\n".self::XSS));
|
||||
}
|
||||
|
||||
public function testToStringEscape()
|
||||
{
|
||||
$this->assertTemplateResult(self::XSS_FAILED, "{{ xss | escape }}", array('xss' => new ObjectWithToString(self::XSS)));
|
||||
}
|
||||
|
||||
public function testToStringEscapeDefault()
|
||||
{
|
||||
Liquid::set('ESCAPE_BY_DEFAULT', true);
|
||||
$this->assertTemplateResult(self::XSS_FAILED, "{{ xss }}", array('xss' => new ObjectWithToString(self::XSS)));
|
||||
}
|
||||
|
||||
/** System default value for the escape flag */
|
||||
private static $escapeDefault;
|
||||
|
||||
public static function setUpBeforeClass(): void
|
||||
{
|
||||
// save system default value for the escape flag before all tests
|
||||
self::$escapeDefault = Liquid::get('ESCAPE_BY_DEFAULT');
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
// reset to the default after each test
|
||||
Liquid::set('ESCAPE_BY_DEFAULT', self::$escapeDefault);
|
||||
}
|
||||
}
|
||||
244
package/vendor/liquid/liquid/tests/Liquid/FilterbankTest.php
vendored
Normal file
244
package/vendor/liquid/liquid/tests/Liquid/FilterbankTest.php
vendored
Normal file
@@ -0,0 +1,244 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace {
|
||||
|
||||
/**
|
||||
* Global function acts as a filter.
|
||||
*
|
||||
* @param $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function functionFilter($value)
|
||||
{
|
||||
return 'worked';
|
||||
}
|
||||
|
||||
/**
|
||||
* Global filter class
|
||||
*/
|
||||
class ClassFilter
|
||||
{
|
||||
private $variable = 'not set';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public static function static_test()
|
||||
{
|
||||
return "worked";
|
||||
}
|
||||
|
||||
public function instance_test_one()
|
||||
{
|
||||
$this->variable = 'set';
|
||||
return 'set';
|
||||
}
|
||||
|
||||
public function instance_test_two()
|
||||
{
|
||||
return $this->variable;
|
||||
}
|
||||
}
|
||||
|
||||
} // global namespace
|
||||
|
||||
namespace Liquid {
|
||||
|
||||
use Liquid\Cache\File;
|
||||
|
||||
class NamespacedClassFilter
|
||||
{
|
||||
public static function static_test2($var)
|
||||
{
|
||||
return "good {$var}";
|
||||
}
|
||||
}
|
||||
|
||||
class FilterbankTest extends TestCase
|
||||
{
|
||||
/** @var FilterBank */
|
||||
private $filterBank;
|
||||
|
||||
/** @var Context */
|
||||
private $context;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->context = new Context();
|
||||
$this->filterBank = new FilterBank($this->context);
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
// have to destroy these else PHP goes nuts
|
||||
unset($this->context);
|
||||
unset($this->filterBank);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function testAddFilterNotObjectAndString()
|
||||
{
|
||||
$this->expectException(\Liquid\Exception\WrongArgumentException::class);
|
||||
|
||||
$this->filterBank->addFilter(array());
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function testAddFilterNoFunctionOrClass()
|
||||
{
|
||||
$this->expectException(\Liquid\Exception\WrongArgumentException::class);
|
||||
|
||||
$this->filterBank->addFilter('no_such_function_or_class');
|
||||
}
|
||||
|
||||
public function testTypeErrorExceptionAndCallDateFilterWithoutArguments()
|
||||
{
|
||||
if (\PHP_VERSION_ID < 70100) {
|
||||
$this->markTestSkipped('TypeError is not thrown in PHP 7.0');
|
||||
}
|
||||
|
||||
$var = new Variable('var | date');
|
||||
$this->context->set('var', 1000);
|
||||
|
||||
$this->expectException(\Liquid\LiquidException::class);
|
||||
$var->render($this->context);
|
||||
}
|
||||
|
||||
public function testInvokeNoFilter()
|
||||
{
|
||||
$value = 'value';
|
||||
$this->assertEquals($value, $this->filterBank->invoke('non_existing_filter', $value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test using a simple function
|
||||
*/
|
||||
public function testFunctionFilter()
|
||||
{
|
||||
$var = new Variable('var | functionFilter');
|
||||
$this->context->set('var', 1000);
|
||||
$this->context->addFilters('functionFilter');
|
||||
$this->assertEquals('worked', $var->render($this->context));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test using a namespaced static class
|
||||
*/
|
||||
public function testNamespacedStaticClassFilter()
|
||||
{
|
||||
$var = new Variable('var | static_test2');
|
||||
$this->context->set('var', 1000);
|
||||
$this->context->addFilters(NamespacedClassFilter::class);
|
||||
$this->assertEquals('good 1000', $var->render($this->context));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test using a static class
|
||||
*/
|
||||
public function testStaticClassFilter()
|
||||
{
|
||||
$var = new Variable('var | static_test');
|
||||
$this->context->set('var', 1000);
|
||||
$this->context->addFilters(\ClassFilter::class);
|
||||
$this->assertEquals('worked', $var->render($this->context));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with instance method on a static class
|
||||
*/
|
||||
public function testStaticMixedClassFilter()
|
||||
{
|
||||
$var = new Variable('var | instance_test_one');
|
||||
$this->context->set('var', 'foo');
|
||||
$this->context->addFilters(\ClassFilter::class);
|
||||
$this->assertEquals('foo', $var->render($this->context));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test using an object as a filter; an object fiter will retain its state
|
||||
* between calls to its filters.
|
||||
*/
|
||||
public function testObjectFilter()
|
||||
{
|
||||
$var = new Variable('var | instance_test_one');
|
||||
$this->context->set('var', 1000);
|
||||
$this->context->addFilters(new \ClassFilter());
|
||||
$this->assertEquals('set', $var->render($this->context));
|
||||
|
||||
$var = new Variable('var | instance_test_two');
|
||||
$this->assertEquals('set', $var->render($this->context));
|
||||
|
||||
$var = new Variable('var | static_test');
|
||||
$this->assertEquals('worked', $var->render($this->context));
|
||||
|
||||
$var = new Variable('var | __construct');
|
||||
$this->assertEquals('1000', $var->render($this->context));
|
||||
}
|
||||
|
||||
public function testObjectFilterDontCallConstruct()
|
||||
{
|
||||
$this->context->set('var', 1000);
|
||||
$this->context->addFilters(new \ClassFilter());
|
||||
|
||||
$filterbankReflectionClass = new \ReflectionClass(Context::class);
|
||||
$methodMapProperty = $filterbankReflectionClass->getProperty('filterbank');
|
||||
$methodMapProperty->setAccessible(true);
|
||||
$filterbank = $methodMapProperty->getValue($this->context);
|
||||
|
||||
$filterbankReflectionClass = new \ReflectionClass(Filterbank::class);
|
||||
$methodMapProperty = $filterbankReflectionClass->getProperty('methodMap');
|
||||
$methodMapProperty->setAccessible(true);
|
||||
$methodMap = $methodMapProperty->getValue($filterbank);
|
||||
|
||||
$this->assertArrayNotHasKey('__construct', $methodMap);
|
||||
|
||||
$var = new Variable('var | __construct');
|
||||
$this->assertEquals('1000', $var->render($this->context));
|
||||
}
|
||||
|
||||
public function testCallbackFilter()
|
||||
{
|
||||
$var = new Variable('var | my_callback');
|
||||
$this->context->set('var', 1000);
|
||||
$this->context->addFilters('my_callback', function ($var) {
|
||||
return $var * 2;
|
||||
});
|
||||
$this->assertEquals('2000', $var->render($this->context));
|
||||
}
|
||||
|
||||
/**
|
||||
* Closures are not to be serialized. Let's check that.
|
||||
*/
|
||||
public function testWithSerializingCache()
|
||||
{
|
||||
$template = new Template();
|
||||
$template->registerFilter('foo', function ($arg) {
|
||||
return "Foo $arg";
|
||||
});
|
||||
$template->setCache(new File(array(
|
||||
'cache_dir' => __DIR__.'/cache_dir/',
|
||||
)));
|
||||
$template->parse("{{'test' | foo }}");
|
||||
$this->assertEquals('Foo test', $template->render());
|
||||
|
||||
$template->parse("{{'bar' | foo }}");
|
||||
$this->assertEquals('Foo bar', $template->render());
|
||||
}
|
||||
}
|
||||
|
||||
} // Liquid namespace
|
||||
50
package/vendor/liquid/liquid/tests/Liquid/FixturesTest.php
vendored
Normal file
50
package/vendor/liquid/liquid/tests/Liquid/FixturesTest.php
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid;
|
||||
|
||||
use Liquid\FileSystem\Virtual;
|
||||
|
||||
class FixturesTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider fixtures
|
||||
* @param string $liquid
|
||||
* @param string $data
|
||||
* @param string $expected
|
||||
*/
|
||||
public function testFixture($liquid, $data, $expected)
|
||||
{
|
||||
$template = new Template();
|
||||
$template->setFileSystem(new Virtual(function ($filename) {
|
||||
if (is_file(__DIR__.'/fixtures/'.$filename)) {
|
||||
return file_get_contents(__DIR__.'/fixtures/'.$filename);
|
||||
}
|
||||
}));
|
||||
|
||||
$template->parse(file_get_contents($liquid));
|
||||
$result = $template->render(include $data);
|
||||
|
||||
if (getenv('GOLDEN') !== false) {
|
||||
file_put_contents($expected, $result);
|
||||
$this->markTestIncomplete("Saved golden fixture");
|
||||
}
|
||||
|
||||
$this->assertEquals(file_get_contents($expected), $result);
|
||||
}
|
||||
|
||||
public function fixtures()
|
||||
{
|
||||
foreach (array_map(null, glob(__DIR__.'/fixtures/*.liquid'), glob(__DIR__.'/fixtures/*.php'), glob(__DIR__.'/fixtures/*.html')) as $files) {
|
||||
yield basename($files[0], '.liquid') => $files;
|
||||
};
|
||||
}
|
||||
}
|
||||
88
package/vendor/liquid/liquid/tests/Liquid/LiquidTest.php
vendored
Normal file
88
package/vendor/liquid/liquid/tests/Liquid/LiquidTest.php
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid;
|
||||
|
||||
class LiquidTest extends TestCase
|
||||
{
|
||||
public function testGetNonExistingPropery()
|
||||
{
|
||||
$this->assertNull(Liquid::get('no_such_value'));
|
||||
}
|
||||
|
||||
public function testSetProperty()
|
||||
{
|
||||
$key = 'test_key';
|
||||
$value = 'test_value';
|
||||
Liquid::set($key, $value);
|
||||
$this->assertSame($value, Liquid::get($key));
|
||||
}
|
||||
|
||||
public function testGetSetAllowedChars()
|
||||
{
|
||||
Liquid::set('ALLOWED_VARIABLE_CHARS', 'abc');
|
||||
$this->assertSame('abc', Liquid::get('ALLOWED_VARIABLE_CHARS'));
|
||||
$this->assertSame('abc+', Liquid::get('VARIABLE_NAME'));
|
||||
}
|
||||
|
||||
public function testArrayFlattenEmptyArray()
|
||||
{
|
||||
$this->assertSame(array(), Liquid::arrayFlatten(array()));
|
||||
}
|
||||
|
||||
public function testArrayFlattenFlatArray()
|
||||
{
|
||||
$object = new \stdClass();
|
||||
|
||||
// Method does not maintain keys.
|
||||
$original = array(
|
||||
'one' => 'one_value',
|
||||
42,
|
||||
$object,
|
||||
);
|
||||
|
||||
$expected = array(
|
||||
'one_value',
|
||||
42,
|
||||
$object
|
||||
);
|
||||
|
||||
$this->assertEquals($expected, Liquid::arrayFlatten($original));
|
||||
}
|
||||
|
||||
public function testArrayFlattenNestedArray()
|
||||
{
|
||||
$object = new \stdClass();
|
||||
|
||||
// Method does not maintain keys.
|
||||
$original = array(
|
||||
'one' => 'one_value',
|
||||
42 => array(
|
||||
'one_value',
|
||||
array(
|
||||
'two_value',
|
||||
10
|
||||
),
|
||||
),
|
||||
$object,
|
||||
);
|
||||
|
||||
$expected = array(
|
||||
'one_value',
|
||||
'one_value',
|
||||
'two_value',
|
||||
10,
|
||||
$object
|
||||
);
|
||||
|
||||
$this->assertEquals($expected, Liquid::arrayFlatten($original));
|
||||
}
|
||||
}
|
||||
169
package/vendor/liquid/liquid/tests/Liquid/LocalFileSystemTest.php
vendored
Normal file
169
package/vendor/liquid/liquid/tests/Liquid/LocalFileSystemTest.php
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid;
|
||||
|
||||
use Liquid\FileSystem\Local;
|
||||
|
||||
class LocalFileSystemTest extends TestCase
|
||||
{
|
||||
protected $root;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->root = __DIR__ . DIRECTORY_SEPARATOR . self::TEMPLATES_DIR . DIRECTORY_SEPARATOR;
|
||||
// reset to defaults
|
||||
Liquid::set('INCLUDE_ALLOW_EXT', false);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function testIllegalTemplateNameEmpty()
|
||||
{
|
||||
$this->expectException(\Liquid\LiquidException::class);
|
||||
|
||||
$fileSystem = new Local('');
|
||||
$fileSystem->fullPath('');
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function testIllegalRootPath()
|
||||
{
|
||||
$this->expectException(\Liquid\LiquidException::class);
|
||||
|
||||
$fileSystem = new Local('invalid/not/found');
|
||||
$fileSystem->fullPath('');
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function testIllegalTemplateNameIncludeExtension()
|
||||
{
|
||||
$this->expectException(\Liquid\LiquidException::class);
|
||||
|
||||
Liquid::set('INCLUDE_ALLOW_EXT', false);
|
||||
|
||||
$fileSystem = new Local('');
|
||||
$fileSystem->fullPath('has_extension.ext');
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function testIllegalTemplateNameNotIncludeExtension()
|
||||
{
|
||||
$this->expectException(\Liquid\LiquidException::class);
|
||||
|
||||
Liquid::set('INCLUDE_ALLOW_EXT', true);
|
||||
|
||||
$fileSystem = new Local('');
|
||||
$fileSystem->fullPath('has_extension');
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function testIllegalTemplatePathNoRoot()
|
||||
{
|
||||
$this->expectException(\Liquid\LiquidException::class);
|
||||
|
||||
$fileSystem = new Local('');
|
||||
$fileSystem->fullPath('mypartial');
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function testIllegalTemplatePathNoFileExists()
|
||||
{
|
||||
$this->expectException(\Liquid\LiquidException::class);
|
||||
|
||||
$fileSystem = new Local(dirname(__DIR__));
|
||||
$fileSystem->fullPath('no_such_file_exists');
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function testIllegalTemplatePathNotUnderTemplateRoot()
|
||||
{
|
||||
$this->expectException(\Liquid\LiquidException::class);
|
||||
$this->expectExceptionMessage('not under');
|
||||
|
||||
Liquid::set('INCLUDE_ALLOW_EXT', true);
|
||||
$fileSystem = new Local(dirname($this->root));
|
||||
// find any fail under deeper under the root, so all other checks would pass
|
||||
$filesUnderCurrentDir = array_map('basename', glob(dirname(__DIR__).'/../*'));
|
||||
// path relative to root; we can't start it with a dot since it isn't allowed anyway
|
||||
$fileSystem->fullPath(self::TEMPLATES_DIR."/../../../{$filesUnderCurrentDir[0]}");
|
||||
}
|
||||
|
||||
public function testValidPathWithDefaultExtension()
|
||||
{
|
||||
$templateName = 'mypartial';
|
||||
|
||||
$fileSystem = new Local($this->root);
|
||||
$this->assertEquals($this->root . Liquid::get('INCLUDE_PREFIX') . $templateName . '.' . Liquid::get('INCLUDE_SUFFIX'), $fileSystem->fullPath($templateName));
|
||||
}
|
||||
|
||||
public function testValidPathWithCustomExtension()
|
||||
{
|
||||
Liquid::set('INCLUDE_PREFIX', '');
|
||||
Liquid::set('INCLUDE_SUFFIX', 'tpl');
|
||||
|
||||
$templateName = 'mypartial';
|
||||
|
||||
$fileSystem = new Local($this->root);
|
||||
$this->assertEquals($this->root . Liquid::get('INCLUDE_PREFIX') . $templateName . '.' . Liquid::get('INCLUDE_SUFFIX'), $fileSystem->fullPath($templateName));
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function testReadIllegalTemplatePathNoFileExists()
|
||||
{
|
||||
$this->expectException(\Liquid\LiquidException::class);
|
||||
$this->expectExceptionMessage('File not found');
|
||||
|
||||
$fileSystem = new Local(dirname(__DIR__));
|
||||
$fileSystem->readTemplateFile('no_such_file_exists');
|
||||
}
|
||||
|
||||
public function testReadTemplateFile()
|
||||
{
|
||||
Liquid::set('INCLUDE_PREFIX', '');
|
||||
Liquid::set('INCLUDE_SUFFIX', 'tpl');
|
||||
|
||||
$fileSystem = new Local($this->root);
|
||||
$this->assertEquals('test content', trim($fileSystem->readTemplateFile('mypartial')));
|
||||
}
|
||||
|
||||
public function testDeprecatedLocalFileSystemExists()
|
||||
{
|
||||
$this->assertInstanceOf(Local::class, new LocalFileSystem($this->root));
|
||||
}
|
||||
|
||||
public function testParseTemplateFile()
|
||||
{
|
||||
Liquid::set('INCLUDE_PREFIX', '');
|
||||
Liquid::set('INCLUDE_SUFFIX', 'tpl');
|
||||
|
||||
$template = new Template($this->root);
|
||||
$this->assertEquals("test content\n", $template->parseFile('mypartial')->render());
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function testParseTemplateFileError()
|
||||
{
|
||||
$this->expectException(\Liquid\LiquidException::class);
|
||||
$this->expectExceptionMessage('Could not load a template');
|
||||
|
||||
$template = new Template();
|
||||
$template->parseFile('mypartial');
|
||||
}
|
||||
}
|
||||
194
package/vendor/liquid/liquid/tests/Liquid/OutputTest.php
vendored
Normal file
194
package/vendor/liquid/liquid/tests/Liquid/OutputTest.php
vendored
Normal file
@@ -0,0 +1,194 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid;
|
||||
|
||||
class FunnyFilter
|
||||
{
|
||||
public function make_funny($input)
|
||||
{
|
||||
return 'LOL';
|
||||
}
|
||||
|
||||
public function cite_funny($input)
|
||||
{
|
||||
return 'LOL: ' . $input;
|
||||
}
|
||||
|
||||
public function add_smiley($input, $smiley = ":-)")
|
||||
{
|
||||
return $input . ' ' . $smiley;
|
||||
}
|
||||
|
||||
public function add_tag($input, $tag = "p", $id = "foo")
|
||||
{
|
||||
return "<" . $tag . " id=\"" . $id . "\">" . $input . "</" . $tag . ">";
|
||||
}
|
||||
|
||||
public function paragraph($input)
|
||||
{
|
||||
return "<p>" . $input . "</p>";
|
||||
}
|
||||
|
||||
public function link_to($name, $url, $protocol)
|
||||
{
|
||||
return "<a href=\"" . $protocol . '://' .$url . "\">" . $name . "</a>";
|
||||
}
|
||||
|
||||
public function str_replace($input, $data)
|
||||
{
|
||||
foreach ($data as $k => $v) {
|
||||
$input = str_replace("[" . $k . "]", $v, $input);
|
||||
}
|
||||
return $input;
|
||||
}
|
||||
|
||||
public function img_url($input, $size, $opts = null)
|
||||
{
|
||||
$output = "image_" . $size;
|
||||
if (isset($opts['crop'])) {
|
||||
$output .= "_cropped_" . $opts['crop'];
|
||||
}
|
||||
if (isset($opts['scale'])) {
|
||||
$output .= "@" . $opts['scale'] . 'x';
|
||||
}
|
||||
return $output . ".png";
|
||||
}
|
||||
}
|
||||
|
||||
class OutputTest extends TestCase
|
||||
{
|
||||
protected $assigns = array();
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->assigns = array(
|
||||
'best_cars' => 'bmw',
|
||||
'car' => array('bmw' => 'good', 'gm' => 'bad')
|
||||
);
|
||||
|
||||
$this->filters = new FunnyFilter();
|
||||
}
|
||||
|
||||
public function testVariable()
|
||||
{
|
||||
$text = " {{best_cars}} ";
|
||||
$expected = " bmw ";
|
||||
|
||||
$this->assertTemplateResult($expected, $text, $this->assigns);
|
||||
}
|
||||
|
||||
public function testVariableTrasversing()
|
||||
{
|
||||
$text = " {{car.bmw}} {{car.gm}} {{car.bmw}} ";
|
||||
|
||||
$expected = " good bad good ";
|
||||
$this->assertTemplateResult($expected, $text, $this->assigns);
|
||||
}
|
||||
|
||||
public function testVariablePiping()
|
||||
{
|
||||
$text = " {{ car.gm | make_funny }} ";
|
||||
$expected = " LOL ";
|
||||
|
||||
$this->assertTemplateResult($expected, $text, $this->assigns);
|
||||
}
|
||||
|
||||
public function testVariablePipingWithInput()
|
||||
{
|
||||
$text = " {{ car.gm | cite_funny }} ";
|
||||
$expected = " LOL: bad ";
|
||||
|
||||
$this->assertTemplateResult($expected, $text, $this->assigns);
|
||||
}
|
||||
|
||||
public function testVariablePipingWithArgs()
|
||||
{
|
||||
$text = " {{ car.gm | add_smiley : '=(' }} ";
|
||||
$expected = " bad =( ";
|
||||
|
||||
$this->assertTemplateResult($expected, $text, $this->assigns);
|
||||
}
|
||||
|
||||
public function textVariablePipingWithNoArgs()
|
||||
{
|
||||
$text = " {{ car.gm | add_smile }} ";
|
||||
$expected = " bad =( ";
|
||||
|
||||
$this->assertTemplateResult($expected, $text, $this->assigns);
|
||||
}
|
||||
|
||||
public function testMultipleVariablePipingWithArgs()
|
||||
{
|
||||
$text = " {{ car.gm | add_smiley : '=(' | add_smiley : '=('}} ";
|
||||
$expected = " bad =( =( ";
|
||||
|
||||
$this->assertTemplateResult($expected, $text, $this->assigns);
|
||||
}
|
||||
|
||||
public function testVariablePipingWithTwoArgs()
|
||||
{
|
||||
$text = " {{ car.gm | add_tag : 'span', 'bar'}} ";
|
||||
$expected = " <span id=\"bar\">bad</span> ";
|
||||
|
||||
$this->assertTemplateResult($expected, $text, $this->assigns);
|
||||
}
|
||||
|
||||
public function testVariablePipingWithVariableArgs()
|
||||
{
|
||||
$text = " {{ car.gm | add_tag : 'span', car.bmw}} ";
|
||||
$expected = " <span id=\"good\">bad</span> ";
|
||||
|
||||
$this->assertTemplateResult($expected, $text, $this->assigns);
|
||||
}
|
||||
|
||||
public function testVariablePipingWithKeywordArg()
|
||||
{
|
||||
$text = " {{ 'Welcome, [name]' | str_replace: name: 'Santa' }} ";
|
||||
$expected = " Welcome, Santa ";
|
||||
|
||||
$this->assertTemplateResult($expected, $text, $this->assigns);
|
||||
}
|
||||
|
||||
public function testVariablePipingWithArgsAndKeywordArgs()
|
||||
{
|
||||
$text = " {{ car.gm | img_url: '450x450', crop: 'center', scale: 2 }} ";
|
||||
$expected = " image_450x450_cropped_center@2x.png ";
|
||||
|
||||
$this->assertTemplateResult($expected, $text, $this->assigns);
|
||||
}
|
||||
|
||||
public function testMultiplePipings()
|
||||
{
|
||||
$text = " {{ best_cars | cite_funny | paragraph }} ";
|
||||
$expected = " <p>LOL: bmw</p> ";
|
||||
|
||||
$this->assertTemplateResult($expected, $text, $this->assigns);
|
||||
}
|
||||
|
||||
public function testLinkTo()
|
||||
{
|
||||
$text = " {{ 'Typo' | link_to: 'typo.leetsoft.com':'http' }} ";
|
||||
$expected = " <a href=\"http://typo.leetsoft.com\">Typo</a> ";
|
||||
|
||||
$this->assertTemplateResult($expected, $text, $this->assigns);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function testVariableWithANewLine()
|
||||
{
|
||||
$text = "{{ aaa\n }}";
|
||||
$this->assertTemplateResult('', $text, $this->assigns);
|
||||
}
|
||||
}
|
||||
27
package/vendor/liquid/liquid/tests/Liquid/ParsingQuirksTest.php
vendored
Normal file
27
package/vendor/liquid/liquid/tests/Liquid/ParsingQuirksTest.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid;
|
||||
|
||||
class ParsingQuirksTest extends TestCase
|
||||
{
|
||||
public function testErrorWithCss()
|
||||
{
|
||||
$text = " div { font-weight: bold; } ";
|
||||
$template = new Template();
|
||||
$template->parse($text);
|
||||
|
||||
$nodelist = $template->getRoot()->getNodelist();
|
||||
|
||||
$this->assertEquals($text, $template->render());
|
||||
$this->assertIsString($nodelist[0]);
|
||||
}
|
||||
}
|
||||
69
package/vendor/liquid/liquid/tests/Liquid/RegexpTest.php
vendored
Normal file
69
package/vendor/liquid/liquid/tests/Liquid/RegexpTest.php
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid;
|
||||
|
||||
class RegexpTest extends TestCase
|
||||
{
|
||||
/** @var Regexp */
|
||||
protected $regexp;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->regexp = new Regexp('/' . Liquid::get('QUOTED_FRAGMENT') . '/');
|
||||
}
|
||||
|
||||
public function testEmpty()
|
||||
{
|
||||
$this->assertEquals(array(), $this->regexp->scan(''));
|
||||
}
|
||||
|
||||
public function testQuote()
|
||||
{
|
||||
$this->assertEquals(array('"arg 1"'), $this->regexp->scan('"arg 1"'));
|
||||
}
|
||||
|
||||
public function testWords()
|
||||
{
|
||||
$this->assertEquals(array('arg1', 'arg2'), $this->regexp->scan('arg1 arg2'));
|
||||
}
|
||||
|
||||
public function testQuotedWords()
|
||||
{
|
||||
$this->assertEquals(array('arg1', 'arg2', '"arg 3"'), $this->regexp->scan('arg1 arg2 "arg 3"'));
|
||||
}
|
||||
|
||||
public function testQuotedWords2()
|
||||
{
|
||||
$this->assertEquals(array('arg1', 'arg2', "'arg 3'"), $this->regexp->scan('arg1 arg2 \'arg 3\''));
|
||||
}
|
||||
|
||||
public function testQuotedWordsInTheMiddle()
|
||||
{
|
||||
$this->assertEquals(array('arg1', 'arg2', '"arg 3"', 'arg4'), $this->regexp->scan('arg1 arg2 "arg 3" arg4 '));
|
||||
}
|
||||
|
||||
public function testPregQuote()
|
||||
{
|
||||
$this->assertEquals('', $this->regexp->quote(''));
|
||||
$this->assertEquals('abc', $this->regexp->quote('abc'));
|
||||
$this->assertEquals('\/\(\{\}\)\/', $this->regexp->quote('/({})/'));
|
||||
}
|
||||
|
||||
public function testNoDelimiter()
|
||||
{
|
||||
$regexp = new Regexp('(example)');
|
||||
$this->assertEquals(array('(example)'), $regexp->scan('(example)'));
|
||||
$this->assertEquals(array(), $regexp->scan('nothing'));
|
||||
}
|
||||
}
|
||||
1144
package/vendor/liquid/liquid/tests/Liquid/StandardFiltersTest.php
vendored
Normal file
1144
package/vendor/liquid/liquid/tests/Liquid/StandardFiltersTest.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
35
package/vendor/liquid/liquid/tests/Liquid/Tag/NoTransformTest.php
vendored
Normal file
35
package/vendor/liquid/liquid/tests/Liquid/Tag/NoTransformTest.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Tag;
|
||||
|
||||
use Liquid\TestCase;
|
||||
|
||||
class NoTransformTest extends TestCase
|
||||
{
|
||||
public function testNoTransform()
|
||||
{
|
||||
$this->assertTemplateResult(
|
||||
'this text should come out of the template without change...',
|
||||
'this text should come out of the template without change...'
|
||||
);
|
||||
|
||||
$this->assertTemplateResult('blah', 'blah');
|
||||
$this->assertTemplateResult('<blah>', '<blah>');
|
||||
$this->assertTemplateResult('|,.:', '|,.:');
|
||||
$this->assertTemplateResult('', '');
|
||||
|
||||
$text = "this shouldnt see any transformation either but has multiple lines
|
||||
as you can clearly see here ...";
|
||||
|
||||
$this->assertTemplateResult($text, $text);
|
||||
}
|
||||
}
|
||||
98
package/vendor/liquid/liquid/tests/Liquid/Tag/TagAssignTest.php
vendored
Normal file
98
package/vendor/liquid/liquid/tests/Liquid/Tag/TagAssignTest.php
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Tag;
|
||||
|
||||
use Liquid\TestCase;
|
||||
use Liquid\Template;
|
||||
|
||||
/**
|
||||
* Basic tests for the assignment of one variable to another. This also tests the
|
||||
* assignment of filtered values to another variable.
|
||||
*/
|
||||
class TagAssignTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* Tests the normal behavior of throwing an exception when the assignment is incorrect
|
||||
*
|
||||
*/
|
||||
public function testInvalidAssign()
|
||||
{
|
||||
$this->expectException(\Liquid\Exception\ParseException::class);
|
||||
|
||||
$template = new Template();
|
||||
|
||||
$template->parse('{% assign test %}');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a simple assignment with no filters
|
||||
*/
|
||||
public function testSimpleAssign()
|
||||
{
|
||||
$template = new Template();
|
||||
|
||||
$template->parse('{% assign test = "hello" %}{{ test }}');
|
||||
$this->assertTrue($template->render() === 'hello');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests filtered value assignment
|
||||
*/
|
||||
public function testAssignWithFilters()
|
||||
{
|
||||
$template = new Template();
|
||||
|
||||
$template->parse('{% assign test = "hello" | upcase %}{{ test }}');
|
||||
$this->assertTrue($template->render() === 'HELLO');
|
||||
|
||||
$template->parse('{% assign test = "hello" | upcase | downcase | capitalize %}{{ test }}');
|
||||
$this->assertTrue($template->render() === 'Hello');
|
||||
|
||||
$template->parse('{% assign test = var1 | first | upcase %}{{ test }}');
|
||||
$this->assertTrue($template->render(array('var1' => array('a', 'b', 'c'))) === 'A');
|
||||
|
||||
$template->parse('{% assign test = var1 | last | upcase %}{{ test }}');
|
||||
$this->assertTrue($template->render(array('var1' => array('a', 'b', 'c'))) === 'C');
|
||||
|
||||
$template->parse('{% assign test = var1 | join %}{{ test }}');
|
||||
$this->assertTrue($template->render(array('var1' => array('a', 'b', 'c'))) === 'a b c');
|
||||
|
||||
$template->parse('{% assign test = var1 | join : "." %}{{ test }}');
|
||||
$this->assertTrue($template->render(array('var1' => array('a', 'b', 'c'))) === 'a.b.c');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests filtered value assignment with separators
|
||||
*/
|
||||
public function testTagAssignWithSplit()
|
||||
{
|
||||
$template = new Template();
|
||||
|
||||
$template->parse('{% assign rows = "one|two|three,one|two|three" | upcase | split: "," %}{% for row in rows %}{% assign cols = row | split: "|" %}{% for col in cols %} {{col}}{%endfor%}{% endfor %}');
|
||||
$this->assertEquals($template->render(), ' ONE TWO THREE ONE TWO THREE');
|
||||
|
||||
$template->parse('{% assign issue_numbers = "1339|1338|1321" | split: "|" %}{% for issue in issue_numbers %} {{ issue }}{% endfor %}');
|
||||
$this->assertEquals($template->render(), ' 1339 1338 1321');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a simple assignment with numbers
|
||||
*/
|
||||
public function testNumbersAssign()
|
||||
{
|
||||
$this->assertTemplateResult('42', '{% assign i = 42 %}{{ i }}');
|
||||
$this->assertTemplateResult('3.14', '{% assign i = 3.14 %}{{ i }}');
|
||||
$this->assertTemplateResult('-100', '{% assign i = -100 %}{{ i }}');
|
||||
$this->assertTemplateResult('-10.0', '{% assign i = -10.0 %}{{ i }}');
|
||||
$this->assertTemplateResult('-10.5', '{% assign i = -10.5 %}{{ i }}');
|
||||
}
|
||||
}
|
||||
31
package/vendor/liquid/liquid/tests/Liquid/Tag/TagBlockTest.php
vendored
Normal file
31
package/vendor/liquid/liquid/tests/Liquid/Tag/TagBlockTest.php
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Tag;
|
||||
|
||||
use Liquid\TestCase;
|
||||
|
||||
class TagBlockTest extends TestCase
|
||||
{
|
||||
/**
|
||||
*/
|
||||
public function testSyntaxError()
|
||||
{
|
||||
$this->expectException(\Liquid\Exception\ParseException::class);
|
||||
|
||||
$this->assertTemplateResult('', '{% block %}');
|
||||
}
|
||||
|
||||
public function testCreateBlock()
|
||||
{
|
||||
$this->assertTemplateResult('block content', '{% block foo %}block content{% endblock %}');
|
||||
}
|
||||
}
|
||||
50
package/vendor/liquid/liquid/tests/Liquid/Tag/TagBreakTest.php
vendored
Normal file
50
package/vendor/liquid/liquid/tests/Liquid/Tag/TagBreakTest.php
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Tag;
|
||||
|
||||
use Liquid\TestCase;
|
||||
|
||||
class TagBreakTest extends TestCase
|
||||
{
|
||||
public function testFor()
|
||||
{
|
||||
$this->assertTemplateResult(' ', '{%for item in array%} {%break%} yo {%endfor%}', array('array' => array(1, 2, 3, 4)));
|
||||
$this->assertTemplateResult(' yo ', '{%for item in array%} yo {%break%} {%endfor%}', array('array' => array(1, 2, 3, 4)));
|
||||
$this->assertTemplateResult(' 1 2 ', '{%for item in array%} {%if item == 3%} {%break%} {%endif%} {{ item }} {%endfor%}', array('array' => array(1, 2, 3, 4)));
|
||||
}
|
||||
|
||||
public function testRange()
|
||||
{
|
||||
$this->assertTemplateResult(' ', '{%for item in (3..6)%} {%break%} yo {%endfor%}');
|
||||
$this->assertTemplateResult(' yo ', '{%for item in (3..6)%} yo {%break%} {%endfor%}');
|
||||
$this->assertTemplateResult(' 3 4 ', '{%for item in (3..6)%} {%if item == 5%} {%break%} {%endif%} {{ item }} {%endfor%}');
|
||||
}
|
||||
|
||||
public function testTablerow()
|
||||
{
|
||||
$this->assertTemplateResult(
|
||||
"<tr class=\"row1\">\n</tr>\n",
|
||||
'{%tablerow item in array%} {%break%} yo {%endtablerow%}',
|
||||
array('array' => array(1, 2, 3, 4))
|
||||
);
|
||||
$this->assertTemplateResult(
|
||||
"<tr class=\"row1\">\n<td class=\"col1\"> yo </td></tr>\n",
|
||||
'{%tablerow item in array%} yo {%break%} {%endtablerow%}',
|
||||
array('array' => array(1, 2, 3, 4))
|
||||
);
|
||||
$this->assertTemplateResult(
|
||||
"<tr class=\"row1\">\n<td class=\"col1\"> 1 </td><td class=\"col2\"> 2 </td></tr>\n",
|
||||
'{%tablerow item in array%} {%if item == 3%} {%break%} {%endif%} {{ item }} {%endtablerow%}',
|
||||
array('array' => array(1, 2, 3, 4))
|
||||
);
|
||||
}
|
||||
}
|
||||
34
package/vendor/liquid/liquid/tests/Liquid/Tag/TagCaptureTest.php
vendored
Normal file
34
package/vendor/liquid/liquid/tests/Liquid/Tag/TagCaptureTest.php
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Tag;
|
||||
|
||||
use Liquid\TestCase;
|
||||
use Liquid\Template;
|
||||
|
||||
class TagCaptureTest extends TestCase
|
||||
{
|
||||
/**
|
||||
*/
|
||||
public function testInvalidSyntax()
|
||||
{
|
||||
$this->expectException(\Liquid\Exception\ParseException::class);
|
||||
|
||||
$template = new Template();
|
||||
$template->parse("{% capture %} hello");
|
||||
}
|
||||
|
||||
public function testCapture()
|
||||
{
|
||||
$assigns = array('var' => 'content');
|
||||
$this->assertTemplateResult('content foo content foo ', '{{ var2 }}{% capture var2 %}{{ var }} foo {% endcapture %}{{ var2 }}{{ var2 }}', $assigns);
|
||||
}
|
||||
}
|
||||
106
package/vendor/liquid/liquid/tests/Liquid/Tag/TagCaseTest.php
vendored
Normal file
106
package/vendor/liquid/liquid/tests/Liquid/Tag/TagCaseTest.php
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Tag;
|
||||
|
||||
use Liquid\TestCase;
|
||||
|
||||
class Stringable
|
||||
{
|
||||
public function __toString()
|
||||
{
|
||||
return "100";
|
||||
}
|
||||
}
|
||||
|
||||
class HasToLiquid
|
||||
{
|
||||
public function toLiquid()
|
||||
{
|
||||
return "100";
|
||||
}
|
||||
}
|
||||
|
||||
class TagCaseTest extends TestCase
|
||||
{
|
||||
public function testCase()
|
||||
{
|
||||
$assigns = array('condition' => 2);
|
||||
$this->assertTemplateResult(' its 2 ', '{% case condition %}{% when 1 %} its 1 {% when 2 %} its 2 {% endcase %}', $assigns);
|
||||
|
||||
$assigns = array('condition' => 1);
|
||||
$this->assertTemplateResult(' its 1 ', '{% case condition %}{% when 1 %} its 1 {% when 2 %} its 2 {% endcase %}', $assigns);
|
||||
|
||||
$assigns = array('condition' => 3);
|
||||
$this->assertTemplateResult('', '{% case condition %}{% when 1 %} its 1 {% when 2 %} its 2 {% endcase %}', $assigns);
|
||||
|
||||
$assigns = array('condition' => "string here");
|
||||
$this->assertTemplateResult(' hit ', '{% case condition %}{% when "string here" %} hit {% endcase %}', $assigns);
|
||||
|
||||
$assigns = array('condition' => "bad string here");
|
||||
$this->assertTemplateResult('', '{% case condition %}{% when "string here" %} hit {% endcase %}', $assigns);
|
||||
}
|
||||
|
||||
public function testCaseWithElse()
|
||||
{
|
||||
$assigns = array('condition' => 5);
|
||||
$this->assertTemplateResult(' hit ', '{% case condition %}{% when 5 %} hit {% else %} else {% endcase %}', $assigns);
|
||||
|
||||
$assigns = array('condition' => 6);
|
||||
$this->assertTemplateResult(' else ', '{% case condition %}{% when 5 %} hit {% else %} else {% endcase %}', $assigns);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function testSyntaxErrorCase()
|
||||
{
|
||||
$this->expectException(\Liquid\Exception\ParseException::class);
|
||||
|
||||
$this->assertTemplateResult('', '{% case %}{% when 5 %}{% endcase %}');
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function testSyntaxErrorWhen()
|
||||
{
|
||||
$this->expectException(\Liquid\Exception\ParseException::class);
|
||||
|
||||
$this->assertTemplateResult('', '{% case condition %}{% when %}{% endcase %}');
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function testSyntaxErrorEnd()
|
||||
{
|
||||
$this->expectException(\Liquid\Exception\ParseException::class);
|
||||
|
||||
$this->assertTemplateResult('', '{% case condition %}{% end %}');
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function testObject()
|
||||
{
|
||||
$this->expectException(\Liquid\Exception\RenderException::class);
|
||||
|
||||
$this->assertTemplateResult('', '{% case variable %}{% when 5 %}{% endcase %}', array('variable' => (object) array()));
|
||||
}
|
||||
|
||||
public function testStringable()
|
||||
{
|
||||
$this->assertTemplateResult('hit', '{% case variable %}{% when 100 %}hit{% endcase %}', array('variable' => new Stringable()));
|
||||
}
|
||||
|
||||
public function testToLiquid()
|
||||
{
|
||||
$this->assertTemplateResult('hit', '{% case variable %}{% when 100 %}hit{% endcase %}', array('variable' => new HasToLiquid()));
|
||||
}
|
||||
}
|
||||
43
package/vendor/liquid/liquid/tests/Liquid/Tag/TagCommentTest.php
vendored
Normal file
43
package/vendor/liquid/liquid/tests/Liquid/Tag/TagCommentTest.php
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Tag;
|
||||
|
||||
use Liquid\TestCase;
|
||||
|
||||
class TagCommentTest extends TestCase
|
||||
{
|
||||
public function testHasABlockWhichDoesNothing()
|
||||
{
|
||||
$this->assertTemplateResult(
|
||||
"the comment block should be removed .. right?",
|
||||
"the comment block should be removed {%comment%} be gone.. {%endcomment%} .. right?"
|
||||
);
|
||||
|
||||
$this->assertTemplateResult('', '{%comment%}{%endcomment%}');
|
||||
$this->assertTemplateResult('', '{%comment%}{% endcomment %}');
|
||||
$this->assertTemplateResult('', '{% comment %}{%endcomment%}');
|
||||
$this->assertTemplateResult('', '{% comment %}{% endcomment %}');
|
||||
$this->assertTemplateResult('', '{%comment%}comment{%endcomment%}');
|
||||
$this->assertTemplateResult('', '{% comment %}comment{% endcomment %}');
|
||||
|
||||
$this->assertTemplateResult('foobar', 'foo{%comment%}comment{%endcomment%}bar');
|
||||
$this->assertTemplateResult('foobar', 'foo{% comment %}comment{% endcomment %}bar');
|
||||
$this->assertTemplateResult('foobar', 'foo{%comment%} comment {%endcomment%}bar');
|
||||
$this->assertTemplateResult('foobar', 'foo{% comment %} comment {% endcomment %}bar');
|
||||
|
||||
$this->assertTemplateResult('foo bar', 'foo {%comment%} {%endcomment%} bar');
|
||||
$this->assertTemplateResult('foo bar', 'foo {%comment%}comment{%endcomment%} bar');
|
||||
$this->assertTemplateResult('foo bar', 'foo {%comment%} comment {%endcomment%} bar');
|
||||
|
||||
$this->assertTemplateResult('foobar', 'foo{%comment%} {%endcomment%}bar');
|
||||
}
|
||||
}
|
||||
50
package/vendor/liquid/liquid/tests/Liquid/Tag/TagContinueTest.php
vendored
Normal file
50
package/vendor/liquid/liquid/tests/Liquid/Tag/TagContinueTest.php
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Tag;
|
||||
|
||||
use Liquid\TestCase;
|
||||
|
||||
class TagContinueTest extends TestCase
|
||||
{
|
||||
public function testFor()
|
||||
{
|
||||
$this->assertTemplateResult(' ', '{%for item in array%} {%continue%} yo {%endfor%}', array('array' => array(1, 2, 3, 4)));
|
||||
$this->assertTemplateResult(' yo yo yo yo ', '{%for item in array%} yo {%continue%} {%endfor%}', array('array' => array(1, 2, 3, 4)));
|
||||
$this->assertTemplateResult(' 1 2 4 ', '{%for item in array%} {%if item == 3%} {%continue%} {%endif%} {{ item }} {%endfor%}', array('array' => array(1, 2, 3, 4)));
|
||||
}
|
||||
|
||||
public function testRange()
|
||||
{
|
||||
$this->assertTemplateResult(' ', '{%for item in (3..6)%} {%continue%} yo {%endfor%}');
|
||||
$this->assertTemplateResult(' yo yo yo yo ', '{%for item in (3..6)%} yo {%continue%} {%endfor%}');
|
||||
$this->assertTemplateResult(' 3 4 6 ', '{%for item in (3..6)%} {%if item == 5%} {%continue%} {%endif%} {{ item }} {%endfor%}');
|
||||
}
|
||||
|
||||
public function testTablerow()
|
||||
{
|
||||
$this->assertTemplateResult(
|
||||
"<tr class=\"row1\">\n</tr>\n",
|
||||
'{%tablerow item in array%} {%continue%} yo {%endtablerow%}',
|
||||
array('array' => array(1, 2, 3, 4))
|
||||
);
|
||||
$this->assertTemplateResult(
|
||||
"<tr class=\"row1\">\n<td class=\"col1\"> yo </td><td class=\"col2\"> yo </td><td class=\"col3\"> yo </td><td class=\"col4\"> yo </td></tr>\n",
|
||||
'{%tablerow item in array%} yo {%continue%} {%endtablerow%}',
|
||||
array('array' => array(1, 2, 3, 4))
|
||||
);
|
||||
$this->assertTemplateResult(
|
||||
"<tr class=\"row1\">\n<td class=\"col1\"> 1 </td><td class=\"col2\"> 2 </td><td class=\"col3\"> 4 </td></tr>\n",
|
||||
'{%tablerow item in array%} {%if item == 3%} {%continue%} {%endif%} {{ item }} {%endtablerow%}',
|
||||
array('array' => array(1, 2, 3, 4))
|
||||
);
|
||||
}
|
||||
}
|
||||
51
package/vendor/liquid/liquid/tests/Liquid/Tag/TagCycleTest.php
vendored
Normal file
51
package/vendor/liquid/liquid/tests/Liquid/Tag/TagCycleTest.php
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Liquid package.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @package Liquid
|
||||
*/
|
||||
|
||||
namespace Liquid\Tag;
|
||||
|
||||
use Liquid\TestCase;
|
||||
use Liquid\Template;
|
||||
|
||||
class TagCycleTest extends TestCase
|
||||
{
|
||||
/**
|
||||
*/
|
||||
public function testInvalidSyntax()
|
||||
{
|
||||
$this->expectException(\Liquid\Exception\ParseException::class);
|
||||
|
||||
$template = new Template();
|
||||
$template->parse("{% cycle %}");
|
||||
}
|
||||
|
||||
public function testCycle()
|
||||
{
|
||||
$this->assertTemplateResult('one', '{%cycle "one", "two"%}');
|
||||
$this->assertTemplateResult('one two', '{%cycle "one", "two"%} {%cycle "one", "two"%}');
|
||||
$this->assertTemplateResult('one two one', '{%cycle "one", "two"%} {%cycle "one", "two"%} {%cycle "one", "two"%}');
|
||||
}
|
||||
|
||||
public function testMultipleCycles()
|
||||
{
|
||||
$this->assertTemplateResult('1 2 1 1 2 3 1', '{%cycle 1,2%} {%cycle 1,2%} {%cycle 1,2%} {%cycle 1,2,3%} {%cycle 1,2,3%} {%cycle 1,2,3%} {%cycle 1,2,3%}');
|
||||
}
|
||||
|
||||
public function testMultipleNamedCycles()
|
||||
{
|
||||
$this->assertTemplateResult('one one two two one one', '{%cycle 1: "one", "two" %} {%cycle 2: "one", "two" %} {%cycle 1: "one", "two" %} {%cycle 2: "one", "two" %} {%cycle 1: "one", "two" %} {%cycle 2: "one", "two" %}');
|
||||
}
|
||||
|
||||
public function testMultipleNamedCyclesWithNamesFromContext()
|
||||
{
|
||||
$assigns = array("var1" => 1, "var2" => 2);
|
||||
$this->assertTemplateResult('one one two two one one', '{%cycle var1: "one", "two" %} {%cycle var2: "one", "two" %} {%cycle var1: "one", "two" %} {%cycle var2: "one", "two" %} {%cycle var1: "one", "two" %} {%cycle var2: "one", "two" %}', $assigns);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user