Merge lp:~dangarner/xibo/server-132 into lp:xibo/1.3

Proposed by Dan Garner
Status: Merged
Merged at revision: 232
Proposed branch: lp:~dangarner/xibo/server-132
Merge into: lp:xibo/1.3
Diff against target: 1890 lines (+1072/-176)
30 files modified
server/install/database/43.sql (+5/-0)
server/install/database/44.sql (+48/-0)
server/lib/app/helpmanager.class.php (+1/-1)
server/lib/data/display.data.class.php (+33/-3)
server/lib/data/layout.data.class.php (+51/-2)
server/lib/data/layoutgroupsecurity.data.class.php (+39/-0)
server/lib/data/layoutmediagroupsecurity.data.class.php (+88/-0)
server/lib/data/layoutregiongroupsecurity.data.class.php (+40/-0)
server/lib/data/media.data.class.php (+67/-0)
server/lib/data/usergroup.data.class.php (+57/-1)
server/lib/include.php (+3/-3)
server/lib/js/index.js (+71/-1)
server/lib/js/mediamanager.js (+8/-33)
server/lib/js/stats.js (+7/-2)
server/lib/modules/module.class.php (+74/-4)
server/lib/pages/admin.class.php (+12/-0)
server/lib/pages/content.class.php (+12/-2)
server/lib/pages/display.class.php (+1/-1)
server/lib/pages/displaygroup.class.php (+5/-7)
server/lib/pages/index.class.php (+42/-35)
server/lib/pages/layout.class.php (+11/-1)
server/lib/pages/mediamanager.class.php (+41/-1)
server/lib/pages/region.class.php (+19/-3)
server/lib/pages/stats.class.php (+246/-35)
server/lib/pages/user.class.php (+68/-38)
server/lib/service/xmdssoap.class.php (+3/-1)
server/locale/dbtranslate.php (+2/-0)
server/modules/module_db_mysql.php (+12/-0)
server/modules/module_user_general.php (+5/-1)
server/template/header.php (+1/-1)
To merge this branch: bzr merge lp:~dangarner/xibo/server-132
Reviewer Review Type Date Requested Status
Xibo Maintainters Pending
Review via email: mp+89590@code.launchpad.net
To post a comment you must log in.
lp:~dangarner/xibo/server-132 updated
254. By Dan Garner

