From 8a72b32e95e759fe2c22dd807c51ab8e962d0dbb Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Wed, 18 Apr 2012 23:21:59 +0200 Subject: [PATCH] API CHANGE Moved Widget API to new module (https://github.com/silverstripe/silverstripe-widgets), incl. WidgetArea and WidgetAreaEditor classes --- code/widgets/Widget.php | 232 --------- code/widgets/WidgetArea.php | 72 --- code/widgets/WidgetAreaEditor.php | 142 ------ javascript/WidgetAreaEditor.js | 282 ----------- templates/WidgetArea.ss | 3 - templates/WidgetAreaEditor.ss | 32 -- templates/WidgetDescription.ss | 6 - templates/WidgetEditor.ss | 12 - templates/WidgetHolder.ss | 4 - tests/widgets/WidgetAreaEditorTest.php | 471 ------------------- tests/widgets/WidgetControllerTest.php | 88 ---- tests/widgets/WidgetControllerTest.yml | 10 - tests/widgets/WidgetControllerTestPage.php | 27 -- tests/widgets/WidgetControllerTestPage.ss | 1 - tests/widgets/WidgetControllerTest_Widget.ss | 1 - 15 files changed, 1383 deletions(-) delete mode 100644 code/widgets/Widget.php delete mode 100644 code/widgets/WidgetArea.php delete mode 100644 code/widgets/WidgetAreaEditor.php delete mode 100644 javascript/WidgetAreaEditor.js delete mode 100644 templates/WidgetArea.ss delete mode 100644 templates/WidgetAreaEditor.ss delete mode 100644 templates/WidgetDescription.ss delete mode 100644 templates/WidgetEditor.ss delete mode 100644 templates/WidgetHolder.ss delete mode 100644 tests/widgets/WidgetAreaEditorTest.php delete mode 100644 tests/widgets/WidgetControllerTest.php delete mode 100644 tests/widgets/WidgetControllerTest.yml delete mode 100644 tests/widgets/WidgetControllerTestPage.php delete mode 100644 tests/widgets/WidgetControllerTestPage.ss delete mode 100644 tests/widgets/WidgetControllerTest_Widget.ss diff --git a/code/widgets/Widget.php b/code/widgets/Widget.php deleted file mode 100644 index 8ef5b7af..00000000 --- a/code/widgets/Widget.php +++ /dev/null @@ -1,232 +0,0 @@ - "Int", - "Enabled" => "Boolean" - ); - - static $defaults = array( - 'Enabled' => true - ); - - static $has_one = array( - "Parent" => "WidgetArea", - ); - - static $has_many = array(); - static $many_many = array(); - static $belongs_many_many = array(); - - static $default_sort = "\"Sort\""; - - static $title = "Widget Title"; - static $cmsTitle = "Name of this widget"; - static $description = "Description of what this widget does."; - - function getCMSFields() { - $fields = new FieldList(); - $this->extend('updateCMSFields', $fields); - return $fields; - } - - /** - * Note: Overloaded in {@link Widget_Controller}. - * - * @return string HTML - */ - function WidgetHolder() { - return $this->renderWith("WidgetHolder"); - } - - /** - * Renders the widget content in a custom template with the same name as the current class. - * This should be the main point of output customization. - * - * Invoked from within WidgetHolder.ss, which contains - * the "framing" around the custom content, like a title. - * - * Note: Overloaded in {@link Widget_Controller}. - * - * @return string HTML - */ - function Content() { - return $this->renderWith(array_reverse(ClassInfo::ancestry($this->class))); - } - - function Title() { - return Object::get_static($this->class, 'title'); - } - - function CMSTitle() { - return Object::get_static($this->class, 'cmsTitle'); - } - - function Description() { - return Object::get_static($this->class, 'description'); - } - - function DescriptionSegment() { - return $this->renderWith('WidgetDescription'); - } - - /** - * @see Widget_Controller->editablesegment() - */ - function EditableSegment() { - return $this->renderWith('WidgetEditor'); - } - - function CMSEditor() { - $output = ''; - $fields = $this->getCMSFields(); - foreach($fields as $field) { - $name = $field->Name(); - $field->setValue($this->getField($name)); - $renderedField = $field->FieldHolder(); - $renderedField = preg_replace("/name=\"([A-Za-z0-9\-_]+)\"/", "name=\"Widget[" . $this->ID . "][\\1]\"", $renderedField); - $renderedField = preg_replace("/id=\"([A-Za-z0-9\-_]+)\"/", "id=\"Widget[" . $this->ID . "][\\1]\"", $renderedField); - $output .= $renderedField; - } - return $output; - } - - function ClassName() { - return $this->class; - } - - function Name() { - return "Widget[".$this->ID."]"; - } - - function populateFromPostData($data) { - foreach($data as $name => $value) { - if($name != "Type") { - $this->setField($name, $value); - } - } - - $this->write(); - - // The field must be written to ensure a unique ID. - $this->Name = $this->class.$this->ID; - $this->write(); - } - -} - -/** - * Optional controller for every widget which has its own logic, - * e.g. in forms. It always handles a single widget, usually passed - * in as a database identifier through the controller URL. - * Needs to be constructed as a nested controller - * within a {@link ContentController}. - * - * ## Forms - * You can add forms like in any other SilverStripe controller. - * If you need access to the widget from within a form, - * you can use `$this->controller->getWidget()` inside the form logic. - * Note: Widget controllers currently only work on {@link Page} objects, - * because the logic is implemented in {@link ContentController->handleWidget()}. - * Copy this logic and the URL rules to enable it for other controllers. - * - * @package cms - * @subpackage widgets - */ -class Widget_Controller extends Controller { - - /** - * @var Widget - */ - protected $widget; - - static $allowed_actions = array( - 'editablesegment' - ); - - function __construct($widget = null) { - // TODO This shouldn't be optional, is only necessary for editablesegment() - if($widget) { - $this->widget = $widget; - $this->failover = $widget; - } - - parent::__construct(); - } - - public function Link($action = null) { - $segment = Controller::join_links('widget', ($this->widget ? $this->widget->ID : null), $action); - - if(Director::get_current_page()) { - return Director::get_current_page()->Link($segment); - } else { - return Controller::curr()->Link($segment); - } - } - - /** - * @return Widget - */ - function getWidget() { - return $this->widget; - } - - /** - * Overloaded from {@link Widget->Content()} - * to allow for controller/form linking. - * - * @return string HTML - */ - function Content() { - return $this->renderWith(array_reverse(ClassInfo::ancestry($this->widget->class))); - } - - /** - * Overloaded from {@link Widget->WidgetHolder()} - * to allow for controller/form linking. - * - * @return string HTML - */ - function WidgetHolder() { - return $this->renderWith("WidgetHolder"); - } - - /** - * Uses the `WidgetEditor.ss` template and {@link Widget->editablesegment()} - * to render a administrator-view of the widget. It is assumed that this - * view contains form elements which are submitted and saved through {@link WidgetAreaEditor} - * within the CMS interface. - * - * @return string HTML - */ - function editablesegment() { - $className = $this->urlParams['ID']; - if(class_exists($className) && is_subclass_of($className, 'Widget')) { - $obj = new $className(); - return $obj->EditableSegment(); - } else { - user_error("Bad widget class: $className", E_USER_WARNING); - return "Bad widget class name given"; - } - } -} - -/** - * @package cms - * @subpackage widgets - */ -class Widget_TreeDropdownField extends TreeDropdownField { - function FieldHolder($properties = array()) {} - function Field($properties = array()) {} -} - diff --git a/code/widgets/WidgetArea.php b/code/widgets/WidgetArea.php deleted file mode 100644 index a3f1d9ea..00000000 --- a/code/widgets/WidgetArea.php +++ /dev/null @@ -1,72 +0,0 @@ - "Widget" - ); - - static $many_many = array(); - - static $belongs_many_many = array(); - - public $template = __CLASS__; - - /** - * Used in template instead of {@link Widgets()} - * to wrap each widget in its controller, making - * it easier to access and process form logic - * and actions stored in {@link Widget_Controller}. - * - * @return SS_List Collection of {@link Widget_Controller} - */ - function WidgetControllers() { - $controllers = new ArrayList(); - - foreach($this->ItemsToRender() as $widget) { - // find controller - $controllerClass = ''; - foreach(array_reverse(ClassInfo::ancestry($widget->class)) as $widgetClass) { - $controllerClass = "{$widgetClass}_Controller"; - if(class_exists($controllerClass)) break; - } - $controller = new $controllerClass($widget); - $controller->init(); - $controllers->push($controller); - } - - return $controllers; - } - - function Items() { - return $this->getComponents('Widgets'); - } - - function ItemsToRender() { - return $this->getComponents('Widgets', "\"Widget\".\"Enabled\" = 1"); - } - - function forTemplate() { - return $this->renderWith($this->template); - } - - function setTemplate($template) { - $this->template = $template; - } - - function onBeforeDelete() { - parent::onBeforeDelete(); - foreach($this->Widgets() as $widget) { - $widget->delete(); - } - } -} - diff --git a/code/widgets/WidgetAreaEditor.php b/code/widgets/WidgetAreaEditor.php deleted file mode 100644 index 9c5dcd11..00000000 --- a/code/widgets/WidgetAreaEditor.php +++ /dev/null @@ -1,142 +0,0 @@ -MaxWidgets = $maxWidgets; - $this->widgetClasses = $widgetClasses; - - parent::__construct($name); - } - - function FieldHolder($properties = array()) { - Requirements::css(CMS_DIR . '/css/WidgetAreaEditor.css'); - Requirements::javascript(THIRDPARTY_DIR . "/prototype/prototype.js"); - Requirements::javascript(THIRDPARTY_DIR . '/behaviour/behaviour.js'); - Requirements::javascript(CMS_DIR . '/javascript/WidgetAreaEditor.js'); - - return $this->renderWith("WidgetAreaEditor"); - } - - function AvailableWidgets() { - - $widgets= new ArrayList(); - - foreach($this->widgetClasses as $widgetClass) { - $classes = ClassInfo::subclassesFor($widgetClass); - array_shift($classes); - foreach($classes as $class) { - $widgets->push(singleton($class)); - } - } - - return $widgets; - } - - function UsedWidgets() { - // Call class_exists() to load Widget.php earlier and avoid a segfault - class_exists('Widget'); - - $relationName = $this->name; - $widgets = $this->form->getRecord()->getComponent($relationName)->Items(); - return $widgets; - } - - function IdxField() { - return $this->id() . 'ID'; - } - - function Value() { - $relationName = $this->name; - return $this->form->getRecord()->getComponent($relationName)->ID; - } - - function saveInto(DataObjectInterface $record) { - $name = $this->name; - $idName = $name . "ID"; - - $widgetarea = $record->getComponent($name); - $widgetarea->write(); - - $record->$idName = $widgetarea->ID; - - $widgets = $widgetarea->Items(); - - // store the field IDs and delete the missing fields - // alternatively, we could delete all the fields and re add them - $missingWidgets = array(); - - if($widgets) { - foreach($widgets as $existingWidget) { - $missingWidgets[$existingWidget->ID] = $existingWidget; - } - } - - if(isset($_REQUEST['Widget'])) { - foreach(array_keys($_REQUEST['Widget']) as $widgetAreaName) { - if ($widgetAreaName !== $this->name) { - continue; - } - - foreach(array_keys($_REQUEST['Widget'][$widgetAreaName]) as $newWidgetID) { - $newWidgetData = $_REQUEST['Widget'][$widgetAreaName][$newWidgetID]; - - // Sometimes the id is "new-1" or similar, ensure this doesn't get into the query - if(!is_numeric($newWidgetID)) { - $newWidgetID = 0; - } - - // \"ParentID\" = '0' is for the new page - $widget = DataObject::get_one( - 'Widget', - "(\"ParentID\" = '{$record->$name()->ID}' OR \"ParentID\" = '0') AND \"Widget\".\"ID\" = '$newWidgetID'" - ); - - - // check if we are updating an existing widget - if($widget && isset($missingWidgets[$widget->ID])) { - unset($missingWidgets[$widget->ID]); - } - - // create a new object - if(!$widget && !empty($newWidgetData['Type']) && class_exists($newWidgetData['Type'])) { - $widget = new $newWidgetData['Type'](); - $widget->ID = 0; - $widget->ParentID = $record->$name()->ID; - - if(!is_subclass_of($widget, 'Widget')) { - $widget = null; - } - } - - if($widget) { - if($widget->ParentID == 0) { - $widget->ParentID = $record->$name()->ID; - } - // echo "Saving $widget->ID into $name/$widget->ParentID\n
"; - $widget->populateFromPostData($newWidgetData); - } - } - } - } - - // remove the fields not saved - if($missingWidgets) { - foreach($missingWidgets as $removedWidget) { - if(isset($removedWidget) && is_numeric($removedWidget->ID)) { - $removedWidget->delete(); - } - } - } - } -} diff --git a/javascript/WidgetAreaEditor.js b/javascript/WidgetAreaEditor.js deleted file mode 100644 index ac2f156b..00000000 --- a/javascript/WidgetAreaEditor.js +++ /dev/null @@ -1,282 +0,0 @@ -// Shortcut-function (until we update to Prototye v1.5) -if(typeof $$ != "Function") $$ = document.getElementsBySelector; - -/** - * File: WidgetAreaEditor.js - */ - -/** - * Class: WidgetAreaEditorClass - */ -WidgetAreaEditorClass = Class.create(); -WidgetAreaEditorClass.prototype = { - initialize: function() { - this.name = this.getAttribute('name'); - this.rewriteWidgetAreaAttributes(); - UsedWidget.applyToChildren(document.getElementById('usedWidgets-'+this.name), 'div.Widget'); - - var availableWidgets = document.getElementById('availableWidgets-'+this.name).childNodes; - - for(var i = 0; i < availableWidgets.length; i++) { - var widget = availableWidgets[i]; - // Don't run on comments, whitespace, etc - if (widget.nodeType == 1) { - // Gotta change their ID's because otherwise we get clashes between two tabs - widget.id = widget.id + '-'+this.name; - } - } - - - // Create dummy sortable to prevent javascript errors - Sortable.create('availableWidgets-'+this.name, { - tag: 'li', - handle: 'handle', - containment: [] - }); - - // Used widgets are sortable - Sortable.create('usedWidgets-'+this.name, { - tag: 'div', - handle: 'handle', - containment: ['availableWidgets-'+this.name, 'usedWidgets-'+this.name], - onUpdate: this.updateWidgets - }); - - // Figure out maxid, this is used when creating new widgets - this.maxid = 0; - - var usedWidgets = document.getElementById('usedWidgets-'+this.name).childNodes; - for(var i = 0; i < usedWidgets.length; i++) { - var widget = usedWidgets[i]; - if(widget.id) { - widgetid = widget.id.match(/\Widget\[(.+?)\]\[([0-9]+)\]/i); - if(widgetid && parseInt(widgetid[2]) > this.maxid) { - this.maxid = parseInt(widgetid[2]); - } - } - } - - // Ensure correct sort values are written when page is saved - // TODO Adjust to new event listeners - jQuery('.cms-edit-form').bind('ajaxsubmit', this.beforeSave.bind(this)); - }, - - rewriteWidgetAreaAttributes: function() { - this.name = this.getAttribute('name'); - - var monkeyWith = function(widgets, name) { - if (!widgets) { - return; - } - for(var i = 0; i < widgets.length; i++) { - widget = widgets[i]; - if (!widget.getAttribute('rewritten') && (widget.id || widget.name)) { - if (widget.id && widget.id.indexOf('Widget[') === 0) { - var newValue = widget.id.replace(/Widget\[/, 'Widget['+name+']['); - //console.log('Renaming '+widget.tagName+' ID '+widget.id+' to '+newValue); - widget.id = newValue; - } - if (widget.name && widget.name.indexOf('Widget[') === 0) { - var newValue = widget.name.replace(/Widget\[/, 'Widget['+name+']['); - //console.log('Renaming '+widget.tagName+' Name '+widget.name+' to '+newValue); - widget.name = newValue; - } - widget.setAttribute('rewritten', 'yes'); - } - else { - //console.log('Skipping '+(widget.id ? widget.id : (widget.name ? widget.name : 'unknown '+widget.tagName))); - } - } - } - - monkeyWith($$('#WidgetAreaEditor-'+this.name+' .Widget'), this.name); - monkeyWith($$('#WidgetAreaEditor-'+this.name+' .Widget *'), this.name); - }, - - beforeSave: function() { - // Ensure correct sort values are written when page is saved - var usedWidgets = document.getElementById('usedWidgets-'+this.name); - - if(usedWidgets) { - this.sortWidgets(); - - var children = usedWidgets.childNodes; - - for( var i = 0; i < children.length; ++i ) { - var child = children[i]; - - if(child.beforeSave) { - child.beforeSave(); - } - } - } - }, - - addWidget: function(className, holder) { - - if (document.getElementById('WidgetAreaEditor-'+holder).getAttribute('maxwidgets')) { - var maxCount = document.getElementById('WidgetAreaEditor-'+holder).getAttribute('maxwidgets'); - var count = $$('#usedWidgets-'+holder+' .Widget').length; - if (count+1 > maxCount) { - alert(ss.i18n._t('WidgetAreaEditor.TOOMANY')); - return; - } - } - - - this.name = holder; - jQuery.ajax({ - 'url': 'Widget_Controller/EditableSegment/' + className, - 'success' : document.getElementById('usedWidgets-'+holder).parentNode.parentNode.insertWidgetEditor.bind(this) - }); - }, - - updateWidgets: function() { - var self = this; - - // Gotta get the name of the current dohickey based off the ID - this.name = this.element.id.split('-').pop(); - - // alert(this.name); - - // Gotta get the name of the current dohickey based off the ID - this.name = this.element.id.split('-').pop(); - - - // This is called when an available widgets is dragged over to used widgets. - // It inserts the editor form into the new used widget - - var usedWidgets = document.getElementById('usedWidgets-'+this.name).childNodes; - for(var i = 0; i < usedWidgets.length; i++) { - var widget = usedWidgets[i]; - if(widget.id && (widget.id.indexOf("Widget[") != 0) && (widget.id != 'NoWidgets-'+this.name)) { - // Need to remove the -$Name part. - var wIdArray = widget.id.split('-'); - wIdArray.pop(); - - jQuery.ajax({ - 'url': 'Widget_Controller/EditableSegment/' + wIdArray.join('-'), - 'success' : function() { - document.getElementById('usedWidgets-'+self.name).parentNode.parentNode.insertWidgetEditor(); - } - }); - } - } - }, - - insertWidgetEditor: function(response) { - // Remove placeholder text - if(document.getElementById('NoWidgets-'+this.name)) { - document.getElementById('usedWidgets-'+this.name).removeChild(document.getElementById('NoWidgets-'+this.name)); - } - - var usedWidgets = document.getElementById('usedWidgets-'+this.name).childNodes; - - // Give the widget a unique id - widgetContent = response.responseText.replace(/Widget\[0\]/gi, "Widget[new-" + (++document.getElementById('usedWidgets-'+this.name).parentNode.parentNode.maxid) + "]"); - new Insertion.Top(document.getElementById('usedWidgets-'+this.name), widgetContent); - - document.getElementById('usedWidgets-'+this.name).parentNode.parentNode.rewriteWidgetAreaAttributes(); - UsedWidget.applyToChildren(document.getElementById('usedWidgets-'+this.name), 'div.Widget'); - - // Repply some common form controls - WidgetTreeDropdownField.applyTo('div.usedWidgets .TreeDropdownField'); - - Sortable.create('usedWidgets-'+this.name, { - tag: 'div', - handle: 'handle', - containment: ['availableWidgets-'+this.name, 'usedWidgets-'+this.name], - onUpdate: document.getElementById('usedWidgets-'+this.name).parentNode.parentNode.updateWidgets - }); - }, - - sortWidgets: function() { - // Order the sort by the order the widgets are in the list - var usedWidgets = document.getElementById('usedWidgets-'+this.name); - - if(usedWidgets) { - widgets = usedWidgets.childNodes; - - for(i = 0; i < widgets.length; i++) { - var div = widgets[i]; - - if(div.nodeName != '#comment') { - var fields = div.getElementsByTagName('input'); - - for(j = 0; field = fields.item(j); j++) { - if(field.name == div.id + '[Sort]') { - field.value = i; - } - } - } - - } - } - }, - - deleteWidget: function(widgetToRemove) { - // Remove a widget from the used widgets column - document.getElementById('usedWidgets-'+this.name).removeChild(widgetToRemove); - // TODO ... re-create NoWidgets div? - } -} - -/** - * Class: UsedWidget - */ -UsedWidget = Class.create(); -UsedWidget.prototype = { - initialize: function() { - // Call deleteWidget when delete button is pushed - this.deleteButton = this.findDescendant('span', 'widgetDelete'); - if(this.deleteButton) - this.deleteButton.onclick = this.deleteWidget.bind(this); - }, - - // Taken from FieldEditor - findDescendant: function(tag, clsName, element) { - if(!element) - element = this; - - var descendants = element.getElementsByTagName(tag); - - for(var i = 0; i < descendants.length; i++) { - var el = descendants[i]; - - if(tag.toUpperCase() == el.tagName && el.className.indexOf( clsName ) != -1) - return el; - } - - return null; - }, - - deleteWidget: function() { - this.parentNode.parentNode.parentNode.deleteWidget(this); - } -} - -/** - * Class: AvailableWidgetHeader - */ -AvailableWidgetHeader = Class.create(); -AvailableWidgetHeader.prototype = { - onclick: function(event) { - parts = this.parentNode.id.split('-'); - var widgetArea = parts.pop(); - var className = parts.pop(); - document.getElementById('WidgetAreaEditor-'+widgetArea).addWidget(className, widgetArea); - } -} -AvailableWidgetHeader.applyTo('div.availableWidgets .Widget h3'); - -/** - * Class: WidgetTreeDropdownField - */ -WidgetTreeDropdownField = Class.extend('TreeDropdownField'); -WidgetTreeDropdownField.prototype = { - getName: function() { - return 'Widget_TDF_Endpoint'; - } -} -WidgetTreeDropdownField.applyTo('div.usedWidgets .TreeDropdownField'); -WidgetAreaEditorClass.applyTo('.WidgetAreaEditor'); \ No newline at end of file diff --git a/templates/WidgetArea.ss b/templates/WidgetArea.ss deleted file mode 100644 index b5279962..00000000 --- a/templates/WidgetArea.ss +++ /dev/null @@ -1,3 +0,0 @@ -<% control WidgetControllers %> - $WidgetHolder -<% end_control %> \ No newline at end of file diff --git a/templates/WidgetAreaEditor.ss b/templates/WidgetAreaEditor.ss deleted file mode 100644 index 6e3854e7..00000000 --- a/templates/WidgetAreaEditor.ss +++ /dev/null @@ -1,32 +0,0 @@ -
maxwidgets="$MaxWidgets"<% end_if %>> - -
-

<% _t('AVAILABLE', 'Available Widgets') %>

-

<% _t('AVAILWIDGETS', 'Click a widget title below to use it on this page.') %>

-
- <% if AvailableWidgets %> - <% control AvailableWidgets %> - $DescriptionSegment - <% end_control %> - <% else %> -
-

<% _t('NOAVAIL', 'There are currently no widgets available.') %>

-
- <% end_if %> -
-
-
-

<% _t('INUSE', 'Widgets currently used') %>

-

<% _t('TOSORT', 'To sort currently used widgets on this page, drag them up and down.') %>

- -
- <% if UsedWidgets %> - <% control UsedWidgets %> - $EditableSegment - <% end_control %> - <% else %> -
- <% end_if %> -
-
-
\ No newline at end of file diff --git a/templates/WidgetDescription.ss b/templates/WidgetDescription.ss deleted file mode 100644 index 423f9907..00000000 --- a/templates/WidgetDescription.ss +++ /dev/null @@ -1,6 +0,0 @@ -
-

$CMSTitle

-
-

$Description

-
-
\ No newline at end of file diff --git a/templates/WidgetEditor.ss b/templates/WidgetEditor.ss deleted file mode 100644 index 0075b76f..00000000 --- a/templates/WidgetEditor.ss +++ /dev/null @@ -1,12 +0,0 @@ -
-

$CMSTitle

-
-

$Description

-
-
- $CMSEditor - - -
-

<% _t('DELETE', 'Delete') %>

-
\ No newline at end of file diff --git a/templates/WidgetHolder.ss b/templates/WidgetHolder.ss deleted file mode 100644 index e6787fd5..00000000 --- a/templates/WidgetHolder.ss +++ /dev/null @@ -1,4 +0,0 @@ -
- <% if Title %>

$Title

<% end_if %> - $Content -
diff --git a/tests/widgets/WidgetAreaEditorTest.php b/tests/widgets/WidgetAreaEditorTest.php deleted file mode 100644 index 5a32536d..00000000 --- a/tests/widgets/WidgetAreaEditorTest.php +++ /dev/null @@ -1,471 +0,0 @@ - array( - 'BottomBar' => array( - 'new-1' => array( - 'Title' => 'MyTestWidget', - 'Type' => $this->widgetToTest, - 'Sort' => 0 - ) - ) - ) - ); - - $editorSide = new WidgetAreaEditor('SideBar'); - $editorBott = new WidgetAreaEditor('BottomBar'); - $page = new WidgetAreaEditorTest_FakePage(); - - $editorSide->saveInto($page); - $editorBott->saveInto($page); - $page->write(); - $page->flushCache(); - $page->BottomBar()->flushCache(); - $page->SideBar()->flushCache(); - - $this->assertEquals($page->BottomBar()->Widgets()->Count(), 1); - $this->assertEquals($page->SideBar()->Widgets()->Count(), 0); - - $_REQUEST = $oldRequest; - } - - function testFillingTwoAreas() { - $oldRequest = $_REQUEST; - - $_REQUEST = array( - 'Widget' => array( - 'SideBar' => array( - 'new-1' => array( - 'Title' => 'MyTestWidgetSide', - 'Type' => $this->widgetToTest, - 'Sort' => 0 - ) - ), - 'BottomBar' => array( - 'new-1' => array( - 'Title' => 'MyTestWidgetBottom', - 'Type' => $this->widgetToTest, - 'Sort' => 0 - ) - ) - ) - ); - - $editorSide = new WidgetAreaEditor('SideBar'); - $editorBott = new WidgetAreaEditor('BottomBar'); - $page = new WidgetAreaEditorTest_FakePage(); - - $editorSide->saveInto($page); - $editorBott->saveInto($page); - $page->write(); - $page->flushCache(); - $page->BottomBar()->flushCache(); - $page->SideBar()->flushCache(); - - // Make sure they both got saved - $this->assertEquals($page->BottomBar()->Widgets()->Count(), 1); - $this->assertEquals($page->SideBar()->Widgets()->Count(), 1); - - $sideWidgets = $page->SideBar()->Widgets()->toArray(); - $bottWidgets = $page->BottomBar()->Widgets()->toArray(); - $this->assertEquals($sideWidgets[0]->Title(), 'MyTestWidgetSide'); - $this->assertEquals($bottWidgets[0]->Title(), 'MyTestWidgetBottom'); - - $_REQUEST = $oldRequest; - } - - function testDeletingOneWidgetFromOneArea() { - $oldRequest = $_REQUEST; - - // First get some widgets in there - $_REQUEST = array( - 'Widget' => array( - 'SideBar' => array( - 'new-1' => array( - 'Title' => 'MyTestWidgetSide', - 'Type' => $this->widgetToTest, - 'Sort' => 0 - ) - ), - 'BottomBar' => array( - 'new-1' => array( - 'Title' => 'MyTestWidgetBottom', - 'Type' => $this->widgetToTest, - 'Sort' => 0 - ) - ) - ) - ); - - $editorSide = new WidgetAreaEditor('SideBar'); - $editorBott = new WidgetAreaEditor('BottomBar'); - $page = new WidgetAreaEditorTest_FakePage(); - - $editorSide->saveInto($page); - $editorBott->saveInto($page); - $page->write(); - $page->flushCache(); - $page->BottomBar()->flushCache(); - $page->SideBar()->flushCache(); - $sideWidgets = $page->SideBar()->Widgets()->toArray(); - $bottWidgets = $page->BottomBar()->Widgets()->toArray(); - - // Save again (after removing the SideBar's widget) - $_REQUEST = array( - 'Widget' => array( - 'SideBar' => array( - ), - 'BottomBar' => array( - $bottWidgets[0]->ID => array( - 'Title' => 'MyTestWidgetBottom', - 'Type' => $this->widgetToTest, - 'Sort' => 0 - ) - ) - ) - ); - - $editorSide->saveInto($page); - $editorBott->saveInto($page); - - $page->write(); - $page->flushCache(); - $page->BottomBar()->flushCache(); - $page->SideBar()->flushCache(); - $sideWidgets = $page->SideBar()->Widgets()->toArray(); - $bottWidgets = $page->BottomBar()->Widgets()->toArray(); - - $this->assertEquals($page->BottomBar()->Widgets()->Count(), 1); - $this->assertEquals($bottWidgets[0]->Title(), 'MyTestWidgetBottom'); - $this->assertEquals($page->SideBar()->Widgets()->Count(), 0); - - $_REQUEST = $oldRequest; - } - - function testDeletingAWidgetFromEachArea() { - $oldRequest = $_REQUEST; - - // First get some widgets in there - $_REQUEST = array( - 'Widget' => array( - 'SideBar' => array( - 'new-1' => array( - 'Title' => 'MyTestWidgetSide', - 'Type' => $this->widgetToTest, - 'Sort' => 0 - ) - ), - 'BottomBar' => array( - 'new-1' => array( - 'Title' => 'MyTestWidgetBottom', - 'Type' => $this->widgetToTest, - 'Sort' => 0 - ) - ) - ) - ); - - $editorSide = new WidgetAreaEditor('SideBar'); - $editorBott = new WidgetAreaEditor('BottomBar'); - $page = new WidgetAreaEditorTest_FakePage(); - - $editorSide->saveInto($page); - $editorBott->saveInto($page); - $page->write(); - $page->flushCache(); - $page->BottomBar()->flushCache(); - $page->SideBar()->flushCache(); - $sideWidgets = $page->SideBar()->Widgets()->toArray(); - $bottWidgets = $page->BottomBar()->Widgets()->toArray(); - - // Save again (after removing the SideBar's widget) - $_REQUEST = array( - 'Widget' => array( - 'SideBar' => array( - ), - 'BottomBar' => array( - ) - ) - ); - - $editorSide->saveInto($page); - $editorBott->saveInto($page); - - $page->write(); - $page->flushCache(); - $page->BottomBar()->flushCache(); - $page->SideBar()->flushCache(); - $sideWidgets = $page->SideBar()->Widgets()->toArray(); - $bottWidgets = $page->BottomBar()->Widgets()->toArray(); - - $this->assertEquals($page->BottomBar()->Widgets()->Count(), 0); - $this->assertEquals($page->SideBar()->Widgets()->Count(), 0); - - $_REQUEST = $oldRequest; - } - - function testEditingOneWidget() { - $oldRequest = $_REQUEST; - - // First get some widgets in there - $_REQUEST = array( - 'Widget' => array( - 'SideBar' => array( - 'new-1' => array( - 'Title' => 'MyTestWidgetSide', - 'Type' => $this->widgetToTest, - 'Sort' => 0 - ) - ), - 'BottomBar' => array( - 'new-1' => array( - 'Title' => 'MyTestWidgetBottom', - 'Type' => $this->widgetToTest, - 'Sort' => 0 - ) - ) - ) - ); - - $editorSide = new WidgetAreaEditor('SideBar'); - $editorBott = new WidgetAreaEditor('BottomBar'); - $page = new WidgetAreaEditorTest_FakePage(); - - $editorSide->saveInto($page); - $editorBott->saveInto($page); - $page->write(); - $page->flushCache(); - $page->BottomBar()->flushCache(); - $page->SideBar()->flushCache(); - $sideWidgets = $page->SideBar()->Widgets()->toArray(); - $bottWidgets = $page->BottomBar()->Widgets()->toArray(); - - // Save again (after removing the SideBar's widget) - $_REQUEST = array( - 'Widget' => array( - 'SideBar' => array( - $sideWidgets[0]->ID => array( - 'Title' => 'MyTestWidgetSide-edited', - 'Type' => $this->widgetToTest, - 'Sort' => 0 - ) - ), - 'BottomBar' => array( - $bottWidgets[0]->ID => array( - 'Title' => 'MyTestWidgetBottom', - 'Type' => $this->widgetToTest, - 'Sort' => 0 - ) - ) - ) - ); - - - $editorSide->saveInto($page); - $editorBott->saveInto($page); - - $page->write(); - $page->flushCache(); - $page->BottomBar()->flushCache(); - $page->SideBar()->flushCache(); - $sideWidgets = $page->SideBar()->Widgets()->toArray(); - $bottWidgets = $page->BottomBar()->Widgets()->toArray(); - - $this->assertEquals($page->BottomBar()->Widgets()->Count(), 1); - $this->assertEquals($page->SideBar()->Widgets()->Count(), 1); - $this->assertEquals($bottWidgets[0]->Title(), 'MyTestWidgetBottom'); - $this->assertEquals($sideWidgets[0]->Title(), 'MyTestWidgetSide-edited'); - - - $_REQUEST = $oldRequest; - } - - function testEditingAWidgetFromEachArea() { - $oldRequest = $_REQUEST; - - // First get some widgets in there - $_REQUEST = array( - 'Widget' => array( - 'SideBar' => array( - 'new-1' => array( - 'Title' => 'MyTestWidgetSide', - 'Type' => $this->widgetToTest, - 'Sort' => 0 - ) - ), - 'BottomBar' => array( - 'new-1' => array( - 'Title' => 'MyTestWidgetBottom', - 'Type' => $this->widgetToTest, - 'Sort' => 0 - ) - ) - ) - ); - - $editorSide = new WidgetAreaEditor('SideBar'); - $editorBott = new WidgetAreaEditor('BottomBar'); - $page = new WidgetAreaEditorTest_FakePage(); - - $editorSide->saveInto($page); - $editorBott->saveInto($page); - $page->write(); - $page->flushCache(); - $page->BottomBar()->flushCache(); - $page->SideBar()->flushCache(); - $sideWidgets = $page->SideBar()->Widgets()->toArray(); - $bottWidgets = $page->BottomBar()->Widgets()->toArray(); - - // Save again (after removing the SideBar's widget) - $_REQUEST = array( - 'Widget' => array( - 'SideBar' => array( - $sideWidgets[0]->ID => array( - 'Title' => 'MyTestWidgetSide-edited', - 'Type' => $this->widgetToTest, - 'Sort' => 0 - ) - ), - 'BottomBar' => array( - $bottWidgets[0]->ID => array( - 'Title' => 'MyTestWidgetBottom-edited', - 'Type' => $this->widgetToTest, - 'Sort' => 0 - ) - ) - ) - ); - - - $editorSide->saveInto($page); - $editorBott->saveInto($page); - - $page->write(); - $page->flushCache(); - $page->BottomBar()->flushCache(); - $page->SideBar()->flushCache(); - $sideWidgets = $page->SideBar()->Widgets()->toArray(); - $bottWidgets = $page->BottomBar()->Widgets()->toArray(); - - $this->assertEquals($page->BottomBar()->Widgets()->Count(), 1); - $this->assertEquals($page->SideBar()->Widgets()->Count(), 1); - $this->assertEquals($bottWidgets[0]->Title(), 'MyTestWidgetBottom-edited'); - $this->assertEquals($sideWidgets[0]->Title(), 'MyTestWidgetSide-edited'); - - - $_REQUEST = $oldRequest; - } - - function testEditAWidgetFromOneAreaAndDeleteAWidgetFromAnotherArea() { - $oldRequest = $_REQUEST; - - // First get some widgets in there - $_REQUEST = array( - 'Widget' => array( - 'SideBar' => array( - 'new-1' => array( - 'Title' => 'MyTestWidgetSide', - 'Type' => $this->widgetToTest, - 'Sort' => 0 - ) - ), - 'BottomBar' => array( - 'new-1' => array( - 'Title' => 'MyTestWidgetBottom', - 'Type' => $this->widgetToTest, - 'Sort' => 0 - ) - ) - ) - ); - - $editorSide = new WidgetAreaEditor('SideBar'); - $editorBott = new WidgetAreaEditor('BottomBar'); - $page = new WidgetAreaEditorTest_FakePage(); - - $editorSide->saveInto($page); - $editorBott->saveInto($page); - $page->write(); - $page->flushCache(); - $page->BottomBar()->flushCache(); - $page->SideBar()->flushCache(); - $sideWidgets = $page->SideBar()->Widgets()->toArray(); - $bottWidgets = $page->BottomBar()->Widgets()->toArray(); - - // Save again (after removing the SideBar's widget) - $_REQUEST = array( - 'Widget' => array( - 'SideBar' => array( - $sideWidgets[0]->ID => array( - 'Title' => 'MyTestWidgetSide-edited', - 'Type' => $this->widgetToTest, - 'Sort' => 0 - ) - ), - 'BottomBar' => array( - ) - ) - ); - - - $editorSide->saveInto($page); - $editorBott->saveInto($page); - - $page->write(); - $page->flushCache(); - $page->BottomBar()->flushCache(); - $page->SideBar()->flushCache(); - $sideWidgets = $page->SideBar()->Widgets()->toArray(); - $bottWidgets = $page->BottomBar()->Widgets()->toArray(); - - $this->assertEquals($page->BottomBar()->Widgets()->Count(), 0); - $this->assertEquals($page->SideBar()->Widgets()->Count(), 1); - $this->assertEquals($sideWidgets[0]->Title(), 'MyTestWidgetSide-edited'); - - - $_REQUEST = $oldRequest; - } -} - -class WidgetAreaEditorTest_FakePage extends Page implements TestOnly { - public static $has_one = array( - "SideBar" => "WidgetArea", - "BottomBar" => "WidgetArea", - ); -} - -class WidgetAreaEditorTest_TestWidget extends Widget implements TestOnly { - static $cmsTitle = "Test widget"; - static $title = "Test widget"; - static $description = "Test widget"; - static $db = array( - 'Title' => 'Varchar' - ); - public function getCMSFields() { - $fields = new FieldList(); - $fields->push(new TextField('Title')); - return $fields; - } - function Title() { - return $this->Title ? $this->Title : self::$title; - } -} diff --git a/tests/widgets/WidgetControllerTest.php b/tests/widgets/WidgetControllerTest.php deleted file mode 100644 index a254cb95..00000000 --- a/tests/widgets/WidgetControllerTest.php +++ /dev/null @@ -1,88 +0,0 @@ -objFromFixture('WidgetControllerTestPage', 'page1'); - $page->publish('Stage', 'Live'); - - $widget = $this->objFromFixture('WidgetControllerTest_Widget', 'widget1'); - - $response = $this->get($page->URLSegment); - - $formAction = sprintf('%s/widget/%d/Form', $page->URLSegment, $widget->ID); - $this->assertContains( - $formAction, - $response->getBody(), - "Widget forms are rendered through WidgetArea templates" - ); - } - - function testWidgetFormSubmission() { - $page = $this->objFromFixture('WidgetControllerTestPage', 'page1'); - $page->publish('Stage', 'Live'); - - $widget = $this->objFromFixture('WidgetControllerTest_Widget', 'widget1'); - - $this->get($page->URLSegment); - $response = $this->submitForm('Form_Form', null, array('TestValue'=>'Updated')); - - $this->assertContains( - 'TestValue: Updated', - $response->getBody(), - "Form values are submitted to correct widget form" - ); - $this->assertContains( - sprintf('Widget ID: %d', $widget->ID), - $response->getBody(), - "Widget form acts on correct widget, as identified in the URL" - ); - } -} - -/** - * @package cms - * @subpackage tests - */ -class WidgetControllerTest_Widget extends Widget implements TestOnly { - static $db = array( - 'TestValue' => 'Text' - ); -} - -/** - * @package cms - * @subpackage tests - */ -class WidgetControllerTest_Widget_Controller extends Widget_Controller implements TestOnly { - function Form() { - $widgetform = new Form( - $this, - 'Form', - new FieldList( - new TextField('TestValue') - ), - new FieldList( - new FormAction('doAction') - ) - ); - - return $widgetform; - } - - function doAction($data, $form) { - return sprintf('TestValue: %s\nWidget ID: %d', - $data['TestValue'], - $this->widget->ID - ); - } -} diff --git a/tests/widgets/WidgetControllerTest.yml b/tests/widgets/WidgetControllerTest.yml deleted file mode 100644 index a549c230..00000000 --- a/tests/widgets/WidgetControllerTest.yml +++ /dev/null @@ -1,10 +0,0 @@ -WidgetControllerTest_Widget: - widget1: - Title: Widget 1 -WidgetArea: - area1: - Widgets: =>WidgetControllerTest_Widget.widget1 -WidgetControllerTestPage: - page1: - Title: Page1 - WidgetControllerTestSidebar: =>WidgetArea.area1 \ No newline at end of file diff --git a/tests/widgets/WidgetControllerTestPage.php b/tests/widgets/WidgetControllerTestPage.php deleted file mode 100644 index f8821ee7..00000000 --- a/tests/widgets/WidgetControllerTestPage.php +++ /dev/null @@ -1,27 +0,0 @@ - 'WidgetArea' - ); -} - -/** - * @package cms - * @subpackage tests - */ -class WidgetControllerTestPage_Controller extends Page_Controller implements TestOnly { - - /** - * Template selection doesnt work in test folders, - * so we enforce a template name. - */ - function getViewer($action) { - $templates = array('WidgetControllerTestPage'); - - return new SSViewer($templates); - } -} diff --git a/tests/widgets/WidgetControllerTestPage.ss b/tests/widgets/WidgetControllerTestPage.ss deleted file mode 100644 index 0c65a8d4..00000000 --- a/tests/widgets/WidgetControllerTestPage.ss +++ /dev/null @@ -1 +0,0 @@ -$WidgetControllerTestSidebar \ No newline at end of file diff --git a/tests/widgets/WidgetControllerTest_Widget.ss b/tests/widgets/WidgetControllerTest_Widget.ss deleted file mode 100644 index 701a1e15..00000000 --- a/tests/widgets/WidgetControllerTest_Widget.ss +++ /dev/null @@ -1 +0,0 @@ -$Form \ No newline at end of file