初始化仓库
This commit is contained in:
1
vendor/topthink/think-template/.gitignore
vendored
Normal file
1
vendor/topthink/think-template/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
.idea
|
||||
201
vendor/topthink/think-template/LICENSE
vendored
Normal file
201
vendor/topthink/think-template/LICENSE
vendored
Normal file
@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
70
vendor/topthink/think-template/README.md
vendored
Normal file
70
vendor/topthink/think-template/README.md
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
# ThinkTemplate
|
||||
|
||||
基于XML和标签库的编译型模板引擎
|
||||
|
||||
## 主要特性
|
||||
|
||||
- 支持XML标签库和普通标签的混合定义;
|
||||
- 支持直接使用PHP代码书写;
|
||||
- 支持文件包含;
|
||||
- 支持多级标签嵌套;
|
||||
- 支持布局模板功能;
|
||||
- 一次编译多次运行,编译和运行效率非常高;
|
||||
- 模板文件和布局模板更新,自动更新模板缓存;
|
||||
- 系统变量无需赋值直接输出;
|
||||
- 支持多维数组的快速输出;
|
||||
- 支持模板变量的默认值;
|
||||
- 支持页面代码去除Html空白;
|
||||
- 支持变量组合调节器和格式化功能;
|
||||
- 允许定义模板禁用函数和禁用PHP语法;
|
||||
- 通过标签库方式扩展;
|
||||
|
||||
## 安装
|
||||
|
||||
~~~php
|
||||
composer require topthink/think-template
|
||||
~~~
|
||||
|
||||
## 用法示例
|
||||
|
||||
|
||||
~~~php
|
||||
<?php
|
||||
namespace think;
|
||||
|
||||
require __DIR__.'/vendor/autoload.php';
|
||||
|
||||
// 设置模板引擎参数
|
||||
$config = [
|
||||
'view_path' => './template/',
|
||||
'cache_path' => './runtime/',
|
||||
'view_suffix' => 'html',
|
||||
];
|
||||
|
||||
$template = new Template($config);
|
||||
// 模板变量赋值
|
||||
$template->assign(['name' => 'think']);
|
||||
// 读取模板文件渲染输出
|
||||
$template->fetch('index');
|
||||
// 完整模板文件渲染
|
||||
$template->fetch('./template/test.php');
|
||||
// 渲染内容输出
|
||||
$template->display($content);
|
||||
~~~
|
||||
|
||||
支持静态调用
|
||||
|
||||
~~~
|
||||
use think\facade\Template;
|
||||
|
||||
Template::config([
|
||||
'view_path' => './template/',
|
||||
'cache_path' => './runtime/',
|
||||
'view_suffix' => 'html',
|
||||
]);
|
||||
Template::assign(['name' => 'think']);
|
||||
Template::fetch('index',['name' => 'think']);
|
||||
Template::display($content,['name' => 'think']);
|
||||
~~~
|
||||
|
||||
详细用法参考[开发手册](https://www.kancloud.cn/manual/think-template/content)
|
||||
20
vendor/topthink/think-template/composer.json
vendored
Normal file
20
vendor/topthink/think-template/composer.json
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "topthink/think-template",
|
||||
"description": "the php template engine",
|
||||
"license": "Apache-2.0",
|
||||
"authors": [
|
||||
{
|
||||
"name": "liu21st",
|
||||
"email": "liu21st@gmail.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=8.0.0",
|
||||
"psr/simple-cache": ">=1.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"think\\": "src"
|
||||
}
|
||||
}
|
||||
}
|
||||
12
vendor/topthink/think-template/phpunit.xml
vendored
Normal file
12
vendor/topthink/think-template/phpunit.xml
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
<phpunit
|
||||
bootstrap="tests/bootstrap.php"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="unit">
|
||||
<directory phpVersion="8.0.0" phpVersionOperator=">=">tests/think</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
</phpunit>
|
||||
1313
vendor/topthink/think-template/src/Template.php
vendored
Normal file
1313
vendor/topthink/think-template/src/Template.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
83
vendor/topthink/think-template/src/facade/Template.php
vendored
Normal file
83
vendor/topthink/think-template/src/facade/Template.php
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2023 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\facade;
|
||||
|
||||
if (class_exists('think\Facade')) {
|
||||
class Facade extends \think\Facade
|
||||
{}
|
||||
} else {
|
||||
class Facade
|
||||
{
|
||||
/**
|
||||
* 始终创建新的对象实例
|
||||
* @var bool
|
||||
*/
|
||||
protected static $alwaysNewInstance;
|
||||
|
||||
protected static $instance;
|
||||
|
||||
/**
|
||||
* 获取当前Facade对应类名
|
||||
* @access protected
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeClass()
|
||||
{}
|
||||
|
||||
/**
|
||||
* 创建Facade实例
|
||||
* @static
|
||||
* @access protected
|
||||
* @return object
|
||||
*/
|
||||
protected static function createFacade()
|
||||
{
|
||||
$class = static::getFacadeClass() ?: 'think\Template';
|
||||
|
||||
if (static::$alwaysNewInstance) {
|
||||
return new $class();
|
||||
}
|
||||
|
||||
if (!self::$instance) {
|
||||
self::$instance = new $class();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
|
||||
}
|
||||
|
||||
// 调用实际类的方法
|
||||
public static function __callStatic($method, $params)
|
||||
{
|
||||
return call_user_func_array([static::createFacade(), $method], $params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see \think\Template
|
||||
* @mixin \think\Template
|
||||
*/
|
||||
class Template extends Facade
|
||||
{
|
||||
protected static $alwaysNewInstance = true;
|
||||
|
||||
/**
|
||||
* 获取当前Facade对应类名(或者已经绑定的容器对象标识)
|
||||
* @access protected
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeClass()
|
||||
{
|
||||
return 'think\Template';
|
||||
}
|
||||
}
|
||||
341
vendor/topthink/think-template/src/template/TagLib.php
vendored
Normal file
341
vendor/topthink/think-template/src/template/TagLib.php
vendored
Normal file
@ -0,0 +1,341 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2023 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\template;
|
||||
|
||||
use Exception;
|
||||
use think\Template;
|
||||
|
||||
/**
|
||||
* ThinkPHP标签库TagLib解析基类
|
||||
* @category Think
|
||||
* @package Think
|
||||
* @subpackage Template
|
||||
* @author liu21st <liu21st@gmail.com>
|
||||
*/
|
||||
class TagLib
|
||||
{
|
||||
|
||||
/**
|
||||
* 标签库定义XML文件
|
||||
* @var string
|
||||
* @access protected
|
||||
*/
|
||||
protected $xml = '';
|
||||
protected $tags = []; // 标签定义
|
||||
/**
|
||||
* 标签库名称
|
||||
* @var string
|
||||
* @access protected
|
||||
*/
|
||||
protected $tagLib = '';
|
||||
|
||||
/**
|
||||
* 标签库标签列表
|
||||
* @var array
|
||||
* @access protected
|
||||
*/
|
||||
protected $tagList = [];
|
||||
|
||||
/**
|
||||
* 标签库分析数组
|
||||
* @var array
|
||||
* @access protected
|
||||
*/
|
||||
protected $parse = [];
|
||||
|
||||
/**
|
||||
* 标签库是否有效
|
||||
* @var bool
|
||||
* @access protected
|
||||
*/
|
||||
protected $valid = false;
|
||||
|
||||
protected $comparison = [' nheq ' => ' !== ', ' heq ' => ' === ', ' neq ' => ' != ', ' eq ' => ' == ', ' egt ' => ' >= ', ' gt ' => ' > ', ' elt ' => ' <= ', ' lt ' => ' < '];
|
||||
|
||||
/**
|
||||
* 架构函数
|
||||
* @access public
|
||||
* @param Template $tpl 模板引擎对象
|
||||
*/
|
||||
public function __construct(protected Template $tpl)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 按签标库替换页面中的标签
|
||||
* @access public
|
||||
* @param string $content 模板内容
|
||||
* @param string $lib 标签库名
|
||||
* @return void
|
||||
*/
|
||||
public function parseTag(string &$content, string $lib = ''): void
|
||||
{
|
||||
$tags = [];
|
||||
$lib = $lib ? strtolower($lib) . ':' : '';
|
||||
|
||||
foreach ($this->tags as $name => $val) {
|
||||
$close = !isset($val['close']) || $val['close'] ? 1 : 0;
|
||||
$tags[$close][$lib . $name] = $name;
|
||||
if (isset($val['alias'])) {
|
||||
// 别名设置
|
||||
$array = (array) $val['alias'];
|
||||
foreach (explode(',', $array[0]) as $v) {
|
||||
$tags[$close][$lib . $v] = $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 闭合标签
|
||||
if (!empty($tags[1])) {
|
||||
$nodes = [];
|
||||
$regex = $this->getRegex(array_keys($tags[1]), 1);
|
||||
if (preg_match_all($regex, $content, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) {
|
||||
$right = [];
|
||||
foreach ($matches as $match) {
|
||||
if ('' == $match[1][0]) {
|
||||
$name = strtolower($match[2][0]);
|
||||
// 如果有没闭合的标签头则取出最后一个
|
||||
if (!empty($right[$name])) {
|
||||
// $match[0][1]为标签结束符在模板中的位置
|
||||
$nodes[$match[0][1]] = [
|
||||
'name' => $name,
|
||||
'begin' => array_pop($right[$name]), // 标签开始符
|
||||
'end' => $match[0], // 标签结束符
|
||||
];
|
||||
}
|
||||
} else {
|
||||
// 标签头压入栈
|
||||
$right[strtolower($match[1][0])][] = $match[0];
|
||||
}
|
||||
}
|
||||
unset($right, $matches);
|
||||
// 按标签在模板中的位置从后向前排序
|
||||
krsort($nodes);
|
||||
}
|
||||
|
||||
$break = '<!--###break###--!>';
|
||||
if ($nodes) {
|
||||
$beginArray = [];
|
||||
// 标签替换 从后向前
|
||||
foreach ($nodes as $pos => $node) {
|
||||
// 对应的标签名
|
||||
$name = $tags[1][$node['name']];
|
||||
$alias = $lib . $name != $node['name'] ? ($lib ? strstr($node['name'], $lib) : $node['name']) : '';
|
||||
|
||||
// 解析标签属性
|
||||
$attrs = $this->parseAttr($node['begin'][0], $name, $alias);
|
||||
$method = 'tag' . $name;
|
||||
|
||||
// 读取标签库中对应的标签内容 replace[0]用来替换标签头,replace[1]用来替换标签尾
|
||||
$replace = explode($break, $this->$method($attrs, $break));
|
||||
|
||||
if (count($replace) > 1) {
|
||||
while ($beginArray) {
|
||||
$begin = end($beginArray);
|
||||
// 判断当前标签尾的位置是否在栈中最后一个标签头的后面,是则为子标签
|
||||
if ($node['end'][1] > $begin['pos']) {
|
||||
break;
|
||||
} else {
|
||||
// 不为子标签时,取出栈中最后一个标签头
|
||||
$begin = array_pop($beginArray);
|
||||
// 替换标签头部
|
||||
$content = substr_replace($content, $begin['str'], $begin['pos'], $begin['len']);
|
||||
}
|
||||
}
|
||||
// 替换标签尾部
|
||||
$content = substr_replace($content, $replace[1], $node['end'][1], strlen($node['end'][0]));
|
||||
// 把标签头压入栈
|
||||
$beginArray[] = ['pos' => $node['begin'][1], 'len' => strlen($node['begin'][0]), 'str' => $replace[0]];
|
||||
}
|
||||
}
|
||||
|
||||
while ($beginArray) {
|
||||
$begin = array_pop($beginArray);
|
||||
// 替换标签头部
|
||||
$content = substr_replace($content, $begin['str'], $begin['pos'], $begin['len']);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 自闭合标签
|
||||
if (!empty($tags[0])) {
|
||||
$regex = $this->getRegex(array_keys($tags[0]), 0);
|
||||
$content = preg_replace_callback($regex, function ($matches) use (&$tags, &$lib) {
|
||||
// 对应的标签名
|
||||
$name = $tags[0][strtolower($matches[1])];
|
||||
$alias = $lib . $name != $matches[1] ? ($lib ? strstr($matches[1], $lib) : $matches[1]) : '';
|
||||
// 解析标签属性
|
||||
$attrs = $this->parseAttr($matches[0], $name, $alias);
|
||||
$method = 'tag' . $name;
|
||||
return $this->$method($attrs, '');
|
||||
}, $content);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 按标签生成正则
|
||||
* @access public
|
||||
* @param array|string $tags 标签名
|
||||
* @param boolean $close 是否为闭合标签
|
||||
* @return string
|
||||
*/
|
||||
public function getRegex($tags, bool $close): string
|
||||
{
|
||||
$begin = $this->tpl->getConfig('taglib_begin');
|
||||
$end = $this->tpl->getConfig('taglib_end');
|
||||
$single = strlen(ltrim($begin, '\\')) == 1 && strlen(ltrim($end, '\\')) == 1 ? true : false;
|
||||
$tagName = is_array($tags) ? implode('|', $tags) : $tags;
|
||||
|
||||
if ($single) {
|
||||
if ($close) {
|
||||
// 如果是闭合标签
|
||||
$regex = $begin . '(?:(' . $tagName . ')\b(?>[^' . $end . ']*)|\/(' . $tagName . '))' . $end;
|
||||
} else {
|
||||
$regex = $begin . '(' . $tagName . ')\b(?>[^' . $end . ']*)' . $end;
|
||||
}
|
||||
} else {
|
||||
if ($close) {
|
||||
// 如果是闭合标签
|
||||
$regex = $begin . '(?:(' . $tagName . ')\b(?>(?:(?!' . $end . ').)*)|\/(' . $tagName . '))' . $end;
|
||||
} else {
|
||||
$regex = $begin . '(' . $tagName . ')\b(?>(?:(?!' . $end . ').)*)' . $end;
|
||||
}
|
||||
}
|
||||
|
||||
return '/' . $regex . '/is';
|
||||
}
|
||||
|
||||
/**
|
||||
* 分析标签属性 正则方式
|
||||
* @access public
|
||||
* @param string $str 标签属性字符串
|
||||
* @param string $name 标签名
|
||||
* @param string $alias 别名
|
||||
* @return array
|
||||
*/
|
||||
public function parseAttr(string $str, string $name, string $alias = ''): array
|
||||
{
|
||||
$regex = '/\s+(?>(?P<name>[\w-]+)\s*)=(?>\s*)([\"\'])(?P<value>(?:(?!\\2).)*)\\2/is';
|
||||
$result = [];
|
||||
|
||||
if (preg_match_all($regex, $str, $matches)) {
|
||||
foreach ($matches['name'] as $key => $val) {
|
||||
$result[$val] = $matches['value'][$key];
|
||||
}
|
||||
|
||||
if (!isset($this->tags[$name])) {
|
||||
// 检测是否存在别名定义
|
||||
foreach ($this->tags as $key => $val) {
|
||||
if (isset($val['alias'])) {
|
||||
$array = (array) $val['alias'];
|
||||
if (in_array($name, explode(',', $array[0]))) {
|
||||
$tag = $val;
|
||||
$type = !empty($array[1]) ? $array[1] : 'type';
|
||||
$result[$type] = $name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$tag = $this->tags[$name];
|
||||
// 设置了标签别名
|
||||
if (!empty($alias) && isset($tag['alias'])) {
|
||||
$type = !empty($tag['alias'][1]) ? $tag['alias'][1] : 'type';
|
||||
$result[$type] = $alias;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($tag['must'])) {
|
||||
$must = explode(',', $tag['must']);
|
||||
foreach ($must as $name) {
|
||||
if (!isset($result[$name])) {
|
||||
throw new Exception('tag attr must:' . $name);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 允许直接使用表达式的标签
|
||||
if (!empty($this->tags[$name]['expression'])) {
|
||||
static $_taglibs;
|
||||
if (!isset($_taglibs[$name])) {
|
||||
$_taglibs[$name][0] = strlen($this->tpl->getConfig('taglib_begin_origin') . $name);
|
||||
$_taglibs[$name][1] = strlen($this->tpl->getConfig('taglib_end_origin'));
|
||||
}
|
||||
$result['expression'] = substr($str, $_taglibs[$name][0], -$_taglibs[$name][1]);
|
||||
// 清除自闭合标签尾部/
|
||||
$result['expression'] = rtrim($result['expression'], '/');
|
||||
$result['expression'] = trim($result['expression']);
|
||||
} elseif (empty($this->tags[$name]) || !empty($this->tags[$name]['attr'])) {
|
||||
throw new Exception('tag error:' . $name);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析条件表达式
|
||||
* @access public
|
||||
* @param string $condition 表达式标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function parseCondition(string $condition): string
|
||||
{
|
||||
if (strpos($condition, ':')) {
|
||||
$condition = ' ' . substr(strstr($condition, ':'), 1);
|
||||
}
|
||||
|
||||
$condition = str_ireplace(array_keys($this->comparison), array_values($this->comparison), $condition);
|
||||
$this->tpl->parseVar($condition);
|
||||
|
||||
return $condition;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动识别构建变量
|
||||
* @access public
|
||||
* @param string $name 变量描述
|
||||
* @return string
|
||||
*/
|
||||
public function autoBuildVar(string &$name): string
|
||||
{
|
||||
$flag = substr($name, 0, 1);
|
||||
|
||||
if (':' == $flag) {
|
||||
// 以:开头为函数调用,解析前去掉:
|
||||
$name = substr($name, 1);
|
||||
} elseif ('$' != $flag && preg_match('/[a-zA-Z_]/', $flag)) {
|
||||
// XXX: 这句的写法可能还需要改进
|
||||
// 常量不需要解析
|
||||
if (defined($name)) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
// 不以$开头并且也不是常量,自动补上$前缀
|
||||
$name = '$' . $name;
|
||||
}
|
||||
|
||||
$this->tpl->parseVar($name);
|
||||
$this->tpl->parseVarFunction($name, false);
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取标签列表
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getTags(): array
|
||||
{
|
||||
return $this->tags;
|
||||
}
|
||||
}
|
||||
35
vendor/topthink/think-template/src/template/contract/DriverInterface.php
vendored
Normal file
35
vendor/topthink/think-template/src/template/contract/DriverInterface.php
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
namespace think\template\contract;
|
||||
|
||||
/**
|
||||
* 模板编译存储器驱动接口
|
||||
*/
|
||||
interface DriverInterface
|
||||
{
|
||||
/**
|
||||
* 写入编译缓存
|
||||
* @access public
|
||||
* @param string $cacheFile 缓存的文件名
|
||||
* @param string $content 缓存的内容
|
||||
* @return void
|
||||
*/
|
||||
public function write(string $cacheFile, string $content): void;
|
||||
|
||||
/**
|
||||
* 读取编译编译
|
||||
* @access public
|
||||
* @param string $cacheFile 缓存的文件名
|
||||
* @param array $vars 变量数组
|
||||
* @return void
|
||||
*/
|
||||
public function read(string $cacheFile, array $vars = []): void;
|
||||
|
||||
/**
|
||||
* 检查编译缓存是否有效
|
||||
* @access public
|
||||
* @param string $cacheFile 缓存的文件名
|
||||
* @param int $cacheTime 缓存时间
|
||||
* @return bool
|
||||
*/
|
||||
public function check(string $cacheFile, int $cacheTime): bool;
|
||||
}
|
||||
84
vendor/topthink/think-template/src/template/driver/File.php
vendored
Normal file
84
vendor/topthink/think-template/src/template/driver/File.php
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2023 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\template\driver;
|
||||
|
||||
use Exception;
|
||||
use think\template\contract\DriverInterface;
|
||||
|
||||
class File implements DriverInterface
|
||||
{
|
||||
protected $cacheFile;
|
||||
|
||||
/**
|
||||
* 写入编译缓存
|
||||
* @access public
|
||||
* @param string $cacheFile 缓存的文件名
|
||||
* @param string $content 缓存的内容
|
||||
* @return void
|
||||
*/
|
||||
public function write(string $cacheFile, string $content): void
|
||||
{
|
||||
// 检测模板目录
|
||||
$dir = dirname($cacheFile);
|
||||
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir, 0755, true);
|
||||
}
|
||||
|
||||
// 生成模板缓存文件
|
||||
if (false === file_put_contents($cacheFile, $content)) {
|
||||
throw new Exception('cache write error:' . $cacheFile, 11602);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取编译编译
|
||||
* @access public
|
||||
* @param string $cacheFile 缓存的文件名
|
||||
* @param array $vars 变量数组
|
||||
* @return void
|
||||
*/
|
||||
public function read(string $cacheFile, array $vars = []): void
|
||||
{
|
||||
$this->cacheFile = $cacheFile;
|
||||
|
||||
if (!empty($vars) && is_array($vars)) {
|
||||
// 模板阵列变量分解成为独立变量
|
||||
extract($vars, EXTR_OVERWRITE);
|
||||
}
|
||||
|
||||
//载入模版缓存文件
|
||||
include $this->cacheFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查编译缓存是否有效
|
||||
* @access public
|
||||
* @param string $cacheFile 缓存的文件名
|
||||
* @param int $cacheTime 缓存时间
|
||||
* @return bool
|
||||
*/
|
||||
public function check(string $cacheFile, int $cacheTime): bool
|
||||
{
|
||||
// 缓存文件不存在, 直接返回false
|
||||
if (!file_exists($cacheFile)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (0 != $cacheTime && time() > filemtime($cacheFile) + $cacheTime) {
|
||||
// 缓存是否在有效期
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
33
vendor/topthink/think-template/src/template/exception/TemplateNotFoundException.php
vendored
Normal file
33
vendor/topthink/think-template/src/template/exception/TemplateNotFoundException.php
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2023 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\template\exception;
|
||||
|
||||
class TemplateNotFoundException extends \RuntimeException
|
||||
{
|
||||
protected $template;
|
||||
|
||||
public function __construct(string $message, string $template = '')
|
||||
{
|
||||
$this->message = $message;
|
||||
$this->template = $template;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取模板文件
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getTemplate(): string
|
||||
{
|
||||
return $this->template;
|
||||
}
|
||||
}
|
||||
715
vendor/topthink/think-template/src/template/taglib/Cx.php
vendored
Normal file
715
vendor/topthink/think-template/src/template/taglib/Cx.php
vendored
Normal file
@ -0,0 +1,715 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2023 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\template\taglib;
|
||||
|
||||
use think\template\TagLib;
|
||||
|
||||
/**
|
||||
* CX标签库解析类
|
||||
* @category Think
|
||||
* @package Think
|
||||
* @subpackage Driver.Taglib
|
||||
* @author liu21st <liu21st@gmail.com>
|
||||
*/
|
||||
class Cx extends Taglib
|
||||
{
|
||||
|
||||
// 标签定义
|
||||
protected $tags = [
|
||||
// 标签定义: attr 属性列表 close 是否闭合(0 或者1 默认1) alias 标签别名 level 嵌套层次
|
||||
'php' => ['attr' => ''],
|
||||
'volist' => ['attr' => 'name,id,offset,length,key,mod', 'alias' => 'iterate'],
|
||||
'foreach' => ['attr' => 'name,id,item,key,offset,length,mod', 'expression' => true],
|
||||
'if' => ['attr' => 'condition', 'expression' => true],
|
||||
'elseif' => ['attr' => 'condition', 'close' => 0, 'expression' => true],
|
||||
'else' => ['attr' => '', 'close' => 0],
|
||||
'switch' => ['attr' => 'name', 'expression' => true],
|
||||
'case' => ['attr' => 'value,break', 'expression' => true],
|
||||
'default' => ['attr' => '', 'close' => 0],
|
||||
'compare' => ['attr' => 'name,value,type', 'alias' => ['eq,equal,notequal,neq,gt,lt,egt,elt,heq,nheq', 'type']],
|
||||
'range' => ['attr' => 'name,value,type', 'alias' => ['in,notin,between,notbetween', 'type']],
|
||||
'empty' => ['attr' => 'name'],
|
||||
'notempty' => ['attr' => 'name'],
|
||||
'present' => ['attr' => 'name'],
|
||||
'notpresent' => ['attr' => 'name'],
|
||||
'defined' => ['attr' => 'name'],
|
||||
'notdefined' => ['attr' => 'name'],
|
||||
'load' => ['attr' => 'file,href,type,value,basepath', 'close' => 0, 'alias' => ['import,css,js', 'type']],
|
||||
'assign' => ['attr' => 'name,value', 'close' => 0],
|
||||
'define' => ['attr' => 'name,value', 'close' => 0],
|
||||
'for' => ['attr' => 'start,end,name,comparison,step'],
|
||||
'url' => ['attr' => 'link,vars,suffix,domain', 'close' => 0, 'expression' => true],
|
||||
'function' => ['attr' => 'name,vars,use,call'],
|
||||
];
|
||||
|
||||
/**
|
||||
* php标签解析
|
||||
* 格式:
|
||||
* {php}echo $name{/php}
|
||||
* @access public
|
||||
* @param array $tag 标签属性
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function tagPhp(array $tag, string $content): string
|
||||
{
|
||||
$parseStr = '<?php ' . $content . ' ?>';
|
||||
return $parseStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* volist标签解析 循环输出数据集
|
||||
* 格式:
|
||||
* {volist name="userList" id="user" empty=""}
|
||||
* {user.username}
|
||||
* {user.email}
|
||||
* {/volist}
|
||||
* @access public
|
||||
* @param array $tag 标签属性
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function tagVolist(array $tag, string $content): string
|
||||
{
|
||||
$name = $tag['name'];
|
||||
$id = $tag['id'];
|
||||
$empty = isset($tag['empty']) ? $tag['empty'] : '';
|
||||
$key = !empty($tag['key']) ? $tag['key'] : 'i';
|
||||
$mod = isset($tag['mod']) ? $tag['mod'] : '2';
|
||||
$offset = !empty($tag['offset']) && is_numeric($tag['offset']) ? intval($tag['offset']) : 0;
|
||||
$length = !empty($tag['length']) && is_numeric($tag['length']) ? intval($tag['length']) : 'null';
|
||||
// 允许使用函数设定数据集 <volist name=":fun('arg')" id="vo">{$vo.name}</volist>
|
||||
$parseStr = '<?php ';
|
||||
$flag = substr($name, 0, 1);
|
||||
|
||||
if (':' == $flag) {
|
||||
$name = $this->autoBuildVar($name);
|
||||
$parseStr .= '$_result=' . $name . ';';
|
||||
$name = '$_result';
|
||||
} else {
|
||||
$name = $this->autoBuildVar($name);
|
||||
}
|
||||
|
||||
$parseStr .= 'if(is_array(' . $name . ') || ' . $name . ' instanceof \think\Collection || ' . $name . ' instanceof \think\Paginator): $' . $key . ' = 0;';
|
||||
|
||||
// 设置了输出数组长度
|
||||
if (0 != $offset || 'null' != $length) {
|
||||
$parseStr .= '$__LIST__ = is_array(' . $name . ') ? array_slice(' . $name . ',' . $offset . ',' . $length . ', true) : ' . $name . '->slice(' . $offset . ',' . $length . ', true); ';
|
||||
} else {
|
||||
$parseStr .= ' $__LIST__ = ' . $name . ';';
|
||||
}
|
||||
|
||||
$parseStr .= 'if( count($__LIST__)==0 ) : echo "' . $empty . '" ;';
|
||||
$parseStr .= 'else: ';
|
||||
$parseStr .= 'foreach($__LIST__ as $key=>$' . $id . '): ';
|
||||
$parseStr .= '$mod = ($' . $key . ' % ' . $mod . ' );';
|
||||
$parseStr .= '++$' . $key . ';?>';
|
||||
$parseStr .= $content;
|
||||
$parseStr .= '<?php endforeach; endif; else: echo "' . $empty . '" ;endif; ?>';
|
||||
|
||||
return $parseStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* foreach标签解析 循环输出数据集
|
||||
* 格式:
|
||||
* {foreach name="userList" id="user" key="key" index="i" mod="2" offset="3" length="5" empty=""}
|
||||
* {user.username}
|
||||
* {/foreach}
|
||||
* @access public
|
||||
* @param array $tag 标签属性
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function tagForeach(array $tag, string $content): string
|
||||
{
|
||||
// 直接使用表达式
|
||||
if (!empty($tag['expression'])) {
|
||||
$expression = ltrim(rtrim($tag['expression'], ')'), '(');
|
||||
$expression = $this->autoBuildVar($expression);
|
||||
$parseStr = '<?php foreach(' . $expression . '): ?>';
|
||||
$parseStr .= $content;
|
||||
$parseStr .= '<?php endforeach; ?>';
|
||||
return $parseStr;
|
||||
}
|
||||
|
||||
$name = $tag['name'];
|
||||
$key = !empty($tag['key']) ? $tag['key'] : 'key';
|
||||
$item = !empty($tag['id']) ? $tag['id'] : $tag['item'];
|
||||
$empty = isset($tag['empty']) ? $tag['empty'] : '';
|
||||
$offset = !empty($tag['offset']) && is_numeric($tag['offset']) ? intval($tag['offset']) : 0;
|
||||
$length = !empty($tag['length']) && is_numeric($tag['length']) ? intval($tag['length']) : 'null';
|
||||
|
||||
$parseStr = '<?php ';
|
||||
|
||||
// 支持用函数传数组
|
||||
if (':' == substr($name, 0, 1)) {
|
||||
$var = '$_' . uniqid();
|
||||
$name = $this->autoBuildVar($name);
|
||||
$parseStr .= $var . '=' . $name . '; ';
|
||||
$name = $var;
|
||||
} else {
|
||||
$name = $this->autoBuildVar($name);
|
||||
}
|
||||
|
||||
$parseStr .= 'if(is_array(' . $name . ') || ' . $name . ' instanceof \think\Collection || ' . $name . ' instanceof \think\Paginator): ';
|
||||
|
||||
// 设置了输出数组长度
|
||||
if (0 != $offset || 'null' != $length) {
|
||||
if (!isset($var)) {
|
||||
$var = '$_' . uniqid();
|
||||
}
|
||||
$parseStr .= $var . ' = is_array(' . $name . ') ? array_slice(' . $name . ',' . $offset . ',' . $length . ', true) : ' . $name . '->slice(' . $offset . ',' . $length . ', true); ';
|
||||
} else {
|
||||
$var = &$name;
|
||||
}
|
||||
|
||||
$parseStr .= 'if( count(' . $var . ')==0 ) : echo "' . $empty . '" ;';
|
||||
$parseStr .= 'else: ';
|
||||
|
||||
// 设置了索引项
|
||||
if (isset($tag['index'])) {
|
||||
$index = $tag['index'];
|
||||
$parseStr .= '$' . $index . '=0; ';
|
||||
}
|
||||
|
||||
$parseStr .= 'foreach(' . $var . ' as $' . $key . '=>$' . $item . '): ';
|
||||
|
||||
// 设置了索引项
|
||||
if (isset($tag['index'])) {
|
||||
$index = $tag['index'];
|
||||
if (isset($tag['mod'])) {
|
||||
$mod = (int) $tag['mod'];
|
||||
$parseStr .= '$mod = ($' . $index . ' % ' . $mod . '); ';
|
||||
}
|
||||
$parseStr .= '++$' . $index . '; ';
|
||||
}
|
||||
|
||||
$parseStr .= '?>';
|
||||
// 循环体中的内容
|
||||
$parseStr .= $content;
|
||||
$parseStr .= '<?php endforeach; endif; else: echo "' . $empty . '" ;endif; ?>';
|
||||
|
||||
return $parseStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* if标签解析
|
||||
* 格式:
|
||||
* {if condition=" $a eq 1"}
|
||||
* {elseif condition="$a eq 2" /}
|
||||
* {else /}
|
||||
* {/if}
|
||||
* 表达式支持 eq neq gt egt lt elt == > >= < <= or and || &&
|
||||
* @access public
|
||||
* @param array $tag 标签属性
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function tagIf(array $tag, string $content): string
|
||||
{
|
||||
$condition = !empty($tag['expression']) ? $tag['expression'] : $tag['condition'];
|
||||
$condition = $this->parseCondition($condition);
|
||||
$parseStr = '<?php if(' . $condition . '): ?>' . $content . '<?php endif; ?>';
|
||||
|
||||
return $parseStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* elseif标签解析
|
||||
* 格式:见if标签
|
||||
* @access public
|
||||
* @param array $tag 标签属性
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function tagElseif(array $tag, string $content): string
|
||||
{
|
||||
$condition = !empty($tag['expression']) ? $tag['expression'] : $tag['condition'];
|
||||
$condition = $this->parseCondition($condition);
|
||||
$parseStr = '<?php elseif(' . $condition . '): ?>';
|
||||
|
||||
return $parseStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* else标签解析
|
||||
* 格式:见if标签
|
||||
* @access public
|
||||
* @param array $tag 标签属性
|
||||
* @return string
|
||||
*/
|
||||
public function tagElse(array $tag): string
|
||||
{
|
||||
$parseStr = '<?php else: ?>';
|
||||
|
||||
return $parseStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* switch标签解析
|
||||
* 格式:
|
||||
* {switch name="a.name"}
|
||||
* {case value="1" break="false"}1{/case}
|
||||
* {case value="2" }2{/case}
|
||||
* {default /}other
|
||||
* {/switch}
|
||||
* @access public
|
||||
* @param array $tag 标签属性
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function tagSwitch(array $tag, string $content): string
|
||||
{
|
||||
$name = !empty($tag['expression']) ? $tag['expression'] : $tag['name'];
|
||||
$name = $this->autoBuildVar($name);
|
||||
$parseStr = '<?php switch(' . $name . '): ?>' . $content . '<?php endswitch; ?>';
|
||||
|
||||
return $parseStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* case标签解析 需要配合switch才有效
|
||||
* @access public
|
||||
* @param array $tag 标签属性
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function tagCase(array $tag, string $content): string
|
||||
{
|
||||
$value = isset($tag['expression']) ? $tag['expression'] : $tag['value'];
|
||||
$flag = substr($value, 0, 1);
|
||||
|
||||
if ('$' == $flag || ':' == $flag) {
|
||||
$value = $this->autoBuildVar($value);
|
||||
$value = 'case ' . $value . ':';
|
||||
} elseif (strpos($value, '|')) {
|
||||
$values = explode('|', $value);
|
||||
$value = '';
|
||||
foreach ($values as $val) {
|
||||
$value .= 'case "' . addslashes($val) . '":';
|
||||
}
|
||||
} else {
|
||||
$value = 'case "' . $value . '":';
|
||||
}
|
||||
|
||||
$parseStr = '<?php ' . $value . ' ?>' . $content;
|
||||
$isBreak = isset($tag['break']) ? $tag['break'] : '';
|
||||
|
||||
if ('' == $isBreak || $isBreak) {
|
||||
$parseStr .= '<?php break; ?>';
|
||||
}
|
||||
|
||||
return $parseStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* default标签解析 需要配合switch才有效
|
||||
* 使用: {default /}ddfdf
|
||||
* @access public
|
||||
* @param array $tag 标签属性
|
||||
* @return string
|
||||
*/
|
||||
public function tagDefault(array $tag): string
|
||||
{
|
||||
$parseStr = '<?php default: ?>';
|
||||
|
||||
return $parseStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* compare标签解析
|
||||
* 用于值的比较 支持 eq neq gt lt egt elt heq nheq 默认是eq
|
||||
* 格式: {compare name="" type="eq" value="" }content{/compare}
|
||||
* @access public
|
||||
* @param array $tag 标签属性
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function tagCompare(array $tag, string $content): string
|
||||
{
|
||||
$name = $tag['name'];
|
||||
$value = $tag['value'];
|
||||
$type = isset($tag['type']) ? $tag['type'] : 'eq'; // 比较类型
|
||||
$name = $this->autoBuildVar($name);
|
||||
$flag = substr($value, 0, 1);
|
||||
|
||||
if ('$' == $flag || ':' == $flag) {
|
||||
$value = $this->autoBuildVar($value);
|
||||
} else {
|
||||
$value = '\'' . $value . '\'';
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case 'equal':
|
||||
$type = 'eq';
|
||||
break;
|
||||
case 'notequal':
|
||||
$type = 'neq';
|
||||
break;
|
||||
}
|
||||
$type = $this->parseCondition(' ' . $type . ' ');
|
||||
$parseStr = '<?php if(' . $name . ' ' . $type . ' ' . $value . '): ?>' . $content . '<?php endif; ?>';
|
||||
|
||||
return $parseStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* range标签解析
|
||||
* 如果某个变量存在于某个范围 则输出内容 type= in 表示在范围内 否则表示在范围外
|
||||
* 格式: {range name="var|function" value="val" type='in|notin' }content{/range}
|
||||
* example: {range name="a" value="1,2,3" type='in' }content{/range}
|
||||
* @access public
|
||||
* @param array $tag 标签属性
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function tagRange(array $tag, string $content): string
|
||||
{
|
||||
$name = $tag['name'];
|
||||
$value = $tag['value'];
|
||||
$type = isset($tag['type']) ? $tag['type'] : 'in'; // 比较类型
|
||||
|
||||
$name = $this->autoBuildVar($name);
|
||||
$flag = substr($value, 0, 1);
|
||||
|
||||
if ('$' == $flag || ':' == $flag) {
|
||||
$value = $this->autoBuildVar($value);
|
||||
$str = 'is_array(' . $value . ')?' . $value . ':explode(\',\',' . $value . ')';
|
||||
} else {
|
||||
$value = '"' . $value . '"';
|
||||
$str = 'explode(\',\',' . $value . ')';
|
||||
}
|
||||
|
||||
if ('between' == $type) {
|
||||
$parseStr = '<?php $_RANGE_VAR_=' . $str . ';if(' . $name . '>= $_RANGE_VAR_[0] && ' . $name . '<= $_RANGE_VAR_[1]):?>' . $content . '<?php endif; ?>';
|
||||
} elseif ('notbetween' == $type) {
|
||||
$parseStr = '<?php $_RANGE_VAR_=' . $str . ';if(' . $name . '<$_RANGE_VAR_[0] || ' . $name . '>$_RANGE_VAR_[1]):?>' . $content . '<?php endif; ?>';
|
||||
} else {
|
||||
$fun = ('in' == $type) ? 'in_array' : '!in_array';
|
||||
$parseStr = '<?php if(' . $fun . '((' . $name . '), ' . $str . ')): ?>' . $content . '<?php endif; ?>';
|
||||
}
|
||||
|
||||
return $parseStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* present标签解析
|
||||
* 如果某个变量已经设置 则输出内容
|
||||
* 格式: {present name="" }content{/present}
|
||||
* @access public
|
||||
* @param array $tag 标签属性
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function tagPresent(array $tag, string $content): string
|
||||
{
|
||||
$name = $tag['name'];
|
||||
$name = $this->autoBuildVar($name);
|
||||
$parseStr = '<?php if(isset(' . $name . ')): ?>' . $content . '<?php endif; ?>';
|
||||
|
||||
return $parseStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* notpresent标签解析
|
||||
* 如果某个变量没有设置,则输出内容
|
||||
* 格式: {notpresent name="" }content{/notpresent}
|
||||
* @access public
|
||||
* @param array $tag 标签属性
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function tagNotpresent(array $tag, string $content): string
|
||||
{
|
||||
$name = $tag['name'];
|
||||
$name = $this->autoBuildVar($name);
|
||||
$parseStr = '<?php if(!isset(' . $name . ')): ?>' . $content . '<?php endif; ?>';
|
||||
|
||||
return $parseStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* empty标签解析
|
||||
* 如果某个变量为empty 则输出内容
|
||||
* 格式: {empty name="" }content{/empty}
|
||||
* @access public
|
||||
* @param array $tag 标签属性
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function tagEmpty(array $tag, string $content): string
|
||||
{
|
||||
$name = $tag['name'];
|
||||
$name = $this->autoBuildVar($name);
|
||||
$parseStr = '<?php if(empty(' . $name . ') || ((' . $name . ' instanceof \think\Collection || ' . $name . ' instanceof \think\Paginator ) && ' . $name . '->isEmpty())): ?>' . $content . '<?php endif; ?>';
|
||||
|
||||
return $parseStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* notempty标签解析
|
||||
* 如果某个变量不为empty 则输出内容
|
||||
* 格式: {notempty name="" }content{/notempty}
|
||||
* @access public
|
||||
* @param array $tag 标签属性
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function tagNotempty(array $tag, string $content): string
|
||||
{
|
||||
$name = $tag['name'];
|
||||
$name = $this->autoBuildVar($name);
|
||||
$parseStr = '<?php if(!(empty(' . $name . ') || ((' . $name . ' instanceof \think\Collection || ' . $name . ' instanceof \think\Paginator ) && ' . $name . '->isEmpty()))): ?>' . $content . '<?php endif; ?>';
|
||||
|
||||
return $parseStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否已经定义了该常量
|
||||
* {defined name='TXT'}已定义{/defined}
|
||||
* @access public
|
||||
* @param array $tag
|
||||
* @param string $content
|
||||
* @return string
|
||||
*/
|
||||
public function tagDefined(array $tag, string $content): string
|
||||
{
|
||||
$name = $tag['name'];
|
||||
$parseStr = '<?php if(defined("' . $name . '")): ?>' . $content . '<?php endif; ?>';
|
||||
|
||||
return $parseStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否没有定义了该常量
|
||||
* {notdefined name='TXT'}已定义{/notdefined}
|
||||
* @access public
|
||||
* @param array $tag
|
||||
* @param string $content
|
||||
* @return string
|
||||
*/
|
||||
public function tagNotdefined(array $tag, string $content): string
|
||||
{
|
||||
$name = $tag['name'];
|
||||
$parseStr = '<?php if(!defined("' . $name . '")): ?>' . $content . '<?php endif; ?>';
|
||||
|
||||
return $parseStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* load 标签解析 {load file="/static/js/base.js" /}
|
||||
* 格式:{load file="/static/css/base.css" /}
|
||||
* @access public
|
||||
* @param array $tag 标签属性
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function tagLoad(array $tag, string $content): string
|
||||
{
|
||||
$file = isset($tag['file']) ? $tag['file'] : $tag['href'];
|
||||
$type = isset($tag['type']) ? strtolower($tag['type']) : '';
|
||||
|
||||
$parseStr = '';
|
||||
$endStr = '';
|
||||
|
||||
// 判断是否存在加载条件 允许使用函数判断(默认为isset)
|
||||
if (isset($tag['value'])) {
|
||||
$name = $tag['value'];
|
||||
$name = $this->autoBuildVar($name);
|
||||
$name = 'isset(' . $name . ')';
|
||||
$parseStr .= '<?php if(' . $name . '): ?>';
|
||||
$endStr = '<?php endif; ?>';
|
||||
}
|
||||
|
||||
// 文件方式导入
|
||||
$array = explode(',', $file);
|
||||
|
||||
foreach ($array as $val) {
|
||||
$type = strtolower(substr(strrchr($val, '.'), 1));
|
||||
switch ($type) {
|
||||
case 'js':
|
||||
$parseStr .= '<script type="text/javascript" src="' . $val . '"></script>';
|
||||
break;
|
||||
case 'css':
|
||||
$parseStr .= '<link rel="stylesheet" type="text/css" href="' . $val . '" />';
|
||||
break;
|
||||
case 'php':
|
||||
$parseStr .= '<?php include "' . $val . '"; ?>';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $parseStr . $endStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* assign标签解析
|
||||
* 在模板中给某个变量赋值 支持变量赋值
|
||||
* 格式: {assign name="" value="" /}
|
||||
* @access public
|
||||
* @param array $tag 标签属性
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function tagAssign(array $tag, string $content): string
|
||||
{
|
||||
$name = $this->autoBuildVar($tag['name']);
|
||||
$flag = substr($tag['value'], 0, 1);
|
||||
|
||||
if ('$' == $flag || ':' == $flag) {
|
||||
$value = $this->autoBuildVar($tag['value']);
|
||||
} else {
|
||||
$value = '\'' . $tag['value'] . '\'';
|
||||
}
|
||||
|
||||
$parseStr = '<?php ' . $name . ' = ' . $value . '; ?>';
|
||||
|
||||
return $parseStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* define标签解析
|
||||
* 在模板中定义常量 支持变量赋值
|
||||
* 格式: {define name="" value="" /}
|
||||
* @access public
|
||||
* @param array $tag 标签属性
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function tagDefine(array $tag, string $content): string
|
||||
{
|
||||
$name = '\'' . $tag['name'] . '\'';
|
||||
$flag = substr($tag['value'], 0, 1);
|
||||
|
||||
if ('$' == $flag || ':' == $flag) {
|
||||
$value = $this->autoBuildVar($tag['value']);
|
||||
} else {
|
||||
$value = '\'' . $tag['value'] . '\'';
|
||||
}
|
||||
|
||||
$parseStr = '<?php define(' . $name . ', ' . $value . '); ?>';
|
||||
|
||||
return $parseStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* for标签解析
|
||||
* 格式:
|
||||
* {for start="" end="" comparison="" step="" name=""}
|
||||
* content
|
||||
* {/for}
|
||||
* @access public
|
||||
* @param array $tag 标签属性
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function tagFor(array $tag, string $content): string
|
||||
{
|
||||
//设置默认值
|
||||
$start = 0;
|
||||
$end = 0;
|
||||
$step = 1;
|
||||
$comparison = 'lt';
|
||||
$name = 'i';
|
||||
$rand = rand(); //添加随机数,防止嵌套变量冲突
|
||||
|
||||
//获取属性
|
||||
foreach ($tag as $key => $value) {
|
||||
$value = trim($value);
|
||||
$flag = substr($value, 0, 1);
|
||||
if ('$' == $flag || ':' == $flag) {
|
||||
$value = $this->autoBuildVar($value);
|
||||
}
|
||||
|
||||
switch ($key) {
|
||||
case 'start':
|
||||
$start = $value;
|
||||
break;
|
||||
case 'end':
|
||||
$end = $value;
|
||||
break;
|
||||
case 'step':
|
||||
$step = $value;
|
||||
break;
|
||||
case 'comparison':
|
||||
$comparison = $value;
|
||||
break;
|
||||
case 'name':
|
||||
$name = $value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$parseStr = '<?php $__FOR_START_' . $rand . '__=' . $start . ';$__FOR_END_' . $rand . '__=' . $end . ';';
|
||||
$parseStr .= 'for($' . $name . '=$__FOR_START_' . $rand . '__;' . $this->parseCondition('$' . $name . ' ' . $comparison . ' $__FOR_END_' . $rand . '__') . ';$' . $name . '+=' . $step . '){ ?>';
|
||||
$parseStr .= $content;
|
||||
$parseStr .= '<?php } ?>';
|
||||
|
||||
return $parseStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* url函数的tag标签
|
||||
* 格式:{url link="模块/控制器/方法" vars="参数" suffix="true或者false 是否带有后缀" domain="true或者false 是否携带域名" /}
|
||||
* @access public
|
||||
* @param array $tag 标签属性
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function tagUrl(array $tag, string $content): string
|
||||
{
|
||||
$url = isset($tag['link']) ? $tag['link'] : '';
|
||||
$vars = isset($tag['vars']) ? $tag['vars'] : '';
|
||||
$suffix = isset($tag['suffix']) ? $tag['suffix'] : 'true';
|
||||
$domain = isset($tag['domain']) ? $tag['domain'] : 'false';
|
||||
|
||||
return '<?php echo url("' . $url . '","' . $vars . '",' . $suffix . ',' . $domain . ');?>';
|
||||
}
|
||||
|
||||
/**
|
||||
* function标签解析 匿名函数,可实现递归
|
||||
* 使用:
|
||||
* {function name="func" vars="$data" call="$list" use="&$a,&$b"}
|
||||
* {if is_array($data)}
|
||||
* {foreach $data as $val}
|
||||
* {~func($val) /}
|
||||
* {/foreach}
|
||||
* {else /}
|
||||
* {$data}
|
||||
* {/if}
|
||||
* {/function}
|
||||
* @access public
|
||||
* @param array $tag 标签属性
|
||||
* @param string $content 标签内容
|
||||
* @return string
|
||||
*/
|
||||
public function tagFunction(array $tag, string $content): string
|
||||
{
|
||||
$name = !empty($tag['name']) ? $tag['name'] : 'func';
|
||||
$vars = !empty($tag['vars']) ? $tag['vars'] : '';
|
||||
$call = !empty($tag['call']) ? $tag['call'] : '';
|
||||
$use = ['&$' . $name];
|
||||
|
||||
if (!empty($tag['use'])) {
|
||||
foreach (explode(',', $tag['use']) as $val) {
|
||||
$use[] = '&' . ltrim(trim($val), '&');
|
||||
}
|
||||
}
|
||||
|
||||
$parseStr = '<?php $' . $name . '=function(' . $vars . ') use(' . implode(',', $use) . ') {';
|
||||
$parseStr .= ' ?>' . $content . '<?php }; ';
|
||||
$parseStr .= $call ? '$' . $name . '(' . $call . '); ?>' : '?>';
|
||||
|
||||
return $parseStr;
|
||||
}
|
||||
}
|
||||
3
vendor/topthink/think-template/tests/bootstrap.php
vendored
Normal file
3
vendor/topthink/think-template/tests/bootstrap.php
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
<?php
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
require __DIR__ . '/tag/Demo.php';
|
||||
46
vendor/topthink/think-template/tests/tag/Demo.php
vendored
Normal file
46
vendor/topthink/think-template/tests/tag/Demo.php
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
namespace tag;
|
||||
|
||||
use think\template\TagLib;
|
||||
class Demo extends TagLib{
|
||||
/**
|
||||
* 定义标签列表
|
||||
*/
|
||||
protected $tags = [
|
||||
// 标签定义: attr 属性列表 close 是否闭合(0 或者1 默认1) alias 标签别名 level 嵌套层次
|
||||
'close' => ['attr' => 'time,format', 'close' => 0], //闭合标签,默认为不闭合
|
||||
'open' => ['attr' => 'name,type', 'close' => 1],
|
||||
|
||||
];
|
||||
|
||||
/**
|
||||
* 这是一个闭合标签的简单演示
|
||||
*/
|
||||
public function tagClose($tag)
|
||||
{
|
||||
$format = empty($tag['format']) ? 'Y-m-d H:i:s' : $tag['format'];
|
||||
$time = empty($tag['time']) ? time() : $tag['time'];
|
||||
$parse = '<?php ';
|
||||
$parse .= 'echo date("' . $format . '",' . $time . ');';
|
||||
$parse .= ' ?>';
|
||||
return $parse;
|
||||
}
|
||||
|
||||
/**
|
||||
* 这是一个非闭合标签的简单演示
|
||||
*/
|
||||
public function tagOpen($tag, $content)
|
||||
{
|
||||
$type = empty($tag['type']) ? 0 : 1; // 这个type目的是为了区分类型,一般来源是数据库
|
||||
$name = $tag['name']; // name是必填项,这里不做判断了
|
||||
$parse = '<?php ';
|
||||
$parse .= '$test_arr=[[1,3,5,7,9],[2,4,6,8,10]];'; // 这里是模拟数据
|
||||
$parse .= '$__LIST__ = $test_arr[' . $type . '];';
|
||||
$parse .= ' ?>';
|
||||
$parse .= '{volist name="__LIST__" id="' . $name . '"}';
|
||||
$parse .= $content;
|
||||
$parse .= '{/volist}';
|
||||
return $parse;
|
||||
}
|
||||
|
||||
}
|
||||
2
vendor/topthink/think-template/tests/template/extend.html
vendored
Normal file
2
vendor/topthink/think-template/tests/template/extend.html
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
{block name="title"}标题{/block}
|
||||
{block name="main"}主内容{/block}
|
||||
1
vendor/topthink/think-template/tests/template/fetch.html
vendored
Normal file
1
vendor/topthink/think-template/tests/template/fetch.html
vendored
Normal file
@ -0,0 +1 @@
|
||||
success
|
||||
1
vendor/topthink/think-template/tests/template/include.html
vendored
Normal file
1
vendor/topthink/think-template/tests/template/include.html
vendored
Normal file
@ -0,0 +1 @@
|
||||
include
|
||||
1
vendor/topthink/think-template/tests/template/layout.html
vendored
Normal file
1
vendor/topthink/think-template/tests/template/layout.html
vendored
Normal file
@ -0,0 +1 @@
|
||||
start{__CONTENT__}end
|
||||
247
vendor/topthink/think-template/tests/think/TemplateTest.php
vendored
Normal file
247
vendor/topthink/think-template/tests/think/TemplateTest.php
vendored
Normal file
@ -0,0 +1,247 @@
|
||||
<?php
|
||||
|
||||
namespace think;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use tag\Demo;
|
||||
|
||||
class TemplateTest extends TestCase
|
||||
{
|
||||
public function getTemplate()
|
||||
{
|
||||
$config = [
|
||||
'view_path' => __DIR__ . '/../template' . DIRECTORY_SEPARATOR,
|
||||
'cache_path' => __DIR__ . '/../cache' . DIRECTORY_SEPARATOR,
|
||||
'tpl_cache' => false,
|
||||
'tpl_replace_string' => ['__STATIC__' => '/static'],
|
||||
'taglib_pre_load' => Demo::class,
|
||||
];
|
||||
return new Template($config);
|
||||
}
|
||||
|
||||
// 直接渲染
|
||||
public function testDisplay()
|
||||
{
|
||||
$this->expectOutputString('hello-thinkphp');
|
||||
|
||||
$template = $this->getTemplate();
|
||||
$content = '{$name}-{$email}';
|
||||
$template->display($content, ['name' => 'hello', 'email' => 'thinkphp']);
|
||||
}
|
||||
|
||||
// 渲染文件
|
||||
public function testFetch()
|
||||
{
|
||||
$this->expectOutputString('success');
|
||||
|
||||
$template = $this->getTemplate();
|
||||
$template->fetch('fetch');
|
||||
}
|
||||
|
||||
// 布局
|
||||
public function testLayout()
|
||||
{
|
||||
$this->expectOutputString('startsuccessend');
|
||||
|
||||
$template = $this->getTemplate();
|
||||
$template->layout('layout');
|
||||
$template->fetch('fetch');
|
||||
$template->layout(false);
|
||||
}
|
||||
|
||||
// 扩展解析
|
||||
public function testExtend()
|
||||
{
|
||||
$this->expectOutputString('test.name');
|
||||
|
||||
$template = $this->getTemplate();
|
||||
$template->extend('$Cms', function (array $vars) {
|
||||
return '\'' . implode('.', $vars) . '\'';
|
||||
});
|
||||
|
||||
$content = '{$Cms.test.name}';
|
||||
$template->display($content);
|
||||
}
|
||||
|
||||
// 变量
|
||||
public function testParseVar()
|
||||
{
|
||||
$this->expectOutputString('e10adc3949ba59abbe56e057f20f883e');
|
||||
|
||||
$template = $this->getTemplate();
|
||||
$content = '{:md5("123456")}';
|
||||
$template->display($content, ['password' => '123456']);
|
||||
}
|
||||
|
||||
// 变量使用函数
|
||||
public function testParseVarFunction()
|
||||
{
|
||||
$this->expectOutputString('e10adc3949ba59abbe56e057f20f883e-123456-666456');
|
||||
|
||||
$template = $this->getTemplate();
|
||||
$content = '{$password|md5}-{$password|raw}-{$password|str_replace=123,666,###}';
|
||||
$template->display($content, ['password' => '123456']);
|
||||
}
|
||||
|
||||
// 默认值
|
||||
public function testParseDefaultFunction()
|
||||
{
|
||||
$this->expectOutputString('test');
|
||||
|
||||
$template = $this->getTemplate();
|
||||
$content = '{$default|default="test"}';
|
||||
$template->display($content);
|
||||
}
|
||||
|
||||
// 系统变量
|
||||
public function testParseThinkVar()
|
||||
{
|
||||
$this->expectOutputString($_SERVER['PHP_SELF'] . '-' . PHP_VERSION . '-' . PHP_VERSION);
|
||||
|
||||
$template = $this->getTemplate();
|
||||
$content = '{$Request.server.PHP_SELF}-{$Think.const.PHP_VERSION}-{$Think.PHP_VERSION}';
|
||||
$template->display($content);
|
||||
}
|
||||
|
||||
// 数组
|
||||
public function testParseArrayVar()
|
||||
{
|
||||
$this->expectOutputString('thinkphp<br/>thinkphp');
|
||||
|
||||
$template = $this->getTemplate();
|
||||
$content = '{$data.name}<br/>{$data["name"]}';
|
||||
$template->display($content, ['data' => ['name' => 'thinkphp']]);
|
||||
}
|
||||
|
||||
// 对象
|
||||
public function testParseObjectVar()
|
||||
{
|
||||
$this->expectOutputString('a-b-c-d');
|
||||
|
||||
$object = new class {
|
||||
public string $a = 'a';
|
||||
public const b = 'b';
|
||||
|
||||
public function c($str) {
|
||||
return $str;
|
||||
}
|
||||
|
||||
static public function d($str) {
|
||||
return $str;
|
||||
}
|
||||
};
|
||||
|
||||
$template = $this->getTemplate();
|
||||
$content = '{$data->a}-{$data::b}-{$data->c("c")}-{$data::d("d")}';
|
||||
$template->display($content, ['data' => $object]);
|
||||
}
|
||||
|
||||
// 运算符
|
||||
public function testParseVarOperator()
|
||||
{
|
||||
$this->expectOutputString('2-0-2-0.5-1-1-1-4');
|
||||
|
||||
$template = $this->getTemplate();
|
||||
$content = '{$a+1}-{$a-1}-{$a*$b}-{$a/$b}-{$a%$b}-{$a++}-{--$b}-{$a+$b+abs(-1)}';
|
||||
$template->display($content, ['a' => 1, 'b' => 2]);
|
||||
}
|
||||
|
||||
// 三元运算符
|
||||
public function testParseTernaryOperator()
|
||||
{
|
||||
$this->expectOutputString('真-默认值-有值-NO');
|
||||
|
||||
$template = $this->getTemplate();
|
||||
$content = '{$true?"真":"假"}-{$null ?? "默认值"}-{$one ?= "有值"}-{$zero ?: "NO"}';
|
||||
$template->display($content, ['null' => null, 'zero' => 0, 'true' => true, 'one' => 1]);
|
||||
}
|
||||
|
||||
// 单行注释
|
||||
public function testParseSimpleNote()
|
||||
{
|
||||
$this->expectOutputString('123');
|
||||
|
||||
$template = $this->getTemplate();
|
||||
$content = '123{// 注释内容 }';
|
||||
$template->display($content);
|
||||
}
|
||||
|
||||
// 多行注释
|
||||
public function testParseMoreNote()
|
||||
{
|
||||
$this->expectOutputString('123');
|
||||
|
||||
$template = $this->getTemplate();
|
||||
$content = "123{/* 这是模板\r\n注释内容*/ }";
|
||||
$template->display($content);
|
||||
}
|
||||
|
||||
// 引用标签
|
||||
public function testParseInclude()
|
||||
{
|
||||
$this->expectOutputString('include');
|
||||
|
||||
$template = $this->getTemplate();
|
||||
$content = '{include file="include"}';
|
||||
$template->display($content);
|
||||
}
|
||||
|
||||
// 继承标签
|
||||
public function testParseExtend()
|
||||
{
|
||||
$this->expectOutputString("title\r\n主内容main\r\n");
|
||||
|
||||
$template = $this->getTemplate();
|
||||
$content = "{extend name='extend' /}\r\n{block name='title'}title{/block}\r\n{block name='main'}{__block__}main{/block}";
|
||||
$template->display($content);
|
||||
}
|
||||
|
||||
// 输出替换
|
||||
public function testParseReplaceString()
|
||||
{
|
||||
$this->expectOutputString("start/staticend");
|
||||
|
||||
$template = $this->getTemplate();
|
||||
$content = "start__STATIC__end";
|
||||
$template->display($content);
|
||||
}
|
||||
|
||||
// 标签扩展
|
||||
public function testParseDemoTag()
|
||||
{
|
||||
$this->expectOutputString(<<<'HTML'
|
||||
<h1>闭合标签</h1>
|
||||
2022-12-31 16:00:00<hr>
|
||||
<h1>开放标签</h1>
|
||||
0=>1<br>
|
||||
1=>3<br>
|
||||
2=>5<br>
|
||||
3=>7<br>
|
||||
4=>9<br>
|
||||
<br>
|
||||
0=>2<br>
|
||||
1=>4<br>
|
||||
2=>6<br>
|
||||
3=>8<br>
|
||||
4=>10<br>
|
||||
|
||||
HTML);
|
||||
|
||||
$template = $this->getTemplate();
|
||||
$content = <<<'HTML'
|
||||
<h1>闭合标签</h1>
|
||||
{demo:close time='$demo_time'/}
|
||||
<hr>
|
||||
<h1>开放标签</h1>
|
||||
{demo:open name='demo_name'}
|
||||
{$key}=>{$demo_name}<br>
|
||||
{/demo:open}
|
||||
<br>
|
||||
{demo:open name='demo_name' type='1'}
|
||||
{$key}=>{$demo_name}<br>
|
||||
{/demo:open}
|
||||
HTML;
|
||||
|
||||
$template->display($content, ['demo_time' => 1672502400]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user