[server] Version bump in pre-display checks

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'server/install/database/43.sql'
2--- server/install/database/43.sql 1970-01-01 00:00:00 +0000
3+++ server/install/database/43.sql 2012-01-22 15:55:27 +0000
4@@ -0,0 +1,5 @@
5+INSERT INTO `setting` (`settingid`, `setting`, `value`, `type`, `helptext`, `options`, `cat`, `userChange`) VALUES (NULL, 'LAYOUT_COPY_MEDIA_CHECKB', 'Unchecked', 'dropdown', 'Default the checkbox for making duplicates of media when copying layouts', 'Checked|Unchecked', 'default', '1');
6+
7+UPDATE `version` SET `app_ver` = '1.3.2', `XmdsVersion` = 3;
8+UPDATE `setting` SET `value` = 0 WHERE `setting` = 'PHONE_HOME_DATE';
9+UPDATE `version` SET `DBVersion` = '43';
10\ No newline at end of file
11
12=== added file 'server/install/database/44.sql'
13--- server/install/database/44.sql 1970-01-01 00:00:00 +0000
14+++ server/install/database/44.sql 2012-01-22 15:55:27 +0000
15@@ -0,0 +1,48 @@
16+TRUNCATE TABLE help;
17+
18+INSERT INTO `help` (`HelpID`, `Topic`, `Category`, `Link`) VALUES
19+(1, 'Layout', 'General', 'http://wiki.xibo.org.uk/wiki/Manual:Layouts'),
20+(2, 'Content', 'General', 'http://wiki.xibo.org.uk/wiki/Manual:Media#The_Library'),
21+(4, 'Schedule', 'General', 'http://wiki.xibo.org.uk/wiki/Manual:Scheduling'),
22+(5, 'Group', 'General', 'http://wiki.xibo.org.uk/wiki/Manual:Administration:Users#Groups'),
23+(6, 'Admin', 'General', 'http://wiki.xibo.org.uk/wiki/Manual:Administration:Settings'),
24+(7, 'Report', 'General', 'http://wiki.xibo.org.uk/wiki/Manual:Administration:Log'),
25+(8, 'Dashboard', 'General', 'http://wiki.xibo.org.uk/wiki/Manual:Overview#Dashboard'),
26+(9, 'User', 'General', 'http://wiki.xibo.org.uk/wiki/Manual:Administration:Users'),
27+(10, 'Display', 'General', 'http://wiki.xibo.org.uk/wiki/Manual:Administration:Displays'),
28+(11, 'Displaygroup', 'General', 'http://wiki.xibo.org.uk/wiki/Manual:Administration:Displays#Groups'),
29+(12, 'Layout', 'Add', 'http://wiki.xibo.org.uk/wiki/Manual:Layouts:Design#Adding_Layouts'),
30+(13, 'Layout', 'Background', 'http://wiki.xibo.org.uk/wiki/Manual:Layouts:Design#Layout_Designer'),
31+(14, 'Content', 'Assign', 'http://wiki.xibo.org.uk/wiki/Manual:Layouts:Design#Library'),
32+(15, 'Layout', 'RegionOptions', 'http://wiki.xibo.org.uk/wiki/Manual:Layouts:Design#Assigning_Media'),
33+(16, 'Content', 'AddtoLibrary', 'http://wiki.xibo.org.uk/wiki/Manual:Media'),
34+(17, 'Display', 'Edit', 'http://wiki.xibo.org.uk/wiki/Manual:Administration:Displays#Edit'),
35+(18, 'Display', 'Delete', 'http://wiki.xibo.org.uk/wiki/Manual:Administration:Displays#Delete'),
36+(19, 'Displays', 'Groups', 'http://wiki.xibo.org.uk/wiki/Manual:Administration:Displays#Groups'),
37+(20, 'Groups', 'General', 'http://wiki.xibo.org.uk/wiki/Manual:Administration:Users'),
38+(21, 'User', 'Add', 'http://wiki.xibo.org.uk/wiki/Manual:Administration:Users#Add'),
39+(22, 'User', 'Delete', 'http://wiki.xibo.org.uk/wiki/Manual:Administration:Users#Delete'),
40+(23, 'Content', 'Config', 'http://wiki.xibo.org.uk/wiki/Manual:Administration:Settings'),
41+(24, 'LayoutMedia', 'Permissions', 'http://wiki.xibo.org.uk/wiki/Manual:Layouts:Management#Layout_Permissions'),
42+(25, 'Region', 'Permissions', 'http://wiki.xibo.org.uk/wiki/Manual:Layouts:Management#Layout_Permissions'),
43+(26, 'Library', 'Assign', 'http://wiki.xibo.org.uk/wiki/Manual:Layouts:Design#AssigningFromLibrary'),
44+(27, 'Media', 'Delete', 'http://wiki.xibo.org.uk/wiki/Manual:Media#Delete'),
45+(28, 'DisplayGroup', 'Add', 'http://wiki.xibo.org.uk/wiki/Manual:Administration:DisplayGroups#Add'),
46+(29, 'DisplayGroup', 'Edit', 'http://wiki.xibo.org.uk/wiki/Manual:Administration:DisplayGroups#Edit'),
47+(30, 'DisplayGroup', 'Delete', 'http://wiki.xibo.org.uk/wiki/Manual:Administration:DisplayGroups#Delete'),
48+(31, 'DisplayGroup', 'Members', 'http://wiki.xibo.org.uk/wiki/Manual:Administration:DisplayGroups#Members'),
49+(32, 'DisplayGroup', 'GroupSecurity', 'http://wiki.xibo.org.uk/wiki/Manual:Administration:DisplayGroups#GroupSecurity');
50+
51+INSERT INTO `setting` (`settingid`, `setting`, `value`, `type`, `helptext`, `options`, `cat`, `userChange`) VALUES (NULL, 'MAX_LICENSED_DISPLAYS', '0', 'text', 'The maximum number of licensed clients for this server installation. 0 = unlimited', NULL, 'general', '0');
52+
53+ALTER TABLE `setting` CHANGE `setting` `setting` VARCHAR( 50 ) NOT NULL;
54+INSERT INTO `setting` (`settingid`, `setting`, `value`, `type`, `helptext`, `options`, `cat`, `userChange`) VALUES (NULL, 'LIBRARY_MEDIA_UPDATEINALL_CHECKB', 'Unchecked', 'dropdown', 'Default the checkbox for updating media on all layouts when editing in the library', 'Checked|Unchecked', 'default', '1');
55+
56+ALTER TABLE `display` ADD `MacAddress` VARCHAR( 254 ) NULL COMMENT 'Mac Address of the Client',
57+ADD `LastChanged` INT NULL COMMENT 'Last time this Mac Address changed';
58+
59+ALTER TABLE `display` ADD `NumberOfMacAddressChanges` INT NOT NULL;
60+
61+UPDATE `version` SET `app_ver` = '1.3.2', `XmdsVersion` = 3;
62+UPDATE `setting` SET `value` = 0 WHERE `setting` = 'PHONE_HOME_DATE';
63+UPDATE `version` SET `DBVersion` = '44';
64\ No newline at end of file
65
66=== modified file 'server/lib/app/helpmanager.class.php'
67--- server/lib/app/helpmanager.class.php 2009-12-31 11:38:50 +0000
68+++ server/lib/app/helpmanager.class.php 2012-01-22 15:55:27 +0000
69@@ -103,7 +103,7 @@
70 $user =& $this->user;
71
72 // if topic is empty use the page name
73- $topic = Kit::GetParam('p', _REQUEST, _WORD, $topic);
74+ $topic = ($topic == '') ? Kit::GetParam('p', _REQUEST, _WORD) : $topic;
75 $topic = ucfirst($topic);
76
77 $link = 'index.php?p=help&q=Display&Topic=' . $topic . '&Category=' . $category . '';
78
79=== modified file 'server/lib/data/display.data.class.php'
80--- server/lib/data/display.data.class.php 2011-03-01 16:42:16 +0000
81+++ server/lib/data/display.data.class.php 2012-01-22 15:55:27 +0000
82@@ -115,8 +115,26 @@
83 {
84 $db =& $this->db;
85
86- Debug::LogEntry($db, 'audit', 'IN', 'DisplayGroup', 'Edit');
87-
88+ Debug::LogEntry($db, 'audit', 'IN', 'Display', 'Edit');
89+
90+ // Check the number of licensed displays
91+ $maxDisplays = Config::GetSetting($db, 'MAX_LICENSED_DISPLAYS');
92+
93+ if ($maxDisplays > 0)
94+ {
95+ // See if this is a license switch
96+ $currentLicense = $db->GetSingleValue(sprintf('SELECT licensed FROM display WHERE DisplayID = %d', $displayID), 'licensed', _INT);
97+
98+ if ($currentLicense != $licensed && $licensed == 1)
99+ {
100+ // License change - test number of licensed displays.
101+ $licensedDisplays = $db->GetSingleValue('SELECT COUNT(DisplayID) AS CountLicensed FROM display WHERE licensed =1 ', 'CountLicensed', _INT);
102+
103+ if ($licensedDisplays + 1 > $maxDisplays)
104+ return $this->SetError(25000, sprintf(__('You have exceeded your maximum number of licensed displays. %d'), $maxDisplays));
105+ }
106+ }
107+
108 // Update the display record
109 $SQL = "UPDATE display SET display = '%s', ";
110 $SQL .= " defaultlayoutid = %d, ";
111@@ -251,7 +269,7 @@
112 * @return
113 * @param $license Object
114 */
115- public function Touch($license, $clientAddress = '', $mediaInventoryComplete = 0, $mediaInventoryXml = '')
116+ public function Touch($license, $clientAddress = '', $mediaInventoryComplete = 0, $mediaInventoryXml = '', $macAddress = '')
117 {
118 $db =& $this->db;
119 $time = time();
120@@ -273,6 +291,18 @@
121 if ($mediaInventoryXml != '')
122 $SQL .= sprintf(" , MediaInventoryXml = '%s' ", $mediaInventoryXml);
123
124+ // Mac address storage
125+ if ($macAddress != '')
126+ {
127+ // Address changed.
128+ $currentAddress = $db->GetSingleValue(sprintf("SELECT MacAddress FROM display WHERE license = '%s'", $license), 'MacAddress', _STRING);
129+
130+ if ($macAddress != $currentAddress)
131+ {
132+ $SQL .= sprintf(" , MacAddress = '%s', LastChanged = %d, NumberOfMacAddressChanges = NumberOfMacAddressChanges + 1 ", $macAddress, time());
133+ }
134+ }
135+
136 // Restrict to the display license
137 $SQL .= " WHERE license = '%s'";
138 $SQL = sprintf($SQL, $time, $license);
139
140=== modified file 'server/lib/data/layout.data.class.php'
141--- server/lib/data/layout.data.class.php 2011-08-29 22:08:11 +0000
142+++ server/lib/data/layout.data.class.php 2012-01-22 15:55:27 +0000
143@@ -1,7 +1,7 @@
144 <?php
145 /*
146 * Xibo - Digitial Signage - http://www.xibo.org.uk
147- * Copyright (C) 2009 Daniel Garner
148+ * Copyright (C) 2011 Daniel Garner
149 *
150 * This file is part of Xibo.
151 *
152@@ -347,13 +347,28 @@
153 * @param <int> $oldLayoutId
154 * @param <string> $newLayoutName
155 * @param <int> $userId
156+ * @param <bool> $copyMedia Make copies of this layouts media
157 * @return <int>
158 */
159- public function Copy($oldLayoutId, $newLayoutName, $userId)
160+ public function Copy($oldLayoutId, $newLayoutName, $userId, $copyMedia = false)
161 {
162 $db =& $this->db;
163 $currentdate = date("Y-m-d H:i:s");
164
165+ // Include to media data class?
166+ if ($copyMedia)
167+ {
168+ Kit::ClassLoader('media');
169+ Kit::ClassLoader('mediagroupsecurity');
170+ $mediaObject = new Media($db);
171+ $mediaSecurity = new MediaGroupSecurity($db);
172+ }
173+
174+ // Permissions model
175+ Kit::ClassLoader('layoutgroupsecurity');
176+ Kit::ClassLoader('layoutregiongroupsecurity');
177+ Kit::ClassLoader('layoutmediagroupsecurity');
178+
179 // The Layout ID is the old layout
180 $SQL = "";
181 $SQL .= " INSERT INTO layout (layout, xml, userID, description, tags, templateID, retired, duration, background, createdDT, modifiedDT) ";
182@@ -399,12 +414,34 @@
183
184 // If this is a non region specific type, then move on
185 if ($this->IsRegionSpecific($type))
186+ {
187+ // Copy media security
188+ $security = new LayoutMediaGroupSecurity($db);
189+ $security->CopyAllForMedia($oldLayoutId, $newLayoutId, $mediaId, $mediaId);
190 continue;
191+ }
192
193 // Get the regionId
194 $regionNode = $mediaNode->parentNode;
195 $regionId = $regionNode->getAttribute('id');
196
197+ // Do we need to copy this media record?
198+ if ($copyMedia)
199+ {
200+ // Store the old media id
201+ $oldMediaId = $mediaId;
202+
203+ // Take this media item and make a hard copy of it.
204+ if (!$mediaId = $mediaObject->Copy($mediaId, $newLayoutName))
205+ {
206+ $this->Delete($newLayoutId);
207+ return false;
208+ }
209+
210+ // Update the permissions for the new media record
211+ $mediaSecurity->Copy($oldMediaId, $mediaId);
212+ }
213+
214 // Add the database link for this media record
215 if (!$lkId = $this->AddLk($newLayoutId, $regionId, $mediaId))
216 {
217@@ -412,14 +449,26 @@
218 return false;
219 }
220
221+ // Update the permissions for this media on this layout
222+ $security = new LayoutMediaGroupSecurity($db);
223+ $security->CopyAllForMedia($oldLayoutId, $newLayoutId, $oldMediaId, $mediaId);
224+
225 // Set this LKID on the media node
226 $mediaNode->setAttribute('lkid', $lkId);
227+ $mediaNode->setAttribute('id', $mediaId);
228 }
229
230 Debug::LogEntry($this->db, 'audit', 'Finished looping through media nodes', 'layout', 'Copy');
231
232 // Set the XML
233 $this->SetLayoutXml($newLayoutId, $this->DomXml->saveXML());
234+
235+ // Layout permissions
236+ $security = new LayoutGroupSecurity($db);
237+ $security->CopyAll($oldLayoutId, $newLayoutId);
238+
239+ $security = new LayoutRegionGroupSecurity($db);
240+ $security->CopyAll($oldLayoutId, $newLayoutId);
241
242 // Return the new layout id
243 return $newLayoutId;
244
245=== modified file 'server/lib/data/layoutgroupsecurity.data.class.php'
246--- server/lib/data/layoutgroupsecurity.data.class.php 2011-07-29 16:23:42 +0000
247+++ server/lib/data/layoutgroupsecurity.data.class.php 2012-01-22 15:55:27 +0000
248@@ -145,5 +145,44 @@
249
250 return true;
251 }
252+
253+ /**
254+ * Copys all security for a layout
255+ * @param <type> $layoutId
256+ * @param <type> $newLayoutId
257+ * @return <type>
258+ */
259+ public function CopyAll($layoutId, $newLayoutId)
260+ {
261+ $db =& $this->db;
262+
263+ Debug::LogEntry($db, 'audit', 'IN', 'LayoutGroupSecurity', 'Copy');
264+
265+ $SQL = "";
266+ $SQL .= "INSERT ";
267+ $SQL .= "INTO lklayoutgroup ";
268+ $SQL .= " ( ";
269+ $SQL .= " LayoutID, ";
270+ $SQL .= " GroupID, ";
271+ $SQL .= " View, ";
272+ $SQL .= " Edit, ";
273+ $SQL .= " Del ";
274+ $SQL .= " ) ";
275+ $SQL .= " SELECT '%s', GroupID, View, Edit, Del ";
276+ $SQL .= " FROM lklayoutgroup ";
277+ $SQL .= " WHERE LayoutID = %d ";
278+
279+ $SQL = sprintf($SQL, $newLayoutId, $layoutId);
280+
281+ if (!$db->query($SQL))
282+ {
283+ trigger_error($db->error());
284+ $this->SetError(25028, __('Could not Copy All Layout Security'));
285+
286+ return false;
287+ }
288+
289+ return true;
290+ }
291 }
292 ?>
293\ No newline at end of file
294
295=== modified file 'server/lib/data/layoutmediagroupsecurity.data.class.php'
296--- server/lib/data/layoutmediagroupsecurity.data.class.php 2011-08-11 18:07:32 +0000
297+++ server/lib/data/layoutmediagroupsecurity.data.class.php 2012-01-22 15:55:27 +0000
298@@ -190,5 +190,93 @@
299
300 return true;
301 }
302+
303+ /**
304+ * Copys all media security for a layout
305+ * @param <type> $layoutId
306+ * @param <type> $newLayoutId
307+ * @return <type>
308+ */
309+ public function CopyAll($layoutId, $newLayoutId)
310+ {
311+ $db =& $this->db;
312+
313+ Debug::LogEntry($db, 'audit', 'IN', 'LayoutMediaGroupSecurity', 'Copy');
314+
315+ $SQL = "";
316+ $SQL .= "INSERT ";
317+ $SQL .= "INTO lklayoutmediagroup ";
318+ $SQL .= " ( ";
319+ $SQL .= " LayoutID, ";
320+ $SQL .= " RegionID, ";
321+ $SQL .= " MediaID, ";
322+ $SQL .= " GroupID, ";
323+ $SQL .= " View, ";
324+ $SQL .= " Edit, ";
325+ $SQL .= " Del ";
326+ $SQL .= " ) ";
327+ $SQL .= " SELECT '%s', RegionID, MediaID, GroupID, View, Edit, Del ";
328+ $SQL .= " FROM lklayoutmediagroup ";
329+ $SQL .= " WHERE LayoutID = %d ";
330+
331+ $SQL = sprintf($SQL, $newLayoutId, $layoutId);
332+
333+ Debug::LogEntry($db, 'audit', $SQL);
334+
335+ if (!$db->query($SQL))
336+ {
337+ trigger_error($db->error());
338+ $this->SetError(25028, __('Could not Copy All Layout Media Security'));
339+
340+ return false;
341+ }
342+
343+ return true;
344+ }
345+
346+ /**
347+ * Copys all security for specific media on a layout
348+ * @param <type> $layoutId
349+ * @param <type> $newLayoutId
350+ * @param <type> $oldMediaId
351+ * @param <type> $newMediaId
352+ * @return <type>
353+ */
354+ public function CopyAllForMedia($layoutId, $newLayoutId, $oldMediaId, $newMediaId)
355+ {
356+ $db =& $this->db;
357+
358+ Debug::LogEntry($db, 'audit', 'IN', 'LayoutMediaGroupSecurity', 'Copy');
359+
360+ $SQL = "";
361+ $SQL .= "INSERT ";
362+ $SQL .= "INTO lklayoutmediagroup ";
363+ $SQL .= " ( ";
364+ $SQL .= " LayoutID, ";
365+ $SQL .= " RegionID, ";
366+ $SQL .= " MediaID, ";
367+ $SQL .= " GroupID, ";
368+ $SQL .= " View, ";
369+ $SQL .= " Edit, ";
370+ $SQL .= " Del ";
371+ $SQL .= " ) ";
372+ $SQL .= " SELECT '%s', RegionID, '%s', GroupID, View, Edit, Del ";
373+ $SQL .= " FROM lklayoutmediagroup ";
374+ $SQL .= " WHERE LayoutID = %d AND MediaID = '%s' ";
375+
376+ $SQL = sprintf($SQL, $newLayoutId, $newMediaId, $layoutId, $oldMediaId);
377+
378+ Debug::LogEntry($db, 'audit', $SQL);
379+
380+ if (!$db->query($SQL))
381+ {
382+ trigger_error($db->error());
383+ $this->SetError(25028, __('Could not Copy All Layout Media Security'));
384+
385+ return false;
386+ }
387+
388+ return true;
389+ }
390 }
391 ?>
392\ No newline at end of file
393
394=== modified file 'server/lib/data/layoutregiongroupsecurity.data.class.php'
395--- server/lib/data/layoutregiongroupsecurity.data.class.php 2011-07-29 16:23:42 +0000
396+++ server/lib/data/layoutregiongroupsecurity.data.class.php 2012-01-22 15:55:27 +0000
397@@ -146,5 +146,45 @@
398
399 return true;
400 }
401+
402+ /**
403+ * Copys all region security for a layout
404+ * @param <type> $layoutId
405+ * @param <type> $newLayoutId
406+ * @return <type>
407+ */
408+ public function CopyAll($layoutId, $newLayoutId)
409+ {
410+ $db =& $this->db;
411+
412+ Debug::LogEntry($db, 'audit', 'IN', 'LayoutRegionGroupSecurity', 'Copy');
413+
414+ $SQL = "";
415+ $SQL .= "INSERT ";
416+ $SQL .= "INTO lklayoutregiongroup ";
417+ $SQL .= " ( ";
418+ $SQL .= " LayoutID, ";
419+ $SQL .= " RegionID, ";
420+ $SQL .= " GroupID, ";
421+ $SQL .= " View, ";
422+ $SQL .= " Edit, ";
423+ $SQL .= " Del ";
424+ $SQL .= " ) ";
425+ $SQL .= " SELECT '%s', RegionID, GroupID, View, Edit, Del ";
426+ $SQL .= " FROM lklayoutregiongroup ";
427+ $SQL .= " WHERE LayoutID = %d ";
428+
429+ $SQL = sprintf($SQL, $newLayoutId, $layoutId);
430+
431+ if (!$db->query($SQL))
432+ {
433+ trigger_error($db->error());
434+ $this->SetError(25028, __('Could not Copy All Layout Region Security'));
435+
436+ return false;
437+ }
438+
439+ return true;
440+ }
441 }
442 ?>
443\ No newline at end of file
444
445=== modified file 'server/lib/data/media.data.class.php'
446--- server/lib/data/media.data.class.php 2011-07-28 23:54:40 +0000
447+++ server/lib/data/media.data.class.php 2012-01-22 15:55:27 +0000
448@@ -337,5 +337,72 @@
449
450 return $modules;
451 }
452+
453+ /**
454+ * Make a copy of this media record
455+ * @param <type> $oldMediaId
456+ */
457+ public function Copy($oldMediaId, $prefix = '')
458+ {
459+ $db =& $this->db;
460+
461+ // Get the extension from the old media record
462+ if (!$fileName = $this->db->GetSingleValue(sprintf("SELECT StoredAs FROM media WHERE MediaID = %d", $oldMediaId), 'StoredAs', _STRING))
463+ {
464+ trigger_error($db->error());
465+ return $this->SetError(26, __('Error getting media extension before copy.'));
466+ }
467+
468+ $extension = strtolower(substr(strrchr($fileName, '.'), 1));
469+
470+ $newMediaName = "CONCAT(name, ' ', 2)";
471+
472+ if ($prefix != '')
473+ $newMediaName = "CONCAT('$prefix', ' ', name)";
474+
475+ // All OK to insert this record
476+ $SQL = "INSERT INTO media (name, type, duration, originalFilename, userID, retired ) ";
477+ $SQL .= " SELECT %s, type, duration, originalFilename, userID, retired ";
478+ $SQL .= " FROM media ";
479+ $SQL .= " WHERE MediaID = %d ";
480+
481+ $SQL = sprintf($SQL, $newMediaName, $oldMediaId);
482+
483+ if (!$newMediaId = $db->insert_query($SQL))
484+ {
485+ trigger_error($db->error());
486+ return $this->SetError(26, __('Error copying media.'));
487+ }
488+
489+ // Make a copy of the file
490+ $libraryFolder = Config::GetSetting($db, 'LIBRARY_LOCATION');
491+
492+ if (!copy($libraryFolder . $oldMediaId . '.' . $extension, $libraryFolder . $newMediaId . '.' . $extension))
493+ {
494+ // If we couldnt move it - we need to delete the media record we just added
495+ $SQL = sprintf("DELETE FROM media WHERE mediaID = %d ", $newMediaId);
496+
497+ if (!$db->query($SQL))
498+ return $this->SetError(14, 'Error cleaning up after failure.');
499+
500+ return $this->SetError(15, 'Error storing file.');
501+ }
502+
503+ // Calculate the MD5 and the file size
504+ $storedAs = $libraryFolder . $newMediaId . '.' . $extension;
505+ $md5 = md5_file($storedAs);
506+ $fileSize = filesize($storedAs);
507+
508+ // Update the media record to include this information
509+ $SQL = sprintf("UPDATE media SET storedAs = '%s', `MD5` = '%s', FileSize = %d WHERE mediaid = %d", $newMediaId . '.' . $extension, $md5, $fileSize, $newMediaId);
510+
511+ if (!$db->query($SQL))
512+ {
513+ trigger_error($db->error());
514+ return $this->SetError(16, 'Updating stored file location and MD5');
515+ }
516+
517+ return $newMediaId;
518+ }
519 }
520 ?>
521
522=== modified file 'server/lib/data/usergroup.data.class.php'
523--- server/lib/data/usergroup.data.class.php 2009-12-11 15:43:31 +0000
524+++ server/lib/data/usergroup.data.class.php 2012-01-22 15:55:27 +0000
525@@ -1,7 +1,7 @@
526 <?php
527 /*
528 * Xibo - Digitial Signage - http://www.xibo.org.uk
529- * Copyright (C) 2009 Daniel Garner
530+ * Copyright (C) 2009-11 Daniel Garner
531 *
532 * This file is part of Xibo.
533 *
534@@ -193,6 +193,62 @@
535 }
536
537 /**
538+ * Unlinks all users from the speficied group
539+ * @param <type> $userGroupId
540+ */
541+ public function UnlinkAllUsers($userGroupId)
542+ {
543+ $db =& $this->db;
544+
545+ Debug::LogEntry($db, 'audit', 'IN', 'UserGroup', 'UnlinkAllUsers');
546+
547+ $SQL = "";
548+ $SQL .= "DELETE FROM ";
549+ $SQL .= " lkusergroup ";
550+ $SQL .= sprintf(" WHERE GroupID = %d ", $userGroupId);
551+
552+ if (!$db->query($SQL))
553+ {
554+ trigger_error($db->error());
555+ $this->SetError(25007, __('Could not Unlink all Users from User Group'));
556+
557+ return false;
558+ }
559+
560+ Debug::LogEntry($db, 'audit', 'OUT', 'UserGroup', 'UnlinkAllUsers');
561+
562+ return true;
563+ }
564+
565+ /**
566+ * Unliks all groups from the specified user
567+ * @param <type> $userId
568+ */
569+ public function UnlinkAllGroups($userId)
570+ {
571+ $db =& $this->db;
572+
573+ Debug::LogEntry($db, 'audit', 'IN', 'UserGroup', 'UnlinkAllGroups');
574+
575+ $SQL = "";
576+ $SQL .= "DELETE FROM ";
577+ $SQL .= " lkusergroup ";
578+ $SQL .= sprintf(" WHERE UserID = %d ", $userId);
579+
580+ if (!$db->query($SQL))
581+ {
582+ trigger_error($db->error());
583+ $this->SetError(25007, __('Could not Unlink Groups from User'));
584+
585+ return false;
586+ }
587+
588+ Debug::LogEntry($db, 'audit', 'OUT', 'UserGroup', 'UnlinkAllGroups');
589+
590+ return true;
591+ }
592+
593+ /**
594 * Edits the User Group associated with a User
595 * @return
596 * @param $userID Object
597
598=== modified file 'server/lib/include.php'
599--- server/lib/include.php 2011-09-01 22:35:43 +0000
600+++ server/lib/include.php 2012-01-22 15:55:27 +0000
601@@ -108,11 +108,11 @@
602 Config::Version($db);
603
604 // Does the version in the DB match the version of the code?
605-if (DBVERSION != '42')
606- die(sprintf('Incompatible database version detected. Please ensure your database and website versions match. You have %d and the website for %d', DBVERSION, 42));
607+if (DBVERSION != '44')
608+ die(sprintf('Incompatible database version detected. Please ensure your database and website versions match. You have %d and the website for %d', DBVERSION, 44));
609
610 // What is the production mode of the server?
611-if(Config::GetSetting($db, "SERVER_MODE")=="Test") ini_set('display_errors', 1);
612+if(Config::GetSetting($db, 'SERVER_MODE') == 'Test') ini_set('display_errors', 1);
613
614 // Debugging?
615 if(Config::GetSetting($db, "debug")=="On") error_reporting(E_ALL);
616
617=== modified file 'server/lib/js/index.js'
618--- server/lib/js/index.js 2008-12-10 23:48:15 +0000
619+++ server/lib/js/index.js 2012-01-22 15:55:27 +0000
620@@ -1,6 +1,6 @@
621 /*
622 * Xibo - Digitial Signage - http://www.xibo.org.uk
623- * Copyright (C) 2006,2007,2008 Daniel Garner and James Packer
624+ * Copyright (C) 2011 Daniel Garner
625 *
626 * This file is part of Xibo.
627 *
628@@ -36,4 +36,74 @@
629 function reset_time() {
630 document.getElementById("3").value = 0;
631 document.getElementById("4").value = 0;
632+}
633+
634+var text_callback = function()
635+{
636+ // Conjure up a text editor
637+ $("#ta_text").ckeditor();
638+
639+ // Make sure when we close the dialog we also destroy the editor
640+ $("#div_dialog").bind("dialogclose.xibo", function(event, ui){
641+ $("#ta_text").ckeditorGet().destroy();
642+ $("#div_dialog").unbind("dialogclose.xibo");
643+ })
644+
645+ $('#div_dialog').dialog('option', 'width', 800);
646+ $('#div_dialog').dialog('option', 'height', 500);
647+ $('#div_dialog').dialog('option', 'position', 'center');
648+
649+ return false; //prevent submit
650+}
651+
652+var microblog_callback = function()
653+{
654+ // Conjure up a text editor
655+ $("#ta_template").ckeditor();
656+ $("#ta_nocontent").ckeditor();
657+
658+ // Make sure when we close the dialog we also destroy the editor
659+ $("#div_dialog").bind("dialogclose.xibo", function(event, ui){
660+ $("#ta_template").ckeditorGet().destroy();
661+ $("#ta_nocontent").ckeditorGet().destroy();
662+
663+ $("#div_dialog").unbind("dialogclose.xibo");
664+ })
665+
666+ $('#div_dialog').dialog('option', 'width', 800);
667+ $('#div_dialog').dialog('option', 'height', 500);
668+ $('#div_dialog').dialog('option', 'position', 'center');
669+
670+
671+ return false; //prevent submit
672+}
673+
674+
675+var datasetview_callback = function()
676+{
677+ $("#columnsIn, #columnsOut").sortable({
678+ connectWith: '.connectedSortable',
679+ dropOnEmpty: true
680+ }).disableSelection();
681+
682+ return false; //prevent submit
683+}
684+
685+var DataSetViewSubmit = function() {
686+ // Serialise the form and then submit it via Ajax.
687+ var href = $("#ModuleForm").attr('action') + "&ajax=true";
688+
689+ // Get the two lists
690+ serializedData = $("#columnsIn").sortable('serialize') + "&" + $("#ModuleForm").serialize();
691+
692+ $.ajax({
693+ type: "post",
694+ url: href,
695+ cache: false,
696+ dataType: "json",
697+ data: serializedData,
698+ success: XiboSubmitResponse
699+ });
700+
701+ return;
702 }
703\ No newline at end of file
704
705=== modified file 'server/lib/js/mediamanager.js'
706--- server/lib/js/mediamanager.js 2011-09-06 19:07:49 +0000
707+++ server/lib/js/mediamanager.js 2012-01-22 15:55:27 +0000
708@@ -26,24 +26,13 @@
709 $("#div_dialog").bind("dialogclose.xibo", function(event, ui){
710 $("#ta_text").ckeditorGet().destroy();
711 $("#div_dialog").unbind("dialogclose.xibo");
712- })
713-
714- var regionid = $("#iRegionId").val();
715- var width = $("#region_"+regionid).width();
716- var height = $("#region_"+regionid).height();
717-
718- // Min width
719- if (width < 800) width = 800;
720-
721- // Adjust the width and height
722- width = width + 80;
723- height = height + 295;
724-
725- $('#div_dialog').height(height+"px");
726- $('#div_dialog').dialog('option', 'width', width);
727- $('#div_dialog').dialog('option', 'height', height);
728+ });
729+
730+ $('#div_dialog').dialog('option', 'width', 800);
731+ $('#div_dialog').dialog('option', 'height', 500);
732 $('#div_dialog').dialog('option', 'position', 'center');
733
734+
735 return false; //prevent submit
736 }
737
738@@ -61,25 +50,11 @@
739 $("#div_dialog").unbind("dialogclose.xibo");
740 })
741
742- var regionid = $("#iRegionId").val();
743- var width = $("#region_"+regionid).width();
744- var height = $("#region_"+regionid).height();
745-
746- //Min width
747- if (width < 800) width = 800;
748- height = height - 170;
749-
750- // Min height
751- if (height < 300) height = 300;
752-
753- width = width + 80;
754- height = height + 480;
755-
756- $('#div_dialog').height(height+"px");
757- $('#div_dialog').dialog('option', 'width', width);
758- $('#div_dialog').dialog('option', 'height', height);
759+ $('#div_dialog').dialog('option', 'width', 800);
760+ $('#div_dialog').dialog('option', 'height', 500);
761 $('#div_dialog').dialog('option', 'position', 'center');
762
763+
764 return false; //prevent submit
765 }
766
767
768=== modified file 'server/lib/js/stats.js'
769--- server/lib/js/stats.js 2009-12-03 21:11:23 +0000
770+++ server/lib/js/stats.js 2012-01-22 15:55:27 +0000
771@@ -1,6 +1,6 @@
772 /*
773 * Xibo - Digitial Signage - http://www.xibo.org.uk
774- * Copyright (C) 2009 Daniel Garner
775+ * Copyright (C) 2009-2012 Daniel Garner
776 *
777 * This file is part of Xibo.
778 *
779@@ -16,4 +16,9 @@
780 *
781 * You should have received a copy of the GNU Affero General Public License
782 * along with Xibo. If not, see <http://www.gnu.org/licenses/>.
783- */
784\ No newline at end of file
785+ */
786+$(document).ready(function(){
787+ $(".date-pick").datepicker({
788+ dateFormat: "yy-mm-dd"
789+ })
790+});
791\ No newline at end of file
792
793=== modified file 'server/lib/modules/module.class.php'
794--- server/lib/modules/module.class.php 2011-09-01 20:42:49 +0000
795+++ server/lib/modules/module.class.php 2012-01-22 15:55:27 +0000
796@@ -463,7 +463,7 @@
797 {
798 $db =& $this->db;
799 $helpManager = new HelpManager($db, $this->user);
800- $this->response->AddButton(__('Help'), 'XiboHelpRender("' . $helpManager->Link($this->type, 'Delete') . '")');
801+ $this->response->AddButton(__('Help'), 'XiboHelpRender("' . $helpManager->Link('Media', 'Delete') . '")');
802
803 //Parameters
804 $layoutid = $this->layoutid;
805@@ -579,7 +579,7 @@
806
807 $msgWarn = __('Are you sure you want to delete this media?');
808 $msgSelect = __('Please select from the following options');
809- $msgCaution = __('Warning! You cannot undo this operation');
810+ $msgCaution = __('Deleting media cannot be undone');
811
812 //we can delete
813 $form = <<<END
814@@ -922,7 +922,8 @@
815 }
816 else
817 {
818- $extraNotes = '<em>Note: As you are editing from the library uploading a new media item will not replace the old one from any layouts. To do this navigate to the layout and edit the media from there.</em>';
819+ $updateMediaChecked = (Config::GetSetting($db, 'LIBRARY_MEDIA_UPDATEINALL_CHECKB') == 'Checked') ? 'checked' : '';
820+ $extraNotes = '<input type="checkbox" id="replaceInLayouts" name="replaceInLayouts" ' . $updateMediaChecked . '><label for="replaceInLayouts">' . __('Update this media in all layouts it is assigned to. Note: It will only be replaced in layouts you have permission to edit.') . '</label>';
821
822 $save_button = <<<END
823 <input id="btnSave" type="submit" value="Save" />
824@@ -1408,12 +1409,81 @@
825 $db->query(sprintf("UPDATE media SET duration = %d WHERE mediaID = %d", $this->duration, $this->mediaid));
826
827 $this->response->message = 'Edited the ' . $this->displayType;
828+
829+ // Edit from the library - check to see if we are replacing this media in *all* layouts.
830+ if (Kit::GetParam('replaceInLayouts', _POST, _CHECKBOX) == 1)
831+ $this->ReplaceMediaInAllLayouts($mediaid, $this->mediaid, $this->duration);
832 }
833
834 return $this->response;
835 }
836
837 /**
838+ * Replace media in all layouts.
839+ * @param <type> $oldMediaId
840+ * @param <type> $newMediaId
841+ */
842+ private function ReplaceMediaInAllLayouts($oldMediaId, $newMediaId)
843+ {
844+ Kit::ClassLoader('region');
845+ $db =& $this->db;
846+ $count = 0;
847+
848+ Debug::LogEntry($db, 'audit', sprintf('Replacing mediaid %s with mediaid %s in all layouts', $oldMediaId, $newMediaId), 'module', 'ReplaceMediaInAllLayouts');
849+
850+ // Create a region object for later use
851+ $region = new region($db, $this->user);
852+
853+ // Loop through a list of layouts this user has access to
854+ foreach($this->user->LayoutList() as $layout)
855+ {
856+ $layoutId = $layout['layoutid'];
857+
858+ // Does this layout use the old media id?
859+ $SQL = sprintf("SELECT lklayoutmediaid, regionid FROM lklayoutmedia WHERE mediaid = %d and layoutid = %d", $oldMediaId, $layoutId);
860+
861+ if (!$results = $db->query($SQL))
862+ return false;
863+
864+ // Loop through each media link for this layout
865+ while ($row = $db->get_assoc_row($results))
866+ {
867+ // Get the LKID of the link between this layout and this media.. could be more than one?
868+ $lkId = $row['lklayoutmediaid'];
869+ $regionId = $row['regionid'];
870+
871+ // Get the Type of this media
872+ if (!$type = $region->GetMediaNodeType($layoutId, '', '', $lkId))
873+ continue;
874+
875+ // Create a new media node use it to swap the nodes over
876+ Debug::LogEntry($db, 'audit', 'Creating new module with MediaID: ' . $newMediaId . ' LayoutID: ' . $layoutId . ' and RegionID: ' . $regionId, 'region', 'ReplaceMediaInAllLayouts');
877+ require_once('modules/' . $type . '.module.php');
878+
879+ // Create a new module as if we were assigning it for the first time
880+ $module = new $type($db, $this->user, $newMediaId);
881+
882+ // Sets the URI field
883+ $module->SetRegionInformation($layoutId, $regionId);
884+
885+ // Get the media xml string to use in the swap.
886+ $mediaXmlString = $module->AsXml();
887+
888+ // Swap the nodes
889+ if (!$region->SwapMedia($layoutId, $regionId, $lkId, $oldMediaId, $newMediaId, $mediaXmlString))
890+ return false;
891+
892+ // Update the LKID with the new media id
893+ $db->query("UPDATE lklayoutmedia SET mediaid = %d WHERE lklayoutmediaid = %d", $newMediaId, $row['lklayoutmediaid']);
894+
895+ $count++;
896+ }
897+ }
898+
899+ Debug::LogEntry($db, 'audit', sprintf('Replaced media in %d layouts', $count), 'module', 'ReplaceMediaInAllLayouts');
900+ }
901+
902+ /**
903 * Default GetName
904 * @return
905 */
906@@ -1529,7 +1599,7 @@
907 $form .= '</form>';
908
909 $response->SetFormRequestResponse($form, __('Permissions'), '350px', '500px');
910- $response->AddButton(__('Help'), 'XiboHelpRender("' . $helpManager->Link('Layout', 'Permissions') . '")');
911+ $response->AddButton(__('Help'), 'XiboHelpRender("' . $helpManager->Link('LayoutMedia', 'Permissions') . '")');
912 $response->AddButton(__('Cancel'), 'XiboSwapDialog("index.php?p=layout&layoutid=' . $this->layoutid . '&regionid=' . $this->regionid . '&q=RegionOptions")');
913 $response->AddButton(__('Save'), '$("#LayoutPermissionsForm").submit()');
914
915
916=== modified file 'server/lib/pages/admin.class.php'
917--- server/lib/pages/admin.class.php 2010-06-08 17:26:47 +0000
918+++ server/lib/pages/admin.class.php 2012-01-22 15:55:27 +0000
919@@ -251,6 +251,18 @@
920 </select>
921 END;
922 }
923+
924+ if ($cat == 'content')
925+ {
926+ // Display the file size
927+ $fileSize = $this->db->GetSingleValue('SELECT SUM(FileSize) AS SumSize FROM media', 'SumSize', _INT);
928+
929+ $sz = 'BKMGTP';
930+ $factor = floor((strlen($fileSize) - 1) / 3);
931+ $fileSize = sprintf('%.2f', $fileSize / pow(1024, $factor)) . @$sz[$factor];
932+
933+ $output .= sprintf('<p>You have %s of media in the library.</p>', $fileSize);
934+ }
935
936 // Need to now get all the Misc settings
937 $SQL = "";
938
939=== modified file 'server/lib/pages/content.class.php'
940--- server/lib/pages/content.class.php 2011-08-22 22:10:57 +0000
941+++ server/lib/pages/content.class.php 2012-01-22 15:55:27 +0000
942@@ -167,7 +167,8 @@
943 $SQL .= " media.name, ";
944 $SQL .= " media.type, ";
945 $SQL .= " media.duration, ";
946- $SQL .= " media.userID ";
947+ $SQL .= " media.userID, ";
948+ $SQL .= " media.FileSize ";
949 $SQL .= "FROM media ";
950 $SQL .= "WHERE isEdited = 0 ";
951 if ($mediatype != "all")
952@@ -206,6 +207,7 @@
953 $msgType = __('Type');
954 $msgRetired = __('Retired');
955 $msgOwner = __('Owner');
956+ $msgFileSize = __('Size');
957 $msgShared = __('Permissions');
958 $msgAction = __('Action');
959
960@@ -217,6 +219,7 @@
961 <th>$msgName</th>
962 <th>$msgType</th>
963 <th>h:mi:ss</th>
964+ <th>$msgFileSize</th>
965 <th>$msgOwner</th>
966 <th>$msgShared</th>
967 <th>$msgAction</th>
968@@ -232,9 +235,15 @@
969 $mediatype = Kit::ValidateParam($aRow[2], _WORD);
970 $length = sec2hms(Kit::ValidateParam($aRow[3], _DOUBLE));
971 $ownerid = Kit::ValidateParam($aRow[4], _INT);
972+ $fileSize = Kit::ValidateParam($aRow[5], _INT);
973+
974+ // Size in MB
975+ $sz = 'BKMGTP';
976+ $factor = floor((strlen($fileSize) - 1) / 3);
977+ $fileSize = sprintf('%.2f', $fileSize / pow(1024, $factor)) . @$sz[$factor];
978
979 //get the username from the userID using the user module
980- $username = $user->getNameFromID($ownerid);
981+ $username = $user->getNameFromID($ownerid);
982
983 $group = $this->GroupsForMedia($mediaid);
984
985@@ -258,6 +267,7 @@
986 $output .= "<td>$media</td>\n";
987 $output .= "<td>$mediatype</td>\n";
988 $output .= "<td>$length</td>\n";
989+ $output .= "<td>$fileSize</td>\n";
990 $output .= "<td>$username</td>";
991 $output .= "<td>$group</td>";
992
993
994=== modified file 'server/lib/pages/display.class.php'
995--- server/lib/pages/display.class.php 2011-07-29 12:46:13 +0000
996+++ server/lib/pages/display.class.php 2012-01-22 15:55:27 +0000
997@@ -157,7 +157,7 @@
998
999 if (!$displayObject->Edit($displayid, $display, $auditing, $layoutid, $licensed, $inc_schedule, $email_alert, $alert_timeout))
1000 {
1001- trigger_error(__('Cannot Edit this Display'), E_USER_ERROR);
1002+ trigger_error($displayObject->GetErrorMessage(), E_USER_ERROR);
1003 }
1004
1005 $response->SetFormSubmitResponse(__('Display Saved.'));
1006
1007=== modified file 'server/lib/pages/displaygroup.class.php'
1008--- server/lib/pages/displaygroup.class.php 2011-07-24 22:19:52 +0000
1009+++ server/lib/pages/displaygroup.class.php 2012-01-22 15:55:27 +0000
1010@@ -174,7 +174,6 @@
1011 $helpManager = new HelpManager($db, $user);
1012
1013 // Help UI
1014- $helpButton = $helpManager->HelpButton("displays/groups", true);
1015 $nameHelp = $helpManager->HelpIcon(__("The Name of this Group."), true);
1016 $descHelp = $helpManager->HelpIcon(__("A short description of this Group."), true);
1017
1018@@ -199,7 +198,7 @@
1019 END;
1020
1021 $response->SetFormRequestResponse($form, __('Add Display Group'), '350px', '275px');
1022- $response->AddButton(__('Help'), "XiboHelpRender('index.php?p=help&q=Display&Topic=Displays&Category=Groups')");
1023+ $response->AddButton(__('Help'), "XiboHelpRender('index.php?p=help&q=Display&Topic=DisplayGroup&Category=Add')");
1024 $response->AddButton($msgCancel, 'XiboDialogClose()');
1025 $response->AddButton($msgSave, '$("#DisplayGroupAddForm").submit()');
1026 $response->Respond();
1027@@ -240,7 +239,6 @@
1028 $description = Kit::ValidateParam($row['Description'], _STRING);
1029
1030 // Help UI
1031- $helpButton = $helpManager->HelpButton("displays/groups", true);
1032 $nameHelp = $helpManager->HelpIcon(__("The Name of this Group."), true);
1033 $descHelp = $helpManager->HelpIcon(__("A short description of this Group."), true);
1034
1035@@ -266,7 +264,7 @@
1036 END;
1037
1038 $response->SetFormRequestResponse($form, __('Edit Display Group'), '350px', '275px');
1039- $response->AddButton(__('Help'), "XiboHelpRender('index.php?p=help&q=Display&Topic=Displays&Category=Groups')");
1040+ $response->AddButton(__('Help'), "XiboHelpRender('index.php?p=help&q=Display&Topic=DisplayGroup&Category=Edit')");
1041 $response->AddButton($msgCancel, 'XiboDialogClose()');
1042 $response->AddButton($msgSave, '$("#DisplayGroupEditForm").submit()');
1043 $response->Respond();
1044@@ -293,7 +291,7 @@
1045 END;
1046
1047 $response->SetFormRequestResponse($form, __('Delete Display Group'), '350px', '175px');
1048- $response->AddButton(__('Help'), "XiboHelpRender('index.php?p=help&q=Display&Topic=Displays&Category=Groups')");
1049+ $response->AddButton(__('Help'), "XiboHelpRender('index.php?p=help&q=Display&Topic=DisplayGroup&Category=Delete')");
1050 $response->AddButton(__('No'), 'XiboDialogClose()');
1051 $response->AddButton(__('Yes'), '$("#DisplayGroupDeleteForm").submit()');
1052 $response->Respond();
1053@@ -375,7 +373,7 @@
1054 $form = $helpText . '<div class="connectedlist"><h3>Members</h3>' . $listIn . '</div><div class="connectedlist"><h3>Non-members</h3>' . $listOut . '</div>';
1055
1056 $response->SetFormRequestResponse($form, __('Manage Membership'), '400', '375', 'ManageMembersCallBack');
1057- $response->AddButton(__('Help'), "XiboHelpRender('index.php?p=help&q=Display&Topic=Displays&Category=Groups')");
1058+ $response->AddButton(__('Help'), "XiboHelpRender('index.php?p=help&q=Display&Topic=DisplayGroup&Category=Members')");
1059 $response->AddButton(__('Cancel'), 'XiboDialogClose()');
1060 $response->AddButton(__('Save'), 'MembersSubmit()');
1061 $response->Respond();
1062@@ -458,7 +456,7 @@
1063 $form = $helpText . '<div class="connectedlist firstList"><h3>Members</h3>' . $listIn . '</div><div class="connectedlist"><h3>Non-members</h3>' . $listOut . '</div>';
1064
1065 $response->SetFormRequestResponse($form, __('Manage Group Security for' . ' ' . $displayGroup), '400', '375', 'GroupSecurityCallBack');
1066- $response->AddButton(__('Help'), "XiboHelpRender('index.php?p=help&q=Display&Topic=Displays&Category=Groups')");
1067+ $response->AddButton(__('Help'), "XiboHelpRender('index.php?p=help&q=Display&Topic=DisplayGroup&Category=GroupSecurity')");
1068 $response->AddButton(__('Cancel'), 'XiboDialogClose()');
1069 $response->AddButton(__('Save'), 'GroupSecuritySubmit()');
1070 $response->Respond();
1071
1072=== modified file 'server/lib/pages/index.class.php'
1073--- server/lib/pages/index.class.php 2011-08-06 15:36:50 +0000
1074+++ server/lib/pages/index.class.php 2012-01-22 15:55:27 +0000
1075@@ -106,7 +106,7 @@
1076
1077 if ($referingpage == '')
1078 {
1079- header('Location:index.php?p=dashboard');
1080+ header('Location:index.php?p=index');
1081 }
1082 else
1083 {
1084@@ -116,27 +116,27 @@
1085 exit;
1086 }
1087
1088- function logout($referingpage = "")
1089- {
1090- global $user;
1091- $db =& $this->db;
1092-
1093- $username = Kit::GetParam('username', _SESSION, _USERNAME);
1094-
1095- setMessage($username . __("Please Login to access this page."));
1096-
1097- //logs the user out -- true if ok
1098- $user->logout();
1099-
1100- if($referingpage=="")
1101- {
1102- $referingpage="index";
1103- }
1104-
1105- //then go back to the index page
1106- header("Location:index.php?p=".$referingpage);
1107- exit;
1108- }
1109+ function logout($referingpage = '')
1110+ {
1111+ global $user;
1112+ $db =& $this->db;
1113+
1114+ $username = Kit::GetParam('username', _SESSION, _USERNAME);
1115+
1116+ setMessage(__('Please Login to access this page.'));
1117+
1118+ //logs the user out -- true if ok
1119+ $user->logout();
1120+
1121+ if($referingpage == '')
1122+ {
1123+ $referingpage = 'index';
1124+ }
1125+
1126+ //then go back to the index page
1127+ header('Location:index.php?p=' . $referingpage);
1128+ exit;
1129+ }
1130
1131 function forgotten()
1132 {
1133@@ -226,19 +226,26 @@
1134 return substr($password, 0, $length);
1135 }
1136
1137- function displayPage()
1138- {
1139- $db =& $this->db;
1140- $user =& $this->user;
1141-
1142- include("lib/pages/dashboard.class.php");
1143-
1144- $schedule = new dashboardDAO($db, $user);
1145-
1146- $schedule->displayPage();
1147-
1148- exit;
1149- }
1150+ function displayPage()
1151+ {
1152+ $db =& $this->db;
1153+ $user =& $this->user;
1154+
1155+ $homepage = $this->user->homePage;
1156+
1157+ if ($homepage == 'mediamanager')
1158+ {
1159+ include('lib/pages/mediamanager.class.php');
1160+ $userHomepage = new mediamanagerDAO($db, $user);
1161+ }
1162+ else
1163+ {
1164+ include("lib/pages/dashboard.class.php");
1165+ $userHomepage = new dashboardDAO($db, $user);
1166+ }
1167+
1168+ $userHomepage->displayPage();
1169+ }
1170
1171 /**
1172 * Ping Pong
1173
1174=== modified file 'server/lib/pages/layout.class.php'
1175--- server/lib/pages/layout.class.php 2011-09-03 11:10:49 +0000
1176+++ server/lib/pages/layout.class.php 2012-01-22 15:55:27 +0000
1177@@ -1823,6 +1823,9 @@
1178
1179 $msgName = __('New Name');
1180 $msgName2 = __('The name for the new layout');
1181+ $msgCopyMedia = __('Make new copies of all media on this layout?');
1182+
1183+ $copyMediaChecked = (Config::GetSetting($db, 'LAYOUT_COPY_MEDIA_CHECKB') == 'Checked') ? 'checked' : '';
1184
1185 $form = <<<END
1186 <form id="LayoutCopyForm" class="XiboForm" method="post" action="index.php?p=layout&q=Copy">
1187@@ -1832,6 +1835,12 @@
1188 <td><label for="layout" accesskey="n" title="$msgName2">$msgName<span class="required">*</span></label></td>
1189 <td><input name="layout" class="required" type="text" id="layout" value="$oldLayout 2" tabindex="1" /></td>
1190 </tr>
1191+ <tr>
1192+ <td colspan="2">
1193+ <input type="checkbox" id="copyMediaFiles" name="copyMediaFiles" $copyMediaChecked />
1194+ <label for="copyMediaFiles" accesskey="c" title="$msgCopyMedia">$msgCopyMedia</label>
1195+ </td>
1196+ </tr>
1197 </table>
1198 </form>
1199 END;
1200@@ -1854,12 +1863,13 @@
1201
1202 $layoutid = Kit::GetParam('layoutid', _POST, _INT);
1203 $layout = Kit::GetParam('layout', _POST, _STRING);
1204+ $copyMedia = Kit::GetParam('copyMediaFiles', _POST, _CHECKBOX);
1205
1206 Kit::ClassLoader('Layout');
1207
1208 $layoutObject = new Layout($db);
1209
1210- if (!$layoutObject->Copy($layoutid, $layout, $user->userid))
1211+ if (!$layoutObject->Copy($layoutid, $layout, $user->userid, (bool)$copyMedia))
1212 trigger_error($layoutObject->GetErrorMessage(), E_USER_ERROR);
1213
1214 $response->SetFormSubmitResponse(__('Layout Copied'));
1215
1216=== modified file 'server/lib/pages/mediamanager.class.php'
1217--- server/lib/pages/mediamanager.class.php 2011-08-09 20:48:36 +0000
1218+++ server/lib/pages/mediamanager.class.php 2012-01-22 15:55:27 +0000
1219@@ -57,6 +57,16 @@
1220
1221 public function MediaManagerFilter()
1222 {
1223+ $msgLayout = __('Layout');
1224+ $msgRegion = __('Region');
1225+ $msgMedia = __('Media');
1226+ $msgMediaType = __('Type');
1227+
1228+ $modules = $this->db->GetArray("SELECT Module, Name FROM module WHERE Enabled = 1 ORDER BY 2", true);
1229+ $modules[] = array('Module' => 'all', 'Name' => 'All');
1230+
1231+ $mediaTypeList = Kit::SelectList('filterMediaType', $modules, 'Module', 'Name', 'all');
1232+
1233 $id = uniqid();
1234
1235 $xiboGrid = <<<HTML
1236@@ -65,6 +75,20 @@
1237 <form onsubmit="return false">
1238 <input type="hidden" name="p" value="mediamanager">
1239 <input type="hidden" name="q" value="MediaManagerGrid">
1240+ <table class="mediamanager_filterform">
1241+ <tr>
1242+ <td>$msgLayout</td>
1243+ <td><input type="text" name="filterLayout"></td>
1244+ <td>$msgMedia</td>
1245+ <td><input type="text" name="filterMediaName"></td>
1246+ </tr>
1247+ <tr>
1248+ <td>$msgRegion</td>
1249+ <td><input type="text" name="filterRegion"></td>
1250+ <td>$msgMediaType</td>
1251+ <td>$mediaTypeList</td>
1252+ </tr>
1253+ </table>
1254 </form>
1255 </div>
1256 <div class="XiboData">
1257@@ -80,10 +104,15 @@
1258 $db =& $this->db;
1259 $user =& $this->user;
1260 $response = new ResponseManager();
1261+
1262+ $filterLayout = Kit::GetParam('filterLayout', _POST, _STRING);
1263+ $filterRegion = Kit::GetParam('filterRegion', _POST, _STRING);
1264+ $filterMediaName = Kit::GetParam('filterMediaName', _POST, _STRING);
1265+ $filterMediaType = Kit::GetParam('filterMediaType', _POST, _STRING);
1266
1267 // We would like a list of all layouts, media and media assignments that this user
1268 // has access to.
1269- $layouts = $user->LayoutList();
1270+ $layouts = $user->LayoutList($filterLayout);
1271
1272 $msgLayout = __('Layout');
1273 $msgRegion = __('Region');
1274@@ -142,6 +171,9 @@
1275 $regionNodeSequence++;
1276 $regionName = ($region->getAttribute('name') == '') ? 'Region ' . $regionNodeSequence : $region->getAttribute('name');
1277
1278+ if ($filterRegion != '' && !stristr($regionName, $filterRegion))
1279+ continue;
1280+
1281 Debug::LogEntry($db, 'audit', 'Permissions granted for ' . $regionId . ' owned by ' . $ownerId, 'mediamanager', 'MediaManagerGrid');
1282
1283 // Media
1284@@ -167,6 +199,14 @@
1285 $tmpModule = new $mediaType($db, $user, $mediaId, $layout['layoutid'], $regionId, $lkId);
1286 $mediaName = $tmpModule->GetName();
1287
1288+ if ($filterMediaName != '' && !stristr($mediaName, $filterMediaName))
1289+ continue;
1290+
1291+ Debug::LogEntry($db, 'audit', $filterMediaType . ' ' . $mediaType);
1292+
1293+ if ($filterMediaType != 'all' && $mediaType != strtolower($filterMediaType))
1294+ continue;
1295+
1296 $editLink = '<button class="XiboFormButton" href="index.php?p=module&mod=' . $mediaType . '&q=Exec&method=EditForm&showRegionOptions=0&layoutid=' . $layout['layoutid'] . '&regionid=' . $regionId . '&mediaid=' . $mediaId . '&lkid=' . $lkId . '">' . $msgEdit . '</button>';
1297 $mediaNodeSequence++;
1298
1299
1300=== modified file 'server/lib/pages/region.class.php'
1301--- server/lib/pages/region.class.php 2011-08-18 23:34:53 +0000
1302+++ server/lib/pages/region.class.php 2012-01-22 15:55:27 +0000
1303@@ -593,18 +593,34 @@
1304 * @param <string> $mediaId
1305 * @return <string>
1306 */
1307- public function GetMediaNodeType($layoutId, $regionId, $mediaId)
1308+ public function GetMediaNodeType($layoutId, $regionId = '', $mediaId = '', $lkId = '')
1309 {
1310 $db =& $this->db;
1311
1312+ // Validate
1313+ if ($regionId == '' && $mediaId == '' && $lkId == '')
1314+ return false;
1315+
1316 //Load the XML for this layout
1317 $xml = new DOMDocument("1.0");
1318 $xml->loadXML($this->GetLayoutXml($layoutId));
1319
1320 //Find the region
1321 $xpath = new DOMXPath($xml);
1322- $mediaNodeList = $xpath->query('//region[@id="' . $regionId . '"]/media[@id="' . $mediaId . '"]');
1323- $mediaNode = $mediaNodeList->item(0);
1324+
1325+ if ($lkId == '')
1326+ {
1327+ Debug::LogEntry($db, 'audit', 'No link ID. Using mediaid and regionid', 'region', 'GetMediaNodeType');
1328+ $mediaNodeList = $xpath->query('//region[@id="' . $regionId . '"]/media[@id="' . $mediaId . '"]');
1329+ }
1330+ else
1331+ {
1332+ $mediaNodeList = $xpath->query('//media[@lkid=' . $lkId . ']');
1333+ }
1334+
1335+ // Only 1 node
1336+ if (!$mediaNode = $mediaNodeList->item(0))
1337+ return false;
1338
1339 return $mediaNode->getAttribute('type');
1340 }
1341
1342=== modified file 'server/lib/pages/stats.class.php'
1343--- server/lib/pages/stats.class.php 2011-06-05 16:19:20 +0000
1344+++ server/lib/pages/stats.class.php 2012-01-22 15:55:27 +0000
1345@@ -1,7 +1,7 @@
1346 <?php
1347 /*
1348 * Xibo - Digitial Signage - http://www.xibo.org.uk
1349- * Copyright (C) 2009 Daniel Garner
1350+ * Copyright (C) 2009-2012 Daniel Garner
1351 *
1352 * This file is part of Xibo.
1353 *
1354@@ -49,40 +49,251 @@
1355 echo 'Display Statistics';
1356 return true;
1357 }
1358-
1359- public function StatsForm()
1360- {
1361- $db =& $this->db;
1362- $user =& $this->user;
1363- $output = '';
1364-
1365- $fromdt = date("Y-m-d H:i:s", time() - 86400);
1366- $todt = date("Y-m-d H:i:s");
1367- $display_list = dropdownlist("SELECT 'All', 'All' UNION SELECT displayID, display FROM display WHERE licensed = 1 ORDER BY 2", "displayid");
1368-
1369- // We want to build a form which will sit on the page and allow a button press to generate a CSV file.
1370- $output .= '<script type="text/javascript">$(document).onload(function(){$(".date-pick").datepicker({dateFormat: "dd/mm/yy"})});</script>';
1371- $output .= '<form action="index.php?p=stats&q=OutputCSV" method="post">';
1372- $output .= ' <table>';
1373- $output .= ' <tr>';
1374- $output .= ' <td>From Date</td>';
1375- $output .= ' <td><input type="text" class="date-pick" name="fromdt" value="' . $fromdt . '"/></td>';
1376- $output .= ' <td>To Date</td>';
1377- $output .= ' <td><input type="text" class="date-pick" name="todt" value="' . $todt . '" /></td>';
1378- $output .= ' </tr>';
1379- $output .= ' <tr>';
1380- $output .= ' <td>Display</td>';
1381- $output .= ' <td>' . $display_list . '</td>';
1382- $output .= ' </tr>';
1383-
1384- $output .= ' <tr>';
1385- $output .= ' <td><input type="submit" value="Export" /></td>';
1386- $output .= ' </tr>';
1387- $output .= ' </table>';
1388- $output .= '</form>';
1389-
1390- echo $output;
1391- }
1392+
1393+ /**
1394+ * Shows the stats form
1395+ */
1396+ public function StatsForm()
1397+ {
1398+ $db =& $this->db;
1399+ $user =& $this->user;
1400+
1401+ $fromdt = date("Y-m-d", time() - 86400);
1402+ $todt = date("Y-m-d");
1403+ $display_list = dropdownlist("SELECT 'All', 'All' UNION SELECT displayID, display FROM display WHERE licensed = 1 ORDER BY 2", "displayid");
1404+
1405+ // List of Media this user has permission for
1406+ $media = $this->user->MediaList();
1407+ $media[] = array('mediaid' => 0, 'media' => 'All');
1408+ $mediaList = Kit::SelectList('mediaid', $media, 'mediaid', 'media', 0);
1409+
1410+ // We want to build a form which will sit on the page and allow a button press to generate a CSV file.
1411+ $output = '';
1412+ $output .= '<div id="StatsFilter">';
1413+ $output .= ' <form onsubmit="return false">';
1414+ $output .= ' <input type="hidden" name="p" value="stats">';
1415+ $output .= ' <input type="hidden" name="q" value="StatsGrid">';
1416+ $output .= ' <table>';
1417+ $output .= ' <tr>';
1418+ $output .= ' <td>From Date</td>';
1419+ $output .= ' <td><input type="text" class="date-pick" name="fromdt" value="' . $fromdt . '"/></td>';
1420+ $output .= ' <td>To Date</td>';
1421+ $output .= ' <td><input type="text" class="date-pick" name="todt" value="' . $todt . '" /></td>';
1422+ $output .= ' </tr>';
1423+ $output .= ' <tr>';
1424+ $output .= ' <td>' . __('Display') . '</td>';
1425+ $output .= ' <td>' . $display_list . '</td>';
1426+ $output .= ' <td>' . __('Media') . '</td>';
1427+ $output .= ' <td>' . $mediaList . '</td>';
1428+ $output .= ' </tr>';
1429+ $output .= ' </table>';
1430+ $output .= '</form>';
1431+ $output .= '</div>';
1432+
1433+ $id = uniqid();
1434+
1435+ $xiboGrid = <<<HTML
1436+ <div class="XiboGrid" id="$id">
1437+ <div class="XiboFilter">
1438+ $output
1439+ </div>
1440+ <div class="XiboData"></div>
1441+ </div>
1442+HTML;
1443+ echo $xiboGrid;
1444+ }
1445+
1446+ /**
1447+ * Shows the stats grid
1448+ */
1449+ public function StatsGrid()
1450+ {
1451+ $db =& $this->db;
1452+ $user =& $this->user;
1453+ $response = new ResponseManager();
1454+
1455+ $fromDt = Kit::GetParam('fromdt', _POST, _STRING);
1456+ $toDt = Kit::GetParam('todt', _POST, _STRING);
1457+ $displayId = Kit::GetParam('displayid', _POST, _INT);
1458+ $mediaId = Kit::GetParam('mediaid', _POST, _INT);
1459+
1460+ $output = '';
1461+
1462+ // Output CSV button
1463+ $output .= '<p>' . __('Export raw data to CSV') . '</p>';
1464+ $output .= '<form action="index.php" method="post">';
1465+ $output .= ' <input type="hidden" name="p" value="stats" />';
1466+ $output .= ' <input type="hidden" name="q" value="OutputCSV" />';
1467+ $output .= ' <input type="hidden" name="displayid" value="' . $displayId . '" />';
1468+ $output .= ' <input type="hidden" name="fromdt" value="' . $fromDt . '" />';
1469+ $output .= ' <input type="hidden" name="todt" value="' . $toDt . '" />';
1470+ $output .= ' <input type="submit" value="Export" />';
1471+ $output .= '</form>';
1472+
1473+ // 3 grids showing different stats.
1474+
1475+ // Layouts Ran
1476+ $SQL = 'SELECT display.Display, layout.Layout, COUNT(StatID) AS NumberPlays, SUM(TIME_TO_SEC(TIMEDIFF(end, start))) AS Duration, MIN(start) AS MinStart, MAX(end) AS MaxEnd ';
1477+ $SQL .= ' FROM stat ';
1478+ $SQL .= ' INNER JOIN layout ON layout.LayoutID = stat.LayoutID ';
1479+ $SQL .= ' INNER JOIN display ON stat.DisplayID = display.DisplayID ';
1480+ $SQL .= ' WHERE 1 = 1 ';
1481+ $SQL .= sprintf(" AND stat.end > '%s' ", $fromDt);
1482+ $SQL .= sprintf(" AND stat.start <= '%s' ", $toDt);
1483+
1484+ if ($displayId != 0)
1485+ $SQL .= sprintf(" AND stat.displayID = %d ", $displayId);
1486+
1487+ $SQL .= 'GROUP BY display.Display, layout.Layout ';
1488+ $SQL .= 'ORDER BY display.Display, layout.Layout';
1489+
1490+ $output .= '<p>' . __('Layouts ran') . '</p>';
1491+ $output .= '<table>';
1492+ $output .= '<thead>';
1493+ $output .= '<th>' . __('Display') . '</th>';
1494+ $output .= '<th>' . __('Layout') . '</th>';
1495+ $output .= '<th>' . __('Number of Plays') . '</th>';
1496+ $output .= '<th>' . __('Total Duration (s)') . '</th>';
1497+ $output .= '<th>' . __('Total Duration') . '</th>';
1498+ $output .= '<th>' . __('First Shown') . '</th>';
1499+ $output .= '<th>' . __('Last Shown') . '</th>';
1500+ $output .= '</thead>';
1501+ $output .= '<tbody>';
1502+
1503+ if (!$results = $this->db->query($SQL))
1504+ {
1505+ trigger_error($db->error());
1506+ trigger_error(__('Unable to get Layouts Ran'), E_USER_ERROR);
1507+ }
1508+
1509+ while ($row = $db->get_assoc_row($results))
1510+ {
1511+ $output .= '<tr>';
1512+ $output .= '<td>' . Kit::ValidateParam($row['Display'], _STRING) . '</td>';
1513+ $output .= '<td>' . Kit::ValidateParam($row['Layout'], _STRING) . '</td>';
1514+ $output .= '<td>' . Kit::ValidateParam($row['NumberPlays'], _INT) . '</td>';
1515+ $output .= '<td>' . Kit::ValidateParam($row['Duration'], _INT) . '</td>';
1516+ $output .= '<td>' . sec2hms(Kit::ValidateParam($row['Duration'], _INT)) . '</td>';
1517+ $output .= '<td>' . Kit::ValidateParam($row['MinStart'], _STRING) . '</td>';
1518+ $output .= '<td>' . Kit::ValidateParam($row['MaxEnd'], _STRING) . '</td>';
1519+ $output .= '</tr>';
1520+ }
1521+
1522+ $output .= '</tbody>';
1523+ $output .= '</table>';
1524+
1525+ // Media Ran
1526+ $SQL = 'SELECT display.Display, media.Name, COUNT(StatID) AS NumberPlays, SUM(TIME_TO_SEC(TIMEDIFF(end, start))) AS Duration, MIN(start) AS MinStart, MAX(end) AS MaxEnd ';
1527+ $SQL .= ' FROM stat ';
1528+ $SQL .= ' INNER JOIN display ON stat.DisplayID = display.DisplayID ';
1529+ $SQL .= ' INNER JOIN media ON media.MediaID = stat.MediaID ';
1530+ $SQL .= ' WHERE 1 = 1 ';
1531+ $SQL .= sprintf(" AND stat.end > '%s' ", $fromDt);
1532+ $SQL .= sprintf(" AND stat.start <= '%s' ", $toDt);
1533+
1534+ if ($mediaId != 0)
1535+ $SQL .= sprintf(" AND media.MediaID = %d ", $mediaId);
1536+
1537+ if ($displayId != 0)
1538+ $SQL .= sprintf(" AND stat.displayID = %d ", $displayId);
1539+
1540+ $SQL .= 'GROUP BY display.Display, media.Name ';
1541+ $SQL .= 'ORDER BY display.Display, media.Name';
1542+
1543+ $output .= '<p>' . __('Library Media ran') . '</p>';
1544+ $output .= '<table>';
1545+ $output .= '<thead>';
1546+ $output .= '<th>' . __('Display') . '</th>';
1547+ $output .= '<th>' . __('Media') . '</th>';
1548+ $output .= '<th>' . __('Number of Plays') . '</th>';
1549+ $output .= '<th>' . __('Total Duration (s)') . '</th>';
1550+ $output .= '<th>' . __('Total Duration') . '</th>';
1551+ $output .= '<th>' . __('First Shown') . '</th>';
1552+ $output .= '<th>' . __('Last Shown') . '</th>';
1553+ $output .= '</thead>';
1554+ $output .= '<tbody>';
1555+
1556+ if (!$results = $this->db->query($SQL))
1557+ {
1558+ trigger_error($db->error());
1559+ trigger_error(__('Unable to get Library Media Ran'), E_USER_ERROR);
1560+ }
1561+
1562+ while ($row = $db->get_assoc_row($results))
1563+ {
1564+ $output .= '<tr>';
1565+ $output .= '<td>' . Kit::ValidateParam($row['Display'], _STRING) . '</td>';
1566+ $output .= '<td>' . Kit::ValidateParam($row['Name'], _STRING) . '</td>';
1567+ $output .= '<td>' . Kit::ValidateParam($row['NumberPlays'], _INT) . '</td>';
1568+ $output .= '<td>' . Kit::ValidateParam($row['Duration'], _INT) . '</td>';
1569+ $output .= '<td>' . sec2hms(Kit::ValidateParam($row['Duration'], _INT)) . '</td>';
1570+ $output .= '<td>' . Kit::ValidateParam($row['MinStart'], _STRING) . '</td>';
1571+ $output .= '<td>' . Kit::ValidateParam($row['MaxEnd'], _STRING) . '</td>';
1572+ $output .= '</tr>';
1573+ }
1574+
1575+ $output .= '</tbody>';
1576+ $output .= '</table>';
1577+
1578+ // Media on Layouts Ran
1579+ $SQL = "SELECT display.Display, layout.Layout, IFNULL(media.Name, 'Text/Rss/Webpage') AS Name, COUNT(StatID) AS NumberPlays, SUM(TIME_TO_SEC(TIMEDIFF(end, start))) AS Duration, MIN(start) AS MinStart, MAX(end) AS MaxEnd ";
1580+ $SQL .= ' FROM stat ';
1581+ $SQL .= ' INNER JOIN display ON stat.DisplayID = display.DisplayID ';
1582+ $SQL .= ' INNER JOIN layout ON layout.LayoutID = stat.LayoutID ';
1583+ $SQL .= ' LEFT OUTER JOIN media ON media.MediaID = stat.MediaID ';
1584+ $SQL .= ' WHERE 1 = 1 ';
1585+ $SQL .= sprintf(" AND stat.end > '%s' ", $fromDt);
1586+ $SQL .= sprintf(" AND stat.start <= '%s' ", $toDt);
1587+
1588+ if ($mediaId != 0)
1589+ $SQL .= sprintf(" AND media.MediaID = %d ", $mediaId);
1590+
1591+ if ($displayId != 0)
1592+ $SQL .= sprintf(" AND stat.displayID = %d ", $displayId);
1593+
1594+ $SQL .= "GROUP BY display.Display, layout.Layout, IFNULL(media.Name, 'Text/Rss/Webpage') ";
1595+ $SQL .= "ORDER BY display.Display, layout.Layout, IFNULL(media.Name, 'Text/Rss/Webpage')";
1596+
1597+ $output .= '<p>' . __('Media on Layouts ran') . '</p>';
1598+ $output .= '<table>';
1599+ $output .= '<thead>';
1600+ $output .= '<th>' . __('Display') . '</th>';
1601+ $output .= '<th>' . __('Layout') . '</th>';
1602+ $output .= '<th>' . __('Media') . '</th>';
1603+ $output .= '<th>' . __('Number of Plays') . '</th>';
1604+ $output .= '<th>' . __('Total Duration (s)') . '</th>';
1605+ $output .= '<th>' . __('Total Duration') . '</th>';
1606+ $output .= '<th>' . __('First Shown') . '</th>';
1607+ $output .= '<th>' . __('Last Shown') . '</th>';
1608+ $output .= '</thead>';
1609+ $output .= '<tbody>';
1610+
1611+ if (!$results = $this->db->query($SQL))
1612+ {
1613+ trigger_error($db->error());
1614+ trigger_error(__('Unable to get Library Media Ran'), E_USER_ERROR);
1615+ }
1616+
1617+ while ($row = $db->get_assoc_row($results))
1618+ {
1619+ $output .= '<tr>';
1620+ $output .= '<td>' . Kit::ValidateParam($row['Display'], _STRING) . '</td>';
1621+ $output .= '<td>' . Kit::ValidateParam($row['Layout'], _STRING) . '</td>';
1622+ $output .= '<td>' . Kit::ValidateParam($row['Name'], _STRING) . '</td>';
1623+ $output .= '<td>' . Kit::ValidateParam($row['NumberPlays'], _INT) . '</td>';
1624+ $output .= '<td>' . Kit::ValidateParam($row['Duration'], _INT) . '</td>';
1625+ $output .= '<td>' . sec2hms(Kit::ValidateParam($row['Duration'], _INT)) . '</td>';
1626+ $output .= '<td>' . Kit::ValidateParam($row['MinStart'], _STRING) . '</td>';
1627+ $output .= '<td>' . Kit::ValidateParam($row['MaxEnd'], _STRING) . '</td>';
1628+ $output .= '</tr>';
1629+ }
1630+
1631+ $output .= '</tbody>';
1632+ $output .= '</table>';
1633+
1634+ $response->SetGridResponse($output);
1635+ $response->Respond();
1636+ }
1637
1638 /**
1639 * Outputs a CSV of stats
1640
1641=== modified file 'server/lib/pages/user.class.php'
1642--- server/lib/pages/user.class.php 2011-08-19 18:06:06 +0000
1643+++ server/lib/pages/user.class.php 2012-01-22 15:55:27 +0000
1644@@ -151,7 +151,7 @@
1645 $password = md5($password);
1646 $email = Kit::GetParam('email', _POST, _STRING);
1647 $usertypeid = Kit::GetParam('usertypeid', _POST, _INT, 0);
1648- $homepage = Kit::GetParam('homepage', _POST, _STRING);
1649+ $homepage = Kit::GetParam('homepage', _POST, _STRING, 'dashboard');
1650 $pass_change = isset($_POST['pass_change']);
1651
1652 // Validation
1653@@ -163,14 +163,8 @@
1654 {
1655 trigger_error("Please enter a Password.", E_USER_ERROR);
1656 }
1657- if ($email == "")
1658- {
1659- trigger_error("Please enter an Email Address.", E_USER_ERROR);
1660- }
1661-
1662- if ($homepage == "") $homepage = "dashboard";
1663-
1664- //Check for duplicate user name
1665+
1666+ // Check for duplicate user name
1667 $sqlcheck = " ";
1668 $sqlcheck .= "SELECT UserName FROM user WHERE UserName = '" . $username . "' AND userID <> $userID ";
1669
1670@@ -185,31 +179,21 @@
1671 trigger_error(__("Could Not Complete, Duplicate User Name Exists"), E_USER_ERROR);
1672 }
1673
1674- //Everything is ok - run the update
1675- $sql = "UPDATE user SET UserName = '$username'";
1676+ // Everything is ok - run the update
1677+ $sql = sprintf("UPDATE user SET UserName = '%s', HomePage = '%s', Email = '%s' ", $username, $homepage, $email);
1678+
1679 if ($pass_change)
1680- {
1681- $sql .= ", UserPassword = '$password'";
1682- }
1683-
1684- $sql .= ", email = '$email' ";
1685- if ($homepage == 'dashboard')
1686- {
1687- //acts as a reset
1688- $sql .= ", homepage='$homepage' ";
1689- }
1690-
1691- if ($usertypeid != "")
1692- {
1693- $sql .= ", usertypeid = " . $usertypeid;
1694- }
1695-
1696- $sql .= " WHERE UserID = ". $userID . "";
1697+ $sql .= sprintf(", UserPassword = '%s'", $password);
1698+
1699+ if ($usertypeid != 0)
1700+ $sql .= sprintf(", usertypeid = %d ", $usertypeid);
1701+
1702+ $sql .= sprintf(" WHERE UserID = %d ", $userID);
1703
1704 if (!$db->query($sql))
1705 {
1706 trigger_error($db->error());
1707- trigger_error("Error updating that user", E_USER_ERROR);
1708+ trigger_error(__('Error updating user'), E_USER_ERROR);
1709 }
1710
1711 // Update the group to follow suit
1712@@ -243,30 +227,76 @@
1713 $userid = Kit::GetParam('userid', _POST, _INT, 0);
1714 $groupID = $user->getGroupFromID($userid, true);
1715
1716+ // Can we delete this user? Dont even try if we cant. Check tables that have this userid or this groupid
1717+ if ($this->db->GetCountOfRows(sprintf('SELECT LayoutID FROM layout WHERE UserID = %d', $userid)) > 0)
1718+ trigger_error(__('Cannot delete this user, they have layouts'), E_USER_ERROR);
1719+
1720+ if ($this->db->GetCountOfRows(sprintf('SELECT MediaID FROM media WHERE UserID = %d', $userid)) > 0)
1721+ trigger_error(__('Cannot delete this user, they have media'), E_USER_ERROR);
1722+
1723+ if ($this->db->GetCountOfRows(sprintf('SELECT EventID FROM schedule WHERE UserID = %d', $userid)) > 0)
1724+ trigger_error(__('Cannot delete this user, they have scheduled layouts'), E_USER_ERROR);
1725+
1726+ if ($this->db->GetCountOfRows(sprintf('SELECT Schedule_DetailID FROM schedule_detail WHERE UserID = %d', $userid)) > 0)
1727+ trigger_error(__('Cannot delete this user, they have schedule detail records'), E_USER_ERROR);
1728+
1729+ if ($this->db->GetCountOfRows(sprintf('SELECT TemplateID FROM template WHERE UserID = %d', $userid)) > 0)
1730+ trigger_error(__('Cannot delete this user, they have templates'), E_USER_ERROR);
1731+
1732+ if ($this->db->GetCountOfRows(sprintf('SELECT osr_id FROM oauth_server_registry WHERE osr_usa_id_ref = %d', $userid)) > 0)
1733+ trigger_error(__('Cannot delete this user, they have applications'), E_USER_ERROR);
1734+
1735+ if ($this->db->GetCountOfRows(sprintf('SELECT GroupID FROM lkdatasetgroup WHERE GroupID = %d', $groupID)) > 0)
1736+ trigger_error(__('Cannot delete this user, they have permissions to data sets'), E_USER_ERROR);
1737+
1738+ if ($this->db->GetCountOfRows(sprintf('SELECT GroupID FROM lkgroupdg WHERE GroupID = %d', $groupID)) > 0)
1739+ trigger_error(__('Cannot delete this user, they have permissions to display groups'), E_USER_ERROR);
1740+
1741+ if ($this->db->GetCountOfRows(sprintf('SELECT GroupID FROM lklayoutgroup WHERE GroupID = %d', $groupID)) > 0)
1742+ trigger_error(__('Cannot delete this user, they have permissions to layouts'), E_USER_ERROR);
1743+
1744+ if ($this->db->GetCountOfRows(sprintf('SELECT GroupID FROM lklayoutmediagroup WHERE GroupID = %d', $groupID)) > 0)
1745+ trigger_error(__('Cannot delete this user, they have permissions to media on layouts'), E_USER_ERROR);
1746+
1747+ if ($this->db->GetCountOfRows(sprintf('SELECT GroupID FROM lklayoutregiongroup WHERE GroupID = %d', $groupID)) > 0)
1748+ trigger_error(__('Cannot delete this user, they have permissions to regions on layouts'), E_USER_ERROR);
1749+
1750+ if ($this->db->GetCountOfRows(sprintf('SELECT GroupID FROM lkmediagroup WHERE GroupID = %d', $groupID)) > 0)
1751+ trigger_error(__('Cannot delete this user, they have permissions to media'), E_USER_ERROR);
1752+
1753+ if ($this->db->GetCountOfRows(sprintf('SELECT GroupID FROM lkmenuitemgroup WHERE GroupID = %d', $groupID)) > 0)
1754+ trigger_error(__('Cannot delete this user, they have permissions to menu items'), E_USER_ERROR);
1755+
1756+ if ($this->db->GetCountOfRows(sprintf('SELECT GroupID FROM lkpagegroup WHERE GroupID = %d', $groupID)) > 0)
1757+ trigger_error(__('Cannot delete this user, they have permissions to pages'), E_USER_ERROR);
1758+
1759+ if ($this->db->GetCountOfRows(sprintf('SELECT GroupID FROM lktemplategroup WHERE GroupID = %d', $groupID)) > 0)
1760+ trigger_error(__('Cannot delete this user, they have permissions to templates'), E_USER_ERROR);
1761+
1762 // Firstly delete the group for this user
1763 $userGroupObject = new UserGroup($db);
1764-
1765- $userGroupObject->Unlink($groupID, $userid);
1766-
1767+
1768+ // Remove this user from all user groups (including their own)
1769+ $userGroupObject->UnlinkAllGroups($userid);
1770+
1771+ // Delete the user specific group
1772 if (!$userGroupObject->Delete($groupID))
1773- {
1774 trigger_error($userGroupObject->GetErrorMessage(), E_USER_ERROR);
1775- }
1776
1777 // Delete the user
1778 $sqldel = "DELETE FROM user";
1779- $sqldel .= " WHERE UserID = ". $userid . "";
1780+ $sqldel .= " WHERE UserID = %d";
1781
1782- if (!$db->query($sqldel))
1783+ if (!$db->query(sprintf($sqldel, $userid)))
1784 {
1785 trigger_error($db->error());
1786 trigger_error(__("This user has been active, you may only retire them."), E_USER_ERROR);
1787 }
1788
1789 // We should delete this users sessions record.
1790- $SQL = "DELETE FROM session WHERE userID = $userid ";
1791+ $SQL = "DELETE FROM session WHERE userID = %d ";
1792
1793- if (!$db->query($sqldel))
1794+ if (!$db->query(sprintf($SQL, $userid)))
1795 {
1796 trigger_error($db->error());
1797 trigger_error(__("If logged in, this user will be deleted once they log out."), E_USER_ERROR);
1798
1799=== modified file 'server/lib/service/xmdssoap.class.php'
1800--- server/lib/service/xmdssoap.class.php 2011-09-01 20:57:15 +0000
1801+++ server/lib/service/xmdssoap.class.php 2012-01-22 15:55:27 +0000
1802@@ -880,6 +880,8 @@
1803 $document = new DOMDocument("1.0");
1804 $document->loadXML($inventory);
1805
1806+ $macAddress = $document->documentElement->getAttribute('macAddress');
1807+
1808 // Assume we are complete (but we are getting some)
1809 $mediaInventoryComplete = 1;
1810
1811@@ -902,7 +904,7 @@
1812
1813 // Touch the display record
1814 $displayObject = new Display($db);
1815- $displayObject->Touch($hardwareKey, '', $mediaInventoryComplete, $inventory);
1816+ $displayObject->Touch($hardwareKey, '', $mediaInventoryComplete, $inventory, $macAddress);
1817
1818 return true;
1819 }
1820
1821=== modified file 'server/locale/dbtranslate.php'
1822--- server/locale/dbtranslate.php 2011-07-29 15:31:53 +0000
1823+++ server/locale/dbtranslate.php 2012-01-22 15:55:27 +0000
1824@@ -74,4 +74,6 @@
1825 echo __('SHOW_DISPLAY_AS_VNCLINK');
1826 echo __('SHOW_DISPLAY_AS_VNC_TGT');
1827 echo __('REGION_OPTIONS_COLOURING');
1828+echo __('LAYOUT_COPY_MEDIA_CHECKB');
1829+echo __('LIBRARY_MEDIA_UPDATEINALL_CHECKB');
1830 ?>
1831
1832=== modified file 'server/modules/module_db_mysql.php'
1833--- server/modules/module_db_mysql.php 2011-08-30 22:31:57 +0000
1834+++ server/modules/module_db_mysql.php 2012-01-22 15:55:27 +0000
1835@@ -164,6 +164,18 @@
1836 }
1837
1838 /**
1839+ * Gets a count of rows returned by the specified SQL
1840+ * @param <type> $SQL
1841+ */
1842+ public function GetCountOfRows($SQL)
1843+ {
1844+ if (!$result = $this->query($SQL))
1845+ return 0;
1846+
1847+ return $this->num_rows($result);
1848+ }
1849+
1850+ /**
1851 * Get an Array of Results
1852 * @param <type> $SQL
1853 * @return <type>
1854
1855=== modified file 'server/modules/module_user_general.php'
1856--- server/modules/module_user_general.php 2011-09-06 19:07:49 +0000
1857+++ server/modules/module_user_general.php 2012-01-22 15:55:27 +0000
1858@@ -1005,7 +1005,7 @@
1859 /**
1860 * Returns an array of layouts that this user has access to
1861 */
1862- public function LayoutList()
1863+ public function LayoutList($filterLayout = '')
1864 {
1865 $SQL = "";
1866 $SQL .= "SELECT layoutID, ";
1867@@ -1014,6 +1014,10 @@
1868 $SQL .= " tags, ";
1869 $SQL .= " userID, xml ";
1870 $SQL .= " FROM layout ";
1871+ $SQL .= " WHERE 1 = 1 ";
1872+
1873+ if ($filterLayout != '')
1874+ $SQL .= " AND layout LIKE '%" . $filterLayout . "%'";
1875
1876 //Debug::LogEntry($this->db, 'audit', sprintf('Retreiving list of layouts for %s with SQL: %s', $this->userName, $SQL));
1877
1878
1879=== modified file 'server/template/header.php'
1880--- server/template/header.php 2011-08-13 14:56:21 +0000
1881+++ server/template/header.php 2012-01-22 15:55:27 +0000
1882@@ -67,7 +67,7 @@
1883 {
1884 echo '<script type="text/javascript" src="lib/js/' . $p . '.js"></script>';
1885
1886- if ($p == 'layout' || $p == 'mediamanager')
1887+ if ($p == 'layout' || $p == 'mediamanager' || $p == 'index')
1888 {
1889 ?>
1890 <script type="text/javascript" src="lib/js/text-render.js"></script>

Subscribers

People subscribed via source and target branches

to status/vote changes: