* @since 2.0 */ class ActionColumn extends Column { /** * @var string the ID of the controller that should handle the actions specified here. * If not set, it will use the currently active controller. This property is mainly used by * [[urlCreator]] to create URLs for different actions. The value of this property will be prefixed * to each action name to form the route of the action. */ public $controller; /** * @var string the template used for composing each cell in the action column. * Tokens enclosed within curly brackets are treated as controller action IDs (also called *button names* * in the context of action column). They will be replaced by the corresponding button rendering callbacks * specified in [[buttons]]. For example, the token `{view}` will be replaced by the result of * the callback `buttons['view']`. If a callback cannot be found, the token will be replaced with an empty string. * @see buttons */ public $template = '{view} {update} {delete}'; /** * @var array button rendering callbacks. The array keys are the button names (without curly brackets), * and the values are the corresponding button rendering callbacks. The callbacks should use the following * signature: * * ```php * function ($url, $model) { * // return the button HTML code * } * ``` * * where `$url` is the URL that the column creates for the button, and `$model` is the model object * being rendered for the current row. */ public $buttons = []; /** * @var callback a callback that creates a button URL using the specified model information. * The signature of the callback should be the same as that of [[createUrl()]]. * If this property is not set, button URLs will be created using [[createUrl()]]. */ public $urlCreator; /** * @inheritdoc */ public function init() { parent::init(); $this->initDefaultButtons(); } /** * Initializes the default button rendering callbacks */ protected function initDefaultButtons() { if (!isset($this->buttons['view'])) { $this->buttons['view'] = function ($url, $model) { return Html::a('', $url, [ 'title' => Yii::t('yii', 'View'), ]); }; } if (!isset($this->buttons['update'])) { $this->buttons['update'] = function ($url, $model) { return Html::a('', $url, [ 'title' => Yii::t('yii', 'Update'), ]); }; } if (!isset($this->buttons['delete'])) { $this->buttons['delete'] = function ($url, $model) { return Html::a('', $url, [ 'title' => Yii::t('yii', 'Delete'), 'data-confirm' => Yii::t('yii', 'Are you sure to delete this item?'), 'data-method' => 'post', ]); }; } } /** * Creates a URL for the given action and model. * This method is called for each button and each row. * @param string $action the button name (or action ID) * @param \yii\db\ActiveRecord $model the data model * @param mixed $key the key associated with the data model * @param integer $index the current row index * @return string the created URL */ public function createUrl($action, $model, $key, $index) { if ($this->urlCreator instanceof Closure) { return call_user_func($this->urlCreator, $action, $model, $key, $index); } else { $params = is_array($key) ? $key : ['id' => $key]; $route = $this->controller ? $this->controller . '/' . $action : $action; return Yii::$app->controller->createUrl($route, $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->buttons[$name])) { $url = $this->createUrl($name, $model, $key, $index); return call_user_func($this->buttons[$name], $url, $model); } else { return ''; } }, $this->template); } }