~xibo-maintainers/xibo/tempel

« back to all changes in this revision

Viewing changes to lib/Controller/Module.php

  • Committer: Dan Garner
  • Date: 2015-09-29 15:16:59 UTC
  • mto: (454.2.11) (471.2.2)
  • mto: This revision was merged to the branch mainline in revision 468.
  • Revision ID: git-v1:ae24387a7b1397750b6ec86d0f286373da05eb16
Fixed Display Version Information Form (not showing media name)

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 
23
23
use Xibo\Entity\Permission;
24
24
use Xibo\Exception\AccessDeniedException;
25
 
use Xibo\Exception\ConfigurationException;
26
 
use Xibo\Exception\InvalidArgumentException;
27
 
use Xibo\Exception\NotFoundException;
28
 
use Xibo\Exception\XiboException;
29
 
use Xibo\Factory\DisplayFactory;
30
 
use Xibo\Factory\DisplayGroupFactory;
31
 
use Xibo\Factory\LayoutFactory;
32
25
use Xibo\Factory\MediaFactory;
33
26
use Xibo\Factory\ModuleFactory;
34
27
use Xibo\Factory\PermissionFactory;
35
28
use Xibo\Factory\PlaylistFactory;
36
29
use Xibo\Factory\RegionFactory;
37
 
use Xibo\Factory\ScheduleFactory;
38
30
use Xibo\Factory\TransitionFactory;
39
 
use Xibo\Factory\UserGroupFactory;
40
 
use Xibo\Factory\WidgetAudioFactory;
41
31
use Xibo\Factory\WidgetFactory;
42
 
use Xibo\Service\ConfigServiceInterface;
43
 
use Xibo\Service\DateServiceInterface;
44
 
use Xibo\Service\LogServiceInterface;
45
 
use Xibo\Service\SanitizerServiceInterface;
46
 
use Xibo\Storage\StorageServiceInterface;
47
 
 
48
 
/**
49
 
 * Class Module
50
 
 * @package Xibo\Controller
51
 
 */
 
32
use Xibo\Helper\Config;
 
33
use Xibo\Helper\Help;
 
34
use Xibo\Helper\Log;
 
35
use Xibo\Helper\Sanitize;
 
36
use Xibo\Storage\PDOConnect;
 
37
 
 
38
 
