summaryrefslogtreecommitdiffstats
path: root/modules-available/roomplanner/inc/pvsgenerator.inc.php
diff options
context:
space:
mode:
Diffstat (limited to 'modules-available/roomplanner/inc/pvsgenerator.inc.php')
-rw-r--r--modules-available/roomplanner/inc/pvsgenerator.inc.php206
1 files changed, 35 insertions, 171 deletions
diff --git a/modules-available/roomplanner/inc/pvsgenerator.inc.php b/modules-available/roomplanner/inc/pvsgenerator.inc.php
index cfb38fd2..3646ae6a 100644
--- a/modules-available/roomplanner/inc/pvsgenerator.inc.php
+++ b/modules-available/roomplanner/inc/pvsgenerator.inc.php
@@ -1,77 +1,31 @@
<?php
-define('X', 0);
-define('Y', 1);
-
class PvsGenerator
{
public static function generate()
{
- /* get all rooms */
- $rooms = array();
- // Use left joins everywhere so we still have the complete list of locations below
- // for figuring out which locations are leafs and which aren't
- $ret = Database::simpleQuery(
- 'SELECT l.locationid, l.parentlocationid, l.locationname, lr.locationid AS notnull, lr.managerip, lr.tutoruuid, m.clientip as tutorip '
- . 'FROM location l '
- . 'LEFT JOIN location_roomplan lr ON (l.locationid = lr.locationid)'
- . 'LEFT JOIN machine m ON (lr.tutoruuid = m.machineuuid)');
- while ($row = $ret->fetch(PDO::FETCH_ASSOC)) {
- $row['locationname'] = str_replace(',', ';', $row['locationname']); // comma probably not the best sep here
- settype($row['locationid'], 'int');
- settype($row['parentlocationid'], 'int');
- $rooms[$row['locationid']] = $row;
- }
- // Mark all non-leafs as skip
- foreach ($rooms as &$room) {
- if ($room['parentlocationid'] > 0 && isset($rooms[$room['parentlocationid']])) {
- $rooms[$room['parentlocationid']]['skip'] = true; // Don't just unset, might be wrong order
- }
- }
- // Now un-mark all where there's at least one child without valid room plan
- foreach ($rooms as &$room) {
- if (!isset($room['skip']) && (is_null($room['notnull']) || empty($room['managerip']))) {
- $room['skip'] = true;
- $r2 =& $room;
- while ($r2['parentlocationid'] > 0) {
- $r2 =& $rooms[$r2['parentlocationid']];
- if (!(is_null($room['notnull']) || empty($room['managerip']))) {
- unset($r2['skip']);
- break;
- }
- }
- }
- }
- unset($room, $r2); // refd!
-
/* collect names and build room blocks - filter empty rooms while at it */
$roomNames = array();
$roomBlocks = '';
+ $rooms = Room::getAll();
foreach ($rooms as $room) {
- if (is_null($room['notnull']) || isset($room['skip'])) // Not leaf
+ if ($room->shouldSkip())
continue;
- if (Module::isAvailable('runmode')) {
- $pc = RunMode::getForMode('roomplanner', $room['locationid'], true);
- if (!empty($pc)) {
- $pc = array_pop($pc);
- $room['managerip'] = $pc['clientip'];
- }
- }
- if (empty($room['managerip'])) // rooms without managerips don't make sense
+ if ($room->getManagerIp() === false) // No .ini entry for rooms without manager (do we want this?)
continue;
$roomBlock = PvsGenerator::generateRoomBlock($room);
if ($roomBlock === false)
continue; // Room nonexistent or empty
- $roomNames[] = md5($room['locationname']);
- $roomBlocks .= $roomBlock;
+ $section = substr(md5($room->locationId() . '-' . $room->locationName()), 0, 10);
+ $roomNames[] = $section;
+ $roomBlocks .= "[$section]\n" . $roomBlock;
}
/* output room plus [General]-block */
return "[General]\n"
. 'rooms=' . implode(', ', $roomNames) . "\n"
. "allowClientQuit=False\n" // TODO: configurable
- . "showLockDesktopButton=True\n" // TODO: Make this configurable (or not)
. "\n\n"
. $roomBlocks;
}
@@ -79,69 +33,36 @@ class PvsGenerator
/**
* Generate .ini section for specific room.
*
- * @param $room array room/location data as fetched from db
- * @return string|bool .ini section for room, or false if room is empty
+ * @param Room $room room/location data as fetched from db
+ * @return string|false .ini section for room, or false if room is empty
*/
private static function generateRoomBlock($room)
{
- $out = '[' . md5($room['locationname']) . "]\n";
-
-
- /* find all clients in that room */
- $machines = PvsGenerator::getMachines($room['locationid']);
- if (empty($machines))
+ $room->getSize($sizeX, $sizeY);
+ if ($sizeX === 0 || $sizeY === 0)
+ return false;
+ $count = 0;
+ $section = $room->getIniClientSection($count);
+ if ($section === false)
return false;
- $out .= "name=" . $room['locationname'] . "\n";
+ $cs = SimpleRoom::CLIENT_SIZE;
+ $out = "name=" . $room->locationName() . "\n";
/* manager */
- $mgr = $room['managerip'];
- $tutor = $room['tutorip'];
- if ($mgr) {
- $out .= 'mgrIP=' . $mgr . "\n";
- }
+ $out .= 'mgrIP=' . $room->getManagerIp() . "\n";
/* tutor */
- if ($tutor) {
- $out .= 'tutorIP=' . $tutor . "\n";
+ if ($room->getTutorIp() !== false) {
+ $out .= 'tutorIP=' . $room->getTutorIp() . "\n";
}
- /* grid */
- $out .= PvsGenerator::generateGrid($machines);
-
- return $out . "\n";
- }
-
- /**
- * Generate grid size information and client position data for given clients.
- *
- * @param $machines array list of clients
- * @return string grid and position data as required for a room's .ini section
- */
- private static function generateGrid($machines)
- {
- $out = "";
-
- /* find bounding box */
- PvsGenerator::boundingBox($machines, $minX, $minY, $maxX, $maxY);
- $clientSizeX = 4; /* TODO: optimize */
- $clientSizeY = 4; /* TODO: optimize */
- $sizeX = max($maxX - $minX + $clientSizeX, 1); /* never negative */
- $sizeY = max($maxY - $minY + $clientSizeY, 1); /* and != 0 to avoid divide-by-zero in pvsmgr */
-
- /* output basic settings for this room */
+ /* basic settings for this room */
$out .= "gridSize=@Size($sizeX $sizeY)\n";
- $out .= "clientSize=@Size($clientSizeX $clientSizeY)\n";
- $out .= "client\\size=" . count($machines) . "\n";
-
- /* output individual client positions, shift coordinates to origin */
- $i = 1;
- foreach ($machines as $pos) {
- $out .= "client\\$i\\ip={$pos['clientip']}\n";
- $out .= "client\\$i\\pos=@Point(" . ($pos['gridCol'] - $minX) . ' ' . ($pos['gridRow'] - $minY) . ")\n";
- $i++;
- }
+ $out .= "clientSize=@Size($cs $cs)\n";
+ $out .= "client\\size=$count\n";
- return $out;
+ /* output with grid */
+ return $out . $section . "\n";
}
/**
@@ -154,6 +75,7 @@ class PvsGenerator
* @param int|false $locationId
* @param string|false $highlightUuid
* @param int $rotate rotate plan (0-3 for N E S W up, -1 for "auto" if highlightUuid is given)
+ * @param float $scale scaling factor for output
* @return string SVG
*/
public static function generateSvg($locationId = false, $highlightUuid = false, $rotate = 0, $scale = 1)
@@ -167,10 +89,15 @@ class PvsGenerator
return false;
$locationId = $locationId['fixedlocationid'];
}
- $machines = self::getMachines($locationId);
- if (empty($machines))
+ // Load room
+ $room = Room::get($locationId);
+ if ($room === false)
return false;
+ $room->getSize($sizeX, $sizeY);
+ if ($sizeX === 0 || $sizeY === 0)
+ return false; // Empty
+ $machines = $room->getShiftedArray();
$ORIENTATION = ['north' => 2, 'east' => 3, 'south' => 0, 'west' => 1];
if (is_string($highlightUuid)) {
$highlightUuid = strtoupper($highlightUuid);
@@ -186,22 +113,13 @@ class PvsGenerator
}
}
$rotate %= 4;
- // Highlight given machine, rotate it's "keyboard"
+ // Highlight given machine, rotate its "keyboard"
foreach ($machines as &$machine) {
if ($machine['machineuuid'] === $highlightUuid) {
$machine['class'] = 'hl';
}
$machine['rotation'] = $ORIENTATION[$machine['rotation']] * 90;
}
- PvsGenerator::boundingBox($machines, $minX, $minY, $maxX, $maxY);
- $clientSizeX = 4; /* this is optimal */
- $clientSizeY = 4;
- $minX--;
- $minY--;
- $maxX++;
- $maxY++;
- $sizeX = max($maxX - $minX + $clientSizeX, 1); /* never negative */
- $sizeY = max($maxY - $minY + $clientSizeY, 1); /* and != 0 to avoid divide-by-zero in pvsmgr */
if ($rotate === 0) {
$centerY = $centerX = 0;
} elseif ($rotate === 1) {
@@ -221,11 +139,8 @@ class PvsGenerator
'centerX' => $centerX,
'centerY' => $centerY,
'rotate' => $rotate * 90,
- 'shiftX' => -$minX,
- 'shiftY' => -$minY,
'machines' => $machines,
- 'line' => ['x1' => $minX, 'y1' => $maxY + $clientSizeY,
- 'x2' => $maxX + $clientSizeX, 'y2' => $maxY + $clientSizeY],
+ 'line' => ['x' => $sizeX, 'y' => $sizeY],
], 'roomplanner'); // FIXME: Needs module param if called from api.inc.php
}
@@ -236,58 +151,6 @@ class PvsGenerator
$b = $tmp;
}
- /**
- * Get all clients for given room with IP and position.
- *
- * @param $roomid int locationid of room
- * @return array
- */
- private static function getMachines($roomid)
- {
- $ret = Database::simpleQuery(
- 'SELECT machineuuid, clientip, position FROM machine WHERE fixedlocationid = :locationid',
- ['locationid' => $roomid]);
-
- $machines = array();
-
- while ($row = $ret->fetch(PDO::FETCH_ASSOC)) {
- $position = json_decode($row['position'], true);
-
- if ($position === false || !isset($position['gridRow']) || !isset($position['gridCol']))
- continue; // TODO: Remove entry/set to NULL?
-
- $rotation = 'north';
- if (preg_match('/(north|east|south|west)/', $position['itemlook'], $out)) {
- $rotation = $out[1];
- }
- $machines[] = array(
- 'machineuuid' => $row['machineuuid'],
- 'clientip' => $row['clientip'],
- 'gridRow' => $position['gridRow'],
- 'gridCol' => $position['gridCol'],
- 'rotation' => $rotation,
- );
- }
-
- return $machines;
-
- }
-
- private static function boundingBox($machines, &$minX, &$minY, &$maxX, &$maxY)
- {
- $minX = PHP_INT_MAX; /* PHP_INT_MIN is only available since PHP 7 */
- $maxX = ~PHP_INT_MAX;
- $minY = PHP_INT_MAX;
- $maxY = ~PHP_INT_MAX;
-
- foreach ($machines as $pos) {
- $minX = min($minX, $pos['gridCol']);
- $maxX = max($maxX, $pos['gridCol']);
- $minY = min($minY, $pos['gridRow']);
- $maxY = max($maxY, $pos['gridRow']);
- }
- }
-
public static function runmodeConfigHook($machineUuid, $locationId, $data)
{
if (!empty($data)) {
@@ -308,6 +171,7 @@ class PvsGenerator
/**
* Get display name for manager of given locationId.
+ * Hook for "runmode" module to resolve mode name.
* @param $locationId
* @return bool|string
*/