Permalink
Browse files

Rewrite designs functionality in OO-style

  • Loading branch information...
1 parent 8c8e392 commit 184a6d39190c91476e82e50461a23ac775c2e8f1 @birtles birtles committed Mar 5, 2013
Showing with 215 additions and 87 deletions.
  1. +4 −9 editor/lib/php/editor-util.inc
  2. +201 −75 wall/lib/designs.inc
  3. +9 −2 wall/lib/walls.inc
  4. +1 −1 wall/tests/unit/TestMySummary.php
@@ -22,24 +22,19 @@ function getStylesheet() {
// Get design name
$design = null;
try {
- $design = getDesignForWallPath($wall);
+ $design = DesignGallery::getByWallPath($wall);
} catch (KeyedException $e) {
error_log(print_r($e, true));
}
- if (!$design || !isset($design['name']) || strlen($design['name']) == 0)
- return null;
-
- // Get stylesheet
- $stylesheet = getEditorStyleSheetForDesign($design['name']);
- if (!$stylesheet)
+ if (!$design || $design->editorStylesheet === null)
return null;
// Construct URL to stylesheet
+ // XXX Rename upload_server to wall_server
$server_path = $config['editor']['upload_server'];
// Make sure server path ends with a /
if (substr($server_path, -1) !== "/")
$server_path .= "/";
- // XXX Rename upload_server to wall_server
- return $server_path . $stylesheet;
+ return $server_path . $design->editorStylesheet;
}
?>
View
@@ -7,103 +7,229 @@
require_once("parapara.inc");
require_once("db.inc");
-// Get the design for a wall given a path
-// Currently returns an associative array with only the design name ('name')
-function getDesignForWallPath($path) {
- $conn =& getDbConnection();
- $res =& $conn->queryRow(
- 'SELECT name FROM designs'
- . ' INNER JOIN walls ON designs.designId = walls.designId'
- . ' WHERE walls.urlPath = ' . $conn->quote(rawurlencode($path), 'text')
- . ' LIMIT 1',
- null,
- MDB2_FETCHMODE_ASSOC);
-
- if (PEAR::isError($res)) {
- error_log($res->getMessage() . ', ' . $res->getDebugInfo());
- throw new KeyedException('db-error');
+class Design {
+ public $id = null;
+ public $name = null;
+ public $duration = null;
+ // virtual: svg
+ // virtual: thumbnail
+ // virtual: video
+ // virtual: editorStylesheet
+ private $virtualFields = array();
+ private $filePath = null;
+
+ public function __construct($id, $name, $duration) {
+ $this->id = intval($id);
+ $this->name = $name;
+ $this->duration = $duration;
+ $this->filePath = dirname(__FILE__) . '/../public/designs/' . $name . '/';
}
- return $res ? $res : null;
-}
-function getEditorStyleSheetForDesign($designName) {
- // Sanitize designName
- $designName = basename($designName);
+ public function __get($name) {
+ if (array_key_exists($name, $this->virtualFields)) {
+ return $this->virtualFields[$name];
+ }
- // Work out where the stylesheet *should* be
- $styleSheetPath = "designs/$designName/editor/editor.css";
- $baseDir = dirname(__FILE__) . '/../public/';
- $fsPath = $baseDir . $styleSheetPath;
+ $result = null;
+ switch ($name) {
+ case 'svg':
+ $result = $this->getSvg();
+ break;
+ case 'thumbnail':
+ $result = $this->getThumbnail();
+ break;
+ case 'video':
+ $result = $this->getVideos();
+ break;
+ case 'editorStylesheet':
+ $result = $this->getEditorStylesheet();
+ break;
+ default:
+ error_log('Unknown property: ' . $name);
+ return null;
+ }
- // Check if it exists
- return file_exists($fsPath) ? $styleSheetPath : null;
-}
+ $this->virtualFields[$name] = $result;
+ return $result;
+ }
-// Get the summary of all designs
-//
-// Returns
-// name - design name (not needed?)
-// (svg) - the SVG file, if any, used to represent this design
-// (thumbnail) - the thumbnail graphic, if any, used to represent this design
-// (video) - the video preview, if any, used to represent this design
-// duration - the default duration for this design
-function getDesignSummary() {
- $conn =& getDbConnection();
- $res =& $conn->query(
- 'SELECT name, duration FROM designs ORDER BY designId');
+ protected function getSvg() {
+ return file_exists($this->filePath . 'preview/' . $this->name . '.svg')
+ ? '/designs/' . $this->name . '/preview/' . $this->name . '.svg'
+ : null;
+ }
- if (PEAR::isError($res)) {
- error_log($res->getMessage() . ', ' . $res->getDebugInfo());
- throw new KeyedException('db-error');
+ protected function getThumbnail() {
+ $extensions = array('png', 'jpg', 'jpeg', 'gif');
+ foreach ($extensions as $extension) {
+ if (file_exists($this->filePath . 'preview/' . $this->name .
+ '.' . $extension)) {
+ return '/designs/' . $this->name . '/preview/' . $this->name
+ . '.' . $extension;
+ }
+ }
+ return null;
}
- $result = array();
- $conn->setFetchMode(MDB2_FETCHMODE_ASSOC);
- while ($row = $res->fetchRow()) {
- $design =
- array(
- 'name' => $row['name'],
- 'duration' => $row['duration']
- );
- $media = _getMedia($row['name']);
- $result[] = array_merge($design, $media);
+ protected function getVideos() {
+ $extensions = array('mp4', 'webm');
+ $videos = array();
+ foreach ($extensions as $extension) {
+ if (file_exists($this->filePath . 'preview/' . $this->name .
+ '.' . $extension)) {
+ $videos[] = '/designs/' . $this->name . '/preview/' . $this->name
+ . '.' . $extension;
+ }
+ }
+ return count($videos) ? $videos : null;
}
- return $result;
+ protected function getEditorStylesheet() {
+ return file_exists($this->filePath . 'editor/editor.css')
+ ? '/designs/' . $this->name . '/editor/editor.css'
+ : null;
+ }
+
+ // Return a form suitable for serializing over JSON
+ public function asArray() {
+ return array(
+ 'id' => $this->id,
+ 'name' => $this->name,
+ 'duration' => $this->duration,
+ 'svg' => $this->svg,
+ 'thumbnail' => $this->thumbnail,
+ 'video' => $this->video,
+ 'editorStylesheet' => $this->editorStylesheet
+ );
+ }
}
-function _getMedia($name) {
- $result = array();
+class DesignGallery {
+ private static $designs = array();
+ private static $allLoaded = false;
+
+ public static function getById($id) {
+ // Sanitize input
+ $id = intval($id);
+
+ // Check if we already have the result cached
+ if (array_key_exists($id, self::$designs))
+ return self::$designs[$id];
+
+ // If we've loaded all designs and it's still not found then it mustn't
+ // exist
+ if (self::$allLoaded)
+ return null;
+
+ // Otherwise load it
+ $conn =& getDbConnection();
+ $row =& $conn->queryRow(
+ 'SELECT designId, name, duration FROM designs WHERE designId = '
+ . $conn->quote($id, 'integer')
+ . ' LIMIT 1',
+ null,
+ MDB2_FETCHMODE_ASSOC
+ );
+ if (PEAR::isError($row)) {
+ error_log($row->getMessage() . ', ' . $row->getDebugInfo());
+ throw new KeyedException('db-error');
+ }
- // If we ever allow users to enter designs into the database then we'll need
- // to sanitize name here
- $mediaPath = dirname(__FILE__) . '/../public/designs/';
+ // Check if it was found
+ if ($row === null)
+ return null;
- // Check for SVG file
- if (file_exists("$mediaPath$name/preview/$name.svg")) {
- $result['svg'] = "/designs/$name/preview/$name.svg";
+ // Otherwise store and return
+ self::$designs[$id] = new Design($id, $row['name'], $row['duration']);
+ return self::$designs[$id];
}
- // Check for thumbnail
- $extensions = array('png', 'jpg', 'jpeg', 'gif');
- foreach ($extensions as $extension) {
- if (file_exists("$mediaPath$name/preview/$name.$extension")) {
- $result['thumbnail'] = "/designs/$name/preview/$name.$extension";
- break;
+ public static function getByWallPath($path) {
+ // Look up path in database
+ $conn =& getDbConnection();
+ $row =& $conn->queryRow(
+ 'SELECT designs.designId, designs.name, designs.duration FROM designs'
+ . ' INNER JOIN walls ON designs.designId = walls.designId'
+ . ' WHERE walls.urlPath = ' . $conn->quote(rawurlencode($path), 'text')
+ . ' LIMIT 1',
+ null,
+ MDB2_FETCHMODE_ASSOC);
+ if (PEAR::isError($row)) {
+ error_log($row->getMessage() . ', ' . $row->getDebugInfo());
+ throw new KeyedException('db-error');
}
+
+ // Check if it was found
+ if ($row === null)
+ return null;
+
+ // Check if we already have it cached
+ $id = intval($row['designid']);
+ if (array_key_exists($id, self::$designs))
+ return self::$designs[$id];
+
+ // Otherwise store and return
+ self::$designs[$id] = new Design($id, $row['name'], $row['duration']);
+ return self::$designs[$id];
}
- // Check for videos
- $extensions = array('mp4', 'webm');
- $videos = array();
- foreach ($extensions as $extension) {
- if (file_exists("$mediaPath$name/preview/$name.$extension")) {
- $videos[] = "/designs/$name/preview/$name.$extension";
+ public static function getAll() {
+ // Return cached result if we already have it
+ if (self::$allLoaded)
+ return self::$designs;
+
+ // Query all designs
+ $conn =& getDbConnection();
+ $res =& $conn->query(
+ 'SELECT designId, name, duration FROM designs ORDER BY designId');
+ if (PEAR::isError($res)) {
+ error_log($res->getMessage() . ', ' . $res->getDebugInfo());
+ throw new KeyedException('db-error');
+ }
+
+ // Create Design objects
+ $result = array();
+ $conn->setFetchMode(MDB2_FETCHMODE_ASSOC);
+ while ($row = $res->fetchRow()) {
+ $result[intval($row['designid'])] =
+ new Design($row['designid'], $row['name'], $row['duration']);
}
+
+ // Cache result
+ self::$designs = $result;
+ self::$allLoaded = true;
+
+ return array_values(self::$designs);
}
- if (count($videos))
- $result['video'] = $videos;
+}
+// Get the summary of all designs as an array suitable for JSON encoding
+//
+// The fields are as follows:
+//
+// name - design name (not needed?)
+// (svg) - the SVG file, if any, used to represent this design
+// (thumbnail) - the thumbnail graphic, if any, used to represent this design
+// (video) - the video preview, if any, used to represent this design
+// duration - the default duration for this design
+//
+function getDesignSummary() {
+ $result = array();
+ $designs = DesignGallery::getAll();
+ foreach ($designs as $design) {
+ // Convert to array
+ $designArray = $design->asArray();
+
+ // Filter out empty values
+ if ($designArray['svg'] === null)
+ unset($designArray['svg']);
+ if ($designArray['thumbnail'] === null)
+ unset($designArray['thumbnail']);
+ if ($designArray['video'] === null || count($designArray['video']) === 0)
+ unset($designArray['video']);
+
+ $result[] = $designArray;
+ }
return $result;
}
View
@@ -7,6 +7,7 @@ require_once("parapara.inc");
require_once("db.inc");
require_once("exceptions.inc");
require_once("UriUtils.inc");
+require_once("designs.inc");
// When updating this, be sure to update wall.js as well
define("WALLMAKER_SESSION_NAME", "WMSESSID");
@@ -30,7 +31,7 @@ function getWallSummaryForUser($email) {
// Run query
$res =& $conn->query(
- 'SELECT walls.wallId, walls.eventName, designs.name,'
+ 'SELECT walls.wallId, walls.eventName, designs.designId,'
. ' walls.galleryDisplay, walls.createDate, walls.modifyDate,'
. ' walls.designId'
. ' FROM users, walls'
@@ -49,11 +50,17 @@ function getWallSummaryForUser($email) {
$result = array();
$conn->setFetchMode(MDB2_FETCHMODE_ASSOC);
while ($row = $res->fetchRow()) {
+ // Get design
+ $design = DesignGallery::getById(intval($row['designid']));
+ $thumbnail = $design && $design->thumbnail
+ ? $design->thumbnail
+ : null;
+
$result[] =
array(
'wallId' => intval($row['wallid']),
'eventName' => $row['eventname'],
- 'thumbnail' => 'XXX',
+ 'thumbnail' => $thumbnail,
'galleryDisplay' => !!($row['gallerydisplay']),
'createDate' => $row['createdate'],
'modifyDate' => $row['modifydate']
@@ -61,7 +61,7 @@ function testWalls() {
"Unexpected wall id: " . $wall['wallId']);
$this->assertTrue($wall['eventName'] === "Test wall",
"Unexpected event name: " . $wall['eventName']);
- $this->assertTrue($wall['thumbnail'] === "designs/test/preview/test.jpg",
+ $this->assertTrue($wall['thumbnail'] === "/designs/test/preview/test.jpg",
"Unexpected thumbnail: " . $wall['thumbnail']);
$this->assertTrue($wall['galleryDisplay'] === true,
"Unexpected gallery display: " . $wall['galleryDisplay']);

0 comments on commit 184a6d3

Please sign in to comment.