Merge lp:~dangarner/xibo/server-133-wol into lp:xibo/1.3

Proposed by Dan Garner
Status: Merged
Approved by: Dan Garner
Approved revision: 243
Merged at revision: 235
Proposed branch: lp:~dangarner/xibo/server-133-wol
Merge into: lp:xibo/1.3
Diff against target: 1653 lines (+980/-455)
8 files modified
server/install/database/45.sql (+14/-0)
server/lib/data/display.data.class.php (+729/-418)
server/lib/data/schedule.data.class.php (+1/-1)
server/lib/include.php (+1/-1)
server/lib/pages/display.class.php (+166/-33)
server/lib/service/rest.class.php (+23/-1)
server/maintenance.php (+45/-0)
server/template/header.php (+1/-1)
To merge this branch: bzr merge lp:~dangarner/xibo/server-133-wol
Reviewer Review Type Date Requested Status
Xibo Maintainters Pending
Review via email: mp+102011@code.launchpad.net
To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'server/install/database/45.sql'
2--- server/install/database/45.sql 1970-01-01 00:00:00 +0000
3+++ server/install/database/45.sql 2012-04-14 10:54:18 +0000
4@@ -0,0 +1,14 @@
5+
6+ALTER TABLE `display` ADD `LastWakeOnLanCommandSent` INT NULL;
7+
8+ALTER TABLE `display` ADD `WakeOnLan` TINYINT NOT NULL DEFAULT 0;
9+
10+ALTER TABLE `display` ADD `WakeOnLanTime` VARCHAR(5) NULL;
11+
12+ALTER TABLE `display` ADD `BroadCastAddress` VARCHAR(100) NULL,
13+ ADD `SecureOn` VARCHAR(17) NULL,
14+ ADD `Cidr` SMALLINT NULL;
15+
16+UPDATE `version` SET `app_ver` = '1.3.3', `XmdsVersion` = 3;
17+UPDATE `setting` SET `value` = 0 WHERE `setting` = 'PHONE_HOME_DATE';
18+UPDATE `version` SET `DBVersion` = '45';
19\ No newline at end of file
20
21=== modified file 'server/lib/data/display.data.class.php'
22--- server/lib/data/display.data.class.php 2011-12-11 12:44:48 +0000
23+++ server/lib/data/display.data.class.php 2012-04-14 10:54:18 +0000
24@@ -1,418 +1,729 @@
25-<?php
26-/*
27- * Xibo - Digitial Signage - http://www.xibo.org.uk
28- * Copyright (C) 2009 Daniel Garner
29- *
30- * This file is part of Xibo.
31- *
32- * Xibo is free software: you can redistribute it and/or modify
33- * it under the terms of the GNU Affero General Public License as published by
34- * the Free Software Foundation, either version 3 of the License, or
35- * any later version.
36- *
37- * Xibo is distributed in the hope that it will be useful,
38- * but WITHOUT ANY WARRANTY; without even the implied warranty of
39- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40- * GNU Affero General Public License for more details.
41- *
42- * You should have received a copy of the GNU Affero General Public License
43- * along with Xibo. If not, see <http://www.gnu.org/licenses/>.
44- */
45-defined('XIBO') or die("Sorry, you are not allowed to directly access this page.<br /> Please press the back button in your browser.");
46-
47-class Display extends Data
48-{
49- public function __construct(database $db)
50- {
51- include_once('lib/data/displaygroup.data.class.php');
52-
53- parent::__construct($db);
54- }
55-
56- /**
57- * Adds a Display
58- * @return
59- * @param $display Object
60- * @param $isAuditing Object
61- * @param $defaultLayoutID Object
62- * @param $license Object
63- * @param $licensed Object
64- * @param $incSchedule Object
65- */
66- public function Add($display, $isAuditing, $defaultLayoutID, $license, $licensed, $incSchedule)
67- {
68- $db =& $this->db;
69-
70- Debug::LogEntry($db, 'audit', 'IN', 'DisplayGroup', 'Add');
71-
72- // Create the SQL
73- $SQL = "";
74- $SQL .= "INSERT ";
75- $SQL .= "INTO display ";
76- $SQL .= " ( ";
77- $SQL .= " display , ";
78- $SQL .= " isAuditing , ";
79- $SQL .= " defaultlayoutid, ";
80- $SQL .= " license , ";
81- $SQL .= " licensed , ";
82- $SQL .= " inc_schedule , ";
83- $SQL .= " email_alert , ";
84- $SQL .= " alert_timeout ";
85- $SQL .= " ) ";
86- $SQL .= " VALUES ";
87- $SQL .= " ( ";
88- $SQL .= sprintf(" '%s', ", $db->escape_string($display));
89- $SQL .= " 0 , ";
90- $SQL .= " 1 , ";
91- $SQL .= sprintf(" '%s', ", $db->escape_string($license));
92- $SQL .= " 0 , ";
93- $SQL .= " 0 , ";
94- $SQL .= " 1 , ";
95- $SQL .= " 0 ";
96- $SQL .= " )";
97-
98- if (!$displayID = $db->insert_query($SQL))
99- {
100- trigger_error($db->error());
101- $this->SetError(25000, __('Could not add display'));
102-
103- return false;
104- }
105-
106- // Also want to add the DisplayGroup associated with this Display.
107- $displayGroupObject = new DisplayGroup($db);
108-
109- if (!$displayGroupID = $displayGroupObject->Add($display, 1, ''))
110- {
111- $this->SetError(25001, __('Could not add a display group for the new display.'));
112-
113- return false;
114- }
115-
116- // Link the Two together
117- if (!$displayGroupObject->Link($displayGroupID, $displayID))
118- {
119- $this->SetError(25001, __('Could not link the new display with its group.'));
120-
121- return false;
122- }
123-
124- Debug::LogEntry($db, 'audit', 'OUT', 'DisplayGroup', 'Add');
125-
126- return $displayID;
127- }
128-
129- /**
130- * Edits a Display
131- * @return
132- * @param $displayID Object
133- * @param $isAuditing Object
134- * @param $defaultLayoutID Object
135- * @param $licensed Object
136- * @param $incSchedule Object
137- */
138- public function Edit($displayID, $display, $isAuditing, $defaultLayoutID, $licensed, $incSchedule, $email_alert, $alert_timeout)
139- {
140- $db =& $this->db;
141-
142- Debug::LogEntry($db, 'audit', 'IN', 'Display', 'Edit');
143-
144- // Check the number of licensed displays
145- $maxDisplays = Config::GetSetting($db, 'MAX_LICENSED_DISPLAYS');
146-
147- if ($maxDisplays > 0)
148- {
149- // See if this is a license switch
150- $currentLicense = $db->GetSingleValue(sprintf('SELECT licensed FROM display WHERE DisplayID = %d', $displayID), 'licensed', _INT);
151-
152- if ($currentLicense != $licensed && $licensed == 1)
153- {
154- // License change - test number of licensed displays.
155- $licensedDisplays = $db->GetSingleValue('SELECT COUNT(DisplayID) AS CountLicensed FROM display WHERE licensed =1 ', 'CountLicensed', _INT);
156-
157- if ($licensedDisplays + 1 > $maxDisplays)
158- return $this->SetError(25000, sprintf(__('You have exceeded your maximum number of licensed displays. %d'), $maxDisplays));
159- }
160- }
161-
162- // Update the display record
163- $SQL = "UPDATE display SET display = '%s', ";
164- $SQL .= " defaultlayoutid = %d, ";
165- $SQL .= " inc_schedule = %d, ";
166- $SQL .= " licensed = %d, ";
167- $SQL .= " isAuditing = %d, ";
168- $SQL .= " email_alert = %d, ";
169- $SQL .= " alert_timeout = %d ";
170- $SQL .= "WHERE displayid = %d ";
171-
172- $SQL = sprintf($SQL, $db->escape_string($display), $defaultLayoutID, $incSchedule, $licensed, $isAuditing, $email_alert, $alert_timeout, $displayID);
173-
174- Debug::LogEntry($db, 'audit', $SQL);
175-
176- if (!$db->query($SQL))
177- {
178- trigger_error($db->error());
179- $this->SetError(25000, __('Could not update display') . '-' . __('Stage 1'));
180-
181- return false;
182- }
183-
184- // Use a DisplayGroup to handle the default layout and displaygroup name for this display
185- $displayGroupObject = new DisplayGroup($db);
186-
187- // Do we also want to update the linked Display Groups name (seeing as that is what we will be presenting to everyone)
188- if (!$displayGroupObject->EditDisplayGroup($displayID, $display))
189- {
190- $this->SetError(25002, __('Could not update this display with a new name.'));
191-
192- return false;
193- }
194-
195- Debug::LogEntry($db, 'audit', 'OUT', 'DisplayGroup', 'Edit');
196-
197- return true;
198- }
199-
200- /**
201- * Deletes a Display
202- * @return
203- * @param $displayID Object
204- */
205- public function Delete($displayID)
206- {
207- $db =& $this->db;
208-
209- Debug::LogEntry($db, 'audit', 'IN', 'DisplayGroup', 'Delete');
210-
211- // Pass over to the DisplayGroup data class so that it can try and delete the
212- // display specific group first (it is that group which is linked to schedules)
213- $displayGroupObject = new DisplayGroup($db);
214-
215- // Do we also want to update the linked Display Groups name (seeing as that is what we will be presenting to everyone)
216- if (!$displayGroupObject->DeleteDisplay($displayID))
217- {
218- $this->SetError(25002, __('Could not delete this display.'));
219-
220- return false;
221- }
222-
223- // Delete the blacklist
224- $SQL = sprintf("DELETE FROM blacklist WHERE DisplayID = %d", $displayID);
225-
226- Debug::LogEntry($db, 'audit', $SQL);
227-
228- if (!$db->query($SQL))
229- return $this->SetError(25016,__('Unable to delete blacklist records.'));
230-
231- // Now we know the Display Group is gone - and so are any links
232- // delete the display
233- $SQL = " ";
234- $SQL .= "DELETE FROM display ";
235- $SQL .= sprintf(" WHERE displayid = %d", $displayID);
236-
237- Debug::LogEntry($db, 'audit', $SQL);
238-
239- if (!$db->query($SQL))
240- {
241- trigger_error($db->error());
242- $this->SetError(25015,__('Unable to delete display record. However it is no longer usable.'));
243-
244- return false;
245- }
246-
247- Debug::LogEntry($db, 'audit', 'OUT', 'DisplayGroup', 'Delete');
248-
249- return true;
250- }
251-
252- /**
253- * Edits a Displays Name
254- * @return
255- * @param $license Object
256- * @param $display Object
257- */
258- public function EditDisplayName($license, $display)
259- {
260- $db =& $this->db;
261-
262- Debug::LogEntry($db, 'audit', 'IN', 'DisplayGroup', 'EditDisplayName');
263-
264- $SQL = sprintf("UPDATE display SET display = '%s' WHERE license = '%s' ", $display, $license);
265-
266- if (!$db->query($SQL))
267- {
268- trigger_error($db->error());
269- $this->SetError(25010, __("Error updating this displays last accessed information."));
270-
271- return false;
272- }
273-
274- // Also need to update the display group name here.
275- $displayGroupObject = new DisplayGroup($db);
276-
277- // Do we also want to update the linked Display Groups name (seeing as that is what we will be presenting to everyone)
278- if (!$displayGroupObject->EditDisplayGroup($displayID, $display))
279- {
280- $this->SetError(25015, __('Could not update this display with a new name.'));
281-
282- return false;
283- }
284-
285- Debug::LogEntry($db, 'audit', 'OUT', 'DisplayGroup', 'EditDisplayName');
286-
287- return true;
288- }
289-
290- /**
291- * Sets the information required on the display to indicate
292- * that it is still logged in
293- * @return
294- * @param $license Object
295- */
296- public function Touch($license, $clientAddress = '', $mediaInventoryComplete = 0, $mediaInventoryXml = '', $macAddress = '')
297- {
298- $db =& $this->db;
299- $time = time();
300-
301- Debug::LogEntry($db, 'audit', 'IN', 'DisplayGroup', 'Touch');
302-
303- // Set the last accessed flag on the display
304- $SQL = "";
305- $SQL .= "UPDATE display SET lastaccessed = %d, loggedin = 1 ";
306-
307- // We will want to update the client Address if it is given
308- if ($clientAddress != '')
309- $SQL .= sprintf(" , ClientAddress = '%s' ", $db->escape_string($clientAddress));
310-
311- // Media Inventory Settings (if appropriate)
312- if ($mediaInventoryComplete != 0)
313- $SQL .= sprintf(" , MediaInventoryStatus = %d ", $mediaInventoryComplete);
314-
315- if ($mediaInventoryXml != '')
316- $SQL .= sprintf(" , MediaInventoryXml = '%s' ", $mediaInventoryXml);
317-
318- // Mac address storage
319- if ($macAddress != '')
320- {
321- // Address changed.
322- $currentAddress = $db->GetSingleValue(sprintf("SELECT MacAddress FROM display WHERE license = '%s'", $license), 'MacAddress', _STRING);
323-
324- if ($macAddress != $currentAddress)
325- {
326- $SQL .= sprintf(" , MacAddress = '%s', LastChanged = %d, NumberOfMacAddressChanges = NumberOfMacAddressChanges + 1 ", $macAddress, time());
327- }
328- }
329-
330- // Restrict to the display license
331- $SQL .= " WHERE license = '%s'";
332- $SQL = sprintf($SQL, $time, $license);
333-
334- if (!$result = $db->query($SQL))
335- {
336- trigger_error($db->error());
337- $this->SetError(25002, __("Error updating this displays last accessed information."));
338-
339- return false;
340- }
341-
342- Debug::LogEntry($db, 'audit', 'OUT', 'DisplayGroup', 'Touch');
343-
344- return true;
345- }
346-
347- /**
348- * Flags a display as being incomplete
349- * @param <type> $displayId
350- */
351- private function FlagIncomplete($displayId)
352- {
353- $db =& $this->db;
354-
355- Debug::LogEntry($db, 'audit', sprintf('Flag DisplayID %d incomplete.', $displayId), 'display', 'NotifyDisplays');
356-
357- $SQL = sprintf("UPDATE display SET MediaInventoryStatus = 3 WHERE displayID = %d", $displayId);
358-
359- if (!$db->query($SQL))
360- {
361- trigger_error($db->error());
362- return $this->SetError(25004, 'Unable to Flag Display as incomplete');
363- }
364-
365- return true;
366- }
367-
368- /**
369- * Notify displays of this layout change
370- * @param <type> $layoutId
371- */
372- public function NotifyDisplays($layoutId)
373- {
374- $db =& $this->db;
375- $currentdate = time();
376- $rfLookahead = Kit::ValidateParam(Config::GetSetting($db,'REQUIRED_FILES_LOOKAHEAD'), _INT);
377-
378- $rfLookahead = $currentdate + $rfLookahead;
379-
380- Debug::LogEntry($db, 'audit', sprintf('Checking for Displays to refresh on Layout %d', $layoutId), 'display', 'NotifyDisplays');
381-
382- // Which displays does a change to this layout effect?
383- $SQL = " SELECT DISTINCT display.DisplayID ";
384- $SQL .= " FROM schedule_detail ";
385- $SQL .= " INNER JOIN lkdisplaydg ";
386- $SQL .= " ON lkdisplaydg.DisplayGroupID = schedule_detail.DisplayGroupID ";
387- $SQL .= " INNER JOIN display ";
388- $SQL .= " ON lkdisplaydg.DisplayID = display.displayID ";
389- $SQL .= " WHERE schedule_detail.layoutID = %d ";
390- $SQL .= " AND schedule_detail.FromDT < %d AND schedule_detail.ToDT > %d ";
391- $SQL .= " UNION ";
392- $SQL .= " SELECT DisplayID FROM display WHERE DefaultLayoutID = %d";
393-
394- $SQL = sprintf($SQL, $layoutId, $rfLookahead, $currentdate - 3600, $layoutId);
395-
396- Debug::LogEntry($db, 'audit', $SQL, 'display', 'NotifyDisplays');
397-
398- if (!$result = $db->query($SQL))
399- {
400- trigger_error($db->error());
401- return $this->SetError(25037, __('Unable to get layouts for Notify'));
402- }
403-
404- while ($row = $db->get_assoc_row($result))
405- {
406- // Notify each display in turn
407- $displayId = Kit::ValidateParam($row['DisplayID'], _INT);
408- $this->FlagIncomplete($displayId);
409- }
410- }
411-
412- /**
413- * Edits the default layout for a display
414- * @param <type> $displayId
415- * @param <type> $defaultLayoutId
416- * @return <type>
417- */
418- public function EditDefaultLayout($displayId, $defaultLayoutId)
419- {
420- $db =& $this->db;
421-
422- Debug::LogEntry($db, 'audit', 'IN', 'Display', 'EditDefaultLayout');
423-
424- $SQL = sprintf('UPDATE display SET defaultLayoutId = %d WHERE displayID = %d ', $defaultLayoutId, $displayId);
425-
426- if (!$db->query($SQL))
427- {
428- trigger_error($db->error());
429- $this->SetError(25012, __('Error updating this displays default layout.'));
430-
431- return false;
432- }
433-
434- // Flag this display as not having all the content
435- $this->FlagIncomplete($displayId);
436-
437- Debug::LogEntry($db, 'audit', 'OUT', 'Display', 'EditDefaultLayout');
438-
439- return true;
440- }
441-}
442-?>
443+<?php
444+/*
445+ * Xibo - Digitial Signage - http://www.xibo.org.uk
446+ * Copyright (C) 2009-2012 Daniel Garner
447+ *
448+ * This file is part of Xibo.
449+ *
450+ * Xibo is free software: you can redistribute it and/or modify
451+ * it under the terms of the GNU Affero General Public License as published by
452+ * the Free Software Foundation, either version 3 of the License, or
453+ * any later version.
454+ *
455+ * Xibo is distributed in the hope that it will be useful,
456+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
457+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
458+ * GNU Affero General Public License for more details.
459+ *
460+ * You should have received a copy of the GNU Affero General Public License
461+ * along with Xibo. If not, see <http://www.gnu.org/licenses/>.
462+ */
463+defined('XIBO') or die("Sorry, you are not allowed to directly access this page.<br /> Please press the back button in your browser.");
464+
465+class Display extends Data
466+{
467+ public function __construct(database $db)
468+ {
469+ include_once('lib/data/displaygroup.data.class.php');
470+
471+ parent::__construct($db);
472+ }
473+
474+ /**
475+ * Adds a Display
476+ * @return
477+ * @param $display Object
478+ * @param $isAuditing Object
479+ * @param $defaultLayoutID Object
480+ * @param $license Object
481+ * @param $licensed Object
482+ * @param $incSchedule Object
483+ */
484+ public function Add($display, $isAuditing, $defaultLayoutID, $license, $licensed, $incSchedule)
485+ {
486+ $db =& $this->db;
487+
488+ Debug::LogEntry($db, 'audit', 'IN', 'DisplayGroup', 'Add');
489+
490+ // Create the SQL
491+ $SQL = "";
492+ $SQL .= "INSERT ";
493+ $SQL .= "INTO display ";
494+ $SQL .= " ( ";
495+ $SQL .= " display , ";
496+ $SQL .= " isAuditing , ";
497+ $SQL .= " defaultlayoutid, ";
498+ $SQL .= " license , ";
499+ $SQL .= " licensed , ";
500+ $SQL .= " inc_schedule , ";
501+ $SQL .= " email_alert , ";
502+ $SQL .= " alert_timeout ";
503+ $SQL .= " ) ";
504+ $SQL .= " VALUES ";
505+ $SQL .= " ( ";
506+ $SQL .= sprintf(" '%s', ", $db->escape_string($display));
507+ $SQL .= " 0 , ";
508+ $SQL .= " 1 , ";
509+ $SQL .= sprintf(" '%s', ", $db->escape_string($license));
510+ $SQL .= " 0 , ";
511+ $SQL .= " 0 , ";
512+ $SQL .= " 1 , ";
513+ $SQL .= " 0 ";
514+ $SQL .= " )";
515+
516+ if (!$displayID = $db->insert_query($SQL))
517+ {
518+ trigger_error($db->error());
519+ $this->SetError(25000, __('Could not add display'));
520+
521+ return false;
522+ }
523+
524+ // Also want to add the DisplayGroup associated with this Display.
525+ $displayGroupObject = new DisplayGroup($db);
526+
527+ if (!$displayGroupID = $displayGroupObject->Add($display, 1, ''))
528+ {
529+ $this->SetError(25001, __('Could not add a display group for the new display.'));
530+
531+ return false;
532+ }
533+
534+ // Link the Two together
535+ if (!$displayGroupObject->Link($displayGroupID, $displayID))
536+ {
537+ $this->SetError(25001, __('Could not link the new display with its group.'));
538+
539+ return false;
540+ }
541+
542+ Debug::LogEntry($db, 'audit', 'OUT', 'DisplayGroup', 'Add');
543+
544+ return $displayID;
545+ }
546+
547+ /**
548+ * Edits a Display
549+ * @return
550+ * @param $displayID Object
551+ * @param $isAuditing Object
552+ * @param $defaultLayoutID Object
553+ * @param $licensed Object
554+ * @param $incSchedule Object
555+ */
556+ public function Edit($displayID, $display, $isAuditing, $defaultLayoutID, $licensed, $incSchedule, $email_alert, $alert_timeout, $wakeOnLanEnabled, $wakeOnLanTime, $broadCastAddress, $secureOn, $cidr)
557+ {
558+ $db =& $this->db;
559+
560+ Debug::LogEntry($db, 'audit', 'IN', 'Display', 'Edit');
561+
562+ // Check the number of licensed displays
563+ $maxDisplays = Config::GetSetting($db, 'MAX_LICENSED_DISPLAYS');
564+
565+ if ($maxDisplays > 0)
566+ {
567+ // See if this is a license switch
568+ $currentLicense = $db->GetSingleValue(sprintf('SELECT licensed FROM display WHERE DisplayID = %d', $displayID), 'licensed', _INT);
569+
570+ if ($currentLicense != $licensed && $licensed == 1)
571+ {
572+ // License change - test number of licensed displays.
573+ $licensedDisplays = $db->GetSingleValue('SELECT COUNT(DisplayID) AS CountLicensed FROM display WHERE licensed =1 ', 'CountLicensed', _INT);
574+
575+ if ($licensedDisplays + 1 > $maxDisplays)
576+ return $this->SetError(25000, sprintf(__('You have exceeded your maximum number of licensed displays. %d'), $maxDisplays));
577+ }
578+ }
579+
580+ // Validate some parameters
581+
582+ // Fill $addr with client's IP address, if $addr is empty
583+ if ($broadCastAddress != '')
584+ {
585+ // Resolve broadcast address
586+ // same as (but easier than): preg_match("/\b(([01]?\d?\d|2[0-4]\d|25[0-5])\.){3}([01]?\d?\d|2[0-4]\d|25[0-5])\b/",$addr)
587+ if (!filter_var ($broadCastAddress, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4))
588+ return $this->SetError(25015, __('BroadCast Address is not a valid IPv4 Address'));
589+ }
590+
591+ // Check whether $cidr is valid
592+ if ($cidr != '')
593+ {
594+ if ((!is_numeric($cidr)) || ($cidr < 0) || ($cidr > 32))
595+ return $this->SetError(25015, __('CIDR subnet mask is not a number within the range of 0 to 32.'));
596+ }
597+
598+ // Check whether $secureon is valid
599+ if ($secureOn != '')
600+ {
601+ $secureon = strtoupper($secureon);
602+ $secureon = str_replace(":", "-", $secureon);
603+
604+ if ((!preg_match("/([A-F0-9]{2}[-]){5}([0-9A-F]){2}/", $secureon)) || (strlen($secureon) != 17))
605+ return $this->SetError(25015, __('Pattern of SecureOn-password is not "xx-xx-xx-xx-xx-xx" (x = digit or CAPITAL letter)'));
606+ }
607+
608+ // Update the display record
609+ $SQL = "UPDATE display SET display = '%s', ";
610+ $SQL .= " defaultlayoutid = %d, ";
611+ $SQL .= " inc_schedule = %d, ";
612+ $SQL .= " licensed = %d, ";
613+ $SQL .= " isAuditing = %d, ";
614+ $SQL .= " email_alert = %d, ";
615+ $SQL .= " alert_timeout = %d, ";
616+ $SQL .= " WakeOnLan = %d, ";
617+ $SQL .= " WakeOnLanTime = '%s', ";
618+ $SQL .= " BroadCastAddress = '%s', ";
619+ $SQL .= " SecureOn = '%s', ";
620+ $SQL .= " Cidr = %d ";
621+ $SQL .= "WHERE displayid = %d ";
622+
623+ $SQL = sprintf($SQL, $db->escape_string($display), $defaultLayoutID, $incSchedule, $licensed, $isAuditing, $email_alert, $alert_timeout, $wakeOnLanEnabled, $wakeOnLanTime, $broadCastAddress, $secureOn, $cidr, $displayID);
624+
625+ Debug::LogEntry($db, 'audit', $SQL);
626+
627+ if (!$db->query($SQL))
628+ {
629+ trigger_error($db->error());
630+ $this->SetError(25000, __('Could not update display') . '-' . __('Stage 1'));
631+
632+ return false;
633+ }
634+
635+ // Use a DisplayGroup to handle the default layout and displaygroup name for this display
636+ $displayGroupObject = new DisplayGroup($db);
637+
638+ // Do we also want to update the linked Display Groups name (seeing as that is what we will be presenting to everyone)
639+ if (!$displayGroupObject->EditDisplayGroup($displayID, $display))
640+ {
641+ $this->SetError(25002, __('Could not update this display with a new name.'));
642+
643+ return false;
644+ }
645+
646+ Debug::LogEntry($db, 'audit', 'OUT', 'DisplayGroup', 'Edit');
647+
648+ return true;
649+ }
650+
651+ /**
652+ * Deletes a Display
653+ * @return
654+ * @param $displayID Object
655+ */
656+ public function Delete($displayID)
657+ {
658+ $db =& $this->db;
659+
660+ Debug::LogEntry($db, 'audit', 'IN', 'DisplayGroup', 'Delete');
661+
662+ // Pass over to the DisplayGroup data class so that it can try and delete the
663+ // display specific group first (it is that group which is linked to schedules)
664+ $displayGroupObject = new DisplayGroup($db);
665+
666+ // Do we also want to update the linked Display Groups name (seeing as that is what we will be presenting to everyone)
667+ if (!$displayGroupObject->DeleteDisplay($displayID))
668+ {
669+ $this->SetError(25002, __('Could not delete this display.'));
670+
671+ return false;
672+ }
673+
674+ // Delete the blacklist
675+ $SQL = sprintf("DELETE FROM blacklist WHERE DisplayID = %d", $displayID);
676+
677+ Debug::LogEntry($db, 'audit', $SQL);
678+
679+ if (!$db->query($SQL))
680+ return $this->SetError(25016,__('Unable to delete blacklist records.'));
681+
682+ // Now we know the Display Group is gone - and so are any links
683+ // delete the display
684+ $SQL = " ";
685+ $SQL .= "DELETE FROM display ";
686+ $SQL .= sprintf(" WHERE displayid = %d", $displayID);
687+
688+ Debug::LogEntry($db, 'audit', $SQL);
689+
690+ if (!$db->query($SQL))
691+ {
692+ trigger_error($db->error());
693+ $this->SetError(25015,__('Unable to delete display record. However it is no longer usable.'));
694+
695+ return false;
696+ }
697+
698+ Debug::LogEntry($db, 'audit', 'OUT', 'DisplayGroup', 'Delete');
699+
700+ return true;
701+ }
702+
703+ /**
704+ * Edits a Displays Name
705+ * @return
706+ * @param $license Object
707+ * @param $display Object
708+ */
709+ public function EditDisplayName($license, $display)
710+ {
711+ $db =& $this->db;
712+
713+ Debug::LogEntry($db, 'audit', 'IN', 'DisplayGroup', 'EditDisplayName');
714+
715+ $SQL = sprintf("UPDATE display SET display = '%s' WHERE license = '%s' ", $display, $license);
716+
717+ if (!$db->query($SQL))
718+ {
719+ trigger_error($db->error());
720+ $this->SetError(25010, __("Error updating this displays last accessed information."));
721+
722+ return false;
723+ }
724+
725+ // Also need to update the display group name here.
726+ $displayGroupObject = new DisplayGroup($db);
727+
728+ // Do we also want to update the linked Display Groups name (seeing as that is what we will be presenting to everyone)
729+ if (!$displayGroupObject->EditDisplayGroup($displayID, $display))
730+ {
731+ $this->SetError(25015, __('Could not update this display with a new name.'));
732+
733+ return false;
734+ }
735+
736+ Debug::LogEntry($db, 'audit', 'OUT', 'DisplayGroup', 'EditDisplayName');
737+
738+ return true;
739+ }
740+
741+ /**
742+ * Sets the information required on the display to indicate
743+ * that it is still logged in
744+ * @return
745+ * @param $license Object
746+ */
747+ public function Touch($license, $clientAddress = '', $mediaInventoryComplete = 0, $mediaInventoryXml = '', $macAddress = '')
748+ {
749+ $db =& $this->db;
750+ $time = time();
751+
752+ Debug::LogEntry($db, 'audit', 'IN', 'DisplayGroup', 'Touch');
753+
754+ // Set the last accessed flag on the display
755+ $SQL = "";
756+ $SQL .= "UPDATE display SET lastaccessed = %d, loggedin = 1 ";
757+
758+ // We will want to update the client Address if it is given
759+ if ($clientAddress != '')
760+ $SQL .= sprintf(" , ClientAddress = '%s' ", $db->escape_string($clientAddress));
761+
762+ // Media Inventory Settings (if appropriate)
763+ if ($mediaInventoryComplete != 0)
764+ $SQL .= sprintf(" , MediaInventoryStatus = %d ", $mediaInventoryComplete);
765+
766+ if ($mediaInventoryXml != '')
767+ $SQL .= sprintf(" , MediaInventoryXml = '%s' ", $mediaInventoryXml);
768+
769+ // Mac address storage
770+ if ($macAddress != '')
771+ {
772+ // Address changed.
773+ $currentAddress = $db->GetSingleValue(sprintf("SELECT MacAddress FROM display WHERE license = '%s'", $license), 'MacAddress', _STRING);
774+
775+ if ($macAddress != $currentAddress)
776+ {
777+ $SQL .= sprintf(" , MacAddress = '%s', LastChanged = %d, NumberOfMacAddressChanges = NumberOfMacAddressChanges + 1 ", $macAddress, time());
778+ }
779+ }
780+
781+ // Restrict to the display license
782+ $SQL .= " WHERE license = '%s'";
783+ $SQL = sprintf($SQL, $time, $license);
784+
785+ if (!$result = $db->query($SQL))
786+ {
787+ trigger_error($db->error());
788+ $this->SetError(25002, __("Error updating this displays last accessed information."));
789+
790+ return false;
791+ }
792+
793+ Debug::LogEntry($db, 'audit', 'OUT', 'DisplayGroup', 'Touch');
794+
795+ return true;
796+ }
797+
798+ /**
799+ * Flags a display as being incomplete
800+ * @param <type> $displayId
801+ */
802+ private function FlagIncomplete($displayId)
803+ {
804+ $db =& $this->db;
805+
806+ Debug::LogEntry($db, 'audit', sprintf('Flag DisplayID %d incomplete.', $displayId), 'display', 'NotifyDisplays');
807+
808+ $SQL = sprintf("UPDATE display SET MediaInventoryStatus = 3 WHERE displayID = %d", $displayId);
809+
810+ if (!$db->query($SQL))
811+ {
812+ trigger_error($db->error());
813+ return $this->SetError(25004, 'Unable to Flag Display as incomplete');
814+ }
815+
816+ return true;
817+ }
818+
819+ /**
820+ * Notify displays of this layout change
821+ * @param <type> $layoutId
822+ */
823+ public function NotifyDisplays($layoutId)
824+ {
825+ $db =& $this->db;
826+ $currentdate = time();
827+ $rfLookahead = Kit::ValidateParam(Config::GetSetting($db,'REQUIRED_FILES_LOOKAHEAD'), _INT);
828+
829+ $rfLookahead = $currentdate + $rfLookahead;
830+
831+ Debug::LogEntry($db, 'audit', sprintf('Checking for Displays to refresh on Layout %d', $layoutId), 'display', 'NotifyDisplays');
832+
833+ // Which displays does a change to this layout effect?
834+ $SQL = " SELECT DISTINCT display.DisplayID ";
835+ $SQL .= " FROM schedule_detail ";
836+ $SQL .= " INNER JOIN lkdisplaydg ";
837+ $SQL .= " ON lkdisplaydg.DisplayGroupID = schedule_detail.DisplayGroupID ";
838+ $SQL .= " INNER JOIN display ";
839+ $SQL .= " ON lkdisplaydg.DisplayID = display.displayID ";
840+ $SQL .= " WHERE schedule_detail.layoutID = %d ";
841+ $SQL .= " AND schedule_detail.FromDT < %d AND schedule_detail.ToDT > %d ";
842+ $SQL .= " UNION ";
843+ $SQL .= " SELECT DisplayID FROM display WHERE DefaultLayoutID = %d";
844+
845+ $SQL = sprintf($SQL, $layoutId, $rfLookahead, $currentdate - 3600, $layoutId);
846+
847+ Debug::LogEntry($db, 'audit', $SQL, 'display', 'NotifyDisplays');
848+
849+ if (!$result = $db->query($SQL))
850+ {
851+ trigger_error($db->error());
852+ return $this->SetError(25037, __('Unable to get layouts for Notify'));
853+ }
854+
855+ while ($row = $db->get_assoc_row($result))
856+ {
857+ // Notify each display in turn
858+ $displayId = Kit::ValidateParam($row['DisplayID'], _INT);
859+ $this->FlagIncomplete($displayId);
860+ }
861+ }
862+
863+ /**
864+ * Edits the default layout for a display
865+ * @param <type> $displayId
866+ * @param <type> $defaultLayoutId
867+ * @return <type>
868+ */
869+ public function EditDefaultLayout($displayId, $defaultLayoutId)
870+ {
871+ $db =& $this->db;
872+
873+ Debug::LogEntry($db, 'audit', 'IN', 'Display', 'EditDefaultLayout');
874+
875+ $SQL = sprintf('UPDATE display SET defaultLayoutId = %d WHERE displayID = %d ', $defaultLayoutId, $displayId);
876+
877+ if (!$db->query($SQL))
878+ {
879+ trigger_error($db->error());
880+ $this->SetError(25012, __('Error updating this displays default layout.'));
881+
882+ return false;
883+ }
884+
885+ // Flag this display as not having all the content
886+ $this->FlagIncomplete($displayId);
887+
888+ Debug::LogEntry($db, 'audit', 'OUT', 'Display', 'EditDefaultLayout');
889+
890+ return true;
891+ }
892+
893+ /**
894+ * Wake this display using a WOL command
895+ * @param <int> $displayId
896+ * @return <bool>
897+ */
898+ public function WakeOnLan($displayId)
899+ {
900+ $db =& $this->db;
901+
902+ // Get the Client Address and the Mac Address
903+ if (!$row = $db->GetSingleRow(sprintf("SELECT MacAddress, BroadCastAddress, SecureOn, Cidr FROM `display` WHERE DisplayID = %d", $displayId)))
904+ $this->SetError(25013, __('Unable to get the Mac or Client Address'));
905+
906+ // Check they are populated
907+ if ($row['MacAddress'] == '' || $row['BroadCastAddress'] == '')
908+ $this->SetError(25014, __('This display has no mac address recorded against it yet. Make sure the display is running.'));
909+
910+ Debug::LogEntry($db, 'audit', 'About to send WOL packet to ' . $row['BroadCastAddress'] . ' with Mac Address ' . $row['MacAddress'], 'display', 'WakeOnLan');
911+
912+ if (!$this->TransmitWakeOnLan($row['MacAddress'], $row['SecureOn'], $row['BroadCastAddress'], $row['Cidr'], "9"))
913+ return false;
914+
915+ // If we succeeded then update this display with the last WOL time
916+ $db->query(sprintf("UPDATE `display` SET LastWakeOnLanCommandSent = %d WHERE DisplayID = %d", time(), $displayId));
917+
918+ return true;
919+ }
920+
921+ /**
922+ * Wake On Lan Script
923+ * // Version: 2
924+ // Author of this application:
925+ // DS508_customer (http://www.synology.com/enu/forum/memberlist.php?mode=viewprofile&u=12636)
926+ // Please inform the author of any suggestions on (the functionality, graphical design, ... of) this application.
927+ // More info: http://wolviaphp.sourceforge.net
928+ // License: GPLv2.0
929+ *
930+ * Modified for use with the Xibo project by Dan Garner.
931+ */
932+ function TransmitWakeOnLan($mac_address, $secureon, $addr, $cidr, $port)
933+ {
934+ // Prepare magic packet: part 1/3 (defined constant)
935+ $buf = "";
936+
937+ // the defined constant as represented in hexadecimal: FF FF FF FF FF FF (i.e., 6 bytes of hexadecimal FF)
938+ for ($a=0; $a<6; $a++) $buf .= chr(255);
939+
940+ // Check whether $mac_address is valid
941+ $mac_address = strtoupper($mac_address);
942+ $mac_address = str_replace(":", "-", $mac_address);
943+
944+ if ((!preg_match("/([A-F0-9]{2}[-]){5}([0-9A-F]){2}/",$mac_address)) || (strlen($mac_address) != 17))
945+ {
946+ return $this->SetError(25015, __('Pattern of MAC-address is not "xx-xx-xx-xx-xx-xx" (x = digit or letter)'));
947+ }
948+ else
949+ {
950+ // Prepare magic packet: part 2/3 (16 times MAC-address)
951+ // Split MAC-address into an array of (six) bytes
952+ $addr_byte = explode('-', $mac_address);
953+ $hw_addr = "";
954+
955+ // Convert MAC-address from bytes to hexadecimal to decimal
956+ for ($a=0; $a<6; $a++) $hw_addr .= chr(hexdec($addr_byte[$a]));
957+
958+ $hw_addr_string = "";
959+
960+ for ($a=0; $a<16; $a++) $hw_addr_string .= $hw_addr;
961+ $buf .= $hw_addr_string;
962+ }
963+
964+ if ($secureon != "")
965+ {
966+ // Check whether $secureon is valid
967+ $secureon = strtoupper($secureon);
968+ $secureon = str_replace(":", "-", $secureon);
969+
970+ if ((!preg_match("/([A-F0-9]{2}[-]){5}([0-9A-F]){2}/", $secureon)) || (strlen($secureon) != 17))
971+ {
972+ return $this->SetError(25015, __('Pattern of SecureOn-password is not "xx-xx-xx-xx-xx-xx" (x = digit or CAPITAL letter)'));
973+ }
974+ else
975+ {
976+ // Prepare magic packet: part 3/3 (Secureon password)
977+ // Split MAC-address into an array of (six) bytes
978+ $addr_byte = explode('-', $secureon);
979+ $hw_addr = "";
980+
981+ // Convert MAC address from hexadecimal to decimal
982+ for ($a=0; $a<6; $a++) $hw_addr .= chr(hexdec($addr_byte[$a]));
983+ $buf .= $hw_addr;
984+ }
985+ }
986+
987+ // Fill $addr with client's IP address, if $addr is empty
988+ if ($addr == "")
989+ return $this->SetError(25000, __('No IP Address Specified'));
990+
991+ // Resolve broadcast address
992+ if (filter_var ($addr, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) // same as (but easier than): preg_match("/\b(([01]?\d?\d|2[0-4]\d|25[0-5])\.){3}([01]?\d?\d|2[0-4]\d|25[0-5])\b/",$addr)
993+ {
994+ // $addr has an IP-adres format
995+ }
996+ else
997+ {
998+ return $this->SetError(25000, __('IP Address Incorrectly Formed'));
999+ }
1000+
1001+ // If $cidr is set, replace $addr for its broadcast address
1002+ if ($cidr != "")
1003+ {
1004+ // Check whether $cidr is valid
1005+ if ((!ctype_digit($cidr)) || ($cidr < 0) || ($cidr > 32))
1006+ {
1007+ return $this->SetError(25015, __('CIDR subnet mask is not a number within the range of 0 till 32.'));
1008+ }
1009+
1010+ // Convert $cidr from one decimal to one inverted binary array
1011+ $inverted_binary_cidr = "";
1012+
1013+ // Build $inverted_binary_cidr by $cidr * zeros (this is the mask)
1014+ for ($a=0; $a<$cidr; $a++) $inverted_binary_cidr .= "0";
1015+
1016+ // Invert the mask (by postfixing ones to $inverted_binary_cidr untill 32 bits are filled/ complete)
1017+ $inverted_binary_cidr = $inverted_binary_cidr.substr("11111111111111111111111111111111", 0, 32 - strlen($inverted_binary_cidr));
1018+
1019+ // Convert $inverted_binary_cidr to an array of bits
1020+ $inverted_binary_cidr_array = str_split($inverted_binary_cidr);
1021+
1022+ // Convert IP address from four decimals to one binary array
1023+ // Split IP address into an array of (four) decimals
1024+ $addr_byte = explode('.', $addr);
1025+ $binary_addr = "";
1026+
1027+ for ($a=0; $a<4; $a++)
1028+ {
1029+ // Prefix zeros
1030+ $pre = substr("00000000",0,8-strlen(decbin($addr_byte[$a])));
1031+
1032+ // Postfix binary decimal
1033+ $post = decbin($addr_byte[$a]);
1034+ $binary_addr .= $pre.$post;
1035+ }
1036+
1037+ // Convert $binary_addr to an array of bits
1038+ $binary_addr_array = str_split($binary_addr);
1039+
1040+ // Perform a bitwise OR operation on arrays ($binary_addr_array & $inverted_binary_cidr_array)
1041+ $binary_broadcast_addr_array="";
1042+
1043+ // binary array of 32 bit variables ('|' = logical operator 'or')
1044+ for ($a=0; $a<32; $a++) $binary_broadcast_addr_array[$a] = ($binary_addr_array[$a] | $inverted_binary_cidr_array[$a]);
1045+
1046+ // build binary address of four bundles of 8 bits (= 1 byte)
1047+ $binary_broadcast_addr = chunk_split(implode("", $binary_broadcast_addr_array), 8, ".");
1048+
1049+ // chop off last dot ('.')
1050+ $binary_broadcast_addr = substr($binary_broadcast_addr,0,strlen($binary_broadcast_addr)-1);
1051+
1052+ // binary array of 4 byte variables
1053+ $binary_broadcast_addr_array = explode(".", $binary_broadcast_addr);
1054+ $broadcast_addr_array = "";
1055+
1056+ // decimal array of 4 byte variables
1057+ for ($a=0; $a<4; $a++) $broadcast_addr_array[$a] = bindec($binary_broadcast_addr_array[$a]);
1058+
1059+ // broadcast address
1060+ $addr = implode(".", $broadcast_addr_array);
1061+ }
1062+
1063+ // Check whether $port is valid
1064+ if ((!ctype_digit($port)) || ($port < 0) || ($port > 65536))
1065+ return $this->SetError(25000, __('Port is not a number within the range of 0 till 65536. Port Provided: ' . $port));
1066+
1067+ // Check whether UDP is supported
1068+ if (!array_search('udp', stream_get_transports()))
1069+ return $this->SetError(25000, __('No magic packet can been sent, since UDP is unsupported (not a registered socket transport)'));
1070+
1071+ // Ready to send the packet
1072+ if (function_exists('fsockopen'))
1073+ {
1074+ // Try fsockopen function - To do: handle error 'Permission denied'
1075+ $socket = fsockopen("udp://" . $addr, $port, $errno, $errstr);
1076+
1077+ if ($socket)
1078+ {
1079+ $socket_data = fwrite($socket, $buf);
1080+
1081+ if ($socket_data)
1082+ {
1083+ $function = "fwrite";
1084+ $sent_fsockopen = "A magic packet of ".$socket_data." bytes has been sent via UDP to IP address: ".$addr.":".$port.", using the '".$function."()' function.";
1085+ $content = bin2hex($buf);
1086+
1087+ $sent_fsockopen = $sent_fsockopen."Contents of magic packet:".strlen($content)." ".$content;
1088+ fclose($socket);
1089+
1090+ unset($socket);
1091+
1092+ Debug::LogEntry($this->db, 'audit', $sent_fsockopen, 'display', 'WakeOnLan');
1093+ return true;
1094+ }
1095+ else
1096+ {
1097+ unset($socket);
1098+
1099+ return $this->SetError(25015, __('Using "fwrite()" failed, due to error: ' . $errstr. ' ("' . $errno . '")'));
1100+ }
1101+ }
1102+ else
1103+ {
1104+ unset($socket);
1105+
1106+ Debug::LogEntry($this->db, 'audit', __('Using fsockopen() failed, due to denied permission'));
1107+ }
1108+ }
1109+
1110+ // Try socket_create function
1111+ if (function_exists('socket_create'))
1112+ {
1113+ // create socket based on IPv4, datagram and UDP
1114+ $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
1115+
1116+ if ($socket)
1117+ {
1118+ // to enable manipulation of options at the socket level (you may have to change this to 1)
1119+ $level = SOL_SOCKET;
1120+
1121+ // to enable permission to transmit broadcast datagrams on the socket (you may have to change this to 6)
1122+ $optname = SO_BROADCAST;
1123+
1124+ $optval = true;
1125+ $opt_returnvalue = socket_set_option($socket, $level, $optname, $optval);
1126+
1127+ if ($opt_returnvalue < 0)
1128+ {
1129+ return $this->SetError(25015, __('Using "socket_set_option()" failed, due to error: ' . socket_strerror($opt_returnvalue)));
1130+ }
1131+
1132+ $flags = 0;
1133+
1134+ // To do: handle error 'Operation not permitted'
1135+ $socket_data = socket_sendto($socket, $buf, strlen($buf), $flags, $addr, $port);
1136+
1137+ if ($socket_data)
1138+ {
1139+ $function = "socket_sendto";
1140+ $socket_create = "A magic packet of ". $socket_data . " bytes has been sent via UDP to IP address: ".$addr.":".$port.", using the '".$function."()' function.<br>";
1141+
1142+ $content = bin2hex($buf);
1143+ $socket_create = $socket_create . "Contents of magic packet:" . strlen($content) ." " . $content;
1144+
1145+ socket_close($socket);
1146+ unset($socket);
1147+
1148+ Debug::LogEntry($this->db, 'audit', $socket_create, 'display', 'WakeOnLan');
1149+ return true;
1150+ }
1151+ else
1152+ {
1153+ $error = "Using 'socket_sendto()' failed, due to error: '".socket_strerror(socket_last_error($socket))."' (".socket_last_error($socket).")<br>\n";
1154+ socket_close($socket);
1155+ unset($socket);
1156+
1157+ return $this->SetError(25015, __('Using "socket_sendto()" failed, due to error: ' . socket_strerror(socket_last_error($socket)) . ' (' . socket_last_error($socket) . ')'));
1158+ }
1159+ }
1160+ else
1161+ {
1162+ return $this->SetError(25015, __('Using "socket_sendto()" failed, due to error: ' . socket_strerror(socket_last_error($socket)) . ' (' . socket_last_error($socket) . ')'));
1163+ }
1164+ }
1165+ else
1166+ {
1167+ return $this->SetError(25015, __('Wake On Lan Failed as there are no functions available to transmit it'));
1168+ }
1169+ }
1170+}
1171+?>
1172
1173=== modified file 'server/lib/data/schedule.data.class.php'
1174--- server/lib/data/schedule.data.class.php 2011-07-29 12:46:13 +0000
1175+++ server/lib/data/schedule.data.class.php 2012-04-14 10:54:18 +0000
1176@@ -1,7 +1,7 @@
1177 <?php
1178 /*
1179 * Xibo - Digitial Signage - http://www.xibo.org.uk
1180- * Copyright (C) 2009 Daniel Garner
1181+ * Copyright (C) 2009-2012 Daniel Garner
1182 *
1183 * This file is part of Xibo.
1184 *
1185
1186=== modified file 'server/lib/include.php'
1187--- server/lib/include.php 2012-01-22 15:52:39 +0000
1188+++ server/lib/include.php 2012-04-14 10:54:18 +0000
1189@@ -1,7 +1,7 @@
1190 <?php
1191 /*
1192 * Xibo - Digitial Signage - http://www.xibo.org.uk
1193- * Copyright (C) 2006,2007,2008 Daniel Garner and James Packer
1194+ * Copyright (C) 2006-2012 Daniel Garner and James Packer
1195 *
1196 * This file is part of Xibo.
1197 *
1198
1199=== modified file 'server/lib/pages/display.class.php'
1200--- server/lib/pages/display.class.php 2011-12-11 11:58:27 +0000
1201+++ server/lib/pages/display.class.php 2012-04-14 10:54:18 +0000
1202@@ -1,7 +1,7 @@
1203 <?php
1204 /*
1205 * Xibo - Digitial Signage - http://www.xibo.org.uk
1206- * Copyright (C) 2006-2010 Daniel Garner and James Packer
1207+ * Copyright (C) 2006-2012 Daniel Garner and James Packer
1208 *
1209 * This file is part of Xibo.
1210 *
1211@@ -39,6 +39,13 @@
1212 private $ajax;
1213 private $mediaInventoryStatus;
1214 private $mediaInventoryXml;
1215+ private $macAddress;
1216+ private $wakeOnLan;
1217+ private $wakeOnLanTime;
1218+ private $broadCastAddress;
1219+ private $secureOn;
1220+ private $cidr;
1221+ private $clientIpAddress;
1222
1223 function __construct(database $db, user $user)
1224 {
1225@@ -73,9 +80,15 @@
1226 display.isAuditing,
1227 display.email_alert,
1228 display.alert_timeout,
1229- display.ClientAddress,
1230 display.MediaInventoryStatus,
1231- display.MediaInventoryXml
1232+ display.MediaInventoryXml,
1233+ display.MacAddress,
1234+ display.WakeOnLan,
1235+ display.WakeOnLanTime,
1236+ display.BroadCastAddress,
1237+ display.SecureOn,
1238+ display.Cidr,
1239+ display.ClientAddress
1240 FROM display
1241 WHERE display.displayid = %d
1242 SQL;
1243@@ -103,6 +116,16 @@
1244 $this->alert_timeout = Kit::ValidateParam($row[8], _INT);
1245 $this->mediaInventoryStatus = Kit::ValidateParam($row[9], _INT);
1246 $this->mediaInventoryXml = Kit::ValidateParam($row[10], _HTMLSTRING);
1247+ $this->macAddress = Kit::ValidateParam($row[11], _STRING);
1248+ $this->wakeOnLan = Kit::ValidateParam($row[12], _INT);
1249+ $this->wakeOnLanTime = Kit::ValidateParam($row[13], _STRING);
1250+ $this->broadCastAddress = Kit::ValidateParam($row[14], _STRING);
1251+ $this->secureOn = Kit::ValidateParam($row[15], _STRING);
1252+ $this->cidr = Kit::ValidateParam($row[16], _INT);
1253+ $this->clientIpAddress = Kit::ValidateParam($row[17], _STRING);
1254+
1255+ // Make cidr null if its a 0
1256+ $this->cidr = ($this->cidr == 0) ? '' : $this->cidr;
1257 }
1258 }
1259
1260@@ -136,6 +159,11 @@
1261 $auditing = Kit::GetParam('auditing', _POST, _INT);
1262 $email_alert = Kit::GetParam('email_alert', _POST, _INT);
1263 $alert_timeout = Kit::GetParam('alert_timeout', _POST, _INT);
1264+ $wakeOnLanEnabled = Kit::GetParam('wakeOnLanEnabled', _POST, _CHECKBOX);
1265+ $wakeOnLanTime = Kit::GetParam('wakeOnLanTime', _POST, _STRING);
1266+ $broadCastAddress = Kit::GetParam('broadCastAddress', _POST, _STRING);
1267+ $secureOn = Kit::GetParam('secureOn', _POST, _STRING);
1268+ $cidr = Kit::GetParam('cidr', _POST, _INT);
1269
1270 // Do we take, or revoke a license
1271 if (isset($_POST['takeLicense']))
1272@@ -153,9 +181,12 @@
1273 trigger_error(__("Can not have a display without a name"), E_USER_ERROR);
1274 }
1275
1276+ if ($wakeOnLanEnabled == 1 && $wakeOnLanTime == '')
1277+ trigger_error(__('Wake on Lan is enabled, but you have not specified a time to wake the display'), E_USER_ERROR);
1278+
1279 $displayObject = new Display($db);
1280
1281- if (!$displayObject->Edit($displayid, $display, $auditing, $layoutid, $licensed, $inc_schedule, $email_alert, $alert_timeout))
1282+ if (!$displayObject->Edit($displayid, $display, $auditing, $layoutid, $licensed, $inc_schedule, $email_alert, $alert_timeout, $wakeOnLanEnabled, $wakeOnLanTime, $broadCastAddress, $secureOn, $cidr))
1283 {
1284 trigger_error($displayObject->GetErrorMessage(), E_USER_ERROR);
1285 }
1286@@ -195,14 +226,18 @@
1287 $auditHelp = $helpManager->HelpIcon(__("Collect auditing from this client. Should only be used if there is a problem with the display."), true);
1288 $emailHelp = $helpManager->HelpIcon(__("Do you want to be notified by email if there is a problem with this display?"), true);
1289 $alertHelp = $helpManager->HelpIcon(__("How long in minutes after the display last connected to the webservice should we send an alert. Set this value higher than the collection interval on the client. Set to 0 to use global default."), true);
1290-
1291-
1292+ $wolHelp = $helpManager->HelpIcon(__('Wake on Lan requires the correct network configuration to route the magic packet to the display PC'), true);
1293+ $wolTimeHelp = $helpManager->HelpIcon(_('The time this display should receive the WOL command, using the 24hr clock - e.g. 19:00. Maintenance must be enabled.'), true);
1294+
1295 $layoutList = Kit::SelectList('defaultlayoutid', $this->user->LayoutList(), 'layoutid', 'layout', $layoutid);
1296
1297 $inc_schedule_list = listcontent("1|Yes,0|No","inc_schedule",$inc_schedule);
1298 $auditing_list = listcontent("1|Yes,0|No","auditing",$auditing);
1299 $email_alert_list = listcontent("1|Yes,0|No","email_alert",$email_alert);
1300
1301+ // Is the wake on lan field checked?
1302+ $wakeOnLanChecked = ($this->wakeOnLan == 1) ? ' checked' : '';
1303+
1304 $license_list = "";
1305
1306 //Are we licensed
1307@@ -227,6 +262,18 @@
1308 $msgLicense = __('License');
1309 $msgAlert = __('Email Alerts');
1310 $msgTimeout = __('Alert Timeout');
1311+ $msgWakeOnLan = __('Enable Wake On LAN');
1312+ $msgWakeOnLanTime = __('Wake On LAN Time');
1313+ $msgBroadCastAddress = __('BroadCast Address');
1314+ $msgSecureOn = __('Wake On LAN Secure On');
1315+ $msgCidr = __('Wake On LAN CIDR');
1316+
1317+ $helpBroadCastAddress = $helpManager->HelpIcon(__('The IP address of the remote host\'s broadcast address (or gateway)'), true);
1318+ $helpSecureOn = $helpManager->HelpIcon(__('Enter a hexidecimal password of a SecureOn enabled Network Interface Card (NIC) of the remote host. Enter a value in this pattern: \'xx-xx-xx-xx-xx-xx\'. Leave the following field empty, if SecureOn is not used (for example, because the NIC of the remote host does not support SecureOn).'), true);
1319+ $helpCidr = $helpManager->HelpIcon(__('Enter a number within the range of 0 to 32 in the following field. Leave the following field empty, if no subnet mask should be used (CIDR = 0). If the remote host\'s broadcast address is unkown: Enter the host name or IP address of the remote host in Broad Cast Address and enter the CIDR subnet mask of the remote host in this field.'), true);
1320+
1321+ // If the broadcast address has not been set, then default to the client ip address
1322+ $broadCastAddress = ($this->broadCastAddress == '') ? $this->clientIpAddress : $this->broadCastAddress;
1323
1324 $form = <<<END
1325 <form id="DisplayEditForm" class="XiboForm" method="post" action="index.php?p=display&q=modify&id=$displayid">
1326@@ -252,6 +299,21 @@
1327 <td>$msgTimeout<span class="required">*</span></td>
1328 <td>$alertHelp <input name="alert_timeout" type="text" value="$alert_timeout"></td>
1329 </tr>
1330+ <tr>
1331+ <td colspan="2"><label for="wakeOnLanEnabled">$msgWakeOnLan</label>$wolHelp<input type="checkbox" id="wakeOnLanEnabled" name="wakeOnLanEnabled" $wakeOnLanChecked></td>
1332+ <td>$msgWakeOnLanTime</td>
1333+ <td>$wolTimeHelp<input name="wakeOnLanTime" type="text" value="$this->wakeOnLanTime"></td>
1334+ </tr>
1335+ <tr>
1336+ <td><label for="broadCastAddress">$msgBroadCastAddress</label></td>
1337+ <td>$helpBroadCastAddress<input type="text" id="broadCastAddress" name="broadCastAddress" value="$broadCastAddress"></td>
1338+ </tr>
1339+ <tr>
1340+ <td><label for="secureOn">$msgSecureOn</label></td>
1341+ <td>$helpSecureOn<input id="secureOn" name="secureOn" type="text" value="$this->secureOn"></td>
1342+ <td><label for="cidr">$msgCidr</label></td>
1343+ <td>$helpCidr<input id="cidr" name="cidr" type="text" value="$this->cidr" class="number"></td>
1344+ </tr>
1345 <tr>
1346 <td>$msgLicense</td>
1347 <td>$licenseHelp <input type="text" readonly value="$license"></td>
1348@@ -322,7 +384,8 @@
1349 WHEN display.MediaInventoryStatus = 2 THEN '<img src="img/warn.gif">'
1350 ELSE '<img src="img/disact.gif">'
1351 END AS MediaInventoryStatus,
1352- display.MediaInventoryXml
1353+ display.MediaInventoryXml,
1354+ display.MacAddress
1355 FROM display
1356 INNER JOIN lkdisplaydg ON lkdisplaydg.DisplayID = display.DisplayID
1357 INNER JOIN displaygroup ON displaygroup.DisplayGroupID = lkdisplaydg.DisplayGroupID
1358@@ -356,6 +419,8 @@
1359 $msgDefault = __('Default Layout');
1360 $msgStatus = __('Status');
1361 $msgMediaInventory = __('Media Inventory');
1362+ $msgMacAddress = __('Mac Address');
1363+ $msgWakeOnLan = __('Wake on LAN');
1364
1365 $output = <<<END
1366 <div class="info_table">
1367@@ -371,6 +436,7 @@
1368 <th>$msgLogIn</th>
1369 <th>$msgLastA</th>
1370 <th>$msgClientAddress</th>
1371+ <th>$msgMacAddress</th>
1372 <th>$msgStatus</th>
1373 <th>$msgAction</th>
1374 </tr>
1375@@ -402,6 +468,7 @@
1376 $vncTemplate = Config::GetSetting($db, 'SHOW_DISPLAY_AS_VNCLINK');
1377 $linkTarget = Kit::ValidateParam(Config::GetSetting($db, 'SHOW_DISPLAY_AS_VNC_TGT'), _STRING);
1378 $mediaInventoryStatusLight = Kit::ValidateParam($aRow[10], _STRING);
1379+ $macAddress = Kit::ValidateParam($aRow[12], _STRING);
1380
1381 if ($vncTemplate != '' && $clientAddress != '')
1382 {
1383@@ -422,6 +489,7 @@
1384 <button class='XiboFormButton' href='index.php?p=display&q=DeleteForm&displayid=$displayid'><span>$msgDelete</span></button>
1385 <button class="XiboFormButton" href="index.php?p=displaygroup&q=GroupSecurityForm&DisplayGroupID=$displayGroupID&DisplayGroup=$displayName"><span>$msgGroupSecurity</span></button>
1386 <button class="XiboFormButton" href="index.php?p=display&q=MediaInventory&DisplayId=$displayid"><span>$msgMediaInventory</span></button>
1387+ <button class="XiboFormButton" href="index.php?p=display&q=WakeOnLanForm&DisplayId=$displayid"><span>$msgWakeOnLan</span></button>
1388 END;
1389 }
1390
1391@@ -440,6 +508,7 @@
1392 <td>$loggedin</td>
1393 <td>$lastaccessed</td>
1394 <td>$clientAddress</td>
1395+ <td>$macAddress</td>
1396 <td>$mediaInventoryStatusLight</td>
1397 <td>$buttons</td>
1398 END;
1399@@ -589,40 +658,48 @@
1400 return $return;
1401 }
1402
1403- /**
1404- * Assess each Display to correctly set the logged in flag based on last accessed time
1405- * @return
1406- */
1407+ /**
1408+ * Assess each Display to correctly set the logged in flag based on last accessed time
1409+ * @return
1410+ */
1411 function validateDisplays()
1412- {
1413- $db =& $this->db;
1414-
1415- // timeout after 10 minutes
1416- $timeout = time() - (60*10);
1417-
1418+ {
1419+ $db =& $this->db;
1420+
1421+ // Get the global timeout (overrides the alert timeout on the display if 0
1422+ $globalTimeout = Config::GetSetting($db, 'MAINTENANCE_ALERT_TOUT');
1423+
1424+ // Get a list of all displays and there last accessed / alert timeout value
1425 $SQL = "";
1426- $SQL .= "SELECT displayid, lastaccessed FROM display ";
1427- $SQL .= sprintf("WHERE lastaccessed < %d ", $timeout);
1428+ $SQL .= "SELECT displayid, lastaccessed, alert_timeout FROM display ";
1429
1430 if (!$result =$db->query($SQL))
1431 {
1432- trigger_error($db->error());
1433- trigger_error(__('Unable to access displays'), E_USER_ERROR);
1434+ trigger_error($db->error());
1435+ trigger_error(__('Unable to access displays'), E_USER_ERROR);
1436 }
1437
1438- while($row = $db->get_row($result))
1439+ // Look through each display
1440+ while($row = $db->get_assoc_row($result))
1441 {
1442- $displayid = $row[0];
1443- $lastAccessed = $row[1];
1444-
1445- Debug::LogEntry($db, 'audit', sprintf('LastAccessed = %d, Timeout = %d for displayId %d', $lastAccessed, $timeout, $displayid));
1446-
1447- $SQL = "UPDATE display SET loggedin = 0 WHERE displayid = " . $displayid;
1448-
1449- if ((!$db->query($SQL)))
1450- {
1451- trigger_error($db->error());
1452- }
1453+ $displayid = Kit::ValidateParam($row['displayid'], _INT);
1454+ $lastAccessed = Kit::ValidateParam($row['lastaccessed'], _INT);
1455+ $alertTimeout = Kit::ValidateParam($row['alert_timeout'], _INT);
1456+
1457+ // Do we need to update the logged in light?
1458+ $timeoutToTestAgainst = ($alertTimeout == 0) ? $globalTimeout : $alertTimeout;
1459+
1460+ // If the last time we accessed is less than now minus the timeout
1461+ if ($lastAccessed < time() - ($timeoutToTestAgainst * 60))
1462+ {
1463+ // Update the display and set it as logged out
1464+ $SQL = "UPDATE display SET loggedin = 0 WHERE displayid = " . $displayid;
1465+
1466+ if ((!$db->query($SQL)))
1467+ trigger_error($db->error());
1468+
1469+ Debug::LogEntry($db, 'audit', sprintf('LastAccessed = %d, Timeout = %d for displayId %d', $lastAccessed, $timeoutToTestAgainst, $displayid));
1470+ }
1471 }
1472 }
1473
1474@@ -794,5 +871,61 @@
1475 $response->AddButton(__('Close'), 'XiboDialogClose()');
1476 $response->Respond();
1477 }
1478+
1479+ /**
1480+ * Form for wake on Lan
1481+ */
1482+ public function WakeOnLanForm()
1483+ {
1484+ $db =& $this->db;
1485+ $response = new ResponseManager();
1486+
1487+ $displayId = Kit::GetParam('DisplayId', _GET, _INT);
1488+
1489+ $msg = __('Are you sure you want to send a Wake On Lan message to this display?');
1490+
1491+ // Get the MAC Address
1492+ $macAddress = $db->GetSingleValue(sprintf("SELECT MacAddress FROM `display` WHERE DisplayID = %d", $displayId), 'MacAddress', _STRING);
1493+
1494+ if (!$macAddress || $macAddress == '')
1495+ trigger_error(__('This display has no mac address recorded against it yet. Make sure the display is running.'), E_USER_ERROR);
1496+
1497+ $form = <<<END
1498+ <form id="WakeOnLanForm" class="XiboForm" method="post" action="index.php?p=display&q=WakeOnLan">
1499+ <input type="hidden" name="DisplayId" value="$displayId">
1500+ <inpput type="hidden" name="MacAddress" value="$macAddress">
1501+ <table>
1502+ <tr>
1503+ <td>$msg</td>
1504+ </tr>
1505+ </table>
1506+ </form>
1507+END;
1508+
1509+ $response->SetFormRequestResponse($form, __('Wake On Lan'), '300px', '150px');
1510+ $response->AddButton(__('Cancel'), 'XiboDialogClose()');
1511+ $response->AddButton(__('Send'), '$("#WakeOnLanForm").submit()');
1512+ $response->Respond();
1513+ }
1514+
1515+ /**
1516+ * Wake on LAN
1517+ */
1518+ public function WakeOnLan()
1519+ {
1520+ $db =& $this->db;
1521+ $response = new ResponseManager();
1522+ $displayObject = new Display($db);
1523+
1524+ $displayId = Kit::GetParam('DisplayId', _POST, _INT);
1525+
1526+ if (!$displayObject->WakeOnLan($displayId))
1527+ {
1528+ trigger_error($displayObject->GetErrorMessage(), E_USER_ERROR);
1529+ }
1530+
1531+ $response->SetFormSubmitResponse(__('Wake on Lan command sent.'));
1532+ $response->Respond();
1533+ }
1534 }
1535 ?>
1536
1537=== modified file 'server/lib/service/rest.class.php'
1538--- server/lib/service/rest.class.php 2011-07-29 11:23:06 +0000
1539+++ server/lib/service/rest.class.php 2012-04-14 10:54:18 +0000
1540@@ -1,7 +1,7 @@
1541 <?php
1542 /*
1543 * Xibo - Digitial Signage - http://www.xibo.org.uk
1544- * Copyright (C) 2010 Daniel Garner
1545+ * Copyright (C) 2010-2012 Daniel Garner
1546 *
1547 * This file is part of Xibo.
1548 *
1549@@ -90,6 +90,28 @@
1550 }
1551
1552 /**
1553+ * Display Wake On LAN
1554+ * @return <XiboAPIResponse>
1555+ */
1556+ public function DisplayWakeOnLan()
1557+ {
1558+ if (!$this->user->PageAuth('display'))
1559+ return $this->Error(1, 'Access Denied');
1560+
1561+ Kit::ClassLoader('Display');
1562+
1563+ $displayObject = new Display($this->db);
1564+ $displaId = $this->GetParam('displayId', _INT);
1565+
1566+ // Try to issue the WOL command
1567+ if (!$displayObject->WakeOnLan($displayId))
1568+ return $this->Error($displayObject->GetErrorNumber(), $displayObject->GetErrorMessage());
1569+
1570+ // Return True
1571+ return $this->Respond($this->ReturnId('success', true));
1572+ }
1573+
1574+ /**
1575 * List Display User Group Security
1576 * @return <XiboAPIResponse>
1577 */
1578
1579=== modified file 'server/maintenance.php'
1580--- server/maintenance.php 2011-02-08 07:26:12 +0000
1581+++ server/maintenance.php 2012-04-14 10:54:18 +0000
1582@@ -31,6 +31,8 @@
1583 require_once("lib/app/translationengine.class.php");
1584 require_once("lib/app/debug.class.php");
1585 require_once("lib/app/kit.class.php");
1586+require_once("lib/data/data.class.php");
1587+require_once("lib/data/display.data.class.php");
1588
1589 // Required Config Files
1590 require_once("config/config.class.php");
1591@@ -280,6 +282,49 @@
1592 print "-&gt;" . __("Disabled") . "<br/>\n";
1593 }
1594 flush();
1595+
1596+
1597+ // Wake On LAN
1598+ print '<h1>' . __('Wake On LAN') . '</h1>';
1599+
1600+ // Create a display object to use later
1601+ $displayObject = new Display($db);
1602+
1603+ // Get a list of all displays which have WOL enabled
1604+ $SQL = "SELECT DisplayID, Display, WakeOnLanTime, LastWakeOnLanCommandSent FROM `display` WHERE WakeOnLan = 1";
1605+
1606+ foreach($db->GetArray($SQL) as $row)
1607+ {
1608+ $displayId = Kit::ValidateParam($row['DisplayID'], _INT);
1609+ $display = Kit::ValidateParam($row['Display'], _STRING);
1610+ $wakeOnLanTime = Kit::ValidateParam($row['WakeOnLanTime'], _STRING);
1611+ $lastWakeOnLan = Kit::ValidateParam($row['LastWakeOnLanCommandSent'], _INT);
1612+
1613+ // Time to WOL (with respect to today)
1614+ $timeToWake = strtotime(date('Y-m-d') . ' ' . $wakeOnLanTime);
1615+ $timeNow = time();
1616+
1617+ // Should the display be awake?
1618+ if ($timeNow >= $timeToWake)
1619+ {
1620+ // Client should be awake, so has this displays WOL time been passed
1621+ if ($lastWakeOnLan < $timeToWake)
1622+ {
1623+ // Call the Wake On Lan method of the display object
1624+ if (!$displayObject->WakeOnLan($displayId))
1625+ print $display . ':Error=' . $displayObject->GetErrorMessage() . '<br/>\n';
1626+ else
1627+ print $display . ':Sent WOL Message. Previous WOL send time: ' . date('Y-m-d H:i:s', $lastWakeOnLan) . '<br/>\n';
1628+ }
1629+ else
1630+ print $display . ':Display already awake. Previous WOL send time: ' . date('Y-m-d H:i:s', $lastWakeOnLan) . '<br/>\n';
1631+ }
1632+ else
1633+ print $display . ':Sleeping<br/>\n';
1634+ print $display . ':N/A<br/>\n';
1635+ }
1636+
1637+ flush();
1638 }
1639 else
1640 {
1641
1642=== modified file 'server/template/header.php'
1643--- server/template/header.php 2011-10-30 12:38:11 +0000
1644+++ server/template/header.php 2012-04-14 10:54:18 +0000
1645@@ -92,7 +92,7 @@
1646
1647 echo $body;
1648 ?>
1649-
1650+ <!-- Copyright 2006-2012 Daniel Garner and the Xibo Developers. Part of the Xibo Open Source Digital Signage Solution. AGPLv3 or later License Applies. -->
1651 <div id="container">
1652 <div id="headercontainer">
1653 <div id="header"></div>

Subscribers

People subscribed via source and target branches

to status/vote changes: