Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

223 lines
7.9KB

  1. <?php
  2. /**
  3. * @link http://www.yiiframework.com/
  4. * @copyright Copyright (c) 2008 Yii Software LLC
  5. * @license http://www.yiiframework.com/license/
  6. */
  7. namespace yii\grid;
  8. use Yii;
  9. use yii\helpers\Html;
  10. use yii\helpers\Url;
  11. /**
  12. * ActionColumn is a column for the [[GridView]] widget that displays buttons for viewing and manipulating the items.
  13. *
  14. * To add an ActionColumn to the gridview, add it to the [[GridView::columns|columns]] configuration as follows:
  15. *
  16. * ```php
  17. * 'columns' => [
  18. * // ...
  19. * [
  20. * 'class' => ActionColumn::className(),
  21. * // you may configure additional properties here
  22. * ],
  23. * ]
  24. * ```
  25. *
  26. * @author Qiang Xue <qiang.xue@gmail.com>
  27. * @since 2.0
  28. */
  29. class ActionColumn extends Column
  30. {
  31. /**
  32. * @inheritdoc
  33. */
  34. public $headerOptions = ['class' => 'action-column'];
  35. /**
  36. * @var string the ID of the controller that should handle the actions specified here.
  37. * If not set, it will use the currently active controller. This property is mainly used by
  38. * [[urlCreator]] to create URLs for different actions. The value of this property will be prefixed
  39. * to each action name to form the route of the action.
  40. */
  41. public $controller;
  42. /**
  43. * @var string the template used for composing each cell in the action column.
  44. * Tokens enclosed within curly brackets are treated as controller action IDs (also called *button names*
  45. * in the context of action column). They will be replaced by the corresponding button rendering callbacks
  46. * specified in [[buttons]]. For example, the token `{view}` will be replaced by the result of
  47. * the callback `buttons['view']`. If a callback cannot be found, the token will be replaced with an empty string.
  48. *
  49. * As an example, to only have the view, and update button you can add the ActionColumn to your GridView columns as follows:
  50. *
  51. * ```php
  52. * ['class' => 'yii\grid\ActionColumn', 'template' => '{view} {update}'],
  53. * ```
  54. *
  55. * @see buttons
  56. */
  57. public $template = '{view} {update} {delete}';
  58. /**
  59. * @var array button rendering callbacks. The array keys are the button names (without curly brackets),
  60. * and the values are the corresponding button rendering callbacks. The callbacks should use the following
  61. * signature:
  62. *
  63. * ```php
  64. * function ($url, $model, $key) {
  65. * // return the button HTML code
  66. * }
  67. * ```
  68. *
  69. * where `$url` is the URL that the column creates for the button, `$model` is the model object
  70. * being rendered for the current row, and `$key` is the key of the model in the data provider array.
  71. *
  72. * You can add further conditions to the button, for example only display it, when the model is
  73. * editable (here assuming you have a status field that indicates that):
  74. *
  75. * ```php
  76. * [
  77. * 'update' => function ($url, $model, $key) {
  78. * return $model->status === 'editable' ? Html::a('Update', $url) : '';
  79. * },
  80. * ],
  81. * ```
  82. */
  83. public $buttons = [];
  84. /** @var array visibility conditions for each button. The array keys are the button names (without curly brackets),
  85. * and the values are the boolean true/false or the anonymous function. When the button name is not specified in
  86. * this array it will be shown by default.
  87. * The callbacks must use the following signature:
  88. *
  89. * ```php
  90. * function ($model, $key, $index) {
  91. * return $model->status === 'editable';
  92. * }
  93. * ```
  94. *
  95. * Or you can pass a boolean value:
  96. *
  97. * ```php
  98. * [
  99. * 'update' => \Yii::$app->user->can('update'),
  100. * ],
  101. * ```
  102. * @since 2.0.7
  103. */
  104. public $visibleButtons = [];
  105. /**
  106. * @var callable a callback that creates a button URL using the specified model information.
  107. * The signature of the callback should be the same as that of [[createUrl()]]
  108. * Since 2.0.10 it can accept additional parameter, which refers to the column instance itself:
  109. *
  110. * ```php
  111. * function (string $action, mixed $model, mixed $key, integer $index, ActionColumn $this) {
  112. * //return string;
  113. * }
  114. * ```
  115. *
  116. * If this property is not set, button URLs will be created using [[createUrl()]].
  117. */
  118. public $urlCreator;
  119. /**
  120. * @var array html options to be applied to the [[initDefaultButtons()|default buttons]].
  121. * @since 2.0.4
  122. */
  123. public $buttonOptions = [];
  124. /**
  125. * @inheritdoc
  126. */
  127. public function init()
  128. {
  129. parent::init();
  130. $this->initDefaultButtons();
  131. }
  132. /**
  133. * Initializes the default button rendering callbacks.
  134. */
  135. protected function initDefaultButtons()
  136. {
  137. if (!isset($this->buttons['view'])) {
  138. $this->buttons['view'] = function ($url, $model, $key) {
  139. $options = array_merge([
  140. 'title' => Yii::t('yii', 'View'),
  141. 'aria-label' => Yii::t('yii', 'View'),
  142. 'data-pjax' => '0',
  143. ], $this->buttonOptions);
  144. return Html::a('<span class="glyphicon glyphicon-eye-open"></span>', $url, $options);
  145. };
  146. }
  147. if (!isset($this->buttons['update'])) {
  148. $this->buttons['update'] = function ($url, $model, $key) {
  149. $options = array_merge([
  150. 'title' => Yii::t('yii', 'Update'),
  151. 'aria-label' => Yii::t('yii', 'Update'),
  152. 'data-pjax' => '0',
  153. ], $this->buttonOptions);
  154. return Html::a('<span class="glyphicon glyphicon-pencil"></span>', $url, $options);
  155. };
  156. }
  157. if (!isset($this->buttons['delete'])) {
  158. $this->buttons['delete'] = function ($url, $model, $key) {
  159. $options = array_merge([
  160. 'title' => Yii::t('yii', 'Delete'),
  161. 'aria-label' => Yii::t('yii', 'Delete'),
  162. 'data-confirm' => Yii::t('yii', 'Are you sure you want to delete this item?'),
  163. 'data-method' => 'post',
  164. 'data-pjax' => '0',
  165. ], $this->buttonOptions);
  166. return Html::a('<span class="glyphicon glyphicon-trash"></span>', $url, $options);
  167. };
  168. }
  169. }
  170. /**
  171. * Creates a URL for the given action and model.
  172. * This method is called for each button and each row.
  173. * @param string $action the button name (or action ID)
  174. * @param \yii\db\ActiveRecord $model the data model
  175. * @param mixed $key the key associated with the data model
  176. * @param integer $index the current row index
  177. * @return string the created URL
  178. */
  179. public function createUrl($action, $model, $key, $index)
  180. {
  181. if (is_callable($this->urlCreator)) {
  182. return call_user_func($this->urlCreator, $action, $model, $key, $index, $this);
  183. } else {
  184. $params = is_array($key) ? $key : ['id' => (string) $key];
  185. $params[0] = $this->controller ? $this->controller . '/' . $action : $action;
  186. return Url::toRoute($params);
  187. }
  188. }
  189. /**
  190. * @inheritdoc
  191. */
  192. protected function renderDataCellContent($model, $key, $index)
  193. {
  194. return preg_replace_callback('/\\{([\w\-\/]+)\\}/', function ($matches) use ($model, $key, $index) {
  195. $name = $matches[1];
  196. if (isset($this->visibleButtons[$name])) {
  197. $isVisible = $this->visibleButtons[$name] instanceof \Closure
  198. ? call_user_func($this->visibleButtons[$name], $model, $key, $index)
  199. : $this->visibleButtons[$name];
  200. } else {
  201. $isVisible = true;
  202. }
  203. if ($isVisible && isset($this->buttons[$name])) {
  204. $url = $this->createUrl($name, $model, $key, $index);
  205. return call_user_func($this->buttons[$name], $url, $model, $key);
  206. } else {
  207. return '';
  208. }
  209. }, $this->template);
  210. }
  211. }