1<?php
2
3/**
4 */
5class PluginManagerController extends Survey_Common_Action
6{
7    public function init()
8    {
9    }
10
11    /**
12     * Overview for plugins
13     * Copied from PluginsController 2015-10-02
14     */
15    public function index()
16    {
17        if (!Permission::model()->hasGlobalPermission('settings', 'read')) {
18            Yii::app()->setFlashMessage(gT("No permission"), 'error');
19            $this->getController()->redirect(array('/admin'));
20        }
21        $oPluginManager = App()->getPluginManager();
22
23        // Scan the plugins folder.
24        $aDiscoveredPlugins = $oPluginManager->scanPlugins();
25        $aInstalledPlugins  = $oPluginManager->getInstalledPlugins();
26        $aInstalledNames    = array_map(
27            function ($installedPlugin) {
28                return $installedPlugin->name;
29            },
30            $aInstalledPlugins
31        );
32
33        // Install newly discovered plugins.
34        foreach ($aDiscoveredPlugins as $discoveredPlugin) {
35            if (!in_array($discoveredPlugin['pluginClass'], $aInstalledNames)) {
36                $oPlugin         = new Plugin();
37                $oPlugin->name   = $discoveredPlugin['pluginClass'];
38                $oPlugin->active = 0;
39                $oPlugin->save();
40                //New plugin registration
41                $event = new PluginEvent('onPluginRegistration');
42                $event->set('pluginName', $oPlugin->name);
43                App()->getPluginManager()->dispatchEvent($event);
44            }
45        }
46
47        $aoPlugins = Plugin::model()->findAll(array('order' => 'name'));
48        $data      = array();
49        foreach ($aoPlugins as $oPlugin) {
50            /* @var $plugin Plugin */
51            if (array_key_exists($oPlugin->name, $aDiscoveredPlugins)) {
52                $plugin = App()->getPluginManager()->loadPlugin($oPlugin->name, $oPlugin->id);
53                if ($plugin) {
54                    $aPluginSettings = $plugin->getPluginSettings(false);
55                    $data[]          = array(
56                        'id'          => $oPlugin->id,
57                        'name'        => $aDiscoveredPlugins[$oPlugin->name]['pluginName'],
58                        'description' => $aDiscoveredPlugins[$oPlugin->name]['description'],
59                        'active'      => $oPlugin->active,
60                        'settings'    => $aPluginSettings,
61                        'new'         => !in_array($oPlugin->name, $aInstalledNames)
62                    );
63                }
64            } else {
65                // This plugin is missing, maybe the files were deleted but the record was not removed from the database
66                // Now delete this record. Depending on the plugin the settings will be preserved
67                App()->user->setFlash('pluginDelete'.$oPlugin->id, sprintf(gT("Plugin '%s' was missing and is removed from the database."), $oPlugin->name));
68                $oPlugin->delete();
69            }
70        }
71
72        if (Yii::app()->request->getParam('pageSize')) {
73            Yii::app()->user->setState('pageSize', intval(Yii::app()->request->getParam('pageSize')));
74        }
75
76        $aData['fullpagebar']['returnbutton']['url'] = 'index';
77        $aData['fullpagebar']['returnbutton']['text'] = gT('Return to admin home');
78        $aData['data'] = $data;
79        $this->_renderWrappedTemplate('pluginmanager', 'index', $aData);
80    }
81
82    /**
83     * Activate or deactivate a plugin
84     *
85     * @return void
86     */
87    public function changestate()
88    {
89        //Yii::app()->request->validateCsrfToken();
90        $id = Yii::app()->request->getPost('id');
91        $type = Yii::app()->request->getPost('type');
92        if ($type == "activate") {
93            $this->activate($id);
94        } else if ($type == "deactivate") {
95            $this->deactivate($id);
96        }
97    }
98
99    /**
100     * Activate a plugin
101     *
102     * @todo Defensive programming
103     * @param int $id Plugin id
104     * @return void
105     */
106    private function activate($id)
107    {
108        if (!Permission::model()->hasGlobalPermission('settings', 'update')) {
109            Yii::app()->setFlashMessage(gT("No permission"), 'error');
110            $this->getController()->redirect(array('/admin/pluginmanager/sa/index'));
111        }
112        $oPlugin = Plugin::model()->findByPk($id);
113        if (!is_null($oPlugin)) {
114            $iStatus = $oPlugin->active;
115            if ($iStatus == 0) {
116                // Load the plugin:
117                App()->getPluginManager()->loadPlugin($oPlugin->name, $id);
118                $result = App()->getPluginManager()->dispatchEvent(new PluginEvent('beforeActivate', $this), $oPlugin->name);
119                if ($result->get('success', true)) {
120                    $iStatus = 1;
121                } else {
122                    $customMessage = $result->get('message');
123                    if ($customMessage) {
124                        Yii::app()->user->setFlash('error', $customMessage);
125                    } else {
126                        Yii::app()->user->setFlash('error', gT('Failed to activate the plugin.'));
127                    }
128
129                    $this->getController()->redirect(array('admin/pluginmanager/sa/index/'));
130                }
131            }
132            $oPlugin->active = $iStatus;
133            $oPlugin->save();
134            Yii::app()->user->setFlash('success', gT('Plugin was activated.'));
135        }
136        $this->getController()->redirect(array('admin/pluginmanager/sa/index/'));
137    }
138
139    /**
140     * Deactivate plugin with $id
141     *
142     * @param int $id
143     * @return void
144     */
145    private function deactivate($id)
146    {
147        if (!Permission::model()->hasGlobalPermission('settings', 'update')) {
148            Yii::app()->setFlashMessage(gT("No permission"), 'error');
149            $this->getController()->redirect(array('/admin/pluginmanager/sa/index'));
150        }
151        $oPlugin = Plugin::model()->findByPk($id);
152        if (!is_null($oPlugin)) {
153            $iStatus = $oPlugin->active;
154            if ($iStatus == 1) {
155                $result = App()->getPluginManager()->dispatchEvent(new PluginEvent('beforeDeactivate', $this), $oPlugin->name);
156                if ($result->get('success', true)) {
157                    $iStatus = 0;
158                } else {
159                    $customMessage = $result->get('message');
160                    if ($customMessage) {
161                        Yii::app()->user->setFlash('error', $customMessage);
162                    } else {
163                        Yii::app()->user->setFlash('error', gT('Failed to activate the plugin.'));
164                    }
165
166                    $this->getController()->redirect(array('admin/pluginmanager/sa/index/'));
167                }
168            }
169            $oPlugin->active = $iStatus;
170            $oPlugin->save();
171            Yii::app()->user->setFlash('success', gT('Plugin was deactivated.'));
172        }
173        $this->getController()->redirect(array('admin/pluginmanager/sa/index/'));
174    }
175
176    /**
177     * Configure for plugin
178     */
179    public function configure($id)
180    {
181        if (!Permission::model()->hasGlobalPermission('settings', 'read')) {
182            Yii::app()->setFlashMessage(gT("No permission"), 'error');
183            $this->getController()->redirect(array('/admin/pluginmanager/sa/index'));
184        }
185
186        $arPlugin      = Plugin::model()->findByPk($id)->attributes;
187        $oPluginObject = App()->getPluginManager()->loadPlugin($arPlugin['name'], $arPlugin['id']);
188
189        if ($arPlugin === null) {
190            Yii::app()->user->setFlash('error', gT('The plugin was not found.'));
191            $this->getController()->redirect(array('admin/pluginmanager/sa/index'));
192        }
193
194        // If post handle data, yt0 seems to be the submit button
195        if (App()->request->isPostRequest) {
196            if (!Permission::model()->hasGlobalPermission('settings', 'update')) {
197                Yii::app()->setFlashMessage(gT("No permission"), 'error');
198                $this->getController()->redirect(array('/admin/pluginmanager/sa/index'));
199            }
200            $aSettings = $oPluginObject->getPluginSettings(false);
201            $aSave     = array();
202            foreach ($aSettings as $name => $setting) {
203                $aSave[$name] = App()->request->getPost($name, null);
204            }
205            $oPluginObject->saveSettings($aSave);
206            Yii::app()->user->setFlash('success', gT('The plugin settings were saved.'));
207            if (App()->request->getPost('redirect')) {
208                $this->getController()->redirect(App()->request->getPost('redirect'), true);
209            }
210        }
211
212        // Prepare settings to be send to the view.
213        $aSettings = $oPluginObject->getPluginSettings();
214        if (empty($aSettings)) {
215            // And show a message
216            Yii::app()->user->setFlash('notice', gt('This plugin has no settings.'));
217            $this->getController()->redirect('admin/pluginmanager/sa/index', true);
218        }
219
220        // Send to view plugin porperties: name and description
221        $aPluginProp = App()->getPluginManager()->getPluginInfo($arPlugin['name']);
222
223        $this->_renderWrappedTemplate('pluginmanager', 'configure', array('settings' => $aSettings, 'plugin' => $arPlugin, 'properties' => $aPluginProp));
224    }
225
226    /**
227     * Renders template(s) wrapped in header and footer
228     *
229     * @param string $sAction Current action, the folder to fetch views from
230     * @param string $aViewUrls View url(s)
231     * @param array $aData Data to be passed on. Optional.
232     */
233    protected function _renderWrappedTemplate($sAction = 'pluginmanager', $aViewUrls = array(), $aData = array(), $sRenderFile = false)
234    {
235        parent::_renderWrappedTemplate($sAction, $aViewUrls, $aData, $sRenderFile);
236    }
237}
238