summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2022-05-03 17:36:29 +0200
committerSimon Rettberg2022-05-03 17:36:29 +0200
commitb155c8167ddd5562f30fcfadd9eeb60d80e2619e (patch)
treecfbb0fda2f4aeadc24a0cbb010f975e3c10ee779
parent[eventlog] Add de translations (diff)
downloadslx-admin-b155c8167ddd5562f30fcfadd9eeb60d80e2619e.tar.gz
slx-admin-b155c8167ddd5562f30fcfadd9eeb60d80e2619e.tar.xz
slx-admin-b155c8167ddd5562f30fcfadd9eeb60d80e2619e.zip
[locations/news] Add per-location news/help/loginscreentext
-rw-r--r--modules-available/locations/pages/details.inc.php1
-rw-r--r--modules-available/locations/templates/location-subnets.html6
-rw-r--r--modules-available/news/api.inc.php61
-rw-r--r--modules-available/news/install.inc.php25
-rw-r--r--modules-available/news/page.inc.php39
-rw-r--r--modules-available/news/permissions/permissions.json12
-rw-r--r--modules-available/news/templates/page-news.html6
7 files changed, 109 insertions, 41 deletions
diff --git a/modules-available/locations/pages/details.inc.php b/modules-available/locations/pages/details.inc.php
index d2ec7b24..77f96221 100644
--- a/modules-available/locations/pages/details.inc.php
+++ b/modules-available/locations/pages/details.inc.php
@@ -342,6 +342,7 @@ class SubPage
'locationname' => $loc['locationname'],
'list' => $rows,
'roomplanner' => Module::get('roomplanner') !== false,
+ 'news' => Module::get('news') !== false && User::hasPermission('.news.*', $loc['locationid']),
'parents' => Location::getLocations($loc['parentlocationid'], $locationId, true)
);
diff --git a/modules-available/locations/templates/location-subnets.html b/modules-available/locations/templates/location-subnets.html
index 85c5a744..976c3cc7 100644
--- a/modules-available/locations/templates/location-subnets.html
+++ b/modules-available/locations/templates/location-subnets.html
@@ -91,6 +91,12 @@
<span class="glyphicon glyphicon-time"></span>
{{lang_openingTime}}
</button>
+ {{#news}}
+ <a class="btn btn-default" href="?do=news&amp;locationid={{locationid}}">
+ <span class="glyphicon glyphicon-pencil"></span>
+ {{lang_editNews}}
+ </a>
+ {{/news}}
{{#roomplanner}}
<a class="btn btn-default" href="?do=roomplanner&amp;locationid={{locationid}}" target="_blank"
onclick="window.open(this.href, '_blank', 'toolbar=0,scrollbars,resizable');return false">
diff --git a/modules-available/news/api.inc.php b/modules-available/news/api.inc.php
index 851f31a8..e8ef11d1 100644
--- a/modules-available/news/api.inc.php
+++ b/modules-available/news/api.inc.php
@@ -4,23 +4,54 @@ header('Content-Type: application/xml; charset=utf-8');
$type = Request::any('type', 'news', 'string');
+$locationId = Request::any('location', 0, 'int');
+if ($locationId === 0) {
+ $locationId = Location::getFromIp($_SERVER['REMOTE_ADDR']);
+}
+$locations = Location::getLocationRootChain($locationId);
+$locations[] = 0;
+
// Fetch news from DB
-$row = Database::queryFirst('SELECT title, content, dateline FROM vmchooser_pages'
- . ' WHERE type = :type AND expires > UNIX_TIMESTAMP() ORDER BY dateline DESC LIMIT 1', compact('type'));
-if ($row !== false ) {
+$res = Database::simpleQuery('SELECT title, locationid, content, dateline FROM vmchooser_pages
+ WHERE type = :type AND (locationid IS NULL OR locationid IN (:lids))
+ AND expires > UNIX_TIMESTAMP() ORDER BY dateline DESC', [
+ 'type' => $type,
+ 'lids' => $locations,
+ ]);
- echo '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
- echo "<news>" . "\n";
- echo "\t" . '<headline>' . "\n";
- echo "\t\t" . htmlspecialchars($row['title']) . "\n";
- echo "\t" . '</headline>' . "\n";
- echo "\t" . "<info>" . "\n";
- echo "\t\t" . htmlspecialchars($row['content']) . "\n";
- echo "\t" . '</info>' . "\n";
- echo "\t" . "<date>" . "\n";
- echo "\t\t" . $row['dateline'] . "\n";
- echo "\t" . "</date>" . "\n";
- echo "</news>";
+// Get one for each location. As we sort by dateline and check expiry in the query, we only
+// need one per location and then pick the first one that is set, as the locations are ordered
+// by closest to furthest
+$locations = array_flip($locations);
+foreach ($res as $row) {
+ $lid = $row['locationid'];
+ if (is_array($locations[$lid]))
+ continue; // Already have one
+ $locations[$lid] = $row;
+}
+// Pick first one
+foreach ($locations as $row) {
+ if (is_array($row))
+ break;
+}
+
+if (is_array($row)) {
+ $title = htmlspecialchars($row['title']);
+ $content = htmlspecialchars($row['content']);
+ echo <<<EOF
+<?xml version="1.0" encoding="UTF-8"?>
+<news>
+ <headline>
+ $title
+ </headline>
+ <info>
+ $content
+ </info>
+ <date>
+ {$row['dateline']}
+ </date>
+</news>
+EOF;
} else {
// no news in DB, output a 'null' news xml
diff --git a/modules-available/news/install.inc.php b/modules-available/news/install.inc.php
index 88a20749..89fc7069 100644
--- a/modules-available/news/install.inc.php
+++ b/modules-available/news/install.inc.php
@@ -1,6 +1,6 @@
<?php
-$res = array();
+$dbret = array();
@@ -10,7 +10,7 @@ if (tableExists('news')) {
if (!tableRename('news', 'vmchooser_pages')) {
finalResponse(UPDATE_FAILED, "Could not rename news to vmchooser_pages: " . Database::lastError());
}
- $res[] = UPDATE_DONE;
+ $dbret[] = UPDATE_DONE;
if (false === Database::exec("ALTER TABLE `vmchooser_pages` ADD COLUMN type VARCHAR(10)")) {
EventLog::warning("Could not add type column to vmchooser_pages: " . Database::lastError());
}
@@ -20,16 +20,16 @@ if (tableExists('news')) {
}
-$res[] = tableCreate('vmchooser_pages', "
+$dbret[] = tableCreate('vmchooser_pages', "
`newsid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`dateline` int(10) unsigned NOT NULL,
`expires` int(10) unsigned NOT NULL,
+ `locationid` int(11) NULL,
`title` varchar(200) DEFAULT NULL,
- `content` text,
- `type` varchar(10),
+ `content` text NOT NULL,
+ `type` varchar(10) CHARACTER SET ascii NOT NULL,
PRIMARY KEY (`newsid`),
- KEY `type` (`type`, `dateline`),
- KEY `all3` (`type`, `expires`, `dateline`)
+ KEY `type` (`type`, `dateline`)
");
if (tableGetIndex('vmchooser_pages', ['dateline']) !== false) {
@@ -44,9 +44,18 @@ if (!tableHasColumn('vmchooser_pages', 'expires')) {
Database::exec('UPDATE vmchooser_pages SET expires = dateline + 86400 * 3650 WHERE expires = 0'); // ~10 Years
}
+if (!tableHasColumn('vmchooser_pages', 'locationid')) {
+ Database::exec('ALTER TABLE vmchooser_pages ADD COLUMN `locationid` int(11) NULL AFTER `expires`');
+}
+
+$dbret[] = Database::exec('ALTER TABLE vmchooser_pages MODIFY `type` varchar(10) CHARACTER SET ascii NOT NULL');
+
+$dbret[] = tableAddConstraint('remoteaccess_x_location', 'locationid', 'location', 'locationid',
+ 'ON UPDATE CASCADE ON DELETE CASCADE');
+
// Create response for browser
-if (in_array(UPDATE_DONE, $res)) {
+if (in_array(UPDATE_DONE, $dbret)) {
finalResponse(UPDATE_DONE, 'Tables created successfully');
}
diff --git a/modules-available/news/page.inc.php b/modules-available/news/page.inc.php
index 21b99952..ceffd028 100644
--- a/modules-available/news/page.inc.php
+++ b/modules-available/news/page.inc.php
@@ -39,6 +39,10 @@ class Page_News extends Page
* @var int Unix epoch date when the news expires.
*/
private $newsExpires = false;
+ /**
+ * @var int location id
+ */
+ private $locationId = 0;
/**
@@ -65,28 +69,31 @@ class Page_News extends Page
/* and also the news (or help) with the given id */
$newsId = Request::get('newsid', false, 'int');
$pageType = Request::get('type', false, 'string');
+ $this->locationId = Request::get('locationid', 0, 'int');
if ($pageType === false && $newsId === false) {
- Util::redirect('?do=news&type=news');
+ Util::redirect('?do=news&type=news&locationid=' . $this->locationId);
}
$this->pageType = $pageType === false ? 'news' : $pageType;
$this->loadNews($newsId, $pageType);
foreach (self::TYPES as $type => $entry) {
- Dashboard::addSubmenu('?do=news&type=' . $type, Dictionary::translate('type_' . $type, true));
+ Dashboard::addSubmenu('?do=news&type=' . $type . '&locationid=' . $this->locationId,
+ Dictionary::translate('type_' . $type, true));
}
} else {
$action = Request::post('action', false, 'string');
$pageType = Request::post('type', false, 'string');
+ $this->locationId = Request::post('locationid', Request::REQUIRED_EMPTY, 'int');
if (!array_key_exists($pageType, self::TYPES)) {
Message::addError('invalid-type', $pageType);
- Util::redirect('?do=news');
+ Util::redirect('?do=news&locationid=' . $this->locationId);
}
if ($action === 'save') {
// save to DB
- User::assertPermission("$pageType.save");
+ User::assertPermission("$pageType.save", $this->locationId);
if (!$this->saveNews($pageType)) {
Message::addError('save-error');
} else {
@@ -95,14 +102,14 @@ class Page_News extends Page
} elseif ($action === 'delete') {
// delete it
- User::assertPermission("$pageType.delete");
+ User::assertPermission("$pageType.delete", $this->locationId);
$this->delNews(Request::post('newsid', false, 'int'), $pageType);
} else {
// unknown action, redirect user
Message::addError('invalid-action', $action);
}
- Util::redirect('?do=news&type=' . $pageType);
+ Util::redirect('?do=news&type=' . $pageType . '&locationid=' . $this->locationId);
}
/* load summernote module if available */
@@ -119,8 +126,9 @@ class Page_News extends Page
// fetch the list of the older news
$NOW = time();
$lines = array();
+ $str = $this->locationId === 0 ? 'IS NULL' : ' = ' . $this->locationId;
$res = Database::simpleQuery("SELECT newsid, dateline, expires, title, content FROM vmchooser_pages
- WHERE type = :type ORDER BY dateline DESC LIMIT 20", ['type' => $this->pageType]);
+ WHERE type = :type AND locationid $str ORDER BY dateline DESC LIMIT 20", ['type' => $this->pageType]);
$foundActive = false;
foreach ($res as $row) {
$row['dateline_s'] = Util::prettyTime($row['dateline']);
@@ -169,6 +177,10 @@ class Page_News extends Page
'disabled' => 'disabled',
];
}
+ $data['locationid'] = $this->locationId;
+ if ($this->locationId > 0) {
+ $data['location_name'] = Location::getName($this->locationId);
+ }
Render::addTemplate('page-news', $data);
}
@@ -199,8 +211,9 @@ class Page_News extends Page
Message::addError('news-empty');
}
} else {
+ $str = $this->locationId === 0 ? 'IS NULL' : ' = ' . $this->locationId;
$row = Database::queryFirst("SELECT newsid, title, content, dateline, expires, type FROM vmchooser_pages
- WHERE type = :type AND expires > UNIX_TIMESTAMP() ORDER BY dateline DESC LIMIT 1", [
+ WHERE type = :type AND locationid $str AND expires > UNIX_TIMESTAMP() ORDER BY dateline DESC LIMIT 1", [
'type' => $pageType,
]);
}
@@ -234,11 +247,12 @@ class Page_News extends Page
$expires = strtotime(Request::post('enddate', 'today', 'string') . ' '
. Request::post('endtime', '23:59', 'string'));
}
+ $str = $this->locationId === 0 ? 'IS NULL' : ' = ' . $this->locationId;
if (!empty($newsContent)) {
// we got title and content, save it to DB
// dup check first
- $row = Database::queryFirst('SELECT newsid FROM vmchooser_pages
- WHERE content = :content AND type = :type LIMIT 1', [
+ $row = Database::queryFirst("SELECT newsid FROM vmchooser_pages
+ WHERE content = :content AND type = :type AND locationid $str LIMIT 1", [
'content' => $newsContent,
'type' => $pageType,
]);
@@ -253,10 +267,11 @@ class Page_News extends Page
return true;
}
// new one
- Database::exec("INSERT INTO vmchooser_pages (dateline, expires, title, content, type)
- VALUES (:dateline, :expires, :title, :content, :type)", array(
+ Database::exec("INSERT INTO vmchooser_pages (dateline, expires, locationid, title, content, type)
+ VALUES (:dateline, :expires, :locationid, :title, :content, :type)", array(
'dateline' => time(),
'expires' => $expires,
+ 'locationid' => $this->locationId,
'title' => $newsTitle,
'content' => $newsContent,
'type' => $pageType,
diff --git a/modules-available/news/permissions/permissions.json b/modules-available/news/permissions/permissions.json
index 4ff1a01b..83fad86c 100644
--- a/modules-available/news/permissions/permissions.json
+++ b/modules-available/news/permissions/permissions.json
@@ -3,21 +3,21 @@
"location-aware": false
},
"help.delete": {
- "location-aware": false
+ "location-aware": true
},
"help.save": {
- "location-aware": false
+ "location-aware": true
},
"news.delete": {
- "location-aware": false
+ "location-aware": true
},
"news.save": {
- "location-aware": false
+ "location-aware": true
},
"login-news.delete": {
- "location-aware": false
+ "location-aware": true
},
"login-news.save": {
- "location-aware": false
+ "location-aware": true
}
} \ No newline at end of file
diff --git a/modules-available/news/templates/page-news.html b/modules-available/news/templates/page-news.html
index 1c944cb8..aa5785da 100644
--- a/modules-available/news/templates/page-news.html
+++ b/modules-available/news/templates/page-news.html
@@ -4,10 +4,16 @@
<h2>{{newsTypeName}}</h2>
+{{#locationid}}
+ <h3>{{location_name}}</h3>
+ <div class="alert alert-info">{{lang_editingForLocation}}</div>
+{{/locationid}}
+
<form action="?do=news" method="post">
<input type="hidden" name="token" value="{{token}}">
<input type="hidden" name="type" value="{{type}}">
<input type="hidden" name="action" value="save">
+ <input type="hidden" name="locationid" value="{{locationid}}">
{{#withTitle}}
<div class="form-group">
<label for="news-title-id">{{lang_title}}</label>