Version: current

      1 <?php
      2 /**
      3  * Special field type for selecting and configuring widgets on a page.
      4  * @package cms
      5  * @subpackage content
      6  */
      7 class WidgetAreaEditor extends FormField {
      8     /**
      9      * 3 variables to hold titles for the template
     10      */
     11     public $InUseTitle;
     12     public $AvailableTitle;
     13     public $ToAddTitle;
     14
     15     function __construct($name, $widgetClasses = array('Widget'), $maxWidgets = 0) {
     16         $this->MaxWidgets = $maxWidgets;
     17         $this->widgetClasses = $widgetClasses;
     18
     19         parent::__construct($name);
     20     }
     21
     22     function FieldHolder() {
     23         Requirements::css(CMS_DIR . '/css/WidgetAreaEditor.css');
     24         Requirements::javascript(CMS_DIR . '/javascript/WidgetAreaEditor.js');
     25
     26         return $this->renderWith("WidgetAreaEditor");
     27     }
     28
     29     function AvailableWidgets() {
     30
     31         $widgets= new DataObjectSet();
     32
     33         foreach($this->widgetClasses as $widgetClass) {
     34             $classes = ClassInfo::subclassesFor($widgetClass);
     35             array_shift($classes);
     36             foreach($classes as $class) {
     37                 $widgets->push(singleton($class));
     38             }
     39         }
     40
     41         return $widgets;
     42     }
     43
     44     function UsedWidgets() {
     45         // Call class_exists() to load Widget.php earlier and avoid a segfault
     46         class_exists('Widget');
     47
     48         $relationName = $this->name;
     49         $widgets = $this->form->getRecord()->getComponent($relationName)->Items();
     50         return $widgets;
     51     }
     52
     53     function IdxField() {
     54         return $this->id() . 'ID';
     55     }
     56
     57     function Value() {
     58         $relationName = $this->name;
     59         return $this->form->getRecord()->getComponent($relationName)->ID;
     60     }
     61
     62     function saveInto(DataObject $record) {
     63         $name = $this->name;
     64         $idName = $name . "ID";
     65
     66         $widgetarea = $record->getComponent($name);
     67         $widgetarea->write();
     68
     69         $record->$idName = $widgetarea->ID;
     70
     71         $widgets = $widgetarea->Items();
     72
     73         // store the field IDs and delete the missing fields
     74         // alternatively, we could delete all the fields and re add them
     75         $missingWidgets = array();
     76
     77         if($widgets) {
     78             foreach($widgets as $existingWidget) {
     79                 $missingWidgets[$existingWidget->ID] = $existingWidget;
     80             }
     81         }
     82
     83         if(isset($_REQUEST['Widget'])) {
     84             foreach(array_keys($_REQUEST['Widget']) as $widgetAreaName) {
     85                 if ($widgetAreaName !== $this->name) {
     86                     continue;
     87                 }
     88
     89                 foreach(array_keys($_REQUEST['Widget'][$widgetAreaName]) as $newWidgetID) {
     90                     $newWidgetData = $_REQUEST['Widget'][$widgetAreaName][$newWidgetID];
     91
     92                     // Sometimes the id is "new-1" or similar, ensure this doesn't get into the query
     93                     if(!is_numeric($newWidgetID)) {
     94                         $newWidgetID = 0;
     95                     }
     96
     97                     // \"ParentID\" = '0' is for the new page
     98                     $widget = DataObject::get_one(
     99                         'Widget',
    100                         "(\"ParentID\" = '{$record->$name()->ID}' OR \"ParentID\" = '0') AND \"Widget\".\"ID\" = '$newWidgetID'"
    101                     );
    102
    103
    104                     // check if we are updating an existing widget
    105                     if($widget && isset($missingWidgets[$widget->ID])) {
    106                         unset($missingWidgets[$widget->ID]);
    107                     }
    108
    109                     // create a new object
    110                     if(!$widget && !empty($newWidgetData['Type']) && class_exists($newWidgetData['Type'])) {
    111                         $widget = new $newWidgetData['Type']();
    112                         $widget->ID = 0;
    113                         $widget->ParentID = $record->$name()->ID;
    114
    115                         if(!is_subclass_of($widget, 'Widget')) {
    116                             $widget = null;
    117                         }
    118                     }
    119
    120                     if($widget) {
    121                         if($widget->ParentID == 0) {
    122                             $widget->ParentID = $record->$name()->ID;
    123                         }
    124                         // echo "Saving $widget->ID into $name/$widget->ParentID\n<br/>";
    125                         $widget->populateFromPostData($newWidgetData);
    126                     }
    127                 }
    128             }
    129         }
    130
    131         // remove the fields not saved
    132         if($missingWidgets) {
    133             foreach($missingWidgets as $removedWidget) {
    134                 if(isset($removedWidget) && is_numeric($removedWidget->ID)) {
    135                     $removedWidget->delete();
    136                 }
    137             }
    138         }
    139     }
    140 }

[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the Silverstripe Forums to ask development related questions. -