2016-08-19 00:51:35 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace SilverStripe\Forms\GridField;
|
|
|
|
|
2017-06-22 12:50:45 +02:00
|
|
|
use SilverStripe\Control\Controller;
|
2018-11-21 04:55:57 +01:00
|
|
|
use SilverStripe\Core\Injector\Injector;
|
2016-08-19 00:51:35 +02:00
|
|
|
use SilverStripe\Forms\Form;
|
|
|
|
use SilverStripe\Forms\FormAction;
|
2018-11-21 04:55:57 +01:00
|
|
|
use SilverStripe\Forms\GridField\FormAction\StateStore;
|
2016-08-19 00:51:35 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* This class is the base class when you want to have an action that alters the state of the
|
|
|
|
* {@link GridField}, rendered as a button element.
|
|
|
|
*/
|
|
|
|
class GridField_FormAction extends FormAction
|
|
|
|
{
|
2018-11-21 04:55:57 +01:00
|
|
|
/**
|
|
|
|
* A common string prefix for keys generated to store form action "state" against
|
|
|
|
*/
|
|
|
|
const STATE_KEY_PREFIX = 'gf_';
|
|
|
|
|
2016-11-29 00:31:16 +01:00
|
|
|
/**
|
|
|
|
* @var GridField
|
|
|
|
*/
|
|
|
|
protected $gridField;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var array
|
|
|
|
*/
|
|
|
|
protected $stateValues;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var array
|
|
|
|
*/
|
2020-04-20 19:58:09 +02:00
|
|
|
protected $args = [];
|
2016-11-29 00:31:16 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $actionName;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var boolean
|
|
|
|
*/
|
|
|
|
public $useButtonTag = true;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param GridField $gridField
|
|
|
|
* @param string $name
|
|
|
|
* @param string $title
|
|
|
|
* @param string $actionName
|
|
|
|
* @param array $args
|
|
|
|
*/
|
|
|
|
public function __construct(GridField $gridField, $name, $title, $actionName, $args)
|
|
|
|
{
|
|
|
|
$this->gridField = $gridField;
|
|
|
|
$this->actionName = $actionName;
|
|
|
|
$this->args = $args;
|
|
|
|
|
|
|
|
parent::__construct($name, $title);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Encode all non-word characters.
|
|
|
|
*
|
|
|
|
* @param string $value
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function nameEncode($value)
|
|
|
|
{
|
2020-04-20 19:58:09 +02:00
|
|
|
return (string)preg_replace_callback('/[^\w]/', [$this, '_nameEncode'], $value);
|
2016-11-29 00:31:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param array $match
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function _nameEncode($match)
|
|
|
|
{
|
|
|
|
return '%' . dechex(ord($match[0]));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
public function getAttributes()
|
|
|
|
{
|
2018-11-21 04:55:57 +01:00
|
|
|
// Determine the state that goes with this action
|
2020-04-20 19:58:09 +02:00
|
|
|
$state = [
|
2016-11-29 00:31:16 +01:00
|
|
|
'grid' => $this->getNameFromParent(),
|
|
|
|
'actionName' => $this->actionName,
|
|
|
|
'args' => $this->args,
|
2020-04-20 19:58:09 +02:00
|
|
|
];
|
2016-11-29 00:31:16 +01:00
|
|
|
|
2018-11-21 04:55:57 +01:00
|
|
|
// Generate a key and attach it to the action name
|
|
|
|
$key = static::STATE_KEY_PREFIX . substr(md5(serialize($state)), 0, 8);
|
|
|
|
// Note: This field needs to be less than 65 chars, otherwise Suhosin security patch will strip it
|
|
|
|
$name = 'action_gridFieldAlterAction?StateID=' . $key;
|
2017-06-22 12:50:45 +02:00
|
|
|
|
2018-11-21 04:55:57 +01:00
|
|
|
// Define attributes
|
2020-04-20 19:58:09 +02:00
|
|
|
$attributes = [
|
2018-11-21 04:55:57 +01:00
|
|
|
'name' => $name,
|
|
|
|
'data-url' => $this->gridField->Link(),
|
|
|
|
'type' => "button",
|
2020-04-20 19:58:09 +02:00
|
|
|
];
|
2018-11-21 04:55:57 +01:00
|
|
|
|
|
|
|
// Create a "store" for the "state" of this action
|
|
|
|
/** @var StateStore $store */
|
2018-11-22 01:05:43 +01:00
|
|
|
$store = Injector::inst()->create(StateStore::class . '.' . $this->gridField->getName());
|
2018-11-21 04:55:57 +01:00
|
|
|
// Store the state and update attributes as required
|
|
|
|
$attributes += $store->save($key, $state);
|
2016-11-29 00:31:16 +01:00
|
|
|
|
2018-11-21 04:55:57 +01:00
|
|
|
// Return attributes
|
2016-11-29 00:31:16 +01:00
|
|
|
return array_merge(
|
|
|
|
parent::getAttributes(),
|
2018-11-21 04:55:57 +01:00
|
|
|
$attributes
|
2016-11-29 00:31:16 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Calculate the name of the gridfield relative to the form.
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
protected function getNameFromParent()
|
|
|
|
{
|
|
|
|
$base = $this->gridField;
|
2020-04-20 19:58:09 +02:00
|
|
|
$name = [];
|
2016-11-29 00:31:16 +01:00
|
|
|
|
|
|
|
do {
|
|
|
|
array_unshift($name, $base->getName());
|
|
|
|
$base = $base->getForm();
|
|
|
|
} while ($base && !($base instanceof Form));
|
|
|
|
|
|
|
|
return implode('.', $name);
|
|
|
|
}
|
2016-08-19 00:51:35 +02:00
|
|
|
}
|