You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

277 lines
8.3 KiB

<?php
/*
* The MIT License
*
* Copyright 2019 Blobt.
*
* 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.
*/
namespace iron\grid;
use Yii;
use yii\helpers\Html;
use yii\helpers\Url;
use blobt\grid\Column;
class ActionColumn extends Column
{
/**
* @var array 配置按钮配置,通过配置参数控制按钮的标题,url,图标以及确认框内容和隐藏条件
*
* ```php
*
* - `$title`: 按钮的标题
* - `$name`: 按钮的跳转路径
* - `$icon`: 按钮图标
* - `$contents`: 确认框内容
* - `$hide`: array 隐藏条件
*
* 使用案例:
* ```php
* [
* 'name' => 'delete',
* 'icon' => 'trash',
* 'title' => '删除',
* 'contents' => '确定删除?'
* //attributes 和 values 两数组对应元素按规则匹配成功时候隐藏该按钮
* 'hide'=>[
* 'attributes'=>['status'],//模型属性
* 'values'=>[1],//属性值
* 'rule'=>'or' //与或规则 只填 or 或 and
* ]
* ]
*
*/
public $config = [
[
'name' => 'view',
'icon' => 'list',
'title' => '详情',
],
[
'name' => 'update',
'icon' => 'pencil',
'title' => '修改'
],
[
'name' => 'delete',
'icon' => 'trash',
'title' => '删除',
'contents' => '确定删除?'
]
];
/**
* @var string 处理的控制器ID
*/
public $controller;
/**
* @var string 按钮模板
*/
public $template = '';
/**
* @var array 以按钮名为键,以匿名函数为值,通过匿名函数返回html,用来控制按钮的表现形式
* 匿名函数必须遵循以下申明方式:
*
* ```php
* function ($url, $model, $key) {
* // return the button HTML code
* }
* ```
*
* - `$url`: 按钮的跳转路径
* - `$model`: 每行的模型
* - `$key`: id值
*
* 使用案例:
* ```php
* [
* 'update' => function ($url, $model, $key) {
* return $model->status === 'editable' ? Html::a('Update', $url) : '';
* },
* ],
*
*/
public $buttons = [];
/** @var array 和上述$buttons功能类似,只是匿名函数返回布尔,只控制是否展示
* 匿名函数必须遵循以下申明方式:
*
* ```php
* function ($model, $key, $index) {
* return $model->status === 'editable';
* }
* ```
*
* 使用案例:
* ```php
* [
* 'update' => \Yii::$app->user->can('update'),
* ],
* ```
* @since 2.0.7
*/
public $visibleButtons = [];
/**
* @var callable 匿名函数,用作控制按钮Url
*
* 匿名函数必须遵循以下申明方式:
* ```php
* function (string $action, mixed $model, mixed $key, integer $index, ActionColumn $this) {
* //return string;
* }
* ```
*
* 如果没有设置,默认使用本类的[[createUrl()]].
*/
public $urlCreator;
/**
* @var array 按钮的html属性
*/
public $buttonOptions = [];
/**
* {@inheritdoc}
*/
public function init()
{
parent::init();
foreach ($this->config as $config) {
if (isset($config['contents'])) {
$options = ['alertify-confirm' => Yii::t('yii', "{$config['contents']}?")];
} else {
$options = [];
}
if (isset($config['icon'])) {
$icon = $config['icon'];
} else {
$icon = 'th-large';
}
if (isset($config['title'])) {
$title = $config['title'];
} else {
$title = $config['name'];
}
if (isset($config['hide'])) {
$this->visibleButtons($config['name'], $config['hide']);
}
$this->initButton($config['name'], $icon, $options, $title);
$this->template .= " {{$config['name']}}";
}
}
/**
* 初始化按钮
* @param string $name
* @param string $iconName
* @param array $additionalOptions 附加html属性
*/
protected function initButton($name, $iconName, $additionalOptions = [], $title = '')
{
$this->buttons[$name] = function ($url, $model, $key) use ($name, $iconName, $additionalOptions, $title) {
$title = $title ?: Yii::t('yii', $name);
$options = array_merge([
'title' => $title,
'aria-label' => $title,
'data-pjax' => '0',
], $additionalOptions, $this->buttonOptions);
$icon = Html::tag('span', '', ['class' => "oi oi-$iconName"]);
return Html::a($icon, $url, $options);
};
}
/**
* @param string $name
* @param array $config 隐藏配置
* 验证按钮的显示隐藏规则
*/
protected function visibleButtons($name, $config)
{
$this->visibleButtons[$name] = function ($model, $key, $index) use ($config) {
$attributes = $config['attributes'];
$values = $config['values'];
if (isset($config['rule']) && $config['rule'] == 'or') {
foreach ($attributes as $k => $attribute) {
if ($model->$attribute == $values[$k]) {
return false;
}
}
return true;
}else{
foreach ($attributes as $k => $attribute) {
if ($model->$attribute != $values[$k]) {
return true;
}
}
return false;
}
};
}
/**
* 通过给定的action和model创建一个URL.
*
* @param string $action 按钮名
* @param \yii\db\ActiveRecordInterface $model 数据模型
* @param mixed $key 模型的ID
* @param int $index 行号
* @return string the created URL
*/
public function createUrl($action, $model, $key, $index)
{
if (is_callable($this->urlCreator)) {
return call_user_func($this->urlCreator, $action, $model, $key, $index, $this);
}
$params = is_array($key) ? $key : ['id' => (string)$key];
$params[0] = $this->controller ? $this->controller . '/' . $action : $action;
return Url::toRoute($params);
}
/**
* {@inheritdoc}
*/
protected function renderDataCellContent($model, $key, $index)
{
return preg_replace_callback('/\\{([\w\-\/]+)\\}/', function ($matches) use ($model, $key, $index) {
$name = $matches[1];
if (isset($this->visibleButtons[$name])) {
$isVisible = $this->visibleButtons[$name] instanceof \Closure ? call_user_func($this->visibleButtons[$name], $model, $key, $index) : $this->visibleButtons[$name];
} else {
$isVisible = true;
}
if ($isVisible && isset($this->buttons[$name])) {
$url = $this->createUrl($name, $model, $key, $index);
return call_user_func($this->buttons[$name], $url, $model, $key);
}
return '';
}, $this->template);
}
}