silverstripe-userforms/code/Form/GridFieldAddClassesButton.php

255 lines
5.9 KiB
PHP

<?php
namespace SilverStripe\UserForms\Form;
use SilverStripe\Control\HTTPResponse_Exception;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridField_ActionProvider;
use SilverStripe\Forms\GridField\GridField_FormAction;
use SilverStripe\Forms\GridField\GridField_HTMLProvider;
/**
* A button which allows objects to be created with a specified classname(s)
*/
class GridFieldAddClassesButton implements GridField_HTMLProvider, GridField_ActionProvider
{
/**
* Name of fragment to insert into
*
* @var string
*/
protected $targetFragment;
/**
* Button title
*
* @var string
*/
protected $buttonName;
/**
* Additonal CSS classes for the button
*
* @var string
*/
protected $buttonClass = null;
/**
* Class names
*
* @var array
*/
protected $modelClasses = null;
/**
* @param array $classes Class or list of classes to create.
* If you enter more than one class, each click of the "add" button will create one of each
* @param string $targetFragment The fragment to render the button into
*/
public function __construct($classes, $targetFragment = 'buttons-before-left')
{
$this->setClasses($classes);
$this->setFragment($targetFragment);
}
/**
* Change the button name
*
* @param string $name
* @return $this
*/
public function setButtonName($name)
{
$this->buttonName = $name;
return $this;
}
/**
* Get the button name
*
* @return string
*/
public function getButtonName()
{
return $this->buttonName;
}
/**
* Gets the fragment name this button is rendered into.
*
* @return string
*/
public function getFragment()
{
return $this->targetFragment;
}
/**
* Sets the fragment name this button is rendered into.
*
* @param string $fragment
* @return GridFieldAddNewInlineButton $this
*/
public function setFragment($fragment)
{
$this->targetFragment = $fragment;
return $this;
}
/**
* Get extra button class
*
* @return string
*/
public function getButtonClass()
{
return $this->buttonClass;
}
/**
* Sets extra CSS classes for this button
*
* @param string $buttonClass
* @return $this
*/
public function setButtonClass($buttonClass)
{
$this->buttonClass = $buttonClass;
return $this;
}
/**
* Get the classes of the objects to create
*
* @return array
*/
public function getClasses()
{
return $this->modelClasses;
}
/**
* Gets the list of classes which can be created, with checks for permissions.
* Will fallback to the default model class for the given DataGrid
*
* @param DataGrid $grid
* @return array
*/
public function getClassesCreate($grid)
{
// Get explicit or fallback class list
$classes = $this->getClasses();
if (empty($classes) && $grid) {
$classes = array($grid->getModelClass());
}
// Filter out classes without permission
return array_filter($classes, function ($class) {
return singleton($class)->canCreate();
});
}
/**
* Specify the classes to create
*
* @param array $classes
*/
public function setClasses($classes)
{
if (!is_array($classes)) {
$classes = $classes ? array($classes) : array();
}
$this->modelClasses = $classes;
}
public function getHTMLFragments($grid)
{
// Check create permission
$singleton = singleton($grid->getModelClass());
if (!$singleton->canCreate()) {
return array();
}
// Get button name
$buttonName = $this->getButtonName();
if (!$buttonName) {
// provide a default button name, can be changed by calling {@link setButtonName()} on this component
$objectName = $singleton->i18n_singular_name();
$buttonName = _t('SilverStripe\\Forms\\GridField\\GridField.Add', 'Add {name}', ['name' => $objectName]);
}
$addAction = GridField_FormAction::create(
$grid,
$this->getAction(),
$buttonName,
$this->getAction(),
array()
);
$addAction->addExtraClass('font-icon-plus btn');
if ($this->getButtonClass()) {
$addAction->addExtraClass($this->getButtonClass());
}
return array(
$this->targetFragment => $addAction->forTemplate()
);
}
/**
* {@inheritDoc}
*/
public function getActions($gridField)
{
return array(
$this->getAction()
);
}
/**
* Get the action suburl for this component
*
* @return string
*/
protected function getAction()
{
return 'add-classes-' . strtolower(implode('-', $this->getClasses()));
}
public function handleAction(GridField $gridField, $actionName, $arguments, $data)
{
switch (strtolower($actionName)) {
case $this->getAction():
return $this->handleAdd($gridField);
default:
return null;
}
}
/**
* Handles adding a new instance of a selected class.
*
* @param GridField $grid
* @return null
*/
public function handleAdd($grid)
{
$classes = $this->getClassesCreate($grid);
if (empty($classes)) {
throw new HTTPResponse_Exception(400);
}
// Add item to gridfield
$list = $grid->getList();
foreach ($classes as $class) {
$item = $class::create();
$item->write();
$list->add($item);
}
// Should trigger a simple reload
return null;
}
}