WidgetController::editablesegment()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 10
dl 0
loc 15
rs 9.9332
c 0
b 0
f 0
cc 3
nc 2
nop 0
1
<?php
2
3
namespace SilverStripe\Widgets\Model;
4
5
use SilverStripe\Admin\LeftAndMain;
6
use SilverStripe\Control\Controller;
7
use SilverStripe\Control\Director;
8
use SilverStripe\Core\ClassInfo;
9
10
/**
11
 * Optional controller for every widget which has its own logic, e.g. in forms.
12
 *
13
 * It always handles a single widget, usually passed in as a database
14
 * identifier through the controller URL. Needs to be constructed as a nested
15
 * controller within a {@link ContentController}.
16
 *
17
 * ## Forms
18
 * You can add forms like in any other SilverStripe controller. If you need
19
 * access to the widget from within a form, you can use
20
 * `$this->controller->getWidget()` inside the form logic.
21
 *
22
 * Note: Widget controllers currently only work on {@link Page} objects,
23
 * because the logic is implemented in {@link ContentController->handleWidget()}.
24
 * Copy this logic and the URL rules to enable it for other controllers.
25
 *
26
 * @package widgets
27
 */
28
class WidgetController extends Controller
29
{
30
    /**
31
     * @var Widget
32
     */
33
    protected $widget;
34
35
    /**
36
     * @var array
37
     */
38
    private static $allowed_actions = array(
0 ignored issues
show
introduced by
The private property $allowed_actions is not used, and could be removed.
Loading history...
39
        'editablesegment'
40
    );
41
42
    /**
43
     * @param Widget $widget
44
     */
45
    public function __construct($widget = null)
46
    {
47
        if ($widget) {
48
            $this->widget = $widget;
49
            $this->failover = $widget;
50
        }
51
52
        parent::__construct();
53
    }
54
55
    /**
56
     * @param string $action
57
     * @return string
58
     */
59
    public function Link($action = null)
60
    {
61
        $id = ($this->widget) ? $this->widget->ID : null;
62
        $segment = Controller::join_links('widget', $id, $action);
63
64
        $page = Director::get_current_page();
65
        if ($page && !($page instanceof WidgetController)) {
66
            return $page->Link($segment);
67
        }
68
69
        if ($controller = $this->getParentController()) {
70
            return $controller->Link($segment);
71
        }
72
73
        return $segment;
74
    }
75
76
    /**
77
     * Cycles up the controller stack until it finds a non-widget controller
78
     * This is needed becauseController::currreturns the widget controller,
79
     * which means anyLinkfunction turns into endless loop.
80
     *
81
     * @return Controller
82
     */
83
    public function getParentController()
84
    {
85
        foreach (Controller::$controller_stack as $controller) {
86
            if (!($controller instanceof WidgetController)) {
87
                return $controller;
88
            }
89
        }
90
        return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type SilverStripe\Control\Controller.
Loading history...
91
    }
92
93
    /**
94
     * @return Widget
95
     */
96
    public function getWidget()
97
    {
98
        return $this->widget;
99
    }
100
101
    /**
102
     * Overloaded from {@link Widget->Content()} to allow for controller / form
103
     * linking.
104
     *
105
     * @return string HTML
106
     */
107
    public function Content()
108
    {
109
        return $this->renderWith(array_reverse(ClassInfo::ancestry(get_class($this->widget))));
110
    }
111
112
    /**
113
     * Overloaded from {@link Widget->WidgetHolder()} to allow for controller/
114
     * form linking.
115
     *
116
     * @return string HTML
117
     */
118
    public function WidgetHolder()
119
    {
120
        return $this->renderWith("WidgetHolder");
121
    }
122
123
    /**
124
     * Uses the `WidgetEditor.ss` template and {@link Widget->editablesegment()}
125
     * to render a administrator-view of the widget. It is assumed that this
126
     * view contains form elements which are submitted and saved through
127
     * {@link WidgetAreaEditor} within the CMS interface.
128
     *
129
     * @return string HTML
130
     */
131
    public function editablesegment()
132
    {
133
        // use left and main to set the html config
134
        $leftandmain = LeftAndMain::create();
135
        $leftandmain->setRequest($this->getRequest());
136
        $leftandmain->doInit();
137
138
        // Decode if fully qualified - @see Widget::ClassName
139
        $className = str_replace('_', '\\', $this->urlParams['ID']);
140
        if (class_exists($className) && is_subclass_of($className, Widget::class)) {
141
            $obj = new $className();
142
            return $obj->EditableSegment();
143
        } else {
144
            user_error("Bad widget class: $className", E_USER_WARNING);
145
            return "Bad widget class name given";
146
        }
147
    }
148
}
149