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.

246 lines
7.4 KiB

  1. <?php
  2. /*
  3. * The MIT License
  4. *
  5. * Copyright 2019 Blobt.
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy
  8. * of this software and associated documentation files (the "Software"), to deal
  9. * in the Software without restriction, including without limitation the rights
  10. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. * copies of the Software, and to permit persons to whom the Software is
  12. * furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in
  15. * all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. * THE SOFTWARE.
  24. */
  25. namespace iron\grid;
  26. use Yii;
  27. use yii\helpers\Html;
  28. use yii\helpers\Url;
  29. use blobt\grid\Column;
  30. class ActionColumn extends Column
  31. {
  32. public $config = [
  33. [
  34. 'name' => 'view',
  35. 'icon' => 'list',
  36. 'title' => '详情',
  37. ],
  38. [
  39. 'name' => 'update',
  40. 'icon' => 'pencil',
  41. 'title' => '修改'
  42. ],
  43. [
  44. 'name' => 'delete',
  45. 'icon' => 'trash',
  46. 'title' => '删除',
  47. 'contents' => '确定删除?'
  48. ]
  49. ];
  50. /**
  51. * @var string 处理的控制器ID
  52. */
  53. public $controller;
  54. /**
  55. * @var string 按钮模板
  56. */
  57. public $template = '';
  58. /**
  59. * @var array 以按钮名为键,以匿名函数为值,通过匿名函数返回html,用来控制按钮的表现形式
  60. * 匿名函数必须遵循以下申明方式:
  61. *
  62. * ```php
  63. * function ($url, $model, $key) {
  64. * // return the button HTML code
  65. * }
  66. * ```
  67. *
  68. * - `$url`: 按钮的跳转路径
  69. * - `$model`: 每行的模型
  70. * - `$key`: id值
  71. *
  72. * 使用案例:
  73. * ```php
  74. * [
  75. * 'update' => function ($url, $model, $key) {
  76. * return $model->status === 'editable' ? Html::a('Update', $url) : '';
  77. * },
  78. * ],
  79. *
  80. */
  81. public $buttons = [];
  82. /** @var array 和上述$buttons功能类似,只是匿名函数返回布尔,只控制是否展示
  83. * 匿名函数必须遵循以下申明方式:
  84. *
  85. * ```php
  86. * function ($model, $key, $index) {
  87. * return $model->status === 'editable';
  88. * }
  89. * ```
  90. *
  91. * 使用案例:
  92. * ```php
  93. * [
  94. * 'update' => \Yii::$app->user->can('update'),
  95. * ],
  96. * ```
  97. * @since 2.0.7
  98. */
  99. public $visibleButtons = [];
  100. /**
  101. * @var callable 匿名函数,用作控制按钮Url
  102. *
  103. * 匿名函数必须遵循以下申明方式:
  104. * ```php
  105. * function (string $action, mixed $model, mixed $key, integer $index, ActionColumn $this) {
  106. * //return string;
  107. * }
  108. * ```
  109. *
  110. * 如果没有设置,默认使用本类的[[createUrl()]].
  111. */
  112. public $urlCreator;
  113. /**
  114. * @var array 按钮的html属性
  115. */
  116. public $buttonOptions = [];
  117. /**
  118. * {@inheritdoc}
  119. */
  120. public function init()
  121. {
  122. parent::init();
  123. foreach ($this->config as $config) {
  124. if (isset($config['contents'])) {
  125. $options = ['alertify-confirm' => Yii::t('yii', "{$config['contents']}?")];
  126. } else {
  127. $options = [];
  128. }
  129. if (isset($config['icon'])) {
  130. $icon = $config['icon'];
  131. } else {
  132. $icon = 'th-large';
  133. }
  134. if (isset($config['title'])) {
  135. $title = $config['title'];
  136. } else {
  137. $title = $config['name'];
  138. }
  139. if (isset($config['hide'])) {
  140. $this->visibleButtons($config['name'], $config['hide']);
  141. }
  142. $this->initButton($config['name'], $icon, $options, $title);
  143. $this->template .= " {{$config['name']}}";
  144. }
  145. }
  146. /**
  147. * 初始化按钮
  148. * @param string $name
  149. * @param string $iconName
  150. * @param array $additionalOptions 附加html属性
  151. */
  152. protected function initButton($name, $iconName, $additionalOptions = [], $title = '')
  153. {
  154. $this->buttons[$name] = function ($url, $model, $key) use ($name, $iconName, $additionalOptions, $title) {
  155. $title = $title ?: Yii::t('yii', $name);
  156. $options = array_merge([
  157. 'title' => $title,
  158. 'aria-label' => $title,
  159. 'data-pjax' => '0',
  160. ], $additionalOptions, $this->buttonOptions);
  161. $icon = Html::tag('span', '', ['class' => "oi oi-$iconName"]);
  162. return Html::a($icon, $url, $options);
  163. };
  164. }
  165. protected function visibleButtons($name, $config)
  166. {
  167. $this->visibleButtons[$name] = function ($model, $key, $index) use ($config) {
  168. $attributes = $config['attributes'];
  169. $values = $config['values'];
  170. if (isset($config['rule']) && $config['rule'] == 'or') {
  171. foreach ($attributes as $k => $attribute) {
  172. if ($model->$attribute == $values[$k]) {
  173. return false;
  174. }
  175. }
  176. return true;
  177. }else{
  178. foreach ($attributes as $k => $attribute) {
  179. if ($model->$attribute != $values[$k]) {
  180. return true;
  181. }
  182. }
  183. return false;
  184. }
  185. };
  186. }
  187. /**
  188. * 通过给定的action和model创建一个URL.
  189. *
  190. * @param string $action 按钮名
  191. * @param \yii\db\ActiveRecordInterface $model 数据模型
  192. * @param mixed $key 模型的ID
  193. * @param int $index 行号
  194. * @return string the created URL
  195. */
  196. public function createUrl($action, $model, $key, $index)
  197. {
  198. if (is_callable($this->urlCreator)) {
  199. return call_user_func($this->urlCreator, $action, $model, $key, $index, $this);
  200. }
  201. $params = is_array($key) ? $key : ['id' => (string)$key];
  202. $params[0] = $this->controller ? $this->controller . '/' . $action : $action;
  203. return Url::toRoute($params);
  204. }
  205. /**
  206. * {@inheritdoc}
  207. */
  208. protected function renderDataCellContent($model, $key, $index)
  209. {
  210. return preg_replace_callback('/\\{([\w\-\/]+)\\}/', function ($matches) use ($model, $key, $index) {
  211. $name = $matches[1];
  212. if (isset($this->visibleButtons[$name])) {
  213. $isVisible = $this->visibleButtons[$name] instanceof \Closure ? call_user_func($this->visibleButtons[$name], $model, $key, $index) : $this->visibleButtons[$name];
  214. } else {
  215. $isVisible = true;
  216. }
  217. if ($isVisible && isset($this->buttons[$name])) {
  218. $url = $this->createUrl($name, $model, $key, $index);
  219. return call_user_func($this->buttons[$name], $url, $model, $key);
  220. }
  221. return '';
  222. }, $this->template);
  223. }
  224. }