2012-04-18 23:15:45 +02:00
|
|
|
<?php
|
2013-05-07 10:56:38 +02:00
|
|
|
|
2017-01-17 23:43:11 +01:00
|
|
|
namespace SilverStripe\Widgets\Model;
|
|
|
|
|
|
|
|
use Exception;
|
2017-12-19 02:20:20 +01:00
|
|
|
use SilverStripe\Control\HTTPRequest;
|
2017-01-17 23:43:11 +01:00
|
|
|
use SilverStripe\Core\ClassInfo;
|
|
|
|
use SilverStripe\Core\Injector\Injector;
|
|
|
|
use SilverStripe\Forms\CheckboxField;
|
|
|
|
use SilverStripe\Forms\FieldList;
|
|
|
|
use SilverStripe\Forms\HiddenField;
|
|
|
|
use SilverStripe\Forms\TextField;
|
|
|
|
use SilverStripe\ORM\DataObject;
|
2018-02-01 23:13:52 +01:00
|
|
|
use SilverStripe\ORM\FieldType\DBHTMLText;
|
2017-12-19 02:20:20 +01:00
|
|
|
use SilverStripe\Versioned\Versioned;
|
2017-01-17 23:43:11 +01:00
|
|
|
|
2012-04-18 23:15:45 +02:00
|
|
|
/**
|
2016-07-14 01:24:26 +02:00
|
|
|
* Widgets let CMS authors drag and drop small pieces of functionality into
|
2012-04-18 23:15:45 +02:00
|
|
|
* defined areas of their websites.
|
2016-07-14 01:24:26 +02:00
|
|
|
*
|
2013-05-07 10:56:38 +02:00
|
|
|
* You can use forms in widgets by implementing a {@link WidgetController}.
|
2016-07-14 01:24:26 +02:00
|
|
|
*
|
2017-01-17 23:43:11 +01:00
|
|
|
* See {@link WidgetController} for more information.
|
2016-07-14 01:24:26 +02:00
|
|
|
*
|
2013-05-07 10:56:38 +02:00
|
|
|
* @package widgets
|
2012-04-18 23:15:45 +02:00
|
|
|
*/
|
2015-11-18 05:08:21 +01:00
|
|
|
class Widget extends DataObject
|
|
|
|
{
|
2017-12-19 02:20:20 +01:00
|
|
|
private static $db = [
|
2015-11-18 05:08:21 +01:00
|
|
|
"Title" => "Varchar(255)",
|
|
|
|
"Sort" => "Int",
|
|
|
|
"Enabled" => "Boolean",
|
2017-12-19 02:20:20 +01:00
|
|
|
];
|
2015-11-18 05:08:21 +01:00
|
|
|
|
2017-12-19 02:20:20 +01:00
|
|
|
private static $defaults = [
|
2015-11-18 05:08:21 +01:00
|
|
|
'Enabled' => true,
|
2017-12-19 02:20:20 +01:00
|
|
|
];
|
2015-11-18 05:08:21 +01:00
|
|
|
|
2017-12-19 02:20:20 +01:00
|
|
|
private static $casting = [
|
2015-11-18 05:08:21 +01:00
|
|
|
'CMSTitle' => 'Text',
|
|
|
|
'Description' => 'Text',
|
2017-12-19 02:20:20 +01:00
|
|
|
];
|
2016-07-14 01:24:26 +02:00
|
|
|
|
2017-12-19 02:20:20 +01:00
|
|
|
private static $only_available_in = [];
|
2015-11-18 05:08:21 +01:00
|
|
|
|
2017-12-19 02:20:20 +01:00
|
|
|
private static $has_one = [
|
2017-01-17 23:43:11 +01:00
|
|
|
"Parent" => WidgetArea::class,
|
2017-12-19 02:20:20 +01:00
|
|
|
];
|
2015-11-18 05:08:21 +01:00
|
|
|
|
|
|
|
private static $default_sort = "\"Sort\"";
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
private static $cmsTitle = "Name of this widget";
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
private static $description = "Description of what this widget does.";
|
|
|
|
|
2017-12-19 02:20:20 +01:00
|
|
|
private static $summary_fields = [
|
2015-11-18 05:08:21 +01:00
|
|
|
'CMSTitle' => 'Title'
|
2017-12-19 02:20:20 +01:00
|
|
|
];
|
2015-11-18 05:08:21 +01:00
|
|
|
|
2017-01-17 23:43:11 +01:00
|
|
|
private static $table_name = 'Widget';
|
|
|
|
|
2017-12-19 02:20:20 +01:00
|
|
|
private static $extensions = [
|
2017-12-20 22:45:55 +01:00
|
|
|
Versioned::class,
|
2017-12-19 02:20:20 +01:00
|
|
|
];
|
|
|
|
|
2015-11-18 05:08:21 +01:00
|
|
|
/**
|
|
|
|
* @var WidgetController
|
|
|
|
*/
|
|
|
|
protected $controller;
|
|
|
|
|
|
|
|
public function populateDefaults()
|
|
|
|
{
|
|
|
|
parent::populateDefaults();
|
|
|
|
$this->setField('Title', $this->getTitle());
|
|
|
|
}
|
2016-07-14 01:24:26 +02:00
|
|
|
|
2015-11-18 05:08:21 +01:00
|
|
|
/**
|
|
|
|
* Note: Overloaded in {@link WidgetController}.
|
2016-07-14 01:24:26 +02:00
|
|
|
*
|
2015-11-18 05:08:21 +01:00
|
|
|
* @return string HTML
|
|
|
|
*/
|
|
|
|
public function WidgetHolder()
|
|
|
|
{
|
|
|
|
return $this->renderWith("WidgetHolder");
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Default way to render widget in templates.
|
|
|
|
* @return string HTML
|
|
|
|
*/
|
|
|
|
public function forTemplate($holder = true)
|
|
|
|
{
|
|
|
|
if ($holder) {
|
|
|
|
return $this->WidgetHolder();
|
|
|
|
}
|
2016-07-14 01:24:26 +02:00
|
|
|
|
2015-11-18 05:08:21 +01:00
|
|
|
return $this->Content();
|
|
|
|
}
|
2016-07-14 01:24:26 +02:00
|
|
|
|
2015-11-18 05:08:21 +01:00
|
|
|
/**
|
2016-07-14 01:24:26 +02:00
|
|
|
* Renders the widget content in a custom template with the same name as the
|
2015-11-18 05:08:21 +01:00
|
|
|
* current class. This should be the main point of output customization.
|
2016-07-14 01:24:26 +02:00
|
|
|
*
|
|
|
|
* Invoked from within WidgetHolder.ss, which contains the "framing" around
|
2015-11-18 05:08:21 +01:00
|
|
|
* the custom content, like a title.
|
2016-07-14 01:24:26 +02:00
|
|
|
*
|
2015-11-18 05:08:21 +01:00
|
|
|
* Note: Overloaded in {@link WidgetController}.
|
2016-07-14 01:24:26 +02:00
|
|
|
*
|
2015-11-18 05:08:21 +01:00
|
|
|
* @return string HTML
|
|
|
|
*/
|
|
|
|
public function Content()
|
|
|
|
{
|
2017-08-25 06:46:09 +02:00
|
|
|
return $this->renderWith(array_reverse(ClassInfo::ancestry(__CLASS__)));
|
2015-11-18 05:08:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getCMSTitle()
|
|
|
|
{
|
2017-08-25 06:46:09 +02:00
|
|
|
return _t(__CLASS__ . '.CMSTITLE', $this->config()->get('cmsTitle'));
|
2015-11-18 05:08:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getDescription()
|
|
|
|
{
|
2017-08-25 06:46:09 +02:00
|
|
|
return _t(__CLASS__ . '.DESCRIPTION', $this->config()->get('description'));
|
2015-11-18 05:08:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return string - HTML
|
|
|
|
*/
|
|
|
|
public function DescriptionSegment()
|
|
|
|
{
|
|
|
|
return $this->renderWith('WidgetDescription');
|
|
|
|
}
|
2016-07-14 01:24:26 +02:00
|
|
|
|
2015-11-18 05:08:21 +01:00
|
|
|
/**
|
|
|
|
* @see WidgetController::editablesegment()
|
|
|
|
*
|
|
|
|
* @return string - HTML
|
|
|
|
*/
|
|
|
|
public function EditableSegment()
|
|
|
|
{
|
|
|
|
return $this->renderWith('WidgetEditor');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return FieldList
|
|
|
|
*/
|
|
|
|
public function getCMSFields()
|
|
|
|
{
|
|
|
|
$fields = new FieldList(
|
|
|
|
new TextField('Title', $this->fieldLabel('Title'), null, 255),
|
|
|
|
new CheckboxField('Enabled', $this->fieldLabel('Enabled'))
|
|
|
|
);
|
|
|
|
$this->extend('updateCMSFields', $fields);
|
2016-07-14 01:24:26 +02:00
|
|
|
|
2015-11-18 05:08:21 +01:00
|
|
|
return $fields;
|
|
|
|
}
|
2016-07-14 01:24:26 +02:00
|
|
|
|
2015-11-18 05:08:21 +01:00
|
|
|
/**
|
|
|
|
* @return FieldList
|
|
|
|
*/
|
|
|
|
public function CMSEditor()
|
|
|
|
{
|
|
|
|
$fields = $this->getCMSFields();
|
|
|
|
$outputFields = new FieldList();
|
|
|
|
|
2016-07-18 01:12:46 +02:00
|
|
|
$this->FormID = $this->ID ?: uniqid();
|
2017-01-17 23:43:11 +01:00
|
|
|
$outputFields->push(
|
|
|
|
HiddenField::create(
|
|
|
|
'Widget[' . $this->FormID . '][FormID]',
|
|
|
|
'FormID',
|
|
|
|
$this->FormID
|
|
|
|
)->addExtraClass('formid')
|
|
|
|
);
|
2016-06-21 01:22:38 +02:00
|
|
|
|
2015-11-18 05:08:21 +01:00
|
|
|
foreach ($fields as $field) {
|
|
|
|
$name = $field->getName();
|
|
|
|
$value = $this->getField($name);
|
|
|
|
if ($value) {
|
|
|
|
$field->setValue($value);
|
|
|
|
}
|
2016-06-21 01:22:38 +02:00
|
|
|
$namefiltered = preg_replace("/([A-Za-z0-9\-_]+)/", "Widget[" . $this->FormID . "][\\1]", $name);
|
|
|
|
|
|
|
|
$field->setName($namefiltered);
|
2015-11-18 05:08:21 +01:00
|
|
|
$outputFields->push($field);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $outputFields;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-01-18 02:49:15 +01:00
|
|
|
* A fully qualified class name is returned with underscores instead of backslashes so it is HTML safe. Dashes
|
|
|
|
* can't be used as they're handled in the Javascript for other purposes.
|
|
|
|
*
|
2015-11-18 05:08:21 +01:00
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function ClassName()
|
|
|
|
{
|
2017-08-25 06:46:09 +02:00
|
|
|
return str_replace('\\', '_', get_class($this));
|
2015-11-18 05:08:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function Name()
|
|
|
|
{
|
2016-07-14 01:24:26 +02:00
|
|
|
return "Widget[" . $this->ID . "]";
|
2015-11-18 05:08:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-09-14 04:16:45 +02:00
|
|
|
* @throws Exception If the widget controller's class name couldn't be found
|
2015-11-18 05:08:21 +01:00
|
|
|
*
|
|
|
|
* @return WidgetController
|
|
|
|
*/
|
|
|
|
public function getController()
|
|
|
|
{
|
|
|
|
if ($this->controller) {
|
|
|
|
return $this->controller;
|
|
|
|
}
|
|
|
|
|
2017-08-25 06:46:09 +02:00
|
|
|
foreach (array_reverse(ClassInfo::ancestry(get_class($this))) as $widgetClass) {
|
2015-11-18 05:08:21 +01:00
|
|
|
$controllerClass = "{$widgetClass}Controller";
|
|
|
|
if (class_exists($controllerClass)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!class_exists($controllerClass)) {
|
2017-12-19 02:20:20 +01:00
|
|
|
throw new Exception('Could not find controller class for ' . static::class);
|
2015-11-18 05:08:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
$this->controller = Injector::inst()->create($controllerClass, $this);
|
2017-12-19 02:20:20 +01:00
|
|
|
if (Injector::inst()->has(HTTPRequest::class)) {
|
|
|
|
$this->controller->setRequest(Injector::inst()->get(HTTPRequest::class));
|
|
|
|
}
|
2015-11-18 05:08:21 +01:00
|
|
|
|
|
|
|
return $this->controller;
|
|
|
|
}
|
2016-07-14 01:24:26 +02:00
|
|
|
|
2015-11-18 05:08:21 +01:00
|
|
|
/**
|
|
|
|
* @param array $data
|
|
|
|
*/
|
|
|
|
public function populateFromPostData($data)
|
|
|
|
{
|
|
|
|
$fields = $this->getCMSFields();
|
|
|
|
foreach ($data as $name => $value) {
|
|
|
|
if ($name != "Type") {
|
|
|
|
if ($field = $fields->dataFieldByName($name)) {
|
|
|
|
$field->setValue($value);
|
|
|
|
$field->saveInto($this);
|
|
|
|
} else {
|
|
|
|
$this->setField($name, $value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-07-14 01:24:26 +02:00
|
|
|
|
2015-11-18 05:08:21 +01:00
|
|
|
//Look for checkbox fields not present in the data
|
|
|
|
foreach ($fields as $field) {
|
|
|
|
if ($field instanceof CheckboxField && !array_key_exists($field->getName(), $data)) {
|
|
|
|
$field->setValue(false);
|
|
|
|
$field->saveInto($this);
|
|
|
|
}
|
|
|
|
}
|
2016-07-14 01:24:26 +02:00
|
|
|
|
2015-11-18 05:08:21 +01:00
|
|
|
$this->write();
|
2016-07-14 01:24:26 +02:00
|
|
|
|
2015-11-18 05:08:21 +01:00
|
|
|
// The field must be written to ensure a unique ID.
|
2017-08-25 06:46:09 +02:00
|
|
|
$this->Name = get_class($this) . $this->ID;
|
2015-11-18 05:08:21 +01:00
|
|
|
$this->write();
|
|
|
|
}
|
2012-04-18 23:15:45 +02:00
|
|
|
}
|