Page MenuHomeCode

No OneTemporary

This file is larger than 256 KB, so syntax highlighting was skipped.
This document is not UTF8. It was detected as ISO-8859-1 (Latin 1) and converted to UTF8 for display.
diff --git a/api.php b/api.php
--- a/api.php
+++ b/api.php
@@ -1,319 +1,320 @@
<?php
/**
* API entry point
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* @package Zed
* @subpackage EntryPoints
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
* @todo Consider to output documentation on / and /ship queries
+ * @todo /app/getdata
*/
//API Preferences
define('URL', 'http://' . $_SERVER['HTTP_HOST'] . '/index.php');
//Pluton library
require_once('includes/core.php');
require_once('includes/config.php');
//API libs
require_once('includes/api/api_helpers.php');
require_once('includes/api/cerbere.php');
//Use our URL controller method if you want to mod_rewrite the API
$url = explode('/', substr($_SERVER['PATH_INFO'], 1));
switch ($module = $url[0]) {
/* -------------------------------------------------------------
Site API
/time
/location
/perso (disabled)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case '':
//Nothing to do
//TODO: offer documentation instead
die();
case 'time':
//Hypership time
api_output(get_hypership_time(), "time");
break;
case 'location':
//Checks creditentials
cerbere();
//Gets location info
require_once("includes/geo/location.php");
$location = new GeoLocation($url[1], $url[2]);
api_output($location, "location");
break;
//case 'perso':
// //Checks creditentials
// cerbere();
// //Gets perso info
// require_once("includes/objects/perso.php");
// $perso = new Perso($url[1]);
// api_output($perso, "perso");
// break;
/* -------------------------------------------------------------
Ship API
/authenticate
/appauthenticate
/appauthenticated
/move
/land
/flyout
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case 'ship':
//Ship API
//Gets ship from Ship API key (distinct of regular API keys)
require_once('includes/objects/ship.php');
$ship = Ship::from_api_key($_REQUEST['key']) or cerbere_die("Invalid ship API key");
switch ($command = $url[1]) {
case '':
//Nothing to do
//TODO: offer documentation instead
die();
case 'authenticate':
//TODO: web authenticate
break;
case 'appauthenticate':
//Allows desktop application to authenticate an user
$tmp_session_id = $url[2] or cerbere_die("/appauthenticate/ must be followed by any session identifier");
if ($_REQUEST['name']) {
//Perso will be offered auth invite at next login.
//Handy for devices like PDA, where it's not easy to auth.
$perso = new Perso($_REQUEST['name']);
if ($perso->lastError) {
cerbere_die($perso->lastError);
}
if (!$ship->is_perso_authenticated($perso->id)) {
$ship->request_perso_authenticate($perso->id);
}
$ship->request_perso_confirm_session($tmp_session_id, $perso->id);
} else {
//Delivers an URL. App have to redirects user to this URL
//launching a browser or printing the link.
$ship_code = $ship->get_code();
registry_set("api.ship.session.$ship_code.$tmp_session_id", -1);
$url = get_server_url() . get_url() . "?action=api.ship.appauthenticate&session_id=" . $tmp_session_id;
api_output($url, "URL");
}
break;
case 'appauthenticated':
//Checks the user authentication
$tmp_session_id = $url[2] or cerbere_die("/appauthenticated/ must be followed by any session identifier you used in /appauthenticate");
$perso_id = $ship->get_perso_from_session($tmp_session_id);
if (!$isPersoAuth = $ship->is_perso_authenticated($perso_id)) {
//Global auth not ok/revoked.
$auth->status = -1;
} else {
$perso = Perso::get($perso_id);
$auth->status = 1;
$auth->perso->id = $perso->id;
$auth->perso->nickname = $perso->nickname;
$auth->perso->name = $perso->name;
//$auth->perso->location = $perso->location;
//Is the perso on board? Yes if its global location is S...
$auth->perso->onBoard = (
$perso->location_global[0] == 'S' &&
substr($perso->location_global, 1, 5) == $ship->id
);
if ($auth->perso->onBoard) {
//If so, give local location
$auth->perso->location_local = $perso->location_local;
}
}
api_output($auth, "auth");
break;
case 'move':
//Moves the ship to a new location, given absolute coordinates
//TODO: handle relative moves
if (count($url) < 2) cerbere_die("/move/ must be followed by a location expression");
//Gets location class
//It's allow: (1) to normalize locations between formats
// (2) to ensure the syntax
//==> if the ship want to communicate free forms coordinates, must be added on GeoLocation a free format
try {
$location = new GeoLocation($url[2]);
} catch (Exception $ex) {
$reply->success = 0;
$reply->error = $ex->getMessage();
api_output($reply, "move");
break;
}
$ship->location_global = $location->global;
$ship->save_to_database();
$reply->success = 1;
$reply->location = $ship->location;
api_output($reply, "move");
break;
case 'land':
case 'flyin':
//Flies in
try {
$location = new GeoLocation($location);
} catch (Exception $ex) {
$reply->success = 0;
$reply->error = $ex->getMessage();
api_output($reply, "land");
break;
}
break;
case 'flyout':
//Flies out
break;
}
break;
/* -------------------------------------------------------------
Application API
/checkuserkey
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case 'app':
//Application API
require_once("includes/objects/application.php");
$app = Application::from_api_key($_REQUEST['key']) or cerbere_die("Invalid application API key");
switch ($command = $url[1]) {
case '':
//Nothing to do
//TODO: offer documentation instead
die();
case 'checkuserkey':
if (count($url) < 2) cerbere_die("/checkuserkey/ must be followed by an user key");
$reply = (boolean)$app->get_perso_id($url[2]);
api_output($reply, "check");
break;
case 'pushuserdata':
if (count($url) < 3) cerbere_die("/pushuserdata/ must be followed by an user key");
$perso_id = $app->get_perso_id($url[2]) or cerbere_die("Invalid application user key");
//then, falls to 'pushdata'
case 'pushdata':
$data_id = $_REQUEST['data'] ? $_REQUEST['data'] : new_guid();
//Gets data
switch ($mode = $_REQUEST['mode']) {
case '':
cerbere_die("Add in your data posted or in the URL mode=file to read data from the file posted (one file per api call) or mode=request to read data from \$_REQUEST['data'].");
case 'request':
$data = $_REQUEST['data'];
$format = "raw";
break;
case 'file':
$file = $_FILES['datafile']['tmp_name'] or cerbere_die("File is missing");
if (!is_uploaded_file($file)) cerbere_die("Invalid form request");
$data = "";
if (preg_match('/\.tar$/', $file)) {
$format = "tar";
$data = file_get_contents($file);
} elseif (preg_match('/\.tar\.bz2$/', $file)) {
$format = "tar";
} elseif (preg_match('/\.bz2$/', $file)) {
$format = "raw";
} else {
$format = "raw";
$data = file_get_contents($file);
}
if ($data === "") {
//.bz2
$bz = bzopen($file, "r") or cerbere_die("Couldn't open $file");
while (!feof($bz)) {
$data .= bzread($bz, BUFFER_SIZE);
}
bzclose($bz);
}
unlink($file);
break;
default:
cerbere_die("Invalid mode. Expected: file, request");
}
//Saves data
global $db;
$data_id = $db->sql_escape($data_id);
$data = $db->sql_escape($data);
$perso_id = $perso_id ? $perso_id : 'NULL';
$sql = "REPLACE INTO applications_data (application_id, data_id, data_content, data_format, perso_id) VALUES ('$app->id', '$data_id', '$data', '$format', $perso_id)";
if (!$db->sql_query($sql))
message_die(SQL_ERROR, "Can't save data", '', __LINE__, __FILE__, $sql);
//cerbere_die("Can't save data");
//Returns
api_output($data_id);
break;
case 'getuserdata':
// /api.php/getuserdata/data_id/perso_key
// /api.php/getdata/data_id
if (count($url) < 3) cerbere_die("/getuserdata/ must be followed by an user key");
$perso_id = $app->get_perso_id($url[2]) or cerbere_die("Invalid application user key");
//then, falls to 'getdata'
case 'getdata':
if (count($url) < 2) cerbere_die('/' + $url[0] + '/ must be followed by the data ID');
if (!$perso_id) $perso_id = 'NULL';
$data_id = $db->sql_escape($url[1]);
$sql = "SELECT data_content FROM applications_data WHERE application_id = '$app->id' AND data_id = '$data_id' AND perso_id = $perso_id";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to query the table", '', __LINE__, __FILE__, $sql);
}
while ($row = $db->sql_fetchrow($result)) {
}
break;
default:
echo "Unknown module:";
dprint_r($url);
break;
}
break;
default:
echo "Unknown module:";
dprint_r($url);
break;
}
?>
diff --git a/controllers/anonymous.php b/controllers/anonymous.php
--- a/controllers/anonymous.php
+++ b/controllers/anonymous.php
@@ -1,134 +1,152 @@
<?php
-/*
- * Zed
- * (c) 2010, Dereckson, some rights reserved
- * Released under BSD license
+/**
+ * Content for anonymous users
+ *
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
+ *
+ * This controller handles the pages for not logged in users.
*
- * Content for anonymous users
+ * It recognizes the following URLs:
+ * /tour a redirect to tour.html file, a visite guidée drom Zed ;
+ * /invite the page to claim the invites.
+ *
+ * In all other cases, it prints the login form.
+ *
+ * @package Zed
+ * @subpackage Controllers
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
*/
//
// Prepares the page
//
switch ($url[0]) {
case 'tour':
//The user have forgotten .html, let's redirect him
header('Location: ' . $Config['StaticContentURL'] . '/tour.html');
exit;
case 'invite':
//Invite form
if ($_POST['form'] == 'account.create') {
//User tries to claim its invite to create an account
require_once('includes/objects/invite.php');
require_once('includes/objects/user.php');
//Gets invite
$invite = new Invite($_POST['invite_code']);
if ($invite->lastError != '') {
//Not existant invite.
$smarty->assign('NOTIFY', lang_get("IncorrectInviteCode"));
} elseif ($invite->is_claimed()) {
//The invitation have already claimed by someone else.
$smarty->assign('NOTIFY', lang_get("InviteCodeAlreadyClaimed"));
} else {
//Checks if the given information is correct
//We ignore bad mails. All we really need is a login and a pass.
//We fill our array $errors with all the errors
$errors = array();
if (!$_POST['username']) {
$errors[] = lang_get('MissingUsername');
} elseif (!User::is_available_login($_POST['username'])) {
$errors[] = lang_get('LoginUnavailable');
}
if (User::get_username_from_email($_POST['email']) !== false) {
$errors[] = "There is already an account with this e-mail.";
}
if (!$_POST['passwd']) {
$errors[] = lang_get('MissingPassword');
}
if (count($errors)) {
$smarty->assign('WAP', join('<br />', $errors));
} else {
//Creates account
$user = new User();
$user->regdate = time();
$user->generate_id();
$user->name = $_POST['username'];
$user->active = 1;
$user->email = $_POST['email'];
$user->set_password($_POST['passwd']);
$user->save_to_database();
//Updates invite
$invite->to_user_id = $user->id;
$invite->save_to_database();
-
//Notifies inviter
require_once('includes/objects/message.php');
$message = new Message();
$message->from = 0;
$message->to = $invite->from_perso_id;
$message->text = sprintf(lang_get('InviteHaveBeenClaimed'), $invite->code);
$message->send();
//Logs in user
login($user->id, $user->name);
//Prints confirm message
$smarty->assign('WAP', lang_get("AccountCreated"));
//Redirects users to homepage
header('refresh: 5; url=' . get_url());
//Calls void controller
$smarty->assign('screen', 'user.create');
define('NO_FOOTER_EXTRA', true);
include("void.php");
exit;
}
}
//Keeps username, email, invite code printed on account create form
$smarty->assign('username', $_POST['username']);
$smarty->assign('invite_code', $_POST['invite_code']);
$smarty->assign('email', $_POST['email']);
}
//If the invite code is specified, checks format
if ($url[1]) {
if (preg_match("/^([A-Z]){3}([0-9]){3}$/i", $url[1])) {
$smarty->assign('invite_code', strtoupper($url[1]));
} else {
$smarty->assign('NOTIFY', lang_get("IncorrectInviteCode"));
}
}
$template = 'account_create.tpl';
break;
default:
//Login form
if (array_key_exists('LastUsername', $_COOKIE))
$smarty->assign('username', $_COOKIE['LastUsername']);
if (array_key_exists('LastOpenID', $_COOKIE))
$smarty->assign('OpenID', $_COOKIE['LastOpenID']);
$smarty->assign('LoginError', $LoginError);
$template = 'login.tpl';
break;
}
//
// HTML output
//
if ($template) $smarty->display($template);
?>
\ No newline at end of file
diff --git a/controllers/explore.php b/controllers/explore.php
--- a/controllers/explore.php
+++ b/controllers/explore.php
@@ -1,39 +1,51 @@
<?php
-/*
- * Zed
- * (c) 2010, Dereckson, some rights reserved
- * Released under BSD license
- *
+/**
* Explore current location
+
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
*
* This is a redirect controller to call the relevant controller,
* according to the location.
- *
+ *
+ * It handles /explore URL
+ *
+ * @package Zed
+ * @subpackage Controllers
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
*/
//
// Determines the kind of content user wants to explore
//
$explore_controller = '';
if (file_exists(STORIES_DIR . '/' . $CurrentPerso->location_global . '.xml')) {
$explore_controller = 'story';
}
//
// No relevant controller found
//
if ($explore_controller == '') {
message_die(GENERAL_ERROR, "<p>Congratulations! You've just found a shiny new place.</p><p>You've so the opportunity to define what this place should be, writing a story, preparing a puzzle or some images.</p><p>If you're interested, contact Dereckson.</p>", "Exploration error");
}
//
// Calls relevant controller
//
include($explore_controller . '.php');
?>
\ No newline at end of file
diff --git a/controllers/footer.php b/controllers/footer.php
--- a/controllers/footer.php
+++ b/controllers/footer.php
@@ -1,38 +1,54 @@
<?php
-/*
- * Zed
- * (c) 2010, Dereckson, some rights reserved
- * Released under BSD license
+/**
+ * Footer
+
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
+ *
+ * This is a redirect controller to call the relevant controller,
+ * according to the location.
*
- * Footer
+ * It handles and prints the footer elements (tutorial, SmartLine, html footer)
+ *
+ * @package Zed
+ * @subpackage Controllers
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
*/
if (!defined('NO_FOOTER_EXTRA')) {
///
/// Tutorials div
///
if ($CurrentPerso->flags['hypership.reached'] < 1 && $controller != 'explore') {
if (!DOJO) $smarty->display('tutorial/dojo.tpl');
lang_load("tutorials.conf", "ReachHypership");
$smarty->assign('controller', $controller);
$smarty->display('tutorial/hypership_reach.tpl');
}
///
/// Footer options
///
$smarty->assign('MultiPerso', isset($_SESSION['UserWithSeveralPersos']) && $_SESSION['UserWithSeveralPersos']);
$smarty->assign('SmartLinePrint', (string)$CurrentPerso->get_flag('site.smartline.show') != "0");
$smarty->assign('SmartLineFormMethod', $CurrentPerso->get_flag('site.smartline.method'));
}
///
/// HTML output
///
lang_load('footer.conf');
$smarty->display('footer.tpl');
?>
\ No newline at end of file
diff --git a/controllers/header.php b/controllers/header.php
--- a/controllers/header.php
+++ b/controllers/header.php
@@ -1,36 +1,63 @@
<?php
-/*
- * Zed
- * (c) 2010, Dereckson, some rights reserved
- * Released under BSD license
+/**
+ * Header
+
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
+ *
+ * This controller handle the header (MOTD, html header)
*
- * Header
+ * @package Zed
+ * @subpackage Controllers
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
+ *
+ * @todo cache MOTD fragments (sql performance)
*/
//
-// Graffiti wall
+// MOTD
//
//TODO: this is a potentially very intensive SQL query
$sql = 'SELECT p.perso_nickname as username, p.perso_name as name, m.motd_text FROM ' . TABLE_PERSOS . ' p, ' . TABLE_MOTD . ' m WHERE p.perso_id = m.perso_id ORDER BY rand() LIMIT 1';
if (!$result = $db->sql_query($sql)) message_die(SQL_ERROR, "Can't query MOTD", '', __LINE__, __FILE__, $sql);
$row = $db->sql_fetchrow($result);
$smarty->assign('WALL_TEXT', $row['motd_text']);
$smarty->assign('WALL_USER', $row['name']);
$smarty->assign('WALL_USER_URL', get_url('who', $row['username']));
//
// HTML output
//
//Defines DOJO if needed, and assigns DOJO/DIJIT smarty variables
-if (!defined('DOJO')) define('DOJO', defined('DIJIT'));
-if (defined('DIJIT')) $smarty->assign('DIJIT', true);
+if (!defined('DOJO')) {
+ /**
+ * Determines if the dojo library have or not been loaded
+ *
+ * If true, there's a code like <script src="js/dojo/dojo/dojo.js"><script>
+ * in the <head> block of the code.
+ */
+ define('DOJO', defined('DIJIT'));
+}
+
+if (defined('DIJIT')) {$smarty->assign('DIJIT', true);
$smarty->assign('DOJO', DOJO);
//Prints the template
$smarty->display('header.tpl');
+/**
+ * This constant indicates the header have been printed
+ */
define('HEADER_PRINTED', true);
?>
\ No newline at end of file
diff --git a/controllers/home.php b/controllers/home.php
--- a/controllers/home.php
+++ b/controllers/home.php
@@ -1,75 +1,103 @@
<?php
-/*
- * Zed
- * (c) 2010, Dereckson, some rights reserved
- * Released under BSD license
+/**
+ * Homepage
+
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
+ *
+ * This controller handle the / URL.
+ *
+ * It prints:
+ * a scene rendering from where the perso is ;
+ * the home.tpl view ;
+ * the messages, using the messages.tpl view.
*
- * Homepage
+ * The controller also handle messages, marking them red and allowing their
+ * suppression: /?action=msg_delete&id=8 to delete the message #8.
+ *
+ * @package Zed
+ * @subpackage Controllers
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
+ *
+ * @todo The homepage requires Dojo but Dojo loading here is currently a kludge, as dojo is required by hypership .tpl scene. We should create an optionnal .meta xml file format to set this kind of options.
*/
//
// Gets and manage messages
//
require_once('includes/objects/message.php');
//Deletes a message if user have clicked the X
if ($_GET['action'] == 'msg_delete') {
//Deletes message $_GET['id']
$id = $_GET['id'];
$messageToDelete = new Message($id);
if ($messageToDelete->to != $CurrentPerso->id) {
//Not one of user message
$smarty->assign('WAP', lang_get('NotYourMessage'));
} elseif ($messageToDelete->flag == 2) {
//Already deleted
$smarty->assign('WAP', lang_get('MessageAlreadyDeleted'));
} else {
$messageToDelete->delete();
$smarty->assign('NOTIFY', lang_get('MessageDeleted'));
}
}
//Gets messages
$newMessagesCount = 0;
$messages = Message::get_messages($CurrentPerso->id, true, $newMessagesCount);
if ($newMessagesCount > 0) {
$smarty->assign('NOTIFY', sprintf(lang_get("NewMessages"), $newMessagesCount, s($newMessagesCount)));
}
//Gets scene
require_once("includes/geo/scene.php");
$scene = new GeoScene($CurrentPerso->location);
$smarty->assign('SCENE', $scene);
//
// HTML output
//
//Serves header
//TODO: Dojo loading here is currently a kludge, as dojo is required by
//hypership .tpl scene. We should create an optionnal .meta xml file format
//to set this kind of options
-if (!defined('DIJIT')) define('DIJIT', true);
+if (!defined('DIJIT')) {
+ /**
+ * This constant indicates we need to load the Dijit (and so Dojo) library.
+ */
+ define('DIJIT', true);
+}
$smarty->assign('PAGE_TITLE', lang_get('Welcome'));
include('header.php');
//Serves content
if (!$scene->lastError)
$scene->render();
$smarty->display('home.tpl');
if ($messages) {
$smarty->assign('MESSAGES', $messages);
$smarty->display('messages.tpl');
}
//Serves footer
$smarty->assign("screen", "Home console");
include('footer.php');
?>
\ No newline at end of file
diff --git a/controllers/motd.php b/controllers/motd.php
--- a/controllers/motd.php
+++ b/controllers/motd.php
@@ -1,38 +1,56 @@
<?php
-/*
- * Zed
- * (c) 2010, Dereckson, some rights reserved
- * Released under BSD license
+/**
+ * MOTD
+
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
+ *
+ * This controller handle the /push "secret" URL.
*
- * Raw text or HTML content
+ * It allows to add a message in the MOTD (messages printed in the header on
+ * the top of each page).
+ *
+ * It usees the motd_add.tpl view and the MOTD class.
+ *
+ * @package Zed
+ * @subpackage Controllers
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
*/
//
// Handles form
//
if ($_REQUEST['text']) {
require_once('includes/objects/motd.php');
$motd = new MOTD();
$motd->text = $_REQUEST['text'];
$motd->perso_id = $CurrentPerso->id;
$motd->save_to_database();
$smarty->assign('WAP', lang_get('Published'));
}
//
// HTML output
//
//Serves header
$smarty->assign('PAGE_TITLE', lang_get('PushMessage'));
include('header.php');
//Serves content
$smarty->display('motd_add.tpl');
//Servers footer
include('footer.php');
?>
\ No newline at end of file
diff --git a/controllers/page.php b/controllers/page.php
--- a/controllers/page.php
+++ b/controllers/page.php
@@ -1,109 +1,135 @@
-<?php
-
-/*
- * Zed
- * (c) 2010, Dereckson, some rights reserved
- * Released under BSD license
- *
- * HTML content
- */
-
-if (!$code = $db->sql_escape($url[1])) {
- message_die(HACK_ERROR, "/page/ must be followed by page code");
-}
-
-//
-// Handles editor form
-//
-
-if ($_POST['code']) {
- //Ask flag admin.pages.editor
- $CurrentPerso->request_flag('admin.pages.editor');
-
- //Gets version
- $sql = "SELECT MAX(page_version) + 1 FROM " . TABLE_PAGES_EDITS .
- " WHERE page_code = '$code'";
- if (!$result = $db->sql_query($sql)) message_die(SQL_ERROR, "Can't fetch pages", '', __LINE__, __FILE__, $sql);
- $row = $db->sql_fetchrow($result);
- $page_version = ($row[0] == "") ? 0 : $row[0];
-
- //Gets other fields
- $page_code = $db->sql_escape($code);
- $page_title = $db->sql_escape($_POST['title']);
- $page_content = $db->sql_escape($_POST['content']);
- $page_edit_reason = $db->sql_escape($_POST['edit_reason']);
- $page_edit_user_id = $CurrentPerso->user_id;
- $page_edit_time = time();
-
- //Saves archive version
- $sql = "INSERT INTO " . TABLE_PAGES_EDITS . " (`page_code`, `page_version`, `page_title`, `page_content`, `page_edit_reason`, `page_edit_user_id`, `page_edit_time`) VALUES ('$page_code', '$page_version', '$page_title', '$page_content', '$page_edit_reason', '$page_edit_user_id', '$page_edit_time')";
- if (!$db->sql_query($sql)) {
- message_die(SQL_ERROR, "Can't save page", '', __LINE__, __FILE__, $sql);
- }
-
- //Saves prod version
- $sql = "REPLACE INTO " . TABLE_PAGES . " (`page_code`, `page_title`, `page_content`) VALUES ('$page_code', '$page_title', '$page_content')";
- if (!$db->sql_query($sql)) {
- message_die(SQL_ERROR, "Can't save page", '', __LINE__, __FILE__, $sql);
- }
-
- $smarty->assign('NOTIFY', "Page $page_code saved, version $page_version.");
-}
-
-//
-// Gets page
-//
-
-$sql = "SELECT page_title, page_content, page_code FROM " . TABLE_PAGES . " WHERE page_code LIKE '$code'";
-if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Can't get pages", '', __LINE__, __FILE__, $sql);
-$row = $db->sql_fetchrow($result);
-
-switch ($_GET['mode']) {
- case 'edit':
- $CurrentPerso->request_flag('admin.pages.editor');
- $template = 'page_edit.tpl';
- if ($row) {
- $smarty->assign('PAGE_TITLE', $row['page_title']);
- $smarty->assign('page', $row);
- } else {
- $smarty->assign('PAGE_TITLE', $code);
- $page['page_code'] = $code;
- $smarty->assign('page', $page);
- unset($page);
- }
- $smarty->assign('PAGE_JS', 'FCKeditor/fckeditor.js');
- break;
-
- default:
- if ($row) {
- $smarty->assign('PAGE_TITLE', $row['page_title']);
- $content = $row['page_content'];
- } else {
- $smarty->assign('PAGE_TITLE', lang_get('PageNotFound'));
- $content = lang_get('PageNotFound');
- }
-
- //Adds edit link
- if ($CurrentPerso->flags['admin.pages.editor']) {
- $content .= '<p class="info" style="text-align: right">[ <a href="?mode=edit">Edit page</a> ]</p>';
- }
- $template = 'raw.tpl';
- $smarty->assign('CONTENT', $content);
- break;
-}
-
-
-//
-// HTML output
-//
-
-//Serves header
-include('header.php');
-
-//Serves content
-$smarty->display($template);
-
-//Serves footer
-include('footer.php');
-
+<?php
+
+/**
+ * Page
+
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
+ *
+ * This controller handle the /page URL.
+ *
+ * It allows to prints a content page.
+ *
+ * The code of the content page to print must be included in the URL:
+ * /page/quux will print the quux page.
+ *
+ * To edit a page, append ?mode=edit to the URL.
+ *
+ * It usees the page_edit.tpl view to edit and the raw.tpl view to print pages.
+ *
+ * Versions of the edited pages are saved in a separate table
+ * but it's not a wiki, it's for backup purposes.
+ *
+ * @package Zed
+ * @subpackage Controllers
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
+ *
+ * @todo move "handle editor form" and some of the "gets page" code to a includes/objets/page.php file (rationale: cleaner model/controller separation)
+ */
+
+if (!$code = $db->sql_escape($url[1])) {
+ message_die(HACK_ERROR, "/page/ must be followed by page code");
+}
+
+//
+// Handles editor form
+//
+
+if ($_POST['code']) {
+ //Ask flag admin.pages.editor
+ $CurrentPerso->request_flag('admin.pages.editor');
+
+ //Gets version
+ $sql = "SELECT MAX(page_version) + 1 FROM " . TABLE_PAGES_EDITS .
+ " WHERE page_code = '$code'";
+ if (!$result = $db->sql_query($sql)) message_die(SQL_ERROR, "Can't fetch pages", '', __LINE__, __FILE__, $sql);
+ $row = $db->sql_fetchrow($result);
+ $page_version = ($row[0] == "") ? 0 : $row[0];
+
+ //Gets other fields
+ $page_code = $db->sql_escape($code);
+ $page_title = $db->sql_escape($_POST['title']);
+ $page_content = $db->sql_escape($_POST['content']);
+ $page_edit_reason = $db->sql_escape($_POST['edit_reason']);
+ $page_edit_user_id = $CurrentPerso->user_id;
+ $page_edit_time = time();
+
+ //Saves archive version
+ $sql = "INSERT INTO " . TABLE_PAGES_EDITS . " (`page_code`, `page_version`, `page_title`, `page_content`, `page_edit_reason`, `page_edit_user_id`, `page_edit_time`) VALUES ('$page_code', '$page_version', '$page_title', '$page_content', '$page_edit_reason', '$page_edit_user_id', '$page_edit_time')";
+ if (!$db->sql_query($sql)) {
+ message_die(SQL_ERROR, "Can't save page", '', __LINE__, __FILE__, $sql);
+ }
+
+ //Saves prod version
+ $sql = "REPLACE INTO " . TABLE_PAGES . " (`page_code`, `page_title`, `page_content`) VALUES ('$page_code', '$page_title', '$page_content')";
+ if (!$db->sql_query($sql)) {
+ message_die(SQL_ERROR, "Can't save page", '', __LINE__, __FILE__, $sql);
+ }
+
+ $smarty->assign('NOTIFY', "Page $page_code saved, version $page_version.");
+}
+
+//
+// Gets page
+//
+
+$sql = "SELECT page_title, page_content, page_code FROM " . TABLE_PAGES . " WHERE page_code LIKE '$code'";
+if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Can't get pages", '', __LINE__, __FILE__, $sql);
+$row = $db->sql_fetchrow($result);
+
+switch ($_GET['mode']) {
+ case 'edit':
+ $CurrentPerso->request_flag('admin.pages.editor');
+ $template = 'page_edit.tpl';
+ if ($row) {
+ $smarty->assign('PAGE_TITLE', $row['page_title']);
+ $smarty->assign('page', $row);
+ } else {
+ $smarty->assign('PAGE_TITLE', $code);
+ $page['page_code'] = $code;
+ $smarty->assign('page', $page);
+ unset($page);
+ }
+ $smarty->assign('PAGE_JS', 'FCKeditor/fckeditor.js');
+ break;
+
+ default:
+ if ($row) {
+ $smarty->assign('PAGE_TITLE', $row['page_title']);
+ $content = $row['page_content'];
+ } else {
+ $smarty->assign('PAGE_TITLE', lang_get('PageNotFound'));
+ $content = lang_get('PageNotFound');
+ }
+
+ //Adds edit link
+ if ($CurrentPerso->flags['admin.pages.editor']) {
+ $content .= '<p class="info" style="text-align: right">[ <a href="?mode=edit">Edit page</a> ]</p>';
+ }
+ $template = 'raw.tpl';
+ $smarty->assign('CONTENT', $content);
+ break;
+}
+
+//
+// HTML output
+//
+
+//Serves header
+include('header.php');
+
+//Serves content
+$smarty->display($template);
+
+//Serves footer
+include('footer.php');
+
?>
\ No newline at end of file
diff --git a/controllers/persorequest.php b/controllers/persorequest.php
--- a/controllers/persorequest.php
+++ b/controllers/persorequest.php
@@ -1,142 +1,182 @@
-<?php
-
-/*
- * Zed
- * (c) 2010, Dereckson, some rights reserved
- * Released under BSD license
- *
- * Perso requests
- */
-
-///
-/// Helper class and method
-///
-
-class PersoRequest {
- public $message;
- public $requestFlag;
- public $flag;
- public $store = 'perso';
- public $value_allow = 1;
- public $value_deny = 0;
-
- function __construct ($requestFlag, $message, $flag) {
- $this->requestFlag = $requestFlag;
- $this->message = $message;
- $this->flag = $flag;
- }
-}
-
-/*
- * Gets ship from specified S00001 code
- * @param string $ship_code the ship code (e.g. S00001)
- * @return Ship the Ship class instance
- */
-function get_ship ($ship_code) {
- require_once('includes/objects/ship.php');
- static $ships;
- $ship_id = substr($ship_code, 1);
- if (!$ships[$ship_id]) $ships[$ship_id] = new Ship($ship_id);
- return $ships[$ship_id];
-}
-
-/*
- * Gets request allow URL
- * @param PersoRequest $request the perso request to confirm
- */
-function get_request_allow_url ($request) {
- return get_request_url($request->requestFlag, $request->store, $request->flag, $request->value_allow);
-}
-
-/*
- * Gets request deny URL
- * @param PersoRequest $request the perso request to confirm
- */
-
-function get_request_deny_url ($request) {
- return get_request_url($request->requestFlag, $request->store, $request->flag, $request->value_deny);
-}
-
-/*
- * Gets request URL
- * @param string $store 'perso' or 'registry'
- * @param string $key the perso flag or registry key
- * @param string $value the value to store
- */
-function get_request_url ($requestFlag, $store, $key, $value) {
- global $Config;
- $hash = md5($_SESSION['ID'] . $Config['SecretKey'] . $requestFlag . $store . $key . $value);
- return "$Config[DoURL]/perso_request/$requestFlag/$store/$key/$value/$hash";
-}
-
-///
-/// Get requests
-///
-
-//Loads perso request language file
-lang_load('persorequest.conf');
-
-//The array request will be passed to Smarty and will contain PersoRequest items.
-$requests = array();
-
-foreach ($CurrentPerso->flags as $flag => $value) {
- if ($value && substr($flag, 0, 8) == "request.") {
- if (string_starts_with($flag, 'request.api.ship.auth.')) {
- //Gets ship
-
- $ship_code = substr($flag, 22);
- $ship = get_ship($ship_code);
-
- //Adds request
- $message = sprintf(lang_get('RequestShipAPIAuthenticate'), $ship->name);
- $requests[] = new PersoRequest($flag, $message, substr($flag, 8));
- } elseif (string_starts_with($flag, 'request.api.ship.session.')) {
- //Gets ship
- $ship_code = substr($flag, 25, 6);
- $ship = get_ship($ship_code);
-
- //Adds request
- $message = sprintf(lang_get('RequestShipAPISessionConfirm'), $ship->name);
- $request = new PersoRequest($flag, $message, substr($flag, 8));
- $request->value_allow = $CurrentPerso->id;
- $request->value_deny = -1;
- $request->store = 'registry';
- $requests[] = $request;
- } else {
- message_die(GENERAL_ERROR, "Unknown request flag: $flag. Please report this bug.");
- }
- }
-}
-
-///
-/// Requests handling
-///
-
-if (count($requests) == 0) {
- //If site.requests flag is at 1 but we don't have request, ignore processing
- $CurrentPerso->set_flag('site.requests', 0);
-
- //We don't die, so next controller takes relay
-} else {
- ///
- /// HTML output
- ///
-
- //Serves header
- define('DOJO', true);
- $smarty->assign('PAGE_TITLE', lang_get('PersoRequests'));
- include('header.php');
-
- //Serves content
- $smarty->assign('requests', $requests);
- $smarty->display('persorequests.tpl');
-
- //Serves footer
- $smarty->assign("screen", "Perso requests");
- include('footer.php');
-
- //Dies
- exit;
-}
-
+<?php
+
+/**
+ * Persos requests
+
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
+ *
+ * This controller handle the /requests URL.
+ *
+ * It can also be called with the requests SmartLine command.
+ *
+ * It allows to prints a content page.
+ *
+ * This controllers uses the persorequests.tpl view.
+ *
+ * This controller offer AJAX capabilities but degrades gracefully in JS.
+ *
+ * @package Zed
+ * @subpackage Controllers
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
+ *
+ * @todo move the get_ship function to a Ship::from_code method
+ * @todo Document the request system in the API documentation
+ */
+
+///
+/// Helper class and method
+///
+
+/**
+ * A perso request
+ */
+class PersoRequest {
+ public $message;
+ public $requestFlag;
+ public $flag;
+ public $store = 'perso';
+ public $value_allow = 1;
+ public $value_deny = 0;
+
+ /**
+ * Initialies a perso request
+ *
+ * @param string $requestFlag the request's flag
+ * @param string $message the message to print
+ * @param string $message the flag to set, according the request approve/denial
+ */
+ function __construct ($requestFlag, $message, $flag) {
+ $this->requestFlag = $requestFlag;
+ $this->message = $message;
+ $this->flag = $flag;
+ }
+}
+
+/**
+ * Gets ship from specified S00001 code
+ *
+ * @param string $ship_code the ship code (e.g. S00001)
+ * @return Ship the Ship class instance
+ */
+function get_ship ($ship_code) {
+ require_once('includes/objects/ship.php');
+ static $ships;
+ $ship_id = substr($ship_code, 1);
+ if (!$ships[$ship_id]) $ships[$ship_id] = new Ship($ship_id);
+ return $ships[$ship_id];
+}
+
+/**
+ * Gets request allow URL
+ *
+ * @param PersoRequest $request the perso request to confirm
+ * @return string the URL to allow the request
+ */
+function get_request_allow_url ($request) {
+ return get_request_url($request->requestFlag, $request->store, $request->flag, $request->value_allow);
+}
+
+/**
+ * Gets request deny URL
+ *
+ * @param PersoRequest $request the perso request to confirm
+ * @return string the URL to deny the request
+ */
+function get_request_deny_url ($request) {
+ return get_request_url($request->requestFlag, $request->store, $request->flag, $request->value_deny);
+}
+
+/**
+ * Gets request URL
+ *
+ * @param string $store 'perso' or 'registry'
+ * @param string $key the perso flag or registry key
+ * @param string $value the value to store
+ * @return the request URL
+ */
+function get_request_url ($requestFlag, $store, $key, $value) {
+ global $Config;
+ $hash = md5($_SESSION['ID'] . $Config['SecretKey'] . $requestFlag . $store . $key . $value);
+ return "$Config[DoURL]/perso_request/$requestFlag/$store/$key/$value/$hash";
+}
+
+///
+/// Get requests
+///
+
+//Loads perso request language file
+lang_load('persorequest.conf');
+
+//The array request will be passed to Smarty and will contain PersoRequest items.
+$requests = array();
+
+foreach ($CurrentPerso->flags as $flag => $value) {
+ if ($value && substr($flag, 0, 8) == "request.") {
+ if (string_starts_with($flag, 'request.api.ship.auth.')) {
+ //Gets ship
+
+ $ship_code = substr($flag, 22);
+ $ship = get_ship($ship_code);
+
+ //Adds request
+ $message = sprintf(lang_get('RequestShipAPIAuthenticate'), $ship->name);
+ $requests[] = new PersoRequest($flag, $message, substr($flag, 8));
+ } elseif (string_starts_with($flag, 'request.api.ship.session.')) {
+ //Gets ship
+ $ship_code = substr($flag, 25, 6);
+ $ship = get_ship($ship_code);
+
+ //Adds request
+ $message = sprintf(lang_get('RequestShipAPISessionConfirm'), $ship->name);
+ $request = new PersoRequest($flag, $message, substr($flag, 8));
+ $request->value_allow = $CurrentPerso->id;
+ $request->value_deny = -1;
+ $request->store = 'registry';
+ $requests[] = $request;
+ } else {
+ message_die(GENERAL_ERROR, "Unknown request flag: $flag. Please report this bug.");
+ }
+ }
+}
+
+///
+/// Requests handling
+///
+
+if (count($requests) == 0) {
+ //If site.requests flag is at 1 but we don't have request, ignore processing
+ $CurrentPerso->set_flag('site.requests', 0);
+
+ //We don't die, so next controller takes relay
+} else {
+ ///
+ /// HTML output
+ ///
+
+ //Serves header
+ define('DOJO', true);
+ $smarty->assign('PAGE_TITLE', lang_get('PersoRequests'));
+ include('header.php');
+
+ //Serves content
+ $smarty->assign('requests', $requests);
+ $smarty->display('persorequests.tpl');
+
+ //Serves footer
+ $smarty->assign("screen", "Perso requests");
+ include('footer.php');
+
+ //Dies
+ exit;
+}
+
?>
\ No newline at end of file
diff --git a/includes/api/BeautyXML.class.php b/includes/api/BeautyXML.class.php
--- a/includes/api/BeautyXML.class.php
+++ b/includes/api/BeautyXML.class.php
@@ -1,94 +1,156 @@
-<?php
-
-//==============================================================================
-// This class is simple XML beautifer
-// it's very, very, very simple - feature version will be better :-)
-//
-//
-// IMPORTANT NOTE
-// there is no warranty, implied or otherwise with this software.
-//
-// version 0.1 | August 2004
-//
-// released under a LGPL licence.
-//
-// Slawomir Jasinski,
-// http://www.jasinski.us (polish only - my home page)
-// http://www.cgi.csd.pl (english & polish)
-// contact me - sj@gex.pl
-//==============================================================================
-
-class BeautyXML {
-
- var $how_to_ident = " "; // you can user also \t or more/less spaces
- var $wrap = false; // wrap long tekst ?
- var $wrap_cont = 90; // where wrap words
-
- // gives ident to string
- function ident(&$str, $level) {
- $level--;
- for ($a = 0; $a < $level; $a++)
- $spaces .= $this->how_to_ident;
- return $spaces .= $str;
- }
-
- // main funcion
- function format($str) {
-
- $str = preg_replace("/<\?[^>]+>/", "", $str);
-
- $tmp = explode("\n", $str); // extracting string into array
-
- // cleaning string from spaces and other stuff like \n \r \t
- for ($a = 0, $c = count($tmp); $a < $c; $a++)
- $tmp[$a] = trim($tmp[$a]);
-
- // joining to string ;-)
- $newstr = join("", $tmp);
-
- $newstr = preg_replace("/>([\s]+)<\//", "></", $newstr);
-
- // adding \n lines where tags ar near
- $newstr = str_replace("><", ">\n<", $newstr);
-
- // exploding - each line is one XML tag
- $tmp = explode("\n", $newstr);
-
- // preparing array for list of tags
- $stab = array('');
-
- // lets go :-)
- for ($a = 0, $c = count($tmp); $a <= $c; $a++) {
-
- $add = true;
-
- preg_match("/<([^\/\s>]+)/", $tmp[$a], $match);
-
- $lan = trim(strtr($match[0], "<>", " "));
-
- $level = count($stab);
-
- if (in_array($lan, $stab) && substr_count($tmp[$a], "</$lan") == 1) {
- $level--;
- $s = array_pop($stab);
- $add = false;
- }
-
- if (substr_count($tmp[$a], "<$lan") == 1 && substr_count($tmp[$a], "</$lan") == 1)
- $add = false;
-
- if (preg_match("/\/>$/", $tmp[$a], $match))
- $add = false;
-
- $tmp[$a] = $this->ident($tmp[$a], $level);
-
- if ($this->wrap) $tmp[$a] = wordwrap($tmp[$a], $this->wrap_cont, "\n" . $this->how_to_ident . $this->how_to_ident . $this->how_to_ident);
-
- if ($add && !@in_array($lan, $stab) && $lan != '') array_push($stab, $lan);
-
- }
-
- return join("\n", $tmp);
- }
-
+<?php
+
+/**
+ * XML beautifer
+ *
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
+ *
+ *
+ * This class is simple XML beautifer
+ * it's very, very, very simple - feature version will be better :-)
+ *
+ * IMPORTANT NOTE
+ * there is no warranty, implied or otherwise with this software.
+ *
+ * version 0.1 | August 2004
+ *
+ * released under a LGPL licence.
+ *
+ * Slawomir Jasinski,
+ * http://www.jasinski.us (polish only - my home page)
+ * http://www.cgi.csd.pl (english & polish)
+ * contact me - sj@gex.pl
+ *
+ * @package Zed
+ * @subpackage API
+ * @author Slawomir Jasinski <sj@gex.pl>
+ * @copyright 2004 Slawomir Jasinski, 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.gnu.org/licenses/lgpl.html LGPL
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
+ *
+ * @todo Contact Slawomir Jasinski and ask it if the current code could be
+ * relicensed under BSD license. If not, rewrite from scratch under BSD license.
+ */
+
+/**
+ * This class is simple XML beautifer.
+ * It's very, very, very simple - feature version will be better :-)
+ *
+ * @author Slawomir Jasinski <sj@gex.pl>
+ */
+class BeautyXML {
+ /**
+ * Indicates what characters to use to indent.
+ *
+ * If you wish a regular tabulation, the suggested value is \t ;
+ * If you wish spaces instead, put the correct amount of spaces as value.
+ *
+ * @var string
+ */
+ var $how_to_ident = " "; // you can user also \t or more/less spaces
+
+ /**
+ * Determines if long text have to be wrapped.
+ *
+ * If true, the text will be wrapped ; otherwise, long lines will be kept.
+ *
+ * @var bool
+ */
+ var $wrap = false;
+
+ /**
+ * If $wrap is true, determines the line lenght.
+ *
+ * After this lenght, any text will be wrapped.
+ *
+ * @see $wrap
+ * @var @int
+ */
+ var $wrap_cont = 80; // where wrap words
+
+ /**
+ * Idents the specified string.
+ *
+ * @param string $str the string to indent
+ * @param int $level the ident level, ie the number of identation to prepend the string with
+ */
+ function ident (&$str, $level) {
+ $level--;
+ for ($a = 0; $a < $level; $a++)
+ $spaces .= $this->how_to_ident;
+ return $spaces .= $str;
+ }
+
+ /**
+ * Formats the specified string, beautifying it, with proper indent.
+ *
+ * This is the main class method.
+ *
+ * @param $str the XML fragment to beautify
+ * @return string the beautified XML fragment
+ */
+ function format ($str) {
+
+ $str = preg_replace("/<\?[^>]+>/", "", $str);
+
+ $tmp = explode("\n", $str); // extracting string into array
+
+ // cleaning string from spaces and other stuff like \n \r \t
+ for ($a = 0, $c = count($tmp); $a < $c; $a++)
+ $tmp[$a] = trim($tmp[$a]);
+
+ // joining to string ;-)
+ $newstr = join("", $tmp);
+
+ $newstr = preg_replace("/>([\s]+)<\//", "></", $newstr);
+
+ // adding \n lines where tags ar near
+ $newstr = str_replace("><", ">\n<", $newstr);
+
+ // exploding - each line is one XML tag
+ $tmp = explode("\n", $newstr);
+
+ // preparing array for list of tags
+ $stab = array('');
+
+ // lets go :-)
+ for ($a = 0, $c = count($tmp); $a <= $c; $a++) {
+
+ $add = true;
+
+ preg_match("/<([^\/\s>]+)/", $tmp[$a], $match);
+
+ $lan = trim(strtr($match[0], "<>", " "));
+
+ $level = count($stab);
+
+ if (in_array($lan, $stab) && substr_count($tmp[$a], "</$lan") == 1) {
+ $level--;
+ $s = array_pop($stab);
+ $add = false;
+ }
+
+ if (substr_count($tmp[$a], "<$lan") == 1 && substr_count($tmp[$a], "</$lan") == 1)
+ $add = false;
+
+ if (preg_match("/\/>$/", $tmp[$a], $match))
+ $add = false;
+
+ $tmp[$a] = $this->ident($tmp[$a], $level);
+
+ if ($this->wrap) $tmp[$a] = wordwrap($tmp[$a], $this->wrap_cont, "\n" . $this->how_to_ident . $this->how_to_ident . $this->how_to_ident);
+
+ if ($add && !@in_array($lan, $stab) && $lan != '') array_push($stab, $lan);
+
+ }
+
+ return join("\n", $tmp);
+ }
+
}
\ No newline at end of file
diff --git a/includes/api/api_helpers.php b/includes/api/api_helpers.php
--- a/includes/api/api_helpers.php
+++ b/includes/api/api_helpers.php
@@ -1,133 +1,166 @@
-<?php
-//
-// API helpers function
-//
-// XML outputs code uses:
-// - http://www.thedeveloperday.com/xml-beautifier-tool/
-// - http://snipplr.com/view/3491/convert-php-array-to-xml-or-simple-xml-object-if-you-wish/
-
-/**
- * The main function for converting to an XML document.
- * Pass in a multi dimensional array and this recrusively loops through and builds up an XML document.
- *
- * @param mixed $data
- * @param string $rootNodeName - what you want the root node to be - defaultsto data.
- * @param SimpleXMLElement $xml - should only be used recursively
- * @param string $unknownNodeName - name to give to unknown (numeric) keys
- * @return string XML
- */
-function toXml($data, $rootNodeName = 'data', $xml = null, $unknownNodeName = 'unknownNode')
-{
- if (!$rootNodeName) $rootNodeName = 'data';
- if (!$unknownNodeName) $unknownNodeName = 'unknownNode';
-
- // turn off compatibility mode as simple xml throws a wobbly if you don't.
- if (ini_get('zend.ze1_compatibility_mode') == 1)
- ini_set('zend.ze1_compatibility_mode', 0);
-
- if ($xml == null) {
- if (!is_array($data) && !is_object($data)) {
- //We've a singleton
- if (is_bool($data)) $data = $data ? 'true' : 'false';
- return "<?xml version='1.0' encoding='utf-8'?><$rootNodeName>$data</$rootNodeName>";
- }
-
- //Starts with simple document
- $xml = simplexml_load_string("<?xml version='1.0' encoding='utf-8'?><$rootNodeName />");
- }
-
- // loop through the data passed in.
- foreach($data as $key => $value) {
- // no numeric keys in our xml please!
- if (is_numeric($key)) {
- // make string key...
- $key = $unknownNodeName . '_'. (string) $key;
- }
-
- // replace anything not alpha numeric
- $key = preg_replace('/[^a-z]/i', '', $key);
-
- //If there is another array found recrusively call this function
- if (is_array($value)) {
- $node = $xml->addChild($key);
- //Recursive call.
- toXml($value, $rootNodeName, $node, $unknownNodeName);
- } elseif (is_object($value)) {
- $node = $xml->addChild($key);
- foreach ($value as $subkey => $subvalue) {
- if ($subkey == "lastError") continue;
- if ($subvalue === null) {
- //Ignore null values
- continue;
- } elseif (is_array($subvalue) || is_object($subvalue)) {
- //TODO: test this
- //Recursive call.
- $subnode = $node->addChild($subkey);
- toXml($subvalue, $rootNodeName, $subnode, $unknownNodeName);
- } elseif (is_bool($subvalue)) {
- $node->addChild($subkey, $subvalue ? 'true' : 'false');
- } else {
- $node->addChild($subkey, htmlentities($subvalue));
- }
- }
- //die();
- //$array = array();
- //$node = $xml->addChild($key);
- //toXml($value, $rootNodeName, $node, $unknownNodeName);
- } elseif (is_bool($value)) {
- $xml->addChild($key, $value ? 'true' : 'false');
- } else {
- //Adds single node.
- if ($value || $value === 0) {
- $value = htmlentities($value);
- $xml->addChild($key,$value);
- }
- }
-
- }
- // pass back as string. or simple xml object if you want!
- return $xml->asXML();
-}
-
-function api_output ($reply, $xmlRoot = null, $xmlChildren = null) {
- $format = isset($_REQUEST['format']) ? $_REQUEST['format'] : 'preview';
- switch ($format) {
- case 'preview':
- echo '<pre>';
- print_r($reply);
- echo '</pre>';
- break;
-
- case 'php':
- echo serialize($reply);
- break;
-
- case 'wddx':
- require_once('BeautyXML.class.php');
- $bc = new BeautyXML();
- echo $bc->format(wddx_serialize_value($reply));
- break;
-
- case 'json':
- echo json_encode($reply);
- break;
-
- case 'xml':
- require_once('BeautyXML.class.php');
- $bc = new BeautyXML();
- echo '<?xml version="1.0" encoding="utf-8"?>';
- echo "\n";
- echo $bc->format(toXml($reply, $xmlRoot, null, $xmlChildren));
- break;
-
- case 'string':
- echo $reply;
- break;
-
- default:
- echo "Unknown API format: $_GET[format]";
- break;
- }
-}
-
+<?php
+
+/**
+ * API helper functions
+ *
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
+ *
+ * This file provides a functions to output the API message in several formats.
+ *
+ * The supported formats are preview (PHP dump), XML, PHP serialize, WDDX
+ * and json.
+ *
+ * The XML outputs code uses the following codes:
+ * - http://www.thedeveloperday.com/xml-beautifier-tool/
+ * - http://snipplr.com/view/3491/convert-php-array-to-xml-or-simple-xml-object-if-you-wish/
+ *
+ * @package Zed
+ * @subpackage API
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
+ */
+
+/**
+ * The main function for converting to an XML document.
+ *
+ * Pass in a multi dimensional array and this recursively loops through
+ * and builds up an XML document.
+ *
+ * @param mixed $data
+ * @param string $rootNodeName What you want the root node to be - defaultsto data.
+ * @param SimpleXMLElement $xml Should only be used recursively
+ * @param string $unknownNodeName Name to give to unknown (numeric) keys
+ * @return string XML
+ */
+function toXml($data, $rootNodeName = 'data', $xml = null, $unknownNodeName = 'unknownNode')
+{
+ if (!$rootNodeName) $rootNodeName = 'data';
+ if (!$unknownNodeName) $unknownNodeName = 'unknownNode';
+
+ // turn off compatibility mode as simple xml throws a wobbly if you don't.
+ if (ini_get('zend.ze1_compatibility_mode') == 1)
+ ini_set('zend.ze1_compatibility_mode', 0);
+
+ if ($xml == null) {
+ if (!is_array($data) && !is_object($data)) {
+ //We've a singleton
+ if (is_bool($data)) $data = $data ? 'true' : 'false';
+ return "<?xml version='1.0' encoding='utf-8'?><$rootNodeName>$data</$rootNodeName>";
+ }
+
+ //Starts with simple document
+ $xml = simplexml_load_string("<?xml version='1.0' encoding='utf-8'?><$rootNodeName />");
+ }
+
+ // loop through the data passed in.
+ foreach($data as $key => $value) {
+ // no numeric keys in our xml please!
+ if (is_numeric($key)) {
+ // make string key...
+ $key = $unknownNodeName . '_'. (string) $key;
+ }
+
+ // replace anything not alpha numeric
+ $key = preg_replace('/[^a-z]/i', '', $key);
+
+ //If there is another array found recrusively call this function
+ if (is_array($value)) {
+ $node = $xml->addChild($key);
+ //Recursive call.
+ toXml($value, $rootNodeName, $node, $unknownNodeName);
+ } elseif (is_object($value)) {
+ $node = $xml->addChild($key);
+ foreach ($value as $subkey => $subvalue) {
+ if ($subkey == "lastError") continue;
+ if ($subvalue === null) {
+ //Ignore null values
+ continue;
+ } elseif (is_array($subvalue) || is_object($subvalue)) {
+ //TODO: test this
+ //Recursive call.
+ $subnode = $node->addChild($subkey);
+ toXml($subvalue, $rootNodeName, $subnode, $unknownNodeName);
+ } elseif (is_bool($subvalue)) {
+ $node->addChild($subkey, $subvalue ? 'true' : 'false');
+ } else {
+ $node->addChild($subkey, htmlentities($subvalue));
+ }
+ }
+ //die();
+ //$array = array();
+ //$node = $xml->addChild($key);
+ //toXml($value, $rootNodeName, $node, $unknownNodeName);
+ } elseif (is_bool($value)) {
+ $xml->addChild($key, $value ? 'true' : 'false');
+ } else {
+ //Adds single node.
+ if ($value || $value === 0) {
+ $value = htmlentities($value);
+ $xml->addChild($key,$value);
+ }
+ }
+
+ }
+ // pass back as string. or simple xml object if you want!
+ return $xml->asXML();
+}
+
+/**
+ * Outputs API reply, printing it in the specified format.
+ *
+ * The format will be read form $_REQUEST['format'].
+ *
+ * @param mixed $reply the reply to format
+ * @param string $xmlRoot the XML root element name (optionnal, default value is 'data').
+ * @param string $xmlChildren the XML children elements name (optionnal, will be deducted from the context if ommited, or, if not posssible, will be unknownNode)
+ */
+function api_output ($reply, $xmlRoot = null, $xmlChildren = null) {
+ $format = isset($_REQUEST['format']) ? $_REQUEST['format'] : 'preview';
+ switch ($format) {
+ case 'preview':
+ echo '<pre>';
+ print_r($reply);
+ echo '</pre>';
+ break;
+
+ case 'php':
+ echo serialize($reply);
+ break;
+
+ case 'wddx':
+ require_once('BeautyXML.class.php');
+ $bc = new BeautyXML();
+ echo $bc->format(wddx_serialize_value($reply));
+ break;
+
+ case 'json':
+ echo json_encode($reply);
+ break;
+
+ case 'xml':
+ require_once('BeautyXML.class.php');
+ $bc = new BeautyXML();
+ echo '<?xml version="1.0" encoding="utf-8"?>';
+ echo "\n";
+ echo $bc->format(toXml($reply, $xmlRoot, null, $xmlChildren));
+ break;
+
+ case 'string':
+ echo $reply;
+ break;
+
+ default:
+ echo "Unknown API format: $_GET[format]";
+ break;
+ }
+}
+
?>
\ No newline at end of file
diff --git a/includes/api/cerbere.php b/includes/api/cerbere.php
--- a/includes/api/cerbere.php
+++ b/includes/api/cerbere.php
@@ -1,70 +1,124 @@
<?php
-/*
- * Zed
- * (c) 2010, Dereckson, some rights reserved
- * Released under BSD license
+/**
+ * API security
+ *
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
*
- * API security
+ * This file provides a cerbere function, to assert the user is correctly
+ * authenticated in the API call.
*
+ * @package Zed
+ * @subpackage API
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
*/
+/**
+ * Determines if localhost calls could be passed.
+ *
+ * If true, any call from localhost is valid. Otherwise, normal security rules are applied.
+ */
define('ALLOW_LOCALHOST', false);
+
+/**
+ * Determines if error should be printed.
+ *
+ * If true, the error will be printed according the FORMAT_ERROR setting. Otherwise, a blank page will be served.
+ */
define('OUTPUT_ERROR', true);
+
+/**
+ * Determines if the error must be formatted.
+ *
+ * If true, any error will be sent to api_output ; otherwise, it will be printed as is.
+ */
define('FORMAT_ERROR', false);
-if (!defined('TABLE_API_KEYS')) define('TABLE_API_KEYS', 'api_keys');
+
+
+if (!defined('TABLE_API_KEYS')) {
+ /**
+ * The table where are located the API keys
+ */
+ define('TABLE_API_KEYS', 'api_keys');
+}
-/*
- * Checks if creditentials are okay and exits after a message error if not
+/**
+ * Checks if creditentials are okay and exits if not
+ *
+ * If the creditentials aren't valid, it will prints an error message if
+ * OUTPUT_ERROR is defined and true.
+ *
+ * This error message will be formatted through the api_output function if
+ * FORMAT_ERROR is defined and true ; otherwise, it will be print as is.
+ *
+ * To help debug, you can also define ALLOW_LOCALHOST. If this constant is
+ * defined and true, any call from localhost will be accepted, without checking
+ * the key.
+ *
+ * @see cerbere_die
*/
function cerbere () {
//If ALLOW_LOCALHOST is true, we allow 127.0.0.1 queries
//If you use one of your local IP in your webserver vhost like 10.0.0.3
//it could be easier to create yourself a test key
if (ALLOW_LOCALHOST && $_SERVER['REMOTE_ADDR'] == '127.0.0.1') {
return;
}
//No key, no authentication
if (!$guid = $_REQUEST['key']) {
cerbere_die('You must add creditentials to your request.');
}
//Authenticates user
global $db;
$guid = $db->sql_escape($guid);
$sql = "SELECT key_active FROM " . TABLE_API_KEYS .
" WHERE key_guid like '$guid'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't get key", '', __LINE__, __FILE__, $sql);
}
if ($row = $db->sql_fetchrow($result)) {
if ($row['key_active']) {
//key_hits++
$sql = "UPDATE " . TABLE_API_KEYS . " SET key_hits = key_hits + 1" .
" WHERE key_guid like '$guid'";
if (!$db->sql_query($sql))
message_die(SQL_ERROR, "Can't record api call", '', __LINE__, __FILE__, $sql);
} else {
cerbere_die("Key disabled.");
}
} else {
cerbere_die("Key doesn't exist.");
}
}
-/*
+/**
* Prints a message in raw or API format, then exits.
+ *
+ * The error message will be formatted through api_output if the constant
+ * FORMAT_ERROR is defined and true. Otherwise, it will be printed as is.
+ *
+ * @param string $message The error message to print
*/
function cerbere_die ($message) {
if (OUTPUT_ERROR) {
if (FORMAT_ERROR) {
api_output($message, 'error');
} else {
echo $message;
}
}
exit;
}
?>
\ No newline at end of file
diff --git a/includes/cache/cache.php b/includes/cache/cache.php
--- a/includes/cache/cache.php
+++ b/includes/cache/cache.php
@@ -1,48 +1,91 @@
<?php
-/*
- * Zed
- * (c) 2010, Dereckson, some rights reserved
- * Released under BSD license
- *
+/**
* Cache calling class.
*
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
+ *
+ * This file provides a calling class, which read the configuration, ensures
+ * the cache class for the cache engine given in config exists and initializes
+ * it.
+ *
+ * You'll find a sample of implementation in the CacheMemcached.
+ * @see CacheMemcached
+ *
+ * If no caching mechanism, a "blackhole" void cache will be used.
+ * @see CacheVoid.
+ *
+ * The class to call is determined from the following preference:
+ * <code>
+ * $Config['cache']['engine'] = 'memcached'; //will use CacheMemcached class.
+ * </code>
+ *
* 0.1 2010-07-06 22:45 Initial version [DcK]
- *
+ *
+ * @package Zed
+ * @subpackage Cache
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
*/
+/**
+ * Cache caller
+ */
class Cache {
- /*
+ /**
* Gets the cache instance, initializing it if needed
+ *
+ * The correct cache instance to initialize will be determined from the
+ * $Config['cache']['engine'] preference.
+ *
+ * The class cache to use will be Cache + (preference engine, capitalized)
+ *
+ * This method will creates an instance of the specified object,
+ * calling the load static method from this object class.
+ *
+ * Example:
+ * <code>
+ * $Config['cache']['engine'] = 'quux';
+ * $cache = Cache::load(); //Cache:load() will call CacheQuux:load();
+ * </code>
+ *
* @eturn Cache the cache instance, or null if nothing is cached
*/
static function load () {
global $Config;
if (
!array_key_exists('cache', $Config) ||
!array_key_exists('engine', $Config['cache'])
) {
//cache is not configured or engine is not specified
$engine = 'void';
} else {
//engine is specified in the configuration
$engine = $Config['cache']['engine'];
}
$engine_file = 'includes/cache/' . $engine . '.php';
$engine_class = 'Cache' . ucfirst($engine);
if (!file_exists($engine_file)) {
message_die(GENERAL_ERROR, "Can't initialize $engine cache engine.<br />$engine_file not found.", 'Cache');
}
require_once($engine_file);
if (!class_exists($engine_class)) {
message_die(GENERAL_ERROR, "Can't initialize $engine cache engine.<br />$engine_class class not found.", 'Cache');
}
return call_user_func(array($engine_class, 'load'));
}
}
?>
\ No newline at end of file
diff --git a/includes/cache/memcached.php b/includes/cache/memcached.php
--- a/includes/cache/memcached.php
+++ b/includes/cache/memcached.php
@@ -1,83 +1,112 @@
<?php
-/*
- * Zed
- * (c) 2010, Dereckson, some rights reserved
- * Released under BSD license
+
+/**
+ * Memcached cache.
+ *
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
*
* Cache class: memcached
*
* 0.1 2010-07-06 22:55 Initial version [DcK]
*
+ * @package Zed
+ * @subpackage Cache
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
+ */
+
+/**
+ * Memcached cache
+ *
* !!! This class uses the Memcached extension AND NOT the Memcache ext !!!!
*
* References:
- * - http://www.php.net/manual/en/book/memcached.php
- * - http://memcached.org
+ * @linkhttp://www.php.net/manual/en/book/memcached.php
+ * @lnk http://memcached.org
*
* This class implements a singleton pattern.
- *
*/
-
class CacheMemcached {
- /*
- * @var CacheMemcached the current cache instance
+ /**
+ * The current cache instance
+ *
+ * @var CacheMemcached
*/
static $instance = null;
- /*
- * @var Memcached the Memcached object
+ /**
+ * The Memcached object
+ *
+ * @var Memcached
*/
private $memcached = null;
- /*
+ /**
* Gets the cache instance, initializing it if needed
+ *
* @eturn Cache the cache instance, or null if nothing is cached
*/
static function load () {
//Checks extension is okay
if (!extension_loaded('memcached')) {
if (extension_loaded('memcache')) {
message_die(GENERAL_ERROR, "Can't initialize $engine cache engine.<br />PHP extension memcached not loaded.<br /><strong>!!! This class uses the Memcached extension AND NOT the Memcache extension (this one is loaded) !!!</strong>", 'Cache');
} else {
message_die(GENERAL_ERROR, "Can't initialize $engine cache engine.<br />PHP extension memcached not loaded.", 'Cache');
}
}
//Creates the Memcached object if needed
if (self::$instance === null) {
global $Config;
self::$instance = new CacheMemcached();
self::$instance->memcached = new Memcached();
self::$instance->memcached->addServer(
$Config['cache']['server'],
$Config['cache']['port']
);
}
return self::$instance;
}
- /*
+ /**
* Gets the specified key's data
+ *
+ * @param string $key the key to fetch
+ * @return mixed the data at the specified key
*/
function get ($key) {
return $this->memcached->get($key);
}
- /*
+ /**
* Sets the specified data at the specified key
- */
+ *
+ * @param string $key the key where to store the specified data
+ * @param mixed $value the data to store
+ */
function set ($key, $value) {
return $this->memcached->set($key, $value);
}
- /*
+ /**
* Deletes the specified key's data
+ *
+ * @param string $key the key to delete
*/
function delete ($key) {
return $this->memcached->delete($key);
}
}
?>
\ No newline at end of file
diff --git a/includes/cache/void.php b/includes/cache/void.php
--- a/includes/cache/void.php
+++ b/includes/cache/void.php
@@ -1,54 +1,81 @@
<?php
-/*
- * Zed
- * (c) 2010, Dereckson, some rights reserved
- * Released under BSD license
+
+/**
+ * "Blackhole" void cache.
+ *
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
*
* Cache class: void
*
* 0.1 2010-07-06 22:55 Initial version [DcK]
*
- * This class doesn't cache information, it'a void wrapper
+ * @package Zed
+ * @subpackage Cache
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
+ */
+
+/**
+ * "blackhole" void cache
+ *
+ * This class doesn't cache information, it'a void wrapper
* get will always return null
* set and delete do nothing
*
+ * It will be used by default if no cache is specified.
+ *
* This class implements a singleton pattern.
- *
*/
-
class CacheVoid {
- /*
+ /**
* @var CacheVoid the current cache instance
*/
static $instance = null;
- /*
+ /**
* Gets the cache instance, initializing it if needed
+ *
* @eturn Cache the cache instance, or null if nothing is cached
*/
static function load () {
if (self::$instance === null) {
self::$instance = new CacheVoid();
}
return self::$instance;
}
- /*
+ /**
* Gets the specified key's data
+ *
+ * @param string $key the key to fetch
+ * @return mixed the data at the specified key
*/
function get ($key) {
return null;
}
- /*
+ /**
* Sets the specified data at the specified key
+ *
+ * @param string $key the key where to store the specified data
+ * @param mixed $value the data to store
*/
function set ($key, $value) { }
- /*
+ /**
* Deletes the specified key's data
+ *
+ * @param string $key the key to delete
*/
function delete ($key) { }
}
?>
\ No newline at end of file
diff --git a/includes/geo/body.php b/includes/geo/body.php
--- a/includes/geo/body.php
+++ b/includes/geo/body.php
@@ -1,148 +1,174 @@
<?php
-/*
- * Geo body class
+/**
+ * Geo body class.
+ *
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
+ *
+ * A 3D grid of objects
*
* 0.1 2010-01-27 21:51 Autogenerated by Pluton Scaffolding
*
- * @package Zed
- * @subpackage Geo
- * @copyright Copyright (c) 2010, Dereckson
- * @license Released under BSD license
- * @version 0.1
- *
+ * @package Zed
+ * @subpackage Geo
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
+ */
+
+/**
+ * Geo body class
*/
class GeoBody {
public $code;
public $name;
public $hypership;
public $asteroid;
public $moon;
public $planet;
public $star;
public $orbital;
public $hidden;
public $location;
public $description;
public $lastError;
- /*
- * Initializes a new instance
+ /**
+ * Initializes a new instance
+ *
* @param int $code the primary key
*/
function __construct ($code = null) {
if ($code) {
$this->code = $code;
$this->load_from_database();
}
}
- /*
- * Loads the object body (ie fill the properties) from the $_POST array
+ /**
+ * Loads the object body (ie fill the properties) from the $_POST array
+ *
+ * @param bool $readBoolean if false, don't read any form item matching a boolean field to avoid to set it to false if there are absent from a form.
*/
function load_from_form ($readBoolean = true) {
if (array_key_exists('name', $_POST)) $this->name = $_POST['name'];
if ($readBoolean) {
if (array_key_exists('hypership', $_POST)) $this->hypership = $_POST['hypership'];
if (array_key_exists('star', $_POST)) $this->start = $_POST['star'];
if (array_key_exists('asteroid', $_POST)) $this->hypership = $_POST['asteroid'];
if (array_key_exists('moon', $_POST)) $this->start = $_POST['moon'];
if (array_key_exists('planet', $_POST)) $this->start = $_POST['planet'];
if (array_key_exists('orbital', $_POST)) $this->start = $_POST['orbital'];
if (array_key_exists('hidden', $_POST)) $this->start = $_POST['hidden'];
}
if (array_key_exists('location', $_POST)) $this->location = $_POST['location'];
if (array_key_exists('description', $_POST)) $this->description = $_POST['description'];
}
- /*
+ /**
* Loads the object body (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$sql = "SELECT * FROM " . TABLE_BODIES . " WHERE body_code = '" . $this->code . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query geo_bodies", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "body unkwown: " . $this->code;
return false;
}
$this->name = $row['body_name'];
$this->location = $row['body_location'];
$this->description = $row['body_description'];
if ($row['body_status']) {
$flags = explode(',', $row['body_status']);
foreach ($flags as $flag) {
$this->$flag = true;
}
}
return true;
}
- /*
- * Gets status
+ /**
+ * Gets the status field
+ *
+ * @return string the status field value (e.g. "asteroid,hidden")
*/
function get_status () {
$flags = array('hypership','asteroid','moon','planet','star','orbital','hidden');
foreach ($flags as $flag) {
if ($this->$flag) {
$status[] = $flag;
}
}
return implode(',', $status);
}
- /*
- * Gets the kind of place the body is (e.g. asteroid)
+ /**
+ * Gets the kind of place the body is (e.g. asteroid)
+ *
+ * @return string the kind of place
*/
function kind () {
//If a location can be described by 2 flags, order the relevant flags list
//by priority, as it'll return the first trigerred.
//e.g. a moon converted in hypership will be "hypership" and not "moon".
$relevantFlags = array('hypership','asteroid','moon','planet','star','orbital');
foreach ($relevantFlags as $flag) {
if ($this->$flag) {
return $flag;
}
}
return "";
}
-
+
+ /**
+ * Gets the name of the body, as a string representation of the object
+ *
+ * @return string the name of the body
+ */
function __toString () {
return $this->name;
}
- /*
+ /**
* Saves to database
*/
function save_to_database () {
global $db;
$code = $this->code ? "'" . $db->sql_escape($this->code) . "'" : 'NULL';
$name = $db->sql_escape($this->name);
$status = get_status();
$location = $db->sql_escape($this->location);
$description = $db->sql_escape($this->description);
//Updates or inserts
$sql = "REPLACE INTO " . TABLE_BODIES . " (`body_code`, `body_name`, `body_status`, `body_location`, `body_description`) VALUES ($code, '$name', '$status', '$location', '$description')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
if (!$code) {
//Gets new record code value
$this->code = $db->sql_nextid();
}
}
}
?>
\ No newline at end of file
diff --git a/includes/geo/galaxy.php b/includes/geo/galaxy.php
--- a/includes/geo/galaxy.php
+++ b/includes/geo/galaxy.php
@@ -1,53 +1,85 @@
<?php
-/*
- * Geo galaxy class
+/**
+ * Geo galaxy class.
+ *
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
+ *
* A 3D grid of objects
*
* 0.1 2010-02-08 14:02 DcK
*
- * @package Zed
- * @subpackage Geo
- * @copyright Copyright (c) 2010, Dereckson
- * @license Released under BSD license
- * @version 0.1
+ * @package Zed
+ * @subpackage Geo
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
+ */
+
+/**
+ * Geo galaxy class
*
+ * This class provides methods to convert coordinate polars.
+ *
+ * @todo add a cartesian_to_polar method
+ * @todo add a static method to get a grid of all the galaxy objects, with their x y z representation ; that will be useful to add in API, for a javascript galaxy viewer.
+ *
+ * @todo create a unit testing file dev/tests/GeoGalaxyTest.php
+ * @todo add unit testing for the normalize_angle method in dev/tests/GeoGalaxyTest.php
+ * @todo add unit testing for the polar_to_cartesian method
*/
class GeoGalaxy {
/*
* ----------------------------------------------------------------------- *
* Helper methods - math
* ----------------------------------------------------------------------- *
*/
- /*
- * Normalizes an angle, so 0 < angle < 2 PI
- * @param $angle angle in radians (use deg2rad() if you've degrees)
- *
+ /**
+ * Normalizes an angle, so 0 =< angle < 2 PI
+ *
+ * @param float $angle angle in radians (use deg2rad() if you've degrees)
+ * @return an angle in the 0 =< angle < 2 PI interval
*/
+ static function normalize_angle ($angle) {
+ while ($angle < 0) {
+ $angle += 2 * M_PI;
+ }
+ while ($angle >= 2 * M_PI) {
+ $angle -= 2 * M_PI;
+ }
+ return $angle;
+ }
/*
* Converts polar coordinates in cartesian x y coordinates
* @param float $angle angle in radians (use deg2rad() if you've degrees)
* @param float $height height
* @return array an array of 2 float items: x, y
*/
static function polar_to_cartesian ($angle, $height) {
//A story of numbers
if ($height < 0) {
- //Adds 180° and gets absolute value
+ //Adds 180° and gets absolute value
$height *= -1;
$angle + M_PI;
}
$x = abs(sin($angle)) . $height;
$y = abs(cos($angle)) . $height;
//And now, the sign
//Returns our coordinates
return array($x, $y);
}
}
\ No newline at end of file
diff --git a/includes/geo/location.php b/includes/geo/location.php
--- a/includes/geo/location.php
+++ b/includes/geo/location.php
@@ -1,368 +1,432 @@
-<?php
-
-require_once('body.php');
-require_once('place.php');
-require_once('point3D.php');
-require_once('includes/objects/ship.php');
-
-/*
- * Geo location class
- *
- * 0.1 2010-01-28 18:52 DcK
- *
- * @package Zed
- * @subpackage Geo
- * @copyright Copyright (c) 2010, Dereckson
- * @license Released under BSD license
- * @version 0.1
- *
- * @todo initializes $point3D from $body or $ship own locations;
- *
- */
-class GeoLocation {
- private $data;
-
- /*
- * @var GeoBody a body object
- */
- public $body = null;
-
- /*
- * @var GeoPlace a place object
- */
- public $place = null;
-
- /*
- * @var GeoPoint3D a point identified by x, y, z coordinates
- */
- public $point3D = null;
-
- /*
- * @var Ship a ship object
- */
- public $ship = null;
-
- function __construct ($global = null, $local = null) {
- if (!$global) {
- $this->data = array();
- } elseif (preg_match("/[BS][0-9]{5}[0-9]{3}/", $global)) {
- $this->data[0] = $global;
- } elseif (preg_match("/[BS][0-9]{5}/", $global)) {
- $this->data[0] = $global;
- } elseif (preg_match("/^xyz\:/", $global)) {
- $coords = sscanf($global, "xyz: [%d, %d, %d]");
- if (count($coords) == 3) {
- $this->data[0] = $global;
- } else {
- throw new Exception("Invalid expression: $global");
- }
- } else {
- global $db;
- $name = $db->sql_escape($global);
- $sql = "SELECT location_code FROM " . TABLE_LOCATIONS . " WHERE location_name LIKE '$name'";
- $code = $db->sql_query_express($sql);
- if ($code) {
- $this->data[0] = $code;
- return;
- }
- throw new Exception("Invalid expression: $global");
- }
-
- //TODO: handle $local in a better way: from the global location, gets
- //a local location handler. Or a some inheriance, like a class
- //HypershipGeoLocation extending GeoLocation.
- if ($local !== null) $this->data[1] = $local;
-
- $this->load_classes();
- }
-
- /*
- * Gets $place, $body and $ship instances if they're needed
- */
- function load_classes () {
- //No data, no class to load
- if (!count($this->data))
- return;
-
- //Loads global classes
- $global = $this->data[0];
- $code = substr($global, 1, 5);
- switch ($global[0]) {
- case 'B':
- switch (strlen($global)) {
- case 9:
- $this->place = GeoPlace::from_code($global);
-
- case 6:
- $this->body = new GeoBody($code);
- break;
- }
- break;
-
- case 'S':
- $this->ship = new Ship($code);
- break;
-
- case 'x':
- $coords = sscanf($global, "xyz: [%d, %d, %d]");
- if (count($coords) == 3) {
- $this->point3D = new GeoPoint3D($coords[0], $coords[1], $coords[2]);
- }
- break;
- }
- }
-
- /*
- * Magic method called when a unknown property is get.
- * Handles $global, $local, $type, $body_code, $ship_code, $place_code,
- * $body_kind, $containsGlobalLocation, $containsLocalLocation.
- */
- function __get ($variable) {
- switch ($variable) {
- /* main variables */
-
- case 'global':
- return $this->data[0];
- break;
-
- case 'local':
- return $this->data[1];
- break;
-
- /* global location */
-
- case 'type':
- return $this->data[0][0];
-
- case 'body_code':
- if ($this->data[0][0] == 'B') {
- return substr($this->data[0], 1, 5);
- }
- return null;
-
- case 'place_code':
- if ($this->data[0][0] == 'B') {
- return substr($this->data[0], 6, 3);
- }
- return null;
-
- case 'ship_code':
- if ($this->data[0][0] == 'S') {
- return substr($this->data[0], 1, 5);
- }
- return null;
-
- case 'body_kind':
- if ($this->data[0][0] == 'B' && $this->body != null) {
- if ($kind = $this->body->kind()) {
- return $kind;
- }
- } elseif ($this->data[0][0] == 'S') {
- return 'ship';
- }
- return 'place';
-
- case 'containsGlobalLocation':
- return count($this->data) > 0;
-
- case 'containsLocalLocation':
- return count($this->data) > 1;
-
- default:
- throw new Exception("Unknown variable: $variable");
- break;
- }
- }
-
- /*
- * Checks if the place exists
- *
- * @return boolean true if the place exists ; false otherwise
- * @todo handles alias
- */
- function exists () {
- $n = count($this->data);
-
- //If not defined, it doesn't exist
- if ($n == 0) return false;
-
- //Checks global location
- switch ($this->data[0][0]) {
- case 'B':
- switch (strlen($this->data[0])) {
- case 9:
- if (!$place = GeoPlace::from_code($this->data[0]))
- return false;
- break;
-
- case 6:
- $body = new GeoBody(substr($this->data[0], 1));
- if ($body->lastError) return false;
- break;
-
- default:
- message_die(GENERAL_ERROR, "Invalid global location expression size: " . $this->data[0], "GeoLocation exists method", __LINE__, __FILE__);
-
- }
- break;
-
- case 'S':
- $ship = new Ship(substr($this->data[0], 1));
- if ($body->lastError) return false;
- break;
-
- default:
- message_die(GENERAL_ERROR, "Invalid global location expression size: " . $this->data[0], "GeoLocation exists method", __LINE__, __FILE__);
- return false;
- }
-
-
- if ($n > 1) {
- if (!isset($place)) {
- message_die(GENERAL_ERROR, "Can't check if a local place exists for the following location: " . $this->data[0], "GeoLocation exists method", __LINE__, __FILE__);
- }
- if (!$place->is_valid_local_location($this->data[1])) {
- return false;
- }
- }
-
- return true;
- }
-
- /*
- * Checks if the place is equals at the specified expression or place
- *
- * @return boolean true if the places are equals ; otherwise, false
- */
- function equals ($expression) {
- //Are global location equals?
-
- //TODO: creates a better set of rules to define when 2 locations are equa l.
- if (is_a($expression, 'GeoLocation')) {
- if (!$this->equals($expression->data[0])) {
- return false;
- }
- if (count($expression->data) + count($this->data) > 2) {
- return $expression->data[1] == $this->data[1];
- }
- }
-
- if ($expression == $this->data[0]) return true;
-
- $n1 = strlen($expression);
- $n2 = strlen($this->data[0]);
-
- if ($n1 > $n2) {
- return substr($expression, 0, $n2) == $this->data[0];
- }
-
- return false;
- }
-
- /*
- * Represents the current location instance as a string
- *
- * @return string a string representing the current location
- */
- function __toString () {
- if (!$this->data[0])
- return "";
-
- switch ($this->data[0][0]) {
- case 'S':
- $ship = new Ship($this->ship_code);
- $location[] = $ship->name;
- break;
-
- case 'B':
- $body = new GeoBody($this->body_code);
- $location[] = $body->name ? $body->name : lang_get('UnknownBody');
-
- if (strlen($this->data[0]) == 9) {
- $place = GeoPlace::from_code($this->data[0]);
- $location[] = $place->name ? $place->name : lang_get('UnknownPlace');
- }
- break;
-
- default:
- message_die(GENERAL_ERROR, "Unknown location identifier: $type.<br />Expected: B or S.");
- }
-
- return implode(", ", array_reverse($location));
- }
-
-
- /*
- * Magic method called when a unknown property is set.
- * Handles $global, $local, $type, $body_code, $ship_code, $place_code
- */
- function __set ($variable, $value) {
- switch ($variable) {
- /* main variables */
-
- case 'global':
- $this->data[0] = $value;
- break;
-
- case 'local':
- $this->data[1] = $value;
- break;
-
- /* global location */
-
- case 'type':
- if ($value == 'B' || $value == 'S') {
- if (!$this->data[0]) {
- $this->data[0] = $value;
- } else {
- $this->data[0][0] = $value;
- }
- }
- break;
-
- case 'body_code':
- if (preg_match("/[0-9]{1,5}/", $value)) {
- $value = sprintf("%05d", $value);
- if (!$this->data[0]) {
- $this->data[0] = "B" . $value;
- return;
- } elseif ($this->data[0][0] == 'B') {
- $this->data[0] = "B" . $value . substr($this->data[0], 6);
- return;
- }
- throw new Exception("Global location isn't a body.");
- }
- throw new Exception("$value isn't a valid body code");
-
- case 'ship_code':
- if (preg_match("/[0-9]{1,5}/", $value)) {
- $value = sprintf("%05d", $value);
- if (!$this->data[0]) {
- $this->data[0] = "S" . $value;
- return;
- } elseif ($this->data[0][0] == 'S') {
- $this->data[0] = "S" . $value . substr($this->data[0], 6);
- return;
- }
- throw new Exception("Global location isn't a ship.");
- }
- throw new Exception("$value isn't a valid ship code");
-
- case 'place_code':
- if (!preg_match("/[0-9]{1,3}/", $value)) {
- throw new Exception("$value isn't a valid place code");
- }
- $value = sprintf("%03d", $value);
- if ($this->data[0][0] == 'B') {
- $this->data[0] = substr($this->data[0], 0, 6) . $value;
- }
- throw new Exception("Global location isn't a body.");
-
- default:
- throw new Exception("Unknown variable: $variable");
- break;
- }
- }
-}
-
-?>
+<?php
+
+/**
+ * Geo location class.
+ *
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
+ *
+ * 0.1 2010-01-28 18:52 DcK
+ *
+ * @package Zed
+ * @subpackage Geo
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
+ */
+
+require_once('body.php');
+require_once('place.php');
+require_once('point3D.php');
+require_once('includes/objects/ship.php');
+
+/**
+ * Geo location class
+ *
+ * This class contains properties to get, set or compare a location and
+ * explore the geo classes linked to.
+ *
+ * It quickly allow to parse through the location classes in templates and
+ * controllers.
+ *
+ * @todo initializes $point3D from $body or $ship own locations;
+ * @todo improve GeoLocation documentation (especially magic properties)
+ */
+class GeoLocation {
+ /**
+ * An array of strings containing location data.
+ *
+ * In the current class implementation,
+ * the first element is the global location
+ * and the second element is the local location.
+ *
+ * @var Aray
+ */
+ private $data;
+
+ /**
+ * A body object
+ *
+ * It contains a GeoBody value when the global location is a body
+ * ie if $this->data[0][0] == 'B'
+ *
+ * Otherwise, its value is null.
+ *
+ * @var GeoBody
+ */
+ public $body = null;
+
+ /**
+ * A place object
+ *
+ * It contains a GeoPlacevalue when the global location is a place
+ * ie if $this->data[0][0] == 'B' && strlen($this->data[0]) == 9
+ *
+ * Otherwise, its value is null.
+ *
+ * @var GeoPlace
+ */
+ public $place = null;
+
+ /**
+ * A point identified by x, y, z coordinates
+ *
+ * @var GeoPoint3D
+ */
+ public $point3D = null;
+
+ /**
+ * A ship object
+ *
+ * It contains a Ship value when the global location is a ship
+ * ie if $this->data[0][0] == 'S'
+ *
+ * Otherwise, its value is null.
+ *
+ * @var Ship
+ */
+ public $ship = null;
+
+ /**
+ * Initializes a new location instance
+ *
+ * @param string $global the global location
+ * @param string local the locallocation
+ *
+ * @todo improve local location handling
+ */
+ function __construct ($global = null, $local = null) {
+ if (!$global) {
+ $this->data = array();
+ } elseif (preg_match("/[BS][0-9]{5}[0-9]{3}/", $global)) {
+ $this->data[0] = $global;
+ } elseif (preg_match("/[BS][0-9]{5}/", $global)) {
+ $this->data[0] = $global;
+ } elseif (preg_match("/^xyz\:/", $global)) {
+ $coords = sscanf($global, "xyz: [%d, %d, %d]");
+ if (count($coords) == 3) {
+ $this->data[0] = $global;
+ } else {
+ throw new Exception("Invalid expression: $global");
+ }
+ } else {
+ global $db;
+ $name = $db->sql_escape($global);
+ $sql = "SELECT location_code FROM " . TABLE_LOCATIONS . " WHERE location_name LIKE '$name'";
+ $code = $db->sql_query_express($sql);
+ if ($code) {
+ $this->data[0] = $code;
+ return;
+ }
+ throw new Exception("Invalid expression: $global");
+ }
+
+ //TODO: handle $local in a better way: from the global location, gets
+ //a local location handler. Or a some inheriance, like a class
+ //HypershipGeoLocation extending GeoLocation.
+ if ($local !== null) $this->data[1] = $local;
+
+ $this->load_classes();
+ }
+
+ /**
+ * Gets $place, $body and $ship instances if they're needed
+ */
+ function load_classes () {
+ //No data, no class to load
+ if (!count($this->data))
+ return;
+
+ //Loads global classes
+ $global = $this->data[0];
+ $code = substr($global, 1, 5);
+ switch ($global[0]) {
+ case 'B':
+ switch (strlen($global)) {
+ case 9:
+ $this->place = GeoPlace::from_code($global);
+
+ case 6:
+ $this->body = new GeoBody($code);
+ break;
+ }
+ break;
+
+ case 'S':
+ $this->ship = new Ship($code);
+ break;
+
+ case 'x':
+ $coords = sscanf($global, "xyz: [%d, %d, %d]");
+ if (count($coords) == 3) {
+ $this->point3D = new GeoPoint3D($coords[0], $coords[1], $coords[2]);
+ }
+ break;
+ }
+ }
+
+ /**
+ * Magic method called when a unknown property is get.
+ *
+ * Handles $global, $local, $type, $body_code, $ship_code, $place_code,
+ * $body_kind, $containsGlobalLocation, $containsLocalLocation.
+ */
+ function __get ($variable) {
+ switch ($variable) {
+ /* main variables */
+
+ case 'global':
+ return $this->data[0];
+ break;
+
+ case 'local':
+ return $this->data[1];
+ break;
+
+ /* global location */
+
+ case 'type':
+ return $this->data[0][0];
+
+ case 'body_code':
+ if ($this->data[0][0] == 'B') {
+ return substr($this->data[0], 1, 5);
+ }
+ return null;
+
+ case 'place_code':
+ if ($this->data[0][0] == 'B') {
+ return substr($this->data[0], 6, 3);
+ }
+ return null;
+
+ case 'ship_code':
+ if ($this->data[0][0] == 'S') {
+ return substr($this->data[0], 1, 5);
+ }
+ return null;
+
+ case 'body_kind':
+ if ($this->data[0][0] == 'B' && $this->body != null) {
+ if ($kind = $this->body->kind()) {
+ return $kind;
+ }
+ } elseif ($this->data[0][0] == 'S') {
+ return 'ship';
+ }
+ return 'place';
+
+ case 'containsGlobalLocation':
+ return count($this->data) > 0;
+
+ case 'containsLocalLocation':
+ return count($this->data) > 1;
+
+ default:
+ throw new Exception("Unknown variable: $variable");
+ break;
+ }
+ }
+
+ /**
+ * Checks if the place exists
+ *
+ * @return bool true if the place exists ; otherwise, false.
+ *
+ * @todo handles alias
+ */
+ function exists () {
+ $n = count($this->data);
+
+ //If not defined, it doesn't exist
+ if ($n == 0) return false;
+
+ //Checks global location
+ switch ($this->data[0][0]) {
+ case 'B':
+ switch (strlen($this->data[0])) {
+ case 9:
+ if (!$place = GeoPlace::from_code($this->data[0]))
+ return false;
+ break;
+
+ case 6:
+ $body = new GeoBody(substr($this->data[0], 1));
+ if ($body->lastError) return false;
+ break;
+
+ default:
+ message_die(GENERAL_ERROR, "Invalid global location expression size: " . $this->data[0], "GeoLocation exists method", __LINE__, __FILE__);
+
+ }
+ break;
+
+ case 'S':
+ $ship = new Ship(substr($this->data[0], 1));
+ if ($body->lastError) return false;
+ break;
+
+ default:
+ message_die(GENERAL_ERROR, "Invalid global location expression size: " . $this->data[0], "GeoLocation exists method", __LINE__, __FILE__);
+ return false;
+ }
+
+
+ if ($n > 1) {
+ if (!isset($place)) {
+ message_die(GENERAL_ERROR, "Can't check if a local place exists for the following location: " . $this->data[0], "GeoLocation exists method", __LINE__, __FILE__);
+ }
+ if (!$place->is_valid_local_location($this->data[1])) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Checks if the place is equals at the specified expression or place
+ *
+ * @return bool true if the places are equals ; otherwise, false.
+ *
+ * @todo Create a better set of rules to define when 2 locations are equall.
+ */
+ function equals ($expression) {
+ //Are global location equals?
+
+ //TODO: create a better set of rules to define when 2 locations are equa l.
+ if (is_a($expression, 'GeoLocation')) {
+ if (!$this->equals($expression->data[0])) {
+ return false;
+ }
+ if (count($expression->data) + count($this->data) > 2) {
+ return $expression->data[1] == $this->data[1];
+ }
+ }
+
+ if ($expression == $this->data[0]) return true;
+
+ $n1 = strlen($expression);
+ $n2 = strlen($this->data[0]);
+
+ if ($n1 > $n2) {
+ return substr($expression, 0, $n2) == $this->data[0];
+ }
+
+ return false;
+ }
+
+ /**
+ * Represents the current location instance as a string
+ *
+ * @return string a string representing the current location
+ */
+ function __toString () {
+ if (!$this->data[0])
+ return "";
+
+ switch ($this->data[0][0]) {
+ case 'S':
+ $ship = new Ship($this->ship_code);
+ $location[] = $ship->name;
+ break;
+
+ case 'B':
+ $body = new GeoBody($this->body_code);
+ $location[] = $body->name ? $body->name : lang_get('UnknownBody');
+
+ if (strlen($this->data[0]) == 9) {
+ $place = GeoPlace::from_code($this->data[0]);
+ $location[] = $place->name ? $place->name : lang_get('UnknownPlace');
+ }
+ break;
+
+ default:
+ message_die(GENERAL_ERROR, "Unknown location identifier: $type.<br />Expected: B or S.");
+ }
+
+ return implode(", ", array_reverse($location));
+ }
+
+
+ /**
+ * Magic method called when a unknown property is set.
+ *
+ * Handles $global, $local, $type, $body_code, $ship_code, $place_code
+ */
+ function __set ($variable, $value) {
+ switch ($variable) {
+ /* main variables */
+
+ case 'global':
+ $this->data[0] = $value;
+ break;
+
+ case 'local':
+ $this->data[1] = $value;
+ break;
+
+ /* global location */
+
+ case 'type':
+ if ($value == 'B' || $value == 'S') {
+ if (!$this->data[0]) {
+ $this->data[0] = $value;
+ } else {
+ $this->data[0][0] = $value;
+ }
+ }
+ break;
+
+ case 'body_code':
+ if (preg_match("/[0-9]{1,5}/", $value)) {
+ $value = sprintf("%05d", $value);
+ if (!$this->data[0]) {
+ $this->data[0] = "B" . $value;
+ return;
+ } elseif ($this->data[0][0] == 'B') {
+ $this->data[0] = "B" . $value . substr($this->data[0], 6);
+ return;
+ }
+ throw new Exception("Global location isn't a body.");
+ }
+ throw new Exception("$value isn't a valid body code");
+
+ case 'ship_code':
+ if (preg_match("/[0-9]{1,5}/", $value)) {
+ $value = sprintf("%05d", $value);
+ if (!$this->data[0]) {
+ $this->data[0] = "S" . $value;
+ return;
+ } elseif ($this->data[0][0] == 'S') {
+ $this->data[0] = "S" . $value . substr($this->data[0], 6);
+ return;
+ }
+ throw new Exception("Global location isn't a ship.");
+ }
+ throw new Exception("$value isn't a valid ship code");
+
+ case 'place_code':
+ if (!preg_match("/[0-9]{1,3}/", $value)) {
+ throw new Exception("$value isn't a valid place code");
+ }
+ $value = sprintf("%03d", $value);
+ if ($this->data[0][0] == 'B') {
+ $this->data[0] = substr($this->data[0], 0, 6) . $value;
+ }
+ throw new Exception("Global location isn't a body.");
+
+ default:
+ throw new Exception("Unknown variable: $variable");
+ break;
+ }
+ }
+}
+
+?>
diff --git a/includes/geo/place.php b/includes/geo/place.php
--- a/includes/geo/place.php
+++ b/includes/geo/place.php
@@ -1,182 +1,216 @@
<?php
-/*
- * place class
+/**
+ * Geo place class.
+ *
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
*
* 0.1 2010-01-28 01:48 Autogenerated by Pluton Scaffolding
*
- * @package Zed
- * @subpackage Geo
- * @copyright Copyright (c) 2010, Dereckson
- * @license Released under BSD license
- * @version 0.1
- *
+ * @package Zed
+ * @subpackage Geo
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
*/
-//By default, local_location format is an (x, y, z) expression
-//The local_location format is a PCRE regular expression
+/**
+ * Default local location format
+ *
+ * The local_location format is a PCRE regular expression
+ *
+ * By default, local_location format is an (x, y, z) expression
+ */
define('LOCATION_LOCAL_DEFAULT_FORMAT', '/^\([0-9]+( )*,( )*[0-9]+( )*,( )*[0-9]+\)$/');
+/**
+ * Geo place
+ *
+ * A place is a city or a hypership district.
+ *
+ * It's identified by a 9 chars geocode like B0001001.
+ * The 5 first chars indicates the body (class GeoBody) where the place is and
+ * the 3 last digits is the place number.
+ *
+ * This class maps the geo_places table.
+ */
class GeoPlace {
public $id;
public $body_code;
public $code;
public $name;
public $description;
public $location_local_format;
public $start;
public $hidden;
- /*
+ /**
* Initializes a new instance
+ *
* @param int $id the primary key
*/
function __construct ($id = null) {
if ($id) {
$this->id = $id;
$this->load_from_database();
}
}
- /*
+ /**
* Loads the object place (ie fill the properties) from the $_POST array
*/
function load_from_form () {
if (array_key_exists('body_code', $_POST)) $this->body_code = $_POST['body_code'];
if (array_key_exists('code', $_POST)) $this->code = $_POST['code'];
if (array_key_exists('name', $_POST)) $this->name = $_POST['name'];
if (array_key_exists('description', $_POST)) $this->description = $_POST['description'];
if (array_key_exists('status', $_POST)) $this->status = $_POST['status'];
if (array_key_exists('location_local_format', $_POST)) $this->location_local_format = $_POST['location_local_format'];
}
- /*
+ /**
* Loads the object place (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$sql = "SELECT * FROM geo_places WHERE place_id = '" . $this->id . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query geo_places", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "place unkwown: " . $this->id;
return false;
}
$this->body_code = $row['body_code'];
$this->code = $row['place_code'];
$this->name = $row['place_name'];
$this->description = $row['place_description'];
$this->location_local_format = $row['location_local_format'];
//Explodes place_status SET field in boolean variables
if ($row['place_status']) {
$flags = explode(',', $row['place_status']);
foreach ($flags as $flag) {
$this->$flag = true;
}
}
return true;
}
- /*
+ /**
* Gets status field value
+ *
+ * @return string the status field value (e.g. "requiresPTA,default")
*/
function get_status () {
$flags = array('start', 'hidden');
foreach ($flags as $flag) {
if ($this->$flag == true) {
$status[] = $flag;
}
}
return implode(',', $status);
}
- /*
+ /**
* Saves to database
*/
function save_to_database () {
global $db;
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$body_code = $db->sql_escape($this->body_code);
$code = $db->sql_escape($this->code);
$name = $db->sql_escape($this->name);
$description = $db->sql_escape($this->description);
$status = $this->get_status();
$location_local_format = $db->sql_escape($this->location_local_format);
//Updates or inserts
$sql = "REPLACE INTO geo_places (`place_id`, `body_code`, `place_code`, `place_name`, `place_description`, `place_status`, `location_local_format`) VALUES ($id, '$body_code', '$code', '$name', '$description', '$status', '$location_local_format')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
if (!$id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
}
- /*
+ /**
* Determines if the specified local location looks valid
+ *
+ * @param string $local_location the local location
* @return boolean true if the specified local location looks valid ; otherwise, false.r
*/
function is_valid_local_location ($local_location) {
$format = $this->location_local_format ? $this->location_local_format : LOCATION_LOCAL_DEFAULT_FORMAT;
return preg_match($format, $local_location) > 0;
}
- /*
+ /**
* Gets a string representation of the current place
+ *
* @return string A Bxxxxxyyy string like B00001001, which represents the current place.
*/
function __tostring () {
return 'B' . $this->body_code . $this->code;
}
- /*
+ /**
* Creates a Place instance, from the specified body/place code
+ *
* @param $code the place's code
* @return GeoPlace the place instance
*/
static function from_code ($code) {
global $db;
$sql = "SELECT * FROM geo_places WHERE CONCAT('B', body_code, place_code) LIKE '$code'";
if (!$result = $db->sql_query($sql)) message_die(SQL_ERROR, "Unable to query geo_places", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
return null;
}
$place = new GeoPlace();
$place->id = $row['place_id'];
$place->body_code = $row['body_code'];
$place->code = $row['place_code'];
$place->name = $row['place_name'];
$place->description = $row['place_description'];
$place->location_local_format = $row['location_local_format'];
//Explodes place_status SET field in boolean variables
if ($row['place_status']) {
$flags = explode(',', $row['place_status']);
foreach ($flags as $flag) {
$place->$flag = true;
}
}
return $place;
}
- /*
+ /**
* Gets a start location
+ *
+ * @return string The global location code of a start location
+ *
* @TODO sql optimisation (query contains ORDER BY RAND())
*/
static function get_start_location () {
global $db;
$sql = "SELECT CONCAT('B', body_code, place_code) FROM geo_places WHERE FIND_IN_SET('start', place_status) > 0 ORDER BY rand() LIMIT 1";
return $db->sql_query_express($sql);
}
}
?>
\ No newline at end of file
diff --git a/includes/geo/point3D.php b/includes/geo/point3D.php
--- a/includes/geo/point3D.php
+++ b/includes/geo/point3D.php
@@ -1,68 +1,114 @@
-<?php
-
-/*
- * Geo point 3D class
- *
- * 0.1 2010-02-23 14:14 DcK
- *
- * @package Zed
- * @subpackage Geo
- * @copyright Copyright (c) 2010, Dereckson
- * @license Released under BSD license
- * @version 0.1
- *
- */
-class GeoPoint3D implements IteratorAggregate {
- //
- // x, y, z public properties
- //
-
- /*
- * @var integer the x coordinate
- */
- public $x;
-
- /*
- * @var integer the y coordinate
- */
- public $y;
-
- /*
- * @var integer the z coordinate
- */
- public $z;
-
- //
- // constructor / toString
- //
-
- /*
- * Initializes a new instance of GeoPoint3D class
- */
- function __construct ($x, $y, $z) {
- $this->x = $x;
- $this->y = $y;
- $this->z = $z;
- }
-
- /*
- * Returns a xyz: [x, y, z] string representation of the point coordinates
- */
- function __toString () {
- return sprintf("xyz: [%d, %d, %d]", $this->x, $this->y, $this->z);
- }
-
- //
- // Implementing IteratorAggregate
- //
-
- /*
- * Retrieves class iterator. It traverses x, y and z.
- * @return Traversable the iterator
- */
- function getIterator () {
- return new ArrayIterator($this);
- }
-}
-
+<?php
+
+/**
+ * Geo point 3D class.
+ *
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
+ *
+ * 0.1 2010-02-23 14:14 DcK
+ *
+ * @package Zed
+ * @subpackage Geo
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
+ */
+
+/**
+ * Geo point 3D class.
+ *
+ * This class reprensents a x, y, z point.
+ *
+ * It implements IteratorAggregate to allow the foreach instruction
+ * on a GeoPoint3D object:
+ *
+ * <code>
+ * $point = new GeoPoint3D(17, 24, -6);
+ * foreach ($point as $axis => $coordinate) {
+ * echo "\n\t$axis = $coordinate";
+ * }
+ * //This will output:
+ * // x = 17
+ * // y = 24
+ * // z = -6
+ * </code>
+ *
+ * The point 3D representation is xyz: [x, y, z] ; you can print it as a string
+ * and get this format:
+ *
+ * <code>
+ * $point = new GeoPoint3D(17, 24, -6);
+ * echo (string)$point; //will output xyz: [17, 24, -6]
+ * </code>
+ *
+ */
+class GeoPoint3D implements IteratorAggregate {
+ //
+ // x, y, z public properties
+ //
+
+ /**
+ * the x coordinate
+ *
+ * @var integer
+ */
+ public $x;
+
+ /**
+ * the y coordinate
+ *
+ * @var integer
+ */
+ public $y;
+
+ /**
+ * the z coordinate
+ *
+ * @var integer
+ */
+ public $z;
+
+ //
+ // constructor / toString
+ //
+
+ /**
+ * Initializes a new instance of GeoPoint3D class
+ */
+ function __construct ($x, $y, $z) {
+ $this->x = $x;
+ $this->y = $y;
+ $this->z = $z;
+ }
+
+ /**
+ * Returns a xyz: [x, y, z] string representation of the point coordinates
+ *
+ * @return string a xyz: [x, y, z] string representation of the coordinates
+ */
+ function __toString () {
+ return sprintf("xyz: [%d, %d, %d]", $this->x, $this->y, $this->z);
+ }
+
+ //
+ // Implementing IteratorAggregate
+ //
+
+ /**
+ * Retrieves class iterator. It traverses x, y and z.
+ *
+ * @return Traversable the iterator
+ */
+ function getIterator () {
+ return new ArrayIterator($this);
+ }
+}
+
?>
\ No newline at end of file
diff --git a/includes/geo/scene.php b/includes/geo/scene.php
--- a/includes/geo/scene.php
+++ b/includes/geo/scene.php
@@ -1,142 +1,190 @@
-<?php
-
-/*
- * Geo scene class
- *
- * 0.1 2010-01-30 17:42 DcK
- *
- * @package Zed
- * @subpackage Geo
- * @copyright Copyright (c) 2010, Dereckson
- * @license Released under BSD license
- * @version 0.1
- *
- */
-
-require_once('location.php');
-if (!defined('SCENE_DIR')) define('SCENE_DIR', 'content/scenes');
-
-class GeoScene {
- /*
- * @var string Last error warning
- */
- public $lastError;
-
- /*
- * @var string File scene to serve
- */
- public $sceneFile;
-
- /*
- * @var GeoLocation the location to print the scene
- */
- public $location;
-
- /*
- * Initializes a new GeoScene instance
- * @param GeoLocation $location location the scene is to print
- */
- function __construct ($location) {
- $this->location = $location;
-
- //Gets local scene
- if ($location->containsLocalLocation) {
- if ($this->get_local_scene()) return;
- }
-
- //Gets global scene
- if ($location->containsGlobalLocation) {
- if ($this->get_global_scene()) return;
- }
-
- //If not scene found, let's set a warning
- $this->lastError = "No scene found.";
- }
-
- /*
- * Gets local scene
- * @return boolean true if a scene have been found ; otherwise, false.
- */
- private function get_local_scene () {
- return false;
- }
-
- /*
- * Gets global scene
- * @return boolean true if a scene have been found ; otherwise, false.
- */
- private function get_global_scene () {
- $location = $this->location;
- if ($location->place) {
- if ($this->try_get_scene($location->global)) {
- return true;
- }
- }
- if ($location->body) {
- if ($this->try_get_scene('B' . $location->body->code)) {
- return true;
- }
- }
- return false;
- }
-
- public static function get_file_extension ($file) {
- $pathinfo = pathinfo($file);
- return $pathinfo['extension'];
- }
-
- public function render () {
- if ($file = $this->sceneFile) {
- switch ($ext = GeoScene::get_file_extension($file)) {
- case 'png':
- case 'jpg':
- case 'gif':
- case 'bmp':
- echo "<img src=\"$file\" />";
- break;
-
- case 'tpl':
- global $smarty;
- $template_dir = $smarty->template_dir;
- $smarty->template_dir = getcwd();
-
- //$this->location is the object reference
- //Some objects like the hypership move, so we also need to know where there are.
- //From the template, this object location is assigned to $location
- //To get $this->location from template, use $CurrentPerso->location
- if ($this->location->body) {
- $smarty->assign("location", new GeoLocation($this->location->body->location));
- } elseif ($this->location->ship) {
- $smarty->assign("location", new GeoLocation($this->location->ship->location));
- }
-
- $smarty->assign("SCENE_URL", defined('SCENE_URL') ? SCENE_URL : '/' . SCENE_DIR);
- lang_load('scenes.conf', $this->location->global);
- $smarty->display($file);
- $smarty->template_dir = $template_dir;
- break;
-
- case 'php':
- message_die(HACK_ERROR, ".php scene files not allowed without review", '', __LINE__, __FILE__);
-
- default:
- message_die(GENERAL_ERROR, "Can't handle $ext extension for $file scene", 'GeoScene render error', __LINE__, __FILE__);
- }
- echo "\n\n";
- }
- }
-
- private function try_get_scene ($code) {
- $file = SCENE_DIR . "/$code";
- $extensions = array('tpl', 'png', 'jpg', 'gif', 'bmp', 'swf', 'html', 'php');
- foreach ($extensions as $ext) {
- if (file_exists("$file.$ext")) {
- $this->sceneFile = "$file.$ext";
- return true;
- }
- }
- return false;
- }
-}
-
+<?php
+
+/**
+ * Geo scene class.
+ *
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
+ *
+ * 0.1 2010-01-30 17:42 DcK
+ *
+ * @package Zed
+ * @subpackage Geo
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
+ */
+
+require_once('location.php');
+
+if (!defined('SCENE_DIR')) {
+ /**
+ * The directory containing scenes files
+ */
+ define('SCENE_DIR', 'content/scenes');
+}
+
+/**
+ * Geo scene class
+ *
+ * This class provides methods to determine and renders the local scene.
+ */
+class GeoScene {
+ /**
+ * Last error or warning
+ *
+ * @var string
+ */
+ public $lastError;
+
+ /**
+ * File scene to serve
+ *
+ * @var string
+ */
+ public $sceneFile;
+
+ /**
+ * The location of the scene to print
+ *
+ * @var GeoLocation
+ */
+ public $location;
+
+ /**
+ * Initializes a new GeoScene instance
+ *
+ * @param GeoLocation $location location the scene is to print
+ */
+ function __construct ($location) {
+ $this->location = $location;
+
+ //Gets local scene
+ if ($location->containsLocalLocation) {
+ if ($this->get_local_scene()) return;
+ }
+
+ //Gets global scene
+ if ($location->containsGlobalLocation) {
+ if ($this->get_global_scene()) return;
+ }
+
+ //If not scene found, let's set a warning
+ $this->lastError = "No scene found.";
+ }
+
+ /**
+ * Gets local scene
+ *
+ * @return boolean true if a scene have been found ; otherwise, false.
+ */
+ private function get_local_scene () {
+ return false;
+ }
+
+ /**
+ * Gets global scene
+ *
+ * @return boolean true if a scene have been found ; otherwise, false.
+ */
+ private function get_global_scene () {
+ $location = $this->location;
+ if ($location->place) {
+ if ($this->try_get_scene($location->global)) {
+ return true;
+ }
+ }
+ if ($location->body) {
+ if ($this->try_get_scene('B' . $location->body->code)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Gets file extension
+ *
+ * @param string $file the file path
+ * @return string the file extension
+ */
+ public static function get_file_extension ($file) {
+ $pathinfo = pathinfo($file);
+ return $pathinfo['extension'];
+ }
+
+ /**
+ * Renders the file
+ *
+ * @todo Add standard code to render .swf Flash/ShockWave files.
+ */
+ public function render () {
+ if ($file = $this->sceneFile) {
+ switch ($ext = GeoScene::get_file_extension($file)) {
+ case 'png':
+ case 'jpg':
+ case 'gif':
+ case 'bmp':
+ echo "<img src=\"$file\" />";
+ break;
+
+ case 'tpl':
+ global $smarty;
+ $template_dir = $smarty->template_dir;
+ $smarty->template_dir = getcwd();
+
+ //$this->location is the object reference
+ //Some objects like the hypership move, so we also need to know where there are.
+ //From the template, this object location is assigned to $location
+ //To get $this->location from template, use $CurrentPerso->location
+ if ($this->location->body) {
+ $smarty->assign("location", new GeoLocation($this->location->body->location));
+ } elseif ($this->location->ship) {
+ $smarty->assign("location", new GeoLocation($this->location->ship->location));
+ }
+
+ $smarty->assign("SCENE_URL", defined('SCENE_URL') ? SCENE_URL : '/' . SCENE_DIR);
+ lang_load('scenes.conf', $this->location->global);
+ $smarty->display($file);
+ $smarty->template_dir = $template_dir;
+ break;
+
+ case 'php':
+ message_die(HACK_ERROR, ".php scene files not allowed without review", '', __LINE__, __FILE__);
+
+ default:
+ message_die(GENERAL_ERROR, "Can't handle $ext extension for $file scene", 'GeoScene render error', __LINE__, __FILE__);
+ }
+ echo "\n\n";
+ }
+ }
+
+ /**
+ * Tries to get the scene file.
+ *
+ * It will tries to find in the scene directory a file with $code as name,
+ * and .tpl .png .gif .bmp .swf .html or .php as extension.
+ *
+ * @param string the location code (and filename)
+ * @return bool true if a scene file have been found and set ; otherwise, false.
+ */
+ private function try_get_scene ($code) {
+ $file = SCENE_DIR . "/$code";
+ $extensions = array('tpl', 'png', 'jpg', 'gif', 'bmp', 'swf', 'html', 'php');
+ foreach ($extensions as $ext) {
+ if (file_exists("$file.$ext")) {
+ $this->sceneFile = "$file.$ext";
+ return true;
+ }
+ }
+ return false;
+ }
+}
+
?>
\ No newline at end of file
diff --git a/includes/objects/application.php b/includes/objects/application.php
--- a/includes/objects/application.php
+++ b/includes/objects/application.php
@@ -1,156 +1,177 @@
<?php
-/*
+/**
* Application class
*
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
+ *
* 0.1 2010-02-10 02:40 Autogenerated by Pluton Scaffolding
* Some API bits
- *
- * @package Zed
- * @copyright Copyright (c) 2010, Dereckson
- * @license Released under BSD license
- * @version 0.1
- *
+ *
+ * @package Zed
+ * @subpackage Model
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
*/
require_once('perso.php');
+/**
+ * Application class
+ *
+ * This class maps the Application table.
+ *
+ * This class also provides methods application API helper methods, to generate
+ * an application user key or to gets the perso ID from such a key.
+ */
class Application {
public $id;
public $code;
public $name;
public $api_key;
public $description;
- /*
+ /**
* Initializes a new instance
+ *
* @param int $id the primary key
*/
function __construct ($id = null) {
if ($id) {
$this->id = $id;
$this->load_from_database();
}
}
- /*
+ /**
* Loads the object Application (ie fill the properties) from the $_POST array
*/
function load_from_form () {
if (array_key_exists('code', $_POST)) $this->code = $_POST['code'];
if (array_key_exists('name', $_POST)) $this->name = $_POST['name'];
if (array_key_exists('api_key', $_POST)) $this->api_key = $_POST['api_key'];
if (array_key_exists('description', $_POST)) $this->description = $_POST['description'];
}
- /*
+ /**
* Loads the object Application (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$id = $db->sql_escape($this->id);
$sql = "SELECT * FROM applications WHERE application_id = '" . $id . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query applications", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "Application unkwown: " . $this->id;
return false;
}
$this->code = $row['application_code'];
$this->name = $row['application_name'];
$this->api_key = $row['api_key'];
$this->description = $row['application_description'];
return true;
}
- /*
+ /**
* Saves to database
*/
function save_to_database () {
global $db;
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$code = $db->sql_escape($this->code);
$name = $db->sql_escape($this->name);
$api_key = $db->sql_escape($this->api_key);
$description = $db->sql_escape($this->description);
//Updates or inserts
$sql = "REPLACE INTO applications (`application_id`, `application_code`, `application_name`, `api_key`, `application_description`) VALUES ($id, '$code', '$name', '$api_key', '$description')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
if (!$id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
}
/*
* ----------------------------------------------------------------------- *
* Application API methods
* ----------------------------------------------------------------------- *
*/
- /*
+ /**
* Loads an Application object from its API key
+ *
* @param string Application API key GUID
* @return Application the application matching the API key
*/
static function from_api_key ($key) {
global $db;
$key = $db->sql_escape($key);
$sql = "SELECT * FROM applications WHERE api_key = '" . $key . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query applications", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result))
return null;
//Fills app information
$app = new Application();
$app->id = $row['application_id'];
$app->code = $row['application_code'];
$app->name = $row['application_name'];
$app->api_key = $row['api_key'];
$app->description = $row['application_description'];
return $app;
}
- /*
+ /**
* Gets the perso ID from an application user key
+ *
* @param string $userkey User application key GUID
* @return int the perso ID
*/
function get_perso_id ($userkey) {
global $db;
$id = $db->sql_escape($this->id);
$userkey = $db->sql_escape($userkey);
$sql = "SELECT perso_id FROM applications_userkeys WHERE api_userkey = '$userkey' AND application_id = '$id'";
return $db->sql_query_express($sql);
}
- /*
+ /**
* Generates a key for the specified perso and current application.
+ *
* @param int $perso_id The perso ID
* @param string $userkey User application key GUID (optionnal)
* @return Application User application key GUID
*/
function generate_userkey ($perso_id = null, $userkey = null) {
global $CurrentPerso;
//Ensures we've a key and someone to be assigned it
if ($userkey === null) $userkey = new_guid();
$perso = ($perso_id === null) ? $CurrentPerso : Perso::get($perso_id);
//Saves key
$perso->set_flag('api.app.keys.' . $this->id, $userkey);
//Returns it
return $userkey;
}
}
?>
\ No newline at end of file
diff --git a/includes/objects/content.php b/includes/objects/content.php
--- a/includes/objects/content.php
+++ b/includes/objects/content.php
@@ -1,268 +1,301 @@
-<?php
-
-/*
- * Content class
- *
- * 0.1 2010-02-24 15:57 Autogenerated by Pluton Scaffolding
- *
- * @package Zed
- * @copyright Copyright (c) 2010, Dereckson
- * @license Released under BSD license
- * @version 0.1
- * @todo remove dbc temporary limitations (cf. /do.php upload_content and infra)
- * @todo create a class ContentLocation and move location fields there
- * @todo validate SQL schema and add in config.php TABLE_CONTENT tables
- *
- * [DESIGN BY CONTRACT] This class works only with the following assertions:
- * i. Each content have EXACTLY ONE location
- * ii. Location fields will not be modified
- *
- * If a content have more than one location, only the first occurence in
- * content_locations table will be considered.
- *
- * If a content have no location, it will be ignored.
- *
- * If you edit content location, then call saveToDatabase, you will create
- * a new location but future instances will contain first not deleted location.
- *
- */
-class Content {
-
-/* -------------------------------------------------------------
- Properties
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- public $id;
- public $path;
- public $user_id;
- public $perso_id;
- public $title;
-
- public $location_global = null;
- public $location_local = null;
- public $location_k = null;
-
- public $perso_name;
- public $perso_nickname;
-
-/* -------------------------------------------------------------
- Constructor, __toString
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /*
- * Initializes a new Content instance
- * @param int $id the primary key
- */
- function __construct ($id = null) {
- if ($id) {
- $this->id = $id;
- $this->load_from_database();
- }
- }
-
- /*
- * Returns a string representation of current Content instance
- * @return string the content title or path if title is blank.
- */
- function __toString () {
- return $this->title ? $this->title : $this->path;
- }
-
-/* -------------------------------------------------------------
- Load/save class
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /*
- * Loads the object Content (ie fill the properties) from the $_POST array
- * @param boolean $allowSensibleFields if false, allow only location_local, location_k and title to be defined ; otherwise, allow all fields.
- */
- function load_from_form ($allowSensibleFields = false) {
- if (array_key_exists('title', $_POST)) $this->title = $_POST['title'];
- if (array_key_exists('location_local', $_POST)) $this->location_local = $_POST['location_local'];
- if (array_key_exists('location_k', $_POST)) $this->location_k = $_POST['location_k'];
-
- if ($allowSensibleFields) {
- if (array_key_exists('path', $_POST)) $this->path = $_POST['path'];
- if (array_key_exists('user_id', $_POST)) $this->user_id = $_POST['user_id'];
- if (array_key_exists('perso_id', $_POST)) $this->perso_id = $_POST['perso_id'];
- if (array_key_exists('location_global', $_POST)) $this->location_global = $_POST['location_global'];
- }
- }
-
- /*
- * Loads the object Content (ie fill the properties) from the database
- */
- function load_from_database () {
- global $db;
- $id = $db->sql_escape($this->id);
- $sql = "SELECT * FROM content WHERE content_id = '" . $id . "'";
- if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query content", '', __LINE__, __FILE__, $sql);
- if (!$row = $db->sql_fetchrow($result)) {
- $this->lastError = "Content unkwown: " . $this->id;
- return false;
- }
- $this->load_from_row($row);
- return true;
- }
-
- /*
- * Loads the object from row
- */
- function load_from_row ($row) {
- $this->id = $row['content_id'];
- $this->path = $row['content_path'];
- $this->user_id = $row['user_id'];
- $this->perso_id = $row['perso_id'];
- $this->title = $row['content_title'];
- $this->location_global = $row['location_global'];
- $this->location_local = $row['location_local'];
- $this->location_k = $row['location_k'];
-
- if (array_key_exists('perso_name', $row)) $this->perso_name = $row['perso_name'];
- if (array_key_exists('perso_nickname', $row)) $this->perso_nickname = $row['perso_nickname'];
- }
-
- /*
- * Saves to database
- */
- function save_to_database () {
- global $db;
-
- $id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
- $path = $db->sql_escape($this->path);
- $user_id = $db->sql_escape($this->user_id);
- $perso_id = $db->sql_escape($this->perso_id);
- $title = $db->sql_escape($this->title);
-
- $location_global = ($this->location_global !== null) ? "'" . $db->sql_escape($this->location_global) . "'" : 'NULL';
- $location_local = ($this->location_local !== null) ? "'" . $db->sql_escape($this->location_local) . "'" : 'NULL';
- $location_k = ($this->location_k !== null) ? "'" . $db->sql_escape($this->location_k) . "'" : 'NULL';
-
- //Updates or inserts
- $sql = "REPLACE INTO content_files (`content_id`, `content_path`, `user_id`, `perso_id`, `content_title`) VALUES ($id, '$path', '$user_id', '$perso_id', '$title')";
- if (!$db->sql_query($sql)) {
- message_die(SQL_ERROR, "Can't save content", '', __LINE__, __FILE__, $sql);
- }
-
- if (!$this->id) {
- //Gets new record id value
- $this->id = $db->sql_nextid();
- }
-
- //Saves location
- $id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
- $sql = "REPLACE INTO content_locations (location_global, location_local, location_k, content_id) VALUES ($location_global, $location_local, $location_k, $id)";
- if (!$db->sql_query($sql))
- message_die(SQL_ERROR, "Can't save content location", '', __LINE__, __FILE__, $sql);
- }
-
-/* -------------------------------------------------------------
- File handling helper methods
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /*
- * Determines if the extension is valid
- * @param string $ext The extension (without dot)
- * @return boolean true if this extension is valid ; otherwise, false.
- */
- function is_valid_extension ($ext) {
- switch ($ext = strtolower($ext)) {
- //Pictures
- case 'jpg':
- case 'gif':
- case 'png':
- case 'bmp':
- case 'xbm':
- return true;
-
- //Denied extension
- default:
- return false;
- }
- }
-
- /*
- * Creates a directory
- */
- function create_directory ($dir) {
- if (!file_exists($dir)) {
- @mkdir($dir); //Creates new directory, chmod 777
- }
- }
-
- /*
- * @return boolean true if the file have been handled
- */
- function handle_uploaded_file ($fileArray) {
- if (count($fileArray) && $fileArray['error'] == 0) {
- $this->create_directory("content/users/$this->user_id");
- $this->path = "content/users/$this->user_id/$fileArray[name]";
- if (!self::is_valid_extension(get_extension($fileArray[name]))) {
- return false;
- }
- if (move_uploaded_file($fileArray['tmp_name'], $this->path)) {
- return true;
- } else {
- $this->path = null;
- return false;
- }
- } else {
- return false;
- }
- }
-
- /*
- * Generates a thumbnail using ImageMagick binary
- * @return boolean true if the thumbnail command returns 0 as program exit code ; otherwise, false
- */
- function generate_thumbnail () {
- global $Config;
-
- //Builds thumbnail filename
- $sourceFile = $this->path;
- $pos = strrpos($this->path, '.');
- $thumbnailFile = substr($sourceFile, 0, $pos) . 'Square' . substr($sourceFile, $pos);
-
- //Executes imagemagick command
- @system($command, $code);
-
- //Returns true if the command have exited with errorcode 0 (= ok)
- return ($code == 0);
- }
-
-/* -------------------------------------------------------------
- Gets content
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /*
- * Gets content at specified location
- * @param string $location_global global content location
- * @param string $location_local local content location
- * @return Array array of Content instances
- */
- static function get_local_content ($location_global, $location_local) {
- global $db;
-
- //Get contents at this location
- $location_global = $db->sql_escape($location_global);
- $location_local = $db->sql_escape($location_local);
-
- $sql = "SELECT c.*, p.perso_nickname, p.perso_name FROM content c, persos p WHERE c.location_global = '$location_global' AND c.location_local = '$location_local' AND p.perso_id = c.perso_id ORDER BY location_k ASC";
- if (!$result = $db->sql_query($sql)) {
- message_die(SQL_ERROR, "Can't get content", '', __LINE__, __FILE__, $sql);
- }
-
- //Fills content array
- $contents = array();
- while ($row = $db->sql_fetchrow($result)) {
- $content = new Content();
- $content->load_from_row($row);
- $contents[] = $content;
- }
-
- return $contents;
- }
-
-}
-
+<?php
+
+/**
+ * Content class
+ *
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
+ *
+ * 0.1 2010-02-24 15:57 Autogenerated by Pluton Scaffolding
+ *
+ * @package Zed
+ * @subpackage Model
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
+ */
+
+/**
+ * Content class
+ *
+ * This class maps the content view.
+ *
+ * This view shows the content_files and content_locations tables.
+ *
+ * This class also provides helper methods, to handle files, generate thumbnails
+ * or get local content from a specific location.
+ *
+ * @todo remove dbc temporary limitations (cf. /do.php upload_content and infra)
+ * @todo create a class ContentLocation and move location fields there
+ * @todo validate SQL schema and add in config.php TABLE_CONTENT tables
+ *
+ * [DESIGN BY CONTRACT] This class works only with the following assertions:
+ * i. Each content have EXACTLY ONE location
+ * ii. Location fields will not be modified
+ *
+ * If a content have more than one location, only the first occurence in
+ * content_locations table will be considered.
+ *
+ * If a content have no location, it will be ignored.
+ *
+ * If you edit content location, then call saveToDatabase, you will create
+ * a new location but future instances will contain first not deleted location.
+ *
+ */
+class Content {
+
+/* -------------------------------------------------------------
+ Properties
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+ public $id;
+ public $path;
+ public $user_id;
+ public $perso_id;
+ public $title;
+
+ public $location_global = null;
+ public $location_local = null;
+ public $location_k = null;
+
+ public $perso_name;
+ public $perso_nickname;
+
+/* -------------------------------------------------------------
+ Constructor, __toString
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+ /**
+ * Initializes a new Content instance
+ *
+ * @param int $id the primary key
+ */
+ function __construct ($id = null) {
+ if ($id) {
+ $this->id = $id;
+ $this->load_from_database();
+ }
+ }
+
+ /**
+ * Returns a string representation of current Content instance
+ *
+ * @return string the content title or path if title is blank.
+ */
+ function __toString () {
+ return $this->title ? $this->title : $this->path;
+ }
+
+/* -------------------------------------------------------------
+ Load/save class
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+ /**
+ * Loads the object Content (ie fill the properties) from the $_POST array
+ *
+ * @param boolean $allowSensibleFields if false, allow only location_local, location_k and title to be defined ; otherwise, allow all fields.
+ */
+ function load_from_form ($allowSensibleFields = false) {
+ if (array_key_exists('title', $_POST)) $this->title = $_POST['title'];
+ if (array_key_exists('location_local', $_POST)) $this->location_local = $_POST['location_local'];
+ if (array_key_exists('location_k', $_POST)) $this->location_k = $_POST['location_k'];
+
+ if ($allowSensibleFields) {
+ if (array_key_exists('path', $_POST)) $this->path = $_POST['path'];
+ if (array_key_exists('user_id', $_POST)) $this->user_id = $_POST['user_id'];
+ if (array_key_exists('perso_id', $_POST)) $this->perso_id = $_POST['perso_id'];
+ if (array_key_exists('location_global', $_POST)) $this->location_global = $_POST['location_global'];
+ }
+ }
+
+ /**
+ * Loads the object Content (ie fill the properties) from the database
+ */
+ function load_from_database () {
+ global $db;
+ $id = $db->sql_escape($this->id);
+ $sql = "SELECT * FROM content WHERE content_id = '" . $id . "'";
+ if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query content", '', __LINE__, __FILE__, $sql);
+ if (!$row = $db->sql_fetchrow($result)) {
+ $this->lastError = "Content unkwown: " . $this->id;
+ return false;
+ }
+ $this->load_from_row($row);
+ return true;
+ }
+
+ /**
+ * Loads the object from row
+ */
+ function load_from_row ($row) {
+ $this->id = $row['content_id'];
+ $this->path = $row['content_path'];
+ $this->user_id = $row['user_id'];
+ $this->perso_id = $row['perso_id'];
+ $this->title = $row['content_title'];
+ $this->location_global = $row['location_global'];
+ $this->location_local = $row['location_local'];
+ $this->location_k = $row['location_k'];
+
+ if (array_key_exists('perso_name', $row)) $this->perso_name = $row['perso_name'];
+ if (array_key_exists('perso_nickname', $row)) $this->perso_nickname = $row['perso_nickname'];
+ }
+
+ /**
+ * Saves to database
+ */
+ function save_to_database () {
+ global $db;
+
+ $id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
+ $path = $db->sql_escape($this->path);
+ $user_id = $db->sql_escape($this->user_id);
+ $perso_id = $db->sql_escape($this->perso_id);
+ $title = $db->sql_escape($this->title);
+
+ $location_global = ($this->location_global !== null) ? "'" . $db->sql_escape($this->location_global) . "'" : 'NULL';
+ $location_local = ($this->location_local !== null) ? "'" . $db->sql_escape($this->location_local) . "'" : 'NULL';
+ $location_k = ($this->location_k !== null) ? "'" . $db->sql_escape($this->location_k) . "'" : 'NULL';
+
+ //Updates or inserts
+ $sql = "REPLACE INTO content_files (`content_id`, `content_path`, `user_id`, `perso_id`, `content_title`) VALUES ($id, '$path', '$user_id', '$perso_id', '$title')";
+ if (!$db->sql_query($sql)) {
+ message_die(SQL_ERROR, "Can't save content", '', __LINE__, __FILE__, $sql);
+ }
+
+ if (!$this->id) {
+ //Gets new record id value
+ $this->id = $db->sql_nextid();
+ }
+
+ //Saves location
+ $id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
+ $sql = "REPLACE INTO content_locations (location_global, location_local, location_k, content_id) VALUES ($location_global, $location_local, $location_k, $id)";
+ if (!$db->sql_query($sql))
+ message_die(SQL_ERROR, "Can't save content location", '', __LINE__, __FILE__, $sql);
+ }
+
+/* -------------------------------------------------------------
+ File handling helper methods
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+ /**
+ * Determines if the extension is valid
+ *
+ * @param string $ext The extension (without dot)
+ * @return boolean true if this extension is valid ; otherwise, false.
+ */
+ function is_valid_extension ($ext) {
+ switch ($ext = strtolower($ext)) {
+ //Pictures
+ case 'jpg':
+ case 'gif':
+ case 'png':
+ case 'bmp':
+ case 'xbm':
+ return true;
+
+ //Denied extension
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Creates a directory
+ *
+ * @param string $dir the directory to create
+ */
+ function create_directory ($directory) {
+ if (!file_exists($directory)) {
+ @mkdir($directory); //Creates new directory, chmod 777
+ }
+ }
+
+ /**
+ * Handles uploaded file
+ *
+ * @return bool true if the file have been handled
+ */
+ function handle_uploaded_file ($fileArray) {
+ if (count($fileArray) && $fileArray['error'] == 0) {
+ $this->create_directory("content/users/$this->user_id");
+ $this->path = "content/users/$this->user_id/$fileArray[name]";
+ if (!self::is_valid_extension(get_extension($fileArray[name]))) {
+ return false;
+ }
+ if (move_uploaded_file($fileArray['tmp_name'], $this->path)) {
+ return true;
+ } else {
+ $this->path = null;
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Generates a thumbnail using ImageMagick binary
+ *
+ * @return boolean true if the thumbnail command returns 0 as program exit code ; otherwise, false
+ */
+ function generate_thumbnail () {
+ global $Config;
+
+ //Builds thumbnail filename
+ $sourceFile = $this->path;
+ $pos = strrpos($this->path, '.');
+ $thumbnailFile = substr($sourceFile, 0, $pos) . 'Square' . substr($sourceFile, $pos);
+
+ //Executes imagemagick command
+ $command = $Config['ImageMagick']['convert'] . " \"$sourceFile\" -resize 162x162 \"$thumbnailFile\"";
+ @system($command, $code);
+
+ //Returns true if the command have exited with errorcode 0 (= ok)
+ return ($code == 0);
+ }
+
+/* -------------------------------------------------------------
+ Gets content
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+ /**
+ * Gets content at specified location
+ *
+ * @param string $location_global global content location
+ * @param string $location_local local content location
+ * @return Array array of Content instances
+ */
+ static function get_local_content ($location_global, $location_local) {
+ global $db;
+
+ //Get contents at this location
+ $location_global = $db->sql_escape($location_global);
+ $location_local = $db->sql_escape($location_local);
+
+ $sql = "SELECT c.*, p.perso_nickname, p.perso_name FROM content c, persos p WHERE c.location_global = '$location_global' AND c.location_local = '$location_local' AND p.perso_id = c.perso_id ORDER BY location_k ASC";
+ if (!$result = $db->sql_query($sql)) {
+ message_die(SQL_ERROR, "Can't get content", '', __LINE__, __FILE__, $sql);
+ }
+
+ //Fills content array
+ $contents = array();
+ while ($row = $db->sql_fetchrow($result)) {
+ $content = new Content();
+ $content->load_from_row($row);
+ $contents[] = $content;
+ }
+
+ return $contents;
+ }
+
+}
+
?>
\ No newline at end of file
diff --git a/includes/objects/invite.php b/includes/objects/invite.php
--- a/includes/objects/invite.php
+++ b/includes/objects/invite.php
@@ -1,170 +1,198 @@
<?php
-/*
+/**
* User invite class
*
- * 0.1 2010-06-29 02:13 Created by hand
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
*
- * @package Zed
- * @copyright Copyright (c) 2010, Dereckson
- * @license Released under BSD license
- * @version 0.1
+ * 0.1 2010-06-29 02:13 Initial version [DcK]
+ *
+ * @package Zed
+ * @subpackage Model
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
+ */
+
+/**
+ * User invite class
*
+ * This class maps the users_invites table.
*/
class Invite {
public $code;
public $date;
public $from_user_id;
public $from_perso_id;
- /*
- * @var int the user_id who have been claimed the invite
+ /**
+ * The user_id who have been claimed the invite
* Will be NULL as long as the invite haven't been claimed
+ *
+ * @var int
*/
public $to_user_id = NULL;
- /*
+ /**
* Initializes a new instance
+ *
* @param int $code the primary key
*/
function __construct ($code = NULL) {
if ($code) {
$this->code = $code;
$this->load_from_database();
} else {
//New invite code
$this->generate_code();
$this->date = time();
}
}
- //Generates a unique invite code
+ /**
+ * Generates a unique invite code and sets it in the code property.
+ */
function generate_code () {
global $db;
do {
$this->code = generate_random_string("AAA111");
$sql = "SELECT COUNT(*) FROM " . TABLE_USERS_INVITES . " WHERE invite_code = '$this->code' LOCK IN SHARE MODE;";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't access invite users table", '', __LINE__, __FILE__, $sql);
}
$row = $db->sql_fetchrow($result);
} while ($row[0]);
}
- /*
+ /**
* Loads the object Invite (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$code = $db->sql_escape($this->code);
$sql = "SELECT * FROM " . TABLE_USERS_INVITES . " WHERE invite_code = '" . $code . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query invite codes", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "Invite code unkwown: " . $this->code;
return false;
}
$this->code = $row['invite_code'];
$this->date = $row['invite_date'];
$this->from_user_id = $row['invite_from_user_id'];
$this->from_perso_id = $row['invite_from_perso_id'];
$this->to_user_id = $row['invite_to_user_id'];
return true;
}
- /*
+ /**
* Determines wheter the current invite code have been claimed by an user.
+ *
* @return true if the code have been claimed ; otherwise, false.
*/
function is_claimed () {
return (bool)$this->to_user_id;
}
- /*
+ /**
* Saves to database
*/
function save_to_database () {
global $db;
$code = $db->sql_escape($this->code);
$date = $db->sql_escape($this->date);
$from_user_id = $db->sql_escape($this->from_user_id);
$from_perso_id = $db->sql_escape($this->from_perso_id);
$to_user_id = $this->to_user_id ? "'" . $db->sql_escape($this->to_user_id) . "'" : 'NULL';
//Updates or inserts
$sql = "REPLACE INTO " . TABLE_USERS_INVITES . " (`invite_code`, `invite_date`, `invite_from_user_id`, `invite_from_perso_id`, `invite_to_user_id`) VALUES ('$code', '$date', '$from_user_id', '$from_perso_id', $to_user_id)";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save invite code", '', __LINE__, __FILE__, $sql);
}
}
- /*
+ /**
* Deletes the invite
*/
function delete () {
global $db;
$code = $db->sql_escape($this->code);
$sql = "DELETE FROM " . TABLE_USERS_INVITES . " WHERE invite_code = '$code'";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save delete code", '', __LINE__, __FILE__, $sql);
}
}
- /*
+ /**
* Creates an invite code
+ *
* @param int $user_id user id
* @param int $perso_id perso id
* @return string the invite code
*/
static function create ($user_id, $perso_id) {
$invite = new Invite();
$invite->from_perso_id = $perso_id;
$invite->from_user_id = $user_id;
$invite->save_to_database();
return $invite->code;
}
- /*
+ /**
* Gets invites generated by the specified perso ID
*
* @param int $perso_id the perso whom to get the invites
* @return Array an array of string, each line being an invite code
*/
static function get_invites_from ($perso_id) {
global $db;
$sql = "SELECT invite_code FROM " . TABLE_USERS_INVITES
. " WHERE invite_from_perso_id = $perso_id AND invite_to_user_id IS NULL ORDER BY invite_date ASC";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't access invite users table", '', __LINE__, __FILE__, $sql);
}
$codes = array();
while ($row = $db->sql_fetchrow($result)) {
$codes[] = $row['invite_code'];
}
return $codes;
}
+ /**
+ * Gets the perso ID who invited the specified perso
+ *
+ * @param int $perso_id the perso whom to get the invites
+ * @return int|null the perso whom to get the invites ; or null, if nobody have invited him
+ */
static function who_invited ($perso_id) {
global $db;
$perso = Perso::get($perso_id);
if ($user_id = $perso->user_id) {
$sql = "SELECT invite_from_perso_id FROM " . TABLE_USERS_INVITES . " WHERE invite_to_user_id = '$user_id'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't access invite users table", '', __LINE__, __FILE__, $sql);
}
if ($row = $db->sql_fetchrow($result)) {
return $row[0];
}
}
return null;
}
}
?>
diff --git a/includes/objects/message.php b/includes/objects/message.php
--- a/includes/objects/message.php
+++ b/includes/objects/message.php
@@ -1,139 +1,157 @@
-<?php
+ <?php
-/*
+/**
* Message class
*
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
+ *
* 0.1 2010-01-28 01:47 Autogenerated by Pluton Scaffolding
+ *
+ * @package Zed
+ * @subpackage Model
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
+ */
+
+/**
+ * Message class
*
- * @package Zed
- * @copyright Copyright (c) 2010, Dereckson
- * @license Released under BSD license
- * @version 0.1
+ * This class maps the messages table.
*
+ * It also provides a static method to get perso's messages.
*/
class Message {
public $id;
public $date;
public $from;
public $to;
public $text;
public $flag;
- /*
+ /**
* Initializes a new instance
+ *
* @param int $id the primary key
*/
function __construct ($id = null) {
if ($id) {
$this->id = $id;
$this->load_from_database();
} else {
$this->date = time();
$this->flag = 0; //unread
}
}
- /*
+ /**
* Loads the object Message (ie fill the properties) from the $_POST array
*/
function load_from_form () {
if (array_key_exists('date', $_POST)) $this->date = $_POST['date'];
if (array_key_exists('from', $_POST)) $this->from = $_POST['from'];
if (array_key_exists('to', $_POST)) $this->to = $_POST['to'];
if (array_key_exists('text', $_POST)) $this->text = $_POST['text'];
if (array_key_exists('flag', $_POST)) $this->flag = $_POST['flag'];
}
- /*
+ /**
* Loads the object Message (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$sql = "SELECT * FROM messages WHERE message_id = '" . $this->id . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query messages", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "Message unkwown: " . $this->id;
return false;
}
$this->date = $row['message_date'];
$this->from = $row['message_from'];
$this->to = $row['message_to'];
$this->text = $row['message_text'];
$this->flag = $row['message_flag'];
return true;
}
- /*
+ /**
* Saves to database
*/
function save_to_database () {
global $db;
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$date = $db->sql_escape($this->date);
$from = $db->sql_escape($this->from);
$to = $db->sql_escape($this->to);
$text = $db->sql_escape($this->text);
$flag = $db->sql_escape($this->flag);
//Updates or inserts
$sql = "REPLACE INTO messages (`message_id`, `message_date`, `message_from`, `message_to`, `message_text`, `message_flag`) VALUES ($id, '$date', '$from', '$to', '$text', '$flag')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
if (!$id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
}
- /*
+ /**
* Sends the message
*/
function send () {
$this->save_to_database();
//TODO: triggers new message notifier
}
- /*
- * Deletes a message
+ /**
+ * Deletes the message
*/
function delete () {
//A message is deleted if its flag value is 2
if ($this->flag != 2) {
$this->flag = 2;
$this->save_to_database();
}
}
- /*
+ /**
* Gets messages from the specified perso
*/
static function get_messages ($perso_id, $mark_as_read = true, &$countNewMessages = 0) {
global $db;
$sql = "SELECT message_id FROM " . TABLE_MESSAGES . " WHERE message_to = " . $db->sql_escape($perso_id) . " AND message_flag < 2 ORDER BY message_id DESC";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to get messages", '', __LINE__, __FILE__, $sql);
}
while ($row = $db->sql_fetchrow($result)) {
$message = new Message($row[0]);
$messages[] = $message;
$ids[] = $message->id;
if ($message->flag == 0) {
//New message
$countNewMessages++;
}
}
if ($mark_as_read && count($ids)) {
$ids = join($ids, ', ');
$sql = "UPDATE " . TABLE_MESSAGES . " SET message_flag = '1' WHERE message_id IN ($ids)";
$db->sql_query($sql);
}
return $messages;
}
}
?>
diff --git a/includes/objects/motd.php b/includes/objects/motd.php
--- a/includes/objects/motd.php
+++ b/includes/objects/motd.php
@@ -1,70 +1,96 @@
<?php
-/*
- * Zed
- * (c) 2010, Dereckson, some rights reserved
- * Released under BSD license
+/**
+ * MOTD class
+ *
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
*
- * MOTD class.
- *
- * 0.1 2010-02-03 21:11 Import from Azhàr
- *
+ * 0.1 2010-02-03 21:11 Import from Azhàr code
+ *
+ * @package Zed
+ * @subpackage Model
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
*/
+/**
+ * MOTD class
+ *
+ * This class maps the motd table.
+ */
class MOTD {
- public $id;
- public $perso_id;
- public $text;
- public $date;
-
- function __construct ($id = '') {
- if ($id) {
- $this->id = $id;
- return $this->load_from_database();
- } else {
- $this->date = time();
- return true;
- }
- }
-
- //Loads the object MOTD (ie fill the properties) from the $_POST array
- function load_from_form () {
- if (array_key_exists('perso_id', $_POST)) $this->user_id = $_POST['user_id'];
- if (array_key_exists('text', $_POST)) $this->text = $_POST['text'];
- if (array_key_exists('date', $_POST)) $this->date = $_POST['date'];
- }
-
- //Loads the object MOTD (ie fill the properties) from the database
- function load_from_database () {
- global $db;
- $id = $db->sql_escape($this->id);
- $sql = "SELECT * FROM " . TABLE_MOTD . " WHERE motd_id = '" . $id . "'";
- if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query azhar_motd", '', __LINE__, __FILE__, $sql);
- if (!$row = $db->sql_fetchrow($result)) {
- $this->lastError = "MOTD unkwown: " . $this->id;
- return false;
- }
- $this->perso_id = $row['perso_id'];
- $this->text = $row['motd_text'];
- $this->date = $row['motd_date'];
- return true;
- }
-
- //Saves the object to the database
- function save_to_database () {
- global $db;
- $id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
- $perso_id = $db->sql_escape($this->perso_id);
- $text = $db->sql_escape($this->text);
- $date = $db->sql_escape($this->date);
+ public $id;
+ public $perso_id;
+ public $text;
+ public $date;
+
+ /**
+ * Initializes a new instance of a MOTD object
+ *
+ * @param int $id The MOTD ID
+ */
+ function __construct ($id = '') {
+ if ($id) {
+ $this->id = $id;
+ return $this->load_from_database();
+ } else {
+ $this->date = time();
+ return true;
+ }
+ }
+
+ /**
+ * Loads the object MOTD (ie fill the properties) from the $_POST array
+ */
+ function load_from_form () {
+ if (array_key_exists('perso_id', $_POST)) $this->user_id = $_POST['user_id'];
+ if (array_key_exists('text', $_POST)) $this->text = $_POST['text'];
+ if (array_key_exists('date', $_POST)) $this->date = $_POST['date'];
+ }
+
+ /**
+ * Loads the object MOTD (ie fill the properties) from the database
+ */
+ function load_from_database () {
+ global $db;
+ $id = $db->sql_escape($this->id);
+ $sql = "SELECT * FROM " . TABLE_MOTD . " WHERE motd_id = '" . $id . "'";
+ if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query azhar_motd", '', __LINE__, __FILE__, $sql);
+ if (!$row = $db->sql_fetchrow($result)) {
+ $this->lastError = "MOTD unkwown: " . $this->id;
+ return false;
+ }
+ $this->perso_id = $row['perso_id'];
+ $this->text = $row['motd_text'];
+ $this->date = $row['motd_date'];
+ return true;
+ }
+
+ /**
+ * Saves the object to the database
+ */
+ function save_to_database () {
+ global $db;
+ $id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
+ $perso_id = $db->sql_escape($this->perso_id);
+ $text = $db->sql_escape($this->text);
+ $date = $db->sql_escape($this->date);
$sql = "REPLACE INTO " . TABLE_MOTD . " (`motd_id`, `perso_id`, `motd_text`, `motd_date`) VALUES ($id, '$perso_id', '$text', '$date')";
- if (!$db->sql_query($sql)) {
- message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
- }
- }
+ if (!$db->sql_query($sql)) {
+ message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
+ }
+ }
}
-
+
?>
diff --git a/includes/objects/perso.php b/includes/objects/perso.php
--- a/includes/objects/perso.php
+++ b/includes/objects/perso.php
@@ -1,464 +1,517 @@
<?php
-/*
+/**
* Perso class
*
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
+ *
* 0.1 2010-01-27 00:39 Autogenerated by Pluton Scaffolding
* 0.2 2010-01-29 14:39 Adding flags support
* 0.3 2010-02-06 17:50 Adding static perso hashtable
- *
- * @package Zed
- * @copyright Copyright (c) 2010, Dereckson
- * @license Released under BSD license
- * @version 0.3
- *
+ *
+ * @package Zed
+ * @subpackage Model
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
*/
require_once("includes/geo/location.php");
+/**
+ * Perso class
+ *
+ * This class maps the persos table.
+ *
+ * The class also provides methods
+ * to move or locate a perso,
+ * to gets and sets perso's flags and notes (tables persos_flags and persos_notes),
+ * to gets user's perso or check if a perso is online,
+ * to handle on select and logout events.
+ *
+ */
class Perso {
public $id;
public $user_id;
public $name;
public $nickname;
public $race;
public $sex;
public $avatar;
public $location_global;
public $location_local;
public $flags;
public static $hashtable_id = array();
public static $hashtable_name = array();
- /*
+ /**
* Initializes a new instance
+ *
* @param mixed $data perso ID or nickname
*/
function __construct ($data = null) {
if ($data) {
if (is_numeric($data)) {
$this->id = $data;
} else {
$this->nickname = $data;
}
$this->load_from_database();
} else {
$this->generate_id();
}
}
- /*
+ /**
* Initializes a new Perso instance if needed or get already available one.
+ *
* @param mixed $data perso ID or nickname
* @eturn Perso the perso instance
*/
static function get ($data = null) {
if ($data) {
//Checks in the hashtables if we already have loaded this instance
if (is_numeric($data)) {
if (array_key_exists($data, Perso::$hashtable_id)) {
return Perso::$hashtable_id[$data];
}
} else {
if (array_key_exists($data, Perso::$hashtable_name)) {
return Perso::$hashtable_name[$data];
}
}
}
$perso = new Perso($data);
return $perso;
}
- /*
+ /**
* Loads the object Perso (ie fill the properties) from the $_POST array
*/
function load_from_form () {
if (array_key_exists('user_id', $_POST)) $this->user_id = $_POST['user_id'];
if (array_key_exists('name', $_POST)) $this->name = $_POST['name'];
if (array_key_exists('nickname', $_POST)) $this->nickname = $_POST['nickname'];
if (array_key_exists('race', $_POST)) $this->race = $_POST['race'];
if (array_key_exists('sex', $_POST)) $this->sex = $_POST['sex'];
if (array_key_exists('avatar', $_POST)) $this->avatar = $_POST['avatar'];
if (array_key_exists('location_global', $_POST)) $this->location_global = $_POST['location_global'];
if (array_key_exists('location_local', $_POST)) $this->location_local = $_POST['location_local'];
}
- /*
+ /**
* Loads the object Perso (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
//Gets perso
$sql = "SELECT * FROM " . TABLE_PERSOS;
if ($this->id) {
$id = $db->sql_escape($this->id);
$sql .= " WHERE perso_id = '" . $id . "'";
} else {
$nickname = $db->sql_escape($this->nickname);
$sql .= " WHERE perso_nickname = '" . $nickname . "'";
}
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query persos", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "Perso unkwown: " . $this->id;
return false;
}
$this->id = $row['perso_id'];
$this->user_id = $row['user_id'];
$this->name = $row['perso_name'];
$this->nickname = $row['perso_nickname'];
$this->race = $row['perso_race'];
$this->sex = $row['perso_sex'];
$this->avatar = $row['perso_avatar'];
$this->location_global = $row['location_global'];
$this->location_local = $row['location_local'];
//Gets flags
$sql = "SELECT flag_key, flag_value FROM " . TABLE_PERSOS_FLAGS .
" WHERE perso_id = $this->id";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't get flags", '', __LINE__, __FILE__, $sql);
}
while ($row = $db->sql_fetchrow($result)) {
$this->flags[$row["flag_key"]] = $row["flag_value"];
}
//Gets location
$this->location = new GeoLocation(
$this->location_global,
$this->location_local
);
//Puts object in hashtables
Perso::$hashtable_id[$this->id] = $this;
Perso::$hashtable_name[$this->nickname] = $this;
return true;
}
- /*
+ /**
* Saves to database
*/
function save_to_database () {
global $db;
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$user_id = $db->sql_escape($this->user_id);
$name = $db->sql_escape($this->name);
$nickname = $db->sql_escape($this->nickname);
$race = $db->sql_escape($this->race);
$sex = $db->sql_escape($this->sex);
$avatar = $db->sql_escape($this->avatar);
$location_global = $this->location_global ? "'" . $db->sql_escape($this->location_global) . "'" : 'NULL';
$location_local = $this->location_local ? "'" . $db->sql_escape($this->location_local) . "'" : 'NULL';
//Updates or inserts
$sql = "REPLACE INTO " . TABLE_PERSOS . " (`perso_id`, `user_id`, `perso_name`, `perso_nickname`, `perso_race`, `perso_sex`, `perso_avatar`, `location_global`, `location_local`) VALUES ($id, '$user_id', '$name', '$nickname', '$race', '$sex', '$avatar', $location_global, $location_local)";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
if (!$id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
}
- /*
+ /**
* Updates the specified field in the database record
+ *
+ * @param string $field The field to save
*/
function save_field ($field) {
global $db;
if (!$this->id) {
message_die(GENERAL_ERROR, "You're trying to update a perso record not yet saved in the database: $field");
}
$id = $db->sql_escape($this->id);
$value = $db->sql_escape($this->$field);
$sql = "UPDATE " . TABLE_PERSOS . " SET `$field` = '$value' WHERE perso_id = '$id'";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save $field field", '', __LINE__, __FILE__, $sql);
}
}
- /*
+ /**
* Gets perso location
+ *
* @return string The location names
*/
public function where () {
return $this->location->__toString();
}
- /*
+ /**
* Moves the perso to a new location
+ *
+ * @param string $global the global target location
+ * @param string $global the local target location
*/
public function move_to ($global = null, $local = null) {
//Sets global location
if ($global != null) {
$this->location_global = $global;
}
//Sets local location
if ($local != null) {
$this->location_local = $local;
}
//Updates database record
if ($global != null && $local != null) {
global $db;
$perso_id = $db->sql_escape($this->id);
$g = $db->sql_escape($this->location_global);
$l = $db->sql_escape($this->location_local);
$sql = "UPDATE " . TABLE_PERSOS .
" SET location_global = '$g', location_local = '$l'" .
" WHERE perso_id = '$perso_id'";
if (!$db->sql_query($sql))
message_die(SQL_ERROR, "Can't save new $global $local location.", '', __LINE__, __FILE__, $sql);
} elseif ($global != null) {
$this->save_field('location_global');
} elseif ($local != null) {
$this->save_field('location_local');
}
//Updates location member
$this->location = new GeoLocation(
$this->location_global,
$this->location_local
);
}
- /*
+ /**
* Gets the specified flag value
+ *
* @param string $key flag key
* @param mixed $defaultValue default value if the flag doesn't exist
* @return mixed the flag value (string) or null if not existing
*/
public function get_flag ($key, $defaultValue = null) {
return $this->flag_exists($key) ? $this->flags[$key] : $defaultValue;
}
- /*
+ /**
* Determines if the specified flag exists
+ *
* @param string $key the flag key to check
* @return boolean true if the specified flag exists ; otherwise, false.
*/
public function flag_exists ($key) {
return array_key_exists($key, $this->flags);
}
- /*
+ /**
* Sets the specified flag
+ *
* @param string $key flag key
* @param string $value flag value (optional, default value: 1)
*/
public function set_flag ($key, $value = 1) {
//Checks if flag isn't already set at this value
if ($this->flags != null && array_key_exists($key, $this->flags) && $this->flags[$key] === $value)
return;
//Saves flag to database
global $db;
$id = $db->sql_escape($this->id);
$key = $db->sql_escape($key);
$value = $db->sql_escape($value);
$sql = "REPLACE " . TABLE_PERSOS_FLAGS . " SET perso_id = '$id', flag_key = '$key', flag_value = '$value'";
if (!$db->sql_query($sql))
message_die(SQL_ERROR, "Can't save flag", '', __LINE__, __FILE__, $sql);
//Sets flag in this perso instance
$this->flags[$key] = $value;
}
- /*
+ /**
* Deletes the specified flag
+ *
* @param string $key flag key
*/
public function delete_flag ($key) {
global $db;
if (!array_key_exists($key, $this->flags)) return;
$id = $db->sql_escape($this->id);
$key = $db->sql_escape($key);
$sql = "DELETE FROM " . TABLE_PERSOS_FLAGS .
" WHERE flag_key = '$key' AND perso_id = '$id' LIMIT 1";
if (!$db->sql_query($sql))
message_die(SQL_ERROR, "Can't delete flag", '', __LINE__, __FILE__, $sql);
}
- /*
- * Ensures the current perso have the flag or dies.
- * @param string $flag XXXX
- * @param string $$threshold YYYY
+ /**
+ * Ensures the current perso have the specified flag or exits.
+ *
+ *
+ * @param string $flag the flag to assert
+ * @param int $threshold value the flasg must stricly be greater than (optional, the default value is 0)
+ *
+ * Example:
+ * <code>
+ * $perso->set_flag('quux.foo', 1);
+ * //The perso wants to read quux, which we allow with the flag quux.foo
+ * $perso->request_flag('quux.foo'); //will be okay
+ *
+ * //The perso wants also to write quux, which we all allow if quux.foo = 2
+ * //The threshold will so be 1, as 2 > 1
+ * $perso->request_flag('quux.foo', 1); //Will exits, with a "You don't have quux.foo permission" message
+ * </code>
*/
public function request_flag ($flag, $threshold = 0) {
if (!array_key_exists($flag, $this->flags) || $this->flags[$flag] <= $threshold) {
message_die(HACK_ERROR, "You don't have $flag permission.", "Permissions");
}
}
- /*
+ /**
* Gets the specified note
+ *
* @param string $code the note code
* @return string the note content
*/
public function get_note ($code) {
global $db;
$id = $db->sql_escape($this->id);
$code = $db->sql_escape($code);
$sql = "SELECT note_text FROM " . TABLE_PERSOS_NOTES . " WHERE perso_id = '$id' AND note_code LIKE '$code'";
return $db->sql_query_express($sql);
}
- /*
+ /**
* Sets the specified note
+ *
* @param string $code the note code
* @param string $text the note content
*/
public function set_note ($code, $text) {
global $db;
$id = $db->sql_escape($this->id);
$code = $db->sql_escape($code);
$text = $db->sql_escape($text);
$sql = "REPLACE INTO " . TABLE_PERSOS_NOTES . " (perso_id, note_code, note_text) VALUES ('$id', '$code', '$text')";
if (!$db->sql_query($sql))
message_die(SQL_ERROR, "Can't save note", '', __LINE__, __FILE__, $sql);
}
- /*
+ /**
* Counts the amount of notes the perso have saved
+ *
* @return int the amount of notes assigned to the this perso
*/
public function count_notes () {
global $db;
$id = $db->sql_escape($this->id);
$sql = "SELECT COUNT(*) FROM " . TABLE_PERSOS_NOTES . " WHERE perso_id = '$id'";
return $db->sql_query_express($sql);
}
/*
* Determines if the specified ID is available
+ *
* @param integer $id The perso ID to check
* @return boolean true if the specified ID is available ; otherwise, false
*/
public static function is_available_id ($id) {
global $db;
$sql = "SELECT COUNT(*) FROM " . TABLE_PERSOS . " WHERE perso_id = $id LOCK IN SHARE MODE";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't access users table", '', __LINE__, __FILE__, $sql);
}
$row = $db->sql_fetchrow($result);
return ($row[0] == 0);
}
- /*
+ /**
* Generates a unique ID for the current object
*/
private function generate_id () {
do {
$this->id = rand(2001, 5999);
} while (!Perso::is_available_id($this->id));
}
- /*
+ /**
* Checks if the nickname is available
+ *
* @param string $nickname the nickname to check
*/
public static function is_available_nickname ($nickname) {
global $db;
$nickname = $db->sql_escape($nickname);
$sql = "SELECT COUNT(*) FROM " . TABLE_PERSOS . " WHERE perso_nickname LIKE '$nickname' LOCK IN SHARE MODE;";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Utilisateurs non parsable", '', __LINE__, __FILE__, $sql);
}
$row = $db->sql_fetchrow($result);
return ($row[0] == 0);
}
- /*
+ /**
* Counts the perso a user have
*
* @param int user_id the user ID
* @return the user's perso count
*/
public static function get_persos_count ($user_id) {
global $db;
$sql = "SELECT COUNT(*) FROM " . TABLE_PERSOS . " WHERE user_id = $user_id";
return $db->sql_query_express($sql);
}
- /*
+ /**
* Gets an array with all the perso of the specified user
+ *
+ * @param int $user_id the user ID
*/
public static function get_persos ($user_id) {
global $db;
$user_id = $db->sql_escape($user_id);
$sql = "SELECT perso_id FROM " . TABLE_PERSOS . " WHERE user_id = $user_id";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't get persos", '', __LINE__, __FILE__, $sql);
}
while ($row = $db->sql_fetchrow($result)) {
$persos[] = Perso::get($row[perso_id]);
}
return $persos;
}
- /*
+ /**
* Gets the first perso a user have
* (typically to be used when get_persos_count returns 1 to autoselect)
*
* @param int user_id the user ID
*/
public static function get_first_perso ($user_id) {
global $db;
$sql = "SELECT perso_id FROM " . TABLE_PERSOS ." WHERE user_id = $user_id LIMIT 1";
if ($perso_id = $db->sql_query_express($sql)) {
return new Perso($perso_id);
}
}
- /*
+ /**
* Determines wheter the perso is online
*
- * @return boolean true if the perso is online ; otherwise, false.
+ * @return bool true if the perso is online ; otherwise, false.
*/
public function is_online () {
global $db;
$id = $db->sql_escape($this->id);
$sql = "SELECT MAX(online) FROM " . TABLE_SESSIONS ." WHERE perso_id = $id";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to query the table", '', __LINE__, __FILE__, $sql);
}
$row = $db->sql_fetchrow($result);
return ($row[0] == 1);
}
- /*
+ /**
* This event method is called when the user selects a new perso
*/
public function on_select () {
//Session
set_info('perso_id', $this->id);
$this->set_flag("site.lastlogin", $_SERVER['REQUEST_TIME']);
define("PersoSelected", true);
}
- /*
+ /**
* This event method is called when the user logs off its account or perso
*/
public function on_logout () {
//Clears perso information in $_SESSION and session table
set_info('perso_id', null);
clean_session();
}
}
?>
\ No newline at end of file
diff --git a/includes/objects/port.php b/includes/objects/port.php
--- a/includes/objects/port.php
+++ b/includes/objects/port.php
@@ -1,176 +1,199 @@
<?php
-/*
+/**
* Port class
*
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
+ *
* 0.1 2010-02-09 19:17 Autogenerated by Pluton Scaffolding
+ *
+ * @package Zed
+ * @subpackage Model
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
+ */
+
+require_once("includes/geo/location.php");
+
+/**
+ * Port class
*
- * @package Zed
- * @copyright Copyright (c) 2010, Dereckson
- * @license Released under BSD license
- * @version 0.1
+ * This class maps the ports table.
*
+ * The class also provides helper methods to handle ports at specified location.
*/
class Port {
public $id;
public $location_global;
public $location_local;
public $name;
public $hidden;
public $requiresPTA;
public $default;
- /*
+ /**
* Initializes a new instance
* @param int $id the primary key
*/
function __construct ($id = NULL) {
if ($id) {
$this->id = $id;
$this->load_from_database();
}
}
- /*
+ /**
* Loads the object Port (ie fill the properties) from the $_POST array
*/
function load_from_form () {
if (array_key_exists('location_global', $_POST)) $this->location_global = $_POST['location_global'];
if (array_key_exists('location_local', $_POST)) $this->location_local = $_POST['location_local'];
if (array_key_exists('name', $_POST)) $this->name = $_POST['name'];
if (array_key_exists('hidden', $_POST)) $this->hidden = $_POST['hidden'] ? true : false;
if (array_key_exists('requiresPTA', $_POST)) $this->requiresPTA = $_POST['requiresPTA'] ? true : false;
if (array_key_exists('default', $_POST)) $this->hidden = $_POST['default'] ? true : false;
}
- /*
+ /**
* Loads the object Port (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$id = $db->sql_escape($this->id);
$sql = "SELECT * FROM " . TABLE_PORTS . " WHERE port_id = '" . $id . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query ports", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "Port unkwown: " . $this->id;
return false;
}
$this->location_global = $row['location_global'];
$this->location_local = $row['location_local'];
$this->name = $row['port_name'];
//Explodes place_status SET field in boolean variables
if ($row['place_status']) {
$flags = explode(',', $row['port_status']);
foreach ($flags as $flag) {
$this->$flag = true;
}
}
return true;
}
- /*
+ /**
* Gets status field value
+ *
+ * @return string the status field value (e.g. "requiresPTA,default")
*/
function get_status () {
$flags = array('hidden', 'requiresPTA', 'default');
foreach ($flags as $flag) {
if ($this->$flag) {
$status[] = $flag;
}
}
return implode(',', $status);
}
- /*
+ /**
* Saves to database
*/
function save_to_database () {
global $db;
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$location_global = $db->sql_escape($this->location_global);
$location_local = $db->sql_escape($this->location_local);
$name = $db->sql_escape($this->name);
$status = $this->get_status();
//Updates or inserts
$sql = "REPLACE INTO " . TABLE_PORTS . " (`port_id`, `location_global`, `location_local`, `port_name`, `port_status`) VALUES ($id, '$location_global', '$location_local', '$name', '$status')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
if (!$id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
}
- /*
+ /**
* Determines if the specified location have a port
+ *
* @param string $location_global the global location
* @return boolean true if there is a spatioport exactly at the specified location ; otherwise, false.
*/
static function have_port ($location_global) {
- return (get_port_id($location_global) === NULL) ? false : true;
+ return (get_port_id($location_global) !== NULL);
}
- /*
+ /**
* Gets the port situated exactly at the specified global location
+ *
* @param string $location_global the global location
* @return int the port ID
*/
static function get_port_id ($location_global) {
global $db;
$location_global = $db->sql_escape($location_global);
$sql = "SELECT port_id FROM " . TABLE_PORTS . " WHERE location_global = '$location_global'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to get ports", '', __LINE__, __FILE__, $sql);
}
if ($row = $db->sql_fetchrow($result)) {
return $row['port_id'];
}
return null;
}
- /*
+ /**
* Gets default port, from specified global location
+ *
* @param string $location_global the global location
* @return Port the port near this location ; null if there isn't port there.
*/
static function from_location ($location_global) {
$havePlace = strlen($location_global) == 9;
$port_id = null;
if ($havePlace) {
//Checks if there's a port at specified location
$port_id = self::get_port_id($location_global);
}
if ($port_id == null) {
//Nearest default port.
//If place have been specified (B0001001), we've to found elsewhere
//==> B00001%
global $db;
$loc = $db->sql_escape(substr($location_global, 0, 6));
$sql = "SELECT port_id FROM " . TABLE_PORTS . " WHERE location_global LIKE '$loc%'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't get port", '', __LINE__, __FILE__, $sql);
}
if ($row = $db->sql_fetchrow($result)) {
$port_id = $row['port_id'];
} else {
return null;
}
}
return new Port($port_id);
}
}
-?>
-
+?>
\ No newline at end of file
diff --git a/includes/objects/profile.php b/includes/objects/profile.php
--- a/includes/objects/profile.php
+++ b/includes/objects/profile.php
@@ -1,110 +1,148 @@
<?php
-/*
- * Zed
- * (c) 2010, Dereckson, some rights reserved
- * Released under BSD license
+/**
+ * Profile class
*
- * Profile class.
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
*
* 0.1 2010-01-02 16:49 Autogenerated by Pluton Scaffolding
* Import from Azhàr
* 0.2 2010-07-05 03:56 Tags
- *
+ *
+ * @package Zed
+ * @subpackage Model
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
*/
+/**
+ * Port class
+ *
+ * This class maps the profiles table.
+ *
+ * The class also provides methods to handle and cache tags.
+ */
class Profile {
public $perso_id;
public $text;
public $updated;
public $fixedwidth;
+ /**
+ * Initializes a new instance of the Profile class
+ *
+ * @param int $perso_id the perso ID
+ */
function __construct ($perso_id) {
$this->perso_id = $perso_id;
$this->load_from_database();
}
- //Loads the object Profile (ie fill the properties) from the $_POST array
+ /**
+ * Loads the object Profile (ie fill the properties) from the $_POST array
+ */
function load_from_form ($read_boolean = true) {
if (array_key_exists('perso_id', $_POST)) $this->perso_id = $_POST['perso_id'];
if (array_key_exists('text', $_POST)) $this->text = $_POST['text'];
if (array_key_exists('updated', $_POST)) $this->updated = $_POST['updated'];
if ($read_boolean) {
if (array_key_exists('fixedwidth', $_POST)) $this->fixedwidth = $_POST['fixedwidth'];
}
}
- //Loads the object Profile (ie fill the properties) from the database
+ /**
+ * Loads the object Profile (ie fill the properties) from the database
+ */
function load_from_database () {
global $db;
$id = $db->sql_escape($this->perso_id);
$sql = "SELECT * FROM " . TABLE_PROFILES . " WHERE perso_id = '$id'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query azhar_profiles", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "Profile unkwown: " . $this->perso_id;
return false;
}
$this->text = $row['profile_text'];
$this->updated = $row['profile_updated'];
$this->fixedwidth = $row['profile_fixedwidth'];
return true;
}
- //Saves the object to the database
+ /**
+ * Saves the object to the database
+ */
function save_to_database () {
global $db;
$perso_id = $db->sql_escape($this->perso_id);
$text = $db->sql_escape($this->text);
$updated = $db->sql_escape($this->updated);
$fixedwidth = $this->fixedwidth ? 1 : 0;
$sql = "REPLACE INTO " . TABLE_PROFILES . " (`perso_id`, `profile_text`, `profile_updated`, `profile_fixedwidth`) VALUES ('$perso_id', '$text', '$updated', '$fixedwidth')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
}
///
/// Tags
///
+ /**
+ * Gets the profile's tags
+ *
+ * @return string The profile's tags
+ */
function get_tags () {
global $db;
$id = $db->sql_escape($this->perso_id);
$sql = "SELECT tag_code, tag_class FROM " . TABLE_PROFILES_TAGS
. " WHERE perso_id = '$id'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't get tags", '', __LINE__, __FILE__, $sql);
}
$tags = array();
while ($row = $db->sql_fetchrow($result)) {
$tags[$row['tag_class']][] = $row['tag_code'];
}
return $tags;
}
+ /**
+ * Gets the profile's cached tags
+ *
+ * @return string The profile's tags
+ */
function get_cached_tags () {
require_once('includes/cache/cache.php');
$cache = Cache::load();
$key = 'zed_profile_tags_' . $this->perso_id;
if (!$tags_html = $cache->get($key)) {
//Regenerates tags cached html snippet
global $smarty;
$tags = $this->get_tags();
if (count($tags)) {
$smarty->assign('tags', $tags);
$tags_html = $smarty->fetch('profile_tags.tpl');
} else {
$tags_html = " ";
}
$cache->set($key, $tags_html);
}
return $tags_html;
}
}
?>
\ No newline at end of file
diff --git a/includes/objects/profilecomment.php b/includes/objects/profilecomment.php
--- a/includes/objects/profilecomment.php
+++ b/includes/objects/profilecomment.php
@@ -1,97 +1,131 @@
<?php
-/*
- * Zed
- * (c) 2010, Dereckson, some rights reserved
- * Released under BSD license
- * * ProfileComment class.
+/**
+ * Profile comments class
+ *
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
*
* 0.1 2010-01-03 01:02 Autogenerated by Pluton Scaffolding
*
+ * @package Zed
+ * @subpackage Model
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
*/
+/**
+ * Profile comments class
+ *
+ * This class maps the profiles_comments table.
+ */
class ProfileComment {
public $id;
public $perso_id;
public $author;
public $authorname; //should be read-only
public $date;
public $text;
+ /**
+ * Initializes a new instance of the ProfileComment class
+ *
+ * @param int $id the comment ID
+ */
function __construct ($id = '') {
if ($id) {
$this->id = $id;
$this->load_from_database();
} else {
$this->date = time();
}
}
- //Loads the object comment (ie fill the properties) from the $_POST array
+ /**
+ * Loads the object comment (ie fill the properties) from the $_POST array
+ */
function load_from_form () {
if (array_key_exists('perso_id', $_POST)) $this->perso_id = $_POST['perso_id'];
if (array_key_exists('author', $_POST)) $this->author = $_POST['author'];
if (array_key_exists('date', $_POST)) $this->date = $_POST['date'];
if (array_key_exists('text', $_POST)) $this->text = $_POST['text'];
}
- //Loads the object comment (ie fill the properties) from the database
+ /**
+ * Loads the object comment (ie fill the properties) from the database
+ */
function load_from_database () {
global $db;
$id = $db->sql_escape($this->id);
$sql = "SELECT c.*, p.perso_name as author FROM " . TABLE_PROFILES_COMMENTS . " c, " . TABLE_PERSOS . " p WHERE c.comment_id = '$id' AND p.perso_id = c.comment_author";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query azhar_profiles_comments", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "comment unkwown: " . $this->id;
return false;
}
$this->perso_id = $row['perso_id'];
$this->author = $row['comment_author'];
$this->authorname = $row['author'];
$this->date = $row['comment_date'];
$this->text = $row['comment_text'];
return true;
}
-
- //Saves the object to the database
+
+ /**
+ * Saves the object to the database
+ */
function save_to_database () {
global $db;
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$perso_id = $db->sql_escape($this->perso_id);
$author = $db->sql_escape($this->author);
$date = $db->sql_escape($this->date);
$text = $db->sql_escape($this->text);
$sql = "REPLACE INTO " . TABLE_PROFILES_COMMENTS . " (`comment_id`, `perso_id`, `comment_author`, `comment_date`, `comment_text`) VALUES ($id, '$perso_id', '$author', '$date', '$text')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
if (!$id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
}
- //Publishes the comment
+ /**
+ * Publishes the comment
+ * @todo Add events on publish
+ */
function publish () {
$this->save_to_database();
- //TODO: triggers new profile comment notifier
}
-
+
+ /**
+ * Gets comments
+ *
+ * @param int $perso_id The Perso ID
+ */
static function get_comments ($perso_id) {
global $db;
$sql = "SELECT comment_id FROM " . TABLE_PROFILES_COMMENTS . " WHERE perso_id = " . $db->sql_escape($perso_id);
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to get comments", '', __LINE__, __FILE__, $sql);
}
while ($row = $db->sql_fetchrow($result)) {
$comments[] = new ProfileComment($row[0]);
}
return $comments;
}
}
?>
diff --git a/includes/objects/profilephoto.php b/includes/objects/profilephoto.php
--- a/includes/objects/profilephoto.php
+++ b/includes/objects/profilephoto.php
@@ -1,163 +1,203 @@
<?php
-/*
- * Zed
- * (c) 2010, Dereckson, some rights reserved
- * Released under BSD license
+/**
+ * Profile photo class
*
- * photo class.
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
*
* 0.1 2010-01-03 21:00 Autogenerated by Pluton Scaffolding
* 0.2 2010-02-02 00:52 Thumbnail ImageMagick generation code
*
+ * @package Zed
+ * @subpackage Model
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
*/
+/**
+ * Profile photo class
+ *
+ * This class maps the profile_photos table.
+ *
+ * It also provides helper methods to handle avatars or get all the photos
+ * from a specified perso.
+ */
class ProfilePhoto {
public $id;
public $perso_id;
public $name;
public $description;
public $avatar;
+ /**
+ * Initializes a new instance of the ProfilePhoto class
+ */
function __construct ($id = '') {
if ($id) {
$this->id = $id;
$this->load_from_database();
}
}
- //Loads the object photo (ie fill the properties) from the $_POST array
+ /**
+ * Loads the object photo (ie fill the properties) from the $_POST array
+ *
+ * @param bool $readBoolean if false, don't read the bool avatar field to avoid to set by error false if the field weren't in the form.
+ */
function load_from_form ($readBoolean = true) {
if (array_key_exists('perso_id', $_POST)) $this->perso_id = $_POST['perso_id'];
if (array_key_exists('name', $_POST)) $this->name = $_POST['name'];
if (array_key_exists('description', $_POST)) $this->description = $_POST['description'];
if ($readBoolean) {
$this->avatar = $_POST['avatar'] ? true : false;
}
}
- //Loads the object photo (ie fill the properties) from the database
+ /**
+ * Loads the object photo (ie fill the properties) from the database
+ */
function load_from_database () {
global $db;
$id = $db->sql_escape($this->id);
$sql = "SELECT * FROM " . TABLE_PROFILES_PHOTOS . " WHERE photo_id = '" . $id . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query azhar_profiles_photos", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "photo unkwown: " . $this->id;
return false;
}
$this->perso_id = $row['perso_id'];
$this->name = $row['photo_name'];
$this->description = $row['photo_description'];
$this->avatar = $row['photo_avatar'];
return true;
}
- /*
- * Promots the photo to avatar
+ /**
+ * Promotes the photo to avatar
*/
function promote_to_avatar () {
global $db;
//1 - locally
$sql = "UPDATE " . TABLE_PROFILES_PHOTOS . " SET photo_avatar = 0 WHERE perso_id = " . $this->perso_id;
$db->sql_query_express($sql);
$this->avatar = true;
//2 - in perso table
$perso = Perso::get($this->perso_id);
$perso->avatar = $this->name;
$perso->saveToDatabase();
}
- //Saves the object to the database
+ /**
+ * Saves the object to the database
+ */
function save_to_database () {
global $db;
//Escapes fields
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$perso_id = $db->sql_escape($this->perso_id);
$name = $db->sql_escape($this->name);
$description = $db->sql_escape($this->description);
$avatar = $this->avatar ? 1 : 0;
//Saves
$sql = "REPLACE INTO " . TABLE_PROFILES_PHOTOS . " (`photo_id`, `perso_id`, `photo_name`, `photo_description`, `photo_avatar`) VALUES ($id, '$perso_id', '$name', '$description', $avatar)";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
if (!$id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
}
+ /**
+ * Deletes the photo
+ */
function delete () {
global $db;
//Deletes from disk
$pic_tn = PHOTOS_DIR . '/' . $this->name;
$pic_genuine = PHOTOS_DIR . '/tn/' . $this->name;
unlink($pic_tn);
unlink($pic_genuine);
//Deletes from database
$id = $db->sql_escape($this->id);
$sql = "DELETE FROM " . TABLE_PROFILES_PHOTOS . " WHERE photo_id = '$id' LIMIT 1";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't delete photo", '', __LINE__, __FILE__, $sql);
}
}
- /*
+ /**
* Generates a thumbnail using ImageMagick binary
+ *
* @return boolean true if the thumbnail command returns 0 as program exit code ; otherwise, false
*/
function generate_thumbnail () {
global $Config;
$sourceFile = PHOTOS_DIR . DIRECTORY_SEPARATOR . $this->name;
$thumbnailFile = PHOTOS_DIR . DIRECTORY_SEPARATOR . 'tn' . DIRECTORY_SEPARATOR . $this->name;
$command = $Config['ImageMagick']['convert'] . " $sourceFile -resize 1000x80 $thumbnailFile";
@system($command, $code);
return ($code == 0);
}
+ /**
+ * Gets photos from the specified perso
+ *
+ * @param int $perso_id the perso ID
+ * @param bool $allowUnsafe if false, don't include not safe for work photos
+ */
static function get_photos ($perso_id, $allowUnsafe = true) {
global $db;
$sql = "SELECT photo_id FROM " . TABLE_PROFILES_PHOTOS . " WHERE perso_id = " . $db->sql_escape($perso_id);
if (!$allowUnsafe) $sql .= " AND photo_safe = 0";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to get photos", '', __LINE__, __FILE__, $sql);
}
while ($row = $db->sql_fetchrow($result)) {
$photos[] = new ProfilePhoto($row[0]);
}
return $photos;
}
- /*
+ /**
* Gets perso avatar
+ *
* @param integer $perso_id the perso to get the avatar ID
* @param string $username the username to put in title tag
*/
static function get_avatar ($perso_id, $username = '') {
global $db;
$perso_id = $db->sql_escape($perso_id);
$sql = "SELECT photo_description, photo_name FROM " . TABLE_PROFILES_PHOTOS . " WHERE perso_id = '$perso_id' and photo_avatar = 1";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to get avatar", '', __LINE__, __FILE__, $sql);
}
if ($row = $db->sql_fetchrow($result)) {
if (!$username) $username = get_name($perso_id);
$description = $row['photo_description'] ? "$row[photo_description] ($username's avatar)" : "$username's avatar";
$url = PHOTOS_URL . '/tn/' . $row['photo_name'];
return "<img src=\"$url\" title=\"$username\" alt=\"$description\" />";
} else {
return null;
}
}
}
?>
\ No newline at end of file
diff --git a/includes/objects/ship.php b/includes/objects/ship.php
--- a/includes/objects/ship.php
+++ b/includes/objects/ship.php
@@ -1,283 +1,321 @@
<?php
-/*
+/**
* Ship class
*
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
+ *
* 0.1 2010-02-05 18:51 Autogenerated by Pluton Scaffolding
* 0.2 2010-02-06 17:30 Ship API
- *
- * @package Zed
- * @copyright Copyright (c) 2010, Dereckson
- * @license Released under BSD license
- * @version 0.1
- *
+ *
+ * @package Zed
+ * @subpackage Model
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
*/
require_once("perso.php");
require_once("includes/geo/location.php");
+/**
+ * Ship class
+ *
+ * This class maps the ship table.
+ *
+ * It also provides helper methods to handle landing and fly out,
+ * or locate the ship.
+ *
+ * The class also provides methods for the ship API.
+ */
class Ship {
/*
* ----------------------------------------------------------------------- *
* Ship class definition
* ----------------------------------------------------------------------- *
*/
public $id;
public $name;
public $location_global;
public $location_local;
public $api_key;
public $description;
private static $hashtable = array();
- /*
+ /**
* Initializes a new instance
+ *
* @param int $id the primary key
*/
function __construct ($id = null) {
if ($id) {
if (preg_match("/^S[0-9]{5}$/", $id)) {
$id = substr($id, 1);
}
$this->id = $id;
$this->load_from_database();
}
}
- /*
+ /**
* Initializes a new Ship instance if needed or gets already available one.
+ *
* @param mixed $data ship ID
* @eturn Ship the ship instance
*/
static function get ($data = null) {
if ($data !== null) {
//Checks in the hashtable if we already have loaded this instance
if (array_key_exists($data, self::$hashtable)) {
return self::$hashtable[$data];
}
}
$ship = new Ship($data);
return $ship;
}
- /*
+ /**
* Loads the object Ship (ie fill the properties) from the $_POST array
*/
function load_from_form () {
if (array_key_exists('name', $_POST)) $this->name = $_POST['name'];
if (array_key_exists('location_global', $_POST)) $this->location = $_POST['location_global'];
if (array_key_exists('location_local', $_POST)) $this->location = $_POST['location_local'];
if (array_key_exists('api_key', $_POST)) $this->api_key = $_POST['api_key'];
if (array_key_exists('description', $_POST)) $this->description = $_POST['description'];
}
- /*
+ /**
* Loads the object Ship (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$id = $db->sql_escape($this->id);
$sql = "SELECT * FROM ships WHERE ship_id = '" . $id . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query Ships", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "Ship unkwown: " . $this->id;
return false;
}
$this->name = $row['ship_name'];
$this->location_global = $row['location_global'];
$this->location_local = $row['location_local'];
$this->api_key = $row['api_key'];
$this->description = $row['ship_description'];
//Puts object in hashtables
self::$hashtable[$this->id] = $this;
return true;
}
- /*
+ /**
* Saves to database
*/
function save_to_database () {
global $db;
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$name = $db->sql_escape($this->name);
$location_global = $db->sql_escape($this->location_global);
$location_local = $db->sql_escape($this->location_local);
$api_key = $db->sql_escape($this->api_key);
$description = $db->sql_escape($this->description);
//Updates or inserts
$sql = "REPLACE INTO ships (`ship_id`, `ship_name`, `location_global`, `location_local`, `api_key`, `ship_description`) VALUES ($id, '$name', '$location_global', '$location_location', '$api_key', '$description')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
if (!$id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
}
+ /**
+ * Gets the ship code, as a string representation of the instance.
+ *
+ * @return the ship's code
+ */
function __toString () {
return $this->get_code();
}
/**
* Get ships at specified location
*
* @param string $location_global global location
* @param string $location_local local location
* @return array An array of Ship items, each one a ship at the specified location
*/
static function get_ships_at ($location_global, $location_local = null) {
global $db;
//Gets ships
$sql = "SELECT ship_id, location_global, location_local FROM " . TABLE_SHIPS . " WHERE location_global IS NOT NULL";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't get ships", '', __LINE__, __FILE__, $sql);
}
$ships = array();
$location = new GeoLocation($location_global, $location_local);
while ($row = $db->sql_fetchrow($result)) {
$shipLocation = new GeoLocation($row['location_global'], $row['location_local']);
if ($location->equals($shipLocation)) {
$ships[] = self::get($row['ship_id']);
}
}
return $ships;
}
/*
* ----------------------------------------------------------------------- *
* Helper methods
* ----------------------------------------------------------------------- *
*/
- /*
+ /**
* Gets ship code, e.g. S00001
+ *
* @return string the ship code
*/
function get_code () {
return sprintf("S%05d", $this->id);
}
- /*
+ /**
* Determines if the ship is at a spatioport (or assimilated)
- * @return boolean true if the ship is at a spatioport ; false if the ship is in space
+ *
+ * @return bool true if the ship is at a spatioport ; false if the ship is in space
*/
function in_spatioport () {
return $this->location_local !== null;
}
- /*
+ /**
+ * Flies in the sip
*
* @param string $location_local the spatioport location
+ *
+ * @todo Completes location global e.g. B00001 -> B00001003
*/
function fly_in ($location_local = null) {
- //TODO: completes location global e.g. B00001 -> B00001003
$this->location_local = ($location_local == null) ? 0 : $location_local;
}
+ /**
+ * Flies out.
+ */
function fly_out () {
$this->location_local = null;
}
/*
* ----------------------------------------------------------------------- *
* Ship API methods
* ----------------------------------------------------------------------- *
*/
- /*
+ /**
* Requests the specified perso to authenticate to this ship
+ *
* @param mixed $perso_data the perso id or name
*/
function request_perso_authenticate ($perso_data) {
$perso = Perso::get($perso_data);
$flag = sprintf("request.api.ship.auth.%s", $this->get_code());
$perso->set_flag($flag);
$perso->set_flag("site.requests");
}
- /*
+ /**
* Determines if a perso is authenticated to this ship
+ *
* @param mixed $perso_data the perso id or name
* @return boolean true if the specified perso name is authenticated to this ship ; otherwise, false.
*/
function is_perso_authenticated ($perso_data) {
$flag = sprintf("api.ship.auth.%s", $this->get_code());
return Perso::get($perso_data)->flags[$flag] == 1;
}
- /*
+ /**
* Requests the specified perso to confirm the ship API session
+ *
* @param string $session_id a session ID provided by calling application
* @param mixed $perso_data the perso id or name
*/
function request_perso_confirm_session ($session_id, $perso_data) {
$perso = Perso::get($perso_data);
$flag = sprintf("request.api.ship.session.%s.%s", $this->get_code(), $session_id);
$perso->set_flag($flag);
$perso->set_flag("site.requests");
}
- /*
+ /**
* Cleans ship API temporary sessions
*/
static function clean_ship_sessions () {
//Cleans old sessions
global $db;
$sql = "DELETE FROM " . TABLE_REGISTRY . " WHERE registry_key LIKE 'api.ship.session.%' AND registry_updated < NOW() - 7200";
if (!$db->sql_query($sql))
message_die(SQL_ERROR, "Can't delete old ship API sessions", '', __LINE__, __FILE__, $sql);
}
- /*
+ /**
* Gets perso id from specified session
+ *
* @param string $session_id a session ID provided by calling application
* @return mixed the session
*/
function get_perso_from_session ($session_id) {
//Cleands old session
self::clean_ship_sessions();
//Reads api.ship.session.S00001.$session_id
//This registry key contains perso_id if it exists and valid
$key = sprintf("api.ship.session.%s.%s", $this->get_code(), $session_id);
return registry_get($key);
}
- /*
+ /**
* Loads a Ship object from its API key
+ *
* @param string $key API key GUID
* @return Ship the ship matching the API key
*/
static function from_api_key ($key) {
global $db;
$key = $db->sql_escape($key);
$sql = "SELECT * FROM ships WHERE api_key = '" . $key . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query ships", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result))
return null;
//Fills ship information
$ship = new Ship();
$ship->id = $row['ship_id'];
$ship->name = $row['ship_name'];
$ship->location = $row['ship_location'];
$ship->api_key = $row['api_key'];
$ship->description = $row['ship_description'];
return $ship;
}
}
?>
diff --git a/includes/objects/user.php b/includes/objects/user.php
--- a/includes/objects/user.php
+++ b/includes/objects/user.php
@@ -1,184 +1,217 @@
<?php
-/*
+/**
* User class
*
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
+ *
* 0.1 2010-01-27 00:33 Autogenerated by Pluton Scaffolding
* 0.2 2010-02-18 11:25 Compliance with strict mode
*
* [DESIGN BY CONTRACT NOTE] No more than one OpenID per user
+ *
+ * @package Zed
+ * @subpackage Model
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
+ */
+
+/**
+ * User class
*
- * @package Zed
- * @copyright Copyright (c) 2010, Dereckson
- * @license Released under BSD license
- * @version 0.1
+ * This class maps the users and users_openid tables.
*
+ * It also provides helper methods to check if a login is available,
+ * or to retrieve a username from e-mail address.
*/
class User {
public $id;
public $name;
public $password;
public $active = 0;
public $actkey;
public $email;
public $regdate;
- /*
+ /**
* Initializes a new instance
+ *
* @param int $id the primary key
*/
function __construct ($id = null) {
if ($id) {
$this->id = $id;
$this->load_from_database();
}
}
- /*
+ /**
* Loads the object User (ie fill the properties) from the $_POST array
*/
function load_from_form () {
if (array_key_exists('name', $_POST)) $this->name = $_POST['name'];
if (array_key_exists('password', $_POST)) $this->password = $_POST['password'];
if (array_key_exists('active', $_POST)) $this->active = $_POST['active'];
if (array_key_exists('actkey', $_POST)) $this->actkey = $_POST['actkey'];
if (array_key_exists('email', $_POST)) $this->email = $_POST['email'];
if (array_key_exists('regdate', $_POST)) $this->regdate = $_POST['regdate'];
}
- /*
+ /**
* Loads the object User (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$sql = "SELECT * FROM " . TABLE_USERS . " WHERE user_id = '" . $this->id . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query users", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "User unkwown: " . $this->id;
return false;
}
$this->name = $row['username'];
$this->password = $row['user_password'];
$this->active = $row['user_active'];
$this->actkey = $row['user_actkey'];
$this->email = $row['user_email'];
$this->regdate = $row['user_regdate'];
return true;
}
- /*
+ /**
* Saves to database
*/
function save_to_database () {
global $db;
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$name = $db->sql_escape($this->name);
$password = $db->sql_escape($this->password);
$active = $db->sql_escape($this->active);
$actkey = $db->sql_escape($this->actkey);
$email = $db->sql_escape($this->email);
$regdate = $this->regdate ? "'" . $db->sql_escape($this->regdate) . "'" : 'NULL';
//Updates or inserts
$sql = "REPLACE INTO " . TABLE_USERS . " (`user_id`, `username`, `user_password`, `user_active`, `user_actkey`, `user_email`, `user_regdate`) VALUES ($id, '$name', '$password', '$active', '$actkey', '$email', $regdate)";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
if (!$id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
}
- /*
+ /**
* Updates the specified field in the database record
*/
function save_field ($field) {
global $db;
if (!$this->id) {
message_die(GENERAL_ERROR, "You're trying to update a record not yet saved in the database");
}
$id = $db->sql_escape($this->id);
$value = $db->sql_escape($this->$field);
$sql = "UPDATE " . TABLE_USERS . " SET `$field` = '$value' WHERE user_id = '$id'";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save $field field", '', __LINE__, __FILE__, $sql);
}
}
- //Generates a unique user id
+ /**
+ * Generates a unique user id
+ */
function generate_id () {
global $db;
do {
$this->id = rand(2001, 5999);
$sql = "SELECT COUNT(*) FROM " . TABLE_USERS . " WHERE user_id = $this->id LOCK IN SHARE MODE;";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't access users table", '', __LINE__, __FILE__, $sql);
}
$row = $db->sql_fetchrow($result);
} while ($row[0]);
}
- /*
+ /**
* Fills password field with encrypted version of the specified clear password
+ *
* @param string $newpassword The user's new password
*/
public function set_password ($newpassword) {
$this->password = md5($newpassword);
}
- /*
+ /**
* Deletes OpenID for this user
*/
public function delete_OpenID () {
$this->set_OpenID('');
}
- /*
+ /**
* Sets OpenID for this user
+ *
* @param string $url OpenID endpoint URL
*/
public function set_OpenID ($url) {
global $db;
if (!$this->id) $this->save_to_database();
$url = $db->sql_escape($url);
$sql = "DELETE FROM " . TABLE_USERS_OPENID . " WHERE user_id = $this->id";
if (!$db->sql_query($sql))
message_die(SQL_ERROR, "Can't delete old OpenID", '', __LINE__, __FILE__, $sql);
if ($url != '') {
$sql = "INSERT INTO " . TABLE_USERS_OPENID . " (openid_url, user_id) VALUES ('$url', $this->id)";
if (!$db->sql_query($sql))
message_die(SQL_ERROR, "Can't add new OpenID", '', __LINE__, __FILE__, $sql);
}
}
- //Checks if a login is available
+ /**
+ * Checks if a login is available
+ *
+ * @param string $login the login to check
+ * @return bool true if the specified login is available ; otherwise, false.
+ */
public static function is_available_login ($login) {
global $db;
$sql = "SELECT COUNT(*) FROM " . TABLE_USERS . " WHERE username LIKE '$login' LOCK IN SHARE MODE;";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Utilisateurs non parsable", '', __LINE__, __FILE__, $sql);
}
$row = $db->sql_fetchrow($result);
return ($row[0] ? false : true);
}
- //Gets username from specified e-mail
+ /**
+ * Gets username from specified e-mail
+ *
+ * @param string $mail the mail to search
+ * @return string|bool the username matching the mail if found ; otherwise, false.
+ */
public static function get_username_from_email ($mail) {
global $db;
$sql = "SELECT username FROM " . TABLE_USERS . " WHERE user_email LIKE '$mail' LOCK IN SHARE MODE;";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Utilisateurs non parsable", '', __LINE__, __FILE__, $sql);
}
if ($row = $db->sql_fetchrow($result)) {
return $row['username'];
}
return false;
}
}
?>
\ No newline at end of file
diff --git a/includes/settings/page.php b/includes/settings/page.php
--- a/includes/settings/page.php
+++ b/includes/settings/page.php
@@ -1,120 +1,156 @@
<?php
-/*
- * Zed
- * (c) 2010, Dereckson, some rights reserved
- * Released under BSD license
+/**
+ * Settings: a settings page class
+ *
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
*
- * Settings page
+ * @package Zed
+ * @subpackage Settings
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
*/
require_once("setting.php");
-/*
- * @package Zed
- * @subpackage settings
+/**
+ * This class maps the page XML element, from our Settings XML schema
+ *
+ * <page id="account" title="Account">
+ * <setting ...>
+ * ...
+ * </setting>
+ * <setting ...>
+ * ...
+ * </setting>
+ * <page>
+ *
+ * It provides method to print a form built from this page and to handle form.
*/
class SettingsPage {
- /*
+ /**
+ * The page ID
+ *
+ * This property maps the id attribute from the page XML tag
+ *
* @var string the page ID
*/
public $id;
- /*
+ /**
+ * The page's title
+ *
+ * This property maps the title attribute from the page XML tag
+ *
* @var string the page title
*/
public $title;
- /*
- * @var Array the settings (array of Setting items)
+ /**
+ * The settings
+ *
+ * This property is an array of Setting items and maps the <setting> tags
+ * @var Array
*/
public $settings = array();
- /*
+ /**
* Initializes a new instance of SettingsPage class
+ *
+ * @param string $id the page ID
*/
function __construct ($id) {
$this->id = $id;
}
- /*
- * Intializes a settings page from an SimpleXMLElement XML fragment
+ /**
+ * Initializes a settings page from an SimpleXMLElement XML fragment
+ *
* @param SimpleXMLElement $xml the XML fragment
* @return SettingsPage the section instance
*/
static function from_xml ($xml) {
//Reads attributes
$id = ''; $title = '';
foreach ($xml->attributes() as $key => $value) {
switch ($key) {
case 'title':
case 'id':
$$key = (string)$value;
break;
default:
message_die(GENERAL_ERROR, "Unknown attribute: $key = \"$value\"", "Settings error");
}
}
//id attribute is mandatory
if (!$id) {
message_die(GENERAL_ERROR, "Section without id. Please add id='' in <section> tag", "Story error");
}
//Initializes new SettingsPage instance
$page = new SettingsPage($id);
$page->title = $title;
//Gets settings
if ($xml->setting) {
foreach ($xml->setting as $settingXml) {
$setting = Setting::from_xml($settingXml);
$page->settings[$setting->key] = $setting;
}
}
return $page;
}
- /*
+ /**
* Handles form reading $_POST array, set new settings values and saves.
+ *
* @param Array $errors an array where the errors will be filled
* @return boolean true if there isn't error ; otherwise, false.
*/
function handle_form (&$errors = array()) {
$objects = array();
//Sets new settings values
foreach ($this->settings as $setting) {
$value = $_POST[$setting->key];
if ($setting->field == "password" && !$value) {
//We don't erase passwords if not set
continue;
}
//If the setting value is different of current one, we update it
$currentValue = $setting->get();
if ($setting->field == "checkbox" || $currentValue != $value) {
if (!$setting->set($value)) {
$errors[] = $setting->lastError ? $setting->lastError : "An error have occured in $setting->key field.";
}
if ($setting->object) $objects[] = $setting->object;
}
}
//Saves object (when the SETTINGS_SAVE_METHOD save method exists)
if (count($objects)) {
$objects = array_unique($objects);
foreach ($objects as $object) {
$object = $GLOBALS[$object];
if (method_exists($object, SETTINGS_SAVE_METHOD)) {
call_user_func(array($object, SETTINGS_SAVE_METHOD));
}
}
}
}
}
\ No newline at end of file
diff --git a/includes/settings/setting.php b/includes/settings/setting.php
--- a/includes/settings/setting.php
+++ b/includes/settings/setting.php
@@ -1,160 +1,175 @@
<?php
-/*
- * Zed
- * (c) 2010, Dereckson, some rights reserved
- * Released under BSD license
+/**
+ * Settings: an individual setting class
+ *
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
*
- * Setting
+ * @package Zed
+ * @subpackage Settings
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
*/
-/*
- * @package Zed
- * @subpackage settings
+/**
+ * Setting class
+ *
+ * This class map the <setting> XML block, from our settings XML format
*/
class Setting {
public $key;
//Rendering variables
public $field;
public $regExp;
public $choices;
//get/set variables
public $object;
private $property;
private $method;
private $handler;
//error variable
public $lastError;
- /*
+ /**
* Gets the current setting value
+ *
* @return string the setting value
*/
function get () {
//1 - Evaluates custom handler
if (array_key_exists('get', $this->handler)) {
return eval($this->handler['get']);
}
//2 - Gets object property
if ($this->object && $property = $this->property) {
return $GLOBALS[$this->object]->$property;
}
if ($this->field == "password") {
//Okay not to have a value for password fields
return;
}
message_die(GENERAL_ERROR, "Setting $this->key haven't any get indication. Please set <object> and <property> / or a custom <handler><get></get></handler> block.", "Settings error");
}
-
- /*
+ /**
* Sets a new value
+ *
* @param $value the setting new value
* @return boolean true if the setting have been successfully set ; otherwise, false.
*/
function set ($value) {
//Validates data
if ($this->regExp) {
if (!preg_match('/^' . $this->regExp . '$/', $value)) {
$this->lastError = "Invalid format for $this->key setting";
return false;
}
}
//Tries to set value
//1 - Evaluates custom handler
if (array_key_exists('set', $this->handler)) {
return eval($this->handler['set']);
}
//2 - Calls object method
//3 - Sets object property
if ($this->object) {
$object = $GLOBALS[$this->object];
if ($this->method) {
return call_user_func(array($object, $this->method), $value);
} elseif ($property = $this->property) {
$object->$property = $value;
return true;
}
}
message_die(GENERAL_ERROR, "Setting $this->key haven't any set indication. Please set <object> (and wheter <method>, whether <property>) or a custom <handler><set></set></handler> block.", "Settings error");
}
- /*
+ /**
* Saves setting
+ *
* @return mixed the SETTINGS_SAVE_METHOD method value, or false if there's no method call;
*/
function save () {
if ($this->object) {
$object = $GLOBALS[$this->object];
if (method_exists($object, SETTINGS_SAVE_METHOD)) {
return call_user_func(array($object, SETTINGS_SAVE_METHOD));
}
}
return false;
}
- /*
+ /**
* Initializes a new instance of Setting class from a XML element
+ *
* @param SimpleXMLElement the xml element to parse
* @return Setting the setting class
*/
static function from_xml ($xml) {
//Reads attributes
$id = '';
foreach ($xml->attributes() as $key => $value) {
switch ($key) {
case 'id':
$id = (string)$value;
break;
default:
message_die(GENERAL_ERROR, "Unknown attribute: $key = \"$value\"", "Settings error");
}
}
//id attribute is mandatory
if (!$id) {
message_die(GENERAL_ERROR, "Setting without id. Please add id='' in <setting> tag", "Settings error");
}
//Initializes new Setting instance
$setting = new Setting($id);
//Parses simple <tag>value</tag>
$properties = array('key', 'field', 'object', 'property', 'method', 'regExp');
foreach ($properties as $property) {
if ($xml->$property)
$setting->$property = (string)$xml->$property;
}
//Parses <handler>
$setting->handler = array();
if ($xml->handler) {
if ($xml->handler->get) $setting->handler['get'] = (string)$xml->handler->get;
if ($xml->handler->set) $setting->handler['set'] = (string)$xml->handler->set;
}
//Parses <choices>
if ($xml->choices) {
foreach ($xml->choices->choice as $choiceXml) {
$setting->choices[(string)$choiceXml->key] = (string)$choiceXml->value;
}
}
return $setting;
}
}
?>
diff --git a/includes/settings/settings.php b/includes/settings/settings.php
--- a/includes/settings/settings.php
+++ b/includes/settings/settings.php
@@ -1,60 +1,84 @@
-<?php
-
-/*
- * Zed
- * (c) 2010, Dereckson, some rights reserved
- * Released under BSD license
- *
- * Settings
- */
-
-//The method to call in your objects, to save data.
-define("SETTINGS_SAVE_METHOD", "save_to_database");
-
-require_once("page.php");
-
-/*
- * @package Zed
- * @subpackage settings
- */
-class Settings {
-
- /*
- * @var string the file path
- */
- public $file;
-
- /*
- * @var Array a collection of SettingsPage items.
- */
- public $pages;
-
- /*
- * Initializes a new instance of Settings class
- */
- function __construct ($xmlFile) {
- //Opens .xml
- if (!file_exists($xmlFile)) {
- message_die(GENERAL_ERROR, "$xmlFile not found.", "Settings load error");
- }
-
- $this->file = $xmlFile;
- $this->parse();
- }
-
- /*
- * Parses XML file
- */
- function parse () {
- //Parses it
- $xml = simplexml_load_file($this->file);
- foreach ($xml->page as $page) {
- //Gets page
- $page = SettingsPage::from_xml($page);
-
- //Adds to sections array
- $this->pages[$page->id] = $page;
- }
- }
-}
+<?php
+
+/**
+ * Settings
+ *
+ * Zed. The immensity of stars. The HyperShip. The people.
+ *
+ * (c) 2010, Dereckson, some rights reserved.
+ * Released under BSD license.
+ *
+ * @package Zed
+ * @subpackage Settings
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @copyright 2010 Sébastien Santoro aka Dereckson
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @version 0.1
+ * @link http://scherzo.dereckson.be/doc/zed
+ * @link http://zed.dereckson.be/
+ * @filesource
+ */
+
+/**
+ * The method to call in your objects, to save data.
+ */
+define("SETTINGS_SAVE_METHOD", "save_to_database");
+
+require_once("page.php");
+
+/**
+ * Settings
+ *
+ * This class maps the Settings format (preferences.xml)
+ *
+ * It allows to generate settings web forms and handle replies, from a
+ * XML document.
+ */
+class Settings {
+
+ /**
+ * The file path
+ *
+ * @var string
+ */
+ public $file;
+
+ /**
+ * A collection of SettingsPage items
+ *
+ * @var Array
+ */
+ public $pages;
+
+ /**
+ * Initializes a new instance of Settings class
+ *
+ * @param string $xmlFile The XML document which defines the settings.
+ */
+ function __construct ($xmlFile) {
+ //Opens .xml
+ if (!file_exists($xmlFile)) {
+ message_die(GENERAL_ERROR, "$xmlFile not found.", "Settings load error");
+ }
+ $this->file = $xmlFile;
+
+ //Parses it
+ $this->parse();
+ }
+
+ /**
+ * Parses XML file
+ */
+ function parse () {
+ //Parses it
+ $xml = simplexml_load_file($this->file);
+ foreach ($xml->page as $page) {
+ //Gets page
+ $page = SettingsPage::from_xml($page);
+
+ //Adds to sections array
+ $this->pages[$page->id] = $page;
+ }
+ }
+}
?>
\ No newline at end of file

File Metadata

Mime Type
text/x-diff
Expires
Sun, Nov 3, 22:34 (3 w, 5 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
21177
Default Alt Text
(259 KB)

Event Timeline