1
3
vendor/topthink/think-captcha/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
/vendor/
|
||||
/composer.lock
|
||||
.idea
|
||||
32
vendor/topthink/think-captcha/LICENSE
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
ThinkPHP遵循Apache2开源协议发布,并提供免费使用。
|
||||
版权所有Copyright © 2006-2016 by ThinkPHP (http://thinkphp.cn)
|
||||
All rights reserved。
|
||||
ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。
|
||||
|
||||
Apache Licence是著名的非盈利开源组织Apache采用的协议。
|
||||
该协议和BSD类似,鼓励代码共享和尊重原作者的著作权,
|
||||
允许代码修改,再作为开源或商业软件发布。需要满足
|
||||
的条件:
|
||||
1. 需要给代码的用户一份Apache Licence ;
|
||||
2. 如果你修改了代码,需要在被修改的文件中说明;
|
||||
3. 在延伸的代码中(修改和有源代码衍生的代码中)需要
|
||||
带有原来代码中的协议,商标,专利声明和其他原来作者规
|
||||
定需要包含的说明;
|
||||
4. 如果再发布的产品中包含一个Notice文件,则在Notice文
|
||||
件中需要带有本协议内容。你可以在Notice中增加自己的
|
||||
许可,但不可以表现为对Apache Licence构成更改。
|
||||
具体的协议参考:http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
33
vendor/topthink/think-captcha/README.md
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
# think-captcha
|
||||
thinkphp5 验证码类库
|
||||
|
||||
## 安装
|
||||
> composer require topthink/think-captcha
|
||||
|
||||
|
||||
##使用
|
||||
|
||||
###模板里输出验证码
|
||||
|
||||
~~~
|
||||
<div>{:captcha_img()}</div>
|
||||
~~~
|
||||
或者
|
||||
~~~
|
||||
<div><img src="{:captcha_src()}" alt="captcha" /></div>
|
||||
~~~
|
||||
> 上面两种的最终效果是一样的
|
||||
|
||||
### 控制器里验证
|
||||
使用TP5的内置验证功能即可
|
||||
~~~
|
||||
$this->validate($data,[
|
||||
'captcha|验证码'=>'require|captcha'
|
||||
]);
|
||||
~~~
|
||||
或者手动验证
|
||||
~~~
|
||||
if(!captcha_check($captcha)){
|
||||
//验证失败
|
||||
};
|
||||
~~~
|
||||
BIN
vendor/topthink/think-captcha/assets/bgs/1.jpg
vendored
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
vendor/topthink/think-captcha/assets/bgs/2.jpg
vendored
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
vendor/topthink/think-captcha/assets/bgs/3.jpg
vendored
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
vendor/topthink/think-captcha/assets/bgs/4.jpg
vendored
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
vendor/topthink/think-captcha/assets/bgs/5.jpg
vendored
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
vendor/topthink/think-captcha/assets/bgs/6.jpg
vendored
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
vendor/topthink/think-captcha/assets/bgs/7.jpg
vendored
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
vendor/topthink/think-captcha/assets/bgs/8.jpg
vendored
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
vendor/topthink/think-captcha/assets/ttfs/1.ttf
vendored
Normal file
BIN
vendor/topthink/think-captcha/assets/ttfs/2.ttf
vendored
Normal file
BIN
vendor/topthink/think-captcha/assets/ttfs/3.ttf
vendored
Normal file
BIN
vendor/topthink/think-captcha/assets/ttfs/4.ttf
vendored
Normal file
BIN
vendor/topthink/think-captcha/assets/ttfs/5.ttf
vendored
Normal file
BIN
vendor/topthink/think-captcha/assets/ttfs/6.ttf
vendored
Normal file
BIN
vendor/topthink/think-captcha/assets/zhttfs/1.ttf
vendored
Normal file
23
vendor/topthink/think-captcha/composer.json
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "topthink/think-captcha",
|
||||
"description": "captcha package for thinkphp5",
|
||||
"authors": [
|
||||
{
|
||||
"name": "yunwuxin",
|
||||
"email": "448901948@qq.com"
|
||||
}
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"require": {
|
||||
"topthink/think-installer": ">=1.0.10",
|
||||
"topthink/framework": "~5.0.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"think\\captcha\\": "src/"
|
||||
},
|
||||
"files": [
|
||||
"src/helper.php"
|
||||
]
|
||||
}
|
||||
}
|
||||
359
vendor/topthink/think-captcha/src/Captcha.php
vendored
Normal file
@@ -0,0 +1,359 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\captcha;
|
||||
|
||||
use think\Session;
|
||||
use think\Cache;
|
||||
|
||||
/**
|
||||
* @property mixed seKey
|
||||
* @property mixed expire
|
||||
* @property mixed length
|
||||
* @property mixed fontSize
|
||||
* @property float|mixed imageH
|
||||
* @property float|int|mixed imageW
|
||||
* @property mixed zhSet
|
||||
* @property mixed codeSet
|
||||
* @property mixed reset
|
||||
* @property mixed fontttf
|
||||
* @property mixed useZh
|
||||
* @property mixed useNoise
|
||||
* @property mixed useCurve
|
||||
* @property mixed useImgBg
|
||||
* @property mixed useArithmetic
|
||||
*/
|
||||
class Captcha
|
||||
{
|
||||
protected $config = [
|
||||
'seKey' => 'ThinkPHP.CN',
|
||||
// 验证码加密密钥
|
||||
'codeSet' => '2345678abcdefhijkmnpqrstuvwxyzABCDEFGHJKLMNPQRTUVWXY',
|
||||
// 验证码字符集合
|
||||
'expire' => 1800,
|
||||
// 验证码过期时间(s)
|
||||
'useZh' => false,
|
||||
// 使用中文验证码
|
||||
'zhSet' => '们以我到他会作时要动国产的一是工就年阶义发成部民可出能方进在了不和有大这主中人上为来分生对于学下级地个用同行面说种过命度革而多子后自社加小机也经力线本电高量长党得实家定深法表着水理化争现所二起政三好十战无农使性前等反体合斗路图把结第里正新开论之物从当两些还天资事队批点育重其思与间内去因件日利相由压员气业代全组数果期导平各基或月毛然如应形想制心样干都向变关问比展那它最及外没看治提五解系林者米群头意只明四道马认次文通但条较克又公孔领军流入接席位情运器并飞原油放立题质指建区验活众很教决特此常石强极土少已根共直团统式转别造切九你取西持总料连任志观调七么山程百报更见必真保热委手改管处己将修支识病象几先老光专什六型具示复安带每东增则完风回南广劳轮科北打积车计给节做务被整联步类集号列温装即毫知轴研单色坚据速防史拉世设达尔场织历花受求传口断况采精金界品判参层止边清至万确究书术状厂须离再目海交权且儿青才证低越际八试规斯近注办布门铁需走议县兵固除般引齿千胜细影济白格效置推空配刀叶率述今选养德话查差半敌始片施响收华觉备名红续均药标记难存测士身紧液派准斤角降维板许破述技消底床田势端感往神便贺村构照容非搞亚磨族火段算适讲按值美态黄易彪服早班麦削信排台声该击素张密害侯草何树肥继右属市严径螺检左页抗苏显苦英快称坏移约巴材省黑武培著河帝仅针怎植京助升王眼她抓含苗副杂普谈围食射源例致酸旧却充足短划剂宣环落首尺波承粉践府鱼随考刻靠够满夫失包住促枝局菌杆周护岩师举曲春元超负砂封换太模贫减阳扬江析亩木言球朝医校古呢稻宋听唯输滑站另卫字鼓刚写刘微略范供阿块某功套友限项余倒卷创律雨让骨远帮初皮播优占死毒圈伟季训控激找叫云互跟裂粮粒母练塞钢顶策双留误础吸阻故寸盾晚丝女散焊功株亲院冷彻弹错散商视艺灭版烈零室轻血倍缺厘泵察绝富城冲喷壤简否柱李望盘磁雄似困巩益洲脱投送奴侧润盖挥距触星松送获兴独官混纪依未突架宽冬章湿偏纹吃执阀矿寨责熟稳夺硬价努翻奇甲预职评读背协损棉侵灰虽矛厚罗泥辟告卵箱掌氧恩爱停曾溶营终纲孟钱待尽俄缩沙退陈讨奋械载胞幼哪剥迫旋征槽倒握担仍呀鲜吧卡粗介钻逐弱脚怕盐末阴丰雾冠丙街莱贝辐肠付吉渗瑞惊顿挤秒悬姆烂森糖圣凹陶词迟蚕亿矩康遵牧遭幅园腔订香肉弟屋敏恢忘编印蜂急拿扩伤飞露核缘游振操央伍域甚迅辉异序免纸夜乡久隶缸夹念兰映沟乙吗儒杀汽磷艰晶插埃燃欢铁补咱芽永瓦倾阵碳演威附牙芽永瓦斜灌欧献顺猪洋腐请透司危括脉宜笑若尾束壮暴企菜穗楚汉愈绿拖牛份染既秋遍锻玉夏疗尖殖井费州访吹荣铜沿替滚客召旱悟刺脑措贯藏敢令隙炉壳硫煤迎铸粘探临薄旬善福纵择礼愿伏残雷延烟句纯渐耕跑泽慢栽鲁赤繁境潮横掉锥希池败船假亮谓托伙哲怀割摆贡呈劲财仪沉炼麻罪祖息车穿货销齐鼠抽画饲龙库守筑房歌寒喜哥洗蚀废纳腹乎录镜妇恶脂庄擦险赞钟摇典柄辩竹谷卖乱虚桥奥伯赶垂途额壁网截野遗静谋弄挂课镇妄盛耐援扎虑键归符庆聚绕摩忙舞遇索顾胶羊湖钉仁音迹碎伸灯避泛亡答勇频皇柳哈揭甘诺概宪浓岛袭谁洪谢炮浇斑讯懂灵蛋闭孩释乳巨徒私银伊景坦累匀霉杜乐勒隔弯绩招绍胡呼痛峰零柴簧午跳居尚丁秦稍追梁折耗碱殊岗挖氏刃剧堆赫荷胸衡勤膜篇登驻案刊秧缓凸役剪川雪链渔啦脸户洛孢勃盟买杨宗焦赛旗滤硅炭股坐蒸凝竟陷枪黎救冒暗洞犯筒您宋弧爆谬涂味津臂障褐陆啊健尊豆拔莫抵桑坡缝警挑污冰柬嘴啥饭塑寄赵喊垫丹渡耳刨虎笔稀昆浪萨茶滴浅拥穴覆伦娘吨浸袖珠雌妈紫戏塔锤震岁貌洁剖牢锋疑霸闪埔猛诉刷狠忽灾闹乔唐漏闻沈熔氯荒茎男凡抢像浆旁玻亦忠唱蒙予纷捕锁尤乘乌智淡允叛畜俘摸锈扫毕璃宝芯爷鉴秘净蒋钙肩腾枯抛轨堂拌爸循诱祝励肯酒绳穷塘燥泡袋朗喂铝软渠颗惯贸粪综墙趋彼届墨碍启逆卸航衣孙龄岭骗休借',
|
||||
// 中文验证码字符串
|
||||
'useImgBg' => false,
|
||||
// 使用背景图片
|
||||
'fontSize' => 25,
|
||||
// 验证码字体大小(px)
|
||||
'useCurve' => true,
|
||||
// 是否画混淆曲线
|
||||
'useNoise' => true,
|
||||
// 是否添加杂点
|
||||
'imageH' => 0,
|
||||
// 验证码图片高度
|
||||
'imageW' => 0,
|
||||
// 验证码图片宽度
|
||||
'length' => 5,
|
||||
// 验证码位数
|
||||
'fontttf' => '',
|
||||
// 验证码字体,不设置随机获取
|
||||
'bg' => [243, 251, 254],
|
||||
// 背景颜色
|
||||
'reset' => true,
|
||||
// 验证成功后是否重置
|
||||
'useArithmetic' => false //是否使用算术验证码
|
||||
];
|
||||
|
||||
private $im = null; // 验证码图片实例
|
||||
private $color = null; // 验证码字体颜色
|
||||
|
||||
/**
|
||||
* 架构方法 设置参数
|
||||
* @access public
|
||||
* @param array $config 配置参数
|
||||
*/
|
||||
public function __construct($config = [])
|
||||
{
|
||||
$this->config = array_merge($this->config, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用 $this->name 获取配置
|
||||
* @access public
|
||||
* @param string $name 配置名称
|
||||
* @return mixed 配置值
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
return $this->config[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置验证码配置
|
||||
* @access public
|
||||
* @param string $name 配置名称
|
||||
* @param string $value 配置值
|
||||
* @return void
|
||||
*/
|
||||
public function __set($name, $value)
|
||||
{
|
||||
if (isset($this->config[$name])) {
|
||||
$this->config[$name] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查配置
|
||||
* @access public
|
||||
* @param string $name 配置名称
|
||||
* @return bool
|
||||
*/
|
||||
public function __isset($name)
|
||||
{
|
||||
return isset($this->config[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证验证码是否正确
|
||||
* @access public
|
||||
* @param string $code 用户验证码
|
||||
* @param string $id 验证码标识
|
||||
* @return bool 用户验证码是否正确
|
||||
*/
|
||||
public function check($code, $id = '')
|
||||
{
|
||||
$key = $this->authcode($this->seKey) . $id;
|
||||
// 验证码不能为空
|
||||
$secode = Session::get($key, '');
|
||||
if (empty($code) || empty($secode)) {
|
||||
return false;
|
||||
}
|
||||
// session 过期
|
||||
if (time() - $secode['verify_time'] > $this->expire) {
|
||||
Session::delete($key, '');
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->authcode(strtoupper($code)) == $secode['verify_code']) {
|
||||
$this->reset && Session::delete($key, '');
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 输出验证码并把验证码的值保存的session中
|
||||
* 验证码保存到session的格式为: array('verify_code' => '验证码值', 'verify_time' => '验证码创建时间');
|
||||
* @access public
|
||||
* @param string $id 要生成验证码的标识
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function entry($id = '')
|
||||
{
|
||||
// 图片宽(px)
|
||||
$this->imageW || $this->imageW = $this->length * $this->fontSize * 1.5 + $this->length * $this->fontSize / 2;
|
||||
// 图片高(px)
|
||||
$this->imageH || $this->imageH = $this->fontSize * 2.5;
|
||||
// 建立一幅 $this->imageW x $this->imageH 的图像
|
||||
$this->im = imagecreate($this->imageW, $this->imageH);
|
||||
// 设置背景
|
||||
imagecolorallocate($this->im, $this->bg[0], $this->bg[1], $this->bg[2]);
|
||||
|
||||
// 验证码字体随机颜色
|
||||
$this->color = imagecolorallocate($this->im, mt_rand(1, 150), mt_rand(1, 150), mt_rand(1, 150));
|
||||
|
||||
|
||||
if ($this->useImgBg) {
|
||||
$this->background();
|
||||
}
|
||||
|
||||
if ($this->useNoise) {
|
||||
// 绘杂点
|
||||
$this->writeNoise();
|
||||
}
|
||||
if ($this->useCurve) {
|
||||
// 绘干扰线
|
||||
$this->writeCurve();
|
||||
}
|
||||
|
||||
|
||||
$ttfPath = __DIR__ . '/../assets/' . ($this->useZh ? 'zhttfs' : 'ttfs') . '/';
|
||||
|
||||
// 绘验证码
|
||||
$code = []; // 验证码
|
||||
$codeNX = 0; // 验证码第N个字符的左边距
|
||||
if ($this->useArithmetic) {
|
||||
$this->fontttf = $ttfPath . '6.ttf';
|
||||
$code = [mt_rand(1, 9), '+', mt_rand(1, 9)];
|
||||
foreach ($code as $key => $char) {
|
||||
$codeNX += $this->fontSize * 1.5;
|
||||
imagettftext($this->im, $this->fontSize, 0, $codeNX, $this->fontSize * 1.6, $this->color, $this->fontttf, $char);
|
||||
}
|
||||
$code = $this->authcode($code[0] + $code[2]);
|
||||
} else {
|
||||
// 验证码使用随机字体
|
||||
if (empty($this->fontttf)) {
|
||||
$dir = dir($ttfPath);
|
||||
$ttfs = [];
|
||||
while (false !== ($file = $dir->read())) {
|
||||
if ('.' != $file[0] && substr($file, -4) == '.ttf') {
|
||||
$ttfs[] = $file;
|
||||
}
|
||||
}
|
||||
$dir->close();
|
||||
$this->fontttf = $ttfs[array_rand($ttfs)];
|
||||
}
|
||||
$this->fontttf = $ttfPath . $this->fontttf;
|
||||
if ($this->useZh) {
|
||||
// 中文验证码
|
||||
for ($i = 0; $i < $this->length; $i++) {
|
||||
$code[$i] = iconv_substr($this->zhSet, floor(mt_rand(0, mb_strlen($this->zhSet, 'utf-8') - 1)), 1, 'utf-8');
|
||||
imagettftext($this->im, $this->fontSize, mt_rand(-40, 40), $this->fontSize * ($i + 1) * 1.5, $this->fontSize + mt_rand(10, 20), $this->color, $this->fontttf, $code[$i]);
|
||||
}
|
||||
} else {
|
||||
for ($i = 0; $i < $this->length; $i++) {
|
||||
$code[$i] = $this->codeSet[mt_rand(0, strlen($this->codeSet) - 1)];
|
||||
$codeNX += mt_rand($this->fontSize * 1.2, $this->fontSize * 1.6);
|
||||
imagettftext($this->im, $this->fontSize, mt_rand(-40, 40), $codeNX, $this->fontSize * 1.6, $this->color, $this->fontttf, $code[$i]);
|
||||
}
|
||||
}
|
||||
$code = $this->authcode(strtoupper(implode('', $code)));
|
||||
}
|
||||
|
||||
// 保存验证码
|
||||
$key = $this->authcode($this->seKey);
|
||||
|
||||
$secode = [];
|
||||
$secode['verify_code'] = $code; // 把校验码保存到session
|
||||
$secode['verify_time'] = time(); // 验证码创建时间
|
||||
Session::set($key . $id, $secode, '');
|
||||
//存储到数据库
|
||||
// Db::table('t_captcha')->insert(array(
|
||||
// 'code'=>$code,
|
||||
// 'vkey'=>md5($id),
|
||||
// 'time'=> time()
|
||||
// ));
|
||||
//存储到缓存
|
||||
Cache::set(md5($id),$code,3600);
|
||||
ob_start();
|
||||
// 输出图像
|
||||
imagepng($this->im);
|
||||
$content = ob_get_clean();
|
||||
imagedestroy($this->im);
|
||||
|
||||
return response($content, 200, ['Content-Length' => strlen($content)])->contentType('image/png');
|
||||
}
|
||||
|
||||
/**
|
||||
* 画一条由两条连在一起构成的随机正弦函数曲线作干扰线(你可以改成更帅的曲线函数)
|
||||
*
|
||||
* 高中的数学公式咋都忘了涅,写出来
|
||||
* 正弦型函数解析式:y=Asin(ωx+φ)+b
|
||||
* 各常数值对函数图像的影响:
|
||||
* A:决定峰值(即纵向拉伸压缩的倍数)
|
||||
* b:表示波形在Y轴的位置关系或纵向移动距离(上加下减)
|
||||
* φ:决定波形与X轴位置关系或横向移动距离(左加右减)
|
||||
* ω:决定周期(最小正周期T=2π/∣ω∣)
|
||||
*
|
||||
*/
|
||||
private function writeCurve()
|
||||
{
|
||||
$px = $py = 0;
|
||||
|
||||
// 曲线前部分
|
||||
$A = mt_rand(1, $this->imageH / 2); // 振幅
|
||||
$b = mt_rand(-$this->imageH / 4, $this->imageH / 4); // Y轴方向偏移量
|
||||
$f = mt_rand(-$this->imageH / 4, $this->imageH / 4); // X轴方向偏移量
|
||||
$T = mt_rand($this->imageH, $this->imageW * 2); // 周期
|
||||
$w = (2 * M_PI) / $T;
|
||||
|
||||
$px1 = 0; // 曲线横坐标起始位置
|
||||
$px2 = mt_rand($this->imageW / 2, $this->imageW * 0.8); // 曲线横坐标结束位置
|
||||
|
||||
for ($px = $px1; $px <= $px2; $px = $px + 1) {
|
||||
if (0 != $w) {
|
||||
$py = $A * sin($w * $px + $f) + $b + $this->imageH / 2; // y = Asin(ωx+φ) + b
|
||||
$i = (int)($this->fontSize / 5);
|
||||
while ($i > 0) {
|
||||
imagesetpixel($this->im, $px + $i, $py + $i, $this->color); // 这里(while)循环画像素点比imagettftext和imagestring用字体大小一次画出(不用这while循环)性能要好很多
|
||||
$i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 曲线后部分
|
||||
$A = mt_rand(1, $this->imageH / 2); // 振幅
|
||||
$f = mt_rand(-$this->imageH / 4, $this->imageH / 4); // X轴方向偏移量
|
||||
$T = mt_rand($this->imageH, $this->imageW * 2); // 周期
|
||||
$w = (2 * M_PI) / $T;
|
||||
$b = $py - $A * sin($w * $px + $f) - $this->imageH / 2;
|
||||
$px1 = $px2;
|
||||
$px2 = $this->imageW;
|
||||
|
||||
for ($px = $px1; $px <= $px2; $px = $px + 1) {
|
||||
if (0 != $w) {
|
||||
$py = $A * sin($w * $px + $f) + $b + $this->imageH / 2; // y = Asin(ωx+φ) + b
|
||||
$i = (int)($this->fontSize / 5);
|
||||
while ($i > 0) {
|
||||
imagesetpixel($this->im, $px + $i, $py + $i, $this->color);
|
||||
$i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 画杂点
|
||||
* 往图片上写不同颜色的字母或数字
|
||||
*/
|
||||
private function writeNoise()
|
||||
{
|
||||
$codeSet = '2345678abcdefhijkmnpqrstuvwxyz';
|
||||
for ($i = 0; $i < 10; $i++) {
|
||||
//杂点颜色
|
||||
$noiseColor = imagecolorallocate($this->im, mt_rand(150, 225), mt_rand(150, 225), mt_rand(150, 225));
|
||||
for ($j = 0; $j < 5; $j++) {
|
||||
// 绘杂点
|
||||
imagestring($this->im, 5, mt_rand(-10, $this->imageW), mt_rand(-10, $this->imageH), $codeSet[mt_rand(0, strlen($codeSet) - 1)], $noiseColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制背景图片
|
||||
* 注:如果验证码输出图片比较大,将占用比较多的系统资源
|
||||
*/
|
||||
private function background()
|
||||
{
|
||||
$path = __DIR__ . '/../assets/bgs/';
|
||||
$dir = dir($path);
|
||||
|
||||
$bgs = [];
|
||||
while (false !== ($file = $dir->read())) {
|
||||
if ('.' != $file[0] && substr($file, -4) == '.jpg') {
|
||||
$bgs[] = $path . $file;
|
||||
}
|
||||
}
|
||||
$dir->close();
|
||||
|
||||
$gb = $bgs[array_rand($bgs)];
|
||||
|
||||
list($width, $height) = @getimagesize($gb);
|
||||
// Resample
|
||||
$bgImage = @imagecreatefromjpeg($gb);
|
||||
@imagecopyresampled($this->im, $bgImage, 0, 0, 0, 0, $this->imageW, $this->imageH, $width, $height);
|
||||
@imagedestroy($bgImage);
|
||||
}
|
||||
|
||||
/* 加密验证码 */
|
||||
private function authcode($str)
|
||||
{
|
||||
$key = substr(md5($this->seKey), 5, 8);
|
||||
$str = substr(md5($str), 8, 10);
|
||||
return md5($key . $str);
|
||||
}
|
||||
}
|
||||
23
vendor/topthink/think-captcha/src/CaptchaController.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\captcha;
|
||||
|
||||
use think\Config;
|
||||
|
||||
class CaptchaController
|
||||
{
|
||||
public function index($id = "")
|
||||
{
|
||||
$captcha = new Captcha((array)Config::get('captcha'));
|
||||
return $captcha->entry($id);
|
||||
}
|
||||
}
|
||||
75
vendor/topthink/think-captcha/src/helper.php
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
\think\Route::get('captcha/[:id]', "\\think\\captcha\\CaptchaController@index");
|
||||
|
||||
\think\Validate::extend('captcha', function ($value, $id = '') {
|
||||
return captcha_check($value, $id);
|
||||
});
|
||||
|
||||
\think\Validate::setTypeMsg('captcha', ':attribute错误!');
|
||||
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @param array $config
|
||||
* @return \think\Response
|
||||
*/
|
||||
function captcha($id = '', $config = [])
|
||||
{
|
||||
$captcha = new \think\captcha\Captcha($config);
|
||||
return $captcha->entry($id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @return string
|
||||
*/
|
||||
function captcha_src($id = '')
|
||||
{
|
||||
return \think\Url::build('/captcha' . ($id ? "/{$id}" : ''));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @return mixed
|
||||
*/
|
||||
function captcha_img($id = '')
|
||||
{
|
||||
return '<img src="' . captcha_src($id) . '" alt="captcha" />';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @param string $element 验证码HTML元素ID
|
||||
* @return string
|
||||
*/
|
||||
function captcha_img_with_replacement($id = '', $element = 'think-captcha')
|
||||
{
|
||||
return '<img src="' . captcha_src($id) . '" alt="captcha" id="' . $element . '" onclick="document.getElementById("'
|
||||
. $element . '").src="' . captcha_src($id) . '"+Math.random()' . '/>';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @param string $id
|
||||
* @param array $config
|
||||
* @return bool
|
||||
*/
|
||||
function captcha_check($value, $id = '')
|
||||
{
|
||||
$captcha = new \think\captcha\Captcha((array)\think\Config::get('captcha'));
|
||||
return $captcha->check($value, $id);
|
||||
}
|
||||
2
vendor/topthink/think-helper/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/vendor/
|
||||
/.idea/
|
||||
201
vendor/topthink/think-helper/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.
|
||||
92
vendor/topthink/think-helper/README.md
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
# thinkphp5 常用的一些扩展类库
|
||||
|
||||
> 更新完善中
|
||||
|
||||
> 以下类库都在`\\think\\helper`命名空间下
|
||||
|
||||
## Str
|
||||
> 字符串操作
|
||||
|
||||
```
|
||||
// 检查字符串中是否包含某些字符串
|
||||
Str::contains($haystack, $needles)
|
||||
|
||||
// 检查字符串是否以某些字符串结尾
|
||||
Str::endsWith($haystack, $needles)
|
||||
|
||||
// 获取指定长度的随机字母数字组合的字符串
|
||||
Str::random($length = 16)
|
||||
|
||||
// 字符串转小写
|
||||
Str::lower($value)
|
||||
|
||||
// 字符串转大写
|
||||
Str::upper($value)
|
||||
|
||||
// 获取字符串的长度
|
||||
Str::length($value)
|
||||
|
||||
// 截取字符串
|
||||
Str::substr($string, $start, $length = null)
|
||||
|
||||
```
|
||||
|
||||
## Hash
|
||||
> 创建密码的哈希
|
||||
|
||||
```
|
||||
// 创建
|
||||
Hash::make($value, $type = null, array $options = [])
|
||||
|
||||
// 检查
|
||||
Hash::check($value, $hashedValue, $type = null, array $options = [])
|
||||
|
||||
```
|
||||
|
||||
## Time
|
||||
> 时间戳操作
|
||||
|
||||
```
|
||||
// 今日开始和结束的时间戳
|
||||
Time::today();
|
||||
|
||||
// 昨日开始和结束的时间戳
|
||||
Time::yesterday();
|
||||
|
||||
// 本周开始和结束的时间戳
|
||||
Time::week();
|
||||
|
||||
// 上周开始和结束的时间戳
|
||||
Time::lastWeek();
|
||||
|
||||
// 本月开始和结束的时间戳
|
||||
Time::month();
|
||||
|
||||
// 上月开始和结束的时间戳
|
||||
Time::lastMonth();
|
||||
|
||||
// 今年开始和结束的时间戳
|
||||
Time::year();
|
||||
|
||||
// 去年开始和结束的时间戳
|
||||
Time::lastYear();
|
||||
|
||||
// 获取7天前零点到现在的时间戳
|
||||
Time::dayToNow(7)
|
||||
|
||||
// 获取7天前零点到昨日结束的时间戳
|
||||
Time::dayToNow(7, true)
|
||||
|
||||
// 获取7天前的时间戳
|
||||
Time::daysAgo(7)
|
||||
|
||||
// 获取7天后的时间戳
|
||||
Time::daysAfter(7)
|
||||
|
||||
// 天数转换成秒数
|
||||
Time::daysToSecond(5)
|
||||
|
||||
// 周数转换成秒数
|
||||
Time::weekToSecond(5)
|
||||
|
||||
```
|
||||
19
vendor/topthink/think-helper/composer.json
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "topthink/think-helper",
|
||||
"description": "The ThinkPHP5 Helper Package",
|
||||
"license": "Apache-2.0",
|
||||
"authors": [
|
||||
{
|
||||
"name": "yunwuxin",
|
||||
"email": "448901948@qq.com"
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"think\\helper\\": "src"
|
||||
},
|
||||
"files": [
|
||||
"src/helper.php"
|
||||
]
|
||||
}
|
||||
}
|
||||
41
vendor/topthink/think-helper/src/Arr.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\helper;
|
||||
|
||||
|
||||
class Arr
|
||||
{
|
||||
|
||||
public static function isAssoc(array $array)
|
||||
{
|
||||
$keys = array_keys($array);
|
||||
|
||||
return array_keys($keys) !== $keys;
|
||||
}
|
||||
|
||||
public static function sortRecursive($array)
|
||||
{
|
||||
foreach ($array as &$value) {
|
||||
if (is_array($value)) {
|
||||
$value = static::sortRecursive($value);
|
||||
}
|
||||
}
|
||||
|
||||
if (static::isAssoc($array)) {
|
||||
ksort($array);
|
||||
} else {
|
||||
sort($array);
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
48
vendor/topthink/think-helper/src/Hash.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\helper;
|
||||
|
||||
|
||||
class Hash
|
||||
{
|
||||
protected static $handle = [];
|
||||
|
||||
public static function make($value, $type = null, array $options = [])
|
||||
{
|
||||
return self::handle($type)->make($value, $options);
|
||||
}
|
||||
|
||||
public static function check($value, $hashedValue, $type = null, array $options = [])
|
||||
{
|
||||
return self::handle($type)->check($value, $hashedValue, $options);
|
||||
}
|
||||
|
||||
public static function handle($type)
|
||||
{
|
||||
if (is_null($type)) {
|
||||
if (PHP_VERSION_ID >= 50500) {
|
||||
$type = 'bcrypt';
|
||||
} else {
|
||||
$type = 'md5';
|
||||
}
|
||||
}
|
||||
if (empty(self::$handle[$type])) {
|
||||
$class = "\\think\\helper\\hash\\" . ucfirst($type);
|
||||
if (!class_exists($class)) {
|
||||
throw new \ErrorException("Not found {$type} hash type!");
|
||||
}
|
||||
self::$handle[$type] = new $class();
|
||||
}
|
||||
return self::$handle[$type];
|
||||
}
|
||||
|
||||
}
|
||||
202
vendor/topthink/think-helper/src/Str.php
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace think\helper;
|
||||
|
||||
class Str
|
||||
{
|
||||
|
||||
protected static $snakeCache = [];
|
||||
|
||||
protected static $camelCache = [];
|
||||
|
||||
protected static $studlyCache = [];
|
||||
|
||||
/**
|
||||
* 检查字符串中是否包含某些字符串
|
||||
* @param string $haystack
|
||||
* @param string|array $needles
|
||||
* @return bool
|
||||
*/
|
||||
public static function contains($haystack, $needles)
|
||||
{
|
||||
foreach ((array) $needles as $needle) {
|
||||
if ($needle != '' && mb_strpos($haystack, $needle) !== false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查字符串是否以某些字符串结尾
|
||||
*
|
||||
* @param string $haystack
|
||||
* @param string|array $needles
|
||||
* @return bool
|
||||
*/
|
||||
public static function endsWith($haystack, $needles)
|
||||
{
|
||||
foreach ((array) $needles as $needle) {
|
||||
if ((string) $needle === static::substr($haystack, -static::length($needle))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查字符串是否以某些字符串开头
|
||||
*
|
||||
* @param string $haystack
|
||||
* @param string|array $needles
|
||||
* @return bool
|
||||
*/
|
||||
public static function startsWith($haystack, $needles)
|
||||
{
|
||||
foreach ((array) $needles as $needle) {
|
||||
if ($needle != '' && mb_strpos($haystack, $needle) === 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定长度的随机字母数字组合的字符串
|
||||
*
|
||||
* @param int $length
|
||||
* @return string
|
||||
*/
|
||||
public static function random($length = 16)
|
||||
{
|
||||
$pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
|
||||
return static::substr(str_shuffle(str_repeat($pool, $length)), 0, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字符串转小写
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public static function lower($value)
|
||||
{
|
||||
return mb_strtolower($value, 'UTF-8');
|
||||
}
|
||||
|
||||
/**
|
||||
* 字符串转大写
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public static function upper($value)
|
||||
{
|
||||
return mb_strtoupper($value, 'UTF-8');
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字符串的长度
|
||||
*
|
||||
* @param string $value
|
||||
* @return int
|
||||
*/
|
||||
public static function length($value)
|
||||
{
|
||||
return mb_strlen($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 截取字符串
|
||||
*
|
||||
* @param string $string
|
||||
* @param int $start
|
||||
* @param int|null $length
|
||||
* @return string
|
||||
*/
|
||||
public static function substr($string, $start, $length = null)
|
||||
{
|
||||
return mb_substr($string, $start, $length, 'UTF-8');
|
||||
}
|
||||
|
||||
/**
|
||||
* 驼峰转下划线
|
||||
*
|
||||
* @param string $value
|
||||
* @param string $delimiter
|
||||
* @return string
|
||||
*/
|
||||
public static function snake($value, $delimiter = '_')
|
||||
{
|
||||
$key = $value;
|
||||
|
||||
if (isset(static::$snakeCache[$key][$delimiter])) {
|
||||
return static::$snakeCache[$key][$delimiter];
|
||||
}
|
||||
|
||||
if (!ctype_lower($value)) {
|
||||
$value = preg_replace('/\s+/u', '', $value);
|
||||
|
||||
$value = static::lower(preg_replace('/(.)(?=[A-Z])/u', '$1' . $delimiter, $value));
|
||||
}
|
||||
|
||||
return static::$snakeCache[$key][$delimiter] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 下划线转驼峰(首字母小写)
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public static function camel($value)
|
||||
{
|
||||
if (isset(static::$camelCache[$value])) {
|
||||
return static::$camelCache[$value];
|
||||
}
|
||||
|
||||
return static::$camelCache[$value] = lcfirst(static::studly($value));
|
||||
}
|
||||
|
||||
/**
|
||||
* 下划线转驼峰(首字母大写)
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public static function studly($value)
|
||||
{
|
||||
$key = $value;
|
||||
|
||||
if (isset(static::$studlyCache[$key])) {
|
||||
return static::$studlyCache[$key];
|
||||
}
|
||||
|
||||
$value = ucwords(str_replace(['-', '_'], ' ', $value));
|
||||
|
||||
return static::$studlyCache[$key] = str_replace(' ', '', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转为首字母大写的标题格式
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public static function title($value)
|
||||
{
|
||||
return mb_convert_case($value, MB_CASE_TITLE, 'UTF-8');
|
||||
}
|
||||
}
|
||||
198
vendor/topthink/think-helper/src/Time.php
vendored
Normal file
@@ -0,0 +1,198 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: 刘志淳 <chun@engineer.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace think\helper;
|
||||
|
||||
class Time
|
||||
{
|
||||
/**
|
||||
* 返回今日开始和结束的时间戳
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function today()
|
||||
{
|
||||
return [
|
||||
mktime(0, 0, 0, date('m'), date('d'), date('Y')),
|
||||
mktime(23, 59, 59, date('m'), date('d'), date('Y'))
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回昨日开始和结束的时间戳
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function yesterday()
|
||||
{
|
||||
$yesterday = date('d') - 1;
|
||||
return [
|
||||
mktime(0, 0, 0, date('m'), $yesterday, date('Y')),
|
||||
mktime(23, 59, 59, date('m'), $yesterday, date('Y'))
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回本周开始和结束的时间戳
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function week()
|
||||
{
|
||||
$timestamp = time();
|
||||
return [
|
||||
strtotime(date('Y-m-d', strtotime("+0 week Monday", $timestamp))),
|
||||
strtotime(date('Y-m-d', strtotime("+0 week Sunday", $timestamp))) + 24 * 3600 - 1
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回上周开始和结束的时间戳
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function lastWeek()
|
||||
{
|
||||
$timestamp = time();
|
||||
return [
|
||||
strtotime(date('Y-m-d', strtotime("last week Monday", $timestamp))),
|
||||
strtotime(date('Y-m-d', strtotime("last week Sunday", $timestamp))) + 24 * 3600 - 1
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回本月开始和结束的时间戳
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function month($everyDay = false)
|
||||
{
|
||||
return [
|
||||
mktime(0, 0, 0, date('m'), 1, date('Y')),
|
||||
mktime(23, 59, 59, date('m'), date('t'), date('Y'))
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回上个月开始和结束的时间戳
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function lastMonth()
|
||||
{
|
||||
$begin = mktime(0, 0, 0, date('m') - 1, 1, date('Y'));
|
||||
$end = mktime(23, 59, 59, date('m') - 1, date('t', $begin), date('Y'));
|
||||
|
||||
return [$begin, $end];
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回今年开始和结束的时间戳
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function year()
|
||||
{
|
||||
return [
|
||||
mktime(0, 0, 0, 1, 1, date('Y')),
|
||||
mktime(23, 59, 59, 12, 31, date('Y'))
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回去年开始和结束的时间戳
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function lastYear()
|
||||
{
|
||||
$year = date('Y') - 1;
|
||||
return [
|
||||
mktime(0, 0, 0, 1, 1, $year),
|
||||
mktime(23, 59, 59, 12, 31, $year)
|
||||
];
|
||||
}
|
||||
|
||||
public static function dayOf()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取几天前零点到现在/昨日结束的时间戳
|
||||
*
|
||||
* @param int $day 天数
|
||||
* @param bool $now 返回现在或者昨天结束时间戳
|
||||
* @return array
|
||||
*/
|
||||
public static function dayToNow($day = 1, $now = true)
|
||||
{
|
||||
$end = time();
|
||||
if (!$now) {
|
||||
list($foo, $end) = self::yesterday();
|
||||
}
|
||||
|
||||
return [
|
||||
mktime(0, 0, 0, date('m'), date('d') - $day, date('Y')),
|
||||
$end
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回几天前的时间戳
|
||||
*
|
||||
* @param int $day
|
||||
* @return int
|
||||
*/
|
||||
public static function daysAgo($day = 1)
|
||||
{
|
||||
$nowTime = time();
|
||||
return $nowTime - self::daysToSecond($day);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回几天后的时间戳
|
||||
*
|
||||
* @param int $day
|
||||
* @return int
|
||||
*/
|
||||
public static function daysAfter($day = 1)
|
||||
{
|
||||
$nowTime = time();
|
||||
return $nowTime + self::daysToSecond($day);
|
||||
}
|
||||
|
||||
/**
|
||||
* 天数转换成秒数
|
||||
*
|
||||
* @param int $day
|
||||
* @return int
|
||||
*/
|
||||
public static function daysToSecond($day = 1)
|
||||
{
|
||||
return $day * 86400;
|
||||
}
|
||||
|
||||
/**
|
||||
* 周数转换成秒数
|
||||
*
|
||||
* @param int $week
|
||||
* @return int
|
||||
*/
|
||||
public static function weekToSecond($week = 1)
|
||||
{
|
||||
return self::daysToSecond() * 7 * $week;
|
||||
}
|
||||
|
||||
private static function startTimeToEndTime()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
51
vendor/topthink/think-helper/src/hash/Bcrypt.php
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace think\helper\hash;
|
||||
|
||||
class Bcrypt
|
||||
{
|
||||
|
||||
/**
|
||||
* Default crypt cost factor.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $rounds = 10;
|
||||
|
||||
public function make($value, array $options = [])
|
||||
{
|
||||
$cost = isset($options['rounds']) ? $options['rounds'] : $this->rounds;
|
||||
|
||||
$hash = password_hash($value, PASSWORD_BCRYPT, ['cost' => $cost]);
|
||||
|
||||
if ($hash === false) {
|
||||
throw new \RuntimeException('Bcrypt hashing not supported.');
|
||||
}
|
||||
|
||||
return $hash;
|
||||
}
|
||||
|
||||
public function check($value, $hashedValue, array $options = [])
|
||||
{
|
||||
if (strlen($hashedValue) === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return password_verify($value, $hashedValue);
|
||||
}
|
||||
|
||||
public function setRounds($rounds)
|
||||
{
|
||||
$this->rounds = (int)$rounds;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
42
vendor/topthink/think-helper/src/hash/Md5.php
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace think\helper\hash;
|
||||
|
||||
class Md5
|
||||
{
|
||||
|
||||
protected $salt = 'think';
|
||||
|
||||
public function make($value, array $options = [])
|
||||
{
|
||||
$salt = isset($options['salt']) ? $options['salt'] : $this->salt;
|
||||
|
||||
return md5(md5($value) . $salt);
|
||||
}
|
||||
|
||||
public function check($value, $hashedValue, array $options = [])
|
||||
{
|
||||
if (strlen($hashedValue) === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$salt = isset($options['salt']) ? $options['salt'] : $this->salt;
|
||||
|
||||
return md5(md5($value) . $salt) == $hashedValue;
|
||||
}
|
||||
|
||||
public function setSalt($salt)
|
||||
{
|
||||
$this->salt = (string)$salt;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
93
vendor/topthink/think-helper/src/helper.php
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
if (!function_exists('class_basename')) {
|
||||
/**
|
||||
* 获取类名(不包含命名空间)
|
||||
*
|
||||
* @param string|object $class
|
||||
* @return string
|
||||
*/
|
||||
function class_basename($class)
|
||||
{
|
||||
$class = is_object($class) ? get_class($class) : $class;
|
||||
|
||||
return basename(str_replace('\\', '/', $class));
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('class_uses_recursive')) {
|
||||
/**
|
||||
*获取一个类里所有用到的trait,包括父类的
|
||||
*
|
||||
* @param $class
|
||||
* @return array
|
||||
*/
|
||||
function class_uses_recursive($class)
|
||||
{
|
||||
if (is_object($class)) {
|
||||
$class = get_class($class);
|
||||
}
|
||||
|
||||
$results = [];
|
||||
|
||||
foreach (array_merge([$class => $class], class_parents($class)) as $class) {
|
||||
$results += trait_uses_recursive($class);
|
||||
}
|
||||
|
||||
return array_unique($results);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('trait_uses_recursive')) {
|
||||
/**
|
||||
* 获取一个trait里所有引用到的trait
|
||||
*
|
||||
* @param string $trait
|
||||
* @return array
|
||||
*/
|
||||
function trait_uses_recursive($trait)
|
||||
{
|
||||
$traits = class_uses($trait);
|
||||
|
||||
foreach ($traits as $trait) {
|
||||
$traits += trait_uses_recursive($trait);
|
||||
}
|
||||
|
||||
return $traits;
|
||||
}
|
||||
}
|
||||
if (!function_exists('classnames')) {
|
||||
/**
|
||||
* css样式名生成器
|
||||
* classnames("foo", "bar"); // => "foo bar"
|
||||
* classnames("foo", [ "bar"=> true ]); // => "foo bar"
|
||||
* classnames([ "foo-bar"=> true ]); // => "foo-bar"
|
||||
* classnames([ "foo-bar"=> false ]); // => "
|
||||
* classnames([ "foo" => true ], [ "bar"=> true ]); // => "foo bar"
|
||||
* classnames([ "foo" => true, "bar"=> true ]); // => "foo bar"
|
||||
* classnames("foo", [ "bar"=> true, "duck"=> false ], "baz", [ "quux"=> true ]); // => "foo bar baz quux"
|
||||
* classnames(null, false, "bar", 0, 1, [ "baz"=> null ]); // => "bar 1"
|
||||
*/
|
||||
function classnames()
|
||||
{
|
||||
$args = func_get_args();
|
||||
$classes = array_map(function ($arg) {
|
||||
if (is_array($arg)) {
|
||||
return implode(" ", array_filter(array_map(function ($expression, $class) {
|
||||
return $expression ? $class : false;
|
||||
}, $arg, array_keys($arg))));
|
||||
}
|
||||
return $arg;
|
||||
}, $args);
|
||||
return implode(" ", array_filter($classes));
|
||||
}
|
||||
}
|
||||
4
vendor/topthink/think-image/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
/vendor/
|
||||
/thinkphp/
|
||||
/composer.lock
|
||||
/.idea/
|
||||
22
vendor/topthink/think-image/.travis.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
language: php
|
||||
|
||||
php:
|
||||
- 5.4
|
||||
- 5.5
|
||||
- 5.6
|
||||
- 7.0
|
||||
- hhvm
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- php: 7.0
|
||||
- php: hhvm
|
||||
|
||||
before_script:
|
||||
- composer self-update
|
||||
- composer install --prefer-source --no-interaction --dev
|
||||
|
||||
script: phpunit --coverage-clover=coverage.xml --configuration=phpunit.xml
|
||||
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
201
vendor/topthink/think-image/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.
|
||||
29
vendor/topthink/think-image/README.md
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
# The ThinkPHP5 Image Package
|
||||
|
||||
[](https://travis-ci.org/top-think/think-image)
|
||||
[](https://codecov.io/github/top-think/think-image)
|
||||
[](https://github.com/top-think/think-image/releases)
|
||||
[](https://github.com/top-think/think-image/releases/latest)
|
||||
[](https://github.com/top-think/think-image/releases/latest)
|
||||
[](https://packagist.org/packages/topthink/think-image)
|
||||
[](https://packagist.org/packages/topthink/think-image)
|
||||
|
||||
## 安装
|
||||
|
||||
> composer require topthink/think-image
|
||||
|
||||
## 使用
|
||||
|
||||
~~~
|
||||
$image = \think\Image::open('./image.jpg');
|
||||
或者
|
||||
$image = \think\Image::open(request()->file('image'));
|
||||
|
||||
|
||||
$image->crop(...)
|
||||
->thumb(...)
|
||||
->water(...)
|
||||
->text(....)
|
||||
->save(..);
|
||||
|
||||
~~~
|
||||
26
vendor/topthink/think-image/composer.json
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "topthink/think-image",
|
||||
"description": "The ThinkPHP5 Image Package",
|
||||
"license": "Apache-2.0",
|
||||
"authors": [
|
||||
{
|
||||
"name": "yunwuxin",
|
||||
"email": "448901948@qq.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"ext-gd": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"topthink/framework": "^5.0",
|
||||
"phpunit/phpunit": "4.8.*"
|
||||
},
|
||||
"config": {
|
||||
"preferred-install": "dist"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"think\\": "src"
|
||||
}
|
||||
}
|
||||
}
|
||||
20
vendor/topthink/think-image/phpunit.xml
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
bootstrap="tests/autoload.php"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false"
|
||||
syntaxCheck="false">
|
||||
<testsuites>
|
||||
<testsuite name="Package Test Suite">
|
||||
<directory suffix=".php">./tests/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<listeners>
|
||||
<listener class="JohnKary\PHPUnit\Listener\SpeedTrapListener" />
|
||||
</listeners>
|
||||
</phpunit>
|
||||
610
vendor/topthink/think-image/src/Image.php
vendored
Normal file
@@ -0,0 +1,610 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think;
|
||||
|
||||
use think\image\Exception as ImageException;
|
||||
use think\image\gif\Gif;
|
||||
|
||||
class Image
|
||||
{
|
||||
|
||||
/* 缩略图相关常量定义 */
|
||||
const THUMB_SCALING = 1; //常量,标识缩略图等比例缩放类型
|
||||
const THUMB_FILLED = 2; //常量,标识缩略图缩放后填充类型
|
||||
const THUMB_CENTER = 3; //常量,标识缩略图居中裁剪类型
|
||||
const THUMB_NORTHWEST = 4; //常量,标识缩略图左上角裁剪类型
|
||||
const THUMB_SOUTHEAST = 5; //常量,标识缩略图右下角裁剪类型
|
||||
const THUMB_FIXED = 6; //常量,标识缩略图固定尺寸缩放类型
|
||||
/* 水印相关常量定义 */
|
||||
const WATER_NORTHWEST = 1; //常量,标识左上角水印
|
||||
const WATER_NORTH = 2; //常量,标识上居中水印
|
||||
const WATER_NORTHEAST = 3; //常量,标识右上角水印
|
||||
const WATER_WEST = 4; //常量,标识左居中水印
|
||||
const WATER_CENTER = 5; //常量,标识居中水印
|
||||
const WATER_EAST = 6; //常量,标识右居中水印
|
||||
const WATER_SOUTHWEST = 7; //常量,标识左下角水印
|
||||
const WATER_SOUTH = 8; //常量,标识下居中水印
|
||||
const WATER_SOUTHEAST = 9; //常量,标识右下角水印
|
||||
/* 翻转相关常量定义 */
|
||||
const FLIP_X = 1; //X轴翻转
|
||||
const FLIP_Y = 2; //Y轴翻转
|
||||
|
||||
/**
|
||||
* 图像资源对象
|
||||
*
|
||||
* @var resource
|
||||
*/
|
||||
protected $im;
|
||||
|
||||
/** @var Gif */
|
||||
protected $gif;
|
||||
|
||||
/**
|
||||
* 图像信息,包括 width, height, type, mime, size
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $info;
|
||||
|
||||
protected function __construct(\SplFileInfo $file)
|
||||
{
|
||||
//获取图像信息
|
||||
$info = @getimagesize($file->getPathname());
|
||||
|
||||
//检测图像合法性
|
||||
if (false === $info || (IMAGETYPE_GIF === $info[2] && empty($info['bits']))) {
|
||||
throw new ImageException('Illegal image file');
|
||||
}
|
||||
|
||||
//设置图像信息
|
||||
$this->info = [
|
||||
'width' => $info[0],
|
||||
'height' => $info[1],
|
||||
'type' => image_type_to_extension($info[2], false),
|
||||
'mime' => $info['mime'],
|
||||
];
|
||||
|
||||
//打开图像
|
||||
if ('gif' == $this->info['type']) {
|
||||
$this->gif = new Gif($file->getPathname());
|
||||
$this->im = @imagecreatefromstring($this->gif->image());
|
||||
} else {
|
||||
$fun = "imagecreatefrom{$this->info['type']}";
|
||||
$this->im = @$fun($file->getPathname());
|
||||
}
|
||||
|
||||
if (empty($this->im)) {
|
||||
throw new ImageException('Failed to create image resources!');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开一个图片文件
|
||||
* @param \SplFileInfo|string $file
|
||||
* @return Image
|
||||
*/
|
||||
public static function open($file)
|
||||
{
|
||||
if (is_string($file)) {
|
||||
$file = new \SplFileInfo($file);
|
||||
}
|
||||
if (!$file->isFile()) {
|
||||
throw new ImageException('image file not exist');
|
||||
}
|
||||
return new self($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存图像
|
||||
* @param string $pathname 图像保存路径名称
|
||||
* @param null|string $type 图像类型
|
||||
* @param int $quality 图像质量
|
||||
* @param bool $interlace 是否对JPEG类型图像设置隔行扫描
|
||||
* @return $this
|
||||
*/
|
||||
public function save($pathname, $type = null, $quality = 80, $interlace = true)
|
||||
{
|
||||
//自动获取图像类型
|
||||
if (is_null($type)) {
|
||||
$type = $this->info['type'];
|
||||
} else {
|
||||
$type = strtolower($type);
|
||||
}
|
||||
//保存图像
|
||||
if ('jpeg' == $type || 'jpg' == $type) {
|
||||
//JPEG图像设置隔行扫描
|
||||
imageinterlace($this->im, $interlace);
|
||||
imagejpeg($this->im, $pathname, $quality);
|
||||
} elseif ('gif' == $type && !empty($this->gif)) {
|
||||
$this->gif->save($pathname);
|
||||
} elseif ('png' == $type) {
|
||||
//设定保存完整的 alpha 通道信息
|
||||
imagesavealpha($this->im, true);
|
||||
//ImagePNG生成图像的质量范围从0到9的
|
||||
imagepng($this->im, $pathname, min((int) ($quality / 10), 9));
|
||||
} else {
|
||||
$fun = 'image' . $type;
|
||||
$fun($this->im, $pathname);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回图像宽度
|
||||
* @return int 图像宽度
|
||||
*/
|
||||
public function width()
|
||||
{
|
||||
return $this->info['width'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回图像高度
|
||||
* @return int 图像高度
|
||||
*/
|
||||
public function height()
|
||||
{
|
||||
return $this->info['height'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回图像类型
|
||||
* @return string 图像类型
|
||||
*/
|
||||
public function type()
|
||||
{
|
||||
return $this->info['type'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回图像MIME类型
|
||||
* @return string 图像MIME类型
|
||||
*/
|
||||
public function mime()
|
||||
{
|
||||
return $this->info['mime'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回图像尺寸数组 0 - 图像宽度,1 - 图像高度
|
||||
* @return array 图像尺寸
|
||||
*/
|
||||
public function size()
|
||||
{
|
||||
return [$this->info['width'], $this->info['height']];
|
||||
}
|
||||
|
||||
/**
|
||||
* 旋转图像
|
||||
* @param int $degrees 顺时针旋转的度数
|
||||
* @return $this
|
||||
*/
|
||||
public function rotate($degrees = 90)
|
||||
{
|
||||
do {
|
||||
$img = imagerotate($this->im, -$degrees, imagecolorallocatealpha($this->im, 0, 0, 0, 127));
|
||||
imagedestroy($this->im);
|
||||
$this->im = $img;
|
||||
} while (!empty($this->gif) && $this->gifNext());
|
||||
|
||||
$this->info['width'] = imagesx($this->im);
|
||||
$this->info['height'] = imagesy($this->im);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 翻转图像
|
||||
* @param integer $direction 翻转轴,X或者Y
|
||||
* @return $this
|
||||
*/
|
||||
public function flip($direction = self::FLIP_X)
|
||||
{
|
||||
//原图宽度和高度
|
||||
$w = $this->info['width'];
|
||||
$h = $this->info['height'];
|
||||
|
||||
do {
|
||||
|
||||
$img = imagecreatetruecolor($w, $h);
|
||||
|
||||
switch ($direction) {
|
||||
case self::FLIP_X:
|
||||
for ($y = 0; $y < $h; $y++) {
|
||||
imagecopy($img, $this->im, 0, $h - $y - 1, 0, $y, $w, 1);
|
||||
}
|
||||
break;
|
||||
case self::FLIP_Y:
|
||||
for ($x = 0; $x < $w; $x++) {
|
||||
imagecopy($img, $this->im, $w - $x - 1, 0, $x, 0, 1, $h);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new ImageException('不支持的翻转类型');
|
||||
}
|
||||
|
||||
imagedestroy($this->im);
|
||||
$this->im = $img;
|
||||
|
||||
} while (!empty($this->gif) && $this->gifNext());
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 裁剪图像
|
||||
*
|
||||
* @param integer $w 裁剪区域宽度
|
||||
* @param integer $h 裁剪区域高度
|
||||
* @param integer $x 裁剪区域x坐标
|
||||
* @param integer $y 裁剪区域y坐标
|
||||
* @param integer $width 图像保存宽度
|
||||
* @param integer $height 图像保存高度
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function crop($w, $h, $x = 0, $y = 0, $width = null, $height = null)
|
||||
{
|
||||
//设置保存尺寸
|
||||
empty($width) && $width = $w;
|
||||
empty($height) && $height = $h;
|
||||
do {
|
||||
//创建新图像
|
||||
$img = imagecreatetruecolor($width, $height);
|
||||
// 调整默认颜色
|
||||
$color = imagecolorallocate($img, 255, 255, 255);
|
||||
imagefill($img, 0, 0, $color);
|
||||
//裁剪
|
||||
imagecopyresampled($img, $this->im, 0, 0, $x, $y, $width, $height, $w, $h);
|
||||
imagedestroy($this->im); //销毁原图
|
||||
//设置新图像
|
||||
$this->im = $img;
|
||||
} while (!empty($this->gif) && $this->gifNext());
|
||||
$this->info['width'] = (int) $width;
|
||||
$this->info['height'] = (int) $height;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成缩略图
|
||||
*
|
||||
* @param integer $width 缩略图最大宽度
|
||||
* @param integer $height 缩略图最大高度
|
||||
* @param int $type 缩略图裁剪类型
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function thumb($width, $height, $type = self::THUMB_SCALING)
|
||||
{
|
||||
//原图宽度和高度
|
||||
$w = $this->info['width'];
|
||||
$h = $this->info['height'];
|
||||
/* 计算缩略图生成的必要参数 */
|
||||
switch ($type) {
|
||||
/* 等比例缩放 */
|
||||
case self::THUMB_SCALING:
|
||||
//原图尺寸小于缩略图尺寸则不进行缩略
|
||||
if ($w < $width && $h < $height) {
|
||||
return $this;
|
||||
}
|
||||
//计算缩放比例
|
||||
$scale = min($width / $w, $height / $h);
|
||||
//设置缩略图的坐标及宽度和高度
|
||||
$x = $y = 0;
|
||||
$width = $w * $scale;
|
||||
$height = $h * $scale;
|
||||
break;
|
||||
/* 居中裁剪 */
|
||||
case self::THUMB_CENTER:
|
||||
//计算缩放比例
|
||||
$scale = max($width / $w, $height / $h);
|
||||
//设置缩略图的坐标及宽度和高度
|
||||
$w = $width / $scale;
|
||||
$h = $height / $scale;
|
||||
$x = ($this->info['width'] - $w) / 2;
|
||||
$y = ($this->info['height'] - $h) / 2;
|
||||
break;
|
||||
/* 左上角裁剪 */
|
||||
case self::THUMB_NORTHWEST:
|
||||
//计算缩放比例
|
||||
$scale = max($width / $w, $height / $h);
|
||||
//设置缩略图的坐标及宽度和高度
|
||||
$x = $y = 0;
|
||||
$w = $width / $scale;
|
||||
$h = $height / $scale;
|
||||
break;
|
||||
/* 右下角裁剪 */
|
||||
case self::THUMB_SOUTHEAST:
|
||||
//计算缩放比例
|
||||
$scale = max($width / $w, $height / $h);
|
||||
//设置缩略图的坐标及宽度和高度
|
||||
$w = $width / $scale;
|
||||
$h = $height / $scale;
|
||||
$x = $this->info['width'] - $w;
|
||||
$y = $this->info['height'] - $h;
|
||||
break;
|
||||
/* 填充 */
|
||||
case self::THUMB_FILLED:
|
||||
//计算缩放比例
|
||||
if ($w < $width && $h < $height) {
|
||||
$scale = 1;
|
||||
} else {
|
||||
$scale = min($width / $w, $height / $h);
|
||||
}
|
||||
//设置缩略图的坐标及宽度和高度
|
||||
$neww = $w * $scale;
|
||||
$newh = $h * $scale;
|
||||
$x = $this->info['width'] - $w;
|
||||
$y = $this->info['height'] - $h;
|
||||
$posx = ($width - $w * $scale) / 2;
|
||||
$posy = ($height - $h * $scale) / 2;
|
||||
do {
|
||||
//创建新图像
|
||||
$img = imagecreatetruecolor($width, $height);
|
||||
// 调整默认颜色
|
||||
$color = imagecolorallocate($img, 255, 255, 255);
|
||||
imagefill($img, 0, 0, $color);
|
||||
//裁剪
|
||||
imagecopyresampled($img, $this->im, $posx, $posy, $x, $y, $neww, $newh, $w, $h);
|
||||
imagedestroy($this->im); //销毁原图
|
||||
$this->im = $img;
|
||||
} while (!empty($this->gif) && $this->gifNext());
|
||||
$this->info['width'] = (int) $width;
|
||||
$this->info['height'] = (int) $height;
|
||||
return $this;
|
||||
/* 固定 */
|
||||
case self::THUMB_FIXED:
|
||||
$x = $y = 0;
|
||||
break;
|
||||
default:
|
||||
throw new ImageException('不支持的缩略图裁剪类型');
|
||||
}
|
||||
/* 裁剪图像 */
|
||||
return $this->crop($w, $h, $x, $y, $width, $height);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加水印
|
||||
*
|
||||
* @param string $source 水印图片路径
|
||||
* @param int $locate 水印位置
|
||||
* @param int $alpha 透明度
|
||||
* @return $this
|
||||
*/
|
||||
public function water($source, $locate = self::WATER_SOUTHEAST, $alpha = 100)
|
||||
{
|
||||
if (!is_file($source)) {
|
||||
throw new ImageException('水印图像不存在');
|
||||
}
|
||||
//获取水印图像信息
|
||||
$info = getimagesize($source);
|
||||
if (false === $info || (IMAGETYPE_GIF === $info[2] && empty($info['bits']))) {
|
||||
throw new ImageException('非法水印文件');
|
||||
}
|
||||
//创建水印图像资源
|
||||
$fun = 'imagecreatefrom' . image_type_to_extension($info[2], false);
|
||||
$water = $fun($source);
|
||||
//设定水印图像的混色模式
|
||||
imagealphablending($water, true);
|
||||
/* 设定水印位置 */
|
||||
switch ($locate) {
|
||||
/* 右下角水印 */
|
||||
case self::WATER_SOUTHEAST:
|
||||
$x = $this->info['width'] - $info[0];
|
||||
$y = $this->info['height'] - $info[1];
|
||||
break;
|
||||
/* 左下角水印 */
|
||||
case self::WATER_SOUTHWEST:
|
||||
$x = 0;
|
||||
$y = $this->info['height'] - $info[1];
|
||||
break;
|
||||
/* 左上角水印 */
|
||||
case self::WATER_NORTHWEST:
|
||||
$x = $y = 0;
|
||||
break;
|
||||
/* 右上角水印 */
|
||||
case self::WATER_NORTHEAST:
|
||||
$x = $this->info['width'] - $info[0];
|
||||
$y = 0;
|
||||
break;
|
||||
/* 居中水印 */
|
||||
case self::WATER_CENTER:
|
||||
$x = ($this->info['width'] - $info[0]) / 2;
|
||||
$y = ($this->info['height'] - $info[1]) / 2;
|
||||
break;
|
||||
/* 下居中水印 */
|
||||
case self::WATER_SOUTH:
|
||||
$x = ($this->info['width'] - $info[0]) / 2;
|
||||
$y = $this->info['height'] - $info[1];
|
||||
break;
|
||||
/* 右居中水印 */
|
||||
case self::WATER_EAST:
|
||||
$x = $this->info['width'] - $info[0];
|
||||
$y = ($this->info['height'] - $info[1]) / 2;
|
||||
break;
|
||||
/* 上居中水印 */
|
||||
case self::WATER_NORTH:
|
||||
$x = ($this->info['width'] - $info[0]) / 2;
|
||||
$y = 0;
|
||||
break;
|
||||
/* 左居中水印 */
|
||||
case self::WATER_WEST:
|
||||
$x = 0;
|
||||
$y = ($this->info['height'] - $info[1]) / 2;
|
||||
break;
|
||||
default:
|
||||
/* 自定义水印坐标 */
|
||||
if (is_array($locate)) {
|
||||
list($x, $y) = $locate;
|
||||
} else {
|
||||
throw new ImageException('不支持的水印位置类型');
|
||||
}
|
||||
}
|
||||
do {
|
||||
//添加水印
|
||||
$src = imagecreatetruecolor($info[0], $info[1]);
|
||||
// 调整默认颜色
|
||||
$color = imagecolorallocate($src, 255, 255, 255);
|
||||
imagefill($src, 0, 0, $color);
|
||||
imagecopy($src, $this->im, 0, 0, $x, $y, $info[0], $info[1]);
|
||||
imagecopy($src, $water, 0, 0, 0, 0, $info[0], $info[1]);
|
||||
imagecopymerge($this->im, $src, $x, $y, 0, 0, $info[0], $info[1], $alpha);
|
||||
//销毁零时图片资源
|
||||
imagedestroy($src);
|
||||
} while (!empty($this->gif) && $this->gifNext());
|
||||
//销毁水印资源
|
||||
imagedestroy($water);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 图像添加文字
|
||||
*
|
||||
* @param string $text 添加的文字
|
||||
* @param string $font 字体路径
|
||||
* @param integer $size 字号
|
||||
* @param string $color 文字颜色
|
||||
* @param int $locate 文字写入位置
|
||||
* @param integer $offset 文字相对当前位置的偏移量
|
||||
* @param integer $angle 文字倾斜角度
|
||||
*
|
||||
* @return $this
|
||||
* @throws ImageException
|
||||
*/
|
||||
public function text($text, $font, $size, $color = '#00000000',
|
||||
$locate = self::WATER_SOUTHEAST, $offset = 0, $angle = 0) {
|
||||
|
||||
if (!is_file($font)) {
|
||||
throw new ImageException("不存在的字体文件:{$font}");
|
||||
}
|
||||
//获取文字信息
|
||||
$info = imagettfbbox($size, $angle, $font, $text);
|
||||
$minx = min($info[0], $info[2], $info[4], $info[6]);
|
||||
$maxx = max($info[0], $info[2], $info[4], $info[6]);
|
||||
$miny = min($info[1], $info[3], $info[5], $info[7]);
|
||||
$maxy = max($info[1], $info[3], $info[5], $info[7]);
|
||||
/* 计算文字初始坐标和尺寸 */
|
||||
$x = $minx;
|
||||
$y = abs($miny);
|
||||
$w = $maxx - $minx;
|
||||
$h = $maxy - $miny;
|
||||
/* 设定文字位置 */
|
||||
switch ($locate) {
|
||||
/* 右下角文字 */
|
||||
case self::WATER_SOUTHEAST:
|
||||
$x += $this->info['width'] - $w;
|
||||
$y += $this->info['height'] - $h;
|
||||
break;
|
||||
/* 左下角文字 */
|
||||
case self::WATER_SOUTHWEST:
|
||||
$y += $this->info['height'] - $h;
|
||||
break;
|
||||
/* 左上角文字 */
|
||||
case self::WATER_NORTHWEST:
|
||||
// 起始坐标即为左上角坐标,无需调整
|
||||
break;
|
||||
/* 右上角文字 */
|
||||
case self::WATER_NORTHEAST:
|
||||
$x += $this->info['width'] - $w;
|
||||
break;
|
||||
/* 居中文字 */
|
||||
case self::WATER_CENTER:
|
||||
$x += ($this->info['width'] - $w) / 2;
|
||||
$y += ($this->info['height'] - $h) / 2;
|
||||
break;
|
||||
/* 下居中文字 */
|
||||
case self::WATER_SOUTH:
|
||||
$x += ($this->info['width'] - $w) / 2;
|
||||
$y += $this->info['height'] - $h;
|
||||
break;
|
||||
/* 右居中文字 */
|
||||
case self::WATER_EAST:
|
||||
$x += $this->info['width'] - $w;
|
||||
$y += ($this->info['height'] - $h) / 2;
|
||||
break;
|
||||
/* 上居中文字 */
|
||||
case self::WATER_NORTH:
|
||||
$x += ($this->info['width'] - $w) / 2;
|
||||
break;
|
||||
/* 左居中文字 */
|
||||
case self::WATER_WEST:
|
||||
$y += ($this->info['height'] - $h) / 2;
|
||||
break;
|
||||
default:
|
||||
/* 自定义文字坐标 */
|
||||
if (is_array($locate)) {
|
||||
list($posx, $posy) = $locate;
|
||||
$x += $posx;
|
||||
$y += $posy;
|
||||
} else {
|
||||
throw new ImageException('不支持的文字位置类型');
|
||||
}
|
||||
}
|
||||
/* 设置偏移量 */
|
||||
if (is_array($offset)) {
|
||||
$offset = array_map('intval', $offset);
|
||||
list($ox, $oy) = $offset;
|
||||
} else {
|
||||
$offset = intval($offset);
|
||||
$ox = $oy = $offset;
|
||||
}
|
||||
/* 设置颜色 */
|
||||
if (is_string($color) && 0 === strpos($color, '#')) {
|
||||
$color = str_split(substr($color, 1), 2);
|
||||
$color = array_map('hexdec', $color);
|
||||
if (empty($color[3]) || $color[3] > 127) {
|
||||
$color[3] = 0;
|
||||
}
|
||||
} elseif (!is_array($color)) {
|
||||
throw new ImageException('错误的颜色值');
|
||||
}
|
||||
do {
|
||||
/* 写入文字 */
|
||||
$col = imagecolorallocatealpha($this->im, $color[0], $color[1], $color[2], $color[3]);
|
||||
imagettftext($this->im, $size, $angle, $x + $ox, $y + $oy, $col, $font, $text);
|
||||
} while (!empty($this->gif) && $this->gifNext());
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换到GIF的下一帧并保存当前帧
|
||||
*/
|
||||
protected function gifNext()
|
||||
{
|
||||
ob_start();
|
||||
ob_implicit_flush(0);
|
||||
imagegif($this->im);
|
||||
$img = ob_get_clean();
|
||||
$this->gif->image($img);
|
||||
$next = $this->gif->nextImage();
|
||||
if ($next) {
|
||||
imagedestroy($this->im);
|
||||
$this->im = imagecreatefromstring($next);
|
||||
return $next;
|
||||
} else {
|
||||
imagedestroy($this->im);
|
||||
$this->im = imagecreatefromstring($this->gif->image());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 析构方法,用于销毁图像资源
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
empty($this->im) || imagedestroy($this->im);
|
||||
}
|
||||
|
||||
}
|
||||
18
vendor/topthink/think-image/src/image/Exception.php
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\image;
|
||||
|
||||
|
||||
class Exception extends \RuntimeException
|
||||
{
|
||||
|
||||
}
|
||||
207
vendor/topthink/think-image/src/image/gif/Decoder.php
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\image\gif;
|
||||
|
||||
|
||||
class Decoder
|
||||
{
|
||||
public $GIF_buffer = [];
|
||||
public $GIF_arrays = [];
|
||||
public $GIF_delays = [];
|
||||
public $GIF_stream = "";
|
||||
public $GIF_string = "";
|
||||
public $GIF_bfseek = 0;
|
||||
public $GIF_screen = [];
|
||||
public $GIF_global = [];
|
||||
public $GIF_sorted;
|
||||
public $GIF_colorS;
|
||||
public $GIF_colorC;
|
||||
public $GIF_colorF;
|
||||
|
||||
/*
|
||||
:::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::
|
||||
:: GIFDecoder ( $GIF_pointer )
|
||||
::
|
||||
*/
|
||||
public function __construct($GIF_pointer)
|
||||
{
|
||||
$this->GIF_stream = $GIF_pointer;
|
||||
$this->getByte(6); // GIF89a
|
||||
$this->getByte(7); // Logical Screen Descriptor
|
||||
$this->GIF_screen = $this->GIF_buffer;
|
||||
$this->GIF_colorF = $this->GIF_buffer[4] & 0x80 ? 1 : 0;
|
||||
$this->GIF_sorted = $this->GIF_buffer[4] & 0x08 ? 1 : 0;
|
||||
$this->GIF_colorC = $this->GIF_buffer[4] & 0x07;
|
||||
$this->GIF_colorS = 2 << $this->GIF_colorC;
|
||||
if (1 == $this->GIF_colorF) {
|
||||
$this->getByte(3 * $this->GIF_colorS);
|
||||
$this->GIF_global = $this->GIF_buffer;
|
||||
}
|
||||
|
||||
for ($cycle = 1; $cycle;) {
|
||||
if ($this->getByte(1)) {
|
||||
switch ($this->GIF_buffer[0]) {
|
||||
case 0x21:
|
||||
$this->readExtensions();
|
||||
break;
|
||||
case 0x2C:
|
||||
$this->readDescriptor();
|
||||
break;
|
||||
case 0x3B:
|
||||
$cycle = 0;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$cycle = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
:::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::
|
||||
:: GIFReadExtension ( )
|
||||
::
|
||||
*/
|
||||
public function readExtensions()
|
||||
{
|
||||
$this->getByte(1);
|
||||
for (; ;) {
|
||||
$this->getByte(1);
|
||||
if (($u = $this->GIF_buffer[0]) == 0x00) {
|
||||
break;
|
||||
}
|
||||
$this->getByte($u);
|
||||
/*
|
||||
* 07.05.2007.
|
||||
* Implemented a new line for a new function
|
||||
* to determine the originaly delays between
|
||||
* frames.
|
||||
*
|
||||
*/
|
||||
if (4 == $u) {
|
||||
$this->GIF_delays[] = ($this->GIF_buffer[1] | $this->GIF_buffer[2] << 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
:::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::
|
||||
:: GIFReadExtension ( )
|
||||
::
|
||||
*/
|
||||
public function readDescriptor()
|
||||
{
|
||||
$this->getByte(9);
|
||||
$GIF_screen = $this->GIF_buffer;
|
||||
$GIF_colorF = $this->GIF_buffer[8] & 0x80 ? 1 : 0;
|
||||
if ($GIF_colorF) {
|
||||
$GIF_code = $this->GIF_buffer[8] & 0x07;
|
||||
$GIF_sort = $this->GIF_buffer[8] & 0x20 ? 1 : 0;
|
||||
} else {
|
||||
$GIF_code = $this->GIF_colorC;
|
||||
$GIF_sort = $this->GIF_sorted;
|
||||
}
|
||||
$GIF_size = 2 << $GIF_code;
|
||||
$this->GIF_screen[4] &= 0x70;
|
||||
$this->GIF_screen[4] |= 0x80;
|
||||
$this->GIF_screen[4] |= $GIF_code;
|
||||
if ($GIF_sort) {
|
||||
$this->GIF_screen[4] |= 0x08;
|
||||
}
|
||||
$this->GIF_string = "GIF87a";
|
||||
$this->putByte($this->GIF_screen);
|
||||
if (1 == $GIF_colorF) {
|
||||
$this->getByte(3 * $GIF_size);
|
||||
$this->putByte($this->GIF_buffer);
|
||||
} else {
|
||||
$this->putByte($this->GIF_global);
|
||||
}
|
||||
$this->GIF_string .= chr(0x2C);
|
||||
$GIF_screen[8] &= 0x40;
|
||||
$this->putByte($GIF_screen);
|
||||
$this->getByte(1);
|
||||
$this->putByte($this->GIF_buffer);
|
||||
for (; ;) {
|
||||
$this->getByte(1);
|
||||
$this->putByte($this->GIF_buffer);
|
||||
if (($u = $this->GIF_buffer[0]) == 0x00) {
|
||||
break;
|
||||
}
|
||||
$this->getByte($u);
|
||||
$this->putByte($this->GIF_buffer);
|
||||
}
|
||||
$this->GIF_string .= chr(0x3B);
|
||||
/*
|
||||
Add frames into $GIF_stream array...
|
||||
*/
|
||||
$this->GIF_arrays[] = $this->GIF_string;
|
||||
}
|
||||
|
||||
/*
|
||||
:::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::
|
||||
:: GIFGetByte ( $len )
|
||||
::
|
||||
*/
|
||||
public function getByte($len)
|
||||
{
|
||||
$this->GIF_buffer = [];
|
||||
for ($i = 0; $i < $len; $i++) {
|
||||
if ($this->GIF_bfseek > strlen($this->GIF_stream)) {
|
||||
return 0;
|
||||
}
|
||||
$this->GIF_buffer[] = ord($this->GIF_stream{$this->GIF_bfseek++});
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
:::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::
|
||||
:: GIFPutByte ( $bytes )
|
||||
::
|
||||
*/
|
||||
public function putByte($bytes)
|
||||
{
|
||||
for ($i = 0; $i < count($bytes); $i++) {
|
||||
$this->GIF_string .= chr($bytes[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
:::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::
|
||||
:: PUBLIC FUNCTIONS
|
||||
::
|
||||
::
|
||||
:: GIFGetFrames ( )
|
||||
::
|
||||
*/
|
||||
public function getFrames()
|
||||
{
|
||||
return ($this->GIF_arrays);
|
||||
}
|
||||
|
||||
/*
|
||||
:::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::
|
||||
:: GIFGetDelays ( )
|
||||
::
|
||||
*/
|
||||
public function getDelays()
|
||||
{
|
||||
return ($this->GIF_delays);
|
||||
}
|
||||
}
|
||||
222
vendor/topthink/think-image/src/image/gif/Encoder.php
vendored
Normal file
@@ -0,0 +1,222 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace think\image\gif;
|
||||
|
||||
class Encoder
|
||||
{
|
||||
public $GIF = "GIF89a"; /* GIF header 6 bytes */
|
||||
public $VER = "GIFEncoder V2.05"; /* Encoder version */
|
||||
public $BUF = [];
|
||||
public $LOP = 0;
|
||||
public $DIS = 2;
|
||||
public $COL = -1;
|
||||
public $IMG = -1;
|
||||
public $ERR = [
|
||||
'ERR00' => "Does not supported function for only one image!",
|
||||
'ERR01' => "Source is not a GIF image!",
|
||||
'ERR02' => "Unintelligible flag ",
|
||||
'ERR03' => "Does not make animation from animated GIF source",
|
||||
];
|
||||
|
||||
/*
|
||||
:::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::
|
||||
:: GIFEncoder...
|
||||
::
|
||||
*/
|
||||
public function __construct(
|
||||
$GIF_src, $GIF_dly, $GIF_lop, $GIF_dis,
|
||||
$GIF_red, $GIF_grn, $GIF_blu, $GIF_mod
|
||||
)
|
||||
{
|
||||
if (!is_array($GIF_src)) {
|
||||
printf("%s: %s", $this->VER, $this->ERR['ERR00']);
|
||||
exit(0);
|
||||
}
|
||||
$this->LOP = ($GIF_lop > -1) ? $GIF_lop : 0;
|
||||
$this->DIS = ($GIF_dis > -1) ? (($GIF_dis < 3) ? $GIF_dis : 3) : 2;
|
||||
$this->COL = ($GIF_red > -1 && $GIF_grn > -1 && $GIF_blu > -1) ?
|
||||
($GIF_red | ($GIF_grn << 8) | ($GIF_blu << 16)) : -1;
|
||||
for ($i = 0; $i < count($GIF_src); $i++) {
|
||||
if (strtolower($GIF_mod) == "url") {
|
||||
$this->BUF[] = fread(fopen($GIF_src[$i], "rb"), filesize($GIF_src[$i]));
|
||||
} else if (strtolower($GIF_mod) == "bin") {
|
||||
$this->BUF[] = $GIF_src[$i];
|
||||
} else {
|
||||
printf("%s: %s ( %s )!", $this->VER, $this->ERR['ERR02'], $GIF_mod);
|
||||
exit(0);
|
||||
}
|
||||
if (substr($this->BUF[$i], 0, 6) != "GIF87a" && substr($this->BUF[$i], 0, 6) != "GIF89a") {
|
||||
printf("%s: %d %s", $this->VER, $i, $this->ERR['ERR01']);
|
||||
exit(0);
|
||||
}
|
||||
for ($j = (13 + 3 * (2 << (ord($this->BUF[$i]{10}) & 0x07))), $k = true; $k; $j++) {
|
||||
switch ($this->BUF[$i]{$j}) {
|
||||
case "!":
|
||||
if ((substr($this->BUF[$i], ($j + 3), 8)) == "NETSCAPE") {
|
||||
printf("%s: %s ( %s source )!", $this->VER, $this->ERR['ERR03'], ($i + 1));
|
||||
exit(0);
|
||||
}
|
||||
break;
|
||||
case ";":
|
||||
$k = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->addHeader();
|
||||
for ($i = 0; $i < count($this->BUF); $i++) {
|
||||
$this->addFrames($i, $GIF_dly[$i]);
|
||||
}
|
||||
$this->addFooter();
|
||||
}
|
||||
|
||||
/*
|
||||
:::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::
|
||||
:: GIFAddHeader...
|
||||
::
|
||||
*/
|
||||
public function addHeader()
|
||||
{
|
||||
if (ord($this->BUF[0]{10}) & 0x80) {
|
||||
$cmap = 3 * (2 << (ord($this->BUF[0]{10}) & 0x07));
|
||||
$this->GIF .= substr($this->BUF[0], 6, 7);
|
||||
$this->GIF .= substr($this->BUF[0], 13, $cmap);
|
||||
$this->GIF .= "!\377\13NETSCAPE2.0\3\1" . $this->word($this->LOP) . "\0";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
:::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::
|
||||
:: GIFAddFrames...
|
||||
::
|
||||
*/
|
||||
public function addFrames($i, $d)
|
||||
{
|
||||
$Locals_img = '';
|
||||
$Locals_str = 13 + 3 * (2 << (ord($this->BUF[$i]{10}) & 0x07));
|
||||
$Locals_end = strlen($this->BUF[$i]) - $Locals_str - 1;
|
||||
$Locals_tmp = substr($this->BUF[$i], $Locals_str, $Locals_end);
|
||||
$Global_len = 2 << (ord($this->BUF[0]{10}) & 0x07);
|
||||
$Locals_len = 2 << (ord($this->BUF[$i]{10}) & 0x07);
|
||||
$Global_rgb = substr($this->BUF[0], 13,
|
||||
3 * (2 << (ord($this->BUF[0]{10}) & 0x07)));
|
||||
$Locals_rgb = substr($this->BUF[$i], 13,
|
||||
3 * (2 << (ord($this->BUF[$i]{10}) & 0x07)));
|
||||
$Locals_ext = "!\xF9\x04" . chr(($this->DIS << 2) + 0) .
|
||||
chr(($d >> 0) & 0xFF) . chr(($d >> 8) & 0xFF) . "\x0\x0";
|
||||
if ($this->COL > -1 && ord($this->BUF[$i]{10}) & 0x80) {
|
||||
for ($j = 0; $j < (2 << (ord($this->BUF[$i]{10}) & 0x07)); $j++) {
|
||||
if (
|
||||
ord($Locals_rgb{3 * $j + 0}) == (($this->COL >> 16) & 0xFF) &&
|
||||
ord($Locals_rgb{3 * $j + 1}) == (($this->COL >> 8) & 0xFF) &&
|
||||
ord($Locals_rgb{3 * $j + 2}) == (($this->COL >> 0) & 0xFF)
|
||||
) {
|
||||
$Locals_ext = "!\xF9\x04" . chr(($this->DIS << 2) + 1) .
|
||||
chr(($d >> 0) & 0xFF) . chr(($d >> 8) & 0xFF) . chr($j) . "\x0";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
switch ($Locals_tmp{0}) {
|
||||
case "!":
|
||||
/**
|
||||
* @var string $Locals_img ;
|
||||
*/
|
||||
$Locals_img = substr($Locals_tmp, 8, 10);
|
||||
$Locals_tmp = substr($Locals_tmp, 18, strlen($Locals_tmp) - 18);
|
||||
break;
|
||||
case ",":
|
||||
$Locals_img = substr($Locals_tmp, 0, 10);
|
||||
$Locals_tmp = substr($Locals_tmp, 10, strlen($Locals_tmp) - 10);
|
||||
break;
|
||||
}
|
||||
if (ord($this->BUF[$i]{10}) & 0x80 && $this->IMG > -1) {
|
||||
if ($Global_len == $Locals_len) {
|
||||
if ($this->blockCompare($Global_rgb, $Locals_rgb, $Global_len)) {
|
||||
$this->GIF .= ($Locals_ext . $Locals_img . $Locals_tmp);
|
||||
} else {
|
||||
$byte = ord($Locals_img{9});
|
||||
$byte |= 0x80;
|
||||
$byte &= 0xF8;
|
||||
$byte |= (ord($this->BUF[0]{10}) & 0x07);
|
||||
$Locals_img{9} = chr($byte);
|
||||
$this->GIF .= ($Locals_ext . $Locals_img . $Locals_rgb . $Locals_tmp);
|
||||
}
|
||||
} else {
|
||||
$byte = ord($Locals_img{9});
|
||||
$byte |= 0x80;
|
||||
$byte &= 0xF8;
|
||||
$byte |= (ord($this->BUF[$i]{10}) & 0x07);
|
||||
$Locals_img{9} = chr($byte);
|
||||
$this->GIF .= ($Locals_ext . $Locals_img . $Locals_rgb . $Locals_tmp);
|
||||
}
|
||||
} else {
|
||||
$this->GIF .= ($Locals_ext . $Locals_img . $Locals_tmp);
|
||||
}
|
||||
$this->IMG = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
:::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::
|
||||
:: GIFAddFooter...
|
||||
::
|
||||
*/
|
||||
public function addFooter()
|
||||
{
|
||||
$this->GIF .= ";";
|
||||
}
|
||||
|
||||
/*
|
||||
:::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::
|
||||
:: GIFBlockCompare...
|
||||
::
|
||||
*/
|
||||
public function blockCompare($GlobalBlock, $LocalBlock, $Len)
|
||||
{
|
||||
for ($i = 0; $i < $Len; $i++) {
|
||||
if (
|
||||
$GlobalBlock{3 * $i + 0} != $LocalBlock{3 * $i + 0} ||
|
||||
$GlobalBlock{3 * $i + 1} != $LocalBlock{3 * $i + 1} ||
|
||||
$GlobalBlock{3 * $i + 2} != $LocalBlock{3 * $i + 2}
|
||||
) {
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
:::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::
|
||||
:: GIFWord...
|
||||
::
|
||||
*/
|
||||
public function word($int)
|
||||
{
|
||||
return (chr($int & 0xFF) . chr(($int >> 8) & 0xFF));
|
||||
}
|
||||
|
||||
/*
|
||||
:::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
::
|
||||
:: GetAnimation...
|
||||
::
|
||||
*/
|
||||
public function getAnimation()
|
||||
{
|
||||
return ($this->GIF);
|
||||
}
|
||||
}
|
||||
88
vendor/topthink/think-image/src/image/gif/Gif.php
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\image\gif;
|
||||
|
||||
class Gif
|
||||
{
|
||||
/**
|
||||
* GIF帧列表
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $frames = [];
|
||||
/**
|
||||
* 每帧等待时间列表
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $delays = [];
|
||||
|
||||
/**
|
||||
* 构造方法,用于解码GIF图片
|
||||
*
|
||||
* @param string $src GIF图片数据
|
||||
* @param string $mod 图片数据类型
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function __construct($src = null, $mod = 'url')
|
||||
{
|
||||
if (!is_null($src)) {
|
||||
if ('url' == $mod && is_file($src)) {
|
||||
$src = file_get_contents($src);
|
||||
}
|
||||
/* 解码GIF图片 */
|
||||
try {
|
||||
$de = new Decoder($src);
|
||||
$this->frames = $de->getFrames();
|
||||
$this->delays = $de->getDelays();
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception("解码GIF图片出错");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置或获取当前帧的数据
|
||||
*
|
||||
* @param string $stream 二进制数据流
|
||||
* @return mixed 获取到的数据
|
||||
*/
|
||||
public function image($stream = null)
|
||||
{
|
||||
if (is_null($stream)) {
|
||||
$current = current($this->frames);
|
||||
return false === $current ? reset($this->frames) : $current;
|
||||
}
|
||||
$this->frames[key($this->frames)] = $stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将当前帧移动到下一帧
|
||||
*
|
||||
* @return string 当前帧数据
|
||||
*/
|
||||
public function nextImage()
|
||||
{
|
||||
return next($this->frames);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编码并保存当前GIF图片
|
||||
*
|
||||
* @param string $pathname 图片名称
|
||||
*/
|
||||
public function save($pathname)
|
||||
{
|
||||
$gif = new Encoder($this->frames, $this->delays, 0, 2, 0, 0, 0, 'bin');
|
||||
file_put_contents($pathname, $gif->getAnimation());
|
||||
}
|
||||
}
|
||||
67
vendor/topthink/think-image/tests/CropTest.php
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace tests;
|
||||
|
||||
use think\Image;
|
||||
|
||||
class CropTest extends TestCase
|
||||
{
|
||||
public function testJpeg()
|
||||
{
|
||||
$pathname = TEST_PATH . 'tmp/crop.jpg';
|
||||
$image = Image::open($this->getJpeg());
|
||||
|
||||
$image->crop(200, 200, 100, 100, 300, 300)->save($pathname);
|
||||
|
||||
$this->assertEquals(300, $image->width());
|
||||
$this->assertEquals(300, $image->height());
|
||||
|
||||
$file = new \SplFileInfo($pathname);
|
||||
|
||||
$this->assertTrue($file->isFile());
|
||||
|
||||
@unlink($pathname);
|
||||
}
|
||||
|
||||
public function testPng()
|
||||
{
|
||||
$pathname = TEST_PATH . 'tmp/crop.png';
|
||||
$image = Image::open($this->getPng());
|
||||
|
||||
$image->crop(200, 200, 100, 100, 300, 300)->save($pathname);
|
||||
|
||||
$this->assertEquals(300, $image->width());
|
||||
$this->assertEquals(300, $image->height());
|
||||
|
||||
$file = new \SplFileInfo($pathname);
|
||||
|
||||
$this->assertTrue($file->isFile());
|
||||
|
||||
@unlink($pathname);
|
||||
}
|
||||
|
||||
public function testGif()
|
||||
{
|
||||
$pathname = TEST_PATH . 'tmp/crop.gif';
|
||||
$image = Image::open($this->getGif());
|
||||
|
||||
$image->crop(200, 200, 100, 100, 300, 300)->save($pathname);
|
||||
|
||||
$this->assertEquals(300, $image->width());
|
||||
$this->assertEquals(300, $image->height());
|
||||
|
||||
$file = new \SplFileInfo($pathname);
|
||||
|
||||
$this->assertTrue($file->isFile());
|
||||
|
||||
@unlink($pathname);
|
||||
}
|
||||
}
|
||||
43
vendor/topthink/think-image/tests/FlipTest.php
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace tests;
|
||||
|
||||
use think\Image;
|
||||
|
||||
class FlipTest extends TestCase
|
||||
{
|
||||
public function testJpeg()
|
||||
{
|
||||
$pathname = TEST_PATH . 'tmp/flip.jpg';
|
||||
$image = Image::open($this->getJpeg());
|
||||
$image->flip()->save($pathname);
|
||||
|
||||
$file = new \SplFileInfo($pathname);
|
||||
|
||||
$this->assertTrue($file->isFile());
|
||||
|
||||
@unlink($pathname);
|
||||
}
|
||||
|
||||
|
||||
public function testGif()
|
||||
{
|
||||
$pathname = TEST_PATH . 'tmp/flip.gif';
|
||||
$image = Image::open($this->getGif());
|
||||
$image->flip(Image::FLIP_Y)->save($pathname);
|
||||
|
||||
$file = new \SplFileInfo($pathname);
|
||||
|
||||
$this->assertTrue($file->isFile());
|
||||
|
||||
@unlink($pathname);
|
||||
}
|
||||
}
|
||||
60
vendor/topthink/think-image/tests/InfoTest.php
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace tests;
|
||||
|
||||
use think\Image;
|
||||
|
||||
class InfoTest extends TestCase
|
||||
{
|
||||
|
||||
public function testOpen()
|
||||
{
|
||||
$this->setExpectedException("\\think\\image\\Exception");
|
||||
Image::open('');
|
||||
}
|
||||
|
||||
public function testIllegal()
|
||||
{
|
||||
$this->setExpectedException("\\think\\image\\Exception", 'Illegal image file');
|
||||
Image::open(TEST_PATH . 'images/test.bmp');
|
||||
}
|
||||
|
||||
public function testJpeg()
|
||||
{
|
||||
$image = Image::open($this->getJpeg());
|
||||
$this->assertEquals(800, $image->width());
|
||||
$this->assertEquals(600, $image->height());
|
||||
$this->assertEquals('jpeg', $image->type());
|
||||
$this->assertEquals('image/jpeg', $image->mime());
|
||||
$this->assertEquals([800, 600], $image->size());
|
||||
}
|
||||
|
||||
|
||||
public function testPng()
|
||||
{
|
||||
$image = Image::open($this->getPng());
|
||||
$this->assertEquals(800, $image->width());
|
||||
$this->assertEquals(600, $image->height());
|
||||
$this->assertEquals('png', $image->type());
|
||||
$this->assertEquals('image/png', $image->mime());
|
||||
$this->assertEquals([800, 600], $image->size());
|
||||
}
|
||||
|
||||
public function testGif()
|
||||
{
|
||||
$image = Image::open($this->getGif());
|
||||
$this->assertEquals(380, $image->width());
|
||||
$this->assertEquals(216, $image->height());
|
||||
$this->assertEquals('gif', $image->type());
|
||||
$this->assertEquals('image/gif', $image->mime());
|
||||
$this->assertEquals([380, 216], $image->size());
|
||||
}
|
||||
}
|
||||
42
vendor/topthink/think-image/tests/RotateTest.php
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace tests;
|
||||
|
||||
use think\Image;
|
||||
|
||||
class RotateTest extends TestCase
|
||||
{
|
||||
public function testJpeg()
|
||||
{
|
||||
$pathname = TEST_PATH . 'tmp/rotate.jpg';
|
||||
$image = Image::open($this->getJpeg());
|
||||
$image->rotate(90)->save($pathname);
|
||||
|
||||
$file = new \SplFileInfo($pathname);
|
||||
|
||||
$this->assertTrue($file->isFile());
|
||||
|
||||
@unlink($pathname);
|
||||
}
|
||||
|
||||
public function testGif()
|
||||
{
|
||||
$pathname = TEST_PATH . 'tmp/rotate.gif';
|
||||
$image = Image::open($this->getGif());
|
||||
$image->rotate(90)->save($pathname);
|
||||
|
||||
$file = new \SplFileInfo($pathname);
|
||||
|
||||
$this->assertTrue($file->isFile());
|
||||
|
||||
@unlink($pathname);
|
||||
}
|
||||
}
|
||||
33
vendor/topthink/think-image/tests/TestCase.php
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace tests;
|
||||
|
||||
use think\File;
|
||||
|
||||
abstract class TestCase extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
protected function getJpeg()
|
||||
{
|
||||
return new File(TEST_PATH . 'images/test.jpg');
|
||||
}
|
||||
|
||||
protected function getPng()
|
||||
{
|
||||
return new File(TEST_PATH . 'images/test.png');
|
||||
}
|
||||
|
||||
protected function getGif()
|
||||
{
|
||||
return new File(TEST_PATH . 'images/test.gif');
|
||||
}
|
||||
}
|
||||
58
vendor/topthink/think-image/tests/TextTest.php
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace tests;
|
||||
|
||||
use think\Image;
|
||||
|
||||
class TextTest extends TestCase
|
||||
{
|
||||
public function testJpeg()
|
||||
{
|
||||
$pathname = TEST_PATH . 'tmp/text.jpg';
|
||||
$image = Image::open($this->getJpeg());
|
||||
|
||||
$image->text('test', TEST_PATH . 'images/test.ttf', 12)->save($pathname);
|
||||
|
||||
$file = new \SplFileInfo($pathname);
|
||||
|
||||
$this->assertTrue($file->isFile());
|
||||
|
||||
@unlink($pathname);
|
||||
}
|
||||
|
||||
public function testPng()
|
||||
{
|
||||
$pathname = TEST_PATH . 'tmp/text.png';
|
||||
$image = Image::open($this->getPng());
|
||||
|
||||
$image->text('test', TEST_PATH . 'images/test.ttf', 12)->save($pathname);
|
||||
|
||||
$file = new \SplFileInfo($pathname);
|
||||
|
||||
$this->assertTrue($file->isFile());
|
||||
|
||||
@unlink($pathname);
|
||||
}
|
||||
|
||||
public function testGif()
|
||||
{
|
||||
$pathname = TEST_PATH . 'tmp/text.gif';
|
||||
$image = Image::open($this->getGif());
|
||||
|
||||
$image->text('test', TEST_PATH . 'images/test.ttf', 12)->save($pathname);
|
||||
|
||||
$file = new \SplFileInfo($pathname);
|
||||
|
||||
$this->assertTrue($file->isFile());
|
||||
|
||||
@unlink($pathname);
|
||||
}
|
||||
}
|
||||
284
vendor/topthink/think-image/tests/ThumbTest.php
vendored
Normal file
@@ -0,0 +1,284 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace tests;
|
||||
|
||||
use think\Image;
|
||||
|
||||
class ThumbTest extends TestCase
|
||||
{
|
||||
public function testJpeg()
|
||||
{
|
||||
$pathname = TEST_PATH . 'tmp/thumb.jpg';
|
||||
|
||||
//1
|
||||
$image = Image::open($this->getJpeg());
|
||||
|
||||
$image->thumb(200, 200, Image::THUMB_CENTER)->save($pathname);
|
||||
|
||||
$this->assertEquals(200, $image->width());
|
||||
$this->assertEquals(200, $image->height());
|
||||
|
||||
$file = new \SplFileInfo($pathname);
|
||||
|
||||
$this->assertTrue($file->isFile());
|
||||
|
||||
@unlink($pathname);
|
||||
|
||||
//2
|
||||
$image = Image::open($this->getJpeg());
|
||||
|
||||
$image->thumb(200, 200, Image::THUMB_SCALING)->save($pathname);
|
||||
|
||||
$this->assertEquals(200, $image->width());
|
||||
$this->assertEquals(150, $image->height());
|
||||
|
||||
$file = new \SplFileInfo($pathname);
|
||||
|
||||
$this->assertTrue($file->isFile());
|
||||
|
||||
@unlink($pathname);
|
||||
|
||||
//3
|
||||
$image = Image::open($this->getJpeg());
|
||||
|
||||
$image->thumb(200, 200, Image::THUMB_FILLED)->save($pathname);
|
||||
|
||||
$this->assertEquals(200, $image->width());
|
||||
$this->assertEquals(200, $image->height());
|
||||
|
||||
$file = new \SplFileInfo($pathname);
|
||||
|
||||
$this->assertTrue($file->isFile());
|
||||
|
||||
@unlink($pathname);
|
||||
|
||||
//4
|
||||
$image = Image::open($this->getJpeg());
|
||||
|
||||
$image->thumb(200, 200, Image::THUMB_NORTHWEST)->save($pathname);
|
||||
|
||||
$this->assertEquals(200, $image->width());
|
||||
$this->assertEquals(200, $image->height());
|
||||
|
||||
$file = new \SplFileInfo($pathname);
|
||||
|
||||
$this->assertTrue($file->isFile());
|
||||
|
||||
@unlink($pathname);
|
||||
|
||||
//5
|
||||
$image = Image::open($this->getJpeg());
|
||||
|
||||
$image->thumb(200, 200, Image::THUMB_SOUTHEAST)->save($pathname);
|
||||
|
||||
$this->assertEquals(200, $image->width());
|
||||
$this->assertEquals(200, $image->height());
|
||||
|
||||
$file = new \SplFileInfo($pathname);
|
||||
|
||||
$this->assertTrue($file->isFile());
|
||||
|
||||
@unlink($pathname);
|
||||
|
||||
//6
|
||||
$image = Image::open($this->getJpeg());
|
||||
|
||||
$image->thumb(200, 200, Image::THUMB_FIXED)->save($pathname);
|
||||
|
||||
$this->assertEquals(200, $image->width());
|
||||
$this->assertEquals(200, $image->height());
|
||||
|
||||
$file = new \SplFileInfo($pathname);
|
||||
|
||||
$this->assertTrue($file->isFile());
|
||||
|
||||
@unlink($pathname);
|
||||
}
|
||||
|
||||
|
||||
public function testPng()
|
||||
{
|
||||
$pathname = TEST_PATH . 'tmp/thumb.png';
|
||||
|
||||
//1
|
||||
$image = Image::open($this->getPng());
|
||||
|
||||
$image->thumb(200, 200, Image::THUMB_CENTER)->save($pathname);
|
||||
|
||||
$this->assertEquals(200, $image->width());
|
||||
$this->assertEquals(200, $image->height());
|
||||
|
||||
$file = new \SplFileInfo($pathname);
|
||||
|
||||
$this->assertTrue($file->isFile());
|
||||
|
||||
@unlink($pathname);
|
||||
|
||||
//2
|
||||
$image = Image::open($this->getPng());
|
||||
|
||||
$image->thumb(200, 200, Image::THUMB_SCALING)->save($pathname);
|
||||
|
||||
$this->assertEquals(200, $image->width());
|
||||
$this->assertEquals(150, $image->height());
|
||||
|
||||
$file = new \SplFileInfo($pathname);
|
||||
|
||||
$this->assertTrue($file->isFile());
|
||||
|
||||
@unlink($pathname);
|
||||
|
||||
//3
|
||||
$image = Image::open($this->getPng());
|
||||
|
||||
$image->thumb(200, 200, Image::THUMB_FILLED)->save($pathname);
|
||||
|
||||
$this->assertEquals(200, $image->width());
|
||||
$this->assertEquals(200, $image->height());
|
||||
|
||||
$file = new \SplFileInfo($pathname);
|
||||
|
||||
$this->assertTrue($file->isFile());
|
||||
|
||||
@unlink($pathname);
|
||||
|
||||
//4
|
||||
$image = Image::open($this->getPng());
|
||||
|
||||
$image->thumb(200, 200, Image::THUMB_NORTHWEST)->save($pathname);
|
||||
|
||||
$this->assertEquals(200, $image->width());
|
||||
$this->assertEquals(200, $image->height());
|
||||
|
||||
$file = new \SplFileInfo($pathname);
|
||||
|
||||
$this->assertTrue($file->isFile());
|
||||
|
||||
@unlink($pathname);
|
||||
|
||||
//5
|
||||
$image = Image::open($this->getPng());
|
||||
|
||||
$image->thumb(200, 200, Image::THUMB_SOUTHEAST)->save($pathname);
|
||||
|
||||
$this->assertEquals(200, $image->width());
|
||||
$this->assertEquals(200, $image->height());
|
||||
|
||||
$file = new \SplFileInfo($pathname);
|
||||
|
||||
$this->assertTrue($file->isFile());
|
||||
|
||||
@unlink($pathname);
|
||||
|
||||
//6
|
||||
$image = Image::open($this->getPng());
|
||||
|
||||
$image->thumb(200, 200, Image::THUMB_FIXED)->save($pathname);
|
||||
|
||||
$this->assertEquals(200, $image->width());
|
||||
$this->assertEquals(200, $image->height());
|
||||
|
||||
$file = new \SplFileInfo($pathname);
|
||||
|
||||
$this->assertTrue($file->isFile());
|
||||
|
||||
@unlink($pathname);
|
||||
}
|
||||
|
||||
public function testGif()
|
||||
{
|
||||
$pathname = TEST_PATH . 'tmp/thumb.gif';
|
||||
|
||||
//1
|
||||
$image = Image::open($this->getGif());
|
||||
|
||||
$image->thumb(200, 200, Image::THUMB_CENTER)->save($pathname);
|
||||
|
||||
$this->assertEquals(200, $image->width());
|
||||
$this->assertEquals(200, $image->height());
|
||||
|
||||
$file = new \SplFileInfo($pathname);
|
||||
|
||||
$this->assertTrue($file->isFile());
|
||||
|
||||
@unlink($pathname);
|
||||
|
||||
//2
|
||||
$image = Image::open($this->getGif());
|
||||
|
||||
$image->thumb(200, 200, Image::THUMB_SCALING)->save($pathname);
|
||||
|
||||
$this->assertEquals(200, $image->width());
|
||||
$this->assertEquals(113, $image->height());
|
||||
|
||||
$file = new \SplFileInfo($pathname);
|
||||
|
||||
$this->assertTrue($file->isFile());
|
||||
|
||||
@unlink($pathname);
|
||||
|
||||
//3
|
||||
$image = Image::open($this->getGif());
|
||||
|
||||
$image->thumb(200, 200, Image::THUMB_FILLED)->save($pathname);
|
||||
|
||||
$this->assertEquals(200, $image->width());
|
||||
$this->assertEquals(200, $image->height());
|
||||
|
||||
$file = new \SplFileInfo($pathname);
|
||||
|
||||
$this->assertTrue($file->isFile());
|
||||
|
||||
@unlink($pathname);
|
||||
|
||||
//4
|
||||
$image = Image::open($this->getGif());
|
||||
|
||||
$image->thumb(200, 200, Image::THUMB_NORTHWEST)->save($pathname);
|
||||
|
||||
$this->assertEquals(200, $image->width());
|
||||
$this->assertEquals(200, $image->height());
|
||||
|
||||
$file = new \SplFileInfo($pathname);
|
||||
|
||||
$this->assertTrue($file->isFile());
|
||||
|
||||
@unlink($pathname);
|
||||
|
||||
//5
|
||||
$image = Image::open($this->getGif());
|
||||
|
||||
$image->thumb(200, 200, Image::THUMB_SOUTHEAST)->save($pathname);
|
||||
|
||||
$this->assertEquals(200, $image->width());
|
||||
$this->assertEquals(200, $image->height());
|
||||
|
||||
$file = new \SplFileInfo($pathname);
|
||||
|
||||
$this->assertTrue($file->isFile());
|
||||
|
||||
@unlink($pathname);
|
||||
|
||||
//6
|
||||
$image = Image::open($this->getGif());
|
||||
|
||||
$image->thumb(200, 200, Image::THUMB_FIXED)->save($pathname);
|
||||
|
||||
$this->assertEquals(200, $image->width());
|
||||
$this->assertEquals(200, $image->height());
|
||||
|
||||
$file = new \SplFileInfo($pathname);
|
||||
|
||||
$this->assertTrue($file->isFile());
|
||||
|
||||
@unlink($pathname);
|
||||
}
|
||||
}
|
||||
58
vendor/topthink/think-image/tests/WaterTest.php
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace tests;
|
||||
|
||||
use think\Image;
|
||||
|
||||
class WaterTest extends TestCase
|
||||
{
|
||||
public function testJpeg()
|
||||
{
|
||||
$pathname = TEST_PATH . 'tmp/water.jpg';
|
||||
$image = Image::open($this->getJpeg());
|
||||
|
||||
$image->water(TEST_PATH . 'images/test.gif')->save($pathname);
|
||||
|
||||
$file = new \SplFileInfo($pathname);
|
||||
|
||||
$this->assertTrue($file->isFile());
|
||||
|
||||
@unlink($pathname);
|
||||
}
|
||||
|
||||
public function testPng()
|
||||
{
|
||||
$pathname = TEST_PATH . 'tmp/water.png';
|
||||
$image = Image::open($this->getPng());
|
||||
|
||||
$image->water(TEST_PATH . 'images/test.gif')->save($pathname);
|
||||
|
||||
$file = new \SplFileInfo($pathname);
|
||||
|
||||
$this->assertTrue($file->isFile());
|
||||
|
||||
@unlink($pathname);
|
||||
}
|
||||
|
||||
public function testGif()
|
||||
{
|
||||
$pathname = TEST_PATH . 'tmp/water.gif';
|
||||
$image = Image::open($this->getGif());
|
||||
|
||||
$image->water(TEST_PATH . 'images/test.jpg')->save($pathname);
|
||||
|
||||
$file = new \SplFileInfo($pathname);
|
||||
|
||||
$this->assertTrue($file->isFile());
|
||||
|
||||
@unlink($pathname);
|
||||
}
|
||||
}
|
||||
15
vendor/topthink/think-image/tests/autoload.php
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
define('TEST_PATH', __DIR__ . '/');
|
||||
// 加载框架基础文件
|
||||
require __DIR__ . '/../thinkphp/base.php';
|
||||
\think\Loader::addNamespace('tests', TEST_PATH);
|
||||
\think\Loader::addNamespace('think', __DIR__ . '/../src/');
|
||||
0
vendor/topthink/think-image/tests/images/test.bmp
vendored
Normal file
BIN
vendor/topthink/think-image/tests/images/test.gif
vendored
Normal file
|
After Width: | Height: | Size: 233 KiB |
BIN
vendor/topthink/think-image/tests/images/test.jpg
vendored
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
BIN
vendor/topthink/think-image/tests/images/test.png
vendored
Normal file
|
After Width: | Height: | Size: 105 KiB |
BIN
vendor/topthink/think-image/tests/images/test.ttf
vendored
Normal file
2
vendor/topthink/think-image/tests/tmp/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
||||
3
vendor/topthink/think-installer/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
/.idea
|
||||
composer.lock
|
||||
/vendor
|
||||
25
vendor/topthink/think-installer/composer.json
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "topthink/think-installer",
|
||||
"type": "composer-plugin",
|
||||
"require": {
|
||||
"composer-plugin-api": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"composer/composer": "1.0.*@dev"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"authors": [
|
||||
{
|
||||
"name": "yunwuxin",
|
||||
"email": "448901948@qq.com"
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"think\\composer\\": "src"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"class": "think\\composer\\Plugin"
|
||||
}
|
||||
}
|
||||
26
vendor/topthink/think-installer/src/Plugin.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace think\composer;
|
||||
|
||||
use Composer\Composer;
|
||||
use Composer\Installer;
|
||||
use Composer\IO\IOInterface;
|
||||
use Composer\Plugin\PluginInterface;
|
||||
|
||||
class Plugin implements PluginInterface
|
||||
{
|
||||
public function activate(Composer $composer, IOInterface $io)
|
||||
{
|
||||
$manager = $composer->getInstallationManager();
|
||||
|
||||
//框架核心
|
||||
$manager->addInstaller(new ThinkFramework($io, $composer));
|
||||
|
||||
//单元测试
|
||||
$manager->addInstaller(new ThinkTesting($io, $composer));
|
||||
|
||||
//扩展
|
||||
$manager->addInstaller(new ThinkExtend($io, $composer));
|
||||
|
||||
}
|
||||
}
|
||||
77
vendor/topthink/think-installer/src/ThinkExtend.php
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\composer;
|
||||
|
||||
use Composer\Installer\LibraryInstaller;
|
||||
use Composer\Package\PackageInterface;
|
||||
use Composer\Repository\InstalledRepositoryInterface;
|
||||
|
||||
class ThinkExtend extends LibraryInstaller
|
||||
{
|
||||
|
||||
public function install(InstalledRepositoryInterface $repo, PackageInterface $package)
|
||||
{
|
||||
parent::install($repo, $package);
|
||||
$this->copyExtraFiles($package);
|
||||
}
|
||||
|
||||
public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target)
|
||||
{
|
||||
parent::update($repo, $initial, $target);
|
||||
$this->copyExtraFiles($target);
|
||||
|
||||
}
|
||||
|
||||
protected function copyExtraFiles(PackageInterface $package)
|
||||
{
|
||||
if ($this->composer->getPackage()->getType() == 'project') {
|
||||
|
||||
$extra = $package->getExtra();
|
||||
|
||||
if (!empty($extra['think-config'])) {
|
||||
|
||||
$composerExtra = $this->composer->getPackage()->getExtra();
|
||||
|
||||
$appDir = !empty($composerExtra['app-path']) ? $composerExtra['app-path'] : 'application';
|
||||
|
||||
if (is_dir($appDir)) {
|
||||
|
||||
$extraDir = $appDir . DIRECTORY_SEPARATOR . 'extra';
|
||||
$this->filesystem->ensureDirectoryExists($extraDir);
|
||||
|
||||
//配置文件
|
||||
foreach ((array) $extra['think-config'] as $name => $config) {
|
||||
$target = $extraDir . DIRECTORY_SEPARATOR . $name . '.php';
|
||||
$source = $this->getInstallPath($package) . DIRECTORY_SEPARATOR . $config;
|
||||
|
||||
if (is_file($target)) {
|
||||
$this->io->write("<info>File {$target} exist!</info>");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!is_file($source)) {
|
||||
$this->io->write("<info>File {$target} not exist!</info>");
|
||||
continue;
|
||||
}
|
||||
|
||||
copy($source, $target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function supports($packageType)
|
||||
{
|
||||
return 'think-extend' === $packageType;
|
||||
}
|
||||
}
|
||||
59
vendor/topthink/think-installer/src/ThinkFramework.php
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace think\composer;
|
||||
|
||||
use Composer\Installer\LibraryInstaller;
|
||||
use Composer\Package\PackageInterface;
|
||||
use Composer\Repository\InstalledRepositoryInterface;
|
||||
|
||||
class ThinkFramework extends LibraryInstaller
|
||||
{
|
||||
public function install(InstalledRepositoryInterface $repo, PackageInterface $package)
|
||||
{
|
||||
parent::install($repo, $package);
|
||||
if ($this->composer->getPackage()->getType() == 'project' && $package->getInstallationSource() != 'source') {
|
||||
//remove tests dir
|
||||
$this->filesystem->removeDirectory($this->getInstallPath($package) . DIRECTORY_SEPARATOR . 'tests');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getInstallPath(PackageInterface $package)
|
||||
{
|
||||
if ('topthink/framework' !== $package->getPrettyName()) {
|
||||
throw new \InvalidArgumentException('Unable to install this library!');
|
||||
}
|
||||
|
||||
if ($this->composer->getPackage()->getType() !== 'project') {
|
||||
return parent::getInstallPath($package);
|
||||
}
|
||||
|
||||
if ($this->composer->getPackage()) {
|
||||
$extra = $this->composer->getPackage()->getExtra();
|
||||
if (!empty($extra['think-path'])) {
|
||||
return $extra['think-path'];
|
||||
}
|
||||
}
|
||||
|
||||
return 'thinkphp';
|
||||
}
|
||||
|
||||
public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target)
|
||||
{
|
||||
parent::update($repo, $initial, $target);
|
||||
if ($this->composer->getPackage()->getType() == 'project' && $target->getInstallationSource() != 'source') {
|
||||
//remove tests dir
|
||||
$this->filesystem->removeDirectory($this->getInstallPath($target) . DIRECTORY_SEPARATOR . 'tests');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function supports($packageType)
|
||||
{
|
||||
return 'think-framework' === $packageType;
|
||||
}
|
||||
}
|
||||
68
vendor/topthink/think-installer/src/ThinkTesting.php
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace think\composer;
|
||||
|
||||
|
||||
use Composer\Installer\LibraryInstaller;
|
||||
use Composer\Package\PackageInterface;
|
||||
use Composer\Repository\InstalledRepositoryInterface;
|
||||
|
||||
class ThinkTesting extends LibraryInstaller
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getInstallPath(PackageInterface $package)
|
||||
{
|
||||
if ('topthink/think-testing' !== $package->getPrettyName()) {
|
||||
throw new \InvalidArgumentException('Unable to install this library!');
|
||||
}
|
||||
|
||||
return parent::getInstallPath($package);
|
||||
}
|
||||
|
||||
public function install(InstalledRepositoryInterface $repo, PackageInterface $package)
|
||||
{
|
||||
parent::install($repo, $package);
|
||||
|
||||
$this->copyTestDir($package);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target)
|
||||
{
|
||||
parent::update($repo, $initial, $target);
|
||||
|
||||
$this->copyTestDir($target);
|
||||
|
||||
}
|
||||
|
||||
private function copyTestDir(PackageInterface $package)
|
||||
{
|
||||
$appDir = dirname($this->vendorDir);
|
||||
$source = $this->getInstallPath($package) . DIRECTORY_SEPARATOR . 'example';
|
||||
if (!is_file($appDir . DIRECTORY_SEPARATOR . 'phpunit.xml')) {
|
||||
$this->filesystem->copyThenRemove($source, $appDir);
|
||||
} else {
|
||||
$this->filesystem->removeDirectoryPhp($source);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function supports($packageType)
|
||||
{
|
||||
return 'think-testing' === $packageType;
|
||||
}
|
||||
}
|
||||
3
vendor/topthink/think-migration/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
/vendor/
|
||||
.idea
|
||||
composer.lock
|
||||
32
vendor/topthink/think-migration/LICENSE
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
ThinkPHP遵循Apache2开源协议发布,并提供免费使用。
|
||||
版权所有Copyright © 2006-2016 by ThinkPHP (http://thinkphp.cn)
|
||||
All rights reserved。
|
||||
ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。
|
||||
|
||||
Apache Licence是著名的非盈利开源组织Apache采用的协议。
|
||||
该协议和BSD类似,鼓励代码共享和尊重原作者的著作权,
|
||||
允许代码修改,再作为开源或商业软件发布。需要满足
|
||||
的条件:
|
||||
1. 需要给代码的用户一份Apache Licence ;
|
||||
2. 如果你修改了代码,需要在被修改的文件中说明;
|
||||
3. 在延伸的代码中(修改和有源代码衍生的代码中)需要
|
||||
带有原来代码中的协议,商标,专利声明和其他原来作者规
|
||||
定需要包含的说明;
|
||||
4. 如果再发布的产品中包含一个Notice文件,则在Notice文
|
||||
件中需要带有本协议内容。你可以在Notice中增加自己的
|
||||
许可,但不可以表现为对Apache Licence构成更改。
|
||||
具体的协议参考:http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
6
vendor/topthink/think-migration/README.md
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
# thinkphp5 数据库迁移工具
|
||||
|
||||
## 安装
|
||||
~~~
|
||||
composer require topthink/think-migration
|
||||
~~~
|
||||
22
vendor/topthink/think-migration/composer.json
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "topthink/think-migration",
|
||||
"authors": [
|
||||
{
|
||||
"name": "yunwuxin",
|
||||
"email": "448901948@qq.com"
|
||||
}
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Phinx\\": "phinx/src/Phinx",
|
||||
"think\\migration\\": "src"
|
||||
},
|
||||
"files": [
|
||||
"src/config.php"
|
||||
]
|
||||
},
|
||||
"require-dev": {
|
||||
"topthink/framework": "^5.0"
|
||||
}
|
||||
}
|
||||
370
vendor/topthink/think-migration/phinx/CHANGELOG.md
vendored
Normal file
@@ -0,0 +1,370 @@
|
||||
# Version History
|
||||
|
||||
**0.6.5** (Thursday, 27 October 2016)
|
||||
|
||||
* Documentation updates
|
||||
* Pull requests
|
||||
* [#831](https://github.com/robmorgan/phinx/pull/831) Typos
|
||||
* [#929](https://github.com/robmorgan/phinx/pull/929) Support glob brace for seed paths
|
||||
* [#949](https://github.com/robmorgan/phinx/pull/949) Fix for Config::getMigrationBaseClassName
|
||||
* [#958](https://github.com/robmorgan/phinx/pull/958) Allow console input to be used within adapters
|
||||
|
||||
**0.6.4** (Wednesday, 27th July 2016)
|
||||
|
||||
* Documentation updates
|
||||
* Pull requests
|
||||
* [#909](https://github.com/robmorgan/phinx/pull/909) Declare test class properties
|
||||
* [#910](https://github.com/robmorgan/phinx/pull/910), [#916](https://github.com/robmorgan/phinx/pull/916) Remove unused variables
|
||||
* [#912](https://github.com/robmorgan/phinx/pull/912) ConfigInterface usage consistency
|
||||
* [#914](https://github.com/robmorgan/phinx/pull/914) Set return values and @return documentation
|
||||
* [#918](https://github.com/robmorgan/phinx/pull/918) Docblock correction for Phinx\Migration\Manager::executeSeed()
|
||||
* [#921](https://github.com/robmorgan/phinx/pull/921) Add Phinx\Wrapper\TextWrapper::getSeed()
|
||||
* Bug fixes
|
||||
* [#908](https://github.com/robmorgan/phinx/pull/908) Fix setting options for Column, ForeignKey and Index
|
||||
* [#922](https://github.com/robmorgan/phinx/pull/922) SQLite adapter drops table on changeColumn if there's a foreign key
|
||||
|
||||
**0.6.3** (Monday, 18th July 2016)
|
||||
|
||||
* New features
|
||||
* [#707](https://github.com/robmorgan/phinx/pull/707/files) Add arguments for timestamps columns names
|
||||
* Documentation cleanup
|
||||
* Bug fixes
|
||||
* [#884](https://github.com/robmorgan/phinx/pull/884) Only rollback 1 migration when only 2 migrations exist
|
||||
* Input and Output are now correctly supplied to migration template creation classes
|
||||
|
||||
**0.6.2** (Thursday, 23rd June 2016)
|
||||
|
||||
* Fix breakpoint support for Postgres
|
||||
* HHVM now passes all tests
|
||||
|
||||
**0.6.1** (Tuesday, 21st June 2016)
|
||||
|
||||
* Fix rollback when only 1 migration
|
||||
|
||||
**0.6.0** (Tuesday, 21st June 2016)
|
||||
|
||||
* Backward incompatibility - see [UPGRADE_0.6](UPGRADE_0.6.md) document
|
||||
* Introduce Input and Output access to migrations and template creation
|
||||
* New breakpoint command
|
||||
* Moved version history to this CHANGELOG.md document
|
||||
* More tests
|
||||
|
||||
**0.5.5** (Friday, 17th May 2016)
|
||||
|
||||
* Fix support for running multiple seeders
|
||||
* Bug fix for migration template source - defaults and command line
|
||||
* Bug fixes
|
||||
|
||||
**0.5.4** (Monday, 25th April 2016)
|
||||
|
||||
* Added support for running multiple seeders
|
||||
* Use `GLOB_BRACE` when finding migrations only if its available
|
||||
* Added support for MySQL `VARBINARY` column type
|
||||
* Minor bug fixes
|
||||
|
||||
**0.5.3** (Monday, 7th March 2016)
|
||||
|
||||
* Critical fix: allow `migration_name` to be `null`. Introduced in 0.5.2
|
||||
* Status command now shows migration start and end times
|
||||
* Bug fix for rolling back by date
|
||||
* Documentation improvements
|
||||
|
||||
**0.5.2** (Tuesday, 1st March 2016)
|
||||
|
||||
* Status command now includes missing migration names
|
||||
* Added support for Postgres table comments
|
||||
* Added `insert()` for the TablePrefixAdapter
|
||||
* Fixed the migration verbosity flag
|
||||
* Added MySQL 5.7 JSON support
|
||||
* Added support for MySQL `FULLTEXT` indexes
|
||||
* Postgres now supports `BIGSERIAL` for primary keys
|
||||
* Added support for MySQL index limits
|
||||
* Initial support for multiple migration paths (using glob)
|
||||
* Documentation improvements
|
||||
* Unit test enhancements
|
||||
|
||||
**0.5.1** (Wednesday, 30th December 2015)
|
||||
|
||||
* **PHP 5.3 is no longer supported!**
|
||||
* Add support for Symfony 3.0 components
|
||||
* Ensure that the `status` command returns the correct exit code
|
||||
* Allow `$version` to be passed into templates
|
||||
* Support for MySQL `YEAR` column type
|
||||
* Multiple documentation updates and corrections
|
||||
|
||||
**0.5.0** (Monday, 30th November 2015)
|
||||
|
||||
* Support for seeding data after database creation
|
||||
* The migration and seed directories are now nested under `db` by default
|
||||
* Moved `Phinx\Migration\Util` to `Phinx\Util\Util`
|
||||
* All `insert()` methods now have a slightly different method signature
|
||||
* Fixed key/insert operations for MySQL
|
||||
* Introduced `AdapterInterface::hasIndexByName()`
|
||||
* Improved `dropForeignKey()` handling for SQLite
|
||||
* Added support for the MySQL `binary` datatype. BLOBs now use the proper type.
|
||||
* The status command shows a count of pending migrations in JSON output
|
||||
* We are now testing against PHP 7
|
||||
|
||||
**0.4.6** (Friday, 11th September 2015)
|
||||
|
||||
* You can now set custom migration templates in the config files
|
||||
* Support for MySQL unsigned booleans
|
||||
* Support for Postgres `smallint` column types
|
||||
* Support for `AFTER` when using `changeColumn()` with MySQL
|
||||
* Support for `precision` and `scale` when using the Postgres `decimal` type
|
||||
* Fixed a bug where duplicate migration names could be used
|
||||
* The schema table is now created with a primary key
|
||||
* Fixed issues when using the MySQL `STRICT_TRANS_TABLE` mode
|
||||
* Improved the docs in the default migration template
|
||||
* Made Box PHAR ignore the bundled `phinx.yml` configuration file
|
||||
* Updated Box installer URL
|
||||
* Internal code improvements
|
||||
* Documentation improvements
|
||||
|
||||
**0.4.5** (Tuesday, 1st September 2015)
|
||||
|
||||
* The rollback command now supports a date argument
|
||||
* Fixed DBLIB DSN strings for Microsoft SQL Server
|
||||
* Postgres support for `jsonb` columns added
|
||||
* The `addTimestamps()` helper method no longer updates the `created_at` column
|
||||
* Fix for Postgres named foreign keys
|
||||
* Unit test improvements (including strict warnings)
|
||||
* Documentation improvements
|
||||
|
||||
**0.4.4** (Sunday, 14th June 2015)
|
||||
|
||||
* The `change` method is now the default
|
||||
* Added a generic adapter insert method. Warning: The implementation will change!
|
||||
* Updated Symfony depdencies to ~2.7
|
||||
* Support for MySQL `BLOB` column types
|
||||
* SQLite migration fixes
|
||||
* Documentation improvements
|
||||
|
||||
**0.4.3** (Monday, 23rd Feburary 2015)
|
||||
|
||||
* Postgres bugfix for modifying column DEFAULTs
|
||||
* MySQL bugfix for setting column INTEGER lengths
|
||||
* SQLite bugfix for creating multiple indexes with similar names
|
||||
|
||||
**0.4.2.1** (Saturday, 7th Feburary 2015)
|
||||
|
||||
* Proper release, updated docs
|
||||
|
||||
**0.4.2** (Friday, 6th Feburary 2015)
|
||||
|
||||
* Postgres support for `json` columns added
|
||||
* MySQL support for `enum` and `set` columns added
|
||||
* Allow setting `identity` option on columns
|
||||
* Template configuration and generation made more extensible
|
||||
* Created a base class for `ProxyAdapter` and `TablePrefixAdapter`
|
||||
* Switched to PSR-4
|
||||
|
||||
**0.4.1** (Tuesday, 23rd December 2014)
|
||||
|
||||
* MySQL support for reserved words in hasColumn and getColumns methods
|
||||
* Better MySQL Adapter test coverage and performance fixes
|
||||
* Updated dependent Symfony components to 2.6.x
|
||||
|
||||
**0.4.0** (Sunday, 14th December 2014)
|
||||
|
||||
* Adding initial support for running Phinx via a web interface
|
||||
* Support for table prefixes and suffixes
|
||||
* Bugfix for foreign key options
|
||||
* MySQL keeps column default when renaming columns
|
||||
* MySQL support for tiny/medium and longtext columns added
|
||||
* Changed SQL Server binary columns to varbinary
|
||||
* MySQL supports table comments
|
||||
* Postgres supports column comments
|
||||
* Empty strings are now supported for default column values
|
||||
* Booleans are now supported for default column values
|
||||
* Fixed SQL Server default constraint error when changing column types
|
||||
* Migration timestamps are now created in UTC
|
||||
* Locked Symfony Components to 2.5.0
|
||||
* Support for custom migration base classes
|
||||
* Cleaned up source code formatting
|
||||
* Migrations have access to the output stream
|
||||
* Support for custom PDO connections when a PHP config
|
||||
* Added support for Postgres UUID type
|
||||
* Fixed issue with Postgres dropping foreign keys
|
||||
|
||||
**0.3.8** (Sunday, 5th October 2014)
|
||||
|
||||
* Added new CHAR & Geospatial column types
|
||||
* Added MySQL unix socket support
|
||||
* Added precision & scale support for SQL Server
|
||||
* Several bug fixes for SQLite
|
||||
* Improved error messages
|
||||
* Overall code optimizations
|
||||
* Optimizations to MySQL hasTable method
|
||||
|
||||
**0.3.7** (Tuesday, 12th August 2014)
|
||||
|
||||
* Smarter configuration file support
|
||||
* Support for Postgres Schemas
|
||||
* Fixed charset support for Microsoft SQL Server
|
||||
* Fix for Unique indexes in all adapters
|
||||
* Improvements for MySQL foreign key migration syntax
|
||||
* Allow MySQL column types with extra info
|
||||
* Fixed SQLite autoincrement behaviour
|
||||
* PHPDoc improvements
|
||||
* Documentation improvements
|
||||
* Unit test improvements
|
||||
* Removing primary_key as a type
|
||||
|
||||
**0.3.6** (Sunday, 29th June 2014)
|
||||
|
||||
* Add custom adapter support
|
||||
* Fix PHP 5.3 compatibility for SQL Server
|
||||
|
||||
**0.3.5** (Saturday, 21st June 2014)
|
||||
|
||||
* Added Microsoft SQL Server support
|
||||
* Removed Primary Key column type
|
||||
* Cleaned up and optimized many methods
|
||||
* Updated Symfony dependencies to v2.5.0
|
||||
* PHPDoc improvements
|
||||
|
||||
**0.3.4** (Sunday, 27th April 2014)
|
||||
|
||||
* Added support MySQL unsigned integer, biginteger, float and decimal types
|
||||
* Added JSON output support for the status command
|
||||
* Fix a bug where Postgres couldnt rollback foreign keys
|
||||
* Moved Phinx type references to interface constants
|
||||
* Fixed a bug with SQLite in-memory databases
|
||||
|
||||
**0.3.3** (Saturday, 22nd March 2014)
|
||||
|
||||
* Added support for JSON configuration
|
||||
* Named index support for all adapters (thanks @archer308)
|
||||
* Updated Composer dependencies
|
||||
* Fix for SQLite Integer Type
|
||||
* Fix for MySQL port option
|
||||
|
||||
**0.3.2** (Monday, 24th February 2014)
|
||||
|
||||
* Adding better Postgres type support
|
||||
|
||||
**0.3.1** (Sunday, 23rd February 2014)
|
||||
|
||||
* Adding MySQL charset support to the YAML config
|
||||
* Removing trailing spaces
|
||||
|
||||
**0.3.0** (Sunday, 2nd February 2014)
|
||||
|
||||
* PSR-2 support
|
||||
* Method to add timestamps easily to tables
|
||||
* Support for column comments in the Postgres adapter
|
||||
* Fixes for MySQL driver options
|
||||
* Fixes for MySQL biginteger type
|
||||
|
||||
**0.2.9** (Saturday, 16th November 2013)
|
||||
|
||||
* Added SQLite Support
|
||||
* Improving the unit tests, especially on Windows
|
||||
|
||||
**0.2.8** (Sunday, 25th August 2013)
|
||||
|
||||
* Added PostgresSQL Support
|
||||
|
||||
**0.2.7** (Saturday, 24th August 2013)
|
||||
|
||||
* Critical fix for a token parsing bug
|
||||
* Removed legacy build system
|
||||
* Improving docs
|
||||
|
||||
**0.2.6** (Saturday, 24th August 2013)
|
||||
|
||||
* Added support for environment vars in config files
|
||||
* Added support for environment vars to set the Phinx Env
|
||||
* Improving docs
|
||||
* Fixed a bug with column names in indexes
|
||||
* Changes for developers in regards to the unit tests
|
||||
|
||||
**0.2.5** (Sunday, 26th May 2013)
|
||||
|
||||
* Added support for Box Phar Archive Packaging
|
||||
* Added support for MYSQL_ATTR driver options
|
||||
* Fixed a bug where foreign keys cannot be removed
|
||||
* Added support for MySQL table collation
|
||||
* Updated Composer dependencies
|
||||
* Removed verbosity options, now relies on Symfony instead
|
||||
* Improved unit tests
|
||||
|
||||
**0.2.4** (Saturday, 20th April 2013)
|
||||
|
||||
* The Rollback command supports the verbosity parameter
|
||||
* The Rollback command has more detailed output
|
||||
* Table::dropForeignKey now returns the table instance
|
||||
|
||||
**0.2.3** (Saturday, 6th April 2013)
|
||||
|
||||
* Fixed a reporting bug when Phinx couldn't connect to a database
|
||||
* Added support for the MySQL 'ON UPDATE' function
|
||||
* Phinx timestamp is now mapped to MySQL timestamp instead of datetime
|
||||
* Fixed a docs typo for the minimum PHP version
|
||||
* Added UTF8 support for migrations
|
||||
* Changed regex to handle migration names differently
|
||||
* Added support for custom MySQL table engines such as MyISAM
|
||||
* Added the change method to the migration template
|
||||
|
||||
**0.2.2** (Sunday, 3rd March 2013)
|
||||
|
||||
* Added a new verbosity parameter to see more output when migrating
|
||||
* Support for PHP config files
|
||||
|
||||
**0.2.1** (Sunday, 3rd March 2013)
|
||||
|
||||
* Broken Release. Do not use!
|
||||
* Unit tests no longer rely on the default phinx.yml file
|
||||
* Running migrate for the first time does not give php warnings
|
||||
* `default_migration_table` is now actually supported
|
||||
* Updated docblocks to 2013.
|
||||
|
||||
**0.2.0** (Sunday, 13th January 2013)
|
||||
|
||||
* First Birthday Release
|
||||
* Added Reversible Migrations
|
||||
* Removed options parameter from AdapterInterface::hasColumn()
|
||||
|
||||
**0.1.7** (Tuesday, 8th January 2013)
|
||||
|
||||
* Improved documentation on the YAML configuration file
|
||||
* Removed options parameter from AdapterInterface::dropIndex()
|
||||
|
||||
**0.1.6** (Sunday, 9th December 2012)
|
||||
|
||||
* Added foreign key support
|
||||
* Removed PEAR support
|
||||
* Support for auto_increment on custom id columns
|
||||
* Bugfix for column default value 0
|
||||
* Documentation improvements
|
||||
|
||||
**0.1.5** (Sunday, 4th November 2012)
|
||||
|
||||
* Added a test command
|
||||
* Added transactions for adapters that support it
|
||||
* Changing the Table API to use pending column methods
|
||||
* Fixed a bug when defining multiple indexes on a table
|
||||
|
||||
**0.1.4** (Sunday, 21st October 2012)
|
||||
|
||||
* Documentation Improvements
|
||||
|
||||
**0.1.3** (Saturday, 20th October 2012)
|
||||
|
||||
* Fixed broken composer support
|
||||
|
||||
**0.1.2** (Saturday, 20th October 2012)
|
||||
|
||||
* Added composer support
|
||||
* Now forces migrations to be in CamelCase format
|
||||
* Now specifies the database name when migrating
|
||||
* Creates the internal log table using its API instead of raw SQL
|
||||
|
||||
**0.1.1** (Wednesday, 13th June 2012)
|
||||
|
||||
* First point release. Ready for limited production use.
|
||||
|
||||
**0.1.0** (Friday, 13th January 2012)
|
||||
|
||||
* Initial public release.
|
||||
66
vendor/topthink/think-migration/phinx/CONTRIBUTING.md
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
# How to contribute to Phinx
|
||||
|
||||
Phinx relies heavily on external contributions in order to make it the best database migration
|
||||
tool possible. Without the support of our 115+ contributors we wouldn't be where we are today!
|
||||
We encourage anyone to submit documentation enhancements and code.
|
||||
|
||||
Issues, feature requests and bugs should be submitted using the Github issue tool:
|
||||
https://github.com/robmorgan/phinx/issues.
|
||||
|
||||
This document briefly outlines the requirements to contribute code to Phinx.
|
||||
|
||||
## Considerations
|
||||
|
||||
Before you submit your pull request take a moment to answer the following questions.
|
||||
|
||||
Answering '**YES**' to all questions will increase the likelihood of your PR being accepted!
|
||||
|
||||
* Have I implemented my feature for as many database adapters as possible?
|
||||
* Does my new feature improve Phinx's performance or keep it consistent?
|
||||
* Does my feature fit within the database migration space?
|
||||
* Is the code entirely my own and free from any commercial licensing?
|
||||
* Am I happy to release my code under the MIT license?
|
||||
* Is my code formatted using the [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md) coding standard?
|
||||
|
||||
**Note:** We accept bug fixes much faster into our development branch than features.
|
||||
|
||||
## Getting Started
|
||||
|
||||
Great, so you want to contribute. Let's get started:
|
||||
|
||||
1. Start by forking Phinx on GitHub: https://github.com/robmorgan/phinx
|
||||
|
||||
1. Clone your repository to a local directory on your development box.
|
||||
|
||||
1. If you do not have Composer set up already, install it:
|
||||
|
||||
```
|
||||
curl -sS https://getcomposer.org/installer | php
|
||||
```
|
||||
|
||||
1. Change to your Phinx clone directory and pull the necessary dependencies:
|
||||
|
||||
```
|
||||
php composer.phar install
|
||||
```
|
||||
|
||||
1. Copy the `phpunit.xml.dist` template to `phpunit.xml` and change the configuration to suit your environment. If you are not using any particular adapter you can disable it in the `phpunit.xml` file.
|
||||
|
||||
1. Run the unit tests locally to ensure they pass:
|
||||
|
||||
```
|
||||
php vendor/bin/phpunit --config phpunit.xml
|
||||
```
|
||||
|
||||
1. Write the code and unit tests for your bug fix or feature.
|
||||
|
||||
1. Add any relevant documentation.
|
||||
|
||||
1. Run the unit tests again and ensure they pass.
|
||||
|
||||
1. Open a pull request on the Github project page. Ensure the code is being merged into the latest development branch (e.g: `0.5.x-dev`) and not `master`.
|
||||
|
||||
## Documentation
|
||||
|
||||
The Phinx documentation is stored in the **docs** directory using the [RestructedText](http://docutils.sourceforge.net/rst.html) format. All documentation merged to `master` is automatically published to the Phinx documentation site available
|
||||
at: http://docs.phinx.org. Keep this in mind when submitting your PR, or ask someone to merge the development branch back down to master.
|
||||
9
vendor/topthink/think-migration/phinx/LICENSE
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
(The MIT license)
|
||||
|
||||
Copyright (c) 2014 Rob Morgan
|
||||
|
||||
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.
|
||||
128
vendor/topthink/think-migration/phinx/README.md
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
# [Phinx](https://phinx.org): Simple PHP Database Migrations
|
||||
|
||||
[](https://travis-ci.org/robmorgan/phinx)
|
||||
[](https://ci.appveyor.com/project/robmorgan/phinx)
|
||||
[](https://scrutinizer-ci.com/g/robmorgan/phinx/)
|
||||
[](https://packagist.org/packages/robmorgan/phinx)
|
||||
[](https://packagist.org/packages/robmorgan/phinx)
|
||||
|
||||
Phinx makes it ridiculously easy to manage the database migrations for your PHP app. In less than 5 minutes you can install Phinx and create your first database migration. Phinx is just about migrations without all the bloat of a database ORM system or framework.
|
||||
|
||||
**Check out http://docs.phinx.org for the comprehensive documentation.**
|
||||
|
||||

|
||||
|
||||
### Features
|
||||
|
||||
* Write database migrations using database agnostic PHP code.
|
||||
* Migrate up and down.
|
||||
* Migrate on deployment.
|
||||
* Seed data after database creation.
|
||||
* Get going in less than 5 minutes.
|
||||
* Stop worrying about the state of your database.
|
||||
* Take advantage of SCM features such as branching.
|
||||
* Integrate with any app.
|
||||
|
||||
### Supported Adapters
|
||||
|
||||
Phinx natively supports the following database adapters:
|
||||
|
||||
* MySQL
|
||||
* PostgreSQL
|
||||
* SQLite
|
||||
* Microsoft SQL Server
|
||||
|
||||
## Install & Run
|
||||
|
||||
### Composer
|
||||
|
||||
The fastest way to install Phinx is to add it to your project using Composer (http://getcomposer.org/).
|
||||
|
||||
1. Install Composer:
|
||||
|
||||
```
|
||||
curl -sS https://getcomposer.org/installer | php
|
||||
```
|
||||
|
||||
1. Require Phinx as a dependency using Composer:
|
||||
|
||||
```
|
||||
php composer.phar require robmorgan/phinx
|
||||
```
|
||||
|
||||
1. Install Phinx:
|
||||
|
||||
```
|
||||
php composer.phar install
|
||||
```
|
||||
|
||||
1. Execute Phinx:
|
||||
|
||||
```
|
||||
php vendor/bin/phinx
|
||||
```
|
||||
|
||||
### As a Phar
|
||||
|
||||
You can also use the Box application to build Phinx as a Phar archive (https://box-project.github.io/box2/).
|
||||
|
||||
1. Clone Phinx from GitHub
|
||||
|
||||
```
|
||||
git clone git://github.com/robmorgan/phinx.git
|
||||
cd phinx
|
||||
```
|
||||
|
||||
1. Install Composer
|
||||
|
||||
```
|
||||
curl -s https://getcomposer.org/installer | php
|
||||
```
|
||||
|
||||
1. Install the Phinx dependencies
|
||||
|
||||
```
|
||||
php composer.phar install
|
||||
```
|
||||
|
||||
1. Install Box:
|
||||
|
||||
```
|
||||
curl -LSs https://box-project.github.io/box2/installer.php | php
|
||||
```
|
||||
|
||||
1. Create a Phar archive
|
||||
|
||||
```
|
||||
php box.phar build
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
Check out http://docs.phinx.org for the comprehensive documentation.
|
||||
|
||||
## Contributing
|
||||
|
||||
Please read the [CONTRIBUTING](CONTRIBUTING.md) document.
|
||||
|
||||
## News & Updates
|
||||
|
||||
Follow Rob (@\_rjm\_) on Twitter to stay up to date (http://twitter.com/_rjm_)
|
||||
|
||||
## Misc
|
||||
|
||||
### Version History
|
||||
|
||||
Please read the [CHANGELOG](CHANGELOG.md) document.
|
||||
|
||||
### License
|
||||
|
||||
(The MIT license)
|
||||
|
||||
Copyright (c) 2016 Rob Morgan
|
||||
|
||||
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.
|
||||
181
vendor/topthink/think-migration/phinx/src/Phinx/Db/Adapter/AdapterFactory.php
vendored
Normal file
@@ -0,0 +1,181 @@
|
||||
<?php
|
||||
/**
|
||||
* Phinx
|
||||
*
|
||||
* (The MIT license)
|
||||
* Copyright (c) 2015 Rob Morgan
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @package Phinx
|
||||
* @subpackage Phinx\Migration
|
||||
*/
|
||||
namespace Phinx\Db\Adapter;
|
||||
|
||||
/**
|
||||
* Adapter factory and registry.
|
||||
*
|
||||
* Used for registering adapters and creating instances of adapters.
|
||||
*
|
||||
* @author Woody Gilk <woody.gilk@gmail.com>
|
||||
*/
|
||||
class AdapterFactory
|
||||
{
|
||||
/**
|
||||
* @var AdapterFactory
|
||||
*/
|
||||
protected static $instance;
|
||||
|
||||
/**
|
||||
* Get the factory singleton instance.
|
||||
*
|
||||
* @return AdapterFactory
|
||||
*/
|
||||
public static function instance()
|
||||
{
|
||||
if (!static::$instance) {
|
||||
static::$instance = new static();
|
||||
}
|
||||
return static::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class map of database adapters, indexed by PDO::ATTR_DRIVER_NAME.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $adapters = array(
|
||||
'mysql' => 'Phinx\Db\Adapter\MysqlAdapter',
|
||||
'pgsql' => 'Phinx\Db\Adapter\PostgresAdapter',
|
||||
'sqlite' => 'Phinx\Db\Adapter\SQLiteAdapter',
|
||||
'sqlsrv' => 'Phinx\Db\Adapter\SqlServerAdapter',
|
||||
);
|
||||
|
||||
/**
|
||||
* Class map of adapters wrappers, indexed by name.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $wrappers = array(
|
||||
'prefix' => 'Phinx\Db\Adapter\TablePrefixAdapter',
|
||||
'proxy' => 'Phinx\Db\Adapter\ProxyAdapter',
|
||||
);
|
||||
|
||||
/**
|
||||
* Add or replace an adapter with a fully qualified class name.
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
* @param string $name
|
||||
* @param string $class
|
||||
* @return $this
|
||||
*/
|
||||
public function registerAdapter($name, $class)
|
||||
{
|
||||
if (!is_subclass_of($class, 'Phinx\Db\Adapter\AdapterInterface')) {
|
||||
throw new \RuntimeException(sprintf(
|
||||
'Adapter class "%s" must implement Phinx\\Db\\Adapter\\AdapterInterface',
|
||||
$class
|
||||
));
|
||||
}
|
||||
$this->adapters[$name] = $class;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an adapter class by name.
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
protected function getClass($name)
|
||||
{
|
||||
if (empty($this->adapters[$name])) {
|
||||
throw new \RuntimeException(sprintf(
|
||||
'Adapter "%s" has not been registered',
|
||||
$name
|
||||
));
|
||||
}
|
||||
return $this->adapters[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an adapter instance by name.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $options
|
||||
* @return AdapterInterface
|
||||
*/
|
||||
public function getAdapter($name, array $options)
|
||||
{
|
||||
$class = $this->getClass($name);
|
||||
return new $class($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add or replace a wrapper with a fully qualified class name.
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
* @param string $name
|
||||
* @param string $class
|
||||
* @return $this
|
||||
*/
|
||||
public function registerWrapper($name, $class)
|
||||
{
|
||||
if (!is_subclass_of($class, 'Phinx\Db\Adapter\WrapperInterface')) {
|
||||
throw new \RuntimeException(sprintf(
|
||||
'Wrapper class "%s" must be implement Phinx\\Db\\Adapter\\WrapperInterface',
|
||||
$class
|
||||
));
|
||||
}
|
||||
$this->wrappers[$name] = $class;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a wrapper class by name.
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
protected function getWrapperClass($name)
|
||||
{
|
||||
if (empty($this->wrappers[$name])) {
|
||||
throw new \RuntimeException(sprintf(
|
||||
'Wrapper "%s" has not been registered',
|
||||
$name
|
||||
));
|
||||
}
|
||||
return $this->wrappers[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a wrapper instance by name.
|
||||
*
|
||||
* @param string $name
|
||||
* @param AdapterInterface $adapter
|
||||
* @return AdapterInterface
|
||||
*/
|
||||
public function getWrapper($name, AdapterInterface $adapter)
|
||||
{
|
||||
$class = $this->getWrapperClass($name);
|
||||
return new $class($adapter);
|
||||
}
|
||||
}
|
||||
510
vendor/topthink/think-migration/phinx/src/Phinx/Db/Adapter/AdapterInterface.php
vendored
Normal file
@@ -0,0 +1,510 @@
|
||||
<?php
|
||||
/**
|
||||
* Phinx
|
||||
*
|
||||
* (The MIT license)
|
||||
* Copyright (c) 2015 Rob Morgan
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @package Phinx
|
||||
* @subpackage Phinx\Db\Adapter
|
||||
*/
|
||||
namespace Phinx\Db\Adapter;
|
||||
|
||||
use think\console\Input as InputInterface;
|
||||
use think\console\Output as OutputInterface;
|
||||
use Phinx\Db\Table;
|
||||
use Phinx\Db\Table\Column;
|
||||
use Phinx\Db\Table\Index;
|
||||
use Phinx\Db\Table\ForeignKey;
|
||||
use Phinx\Migration\MigrationInterface;
|
||||
|
||||
/**
|
||||
* Adapter Interface.
|
||||
*
|
||||
* @author Rob Morgan <robbym@gmail.com>
|
||||
*/
|
||||
interface AdapterInterface
|
||||
{
|
||||
const PHINX_TYPE_STRING = 'string';
|
||||
const PHINX_TYPE_CHAR = 'char';
|
||||
const PHINX_TYPE_TEXT = 'text';
|
||||
const PHINX_TYPE_INTEGER = 'integer';
|
||||
const PHINX_TYPE_BIG_INTEGER = 'biginteger';
|
||||
const PHINX_TYPE_FLOAT = 'float';
|
||||
const PHINX_TYPE_DECIMAL = 'decimal';
|
||||
const PHINX_TYPE_DATETIME = 'datetime';
|
||||
const PHINX_TYPE_TIMESTAMP = 'timestamp';
|
||||
const PHINX_TYPE_TIME = 'time';
|
||||
const PHINX_TYPE_DATE = 'date';
|
||||
const PHINX_TYPE_BINARY = 'binary';
|
||||
const PHINX_TYPE_VARBINARY = 'varbinary';
|
||||
const PHINX_TYPE_BLOB = 'blob';
|
||||
const PHINX_TYPE_BOOLEAN = 'boolean';
|
||||
const PHINX_TYPE_JSON = 'json';
|
||||
const PHINX_TYPE_JSONB = 'jsonb';
|
||||
const PHINX_TYPE_UUID = 'uuid';
|
||||
const PHINX_TYPE_FILESTREAM = 'filestream';
|
||||
|
||||
// Geospatial database types
|
||||
const PHINX_TYPE_GEOMETRY = 'geometry';
|
||||
const PHINX_TYPE_POINT = 'point';
|
||||
const PHINX_TYPE_LINESTRING = 'linestring';
|
||||
const PHINX_TYPE_POLYGON = 'polygon';
|
||||
|
||||
// only for mysql so far
|
||||
const PHINX_TYPE_ENUM = 'enum';
|
||||
const PHINX_TYPE_SET = 'set';
|
||||
|
||||
/**
|
||||
* Get all migrated version numbers.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getVersions();
|
||||
|
||||
/**
|
||||
* Get all migration log entries, indexed by version number.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getVersionLog();
|
||||
|
||||
/**
|
||||
* Set adapter configuration options.
|
||||
*
|
||||
* @param array $options
|
||||
* @return AdapterInterface
|
||||
*/
|
||||
public function setOptions(array $options);
|
||||
|
||||
/**
|
||||
* Get all adapter options.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getOptions();
|
||||
|
||||
/**
|
||||
* Check if an option has been set.
|
||||
*
|
||||
* @param string $name
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasOption($name);
|
||||
|
||||
/**
|
||||
* Get a single adapter option, or null if the option does not exist.
|
||||
*
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function getOption($name);
|
||||
|
||||
/**
|
||||
* Sets the console input.
|
||||
*
|
||||
* @param InputInterface $input Input
|
||||
* @return AdapterInterface
|
||||
*/
|
||||
public function setInput(InputInterface $input);
|
||||
|
||||
/**
|
||||
* Gets the console input.
|
||||
*
|
||||
* @return InputInterface
|
||||
*/
|
||||
public function getInput();
|
||||
|
||||
/**
|
||||
* Sets the console output.
|
||||
*
|
||||
* @param OutputInterface $output Output
|
||||
* @return AdapterInterface
|
||||
*/
|
||||
public function setOutput(OutputInterface $output);
|
||||
|
||||
/**
|
||||
* Gets the console output.
|
||||
*
|
||||
* @return OutputInterface
|
||||
*/
|
||||
public function getOutput();
|
||||
|
||||
/**
|
||||
* Records a migration being run.
|
||||
*
|
||||
* @param MigrationInterface $migration Migration
|
||||
* @param string $direction Direction
|
||||
* @param int $startTime Start Time
|
||||
* @param int $endTime End Time
|
||||
* @return AdapterInterface
|
||||
*/
|
||||
public function migrated(MigrationInterface $migration, $direction, $startTime, $endTime);
|
||||
|
||||
/**
|
||||
* Toggle a migration breakpoint.
|
||||
*
|
||||
* @param MigrationInterface $migration
|
||||
*
|
||||
* @return AdapterInterface
|
||||
*/
|
||||
public function toggleBreakpoint(MigrationInterface $migration);
|
||||
|
||||
/**
|
||||
* Reset all migration breakpoints.
|
||||
*
|
||||
* @return int The number of breakpoints reset
|
||||
*/
|
||||
public function resetAllBreakpoints();
|
||||
|
||||
/**
|
||||
* Does the schema table exist?
|
||||
*
|
||||
* @deprecated use hasTable instead.
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasSchemaTable();
|
||||
|
||||
/**
|
||||
* Creates the schema table.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function createSchemaTable();
|
||||
|
||||
/**
|
||||
* Returns the adapter type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAdapterType();
|
||||
|
||||
/**
|
||||
* Initializes the database connection.
|
||||
*
|
||||
* @throws \RuntimeException When the requested database driver is not installed.
|
||||
* @return void
|
||||
*/
|
||||
public function connect();
|
||||
|
||||
/**
|
||||
* Closes the database connection.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function disconnect();
|
||||
|
||||
/**
|
||||
* Does the adapter support transactions?
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasTransactions();
|
||||
|
||||
/**
|
||||
* Begin a transaction.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function beginTransaction();
|
||||
|
||||
/**
|
||||
* Commit a transaction.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function commitTransaction();
|
||||
|
||||
/**
|
||||
* Rollback a transaction.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function rollbackTransaction();
|
||||
|
||||
/**
|
||||
* Executes a SQL statement and returns the number of affected rows.
|
||||
*
|
||||
* @param string $sql SQL
|
||||
* @return int
|
||||
*/
|
||||
public function execute($sql);
|
||||
|
||||
/**
|
||||
* Executes a SQL statement and returns the result as an array.
|
||||
*
|
||||
* @param string $sql SQL
|
||||
* @return array
|
||||
*/
|
||||
public function query($sql);
|
||||
|
||||
/**
|
||||
* Executes a query and returns only one row as an array.
|
||||
*
|
||||
* @param string $sql SQL
|
||||
* @return array
|
||||
*/
|
||||
public function fetchRow($sql);
|
||||
|
||||
/**
|
||||
* Executes a query and returns an array of rows.
|
||||
*
|
||||
* @param string $sql SQL
|
||||
* @return array
|
||||
*/
|
||||
public function fetchAll($sql);
|
||||
|
||||
/**
|
||||
* Inserts data into a table.
|
||||
*
|
||||
* @param Table $table where to insert data
|
||||
* @param array $row
|
||||
* @return void
|
||||
*/
|
||||
public function insert(Table $table, $row);
|
||||
|
||||
/**
|
||||
* Quotes a table name for use in a query.
|
||||
*
|
||||
* @param string $tableName Table Name
|
||||
* @return string
|
||||
*/
|
||||
public function quoteTableName($tableName);
|
||||
|
||||
/**
|
||||
* Quotes a column name for use in a query.
|
||||
*
|
||||
* @param string $columnName Table Name
|
||||
* @return string
|
||||
*/
|
||||
public function quoteColumnName($columnName);
|
||||
|
||||
/**
|
||||
* Checks to see if a table exists.
|
||||
*
|
||||
* @param string $tableName Table Name
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasTable($tableName);
|
||||
|
||||
/**
|
||||
* Creates the specified database table.
|
||||
*
|
||||
* @param Table $table Table
|
||||
* @return void
|
||||
*/
|
||||
public function createTable(Table $table);
|
||||
|
||||
/**
|
||||
* Renames the specified database table.
|
||||
*
|
||||
* @param string $tableName Table Name
|
||||
* @param string $newName New Name
|
||||
* @return void
|
||||
*/
|
||||
public function renameTable($tableName, $newName);
|
||||
|
||||
/**
|
||||
* Drops the specified database table.
|
||||
*
|
||||
* @param string $tableName Table Name
|
||||
* @return void
|
||||
*/
|
||||
public function dropTable($tableName);
|
||||
|
||||
/**
|
||||
* Returns table columns
|
||||
*
|
||||
* @param string $tableName Table Name
|
||||
* @return Column[]
|
||||
*/
|
||||
public function getColumns($tableName);
|
||||
|
||||
/**
|
||||
* Checks to see if a column exists.
|
||||
*
|
||||
* @param string $tableName Table Name
|
||||
* @param string $columnName Column Name
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasColumn($tableName, $columnName);
|
||||
|
||||
/**
|
||||
* Adds the specified column to a database table.
|
||||
*
|
||||
* @param Table $table Table
|
||||
* @param Column $column Column
|
||||
* @return void
|
||||
*/
|
||||
public function addColumn(Table $table, Column $column);
|
||||
|
||||
/**
|
||||
* Renames the specified column.
|
||||
*
|
||||
* @param string $tableName Table Name
|
||||
* @param string $columnName Column Name
|
||||
* @param string $newColumnName New Column Name
|
||||
* @return void
|
||||
*/
|
||||
public function renameColumn($tableName, $columnName, $newColumnName);
|
||||
|
||||
/**
|
||||
* Change a table column type.
|
||||
*
|
||||
* @param string $tableName Table Name
|
||||
* @param string $columnName Column Name
|
||||
* @param Column $newColumn New Column
|
||||
* @return Table
|
||||
*/
|
||||
public function changeColumn($tableName, $columnName, Column $newColumn);
|
||||
|
||||
/**
|
||||
* Drops the specified column.
|
||||
*
|
||||
* @param string $tableName Table Name
|
||||
* @param string $columnName Column Name
|
||||
* @return void
|
||||
*/
|
||||
public function dropColumn($tableName, $columnName);
|
||||
|
||||
/**
|
||||
* Checks to see if an index exists.
|
||||
*
|
||||
* @param string $tableName Table Name
|
||||
* @param mixed $columns Column(s)
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasIndex($tableName, $columns);
|
||||
|
||||
/**
|
||||
* Checks to see if an index specified by name exists.
|
||||
*
|
||||
* @param string $tableName Table Name
|
||||
* @param string $indexName
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasIndexByName($tableName, $indexName);
|
||||
|
||||
/**
|
||||
* Adds the specified index to a database table.
|
||||
*
|
||||
* @param Table $table Table
|
||||
* @param Index $index Index
|
||||
* @return void
|
||||
*/
|
||||
public function addIndex(Table $table, Index $index);
|
||||
|
||||
/**
|
||||
* Drops the specified index from a database table.
|
||||
*
|
||||
* @param string $tableName
|
||||
* @param mixed $columns Column(s)
|
||||
* @return void
|
||||
*/
|
||||
public function dropIndex($tableName, $columns);
|
||||
|
||||
/**
|
||||
* Drops the index specified by name from a database table.
|
||||
*
|
||||
* @param string $tableName
|
||||
* @param string $indexName
|
||||
* @return void
|
||||
*/
|
||||
public function dropIndexByName($tableName, $indexName);
|
||||
|
||||
/**
|
||||
* Checks to see if a foreign key exists.
|
||||
*
|
||||
* @param string $tableName
|
||||
* @param string[] $columns Column(s)
|
||||
* @param string $constraint Constraint name
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasForeignKey($tableName, $columns, $constraint = null);
|
||||
|
||||
/**
|
||||
* Adds the specified foreign key to a database table.
|
||||
*
|
||||
* @param Table $table
|
||||
* @param ForeignKey $foreignKey
|
||||
* @return void
|
||||
*/
|
||||
public function addForeignKey(Table $table, ForeignKey $foreignKey);
|
||||
|
||||
/**
|
||||
* Drops the specified foreign key from a database table.
|
||||
*
|
||||
* @param string $tableName
|
||||
* @param string[] $columns Column(s)
|
||||
* @param string $constraint Constraint name
|
||||
* @return void
|
||||
*/
|
||||
public function dropForeignKey($tableName, $columns, $constraint = null);
|
||||
|
||||
/**
|
||||
* Returns an array of the supported Phinx column types.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getColumnTypes();
|
||||
|
||||
/**
|
||||
* Checks that the given column is of a supported type.
|
||||
*
|
||||
* @param Column $column
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValidColumnType(Column $column);
|
||||
|
||||
/**
|
||||
* Converts the Phinx logical type to the adapter's SQL type.
|
||||
*
|
||||
* @param string $type
|
||||
* @param integer $limit
|
||||
* @return string
|
||||
*/
|
||||
public function getSqlType($type, $limit = null);
|
||||
|
||||
/**
|
||||
* Creates a new database.
|
||||
*
|
||||
* @param string $name Database Name
|
||||
* @param array $options Options
|
||||
* @return void
|
||||
*/
|
||||
public function createDatabase($name, $options = array());
|
||||
|
||||
/**
|
||||
* Checks to see if a database exists.
|
||||
*
|
||||
* @param string $name Database Name
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasDatabase($name);
|
||||
|
||||
/**
|
||||
* Drops the specified database.
|
||||
*
|
||||
* @param string $name Database Name
|
||||
* @return void
|
||||
*/
|
||||
public function dropDatabase($name);
|
||||
}
|
||||
507
vendor/topthink/think-migration/phinx/src/Phinx/Db/Adapter/AdapterWrapper.php
vendored
Normal file
@@ -0,0 +1,507 @@
|
||||
<?php
|
||||
/**
|
||||
* Phinx
|
||||
*
|
||||
* (The MIT license)
|
||||
* Copyright (c) 2015 Rob Morgan
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @package Phinx
|
||||
* @subpackage Phinx\Db\Adapter
|
||||
*/
|
||||
namespace Phinx\Db\Adapter;
|
||||
|
||||
use Phinx\Db\Table;
|
||||
use Phinx\Db\Table\Column;
|
||||
use Phinx\Db\Table\Index;
|
||||
use Phinx\Db\Table\ForeignKey;
|
||||
use Phinx\Migration\MigrationInterface;
|
||||
use think\console\Input as InputInterface;
|
||||
use think\console\Output as OutputInterface;
|
||||
|
||||
/**
|
||||
* Adapter Wrapper.
|
||||
*
|
||||
* Proxy commands through to another adapter, allowing modification of
|
||||
* parameters during calls.
|
||||
*
|
||||
* @author Woody Gilk <woody.gilk@gmail.com>
|
||||
*/
|
||||
abstract class AdapterWrapper implements AdapterInterface, WrapperInterface
|
||||
{
|
||||
/**
|
||||
* @var AdapterInterface
|
||||
*/
|
||||
protected $adapter;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(AdapterInterface $adapter)
|
||||
{
|
||||
$this->setAdapter($adapter);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setAdapter(AdapterInterface $adapter)
|
||||
{
|
||||
$this->adapter = $adapter;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAdapter()
|
||||
{
|
||||
return $this->adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setOptions(array $options)
|
||||
{
|
||||
$this->adapter->setOptions($options);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getOptions()
|
||||
{
|
||||
return $this->adapter->getOptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasOption($name)
|
||||
{
|
||||
return $this->adapter->hasOption($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getOption($name)
|
||||
{
|
||||
return $this->adapter->getOption($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setInput(InputInterface $input)
|
||||
{
|
||||
$this->adapter->setInput($input);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getInput()
|
||||
{
|
||||
return $this->adapter->getInput();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setOutput(OutputInterface $output)
|
||||
{
|
||||
$this->adapter->setOutput($output);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getOutput()
|
||||
{
|
||||
return $this->adapter->getOutput();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function connect()
|
||||
{
|
||||
return $this->getAdapter()->connect();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function disconnect()
|
||||
{
|
||||
return $this->getAdapter()->disconnect();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function execute($sql)
|
||||
{
|
||||
return $this->getAdapter()->execute($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query($sql)
|
||||
{
|
||||
return $this->getAdapter()->query($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function insert(Table $table, $row)
|
||||
{
|
||||
return $this->getAdapter()->insert($table, $row);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchRow($sql)
|
||||
{
|
||||
return $this->getAdapter()->fetchRow($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchAll($sql)
|
||||
{
|
||||
return $this->getAdapter()->fetchAll($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getVersions()
|
||||
{
|
||||
return $this->getAdapter()->getVersions();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getVersionLog()
|
||||
{
|
||||
return $this->getAdapter()->getVersionLog();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function migrated(MigrationInterface $migration, $direction, $startTime, $endTime)
|
||||
{
|
||||
$this->getAdapter()->migrated($migration, $direction, $startTime, $endTime);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function toggleBreakpoint(MigrationInterface $migration)
|
||||
{
|
||||
$this->getAdapter()->toggleBreakpoint($migration);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function resetAllBreakpoints()
|
||||
{
|
||||
return $this->getAdapter()->resetAllBreakpoints();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasSchemaTable()
|
||||
{
|
||||
return $this->getAdapter()->hasSchemaTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function createSchemaTable()
|
||||
{
|
||||
return $this->getAdapter()->createSchemaTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getColumnTypes()
|
||||
{
|
||||
return $this->getAdapter()->getColumnTypes();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isValidColumnType(Column $column)
|
||||
{
|
||||
return $this->getAdapter()->isValidColumnType($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasTransactions()
|
||||
{
|
||||
return $this->getAdapter()->hasTransactions();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function beginTransaction()
|
||||
{
|
||||
return $this->getAdapter()->beginTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function commitTransaction()
|
||||
{
|
||||
return $this->getAdapter()->commitTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function rollbackTransaction()
|
||||
{
|
||||
return $this->getAdapter()->rollbackTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function quoteTableName($tableName)
|
||||
{
|
||||
return $this->getAdapter()->quoteTableName($tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function quoteColumnName($columnName)
|
||||
{
|
||||
return $this->getAdapter()->quoteColumnName($columnName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasTable($tableName)
|
||||
{
|
||||
return $this->getAdapter()->hasTable($tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function createTable(Table $table)
|
||||
{
|
||||
return $this->getAdapter()->createTable($table);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function renameTable($tableName, $newTableName)
|
||||
{
|
||||
return $this->getAdapter()->renameTable($tableName, $newTableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dropTable($tableName)
|
||||
{
|
||||
return $this->getAdapter()->dropTable($tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getColumns($tableName)
|
||||
{
|
||||
return $this->getAdapter()->getColumns($tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasColumn($tableName, $columnName)
|
||||
{
|
||||
return $this->getAdapter()->hasColumn($tableName, $columnName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addColumn(Table $table, Column $column)
|
||||
{
|
||||
return $this->getAdapter()->addColumn($table, $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function renameColumn($tableName, $columnName, $newColumnName)
|
||||
{
|
||||
return $this->getAdapter()->renameColumn($tableName, $columnName, $newColumnName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function changeColumn($tableName, $columnName, Column $newColumn)
|
||||
{
|
||||
return $this->getAdapter()->changeColumn($tableName, $columnName, $newColumn);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dropColumn($tableName, $columnName)
|
||||
{
|
||||
return $this->getAdapter()->dropColumn($tableName, $columnName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasIndex($tableName, $columns)
|
||||
{
|
||||
return $this->getAdapter()->hasIndex($tableName, $columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasIndexByName($tableName, $indexName)
|
||||
{
|
||||
return $this->getAdapter()->hasIndexByName($tableName, $indexName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addIndex(Table $table, Index $index)
|
||||
{
|
||||
return $this->getAdapter()->addIndex($table, $index);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dropIndex($tableName, $columns, $options = array())
|
||||
{
|
||||
return $this->getAdapter()->dropIndex($tableName, $columns, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dropIndexByName($tableName, $indexName)
|
||||
{
|
||||
return $this->getAdapter()->dropIndexByName($tableName, $indexName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasForeignKey($tableName, $columns, $constraint = null)
|
||||
{
|
||||
return $this->getAdapter()->hasForeignKey($tableName, $columns, $constraint);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addForeignKey(Table $table, ForeignKey $foreignKey)
|
||||
{
|
||||
return $this->getAdapter()->addForeignKey($table, $foreignKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dropForeignKey($tableName, $columns, $constraint = null)
|
||||
{
|
||||
return $this->getAdapter()->dropForeignKey($tableName, $columns, $constraint);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSqlType($type, $limit = null)
|
||||
{
|
||||
return $this->getAdapter()->getSqlType($type, $limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function createDatabase($name, $options = array())
|
||||
{
|
||||
return $this->getAdapter()->createDatabase($name, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasDatabase($name)
|
||||
{
|
||||
return $this->getAdapter()->hasDatabase($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dropDatabase($name)
|
||||
{
|
||||
return $this->getAdapter()->dropDatabase($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function castToBool($value)
|
||||
{
|
||||
return $this->getAdapter()->castToBool($value);
|
||||
}
|
||||
}
|
||||
1148
vendor/topthink/think-migration/phinx/src/Phinx/Db/Adapter/MysqlAdapter.php
vendored
Normal file
587
vendor/topthink/think-migration/phinx/src/Phinx/Db/Adapter/PdoAdapter.php
vendored
Normal file
@@ -0,0 +1,587 @@
|
||||
<?php
|
||||
/**
|
||||
* Phinx
|
||||
*
|
||||
* (The MIT license)
|
||||
* Copyright (c) 2015 Rob Morgan
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @package Phinx
|
||||
* @subpackage Phinx\Db\Adapter
|
||||
*/
|
||||
namespace Phinx\Db\Adapter;
|
||||
|
||||
use think\console\Input as InputInterface;
|
||||
use think\console\Output as OutputInterface;
|
||||
use Phinx\Db\Table;
|
||||
use Phinx\Db\Table\Column;
|
||||
use Phinx\Migration\MigrationInterface;
|
||||
|
||||
/**
|
||||
* Phinx PDO Adapter.
|
||||
*
|
||||
* @author Rob Morgan <robbym@gmail.com>
|
||||
*/
|
||||
abstract class PdoAdapter implements AdapterInterface
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $options = array();
|
||||
|
||||
/**
|
||||
* @var InputInterface
|
||||
*/
|
||||
protected $input;
|
||||
|
||||
/**
|
||||
* @var OutputInterface
|
||||
*/
|
||||
protected $output;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $schemaTableName = 'migrations';
|
||||
|
||||
/**
|
||||
* @var \PDO
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
protected $commandStartTime;
|
||||
|
||||
/**
|
||||
* Class Constructor.
|
||||
*
|
||||
* @param array $options Options
|
||||
* @param InputInterface $input Input Interface
|
||||
* @param OutputInterface $output Output Interface
|
||||
*/
|
||||
public function __construct(array $options, InputInterface $input = null, OutputInterface $output = null)
|
||||
{
|
||||
$this->setOptions($options);
|
||||
if (null !== $input) {
|
||||
$this->setInput($input);
|
||||
}
|
||||
if (null !== $output) {
|
||||
$this->setOutput($output);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setOptions(array $options)
|
||||
{
|
||||
$this->options = $options;
|
||||
|
||||
if (isset($options['default_migration_table'])) {
|
||||
$this->setSchemaTableName($options['default_migration_table']);
|
||||
}
|
||||
|
||||
if (isset($options['connection'])) {
|
||||
$this->setConnection($options['connection']);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getOptions()
|
||||
{
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasOption($name)
|
||||
{
|
||||
return isset($this->options[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getOption($name)
|
||||
{
|
||||
if (!$this->hasOption($name)) {
|
||||
return;
|
||||
}
|
||||
return $this->options[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setInput(InputInterface $input)
|
||||
{
|
||||
$this->input = $input;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getInput()
|
||||
{
|
||||
return $this->input;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setOutput(OutputInterface $output)
|
||||
{
|
||||
$this->output = $output;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getOutput()
|
||||
{
|
||||
if (null === $this->output) {
|
||||
$output = new OutputInterface('nothing');
|
||||
$this->setOutput($output);
|
||||
}
|
||||
return $this->output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the schema table name.
|
||||
*
|
||||
* @param string $schemaTableName Schema Table Name
|
||||
* @return PdoAdapter
|
||||
*/
|
||||
public function setSchemaTableName($schemaTableName)
|
||||
{
|
||||
$this->schemaTableName = $schemaTableName;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the schema table name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSchemaTableName()
|
||||
{
|
||||
return $this->schemaTableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the database connection.
|
||||
*
|
||||
* @param \PDO $connection Connection
|
||||
* @return AdapterInterface
|
||||
*/
|
||||
public function setConnection(\PDO $connection)
|
||||
{
|
||||
$this->connection = $connection;
|
||||
|
||||
// Create the schema table if it doesn't already exist
|
||||
if (!$this->hasSchemaTable()) {
|
||||
$this->createSchemaTable();
|
||||
} else {
|
||||
$table = new Table($this->getSchemaTableName(), array(), $this);
|
||||
if (!$table->hasColumn('migration_name')) {
|
||||
$table
|
||||
->addColumn('migration_name', 'string',
|
||||
array('limit' => 100, 'after' => 'version', 'default' => null, 'null' => true)
|
||||
)
|
||||
->save();
|
||||
}
|
||||
if (!$table->hasColumn('breakpoint')) {
|
||||
$table
|
||||
->addColumn('breakpoint', 'boolean', array('default' => false))
|
||||
->save();
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the database connection
|
||||
*
|
||||
* @return \PDO
|
||||
*/
|
||||
public function getConnection()
|
||||
{
|
||||
if (null === $this->connection) {
|
||||
$this->connect();
|
||||
}
|
||||
return $this->connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the command start time
|
||||
*
|
||||
* @param int $time
|
||||
* @return AdapterInterface
|
||||
*/
|
||||
public function setCommandStartTime($time)
|
||||
{
|
||||
$this->commandStartTime = $time;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the command start time
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getCommandStartTime()
|
||||
{
|
||||
return $this->commandStartTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start timing a command.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function startCommandTimer()
|
||||
{
|
||||
$this->setCommandStartTime(microtime(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop timing the current command and write the elapsed time to the
|
||||
* output.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function endCommandTimer()
|
||||
{
|
||||
$end = microtime(true);
|
||||
if (OutputInterface::VERBOSITY_VERBOSE <= $this->getOutput()->getVerbosity()) {
|
||||
$this->getOutput()->writeln(' -> ' . sprintf('%.4fs', $end - $this->getCommandStartTime()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a Phinx command to the output.
|
||||
*
|
||||
* @param string $command Command Name
|
||||
* @param array $args Command Args
|
||||
* @return void
|
||||
*/
|
||||
public function writeCommand($command, $args = array())
|
||||
{
|
||||
if (OutputInterface::VERBOSITY_VERBOSE <= $this->getOutput()->getVerbosity()) {
|
||||
if (count($args)) {
|
||||
$outArr = array();
|
||||
foreach ($args as $arg) {
|
||||
if (is_array($arg)) {
|
||||
$arg = array_map(function ($value) {
|
||||
return '\'' . $value . '\'';
|
||||
}, $arg);
|
||||
$outArr[] = '[' . implode(', ', $arg) . ']';
|
||||
continue;
|
||||
}
|
||||
|
||||
$outArr[] = '\'' . $arg . '\'';
|
||||
}
|
||||
$this->getOutput()->writeln(' -- ' . $command . '(' . implode(', ', $outArr) . ')');
|
||||
return;
|
||||
}
|
||||
$this->getOutput()->writeln(' -- ' . $command);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function connect()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function disconnect()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function execute($sql)
|
||||
{
|
||||
return $this->getConnection()->exec($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query($sql)
|
||||
{
|
||||
return $this->getConnection()->query($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchRow($sql)
|
||||
{
|
||||
$result = $this->query($sql);
|
||||
return $result->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchAll($sql)
|
||||
{
|
||||
$rows = array();
|
||||
$result = $this->query($sql);
|
||||
while ($row = $result->fetch()) {
|
||||
$rows[] = $row;
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function insert(Table $table, $row)
|
||||
{
|
||||
$this->startCommandTimer();
|
||||
$this->writeCommand('insert', array($table->getName()));
|
||||
|
||||
$sql = sprintf(
|
||||
"INSERT INTO %s ",
|
||||
$this->quoteTableName($table->getName())
|
||||
);
|
||||
|
||||
$columns = array_keys($row);
|
||||
$sql .= "(". implode(', ', array_map(array($this, 'quoteColumnName'), $columns)) . ")";
|
||||
$sql .= " VALUES (" . implode(', ', array_fill(0, count($columns), '?')) . ")";
|
||||
|
||||
$stmt = $this->getConnection()->prepare($sql);
|
||||
$stmt->execute(array_values($row));
|
||||
$this->endCommandTimer();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getVersions()
|
||||
{
|
||||
$rows = $this->getVersionLog();
|
||||
|
||||
return array_keys($rows);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getVersionLog()
|
||||
{
|
||||
$result = array();
|
||||
$rows = $this->fetchAll(sprintf('SELECT * FROM %s ORDER BY version ASC', $this->getSchemaTableName()));
|
||||
foreach ($rows as $version) {
|
||||
$result[$version['version']] = $version;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function migrated(MigrationInterface $migration, $direction, $startTime, $endTime)
|
||||
{
|
||||
if (strcasecmp($direction, MigrationInterface::UP) === 0) {
|
||||
// up
|
||||
$sql = sprintf(
|
||||
"INSERT INTO %s (%s, %s, %s, %s, %s) VALUES ('%s', '%s', '%s', '%s', %s);",
|
||||
$this->getSchemaTableName(),
|
||||
$this->quoteColumnName('version'),
|
||||
$this->quoteColumnName('migration_name'),
|
||||
$this->quoteColumnName('start_time'),
|
||||
$this->quoteColumnName('end_time'),
|
||||
$this->quoteColumnName('breakpoint'),
|
||||
$migration->getVersion(),
|
||||
substr($migration->getName(), 0, 100),
|
||||
$startTime,
|
||||
$endTime,
|
||||
$this->castToBool(false)
|
||||
);
|
||||
|
||||
$this->query($sql);
|
||||
} else {
|
||||
// down
|
||||
$sql = sprintf(
|
||||
"DELETE FROM %s WHERE %s = '%s'",
|
||||
$this->getSchemaTableName(),
|
||||
$this->quoteColumnName('version'),
|
||||
$migration->getVersion()
|
||||
);
|
||||
|
||||
$this->query($sql);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function toggleBreakpoint(MigrationInterface $migration)
|
||||
{
|
||||
$this->query(
|
||||
sprintf(
|
||||
'UPDATE %1$s SET %2$s = CASE %2$s WHEN %3$s THEN %4$s ELSE %3$s END WHERE %5$s = \'%6$s\';',
|
||||
$this->getSchemaTableName(),
|
||||
$this->quoteColumnName('breakpoint'),
|
||||
$this->castToBool(true),
|
||||
$this->castToBool(false),
|
||||
$this->quoteColumnName('version'),
|
||||
$migration->getVersion()
|
||||
)
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function resetAllBreakpoints()
|
||||
{
|
||||
return $this->execute(
|
||||
sprintf(
|
||||
'UPDATE %1$s SET %2$s = %3$s WHERE %2$s <> %3$s;',
|
||||
$this->getSchemaTableName(),
|
||||
$this->quoteColumnName('breakpoint'),
|
||||
$this->castToBool(false)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasSchemaTable()
|
||||
{
|
||||
return $this->hasTable($this->getSchemaTableName());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function createSchemaTable()
|
||||
{
|
||||
try {
|
||||
$options = array(
|
||||
'id' => false,
|
||||
'primary_key' => 'version'
|
||||
);
|
||||
|
||||
$table = new Table($this->getSchemaTableName(), $options, $this);
|
||||
|
||||
if ($this->getConnection()->getAttribute(\PDO::ATTR_DRIVER_NAME) === 'mysql'
|
||||
&& version_compare($this->getConnection()->getAttribute(\PDO::ATTR_SERVER_VERSION), '5.6.0', '>=')) {
|
||||
$table->addColumn('version', 'biginteger', array('limit' => 14))
|
||||
->addColumn('migration_name', 'string', array('limit' => 100, 'default' => null, 'null' => true))
|
||||
->addColumn('start_time', 'timestamp', array('default' => 'CURRENT_TIMESTAMP'))
|
||||
->addColumn('end_time', 'timestamp', array('default' => 'CURRENT_TIMESTAMP'))
|
||||
->addColumn('breakpoint', 'boolean', array('default' => false))
|
||||
->save();
|
||||
} else {
|
||||
$table->addColumn('version', 'biginteger')
|
||||
->addColumn('migration_name', 'string', array('limit' => 100, 'default' => null, 'null' => true))
|
||||
->addColumn('start_time', 'timestamp')
|
||||
->addColumn('end_time', 'timestamp')
|
||||
->addColumn('breakpoint', 'boolean', array('default' => false))
|
||||
->save();
|
||||
}
|
||||
} catch (\Exception $exception) {
|
||||
throw new \InvalidArgumentException('There was a problem creating the schema table: ' . $exception->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAdapterType()
|
||||
{
|
||||
return $this->getOption('adapter');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getColumnTypes()
|
||||
{
|
||||
return array(
|
||||
'string',
|
||||
'char',
|
||||
'text',
|
||||
'integer',
|
||||
'biginteger',
|
||||
'float',
|
||||
'decimal',
|
||||
'datetime',
|
||||
'timestamp',
|
||||
'time',
|
||||
'date',
|
||||
'blob',
|
||||
'binary',
|
||||
'varbinary',
|
||||
'boolean',
|
||||
'uuid',
|
||||
// Geospatial data types
|
||||
'geometry',
|
||||
'point',
|
||||
'linestring',
|
||||
'polygon',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isValidColumnType(Column $column) {
|
||||
return in_array($column->getType(), $this->getColumnTypes());
|
||||
}
|
||||
|
||||
/**
|
||||
* Cast a value to a boolean appropriate for the adapter.
|
||||
*
|
||||
* @param mixed $value The value to be cast
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function castToBool($value)
|
||||
{
|
||||
return (bool) $value ? 1 : 0;
|
||||
}
|
||||
}
|
||||
1182
vendor/topthink/think-migration/phinx/src/Phinx/Db/Adapter/PostgresAdapter.php
vendored
Normal file
325
vendor/topthink/think-migration/phinx/src/Phinx/Db/Adapter/ProxyAdapter.php
vendored
Normal file
@@ -0,0 +1,325 @@
|
||||
<?php
|
||||
/**
|
||||
* Phinx
|
||||
*
|
||||
* (The MIT license)
|
||||
* Copyright (c) 2015 Rob Morgan
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @package Phinx
|
||||
* @subpackage Phinx\Db\Adapter
|
||||
*/
|
||||
namespace Phinx\Db\Adapter;
|
||||
|
||||
use Phinx\Db\Table;
|
||||
use Phinx\Db\Table\Column;
|
||||
use Phinx\Db\Table\Index;
|
||||
use Phinx\Db\Table\ForeignKey;
|
||||
use Phinx\Migration\IrreversibleMigrationException;
|
||||
|
||||
/**
|
||||
* Phinx Proxy Adapter.
|
||||
*
|
||||
* Used for recording migration commands to automatically reverse them.
|
||||
*
|
||||
* @author Rob Morgan <robbym@gmail.com>
|
||||
*/
|
||||
class ProxyAdapter extends AdapterWrapper
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $commands;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAdapterType()
|
||||
{
|
||||
return 'ProxyAdapter';
|
||||
}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function createTable(Table $table)
|
||||
{
|
||||
$this->recordCommand('createTable', array($table->getName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function renameTable($tableName, $newTableName)
|
||||
{
|
||||
$this->recordCommand('renameTable', array($tableName, $newTableName));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dropTable($tableName)
|
||||
{
|
||||
$this->recordCommand('dropTable', array($tableName));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addColumn(Table $table, Column $column)
|
||||
{
|
||||
$this->recordCommand('addColumn', array($table, $column));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function renameColumn($tableName, $columnName, $newColumnName)
|
||||
{
|
||||
$this->recordCommand('renameColumn', array($tableName, $columnName, $newColumnName));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function changeColumn($tableName, $columnName, Column $newColumn)
|
||||
{
|
||||
$this->recordCommand('changeColumn', array($tableName, $columnName, $newColumn));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dropColumn($tableName, $columnName)
|
||||
{
|
||||
$this->recordCommand('dropColumn', array($tableName, $columnName));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addIndex(Table $table, Index $index)
|
||||
{
|
||||
$this->recordCommand('addIndex', array($table, $index));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dropIndex($tableName, $columns, $options = array())
|
||||
{
|
||||
$this->recordCommand('dropIndex', array($tableName, $columns, $options));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dropIndexByName($tableName, $indexName)
|
||||
{
|
||||
$this->recordCommand('dropIndexByName', array($tableName, $indexName));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addForeignKey(Table $table, ForeignKey $foreignKey)
|
||||
{
|
||||
$this->recordCommand('addForeignKey', array($table, $foreignKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dropForeignKey($tableName, $columns, $constraint = null)
|
||||
{
|
||||
$this->recordCommand('dropForeignKey', array($columns, $constraint));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function createDatabase($name, $options = array())
|
||||
{
|
||||
$this->recordCommand('createDatabase', array($name, $options));
|
||||
}
|
||||
|
||||
/**
|
||||
* Record a command for execution later.
|
||||
*
|
||||
* @param string $name Command Name
|
||||
* @param array $arguments Command Arguments
|
||||
* @return void
|
||||
*/
|
||||
public function recordCommand($name, $arguments)
|
||||
{
|
||||
$this->commands[] = array(
|
||||
'name' => $name,
|
||||
'arguments' => $arguments
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an array of recorded commands.
|
||||
*
|
||||
* @param array $commands Commands
|
||||
* @return ProxyAdapter
|
||||
*/
|
||||
public function setCommands($commands)
|
||||
{
|
||||
$this->commands = $commands;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of the recorded commands.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCommands()
|
||||
{
|
||||
return $this->commands;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of the recorded commands in reverse.
|
||||
*
|
||||
* @throws IrreversibleMigrationException if a command cannot be reversed.
|
||||
* @return array
|
||||
*/
|
||||
public function getInvertedCommands()
|
||||
{
|
||||
if (null === $this->getCommands()) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$invCommands = array();
|
||||
$supportedCommands = array(
|
||||
'createTable', 'renameTable', 'addColumn',
|
||||
'renameColumn', 'addIndex', 'addForeignKey'
|
||||
);
|
||||
foreach (array_reverse($this->getCommands()) as $command) {
|
||||
if (!in_array($command['name'], $supportedCommands)) {
|
||||
throw new IrreversibleMigrationException(sprintf(
|
||||
'Cannot reverse a "%s" command',
|
||||
$command['name']
|
||||
));
|
||||
}
|
||||
$invertMethod = 'invert' . ucfirst($command['name']);
|
||||
$invertedCommand = $this->$invertMethod($command['arguments']);
|
||||
$invCommands[] = array(
|
||||
'name' => $invertedCommand['name'],
|
||||
'arguments' => $invertedCommand['arguments']
|
||||
);
|
||||
}
|
||||
|
||||
return $invCommands;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the recorded commands.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function executeCommands()
|
||||
{
|
||||
$commands = $this->getCommands();
|
||||
foreach ($commands as $command) {
|
||||
call_user_func_array(array($this->getAdapter(), $command['name']), $command['arguments']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the recorded commands in reverse.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function executeInvertedCommands()
|
||||
{
|
||||
$commands = $this->getInvertedCommands();
|
||||
foreach ($commands as $command) {
|
||||
call_user_func_array(array($this->getAdapter(), $command['name']), $command['arguments']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the reverse of a createTable command.
|
||||
*
|
||||
* @param array $args Method Arguments
|
||||
* @return array
|
||||
*/
|
||||
public function invertCreateTable($args)
|
||||
{
|
||||
return array('name' => 'dropTable', 'arguments' => array($args[0]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the reverse of a renameTable command.
|
||||
*
|
||||
* @param array $args Method Arguments
|
||||
* @return array
|
||||
*/
|
||||
public function invertRenameTable($args)
|
||||
{
|
||||
return array('name' => 'renameTable', 'arguments' => array($args[1], $args[0]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the reverse of a addColumn command.
|
||||
*
|
||||
* @param array $args Method Arguments
|
||||
* @return array
|
||||
*/
|
||||
public function invertAddColumn($args)
|
||||
{
|
||||
return array('name' => 'dropColumn', 'arguments' => array($args[0]->getName(), $args[1]->getName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the reverse of a renameColumn command.
|
||||
*
|
||||
* @param array $args Method Arguments
|
||||
* @return array
|
||||
*/
|
||||
public function invertRenameColumn($args)
|
||||
{
|
||||
return array('name' => 'renameColumn', 'arguments' => array($args[0], $args[2], $args[1]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the reverse of a addIndex command.
|
||||
*
|
||||
* @param array $args Method Arguments
|
||||
* @return array
|
||||
*/
|
||||
public function invertAddIndex($args)
|
||||
{
|
||||
return array('name' => 'dropIndex', 'arguments' => array($args[0]->getName(), $args[1]->getColumns()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the reverse of a addForeignKey command.
|
||||
*
|
||||
* @param array $args Method Arguments
|
||||
* @return array
|
||||
*/
|
||||
public function invertAddForeignKey($args)
|
||||
{
|
||||
return array('name' => 'dropForeignKey', 'arguments' => array($args[0]->getName(), $args[1]->getColumns()));
|
||||
}
|
||||
}
|
||||
1136
vendor/topthink/think-migration/phinx/src/Phinx/Db/Adapter/SQLiteAdapter.php
vendored
Normal file
1165
vendor/topthink/think-migration/phinx/src/Phinx/Db/Adapter/SqlServerAdapter.php
vendored
Normal file
272
vendor/topthink/think-migration/phinx/src/Phinx/Db/Adapter/TablePrefixAdapter.php
vendored
Normal file
@@ -0,0 +1,272 @@
|
||||
<?php
|
||||
/**
|
||||
* Phinx
|
||||
*
|
||||
* (The MIT license)
|
||||
* Copyright (c) 2015 Rob Morgan
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @package Phinx
|
||||
* @subpackage Phinx\Db\Adapter
|
||||
*/
|
||||
namespace Phinx\Db\Adapter;
|
||||
|
||||
use Phinx\Db\Table;
|
||||
use Phinx\Db\Table\Column;
|
||||
use Phinx\Db\Table\Index;
|
||||
use Phinx\Db\Table\ForeignKey;
|
||||
|
||||
/**
|
||||
* Table prefix/suffix adapter.
|
||||
*
|
||||
* Used for inserting a prefix or suffix into table names.
|
||||
*
|
||||
* @author Samuel Fisher <sam@sfisher.co>
|
||||
*/
|
||||
class TablePrefixAdapter extends AdapterWrapper
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAdapterType()
|
||||
{
|
||||
return 'TablePrefixAdapter';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasTable($tableName)
|
||||
{
|
||||
$adapterTableName = $this->getAdapterTableName($tableName);
|
||||
return parent::hasTable($adapterTableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function createTable(Table $table)
|
||||
{
|
||||
$adapterTable = clone $table;
|
||||
$adapterTableName = $this->getAdapterTableName($table->getName());
|
||||
$adapterTable->setName($adapterTableName);
|
||||
|
||||
foreach ($adapterTable->getForeignKeys() as $fk) {
|
||||
$adapterReferenceTable = $fk->getReferencedTable();
|
||||
$adapterReferenceTableName = $this->getAdapterTableName($adapterReferenceTable->getName());
|
||||
$adapterReferenceTable->setName($adapterReferenceTableName);
|
||||
}
|
||||
|
||||
return parent::createTable($adapterTable);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function renameTable($tableName, $newTableName)
|
||||
{
|
||||
$adapterTableName = $this->getAdapterTableName($tableName);
|
||||
$adapterNewTableName = $this->getAdapterTableName($newTableName);
|
||||
return parent::renameTable($adapterTableName, $adapterNewTableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dropTable($tableName)
|
||||
{
|
||||
$adapterTableName = $this->getAdapterTableName($tableName);
|
||||
return parent::dropTable($adapterTableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getColumns($tableName)
|
||||
{
|
||||
$adapterTableName = $this->getAdapterTableName($tableName);
|
||||
return parent::getColumns($adapterTableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasColumn($tableName, $columnName)
|
||||
{
|
||||
$adapterTableName = $this->getAdapterTableName($tableName);
|
||||
return parent::hasColumn($adapterTableName, $columnName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addColumn(Table $table, Column $column)
|
||||
{
|
||||
$adapterTable = clone $table;
|
||||
$adapterTableName = $this->getAdapterTableName($table->getName());
|
||||
$adapterTable->setName($adapterTableName);
|
||||
return parent::addColumn($adapterTable, $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function renameColumn($tableName, $columnName, $newColumnName)
|
||||
{
|
||||
$adapterTableName = $this->getAdapterTableName($tableName);
|
||||
return parent::renameColumn($adapterTableName, $columnName, $newColumnName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function changeColumn($tableName, $columnName, Column $newColumn)
|
||||
{
|
||||
$adapterTableName = $this->getAdapterTableName($tableName);
|
||||
return parent::changeColumn($adapterTableName, $columnName, $newColumn);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dropColumn($tableName, $columnName)
|
||||
{
|
||||
$adapterTableName = $this->getAdapterTableName($tableName);
|
||||
return parent::dropColumn($adapterTableName, $columnName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasIndex($tableName, $columns)
|
||||
{
|
||||
$adapterTableName = $this->getAdapterTableName($tableName);
|
||||
return parent::hasIndex($adapterTableName, $columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasIndexByName($tableName, $indexName)
|
||||
{
|
||||
$adapterTableName = $this->getAdapterTableName($tableName);
|
||||
return parent::hasIndexByName($adapterTableName, $indexName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addIndex(Table $table, Index $index)
|
||||
{
|
||||
$adapterTable = clone $table;
|
||||
$adapterTableName = $this->getAdapterTableName($table->getName());
|
||||
$adapterTable->setName($adapterTableName);
|
||||
return parent::addIndex($adapterTable, $index);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dropIndex($tableName, $columns, $options = array())
|
||||
{
|
||||
$adapterTableName = $this->getAdapterTableName($tableName);
|
||||
return parent::dropIndex($adapterTableName, $columns, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dropIndexByName($tableName, $indexName)
|
||||
{
|
||||
$adapterTableName = $this->getAdapterTableName($tableName);
|
||||
return parent::dropIndexByName($adapterTableName, $indexName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasForeignKey($tableName, $columns, $constraint = null)
|
||||
{
|
||||
$adapterTableName = $this->getAdapterTableName($tableName);
|
||||
return parent::hasForeignKey($adapterTableName, $columns, $constraint);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addForeignKey(Table $table, ForeignKey $foreignKey)
|
||||
{
|
||||
$adapterTable = clone $table;
|
||||
$adapterTableName = $this->getAdapterTableName($table->getName());
|
||||
$adapterTable->setName($adapterTableName);
|
||||
return parent::addForeignKey($adapterTable, $foreignKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dropForeignKey($tableName, $columns, $constraint = null)
|
||||
{
|
||||
$adapterTableName = $this->getAdapterTableName($tableName);
|
||||
return parent::dropForeignKey($adapterTableName, $columns, $constraint);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function insert(Table $table, $row)
|
||||
{
|
||||
$adapterTable = clone $table;
|
||||
$adapterTableName = $this->getAdapterTableName($table->getName());
|
||||
$adapterTable->setName($adapterTableName);
|
||||
return parent::insert($adapterTable, $row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the table prefix.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPrefix()
|
||||
{
|
||||
return (string) $this->getOption('table_prefix');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the table suffix.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSuffix()
|
||||
{
|
||||
return (string) $this->getOption('table_suffix');
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the prefix and suffix to the table name.
|
||||
*
|
||||
* @param string $tableName
|
||||
* @return string
|
||||
*/
|
||||
public function getAdapterTableName($tableName)
|
||||
{
|
||||
return $this->getPrefix() . $tableName . $this->getSuffix();
|
||||
}
|
||||
}
|
||||
60
vendor/topthink/think-migration/phinx/src/Phinx/Db/Adapter/WrapperInterface.php
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
/**
|
||||
* Phinx
|
||||
*
|
||||
* (The MIT license)
|
||||
* Copyright (c) 2015 Rob Morgan
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @package Phinx
|
||||
* @subpackage Phinx\Db\Adapter
|
||||
*/
|
||||
namespace Phinx\Db\Adapter;
|
||||
|
||||
/**
|
||||
* Wrapper Interface.
|
||||
*
|
||||
* @author Woody Gilk <woody.gilk@gmail.com>
|
||||
*/
|
||||
interface WrapperInterface
|
||||
{
|
||||
/**
|
||||
* Class constructor, must always wrap another adapter.
|
||||
*
|
||||
* @param AdapterInterface $adapter
|
||||
*/
|
||||
public function __construct(AdapterInterface $adapter);
|
||||
|
||||
/**
|
||||
* Sets the database adapter to proxy commands to.
|
||||
*
|
||||
* @param AdapterInterface $adapter
|
||||
* @return AdapterInterface
|
||||
*/
|
||||
public function setAdapter(AdapterInterface $adapter);
|
||||
|
||||
/**
|
||||
* Gets the database adapter.
|
||||
*
|
||||
* @throws \RuntimeException if the adapter has not been set
|
||||
* @return AdapterInterface
|
||||
*/
|
||||
public function getAdapter();
|
||||
}
|
||||
674
vendor/topthink/think-migration/phinx/src/Phinx/Db/Table.php
vendored
Normal file
@@ -0,0 +1,674 @@
|
||||
<?php
|
||||
/**
|
||||
* Phinx
|
||||
*
|
||||
* (The MIT license)
|
||||
* Copyright (c) 2015 Rob Morgan
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @package Phinx
|
||||
* @subpackage Phinx\Db
|
||||
*/
|
||||
namespace Phinx\Db;
|
||||
|
||||
use Phinx\Db\Table\Column;
|
||||
use Phinx\Db\Table\Index;
|
||||
use Phinx\Db\Table\ForeignKey;
|
||||
use Phinx\Db\Adapter\AdapterInterface;
|
||||
|
||||
/**
|
||||
*
|
||||
* This object is based loosely on: http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Table.html.
|
||||
*/
|
||||
class Table
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $options = array();
|
||||
|
||||
/**
|
||||
* @var AdapterInterface
|
||||
*/
|
||||
protected $adapter;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $columns = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $indexes = array();
|
||||
|
||||
/**
|
||||
* @var ForeignKey[]
|
||||
*/
|
||||
protected $foreignKeys = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $data = array();
|
||||
|
||||
/**
|
||||
* Class Constuctor.
|
||||
*
|
||||
* @param string $name Table Name
|
||||
* @param array $options Options
|
||||
* @param AdapterInterface $adapter Database Adapter
|
||||
*/
|
||||
public function __construct($name, $options = array(), AdapterInterface $adapter = null)
|
||||
{
|
||||
$this->setName($name);
|
||||
$this->setOptions($options);
|
||||
|
||||
if (null !== $adapter) {
|
||||
$this->setAdapter($adapter);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the table name.
|
||||
*
|
||||
* @param string $name Table Name
|
||||
* @return Table
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the table name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the table options.
|
||||
*
|
||||
* @param array $options
|
||||
* @return Table
|
||||
*/
|
||||
public function setOptions($options)
|
||||
{
|
||||
$this->options = $options;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the table options.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getOptions()
|
||||
{
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the database adapter.
|
||||
*
|
||||
* @param AdapterInterface $adapter Database Adapter
|
||||
* @return Table
|
||||
*/
|
||||
public function setAdapter(AdapterInterface $adapter)
|
||||
{
|
||||
$this->adapter = $adapter;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the database adapter.
|
||||
*
|
||||
* @return AdapterInterface
|
||||
*/
|
||||
public function getAdapter()
|
||||
{
|
||||
return $this->adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the table exist?
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function exists()
|
||||
{
|
||||
return $this->getAdapter()->hasTable($this->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops the database table.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function drop()
|
||||
{
|
||||
$this->getAdapter()->dropTable($this->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Renames the database table.
|
||||
*
|
||||
* @param string $newTableName New Table Name
|
||||
* @return Table
|
||||
*/
|
||||
public function rename($newTableName)
|
||||
{
|
||||
$this->getAdapter()->renameTable($this->getName(), $newTableName);
|
||||
$this->setName($newTableName);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an array of columns waiting to be committed.
|
||||
* Use setPendingColumns
|
||||
*
|
||||
* @deprecated
|
||||
* @param array $columns Columns
|
||||
* @return Table
|
||||
*/
|
||||
public function setColumns($columns)
|
||||
{
|
||||
$this->setPendingColumns($columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of the table columns.
|
||||
*
|
||||
* @return Column[]
|
||||
*/
|
||||
public function getColumns()
|
||||
{
|
||||
return $this->getAdapter()->getColumns($this->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an array of columns waiting to be committed.
|
||||
*
|
||||
* @param array $columns Columns
|
||||
* @return Table
|
||||
*/
|
||||
public function setPendingColumns($columns)
|
||||
{
|
||||
$this->columns = $columns;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of columns waiting to be committed.
|
||||
*
|
||||
* @return Column[]
|
||||
*/
|
||||
public function getPendingColumns()
|
||||
{
|
||||
return $this->columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an array of columns waiting to be indexed.
|
||||
*
|
||||
* @param array $indexes Indexes
|
||||
* @return Table
|
||||
*/
|
||||
public function setIndexes($indexes)
|
||||
{
|
||||
$this->indexes = $indexes;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of indexes waiting to be committed.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getIndexes()
|
||||
{
|
||||
return $this->indexes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an array of foreign keys waiting to be commited.
|
||||
*
|
||||
* @param ForeignKey[] $foreignKeys foreign keys
|
||||
* @return Table
|
||||
*/
|
||||
public function setForeignKeys($foreignKeys)
|
||||
{
|
||||
$this->foreignKeys = $foreignKeys;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of foreign keys waiting to be commited.
|
||||
*
|
||||
* @return array|ForeignKey[]
|
||||
*/
|
||||
public function getForeignKeys()
|
||||
{
|
||||
return $this->foreignKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an array of data to be inserted.
|
||||
*
|
||||
* @param array $data Data
|
||||
* @return Table
|
||||
*/
|
||||
public function setData($data)
|
||||
{
|
||||
$this->data = $data;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the data waiting to be inserted.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets all of the pending table changes.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->setPendingColumns(array());
|
||||
$this->setIndexes(array());
|
||||
$this->setForeignKeys(array());
|
||||
$this->setData(array());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a table column.
|
||||
*
|
||||
* Type can be: string, text, integer, float, decimal, datetime, timestamp,
|
||||
* time, date, binary, boolean.
|
||||
*
|
||||
* Valid options can be: limit, default, null, precision or scale.
|
||||
*
|
||||
* @param string|Column $columnName Column Name
|
||||
* @param string $type Column Type
|
||||
* @param array $options Column Options
|
||||
* @throws \RuntimeException
|
||||
* @throws \InvalidArgumentException
|
||||
* @return Table
|
||||
*/
|
||||
public function addColumn($columnName, $type = null, $options = array())
|
||||
{
|
||||
// we need an adapter set to add a column
|
||||
if (null === $this->getAdapter()) {
|
||||
throw new \RuntimeException('An adapter must be specified to add a column.');
|
||||
}
|
||||
|
||||
// create a new column object if only strings were supplied
|
||||
if (!$columnName instanceof Column) {
|
||||
$column = new Column();
|
||||
$column->setName($columnName);
|
||||
$column->setType($type);
|
||||
$column->setOptions($options); // map options to column methods
|
||||
} else {
|
||||
$column = $columnName;
|
||||
}
|
||||
|
||||
// Delegate to Adapters to check column type
|
||||
if (!$this->getAdapter()->isValidColumnType($column)) {
|
||||
throw new \InvalidArgumentException(sprintf(
|
||||
'An invalid column type "%s" was specified for column "%s".',
|
||||
$column->getType(),
|
||||
$column->getName()
|
||||
));
|
||||
}
|
||||
|
||||
$this->columns[] = $column;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a table column.
|
||||
*
|
||||
* @param string $columnName Column Name
|
||||
* @return Table
|
||||
*/
|
||||
public function removeColumn($columnName)
|
||||
{
|
||||
$this->getAdapter()->dropColumn($this->getName(), $columnName);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename a table column.
|
||||
*
|
||||
* @param string $oldName Old Column Name
|
||||
* @param string $newName New Column Name
|
||||
* @return Table
|
||||
*/
|
||||
public function renameColumn($oldName, $newName)
|
||||
{
|
||||
$this->getAdapter()->renameColumn($this->getName(), $oldName, $newName);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change a table column type.
|
||||
*
|
||||
* @param string $columnName Column Name
|
||||
* @param string|Column $newColumnType New Column Type
|
||||
* @param array $options Options
|
||||
* @return Table
|
||||
*/
|
||||
public function changeColumn($columnName, $newColumnType, $options = array())
|
||||
{
|
||||
// create a column object if one wasn't supplied
|
||||
if (!$newColumnType instanceof Column) {
|
||||
$newColumn = new Column();
|
||||
$newColumn->setType($newColumnType);
|
||||
$newColumn->setOptions($options);
|
||||
} else {
|
||||
$newColumn = $newColumnType;
|
||||
}
|
||||
|
||||
// if the name was omitted use the existing column name
|
||||
if (null === $newColumn->getName() || strlen($newColumn->getName()) === 0) {
|
||||
$newColumn->setName($columnName);
|
||||
}
|
||||
|
||||
$this->getAdapter()->changeColumn($this->getName(), $columnName, $newColumn);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a column exists.
|
||||
*
|
||||
* @param string $columnName Column Name
|
||||
* @param array $options Options
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasColumn($columnName, $options = array())
|
||||
{
|
||||
return $this->getAdapter()->hasColumn($this->getName(), $columnName, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an index to a database table.
|
||||
*
|
||||
* In $options you can specific unique = true/false or name (index name).
|
||||
*
|
||||
* @param string|array|Index $columns Table Column(s)
|
||||
* @param array $options Index Options
|
||||
* @return Table
|
||||
*/
|
||||
public function addIndex($columns, $options = array())
|
||||
{
|
||||
// create a new index object if strings or an array of strings were supplied
|
||||
if (!$columns instanceof Index) {
|
||||
$index = new Index();
|
||||
if (is_string($columns)) {
|
||||
$columns = array($columns); // str to array
|
||||
}
|
||||
$index->setColumns($columns);
|
||||
$index->setOptions($options);
|
||||
} else {
|
||||
$index = $columns;
|
||||
}
|
||||
|
||||
$this->indexes[] = $index;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given index from a table.
|
||||
*
|
||||
* @param array $columns Columns
|
||||
* @param array $options Options
|
||||
* @return Table
|
||||
*/
|
||||
public function removeIndex($columns, $options = array())
|
||||
{
|
||||
$this->getAdapter()->dropIndex($this->getName(), $columns, $options);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given index identified by its name from a table.
|
||||
*
|
||||
* @param string $name Index name
|
||||
* @return Table
|
||||
*/
|
||||
public function removeIndexByName($name)
|
||||
{
|
||||
$this->getAdapter()->dropIndexByName($this->getName(), $name);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if an index exists.
|
||||
*
|
||||
* @param string|array $columns Columns
|
||||
* @param array $options Options
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasIndex($columns, $options = array())
|
||||
{
|
||||
return $this->getAdapter()->hasIndex($this->getName(), $columns, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a foreign key to a database table.
|
||||
*
|
||||
* In $options you can specify on_delete|on_delete = cascade|no_action ..,
|
||||
* on_update, constraint = constraint name.
|
||||
*
|
||||
* @param string|array $columns Columns
|
||||
* @param string|Table $referencedTable Referenced Table
|
||||
* @param string|array $referencedColumns Referenced Columns
|
||||
* @param array $options Options
|
||||
* @return Table
|
||||
*/
|
||||
public function addForeignKey($columns, $referencedTable, $referencedColumns = array('id'), $options = array())
|
||||
{
|
||||
if (is_string($referencedColumns)) {
|
||||
$referencedColumns = array($referencedColumns); // str to array
|
||||
}
|
||||
$fk = new ForeignKey();
|
||||
if ($referencedTable instanceof Table) {
|
||||
$fk->setReferencedTable($referencedTable);
|
||||
} else {
|
||||
$fk->setReferencedTable(new Table($referencedTable, array(), $this->adapter));
|
||||
}
|
||||
$fk->setColumns($columns)
|
||||
->setReferencedColumns($referencedColumns)
|
||||
->setOptions($options);
|
||||
$this->foreignKeys[] = $fk;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given foreign key from the table.
|
||||
*
|
||||
* @param string|array $columns Column(s)
|
||||
* @param null|string $constraint Constraint names
|
||||
* @return Table
|
||||
*/
|
||||
public function dropForeignKey($columns, $constraint = null)
|
||||
{
|
||||
if (is_string($columns)) {
|
||||
$columns = array($columns);
|
||||
}
|
||||
if ($constraint) {
|
||||
$this->getAdapter()->dropForeignKey($this->getName(), array(), $constraint);
|
||||
} else {
|
||||
$this->getAdapter()->dropForeignKey($this->getName(), $columns);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a foreign key exists.
|
||||
*
|
||||
* @param string|array $columns Column(s)
|
||||
* @param null|string $constraint Constraint names
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasForeignKey($columns, $constraint = null)
|
||||
{
|
||||
return $this->getAdapter()->hasForeignKey($this->getName(), $columns, $constraint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add timestamp columns created_at and updated_at to the table.
|
||||
*
|
||||
* @param string $createdAtColumnName
|
||||
* @param string $updatedAtColumnName
|
||||
*
|
||||
* @return Table
|
||||
*/
|
||||
public function addTimestamps($createdAtColumnName = 'created_at', $updatedAtColumnName = 'updated_at')
|
||||
{
|
||||
$createdAtColumnName = is_null($createdAtColumnName) ? 'created_at' : $createdAtColumnName;
|
||||
$updatedAtColumnName = is_null($updatedAtColumnName) ? 'updated_at' : $updatedAtColumnName;
|
||||
$this->addColumn($createdAtColumnName, 'timestamp', array(
|
||||
'default' => 'CURRENT_TIMESTAMP',
|
||||
'update' => ''
|
||||
))
|
||||
->addColumn($updatedAtColumnName, 'timestamp', array(
|
||||
'null' => true,
|
||||
'default' => null
|
||||
));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert data into the table.
|
||||
*
|
||||
* @param $data array of data in the form:
|
||||
* array(
|
||||
* array("col1" => "value1", "col2" => "anotherValue1"),
|
||||
* array("col2" => "value2", "col2" => "anotherValue2"),
|
||||
* )
|
||||
* or array("col1" => "value1", "col2" => "anotherValue1")
|
||||
*
|
||||
* @return Table
|
||||
*/
|
||||
public function insert($data)
|
||||
{
|
||||
// handle array of array situations
|
||||
if (isset($data[0]) && is_array($data[0])) {
|
||||
foreach ($data as $row) {
|
||||
$this->data[] = $row;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
$this->data[] = $data;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a table from the object instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$this->getAdapter()->createTable($this);
|
||||
$this->saveData();
|
||||
$this->reset(); // reset pending changes
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a table from the object instance.
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
* @return void
|
||||
*/
|
||||
public function update()
|
||||
{
|
||||
if (!$this->exists()) {
|
||||
throw new \RuntimeException('Cannot update a table that doesn\'t exist!');
|
||||
}
|
||||
|
||||
// update table
|
||||
foreach ($this->getPendingColumns() as $column) {
|
||||
$this->getAdapter()->addColumn($this, $column);
|
||||
}
|
||||
|
||||
foreach ($this->getIndexes() as $index) {
|
||||
$this->getAdapter()->addIndex($this, $index);
|
||||
}
|
||||
|
||||
foreach ($this->getForeignKeys() as $foreignKey) {
|
||||
$this->getAdapter()->addForeignKey($this, $foreignKey);
|
||||
}
|
||||
|
||||
$this->saveData();
|
||||
$this->reset(); // reset pending changes
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit the pending data waiting for insertion.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function saveData()
|
||||
{
|
||||
foreach ($this->getData() as $row) {
|
||||
$this->getAdapter()->insert($this, $row);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Commits the table changes.
|
||||
*
|
||||
* If the table doesn't exist it is created otherwise it is updated.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
if ($this->exists()) {
|
||||
$this->update(); // update the table
|
||||
} else {
|
||||
$this->create(); // create the table
|
||||
}
|
||||
|
||||
$this->reset(); // reset pending changes
|
||||
}
|
||||
}
|
||||
550
vendor/topthink/think-migration/phinx/src/Phinx/Db/Table/Column.php
vendored
Normal file
@@ -0,0 +1,550 @@
|
||||
<?php
|
||||
/**
|
||||
* Phinx
|
||||
*
|
||||
* (The MIT license)
|
||||
* Copyright (c) 2015 Rob Morgan
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @package Phinx
|
||||
* @subpackage Phinx\Db
|
||||
*/
|
||||
namespace Phinx\Db\Table;
|
||||
|
||||
/**
|
||||
*
|
||||
* This object is based loosely on: http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Table.html.
|
||||
*/
|
||||
class Column
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $type;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
protected $limit = null;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
protected $null = false;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
protected $default = null;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
protected $identity = false;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
protected $precision;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
protected $scale;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $after;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $update;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $comment;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
protected $signed = true;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
protected $timezone = false;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $properties = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $values;
|
||||
|
||||
/**
|
||||
* Sets the column name.
|
||||
*
|
||||
* @param string $name
|
||||
* @return $this
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the column name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the column type.
|
||||
*
|
||||
* @param string $type
|
||||
* @return $this
|
||||
*/
|
||||
public function setType($type)
|
||||
{
|
||||
$this->type = $type;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the column type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the column limit.
|
||||
*
|
||||
* @param integer $limit
|
||||
* @return $this
|
||||
*/
|
||||
public function setLimit($limit)
|
||||
{
|
||||
$this->limit = $limit;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the column limit.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getLimit()
|
||||
{
|
||||
return $this->limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the column allows nulls.
|
||||
*
|
||||
* @param boolean $null
|
||||
* @return $this
|
||||
*/
|
||||
public function setNull($null)
|
||||
{
|
||||
$this->null = (bool) $null;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether the column allows nulls.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getNull()
|
||||
{
|
||||
return $this->null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the column allow nulls?
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isNull()
|
||||
{
|
||||
return $this->getNull();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default column value.
|
||||
*
|
||||
* @param mixed $default
|
||||
* @return $this
|
||||
*/
|
||||
public function setDefault($default)
|
||||
{
|
||||
$this->default = $default;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default column value.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getDefault()
|
||||
{
|
||||
return $this->default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether or not the column is an identity column.
|
||||
*
|
||||
* @param boolean $identity
|
||||
* @return $this
|
||||
*/
|
||||
public function setIdentity($identity)
|
||||
{
|
||||
$this->identity = $identity;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether or not the column is an identity column.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getIdentity()
|
||||
{
|
||||
return $this->identity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the column an identity column?
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isIdentity()
|
||||
{
|
||||
return $this->getIdentity();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the column to add this column after.
|
||||
*
|
||||
* @param string $after After
|
||||
* @return $this
|
||||
*/
|
||||
public function setAfter($after)
|
||||
{
|
||||
$this->after = $after;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the column to add this column after.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAfter()
|
||||
{
|
||||
return $this->after;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the 'ON UPDATE' mysql column function.
|
||||
*
|
||||
* @param string $update On Update function
|
||||
* @return $this
|
||||
*/
|
||||
public function setUpdate($update)
|
||||
{
|
||||
$this->update = $update;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the ON UPDATE column function.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUpdate()
|
||||
{
|
||||
return $this->update;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the column precision for decimal.
|
||||
*
|
||||
* @param integer $precision
|
||||
* @return $this
|
||||
*/
|
||||
public function setPrecision($precision)
|
||||
{
|
||||
$this->precision = $precision;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the column precision for decimal.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getPrecision()
|
||||
{
|
||||
return $this->precision;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the column scale for decimal.
|
||||
*
|
||||
* @param integer $scale
|
||||
* @return $this
|
||||
*/
|
||||
public function setScale($scale)
|
||||
{
|
||||
$this->scale = $scale;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the column scale for decimal.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getScale()
|
||||
{
|
||||
return $this->scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the column comment.
|
||||
*
|
||||
* @param string $comment
|
||||
* @return $this
|
||||
*/
|
||||
public function setComment($comment)
|
||||
{
|
||||
$this->comment = $comment;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the column comment.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getComment()
|
||||
{
|
||||
return $this->comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether field should be signed.
|
||||
*
|
||||
* @param bool $signed
|
||||
* @return $this
|
||||
*/
|
||||
public function setSigned($signed)
|
||||
{
|
||||
$this->signed = (bool) $signed;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether field should be signed.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSigned()
|
||||
{
|
||||
return $this->signed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the column be signed?
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isSigned()
|
||||
{
|
||||
return $this->getSigned();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the field should have a timezone identifier.
|
||||
* Used for date/time columns only!
|
||||
*
|
||||
* @param bool $timezone
|
||||
* @return $this
|
||||
*/
|
||||
public function setTimezone($timezone)
|
||||
{
|
||||
$this->timezone = (bool) $timezone;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether field has a timezone identifier.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getTimezone()
|
||||
{
|
||||
return $this->timezone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the column have a timezone?
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isTimezone()
|
||||
{
|
||||
return $this->getTimezone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets field properties.
|
||||
*
|
||||
* @param array $properties
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setProperties($properties)
|
||||
{
|
||||
$this->properties = $properties;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets field properties
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getProperties()
|
||||
{
|
||||
return $this->properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets field values.
|
||||
*
|
||||
* @param mixed (array|string) $values
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setValues($values)
|
||||
{
|
||||
if (!is_array($values)) {
|
||||
$values = preg_split('/,\s*/', $values);
|
||||
}
|
||||
$this->values = $values;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets field values
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getValues()
|
||||
{
|
||||
return $this->values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all allowed options. Each option must have a corresponding `setFoo` method.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getValidOptions()
|
||||
{
|
||||
return array(
|
||||
'limit',
|
||||
'default',
|
||||
'null',
|
||||
'identity',
|
||||
'precision',
|
||||
'scale',
|
||||
'after',
|
||||
'update',
|
||||
'comment',
|
||||
'signed',
|
||||
'timezone',
|
||||
'properties',
|
||||
'values',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all aliased options. Each alias must reference a valid option.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getAliasedOptions()
|
||||
{
|
||||
return array(
|
||||
'length' => 'limit',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method that maps an array of column options to this objects methods.
|
||||
*
|
||||
* @param array $options Options
|
||||
* @return $this
|
||||
*/
|
||||
public function setOptions($options)
|
||||
{
|
||||
$validOptions = $this->getValidOptions();
|
||||
$aliasOptions = $this->getAliasedOptions();
|
||||
|
||||
foreach ($options as $option => $value) {
|
||||
if (isset($aliasOptions[$option])) {
|
||||
// proxy alias -> option
|
||||
$option = $aliasOptions[$option];
|
||||
}
|
||||
|
||||
if (!in_array($option, $validOptions, true)) {
|
||||
throw new \RuntimeException(sprintf('"%s" is not a valid column option.', $option));
|
||||
}
|
||||
|
||||
$method = 'set' . ucfirst($option);
|
||||
$this->$method($value);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
252
vendor/topthink/think-migration/phinx/src/Phinx/Db/Table/ForeignKey.php
vendored
Normal file
@@ -0,0 +1,252 @@
|
||||
<?php
|
||||
/**
|
||||
* Phinx
|
||||
*
|
||||
* (The MIT license)
|
||||
* Copyright (c) 2015 Rob Morgan
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @package Phinx
|
||||
* @subpackage Phinx\Db
|
||||
* @author Leonid Kuzmin <lndkuzmin@gmail.com>
|
||||
*/
|
||||
namespace Phinx\Db\Table;
|
||||
|
||||
use Phinx\Db\Table;
|
||||
|
||||
class ForeignKey
|
||||
{
|
||||
const CASCADE = 'CASCADE';
|
||||
const RESTRICT = 'RESTRICT';
|
||||
const SET_NULL = 'SET NULL';
|
||||
const NO_ACTION = 'NO ACTION';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $columns = array();
|
||||
|
||||
/**
|
||||
* @var Table
|
||||
*/
|
||||
protected $referencedTable;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $referencedColumns = array();
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $onDelete;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $onUpdate;
|
||||
|
||||
/**
|
||||
* @var string|boolean
|
||||
*/
|
||||
protected $constraint;
|
||||
|
||||
/**
|
||||
* Sets the foreign key columns.
|
||||
*
|
||||
* @param array|string $columns
|
||||
* @return ForeignKey
|
||||
*/
|
||||
public function setColumns($columns)
|
||||
{
|
||||
if (is_string($columns)) {
|
||||
$columns = array($columns);
|
||||
}
|
||||
$this->columns = $columns;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the foreign key columns.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getColumns()
|
||||
{
|
||||
return $this->columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the foreign key referenced table.
|
||||
*
|
||||
* @param Table $table
|
||||
* @return ForeignKey
|
||||
*/
|
||||
public function setReferencedTable(Table $table)
|
||||
{
|
||||
$this->referencedTable = $table;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the foreign key referenced table.
|
||||
*
|
||||
* @return Table
|
||||
*/
|
||||
public function getReferencedTable()
|
||||
{
|
||||
return $this->referencedTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the foreign key referenced columns.
|
||||
*
|
||||
* @param array $referencedColumns
|
||||
* @return ForeignKey
|
||||
*/
|
||||
public function setReferencedColumns(array $referencedColumns)
|
||||
{
|
||||
$this->referencedColumns = $referencedColumns;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the foreign key referenced columns.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getReferencedColumns()
|
||||
{
|
||||
return $this->referencedColumns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets ON DELETE action for the foreign key.
|
||||
*
|
||||
* @param string $onDelete
|
||||
* @return ForeignKey
|
||||
*/
|
||||
public function setOnDelete($onDelete)
|
||||
{
|
||||
$this->onDelete = $this->normalizeAction($onDelete);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets ON DELETE action for the foreign key.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getOnDelete()
|
||||
{
|
||||
return $this->onDelete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets ON UPDATE action for the foreign key.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getOnUpdate()
|
||||
{
|
||||
return $this->onUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets ON UPDATE action for the foreign key.
|
||||
*
|
||||
* @param string $onUpdate
|
||||
* @return ForeignKey
|
||||
*/
|
||||
public function setOnUpdate($onUpdate)
|
||||
{
|
||||
$this->onUpdate = $this->normalizeAction($onUpdate);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets constraint for the foreign key.
|
||||
*
|
||||
* @param string $constraint
|
||||
* @return ForeignKey
|
||||
*/
|
||||
public function setConstraint($constraint)
|
||||
{
|
||||
$this->constraint = $constraint;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets constraint name for the foreign key.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getConstraint()
|
||||
{
|
||||
return $this->constraint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method that maps an array of index options to this objects methods.
|
||||
*
|
||||
* @param array $options Options
|
||||
* @throws \RuntimeException
|
||||
* @throws \InvalidArgumentException
|
||||
* @return ForeignKey
|
||||
*/
|
||||
public function setOptions($options)
|
||||
{
|
||||
// Valid Options
|
||||
$validOptions = array('delete', 'update', 'constraint');
|
||||
foreach ($options as $option => $value) {
|
||||
if (!in_array($option, $validOptions, true)) {
|
||||
throw new \RuntimeException(sprintf('"%s" is not a valid foreign key option.', $option));
|
||||
}
|
||||
|
||||
// handle $options['delete'] as $options['update']
|
||||
if ('delete' === $option) {
|
||||
$this->setOnDelete($value);
|
||||
} elseif ('update' === $option) {
|
||||
$this->setOnUpdate($value);
|
||||
} else {
|
||||
$method = 'set' . ucfirst($option);
|
||||
$this->$method($value);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* From passed value checks if it's correct and fixes if needed
|
||||
*
|
||||
* @param string $action
|
||||
* @throws \InvalidArgumentException
|
||||
* @return string
|
||||
*/
|
||||
protected function normalizeAction($action)
|
||||
{
|
||||
$constantName = 'static::' . str_replace(' ', '_', strtoupper(trim($action)));
|
||||
if (!defined($constantName)) {
|
||||
throw new \InvalidArgumentException('Unknown action passed: ' . $action);
|
||||
}
|
||||
return constant($constantName);
|
||||
}
|
||||
}
|
||||
185
vendor/topthink/think-migration/phinx/src/Phinx/Db/Table/Index.php
vendored
Normal file
@@ -0,0 +1,185 @@
|
||||
<?php
|
||||
/**
|
||||
* Phinx
|
||||
*
|
||||
* (The MIT license)
|
||||
* Copyright (c) 2015 Rob Morgan
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @package Phinx
|
||||
* @subpackage Phinx\Db
|
||||
*/
|
||||
namespace Phinx\Db\Table;
|
||||
|
||||
class Index
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const UNIQUE = 'unique';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const INDEX = 'index';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const FULLTEXT = 'fulltext';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $columns;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $type = self::INDEX;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $name = null;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
protected $limit = null;
|
||||
|
||||
/**
|
||||
* Sets the index columns.
|
||||
*
|
||||
* @param array $columns
|
||||
* @return Index
|
||||
*/
|
||||
public function setColumns($columns)
|
||||
{
|
||||
$this->columns = $columns;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index columns.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getColumns()
|
||||
{
|
||||
return $this->columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the index type.
|
||||
*
|
||||
* @param string $type
|
||||
* @return Index
|
||||
*/
|
||||
public function setType($type)
|
||||
{
|
||||
$this->type = $type;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the index name.
|
||||
*
|
||||
* @param string $name
|
||||
* @return Index
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the index limit.
|
||||
*
|
||||
* @param integer $limit
|
||||
* @return Index
|
||||
*/
|
||||
public function setLimit($limit)
|
||||
{
|
||||
$this->limit = $limit;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index limit.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getLimit()
|
||||
{
|
||||
return $this->limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method that maps an array of index options to this objects methods.
|
||||
*
|
||||
* @param array $options Options
|
||||
* @throws \RuntimeException
|
||||
* @return Index
|
||||
*/
|
||||
public function setOptions($options)
|
||||
{
|
||||
// Valid Options
|
||||
$validOptions = array('type', 'unique', 'name', 'limit');
|
||||
foreach ($options as $option => $value) {
|
||||
if (!in_array($option, $validOptions, true)) {
|
||||
throw new \RuntimeException(sprintf('"%s" is not a valid index option.', $option));
|
||||
}
|
||||
|
||||
// handle $options['unique']
|
||||
if (strcasecmp($option, self::UNIQUE) === 0) {
|
||||
if ((bool) $value) {
|
||||
$this->setType(self::UNIQUE);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
$method = 'set' . ucfirst($option);
|
||||
$this->$method($value);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
273
vendor/topthink/think-migration/phinx/src/Phinx/Migration/AbstractMigration.php
vendored
Normal file
@@ -0,0 +1,273 @@
|
||||
<?php
|
||||
/**
|
||||
* Phinx
|
||||
*
|
||||
* (The MIT license)
|
||||
* Copyright (c) 2015 Rob Morgan
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @package Phinx
|
||||
* @subpackage Phinx\Migration
|
||||
*/
|
||||
namespace Phinx\Migration;
|
||||
|
||||
use Phinx\Db\Table;
|
||||
use Phinx\Db\Adapter\AdapterInterface;
|
||||
use think\console\Input as InputInterface;
|
||||
use think\console\Output as OutputInterface;
|
||||
|
||||
/**
|
||||
* Abstract Migration Class.
|
||||
*
|
||||
* It is expected that the migrations you write extend from this class.
|
||||
*
|
||||
* This abstract class proxies the various database methods to your specified
|
||||
* adapter.
|
||||
*
|
||||
* @author Rob Morgan <robbym@gmail.com>
|
||||
*/
|
||||
abstract class AbstractMigration implements MigrationInterface
|
||||
{
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
protected $version;
|
||||
|
||||
/**
|
||||
* @var AdapterInterface
|
||||
*/
|
||||
protected $adapter;
|
||||
|
||||
/**
|
||||
* @var OutputInterface
|
||||
*/
|
||||
protected $output;
|
||||
|
||||
/**
|
||||
* @var InputInterface
|
||||
*/
|
||||
protected $input;
|
||||
|
||||
/**
|
||||
* Class Constructor.
|
||||
*
|
||||
* @param int $version Migration Version
|
||||
* @param InputInterface|null $input
|
||||
* @param OutputInterface|null $output
|
||||
*/
|
||||
final public function __construct($version, InputInterface $input = null, OutputInterface $output = null)
|
||||
{
|
||||
$this->version = $version;
|
||||
if (!is_null($input)){
|
||||
$this->setInput($input);
|
||||
}
|
||||
if (!is_null($output)){
|
||||
$this->setOutput($output);
|
||||
}
|
||||
|
||||
$this->init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize method.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function init()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setAdapter(AdapterInterface $adapter)
|
||||
{
|
||||
$this->adapter = $adapter;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAdapter()
|
||||
{
|
||||
return $this->adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setInput(InputInterface $input)
|
||||
{
|
||||
$this->input = $input;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getInput()
|
||||
{
|
||||
return $this->input;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setOutput(OutputInterface $output)
|
||||
{
|
||||
$this->output = $output;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getOutput()
|
||||
{
|
||||
return $this->output;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return get_class($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setVersion($version)
|
||||
{
|
||||
$this->version = $version;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getVersion()
|
||||
{
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function execute($sql)
|
||||
{
|
||||
return $this->getAdapter()->execute($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query($sql)
|
||||
{
|
||||
return $this->getAdapter()->query($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchRow($sql)
|
||||
{
|
||||
return $this->getAdapter()->fetchRow($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchAll($sql)
|
||||
{
|
||||
return $this->getAdapter()->fetchAll($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function insert($table, $data)
|
||||
{
|
||||
// convert to table object
|
||||
if (is_string($table)) {
|
||||
$table = new Table($table, array(), $this->getAdapter());
|
||||
}
|
||||
return $table->insert($data)->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function createDatabase($name, $options)
|
||||
{
|
||||
$this->getAdapter()->createDatabase($name, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dropDatabase($name)
|
||||
{
|
||||
$this->getAdapter()->dropDatabase($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasTable($tableName)
|
||||
{
|
||||
return $this->getAdapter()->hasTable($tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function table($tableName, $options = array())
|
||||
{
|
||||
return new Table($tableName, $options, $this->getAdapter());
|
||||
}
|
||||
|
||||
/**
|
||||
* A short-hand method to drop the given database table.
|
||||
*
|
||||
* @param string $tableName Table Name
|
||||
* @return void
|
||||
*/
|
||||
public function dropTable($tableName)
|
||||
{
|
||||
$this->table($tableName)->drop();
|
||||
}
|
||||
}
|
||||
97
vendor/topthink/think-migration/phinx/src/Phinx/Migration/AbstractTemplateCreation.php
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
/**
|
||||
* Phinx
|
||||
*
|
||||
* (The MIT license)
|
||||
* Copyright (c) 2015 Rob Morgan
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @package Phinx
|
||||
* @subpackage Phinx\Migration
|
||||
*/
|
||||
namespace Phinx\Migration;
|
||||
|
||||
use think\console\Input as InputInterface;
|
||||
use think\console\Output as OutputInterface;
|
||||
|
||||
abstract class AbstractTemplateCreation implements CreationInterface
|
||||
{
|
||||
/**
|
||||
* @var InputInterface
|
||||
*/
|
||||
protected $input;
|
||||
|
||||
/**
|
||||
* @var OutputInterface
|
||||
*/
|
||||
protected $output;
|
||||
|
||||
/**
|
||||
* Class Constructor.
|
||||
*
|
||||
* @param InputInterface|null $input
|
||||
* @param OutputInterface|null $output
|
||||
*/
|
||||
public function __construct(InputInterface $input = null, OutputInterface $output = null)
|
||||
{
|
||||
if (!is_null($input)) {
|
||||
$this->setInput($input);
|
||||
}
|
||||
if (!is_null($output)) {
|
||||
$this->setOutput($output);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getInput()
|
||||
{
|
||||
return $this->input;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setInput(InputInterface $input)
|
||||
{
|
||||
$this->input = $input;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getOutput()
|
||||
{
|
||||
return $this->output;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setOutput(OutputInterface $output)
|
||||
{
|
||||
$this->output = $output;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
94
vendor/topthink/think-migration/phinx/src/Phinx/Migration/CreationInterface.php
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
/**
|
||||
* Phinx
|
||||
*
|
||||
* (The MIT license)
|
||||
* Copyright (c) 2015 Rob Morgan
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @package Phinx
|
||||
* @subpackage Phinx\Migration
|
||||
*/
|
||||
namespace Phinx\Migration;
|
||||
|
||||
use think\console\Input as InputInterface;
|
||||
use think\console\Output as OutputInterface;
|
||||
|
||||
/**
|
||||
* Migration interface
|
||||
*
|
||||
* @author Richard Quadling <RQuadling@GMail.com>
|
||||
*/
|
||||
interface CreationInterface
|
||||
{
|
||||
/**
|
||||
* CreationInterface constructor.
|
||||
*
|
||||
* @param InputInterface|null $input
|
||||
* @param OutputInterface|null $output
|
||||
*/
|
||||
public function __construct(InputInterface $input = null, OutputInterface $output = null);
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
*
|
||||
* @return CreationInterface
|
||||
*/
|
||||
public function setInput(InputInterface $input);
|
||||
|
||||
/**
|
||||
* @param OutputInterface $output
|
||||
*
|
||||
* @return CreationInterface
|
||||
*/
|
||||
public function setOutput(OutputInterface $output);
|
||||
|
||||
/**
|
||||
* @return InputInterface
|
||||
*/
|
||||
public function getInput();
|
||||
|
||||
/**
|
||||
* @return OutputInterface
|
||||
*/
|
||||
public function getOutput();
|
||||
|
||||
/**
|
||||
* Get the migration template.
|
||||
*
|
||||
* This will be the content that Phinx will amend to generate the migration file.
|
||||
*
|
||||
* @return string The content of the template for Phinx to amend.
|
||||
*/
|
||||
public function getMigrationTemplate();
|
||||
|
||||
/**
|
||||
* Post Migration Creation.
|
||||
*
|
||||
* Once the migration file has been created, this method will be called, allowing any additional
|
||||
* processing, specific to the template to be performed.
|
||||
*
|
||||
* @param string $migrationFilename The name of the newly created migration.
|
||||
* @param string $className The class name.
|
||||
* @param string $baseClassName The name of the base class.
|
||||
* @return void
|
||||
*/
|
||||
public function postMigrationCreation($migrationFilename, $className, $baseClassName);
|
||||
}
|
||||
39
vendor/topthink/think-migration/phinx/src/Phinx/Migration/IrreversibleMigrationException.php
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* Phinx
|
||||
*
|
||||
* (The MIT license)
|
||||
* Copyright (c) 2015 Rob Morgan
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @package Phinx
|
||||
* @subpackage Phinx\Migration
|
||||
*/
|
||||
namespace Phinx\Migration;
|
||||
|
||||
/**
|
||||
* Exception class thrown when migrations cannot be reversed using the 'change'
|
||||
* feature.
|
||||
*
|
||||
* @author Rob Morgan <robbym@gmail.com>
|
||||
*/
|
||||
class IrreversibleMigrationException extends \Exception
|
||||
{
|
||||
}
|
||||
32
vendor/topthink/think-migration/phinx/src/Phinx/Migration/Migration.template.php.dist
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use $useClassName;
|
||||
|
||||
class $className extends $baseClassName
|
||||
{
|
||||
/**
|
||||
* Change Method.
|
||||
*
|
||||
* Write your reversible migrations using this method.
|
||||
*
|
||||
* More information on writing migrations is available here:
|
||||
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
|
||||
*
|
||||
* The following commands can be used in this method and Phinx will
|
||||
* automatically reverse them when rolling back:
|
||||
*
|
||||
* createTable
|
||||
* renameTable
|
||||
* addColumn
|
||||
* renameColumn
|
||||
* addIndex
|
||||
* addForeignKey
|
||||
*
|
||||
* Remember to call "create()" or "update()" and NOT "save()" when working
|
||||
* with the Table class.
|
||||
*/
|
||||
public function change()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
215
vendor/topthink/think-migration/phinx/src/Phinx/Migration/MigrationInterface.php
vendored
Normal file
@@ -0,0 +1,215 @@
|
||||
<?php
|
||||
/**
|
||||
* Phinx
|
||||
*
|
||||
* (The MIT license)
|
||||
* Copyright (c) 2015 Rob Morgan
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @package Phinx
|
||||
* @subpackage Phinx\Migration
|
||||
*/
|
||||
namespace Phinx\Migration;
|
||||
|
||||
use Phinx\Db\Adapter\AdapterInterface;
|
||||
use Phinx\Db\Table;
|
||||
use think\console\Input as InputInterface;
|
||||
use think\console\Output as OutputInterface;
|
||||
|
||||
/**
|
||||
* Migration interface
|
||||
*
|
||||
* @author Rob Morgan <robbym@gmail.com>
|
||||
*/
|
||||
interface MigrationInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const CHANGE = 'change';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const UP = 'up';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const DOWN = 'down';
|
||||
|
||||
/**
|
||||
* Migrate Up
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up();
|
||||
|
||||
/**
|
||||
* Migrate Down
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down();
|
||||
|
||||
/**
|
||||
* Sets the database adapter.
|
||||
*
|
||||
* @param AdapterInterface $adapter Database Adapter
|
||||
* @return MigrationInterface
|
||||
*/
|
||||
public function setAdapter(AdapterInterface $adapter);
|
||||
|
||||
/**
|
||||
* Gets the database adapter.
|
||||
*
|
||||
* @return AdapterInterface
|
||||
*/
|
||||
public function getAdapter();
|
||||
|
||||
/**
|
||||
* Sets the input object to be used in migration object
|
||||
*
|
||||
* @param InputInterface $input
|
||||
* @return MigrationInterface
|
||||
*/
|
||||
public function setInput(InputInterface $input);
|
||||
|
||||
/**
|
||||
* Gets the input object to be used in migration object
|
||||
*
|
||||
* @return InputInterface
|
||||
*/
|
||||
public function getInput();
|
||||
|
||||
/**
|
||||
* Sets the output object to be used in migration object
|
||||
*
|
||||
* @param OutputInterface $output
|
||||
* @return MigrationInterface
|
||||
*/
|
||||
public function setOutput(OutputInterface $output);
|
||||
|
||||
/**
|
||||
* Gets the output object to be used in migration object
|
||||
*
|
||||
* @return OutputInterface
|
||||
*/
|
||||
public function getOutput();
|
||||
|
||||
/**
|
||||
* Gets the name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName();
|
||||
|
||||
/**
|
||||
* Sets the migration version number.
|
||||
*
|
||||
* @param float $version Version
|
||||
* @return MigrationInterface
|
||||
*/
|
||||
public function setVersion($version);
|
||||
|
||||
/**
|
||||
* Gets the migration version number.
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getVersion();
|
||||
|
||||
/**
|
||||
* Executes a SQL statement and returns the number of affected rows.
|
||||
*
|
||||
* @param string $sql SQL
|
||||
* @return int
|
||||
*/
|
||||
public function execute($sql);
|
||||
|
||||
/**
|
||||
* Executes a SQL statement and returns the result as an array.
|
||||
*
|
||||
* @param string $sql SQL
|
||||
* @return array
|
||||
*/
|
||||
public function query($sql);
|
||||
|
||||
/**
|
||||
* Executes a query and returns only one row as an array.
|
||||
*
|
||||
* @param string $sql SQL
|
||||
* @return array
|
||||
*/
|
||||
public function fetchRow($sql);
|
||||
|
||||
/**
|
||||
* Executes a query and returns an array of rows.
|
||||
*
|
||||
* @param string $sql SQL
|
||||
* @return array
|
||||
*/
|
||||
public function fetchAll($sql);
|
||||
|
||||
/**
|
||||
* Insert data into a table.
|
||||
*
|
||||
* @param string $tableName
|
||||
* @param array $data
|
||||
* @return void
|
||||
*/
|
||||
public function insert($tableName, $data);
|
||||
|
||||
/**
|
||||
* Create a new database.
|
||||
*
|
||||
* @param string $name Database Name
|
||||
* @param array $options Options
|
||||
* @return void
|
||||
*/
|
||||
public function createDatabase($name, $options);
|
||||
|
||||
/**
|
||||
* Drop a database.
|
||||
*
|
||||
* @param string $name Database Name
|
||||
* @return void
|
||||
*/
|
||||
public function dropDatabase($name);
|
||||
|
||||
/**
|
||||
* Checks to see if a table exists.
|
||||
*
|
||||
* @param string $tableName Table Name
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasTable($tableName);
|
||||
|
||||
/**
|
||||
* Returns an instance of the <code>\Table</code> class.
|
||||
*
|
||||
* You can use this class to create and manipulate tables.
|
||||
*
|
||||
* @param string $tableName Table Name
|
||||
* @param array $options Options
|
||||
* @return Table
|
||||
*/
|
||||
public function table($tableName, $options);
|
||||
}
|
||||
215
vendor/topthink/think-migration/phinx/src/Phinx/Seed/AbstractSeed.php
vendored
Normal file
@@ -0,0 +1,215 @@
|
||||
<?php
|
||||
/**
|
||||
* Phinx
|
||||
*
|
||||
* (The MIT license)
|
||||
* Copyright (c) 2015 Rob Morgan
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @package Phinx
|
||||
* @subpackage Phinx\Seed
|
||||
*/
|
||||
namespace Phinx\Seed;
|
||||
|
||||
use Phinx\Db\Table;
|
||||
use Phinx\Db\Adapter\AdapterInterface;
|
||||
use think\console\Input as InputInterface;
|
||||
use think\console\Output as OutputInterface;
|
||||
|
||||
/**
|
||||
* Abstract Seed Class.
|
||||
*
|
||||
* It is expected that the seeds you write extend from this class.
|
||||
*
|
||||
* This abstract class proxies the various database methods to your specified
|
||||
* adapter.
|
||||
*
|
||||
* @author Rob Morgan <robbym@gmail.com>
|
||||
*/
|
||||
abstract class AbstractSeed implements SeedInterface
|
||||
{
|
||||
/**
|
||||
* @var AdapterInterface
|
||||
*/
|
||||
protected $adapter;
|
||||
|
||||
/**
|
||||
* @var InputInterface
|
||||
*/
|
||||
protected $input;
|
||||
|
||||
/**
|
||||
* @var OutputInterface
|
||||
*/
|
||||
protected $output;
|
||||
|
||||
/**
|
||||
* Class Constructor.
|
||||
*
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
*/
|
||||
final public function __construct(InputInterface $input = null, OutputInterface $output = null)
|
||||
{
|
||||
if (!is_null($input)){
|
||||
$this->setInput($input);
|
||||
}
|
||||
if (!is_null($output)){
|
||||
$this->setOutput($output);
|
||||
}
|
||||
|
||||
$this->init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize method.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function init()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setAdapter(AdapterInterface $adapter)
|
||||
{
|
||||
$this->adapter = $adapter;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAdapter()
|
||||
{
|
||||
return $this->adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setInput(InputInterface $input)
|
||||
{
|
||||
$this->input = $input;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getInput()
|
||||
{
|
||||
return $this->input;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setOutput(OutputInterface $output)
|
||||
{
|
||||
$this->output = $output;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getOutput()
|
||||
{
|
||||
return $this->output;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return get_class($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function execute($sql)
|
||||
{
|
||||
return $this->getAdapter()->execute($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query($sql)
|
||||
{
|
||||
return $this->getAdapter()->query($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchRow($sql)
|
||||
{
|
||||
return $this->getAdapter()->fetchRow($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchAll($sql)
|
||||
{
|
||||
return $this->getAdapter()->fetchAll($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function insert($table, $data)
|
||||
{
|
||||
// convert to table object
|
||||
if (is_string($table)) {
|
||||
$table = new Table($table, array(), $this->getAdapter());
|
||||
}
|
||||
return $table->insert($data)->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasTable($tableName)
|
||||
{
|
||||
return $this->getAdapter()->hasTable($tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function table($tableName, $options = array())
|
||||
{
|
||||
return new Table($tableName, $options, $this->getAdapter());
|
||||
}
|
||||
}
|
||||
19
vendor/topthink/think-migration/phinx/src/Phinx/Seed/Seed.template.php.dist
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
use $useClassName;
|
||||
|
||||
class $className extends $baseClassName
|
||||
{
|
||||
/**
|
||||
* Run Method.
|
||||
*
|
||||
* Write your database seeder using this method.
|
||||
*
|
||||
* More information on writing seeders is available here:
|
||||
* http://docs.phinx.org/en/latest/seeding.html
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
166
vendor/topthink/think-migration/phinx/src/Phinx/Seed/SeedInterface.php
vendored
Normal file
@@ -0,0 +1,166 @@
|
||||
<?php
|
||||
/**
|
||||
* Phinx
|
||||
*
|
||||
* (The MIT license)
|
||||
* Copyright (c) 2015 Rob Morgan
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @package Phinx
|
||||
* @subpackage Phinx\Seed
|
||||
*/
|
||||
namespace Phinx\Seed;
|
||||
|
||||
use Phinx\Db\Adapter\AdapterInterface;
|
||||
use Phinx\Db\Table;
|
||||
use think\console\Input as InputInterface;
|
||||
use think\console\Output as OutputInterface;
|
||||
|
||||
/**
|
||||
* Seed interface
|
||||
*
|
||||
* @author Rob Morgan <robbym@gmail.com>
|
||||
*/
|
||||
interface SeedInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const RUN = 'run';
|
||||
|
||||
/**
|
||||
* Run the seeder.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run();
|
||||
|
||||
/**
|
||||
* Sets the database adapter.
|
||||
*
|
||||
* @param AdapterInterface $adapter Database Adapter
|
||||
* @return MigrationInterface
|
||||
*/
|
||||
public function setAdapter(AdapterInterface $adapter);
|
||||
|
||||
/**
|
||||
* Gets the database adapter.
|
||||
*
|
||||
* @return AdapterInterface
|
||||
*/
|
||||
public function getAdapter();
|
||||
|
||||
/**
|
||||
* Sets the input object to be used in migration object
|
||||
*
|
||||
* @param InputInterface $input
|
||||
* @return MigrationInterface
|
||||
*/
|
||||
public function setInput(InputInterface $input);
|
||||
|
||||
/**
|
||||
* Gets the input object to be used in migration object
|
||||
*
|
||||
* @return InputInterface
|
||||
*/
|
||||
public function getInput();
|
||||
|
||||
/**
|
||||
* Sets the output object to be used in migration object
|
||||
*
|
||||
* @param OutputInterface $output
|
||||
* @return MigrationInterface
|
||||
*/
|
||||
public function setOutput(OutputInterface $output);
|
||||
|
||||
/**
|
||||
* Gets the output object to be used in migration object
|
||||
*
|
||||
* @return OutputInterface
|
||||
*/
|
||||
public function getOutput();
|
||||
|
||||
/**
|
||||
* Gets the name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName();
|
||||
|
||||
/**
|
||||
* Executes a SQL statement and returns the number of affected rows.
|
||||
*
|
||||
* @param string $sql SQL
|
||||
* @return int
|
||||
*/
|
||||
public function execute($sql);
|
||||
|
||||
/**
|
||||
* Executes a SQL statement and returns the result as an array.
|
||||
*
|
||||
* @param string $sql SQL
|
||||
* @return array
|
||||
*/
|
||||
public function query($sql);
|
||||
|
||||
/**
|
||||
* Executes a query and returns only one row as an array.
|
||||
*
|
||||
* @param string $sql SQL
|
||||
* @return array
|
||||
*/
|
||||
public function fetchRow($sql);
|
||||
|
||||
/**
|
||||
* Executes a query and returns an array of rows.
|
||||
*
|
||||
* @param string $sql SQL
|
||||
* @return array
|
||||
*/
|
||||
public function fetchAll($sql);
|
||||
|
||||
/**
|
||||
* Insert data into a table.
|
||||
*
|
||||
* @param string $tableName
|
||||
* @param array $data
|
||||
* @return void
|
||||
*/
|
||||
public function insert($tableName, $data);
|
||||
|
||||
/**
|
||||
* Checks to see if a table exists.
|
||||
*
|
||||
* @param string $tableName Table Name
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasTable($tableName);
|
||||
|
||||
/**
|
||||
* Returns an instance of the <code>\Table</code> class.
|
||||
*
|
||||
* You can use this class to create and manipulate tables.
|
||||
*
|
||||
* @param string $tableName Table Name
|
||||
* @param array $options Options
|
||||
* @return Table
|
||||
*/
|
||||
public function table($tableName, $options);
|
||||
}
|
||||
190
vendor/topthink/think-migration/phinx/src/Phinx/Util/Util.php
vendored
Normal file
@@ -0,0 +1,190 @@
|
||||
<?php
|
||||
/**
|
||||
* Phinx
|
||||
*
|
||||
* (The MIT license)
|
||||
* Copyright (c) 2015 Rob Morgan
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @package Phinx
|
||||
* @subpackage Phinx\Util
|
||||
*/
|
||||
namespace Phinx\Util;
|
||||
|
||||
class Util
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const DATE_FORMAT = 'YmdHis';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const MIGRATION_FILE_NAME_PATTERN = '/^\d+_([\w_]+).php$/i';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const SEED_FILE_NAME_PATTERN = '/^([A-Z][a-z0-9]+).php$/i';
|
||||
|
||||
/**
|
||||
* Gets the current timestamp string, in UTC.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getCurrentTimestamp()
|
||||
{
|
||||
$dt = new \DateTime('now', new \DateTimeZone('UTC'));
|
||||
return $dt->format(static::DATE_FORMAT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of all the existing migration class names.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getExistingMigrationClassNames($path)
|
||||
{
|
||||
$classNames = array();
|
||||
|
||||
if (!is_dir($path)) {
|
||||
return $classNames;
|
||||
}
|
||||
|
||||
// filter the files to only get the ones that match our naming scheme
|
||||
$phpFiles = glob($path . DIRECTORY_SEPARATOR . '*.php');
|
||||
|
||||
foreach ($phpFiles as $filePath) {
|
||||
if (preg_match('/([0-9]+)_([_a-z0-9]*).php/', basename($filePath))) {
|
||||
$classNames[] = static::mapFileNameToClassName(basename($filePath));
|
||||
}
|
||||
}
|
||||
|
||||
return $classNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the version from the beginning of a file name.
|
||||
*
|
||||
* @param string $fileName File Name
|
||||
* @return string
|
||||
*/
|
||||
public static function getVersionFromFileName($fileName)
|
||||
{
|
||||
$matches = array();
|
||||
preg_match('/^[0-9]+/', basename($fileName), $matches);
|
||||
return $matches[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn migration names like 'CreateUserTable' into file names like
|
||||
* '12345678901234_create_user_table.php' or 'LimitResourceNamesTo30Chars' into
|
||||
* '12345678901234_limit_resource_names_to_30_chars.php'.
|
||||
*
|
||||
* @param string $className Class Name
|
||||
* @return string
|
||||
*/
|
||||
public static function mapClassNameToFileName($className)
|
||||
{
|
||||
$arr = preg_split('/(?=[A-Z])/', $className);
|
||||
unset($arr[0]); // remove the first element ('')
|
||||
$fileName = static::getCurrentTimestamp() . '_' . strtolower(implode($arr, '_')) . '.php';
|
||||
return $fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn file names like '12345678901234_create_user_table.php' into class
|
||||
* names like 'CreateUserTable'.
|
||||
*
|
||||
* @param string $fileName File Name
|
||||
* @return string
|
||||
*/
|
||||
public static function mapFileNameToClassName($fileName)
|
||||
{
|
||||
$matches = array();
|
||||
if (preg_match(static::MIGRATION_FILE_NAME_PATTERN, $fileName, $matches)) {
|
||||
$fileName = $matches[1];
|
||||
}
|
||||
|
||||
return str_replace(' ', '', ucwords(str_replace('_', ' ', $fileName)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a migration class name is unique regardless of the
|
||||
* timestamp.
|
||||
*
|
||||
* This method takes a class name and a path to a migrations directory.
|
||||
*
|
||||
* Migration class names must be in CamelCase format.
|
||||
* e.g: CreateUserTable or AddIndexToPostsTable.
|
||||
*
|
||||
* Single words are not allowed on their own.
|
||||
*
|
||||
* @param string $className Class Name
|
||||
* @param string $path Path
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isUniqueMigrationClassName($className, $path)
|
||||
{
|
||||
$existingClassNames = static::getExistingMigrationClassNames($path);
|
||||
return !(in_array($className, $existingClassNames));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a migration/seed class name is valid.
|
||||
*
|
||||
* Migration & Seed class names must be in CamelCase format.
|
||||
* e.g: CreateUserTable, AddIndexToPostsTable or UserSeeder.
|
||||
*
|
||||
* Single words are not allowed on their own.
|
||||
*
|
||||
* @param string $className Class Name
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isValidPhinxClassName($className)
|
||||
{
|
||||
return (bool) preg_match('/^([A-Z][a-z0-9]+)+$/', $className);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a migration file name is valid.
|
||||
*
|
||||
* @param string $fileName File Name
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isValidMigrationFileName($fileName)
|
||||
{
|
||||
$matches = array();
|
||||
return preg_match(static::MIGRATION_FILE_NAME_PATTERN, $fileName, $matches);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a seed file name is valid.
|
||||
*
|
||||
* @param string $fileName File Name
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isValidSeedFileName($fileName)
|
||||
{
|
||||
$matches = array();
|
||||
return preg_match(static::SEED_FILE_NAME_PATTERN, $fileName, $matches);
|
||||
}
|
||||
}
|
||||
94
vendor/topthink/think-migration/src/Command.php
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace think\migration;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Phinx\Db\Adapter\AdapterFactory;
|
||||
use think\Config;
|
||||
use think\Db;
|
||||
|
||||
abstract class Command extends \think\console\Command
|
||||
{
|
||||
protected $config = 'database';
|
||||
|
||||
public function getAdapter()
|
||||
{
|
||||
if (isset($this->adapter)) {
|
||||
return $this->adapter;
|
||||
}
|
||||
|
||||
$options = $this->getDbConfig();
|
||||
|
||||
$adapter = AdapterFactory::instance()->getAdapter($options['adapter'], $options);
|
||||
|
||||
if ($adapter->hasOption('table_prefix') || $adapter->hasOption('table_suffix')) {
|
||||
$adapter = AdapterFactory::instance()->getWrapper('prefix', $adapter);
|
||||
}
|
||||
|
||||
$this->adapter = $adapter;
|
||||
|
||||
return $adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据库配置
|
||||
* @return array
|
||||
*/
|
||||
protected function getDbConfig()
|
||||
{
|
||||
$config = Db::connect($this->config)->getConfig();
|
||||
|
||||
if ($config['deploy'] == 0) {
|
||||
$dbConfig = [
|
||||
'adapter' => $config['type'],
|
||||
'host' => $config['hostname'],
|
||||
'name' => $config['database'],
|
||||
'user' => $config['username'],
|
||||
'pass' => $config['password'],
|
||||
'port' => $config['hostport'],
|
||||
'charset' => $config['charset'],
|
||||
'table_prefix' => $config['prefix'],
|
||||
];
|
||||
} else {
|
||||
$dbConfig = [
|
||||
'adapter' => explode(',', $config['type'])[0],
|
||||
'host' => explode(',', $config['hostname'])[0],
|
||||
'name' => explode(',', $config['database'])[0],
|
||||
'user' => explode(',', $config['username'])[0],
|
||||
'pass' => explode(',', $config['password'])[0],
|
||||
'port' => explode(',', $config['hostport'])[0],
|
||||
'charset' => explode(',', $config['charset'])[0],
|
||||
'table_prefix' => explode(',', $config['prefix'])[0],
|
||||
];
|
||||
}
|
||||
|
||||
$dbConfig['default_migration_table'] = $this->getConfig('table', $dbConfig['table_prefix'] . 'migrations');
|
||||
|
||||
return $dbConfig;
|
||||
}
|
||||
|
||||
protected function getConfig($name, $default = null)
|
||||
{
|
||||
$config = Config::get('migration');
|
||||
return isset($config[$name]) ? $config[$name] : $default;
|
||||
}
|
||||
|
||||
protected function verifyMigrationDirectory($path)
|
||||
{
|
||||
if (!is_dir($path)) {
|
||||
throw new InvalidArgumentException(sprintf('Migration directory "%s" does not exist', $path));
|
||||
}
|
||||
|
||||
if (!is_writable($path)) {
|
||||
throw new InvalidArgumentException(sprintf('Migration directory "%s" is not writable', $path));
|
||||
}
|
||||
}
|
||||
}
|
||||
27
vendor/topthink/think-migration/src/Migrator.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace think\migration;
|
||||
|
||||
use Phinx\Migration\AbstractMigration;
|
||||
use think\migration\db\Table;
|
||||
|
||||
class Migrator extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* @param string $tableName
|
||||
* @param array $options
|
||||
* @return Table
|
||||
*/
|
||||
public function table($tableName, $options = [])
|
||||
{
|
||||
return new Table($tableName, $options, $this->getAdapter());
|
||||
}
|
||||
}
|
||||