52
39
class Module extends Base
53
40
{
54
41
    /**
55
 
     * @var StorageServiceInterface
56
 
     */
57
 
    private $store;
58
 
 
59
 
    /**
60
 
     * @var ModuleFactory
61
 
     */
62
 
    private $moduleFactory;
63
 
 
64
 
    /**
65
 
     * @var PlaylistFactory
66
 
     */
67
 
    private $playlistFactory;
68
 
 
69
 
    /**
70
 
     * @var MediaFactory
71
 
     */
72
 
    private $mediaFactory;
73
 
 
74
 
    /**
75
 
     * @var PermissionFactory
76
 
     */
77
 
    private $permissionFactory;
78
 
 
79
 
    /**
80
 
     * @var UserGroupFactory
81
 
     */
82
 
    private $userGroupFactory;
83
 
 
84
 
    /**
85
 
     * @var WidgetFactory
86
 
     */
87
 
    private $widgetFactory;
88
 
 
89
 
    /**
90
 
     * @var TransitionFactory
91
 
     */
92
 
    private $transitionFactory;
93
 
 
94
 
    /**
95
 
     * @var RegionFactory
96
 
     */
97
 
    private $regionFactory;
98
 
 
99
 
    /** @var  LayoutFactory */
100
 
    protected $layoutFactory;
101
 
 
102
 
    /** @var  DisplayGroupFactory */
103
 
    protected $displayGroupFactory;
104
 
 
105
 
    /** @var  WidgetAudioFactory */
106
 
    protected $widgetAudioFactory;
107
 
 
108
 
    /** @var  DisplayFactory */
109
 
    private $displayFactory;
110
 
 
111
 
    /** @var ScheduleFactory  */
112
 
    private $scheduleFactory;
113
 
 
114
 
    /**
115
 
     * Set common dependencies.
116
 
     * @param LogServiceInterface $log
117
 
     * @param SanitizerServiceInterface $sanitizerService
118
 
     * @param \Xibo\Helper\ApplicationState $state
119
 
     * @param \Xibo\Entity\User $user
120
 
     * @param \Xibo\Service\HelpServiceInterface $help
121
 
     * @param DateServiceInterface $date
122
 
     * @param ConfigServiceInterface $config
123
 
     * @param StorageServiceInterface $store
124
 
     * @param ModuleFactory $moduleFactory
125
 
     * @param PlaylistFactory $playlistFactory
126
 
     * @param MediaFactory $mediaFactory
127
 
     * @param PermissionFactory $permissionFactory
128
 
     * @param UserGroupFactory $userGroupFactory
129
 
     * @param WidgetFactory $widgetFactory
130
 
     * @param TransitionFactory $transitionFactory
131
 
     * @param RegionFactory $regionFactory
132
 
     * @param LayoutFactory $layoutFactory
133
 
     * @param DisplayGroupFactory $displayGroupFactory
134
 
     * @param WidgetAudioFactory $widgetAudioFactory
135
 
     * @param DisplayFactory $displayFactory
136
 
     * @param ScheduleFactory $scheduleFactory
137
 
     */
138
 
    public function __construct($log, $sanitizerService, $state, $user, $help, $date, $config, $store, $moduleFactory, $playlistFactory, $mediaFactory, $permissionFactory, $userGroupFactory, $widgetFactory, $transitionFactory, $regionFactory, $layoutFactory, $displayGroupFactory, $widgetAudioFactory, $displayFactory, $scheduleFactory)
139
 
    {
140
 
        $this->setCommonDependencies($log, $sanitizerService, $state, $user, $help, $date, $config);
141
 
 
142
 
        $this->store = $store;
143
 
        $this->moduleFactory = $moduleFactory;
144
 
        $this->playlistFactory = $playlistFactory;
145
 
        $this->mediaFactory = $mediaFactory;
146
 
        $this->permissionFactory = $permissionFactory;
147
 
        $this->userGroupFactory = $userGroupFactory;
148
 
        $this->widgetFactory = $widgetFactory;
149
 
        $this->transitionFactory = $transitionFactory;
150
 
        $this->regionFactory = $regionFactory;
151
 
        $this->layoutFactory = $layoutFactory;
152
 
        $this->displayGroupFactory = $displayGroupFactory;
153
 
        $this->widgetAudioFactory = $widgetAudioFactory;
154
 
        $this->displayFactory = $displayFactory;
155
 
        $this->scheduleFactory = $scheduleFactory;
156
 
    }
157
 
 
158
 
    /**
159
42
     * Display the module page
160
43
     */
161
44
    function displayPage()
162
45
    {
 
46
        $data = [];
 
47
 
 
48
        // Do we have any modules to install?!
 
49
        if (Config::GetSetting('MODULE_CONFIG_LOCKED_CHECKB') != 'Checked') {
 
50
            // Get a list of matching files in the modules folder
 
51
            $files = glob(PROJECT_ROOT . '/modules/*.json');
 
52
 
 
53
            // Get a list of all currently installed modules
 
54
            $installed = [];
 
55
            $data['modulesToInstall'] = [];
 
56
 
 
57
            foreach (ModuleFactory::query() as $row) {
 
58
                /* @var \Xibo\Entity\Module $row */
 
59
                $installed[] = $row->type;
 
60
            }
 
61
 
 
62
            // Compare the two
 
63
            foreach ($files as $file) {
 
64
                // Check to see if the module has already been installed
 
65
                $fileName = explode('.', basename($file));
 
66
 
 
67
                if (in_array($fileName[0], $installed))
 
68
                    continue;
 
69
 
 
70
                // If not, open it up and get some information about it
 
71
                $data['modulesToInstall'][] = json_decode(file_get_contents($file));
 
72
            }
 
73
        }
 
74
 
163
75
        $this->getState()->template = 'module-page';
164
 
        $this->getState()->setData([
165
 
            'modulesToInstall' => $this->getInstallableModules()
166
 
        ]);
 
76
        $this->getState()->setData($data);
167
77
    }
168
78
 
169
79
    /**
170
80
     * A grid of modules
171
 
     * @throws XiboException
172
81
     */
173
82
    public function grid()
174
83
    {
175
 
        $modules = $this->moduleFactory->query($this->gridRenderSort(), $this->gridRenderFilter());
 
84
        $modules = ModuleFactory::query($this->gridRenderSort(), $this->gridRenderFilter());
176
85
 
177
86
        foreach ($modules as $module) {
178
87
            /* @var \Xibo\Entity\Module $module */
182
91
 
183
92
            $module->includeProperty('buttons');
184
93
 
185
 
            // Edit button
186
 
            $module->buttons[] = array(
187
 
                'id' => 'module_button_edit',
188
 
                'url' => $this->urlFor('module.settings.form', ['id' => $module->moduleId]),
189
 
                'text' => __('Edit')
190
 
            );
 
94
            // If the module config is not locked, present some buttons
 
95
            if (Config::GetSetting('MODULE_CONFIG_LOCKED_CHECKB') != 'Checked') {
191
96
 
192
 
            // Clear cache
193
 
            if ($module->regionSpecific == 1) {
 
97
                // Edit button
194
98
                $module->buttons[] = array(
195
 
                    'id' => 'module_button_clear_cache',
196
 
                    'url' => $this->urlFor('module.clear.cache.form', ['id' => $module->moduleId]),
197
 
                    'text' => __('Clear Cache')
 
99
                    'id' => 'module_button_edit',
 
100
                    'url' => $this->urlFor('module.settings.form', ['id' => $module->moduleId]),
 
101
                    'text' => __('Edit')
198
102
                );
199
103
            }
200
104
 
201
 
            // Create a module object and return any buttons it may require
202
 
            $moduleObject = $this->moduleFactory->create($module->type);
203
 
 
204
105
            // Are there any buttons we need to provide as part of the module?
205
 
            foreach ($moduleObject->settingsButtons() as $button) {
206
 
                $button['text'] = __($button['text']);
207
 
                $module->buttons[] = $button;
 
106
            if (isset($module->settings['buttons'])) {
 
107
                foreach ($module->settings['buttons'] as $button) {
 
108
                    $button['text'] = __($button['text']);
 
109
                    $module->buttons[] = $button;
 
110
                }
208
111
            }
209
112
        }
210
113
 
211
114
        $this->getState()->template = 'grid';
212
 
        $this->getState()->recordsTotal = $this->moduleFactory->countLast();
 
115
        $this->getState()->recordsTotal = ModuleFactory::countLast();
213
116
        $this->getState()->setData($modules);
214
117
    }
215
118
 
216
119
    /**
217
120
     * Settings Form
218
121
     * @param int $moduleId
219
 
     * @throws XiboException
220
122
     */
221
123
    public function settingsForm($moduleId)
222
124
    {
223
125
        // Can we edit?
224
 
        $moduleConfigLocked = ($this->getConfig()->GetSetting('MODULE_CONFIG_LOCKED_CHECKB') == 'Checked');
 
126
        if (Config::GetSetting('MODULE_CONFIG_LOCKED_CHECKB') == 'Checked')
 
127
            throw new \InvalidArgumentException(__('Module Config Locked'));
225
128
 
226
129
        if (!$this->getUser()->userTypeId == 1)
227
130
            throw new AccessDeniedException();
228
131
 
229
 
        $module = $this->moduleFactory->createById($moduleId);
 
132
        $module = ModuleFactory::createById($moduleId);
230
133
 
231
134
        $moduleFields = $module->settingsForm();
232
135
 
233
136
        // Pass to view
234
137
        $this->getState()->template = ($moduleFields == null) ? 'module-form-settings' : $moduleFields;
235
138
        $this->getState()->setData([
236
 
            'moduleConfigLocked' => $moduleConfigLocked,
237
139
            'module' => $module,
238
 
            'help' => $this->getHelp()->link('Module', 'Edit')
 
140
            'help' => Help::Link('Module', 'Edit')
239
141
        ]);
240
142
    }
241
143
 
242
144
    /**
243
145
     * Settings
244
146
     * @param int $moduleId
245
 
     * @throws XiboException
246
147
     */
247
148
    public function settings($moduleId)
248
149
    {
249
150
        // Can we edit?
250
 
        $moduleConfigLocked = ($this->getConfig()->GetSetting('MODULE_CONFIG_LOCKED_CHECKB') == 'Checked');
 
151
        if (Config::GetSetting('MODULE_CONFIG_LOCKED_CHECKB') == 'Checked')
 
152
            throw new \InvalidArgumentException(__('Module Config Locked'));
251
153
 
252
154
        if (!$this->getUser()->userTypeId == 1)
253
155
            throw new AccessDeniedException();
254
156
 
255
 
        $module = $this->moduleFactory->createById($moduleId);
256
 
        $module->getModule()->defaultDuration = $this->getSanitizer()->getInt('defaultDuration');
257
 
        $module->getModule()->validExtensions = $this->getSanitizer()->getString('validExtensions');
258
 
        $module->getModule()->enabled = $this->getSanitizer()->getCheckbox('enabled');
259
 
        $module->getModule()->previewEnabled = $this->getSanitizer()->getCheckbox('previewEnabled');
260
 
 
261
 
        if (!$moduleConfigLocked)
262
 
            $module->getModule()->imageUri = $this->getSanitizer()->getString('imageUri');
263
 
 
264
 
        // Validation
265
 
        if (strpbrk($module->getModule()->validExtensions, '*.{}[]|') !== false)
266
 
            throw new InvalidArgumentException('Comma separated file extensions only please, without the .', 'validExtensions');
 
157
        $module = ModuleFactory::createById($moduleId);
 
158
        $module->getModule()->validExtensions = Sanitize::getString('validExtensions');
 
159
        $module->getModule()->imageUri = Sanitize::getString('imageUri');
 
160
        $module->getModule()->enabled = Sanitize::getString('enabled');
 
161
        $module->getModule()->previewEnabled = Sanitize::getString('previewEnabled');
267
162
 
268
163
        // Install Files for this module
269
164
        $module->installFiles();
290
185
        // Pass to view
291
186
        $this->getState()->template = 'module-form-verify';
292
187
        $this->getState()->setData([
293
 
            'help' => $this->getHelp()->link('Module', 'Edit')
 
188
            'help' => Help::Link('Module', 'Edit')
294
189
        ]);
295
190
    }
296
191
 
297
192
    /**
298
193
     * Verify Module
299
 
     * @throws \Exception
300
194
     */
301
195
    public function verify()
302
196
    {
303
197
        // Set all files to valid = 0
304
 
        $this->store->update('UPDATE `media` SET valid = 0 WHERE moduleSystemFile = 1', []);
 
198
        PDOConnect::update('UPDATE `media` SET valid = 0 WHERE moduleSystemFile = 1', []);
305
199
 
306
200
        // Install all files
307
 
        $this->getApp()->container->get('\Xibo\Controller\Library')->installAllModuleFiles();
 
201
        Library::installAllModuleFiles();
308
202
 
309
203
        // Successful
310
204
        $this->getState()->hydrate([
313
207
    }
314
208
 
315
209
    /**
316
 
     * Form for the install list
317
 
     * @throws XiboException
318
 
     */
319
 
    public function installListForm()
320
 
    {
321
 
        // Use the name to get details about this module.
322
 
        $modules = $this->getInstallableModules();
323
 
 
324
 
        if (count($modules) <= 0)
325
 
            throw new InvalidArgumentException(__('Sorry, no modules available to install'), 'modules');
326
 
 
327
 
        $this->getState()->template = 'module-form-install-list';
328
 
        $this->getState()->setData([
329
 
            'modulesToInstall' => $modules,
330
 
            'help' => $this->getHelp()->link('Module', 'Install')
331
 
        ]);
332
 
    }
333
 
 
334
 
    /**
335
210
     * @param string $name
336
 
     * @throws InvalidArgumentException
337
211
     */
338
212
    public function installForm($name)
339
213
    {
340
 
        // Check the module hasn't already been installed
341
 
        if ($this->checkModuleInstalled($name))
342
 
            throw new InvalidArgumentException(__('Module already installed'), 'install');
 
214
        if (!file_exists('../modules/' . $name . '.json'))
 
215
            throw new \InvalidArgumentException(__('Invalid module'));
343
216
 
344
217
        // Use the name to get details about this module.
345
 
        if (file_exists(PROJECT_ROOT . '/modules/' . $name . '.json'))
346
 
            $module = json_decode(file_get_contents(PROJECT_ROOT . '/modules/' . $name . '.json'));
347
 
        else if (file_exists(PROJECT_ROOT . '/custom/' . $name . '.json'))
348
 
            $module = json_decode(file_get_contents(PROJECT_ROOT . '/custom/' . $name . '.json'));
349
 
        else
350
 
            throw new \InvalidArgumentException(__('Invalid module'));
351
 
 
 
218
        $module = json_decode(file_get_contents('../modules/' . $name . '.json'));
352
219
 
353
220
        $this->getState()->template = 'module-form-install';
354
221
        $this->getState()->setData([
355
222
            'module' => $module,
356
 
            'help' => $this->getHelp()->link('Module', 'Install')
 
223
            'help' => Help::Link('Module', 'Install')
357
224
        ]);
358
225
    }
359
226
 
360
227
    /**
361
228
     * Install Module
362
229
     * @param string $name
363
 
     * @throws XiboException
364
230
     */
365
231
    public function install($name)
366
232
    {
367
 
        $this->getLog()->notice('Request to install Module: ' . $name);
368
 
 
369
 
        // Check the module hasn't already been installed
370
 
        if ($this->checkModuleInstalled($name))
371
 
            throw new InvalidArgumentException(__('Module already installed'), 'install');
372
 
 
373
 
        if (file_exists(PROJECT_ROOT . '/modules/' . $name . '.json'))
374
 
            $moduleDetails = json_decode(file_get_contents(PROJECT_ROOT . '/modules/' . $name . '.json'));
375
 
        else if (file_exists(PROJECT_ROOT . '/custom/' . $name . '.json'))
376
 
            $moduleDetails = json_decode(file_get_contents(PROJECT_ROOT . '/custom/' . $name . '.json'));
377
 
        else
 
233
        Log::notice('Request to install Module: ' . $name);
 
234
 
 
235
        if (!file_exists('../modules/' . $name . '.json'))
378
236
            throw new \InvalidArgumentException(__('Invalid module'));
379
237
 
 
238
        // Use the name to get details about this module.
 
239
        $moduleDetails = json_decode(file_get_contents('../modules/' . $name . '.json'));
 
240
 
380
241
        // All modules should be capable of autoload
381
 
        $module = $this->moduleFactory->createForInstall($moduleDetails->class);
382
 
        $module->setUser($this->getUser());
383
 
        $module->installOrUpdate($this->moduleFactory);
 
242
        $module = ModuleFactory::createForInstall($moduleDetails->class);
 
243
        $module->installOrUpdate();
384
244
 
385
 
        $this->getLog()->notice('Module Installed: ' . $module->getModuleType());
 
245
        Log::notice('Module Installed: ' . $module->getModuleType());
386
246
 
387
247
        // Excellent... capital... success
388
248
        $this->getState()->hydrate([
395
255
     * Add Widget Form
396
256
     * @param string $type
397
257
     * @param int $playlistId
398
 
     * @throws XiboException
399
258
     */
400
259
    public function addWidgetForm($type, $playlistId)
401
260
    {
402
 
        $playlist = $this->playlistFactory->getById($playlistId);
 
261
        $playlist = PlaylistFactory::getById($playlistId);
403
262
 
404
263
        if (!$this->getUser()->checkEditable($playlist))
405
264
            throw new AccessDeniedException();
406
265
 
407
266
        // Create a module to use
408
 
        $module = $this->moduleFactory->createForWidget($type, null, $this->getUser()->userId, $playlistId);
 
267
        $module = ModuleFactory::createForWidget($type, null, $this->getUser()->userId, $playlistId);
409
268
 
410
269
        // Pass to view
411
 
        $this->getState()->template = $module->addForm();
412
 
        $this->getState()->setData($module->setTemplateData([
 
270
        $this->getState()->template = $module->getModuleType() . '-form-add';
 
271
        $this->getState()->setData([
413
272
            'playlist' => $playlist,
414
 
            'media' => $this->mediaFactory->query(),
 
273
            'media' => MediaFactory::query(),
415
274
            'module' => $module
416
 
        ]));
 
275
        ]);
417
276
    }
418
277
 
419
278
    /**
420
279
     * Add Widget
421
280
     * @param string $type
422
281
     * @param int $playlistId
423
 
     * @throws XiboException
424
282
     */
425
283
    public function addWidget($type, $playlistId)
426
284
    {
427
 
        $playlist = $this->playlistFactory->getById($playlistId);
 
285
        $playlist = PlaylistFactory::getById($playlistId);
428
286
 
429
287
        if (!$this->getUser()->checkEditable($playlist))
430
288
            throw new AccessDeniedException();
431
289
 
432
 
        // Check we have a permission factory
433
 
        if ($this->permissionFactory == null)
434
 
            throw new ConfigurationException(__('Sorry there is an error with this request, cannot set inherited permissions'));
435
 
 
436
290
        // Load some information about this playlist
437
 
        $playlist->setChildObjectDependencies($this->regionFactory);
438
291
        $playlist->load([
439
292
            'playlistIncludeRegionAssignments' => false,
440
293
            'loadWidgets' => false
441
294
        ]);
442
295
 
443
296
        // Create a module to use
444
 
        $module = $this->moduleFactory->createForWidget($type, null, $this->getUser()->userId, $playlistId);
 
297
        $module = ModuleFactory::createForWidget($type, null, $this->getUser()->userId, $playlistId);
445
298
 
446
299
        // Inject the Current User
447
300
        $module->setUser($this->getUser());
450
303
        $module->add();
451
304
 
452
305
        // Permissions
453
 
        if ($this->getConfig()->GetSetting('INHERIT_PARENT_PERMISSIONS') == 1) {
 
306
        if (Config::GetSetting('INHERIT_PARENT_PERMISSIONS') == 1) {
454
307
            // Apply permissions from the Parent
455
308
            foreach ($playlist->permissions as $permission) {
456
309
                /* @var Permission $permission */
457
 
                $permission = $this->permissionFactory->create($permission->groupId, get_class($module->widget), $module->widget->getId(), $permission->view, $permission->edit, $permission->delete);
 
310
                $permission = PermissionFactory::create($permission->groupId, get_class($module->widget), $module->widget->getId(), $permission->view, $permission->edit, $permission->delete);
458
311
                $permission->save();
459
312
            }
460
313
        } else {
461
 
            foreach ($this->permissionFactory->createForNewEntity($this->getUser(), get_class($module->widget), $module->widget->getId(), $this->getConfig()->GetSetting('LAYOUT_DEFAULT'), $this->userGroupFactory) as $permission) {
 
314
            foreach (PermissionFactory::createForNewEntity($this->getUser(), get_class($module->widget), $module->widget->getId(), Config::GetSetting('LAYOUT_DEFAULT')) as $permission) {
462
315
                /* @var Permission $permission */
463
316
                $permission->save();
464
317
            }
466
319
 
467
320
        // Successful
468
321
        $this->getState()->hydrate([
469
 
            'httpStatus' => 201,
470
322
            'message' => sprintf(__('Added %s'), $module->getName()),
471
323
            'id' => $module->widget->widgetId,
472
 
            'data' => $module->widget
 
324
            'data' => $module
473
325
        ]);
474
326
    }
475
327
 
476
328
    /**
477
329
     * Edit Widget Form
478
330
     * @param int $widgetId
479
 
     * @throws XiboException
480
331
     */
481
332
    public function editWidgetForm($widgetId)
482
333
    {
483
 
        $module = $this->moduleFactory->createWithWidget($this->widgetFactory->loadByWidgetId($widgetId));
 
334
        $module = ModuleFactory::createWithWidget(WidgetFactory::loadByWidgetId($widgetId));
484
335
 
485
336
        if (!$this->getUser()->checkEditable($module->widget))
486
337
            throw new AccessDeniedException();
487
338
 
488
339
        // Pass to view
489
 
        $this->getState()->template = $module->editForm();
490
 
        $this->getState()->setData($module->setTemplateData([
 
340
        $this->getState()->template = $module->getModuleType() . '-form-edit';
 
341
        $this->getState()->setData([
491
342
            'module' => $module,
492
 
            'media' => $this->mediaFactory->query(),
 
343
            'media' => MediaFactory::query(),
493
344
            'validExtensions' => str_replace(',', '|', $module->getModule()->validExtensions)
494
 
        ]));
 
345
        ]);
495
346
    }
496
347
 
497
348
    /**
498
 
     * Edit a Widget
499
 
     * @SWG\Put(
500
 
     *  path="/playlist/widget/{widgetId}",
501
 
     *  operationId="WidgetEdit",
502
 
     *  tags={"widget"},
503
 
     *  summary="Edit a Widget",
504
 
     *  description="Edit a Widget, please refer to individual widget Add documentation for module specific parameters",
505
 
     *  @SWG\Parameter(
506
 
     *      name="widgetId",
507
 
     *      in="path",
508
 
     *      description="The widget ID to edit",
509
 
     *      type="integer",
510
 
     *      required=true
511
 
     *   ),
512
 
     *  @SWG\Response(
513
 
     *      response=201,
514
 
     *      description="successful operation",
515
 
     *      @SWG\Schema(ref="#/definitions/Widget"),
516
 
     *      @SWG\Header(
517
 
     *          header="Location",
518
 
     *          description="Location of the edited widget",
519
 
     *          type="string"
520
 
     *      )
521
 
     * )
522
 
     *)
523
 
     *
 
349
     * Edit Widget
524
350
     * @param int $widgetId
525
 
     * @throws XiboException
526
351
     */
527
352
    public function editWidget($widgetId)
528
353
    {
529
 
        $module = $this->moduleFactory->createWithWidget($this->widgetFactory->loadByWidgetId($widgetId));
 
354
        $module = ModuleFactory::createWithWidget(WidgetFactory::loadByWidgetId($widgetId));
530
355
 
531
356
        if (!$this->getUser()->checkEditable($module->widget))
532
357
            throw new AccessDeniedException();
541
366
        $this->getState()->hydrate([
542
367
            'message' => sprintf(__('Edited %s'), $module->getName()),
543
368
            'id' => $module->widget->widgetId,
544
 
            'data' => $module->widget
 
369
            'data' => $module
545
370
        ]);
546
371
    }
547
372
 
548
373
    /**
549
374
     * Delete Widget Form
550
375
     * @param int $widgetId
551
 
     * @throws XiboException
552
376
     */
553
377
    public function deleteWidgetForm($widgetId)
554
378
    {
555
 
        $module = $this->moduleFactory->createWithWidget($this->widgetFactory->loadByWidgetId($widgetId));
 
379
        $module = ModuleFactory::createWithWidget(WidgetFactory::loadByWidgetId($widgetId));
556
380
 
557
381
        if (!$this->getUser()->checkDeleteable($module->widget))
558
382
            throw new AccessDeniedException();
559
383
 
560
 
        // Set some dependencies that are used in the delete
561
 
        $module->setChildObjectDependencies($this->layoutFactory, $this->widgetFactory, $this->displayGroupFactory);
562
 
 
563
384
        // Pass to view
564
385
        $this->getState()->template = 'module-form-delete';
565
386
        $this->getState()->setData([
566
387
            'module' => $module,
567
 
            'help' => $this->getHelp()->link('Media', 'Delete')
 
388
            'help' => Help::Link('Media', 'Delete')
568
389
        ]);
569
390
    }
570
391
 
571
392
    /**
572
 
     * Delete a Widget
573
 
     * @SWG\Delete(
574
 
     *  path="/playlist/widget/{widgetId}",
575
 
     *  operationId="WidgetDelete",
576
 
     *  tags={"widget"},
577
 
     *  summary="Delete a Widget",
578
 
     *  description="Deleted a specified widget",
579
 
     *  @SWG\Parameter(
580
 
     *      name="widgetId",
581
 
     *      in="path",
582
 
     *      description="The widget ID to delete",
583
 
     *      type="integer",
584
 
     *      required=true
585
 
     *   ),
586
 
     *  @SWG\Response(
587
 
     *      response=200,
588
 
     *      description="successful operation",
589
 
     *  )
590
 
     *)
591
 
     *
 
393
     * Delete Widget
592
394
     * @param int $widgetId
593
 
     * @throws XiboException
594
395
     */
595
396
    public function deleteWidget($widgetId)
596
397
    {
597
 
        $module = $this->moduleFactory->createWithWidget($this->widgetFactory->loadByWidgetId($widgetId));
 
398
        $module = ModuleFactory::createWithWidget(WidgetFactory::loadByWidgetId($widgetId));
598
399
 
599
400
        if (!$this->getUser()->checkDeleteable($module->widget))
600
401
            throw new AccessDeniedException();
601
402
 
602
 
        // Set some dependencies that are used in the delete
603
 
        $module->setChildObjectDependencies($this->layoutFactory, $this->widgetFactory, $this->displayGroupFactory);
604
 
 
605
403
        $moduleName = $module->getName();
606
404
        $widgetMedia = $module->widget->mediaIds;
607
405
 
615
413
        $module->widget->delete();
616
414
 
617
415
        // Delete Media?
618
 
        if ($this->getSanitizer()->getCheckbox('deleteMedia') == 1) {
 
416
        if (Sanitize::getCheckbox('deleteMedia') == 1) {
619
417
            foreach ($widgetMedia as $mediaId) {
620
 
                $media = $this->mediaFactory->getById($mediaId);
 
418
                $media = MediaFactory::getById($mediaId);
621
419
 
622
420
                // Check we have permissions to delete
623
421
                if (!$this->getUser()->checkDeleteable($media))
624
422
                    throw new AccessDeniedException();
625
423
 
626
 
                $media->setChildObjectDependencies($this->layoutFactory, $this->widgetFactory, $this->displayGroupFactory, $this->displayFactory, $this->scheduleFactory);
627
 
 
628
424
                $media->delete();
629
425
            }
630
426
        }
639
435
     * Edit Widget Transition Form
640
436
     * @param string $type
641
437
     * @param int $widgetId
642
 
     * @throws XiboException
643
438
     */
644
439
    public function editWidgetTransitionForm($type, $widgetId)
645
440
    {
646
 
        $module = $this->moduleFactory->createWithWidget($this->widgetFactory->loadByWidgetId($widgetId));
 
441
        $module = ModuleFactory::createWithWidget(WidgetFactory::loadByWidgetId($widgetId));
647
442
 
648
443
        if (!$this->getUser()->checkEditable($module->widget))
649
444
            throw new AccessDeniedException();
654
449
            'type' => $type,
655
450
            'module' => $module,
656
451
            'transitions' => [
657
 
                'in' => $this->transitionFactory->getEnabledByType('in'),
658
 
                'out' => $this->transitionFactory->getEnabledByType('out'),
 
452
                'in' => TransitionFactory::getEnabledByType('in'),
 
453
                'out' => TransitionFactory::getEnabledByType('out'),
659
454
                'compassPoints' => array(
660
455
                    array('id' => 'N', 'name' => __('North')),
661
456
                    array('id' => 'NE', 'name' => __('North East')),
667
462
                    array('id' => 'NW', 'name' => __('North West'))
668
463
                )
669
464
            ],
670
 
            'help' => $this->getHelp()->link('Transition', 'Edit')
 
465
            'help' => Help::Link('Transition', 'Edit')
671
466
        ]);
672
467
    }
673
468
 
674
469
    /**
675
 
     * Edit Widget transition
676
 
     * @SWG\Put(
677
 
     *  path="/playlist/widget/transition/{type}/{widgetId}",
678
 
     *  operationId="WidgetEditTransition",
679
 
     *  tags={"widget"},
680
 
     *  summary="Adds In/Out transition",
681
 
     *  description="Adds In/Out transition to a specified widget",
682
 
     *  @SWG\Parameter(
683
 
     *      name="type",
684
 
     *      in="path",
685
 
     *      description="Transition type, available options: in, out",
686
 
     *      type="string",
687
 
     *      required=true
688
 
     *   ),
689
 
     *  @SWG\Parameter(
690
 
     *      name="widgetId",
691
 
     *      in="path",
692
 
     *      description="The widget ID to add the transition to",
693
 
     *      type="integer",
694
 
     *      required=true
695
 
     *   ),
696
 
     *  @SWG\Parameter(
697
 
     *      name="transitionType",
698
 
     *      in="formData",
699
 
     *      description="Type of a transition, available Options: fly, fadeIn, fadeOut",
700
 
     *      type="string",
701
 
     *      required=true
702
 
     *  ),
703
 
     *  @SWG\Parameter(
704
 
     *      name="transitionDuration",
705
 
     *      in="formData",
706
 
     *      description="Duration of this transition in milliseconds",
707
 
     *      type="integer",
708
 
     *      required=false
709
 
     *  ),
710
 
     *  @SWG\Parameter(
711
 
     *      name="transitionDirection",
712
 
     *      in="formData",
713
 
     *      description="The direction for this transition, only appropriate for transitions that move, such as fly. Available options: N, NE, E, SE, S, SW, W, NW",
714
 
     *      type="integer",
715
 
     *      required=false
716
 
     *   ),
717
 
     *  @SWG\Response(
718
 
     *      response=201,
719
 
     *      description="successful operation",
720
 
     *      @SWG\Schema(ref="#/definitions/Widget"),
721
 
     *      @SWG\Header(
722
 
     *          header="Location",
723
 
     *          description="Location of the new widget",
724
 
     *          type="string"
725
 
     *      )
726
 
     *   )
727
 
     * )
728
 
     *
 
470
     * Edit Widget Transition
729
471
     * @param string $type
730
472
     * @param int $widgetId
731
473
     */
732
474
    public function editWidgetTransition($type, $widgetId)
733
475
    {
734
 
        $widget = $this->widgetFactory->getById($widgetId);
 
476
        $widget = WidgetFactory::getById($widgetId);
735
477
 
736
478
        if (!$this->getUser()->checkEditable($widget))
737
479
            throw new AccessDeniedException();
740
482
 
741
483
        switch ($type) {
742
484
            case 'in':
743
 
                $widget->setOptionValue('transIn', 'attrib', $this->getSanitizer()->getString('transitionType'));
744
 
                $widget->setOptionValue('transInDuration', 'attrib', $this->getSanitizer()->getInt('transitionDuration'));
745
 
                $widget->setOptionValue('transInDirection', 'attrib', $this->getSanitizer()->getString('transitionDirection'));
 
485
                $widget->setOptionValue('transIn', 'attrib', Sanitize::getString('transitionType'));
 
486
                $widget->setOptionValue('transInDuration', 'attrib', Sanitize::getInt('transitionDuration'));
 
487
                $widget->setOptionValue('transInDirection', 'attrib', Sanitize::getString('transitionDirection'));
746
488
 
747
489
                break;
748
490
 
749
491
            case 'out':
750
 
                $widget->setOptionValue('transOut', 'attrib', $this->getSanitizer()->getString('transitionType'));
751
 
                $widget->setOptionValue('transOutDuration', 'attrib', $this->getSanitizer()->getInt('transitionDuration'));
752
 
                $widget->setOptionValue('transOutDirection', 'attrib', $this->getSanitizer()->getString('transitionDirection'));
 
492
                $widget->setOptionValue('transOut', 'attrib', Sanitize::getString('transitionType'));
 
493
                $widget->setOptionValue('transOutDuration', 'attrib', Sanitize::getInt('transitionDuration'));
 
494
                $widget->setOptionValue('transOutDirection', 'attrib', Sanitize::getString('transitionDirection'));
753
495
 
754
496
                break;
755
497
 
768
510
    }
769
511
 
770
512
    /**
771
 
     * Widget Audio Form
772
 
     * @param int $widgetId
773
 
     * @throws XiboException
774
 
     */
775
 
    public function widgetAudioForm($widgetId)
776
 
    {
777
 
        $module = $this->moduleFactory->createWithWidget($this->widgetFactory->loadByWidgetId($widgetId));
778
 
 
779
 
        if (!$this->getUser()->checkEditable($module->widget))
780
 
            throw new AccessDeniedException();
781
 
 
782
 
        $audioAvailable = true;
783
 
        if ($module->widget->countAudio() > 0) {
784
 
            $audio = $this->mediaFactory->getById($module->widget->getAudioIds()[0]);
785
 
 
786
 
            $this->getLog()->debug('Found audio: ' . $audio->mediaId . ', isEdited = ' . $audio->isEdited . ', retired = ' . $audio->retired);
787
 
            $audioAvailable = ($audio->isEdited == 0 && $audio->retired == 0);
788
 
        }
789
 
 
790
 
        // Pass to view
791
 
        $this->getState()->template = 'module-form-audio';
792
 
        $this->getState()->setData([
793
 
            'module' => $module,
794
 
            'media' => $this->mediaFactory->getByMediaType('audio'),
795
 
            'isAudioAvailable' => $audioAvailable
796
 
        ]);
797
 
    }
798
 
 
799
 
    /**
800
 
     * Edit an Audio Widget
801
 
     * @SWG\Put(
802
 
     *  path="/playlist/widget/{widgetId}/audio",
803
 
     *  operationId="WidgetAssignedAudioEdit",
804
 
     *  tags={"widget"},
805
 
     *  summary="Parameters for edting/adding audio file to a specific widget",
806
 
     *  description="Parameters for edting/adding audio file to a specific widget",
807
 
     *  @SWG\Parameter(
808
 
     *      name="widgetId",
809
 
     *      in="path",
810
 
     *      description="Id of a widget to which you want to add audio or edit existing audio",
811
 
     *      type="integer",
812
 
     *      required=true
813
 
     *  ),
814
 
     *  @SWG\Parameter(
815
 
     *      name="mediaId",
816
 
     *      in="formData",
817
 
     *      description="Id of a audio file in CMS library you wish to add to a widget",
818
 
     *      type="integer",
819
 
     *      required=false
820
 
     *  ),
821
 
     *  @SWG\Parameter(
822
 
     *      name="volume",
823
 
     *      in="formData",
824
 
     *      description="Volume percentage(0-100) for this audio to play at",
825
 
     *      type="integer",
826
 
     *      required=false
827
 
     *  ),
828
 
     *  @SWG\Parameter(
829
 
     *      name="loop",
830
 
     *      in="formData",
831
 
     *      description="Flag (0, 1) Should the audio loop if it finishes before the widget has finished?",
832
 
     *      type="integer",
833
 
     *      required=false
834
 
     *   ),
835
 
     *  @SWG\Response(
836
 
     *      response=200,
837
 
     *      description="successful operation",
838
 
     *      @SWG\Schema(ref="#/definitions/Widget"),
839
 
     *      @SWG\Header(
840
 
     *          header="Location",
841
 
     *          description="Location of the new widget",
842
 
     *          type="string"
843
 
     *      )
844
 
     *  )
845
 
     * )
846
 
     *
847
 
     * @param int $widgetId
848
 
     */
849
 
    public function widgetAudio($widgetId)
850
 
    {
851
 
        $widget = $this->widgetFactory->getById($widgetId);
852
 
 
853
 
        if (!$this->getUser()->checkEditable($widget))
854
 
            throw new AccessDeniedException();
855
 
 
856
 
        $widget->load();
857
 
 
858
 
        // Pull in the parameters we are expecting from the form.
859
 
        $mediaId = $this->getSanitizer()->getInt('mediaId');
860
 
        $volume = $this->getSanitizer()->getInt('volume', 100);
861
 
        $loop = $this->getSanitizer()->getCheckbox('loop');
862
 
 
863
 
        // Remove existing audio records.
864
 
        foreach ($widget->audio as $audio) {
865
 
            $widget->unassignAudio($audio);
866
 
        }
867
 
 
868
 
        if ($mediaId != 0) {
869
 
            $widgetAudio = $this->widgetAudioFactory->createEmpty();
870
 
            $widgetAudio->mediaId = $mediaId;
871
 
            $widgetAudio->volume = $volume;
872
 
            $widgetAudio->loop = $loop;
873
 
 
874
 
            $widget->assignAudio($widgetAudio);
875
 
        }
876
 
 
877
 
        $widget->save();
878
 
 
879
 
        // Successful
880
 
        $this->getState()->hydrate([
881
 
            'message' => sprintf(__('Edited Audio')),
882
 
            'id' => $widget->widgetId,
883
 
            'data' => $widget
884
 
        ]);
885
 
    }
886
 
 
887
 
    /**
888
 
     * Delete an Assigned Audio Widget
889
 
     * @SWG\Delete(
890
 
     *  path="/playlist/widget/{widgetId}/audio",
891
 
     *  operationId="WidgetAudioDelete",
892
 
     *  tags={"widget"},
893
 
     *  summary="Delete assigned audio widget",
894
 
     *  description="Delete assigned audio widget from specified widget ID",
895
 
     *  @SWG\Parameter(
896
 
     *      name="widgetId",
897
 
     *      in="path",
898
 
     *      description="Id of a widget from which you want to delete the audio from",
899
 
     *      type="integer",
900
 
     *      required=true
901
 
     *  ),
902
 
     *  @SWG\Response(
903
 
     *      response=200,
904
 
     *      description="successful operation",
905
 
     *  )
906
 
     *)
907
 
     *
908
 
     * @param int $widgetId
909
 
     */
910
 
    public function widgetAudioDelete($widgetId)
911
 
    {
912
 
        $widget = $this->widgetFactory->getById($widgetId);
913
 
 
914
 
        if (!$this->getUser()->checkEditable($widget))
915
 
            throw new AccessDeniedException();
916
 
 
917
 
        $widget->load();
918
 
 
919
 
        foreach ($widget->audio as $audio) {
920
 
            $widget->unassignAudio($audio);
921
 
        }
922
 
 
923
 
        $widget->save();
924
 
 
925
 
        // Successful
926
 
        $this->getState()->hydrate([
927
 
            'message' => sprintf(__('Removed Audio')),
928
 
            'id' => $widget->widgetId,
929
 
            'data' => $widget
930
 
        ]);
931
 
    }
932
 
 
933
 
    /**
934
513
     * Get Tab
935
514
     * @param string $tab
936
515
     * @param int $widgetId
937
 
     * @throws XiboException
 
516
     * @throws \Xibo\Exception\NotFoundException
938
517
     */
939
518
    public function getTab($tab, $widgetId)
940
519
    {
941
 
        $module = $this->moduleFactory->createWithWidget($this->widgetFactory->loadByWidgetId($widgetId));
 
520
        $module = ModuleFactory::createWithWidget(WidgetFactory::loadByWidgetId($widgetId));
942
521
 
943
522
        if (!$this->getUser()->checkViewable($module->widget))
944
523
            throw new AccessDeniedException();
949
528
    }
950
529
 
951
530
    /**
952
 
     * @param $type
953
 
     * @param $templateId
954
 
     * @throws XiboException
955
 
     */
956
 
    public function getTemplateImage($type, $templateId)
957
 
    {
958
 
        $module = $this->moduleFactory->create($type);
959
 
        $module->getTemplateImage($templateId);
960
 
        $this->setNoOutput(true);
961
 
    }
962
 
 
963
 
    /**
964
531
     * Get Resource
965
532
     * @param $regionId
966
533
     * @param $widgetId
967
 
     * @throws XiboException
 
534
     * @throws \Xibo\Exception\NotFoundException
968
535
     */
969
536
    public function getResource($regionId, $widgetId)
970
537
    {
971
 
        $module = $this->moduleFactory->createWithWidget($this->widgetFactory->loadByWidgetId($widgetId), $this->regionFactory->getById($regionId));
 
538
        $module = ModuleFactory::createWithWidget(WidgetFactory::loadByWidgetId($widgetId), RegionFactory::getById($regionId));
972
539
 
973
540
        if (!$this->getUser()->checkViewable($module->widget))
974
541
            throw new AccessDeniedException();
975
542
 
976
543
        // Call module GetResource
977
 
        $module->setUser($this->getUser());
978
544
        echo $module->getResource();
979
545
        $this->setNoOutput(true);
980
546
    }
981
 
 
982
 
    /**
983
 
     * @param $moduleId
984
 
     * @param $formName
985
 
     * @throws XiboException
986
 
     */
987
 
    public function customFormRender($moduleId, $formName)
988
 
    {
989
 
        $module = $this->moduleFactory->createById($moduleId);
990
 
 
991
 
        if (!method_exists($module, $formName))
992
 
            throw new ConfigurationException(__('Method does not exist'));
993
 
 
994
 
        $formDetails = $module->$formName();
995
 
 
996
 
        $this->getState()->template = $formDetails['template'];
997
 
        $this->getState()->setData($formDetails['data']);
998
 
    }
999
 
 
1000
 
    /**
1001
 
     * @param $moduleId
1002
 
     * @param $formName
1003
 
     * @throws XiboException
1004
 
     */
1005
 
    public function customFormExecute($moduleId, $formName)
1006
 
    {
1007
 
        $module = $this->moduleFactory->createById($moduleId);
1008
 
 
1009
 
        if (!method_exists($module, $formName))
1010
 
            throw new ConfigurationException(__('Method does not exist'));
1011
 
 
1012
 
        $module->$formName();
1013
 
        $this->setNoOutput(true);
1014
 
    }
1015
 
 
1016
 
    /**
1017
 
     * Get installable modules
1018
 
     * @return array
1019
 
     */
1020
 
    private function getInstallableModules()
1021
 
    {
1022
 
        $modules = [];
1023
 
 
1024
 
        // Do we have any modules to install?!
1025
 
        if ($this->getConfig()->GetSetting('MODULE_CONFIG_LOCKED_CHECKB') != 'Checked') {
1026
 
            // Get a list of matching files in the modules folder
1027
 
            $files = array_merge(glob(PROJECT_ROOT . '/modules/*.json'), glob(PROJECT_ROOT . '/custom/*.json'));
1028
 
 
1029
 
            // Get a list of all currently installed modules
1030
 
            $installed = [];
1031
 
 
1032
 
            foreach ($this->moduleFactory->query() as $row) {
1033
 
                /* @var \Xibo\Entity\Module $row */
1034
 
                $installed[] = $row->installName;
1035
 
            }
1036
 
 
1037
 
            // Compare the two
1038
 
            foreach ($files as $file) {
1039
 
                // Check to see if the module has already been installed
1040
 
                $fileName = explode('.', basename($file));
1041
 
 
1042
 
                if (in_array($fileName[0], $installed))
1043
 
                    continue;
1044
 
 
1045
 
                // If not, open it up and get some information about it
1046
 
                $modules[] = json_decode(file_get_contents($file));
1047
 
            }
1048
 
        }
1049
 
 
1050
 
        return $modules;
1051
 
    }
1052
 
 
1053
 
    /**
1054
 
     * Check whether a module is installed or not.
1055
 
     * @param string $name
1056
 
     * @return bool
1057
 
     */
1058
 
    private function checkModuleInstalled($name)
1059
 
    {
1060
 
        try {
1061
 
            $this->moduleFactory->getByInstallName($name);
1062
 
            return true;
1063
 
        } catch (NotFoundException $notFoundException) {
1064
 
            return false;
1065
 
        }
1066
 
    }
1067
 
 
1068
 
    /**
1069
 
     * Clear Cache Form
1070
 
     * @param $moduleId
1071
 
     * @throws XiboException
1072
 
     */
1073
 
    public function clearCacheForm($moduleId)
1074
 
    {
1075
 
        $module = $this->moduleFactory->getById($moduleId);
1076
 
 
1077
 
        $this->getState()->template = 'module-form-clear-cache';
1078
 
        $this->getState()->setData([
1079
 
            'module' => $module,
1080
 
            'help' => $this->getHelp()->link('Module', 'General')
1081
 
        ]);
1082
 
    }
1083
 
 
1084
 
    /**
1085
 
     * Clear Cache
1086
 
     * @param $moduleId
1087
 
     * @throws XiboException
1088
 
     */
1089
 
    public function clearCache($moduleId)
1090
 
    {
1091
 
        $module = $this->moduleFactory->createById($moduleId);
1092
 
        $module->dumpCacheForModule();
1093
 
 
1094
 
        $this->getState()->hydrate([
1095
 
            'message' => sprintf(__('Cleared the Cache'))
1096
 
        ]);
1097
 
    }
1098
547
}