Page MenuHomeCode

No OneTemporary

This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/api.php b/api.php
index 44c1118..c601d6c 100644
--- a/api.php
+++ b/api.php
@@ -1,332 +1,332 @@
<?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
$Config['SiteURL'] = get_server_url() . $_SERVER["PHP_SELF"];
$url = get_current_url_fragments();
switch ($module = $url[0]) {
/* -------------------------------------------------------------
Site API
/time
/location
/coordinates
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case '':
//Nothing to do
//TODO: offer documentation instead
die();
case 'time':
//Hypership time
api_output(get_hypership_time(), "time");
break;
case 'location':
- //Checks creditentials
+ //Checks credentials
cerbere();
//Gets location info
require_once("includes/geo/location.php");
$location = new GeoLocation($url[1], $url[2]);
api_output($location, "location");
break;
case 'coordinates':
- //Checks creditentials
+ //Checks credentials
cerbere();
- //Get coordiantes
+ //Get coordinates
api_output(GeoGalaxy::getCoordinates(), 'galaxy', 'object');
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/content/travel.xml b/content/travel.xml
index 837bbdd..8c499bf 100644
--- a/content/travel.xml
+++ b/content/travel.xml
@@ -1,69 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This document contains travel rules.
By default, travel inside a place is restricted and should be handled
by /explore mechanisms.
- To allow wheter a local move, wheter a move to another place, you've
+ To allow whether a local move, whether a move to another place, you've
to add an TravelPlace entry.
When you need regular behavior, without any exception, you don't need
to list the place here.
-->
<Travel>
<TravelPlace code="B00001001" freeLocalMove="true">
<!--
HyperShip tower allows free movement, at least in corridors.
For other locations, we should trust /explore mechanism to
implement a security kick, if the perso have no access.
Then, we allow travel to core and bays
-->
<GlobalTravelTo code="B00001002" />
<GlobalTravelTo code="B00001003" />
<!--
To ease the movements in the ship, we can write the sector name
-->
<RewriteRule expression="/^T([1-9][0-9]*)$/" global_location="B00001001" local_location="T$1C1" />
<RewriteRule expression="/^C([1-8])$/" global_location="B00001002" local_location="C$1" />
</TravelPlace>
<TravelPlace code="B00001002">
<!-- From the HyperShip core, perso can travel to tower and bays -->
<GlobalTravelTo code="B00001001" />
<GlobalTravelTo code="B00001003" />
<!-- And we add local travel exceptions allowing limited usage
to free travel movements to reach the 8 core cubes.
-->
<LocalMove local_location="(-10, 6, -4)" alias="C1" name="Secteur C1" />
<LocalMove local_location="(10, 6, -4)" alias="C2" name="Secteur C2" />
<LocalMove local_location="(-10, -6, -4)" alias="C3" name="Secteur C3" />
<LocalMove local_location="(10, -6, -4)" alias="C4" name="Secteur C4" />
<LocalMove local_location="(-10, 6, 4)" alias="C5" name="Secteur C5" />
<LocalMove local_location="(10, 6, 4)" alias="C6" name="Secteur C6" />
<LocalMove local_location="(-10, -6, 4)" alias="C7" name="Secteur C7" />
<LocalMove local_location="(10, -6, 4)" alias="C8" name="Secteur C8" />
<!--
To ease the movements in the ship, we can write the sector name
-->
<RewriteRule expression="/^T([1-9][0-9]*)$/" global_location="B00001001" local_location="T$1C1" />
<RewriteRule expression="/^(T[1-9][0-9]*C[1-6])$/" global_location="B00001001" local_location="$1" />
</TravelPlace>
<TravelPlace code="B00001003">
<!-- From the HyperShip core, perso can travel to core and tower -->
<GlobalTravelTo code="B00001001" />
<GlobalTravelTo code="B00001002" />
<!--
To ease the movements in the ship, we can write the sector name
-->
<RewriteRule expression="/^T([1-9][0-9]*)$/" global_location="B00001001" local_location="T$1C1" />
<RewriteRule expression="/^(T[1-9][0-9]*C[1-6])$/" global_location="B00001001" local_location="$1" />
<RewriteRule expression="/^C([1-8])$/" global_location="B00001002" local_location="C$1" />
</TravelPlace>
</Travel>
diff --git a/controllers/anonymous.php b/controllers/anonymous.php
index 50ca610..955fb15 100644
--- a/controllers/anonymous.php
+++ b/controllers/anonymous.php
@@ -1,154 +1,154 @@
<?php
/**
* 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.
*
* It recognizes the following URLs:
- * /tour a redirect to tour.html file, a visite guidée drom Zed ;
+ * /tour a redirect to tour.html file, a visite guidée from 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.
+ //Not existing 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
+ //Notifies host
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);
}
diff --git a/controllers/builder.php b/controllers/builder.php
index c5014bc..94d9373 100644
--- a/controllers/builder.php
+++ b/controllers/builder.php
@@ -1,135 +1,135 @@
<?php
/**
* Builder
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* @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/gpl-2.0.php GPLv2
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
require_once('includes/content/zone.php');
//
// Helper methods
//
/**
* Determines if a specified location is buildable
*
* @param GeoLocation $location the location to check
- * @param string if the location isn't buidable, a textual description of why.
+ * @param string if the location isn't buildable, a textual description of why.
* @return bool true if the location is buildable ; otherwise, false
*
* @todo create a build.xml document to set what's buildable, and by who
*/
function is_buildable ($location, &$error = '') {
//We currently allow build only in the hypership tower and core.
if (!$location->body->hypership) {
$error = "You can only invoke the HyperShip builder facilities inside the HyperShip.";
return false;
}
//if ($build_location->place->code == "001") {
// //Don't allow custom builds in the corridor (T?C?)
//}
if ($build_location->place->code == "003") {
message_die("Bays aren't buildable.");
return false;
}
return true;
}
//
// Determines mode and initializes resources
//
switch ($build_mode = $url[1]) {
case 'map':
require_once('includes/geo/octocube.php');
$build_mode = 'map';
//Get zones at this floor
if ($CurrentPerso->location->global == 'B00001002') {
$point = GeoPoint3D::fromString($CurrentPerso->location->local);
$sector = GeoOctocube::getSectorFromPoint3D($point);
$pattern = GeoOctocube::getRlikePatternFromSector($sector, $point->z);
$zones = ContentZone::search($CurrentPerso->location->global, $pattern, true);
} else {
message_die(GENERAL_ERROR, "Can't map this area.", "Builder :: Map");
}
//Template
define('DOJO', true);
$smarty->assign('zones', $zones);
$template = "builder_map.tpl";
break;
case '':
case 'hotglue':
//Temporary initialization code, to allow some build during the Zed alphatest
$build_location = $CurrentPerso->location;
$build_mode = 'hotglue';
$error = '';
if (!is_buildable($build_location, $error)) {
message_die(GENERAL_ERROR, $error, "Can't build");
}
//Gets or creates a new zone at build location
$zone = ContentZone::at($build_location->global, $build_location->local, true);
switch ($zone->type) {
case 'hotglue':
//All rulez
break;
case '':
//New zone
$zone->title = "Sandbox hotglue zone for $build_location->global $build_location->local";
$zone->type = 'hotglue';
$zone->save_to_database();
break;
default:
message_die("This isn't a zone managed by hotglue.");
}
unset($error);
//Template
$smarty->assign('location', $build_location);
$smarty->assign('zone', $zone);
$smarty->assign('IFRAME_SRC', '/apps/hotglue/index.php?zone_' . $zone->id . '/edit');
$template = 'builder_hotglue.tpl';
break;
default:
message_die(GENERAL_ERROR, "Unknown build mode: $build_mode");
}
//
// HTML output
//
//Serves header
$smarty->assign('PAGE_TITLE', 'Builder');
include('header.php');
//Serves content
$smarty->display($template);
//Serves footer
include('footer.php');
diff --git a/controllers/home.php b/controllers/home.php
index 80bbe88..3413614 100644
--- a/controllers/home.php
+++ b/controllers/home.php
@@ -1,102 +1,102 @@
<?php
/**
* 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.
*
* 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.
+ * @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 optional .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
+//hypership .tpl scene. We should create an optional .meta xml file format
//to set this kind of options
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');
diff --git a/controllers/motd.php b/controllers/motd.php
index 5867b80..60116c5 100644
--- a/controllers/motd.php
+++ b/controllers/motd.php
@@ -1,54 +1,54 @@
<?php
/**
* 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.
*
* 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.
+ * It uses 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');
diff --git a/controllers/page.php b/controllers/page.php
index 4bc306c..516eef4 100644
--- a/controllers/page.php
+++ b/controllers/page.php
@@ -1,133 +1,133 @@
<?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.
+ * It uses 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)
+ * @todo move "handle editor form" and some of the "gets page" code to a includes/objects/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');
diff --git a/controllers/persorequest.php b/controllers/persorequest.php
index afca926..d5c3f2d 100644
--- a/controllers/persorequest.php
+++ b/controllers/persorequest.php
@@ -1,166 +1,166 @@
<?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 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
+ * Initialises 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 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
require_once('include/objects/ship.php');
$ship_code = substr($flag, 22);
$ship = Ship::get($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
require_once('include/objects/ship.php');
$ship_code = substr($flag, 25, 6);
$ship = Ship::get($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;
}
diff --git a/controllers/profile.php b/controllers/profile.php
index b990001..6dd1e7a 100644
--- a/controllers/profile.php
+++ b/controllers/profile.php
@@ -1,344 +1,344 @@
<?php
/**
* User profile
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* This is a controller allowing user profile view and edit.
*
* It handles the following URLs:
* /who/<perso nickname> views the nickname's profile,
* /who/random views a random profile,
- * /who/edit/profile edits its profileq
+ * /who/edit/profile edits its profile
* /who/edit/account edits its account (disabled on Zed, cf. settings),
* /who/edit/photo(s) manages its profile's photos,
* /who/edit/photo/edit/<photo id> edits a photo properties,
* /who/edit/photo/delete/<photo id> deletes a photo,
* /who/edit/photo/avatar/<photo id> promotes a photo to avatar.
*
* The following views are used:
* profile.tpl,
* profile_edit.tpl,
* user_account.tpl,
* profile_photo.tpl,
* profile_photo_edit.tpl.
*
* The following models are used:
* Profile,
* ProfilePhoto,
* ProfileComment.
*
* The view profile_tags.tpl is indirectly used by the Profile model.
*
* This code is maintained in // with Azhàr.
*
* @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
*/
//Loads language file
lang_load('profile.conf');
//Gets perso nickname from URL
$who = $url[1];
switch ($who) {
case 'edit':
$mode = 'edit';
$who = $CurrentPerso->nickname;
break;
case 'random':
$mode = 'view';
$who = $db->sql_query_express("SELECT perso_id FROM " . TABLE_PROFILES . " ORDER BY rand() LIMIT 1");
break;
default:
$mode = 'view';
}
if (!$who) {
message_die(GENERAL_ERROR, "Who?", "URL error");
}
//Libs
require_once('includes/objects/profile.php');
require_once('includes/objects/profilecomment.php');
require_once('includes/objects/profilephoto.php');
//Gets perso information
require_once('includes/objects/perso.php');
$perso = Perso::get($who);
if ($perso->lastError) {
message_die(GENERAL_ERROR, $perso->lastError, "Error");
}
$smarty->assign('perso', $perso);
//Gets profile
$profile = new Profile($perso->id);
//Handles form
if ($_POST['EditProfile']) {
$profile->load_from_form();
$profile->updated = time();
$profile->save_to_database();
$mode = 'view';
} elseif ($_POST['UserAccount']) {
$smarty->assign('WAP', "This form have been deprecated. You can write instead settings in the SmartLine");
} elseif ($_POST['message_type'] == 'private_message') {
//Sends a message
require_once('includes/objects/message.php');
$msg = new Message();
$msg->from = $CurrentPerso->id;
$msg->to = $perso->id;
$msg->text = $_POST['message'];
$msg->send();
if ($msg->from == $msg->to) {
$smarty->assign('NOTIFY', lang_get('MessageSentSelf'));
} else {
$smarty->assign('NOTIFY', lang_get('MessageSent'));
}
} elseif ($_POST['message_type'] == 'profile_comment') {
//New profile comment
$comment = new ProfileComment();
$comment->author = $CurrentPerso->id;
$comment->perso_id = $perso->id;
$comment->text = $_POST['message'];
$comment->publish();
$smarty->assign('NOTIFY', lang_get('CommentPublished'));
} elseif ($_FILES['photo']) {
#We've a file !
$hash = md5(microtime() . serialize($_FILES));
$extension = get_extension($_FILES['photo']['name']);
$filename = $CurrentPerso->id . '_' . $hash . '.' . $extension;
#We ignore $_FILES[photo][error] 4, this means no file has been uploaded
#(so user doesn't want upload a new file)
#See http:/www.php.net/features.file-upload and http://www.php.net/manual/en/features.file-upload.errors.php about common errors
#Not valid before PHP 4.2.0
switch ($_FILES['photo']['error']) {
case 0:
#There is no error, the file uploaded with success.
if (!move_uploaded_file($_FILES['photo']['tmp_name'], PHOTOS_DIR . '/' . $filename)) {
$errors[] = "Upload successful, but error saving it.";
} else {
//Attaches the picture to the profile
$photo = new ProfilePhoto();
$photo->name = $filename;
$photo->perso_id = $CurrentPerso->id;
$photo->description = $_POST['description'];
if ($photo->avatar) $photo->promote_to_avatar();
$photo->save_to_database();
//Generates thumbnail
if (!$photo->generate_thumbnail()) {
$smarty->assign('WAP', "Error generating thumbnail.");
}
$smarty->assign('NOTIFY', lang_get('PhotoUploaded'));
$mode = 'view';
}
break;
case 1:
$errors[] = "The file is too large.";
break;
#TODO : more explicit error messages
default:
$errors[] = "Unknown error (#" . $_FILES['photo']['error'] . ")";
break;
}
if (count($errors)) {
$smarty->assign('WAP', join($errors, '<br />'));
}
} elseif ($_POST['id']) {
//Edits photo properties
$photo = new ProfilePhoto($_POST['id']);
if ($photo->lastError) {
$smarty->assign('WAP', $photo->lastError);
$mode = 'view';
} elseif ($photo->perso_id != $CurrentPerso->id) {
$smarty->assign('WAP', lang_get('NotYourPic'));
$mode = 'view';
} else {
//OK
$wereAvatar = $photo->avatar;
$photo->load_from_form();
if (!$wereAvatar && $photo->avatar) {
//Promote to avatar
$photo->promote_to_avatar();
}
$photo->save_to_database();
}
}
//Prepares output
if ($profile->text) {
//Profile
$smarty->assign('PROFILE_TEXT', $profile->text);
$smarty->assign('PROFILE_FIXEDWIDTH', $profile->fixedwidth);
}
if ($mode == 'view') {
require_once('includes/objects/profilephoto.php');
//Self profile?
$self = $CurrentPerso->id == $profile->perso_id;
//Gets profiles comments, photos, tags
$comments = ProfileComment::get_comments($profile->perso_id);
$photos = ProfilePhoto::get_photos($profile->perso_id);
$tags = $profile->get_cached_tags();
//Records timestamp, to be able to track new comments
if ($self) $CurrentPerso->set_flag('profile.lastvisit', time());
//Template
$smarty->assign('PROFILE_COMMENTS', $comments);
$smarty->assign('PROFILE_SELF', $self);
if ($tags) $smarty->assign('PROFILE_TAGS', $tags);
$smarty->assign('USERNAME', $perso->username);
$smarty->assign('NAME', $perso->name ? $perso->name : $perso->nickname);
$template = 'profile.tpl';
} elseif ($mode == 'edit') {
switch ($url[2]) {
case 'profile':
$smarty->assign('USERNAME', $perso->name);
$smarty->assign('DIJIT', true);
$css[] = THEME . '/forms.css';
$template = 'profile_edit.tpl';
break;
case 'account':
$smarty->assign('user', $CurrentUser);
$smarty->assign('DIJIT', true);
$css[] = THEME . '/forms.css';
$template = 'user_account.tpl';
break;
case '':
$smarty->assign('NOTIFY', "What do you want to edit ? Append /profile, /account or /photos to the URL");
break;
case 'photo':
case 'photos':
$smarty->assign('USERNAME', $perso->name);
switch ($action = $url[3]) {
case '':
//Nothing to do
break;
case 'delete':
//Deletes a picture
if (!$id = $url[4]) {
$smarty->assign('WAP', "URL error. Parameter missing: picture id.");
} else {
$photo = new ProfilePhoto($id);
if ($photo->lastError) {
//Probably an non existent id (e.g. double F5, photo already deleted)
$smarty->assign('WAP', $photo->lastError);
} elseif ($photo->perso_id != $CurrentPerso->id) {
$smarty->assign('WAP', lang_get('NotYourPic'));
} else {
//OK we can delete it
$photo->delete();
$smarty->assign('NOTIFY', lang_get('PictureDeleted'));
}
}
break;
case 'edit':
if (!$id = $url[4]) {
$smarty->assign('WAP', "URL error. Parameter missing: picture id.");
} else {
$photo = new ProfilePhoto($id);
if ($photo->lastError) {
//Probably an non existent id (e.g. double F5, photo already deleted)
$smarty->assign('WAP', $photo->lastError);
} elseif ($photo->perso_id != $CurrentPerso->id) {
$smarty->assign('WAP', lang_get('NotYourPic'));
} else {
//Photo information edit form
$smarty->assign('photo', $photo);
$template = 'profile_photo_edit.tpl';
}
}
break;
case 'avatar':
//Promotes a picture to avatar
if (!$id = $url[4]) {
$smarty->assign('WAP', "URL error. Parameter missing: picture id.");
} else {
$photo = new ProfilePhoto($id);
if ($photo->lastError) {
$smarty->assign('WAP', $photo->lastError);
} elseif ($photo->perso_id != $CurrentPerso->id) {
$smarty->assign('WAP', lang_get('NotYourPic'));
} else {
//OK, promote it to avatar
$photo->promote_to_avatar();
$photo->save_to_database();
$smarty->assign('NOTIFY', lang_get('PromotedToAvatar'));
}
}
break;
default:
$smarty->assign('WAP', "Unknown URL. To delete a picture it's /delete/<picture id>. To edit it /edit/<picture id>");
break;
}
if (!$template) {
$photos = ProfilePhoto::get_photos($profile->perso_id);
if (!$smarty->tpl_vars['NOTIFY'])
$smarty->assign('NOTIFY', "Your feedback is valued. Report any bug or suggestion on the graffiti wall.");
$template = 'profile_photo.tpl';
}
break;
default:
$smarty->assign('WAP', "URL error. You can use /edit with profile, account or photos.");
break;
}
}
//
// HTML output
//
//Photos
if (count($photos) || $photo) {
$smarty->assign('URL_PICS', PHOTOS_URL);
$css[] = 'lightbox.css';
$smarty->assign('PAGE_JS', array('prototype.js', 'effects.js', 'lightbox.js'));
$smarty->assign('PICS', $photos);
}
//Serves header
$css[] = THEME . "/profile.css";
$smarty->assign('PAGE_CSS', $css);
$smarty->assign('PAGE_TITLE', $perso->name);
include('header.php');
//Serves content
if ($template) $smarty->display($template);
//Serves footer
include('footer.php');
diff --git a/controllers/raw.php b/controllers/raw.php
index 8aa63bc..707f90c 100644
--- a/controllers/raw.php
+++ b/controllers/raw.php
@@ -1,61 +1,61 @@
<?php
/**
* Raw text ou HTML content
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* This is a controller printing HTML content as is.
*
* It prints the raw.tpl view containing two variables:
- * - PAGE_TITLE (optionnal), to add a H1 page title
+ * - PAGE_TITLE (optional), to add a H1 page title
* - CONTENT (should be defined), the content to print
*
* To use it:
* <code>
* //(1) Assign your HTML content in CONTENT smarty variable:
* $content = "Hello World!";
* $smarty->assign('CONTENT', $content);
*
* //(2) Call the raw controller
* include('controllers/raw.php');
*
* //That's all folk.
* </code>
*
* To add a title:
* <code>
* $content = "Hello World";
* $title = "Raw sample";
*
* $smarty->assign('PAGE_TITLE', $title);
* $smarty->assign('CONTENT', $content);
* </code>
*
* @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
*/
//
// HTML output
//
//Serves header
$smarty->assign('PAGE_TITLE', $title);
include('header.php');
//Serves content
$smarty->display('raw.tpl');
//Serves footer
include('footer.php');
diff --git a/controllers/ship.php b/controllers/ship.php
index 1ca316b..1aec9e8 100644
--- a/controllers/ship.php
+++ b/controllers/ship.php
@@ -1,88 +1,88 @@
<?php
/**
* Ship
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* This controller handle the /ship URL
*
* It allows the user to let personal notes about the ship.
*
* It uses the Ship model and the ship.tpl view
*
* @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 prints information indicating if we're or not in the ship
* @todo implement a console to control the ship
*/
//
// Load library and language file
//
require_once('includes/objects/ship.php');
lang_load('ships.conf');
//
// Ship information
//
//Gets ship from URL
if (count($url) < 2) {
- //No parameter, gets ship perso is onboard
+ //No parameter, gets ship perso is aboard
if (!$code = $CurrentPerso->location->ship_code) {
message_die(GENERAL_ERROR, lang_get("NotAboardNoCode"), lang_get("URLError"));
//"
}
$code = 'S' . $code;
} else {
//Code have been specified
$code = $url[1];
if (!preg_match("/^S[0-9]{5}$/", $code)) {
message_die(GENERAL_ERROR, lang_get("InvalidShipCode"), lang_get("URLError"));
}
}
//Gets relevant information
$ship = Ship::get($code);
$note = $CurrentPerso->get_note($code);
//Determines the spatial relation between perso and ship
//dieprint_r($CurrentPerso->location->ship_code);
//
// Actions handling
//
if ($_REQUEST['action'] == 'ship.setnote' && $_REQUEST['note'] != $note) {
//Updates note content
$CurrentPerso->set_note($code, $_REQUEST['note']);
$note = $_REQUEST['note'];
}
//
// HTML output
//
//Serves header
$smarty->assign('PAGE_TITLE', $ship->name);
include('header.php');
//Serves content
$smarty->assign('note', $note);
$smarty->assign('ship', $ship);
$smarty->display('ship.tpl');
//Serves footer
include('footer.php');
diff --git a/dev/quux.php b/dev/quux.php
index deb80b8..54f34a6 100644
--- a/dev/quux.php
+++ b/dev/quux.php
@@ -1,161 +1,161 @@
<?php
require_once('includes/objects/ship.php');
require_once('includes/objects/port.php');
require_once('includes/objects/application.php');
require_once('includes/objects/content.php');
require_once('includes/objects/message.php');
require_once('includes/objects/invite.php');
require_once('includes/cache/cache.php');
include('controllers/header.php');
$case = 'YubiCloud';
switch ($case) {
case 'YubiCloud':
require_once('Auth/Yubico.php');
echo '<h2>YubiKey</h2>';
if (!array_key_exists('YubiCloud', $Config)) {
message_die(GENERAL_ERROR, "YubiCloud authentication not configured. Add \$Config['YubiCloud']['ClientID'] and \$Config['YubiCloud']['SecretKey'] to your config.");
}
if (!$key = $_GET['OTP']) {
message_die(GENERAL_ERROR, "Please add in URL ?OTP=, then put your cursor at right of the = and press your YubiKey button");
}
- $yubi = new Auth_Yubico($Config['YubiCloud']['ClientID'], $Config['YubiCloud']['SecreyKey']);
+ $yubi = new Auth_Yubico($Config['YubiCloud']['ClientID'], $Config['YubiCloud']['SecretKey']);
if (!$data = $yubi->parsePasswordOTP($key)) {
message_die(GENERAL_ERROR, "This is not an YubiKey OTP.");
}
$prefix = $data['prefix'];
$auth = $yubi->verify($key);
if (@PEAR::isError($auth)) {
if ($auth->getMessage() == 'REPLAYED_OTP') {
message_die("This OTP has already been used.");
}
message_die(HACK_ERROR, "<p>Authentication failed: " . $auth->getMessage() . "</p><p>Debug: " . $yubi->getLastResponse() . "</p>");
} else {
print "<p>You are authenticated!</p>";
}
break;
case 'GeoPointPolarZ':
require_once('includes/geo/pointPolarZ.php');
echo "<H2>GeoPointPolarZ</H2>";
$point = GeoPointPolarZ::fromString("(48, 30°, 3)");
printf("Secteur T%dC%d, zone %d-%d");
dprint_r($point);
break;
case 'index_scenes':
$time[] = microtime();
require_once('includes/geo/scene.php');
require_once('includes/geo/sceneindex.php');
$cache = Cache::load();
if ($index = $cache->get('GeoSceneIndex')) {
$index = unserialize($index);
} else {
$index = GeoSceneIndex::Load(SCENE_DIR);
$cache->set('GeoSceneIndex', serialize($index));
}
$time[] = microtime();
echo '<H2>GeoSceneIndex</H2>';
dprint_r($index);
echo '<H2>Time (ms)</H2>';
dprint_r(1000 * ($time[1] - $time[0]));
dprint_r($time);
break;
case 'travel':
require_once('includes/travel/travel.php');
$travel = Travel::load();
dieprint_r($travel);
break;
case 'spherical':
require_once('includes/geo/galaxy.php');
echo '<H2>Spherical coordinates test</H2>';
echo '<table cellpadding=8>';
echo "<tr><th>Name</th><th>Type</th><th>Cartesian coords</th><th>Spherical I</th><th>Spherical II</th><th>Pencil coordinates</th></tr>";
$objects = GeoGalaxy::getCoordinates();
foreach ($objects as $row) {
echo "<tr><th style='text-align: left'>$row[0]</th><td>$row[1]</td><td>$row[2]</td>";
$pt = $row[2];
echo '<td>(', implode(', ', $pt->toSpherical()), ')</td>';
echo '<td>(', implode(', ', $pt->toSphericalAlternative()), ')</td>';
$pt->translate(500, 300, 200, 2);
echo '<td>', $pt, '</td>';
echo '</tr>';
}
echo '</table>';
break;
case 'travel':
require_once('includes/travel/travel.php');
require_once('includes/travel/place.php');
$cache = Cache::load();
$travel = $cache->get('zed_travel');
if ($travel == '') {
$travel_nocached = new Travel();
$travel_nocached->load_xml("content/travel.xml");
$cache->set('zed_travel', serialize($travel_nocached));
} else {
$travel = unserialize($travel);
}
dieprint_r($travel);
break;
case 'perso.create.notify':
$testperso = Perso::get(4733);
$message = new Message();
$message->from = 0;
$message->to = invite::who_invited(4733);
$url = get_server_url() . get_url('who', $testperso->nickname);
$message->text = sprintf(lang_get('InvitePersoCreated'), $testperso->name, $url);
$message->send();
dieprint_r($message);
break;
case 'pushdata';
echo '
<h2>/api.php/app/pushdata</h2>
<form method="post" action="/api.php/app/pushdata?mode=file&key=37d839ba-f9fc-42ca-a3e8-28053e979b90" enctype="multipart/form-data">
<input type="file" name="datafile" /><br />
<input type="submit" value="Send file" />
</form>
';
break;
case 'thumbnail':
$content = new Content(1);
dprint_r($content);
$content->generate_thumbnail();
break;
case 'port':
echo '<h2>Port::from_location test</h2>';
$locations = array("B00002", "B00002123", "B00001001", "xyz: [800, 42, 220]");
foreach ($locations as $location) {
dprint_r(Port::from_location($location));
}
break;
case 'ext':
$file = 'dev/foo.tar';
echo "<h2>$file</h2>";
echo "<h3>.tar.bz2</h3>";
echo ereg('\.tar\.bz2$', $file);
echo "<h3>.tar</h3>";
echo ereg('\.tar$', $file);
break;
case 'app':
echo Application::from_api_key("37d839ba-f9fc-42ca-a3e8-28053e979b90")->generate_userkey();
break;
case '':
dieprint_r("No case currently selected.");
break;
}
include('controllers/footer.php');
diff --git a/dev/scripts/autoload.tcl b/dev/scripts/autoload.tcl
index 706e443..326b195 100755
--- a/dev/scripts/autoload.tcl
+++ b/dev/scripts/autoload.tcl
@@ -1,133 +1,133 @@
#!/usr/local/bin/tclsh8.5
#
# php-autoload-generator
-# (c) Sébastien Santoro aka Dereckson, 2010-2013, some rights resrved.
+# (c) Sébastien Santoro aka Dereckson, 2010-2013, some rights reserved.
# Released under BSD license
#
# Last version of the code can be fetch at:
# http://bitbucket.org/dereckson/php-autoload-generator
#
# This code generator write a __autoload() PHP method, when you don't have a
# consistent pattern for classes naming and don't want to register several
# autoloader with spl_autoload_register().
#
# Parses your classes folder & reads each file to check if it contains classes.
#
#
# Configuration
#
#A list of regexp, one per directory to ignore
set config(directoriesToIgnore) {Smarty SmartLine}
#The output to produce before the lines
set config(templateBefore) "<?php
/**
* This magic method is called when a class can't be loaded
*/
function __autoload (\$className) {
//Classes"
#The output to produce after the
set config(templateAfter) "
//Loader
if (array_key_exists(\$className, \$classes)) {
require_once(\$classes\[\$className]);
}
}"
#The line format, for %%lines%%
set config(templateClassLine) { $classes['%%class%%'] = '%%file%%';}
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# Helpers methods
#
#Find .php script
proc find_scripts {directory} {
set dirs {}
foreach i [lsort [glob -nocomplain -dir $directory *]] {
if {[file type $i] == "directory" && ![is_ignored_directory $i]} {
lappend dirs $i
} elseif {[file extension $i] == ".php"} {
find_objects $i
}
}
foreach subdir $dirs {
#Adds a white line as a separator, then the classes in this dir
puts ""
find_scripts $subdir
}
}
#Called when we've got a winner
proc add_class {script class} {
global config
set line $config(templateClassLine)
regsub -all -- "%%class%%" $line $class line
regsub -all -- "%%file%%" $line $script line
puts $line
}
#Find objects like classes or interfaces in the file
#Thanks to Richard Suchenwirth for its glob-r code snippet this proc is forked
proc find_objects {file} {
set fp [open $file]
while {[gets $fp line] >= 0} {
set pos1 [string first "class " $line]
if {$pos1 == -1} {
set pos1 [string first "interface " $line]
set len 10
} {
set len 6
}
set pos2 [string first " \{" $line $pos1]
set pos3 [string first " implements" $line $pos1]
set pos4 [string first " extends" $line $pos1]
if {$pos1 > -1 && $pos2 > -1} {
if {$pos4 > -1} {
#We test implements first, as if a class implements and extends
#the syntax is class Plane extends Vehicle implements FlyingItem
set pos $pos4
} elseif {$pos3 > -1} {
set pos $pos3
} else {
set pos $pos2
}
set class [string range $line [expr $pos1 + $len] [expr $pos - 1]]
add_class $file $class
}
}
close $fp
}
#Check if the directory is ignored
proc is_ignored_directory {directory} {
global config
foreach re $config(directoriesToIgnore) {
if [regexp $re $directory] {return 1}
}
return 0
}
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# Procedural code
#
if {$argc > 0} {
set directory [lindex $argv 0]
} {
set directory .
}
puts $config(templateBefore)
find_scripts $directory/includes
puts $config(templateAfter)
diff --git a/do.php b/do.php
index e6beaab..0d4d82f 100644
--- a/do.php
+++ b/do.php
@@ -1,474 +1,474 @@
<?php
/**
* AJAX callbacks
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* As main controller could potentially be interrupted (e.g. if site.requests
* flag is at 1, user is redirected to controllers/userrequest.php), all AJAX
* queries should be handled by this script and not directly by the controllers.
*
* Standard return values:
* -7 user is logged but perso isn't selected,
* -9 user is not logged.
*
* @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
*/
////////////////////////////////////////////////////////////////////////////////
///
/// Constants
///
//We define one negative number constant by standard erroneous return value.
/**
* Magic number which indicates the user is not logged in.
*/
define('USER_NOT_LOGGED', -9);
/**
* Magic number which indicates the user is logged in, but haven't selected its perso.
*/
define('PERSO_NOT_SELECTED', -7);
////////////////////////////////////////////////////////////////////////////////
///
/// Initialization
///
include('includes/core.php');
//Session
$IP = encode_ip($_SERVER["REMOTE_ADDR"]);
require_once('includes/story/story.php'); //this class can be stored in session
session_start();
$_SESSION[ID] = session_id();
session_update(); //updates or creates the session
//Gets current perso
require_once('includes/objects/perso.php');
$CurrentUser = get_logged_user(); //Gets current user infos
if ($perso_id = $CurrentUser->session['perso_id']) {
$CurrentPerso = new Perso($perso_id);
}
//Requires user and perso
if ($CurrentUser->id < 1000) {
echo USER_NOT_LOGGED;
exit;
}
if (!$CurrentPerso) {
echo PERSO_NOT_SELECTED;
exit;
}
//Loads Smarty (as it handles l10n, it will be used by lang_get)
require('includes/Smarty/Smarty.class.php');
$smarty = new Smarty();
$current_dir = dirname(__FILE__);
$smarty->template_dir = $current_dir . '/skins/zed';
$smarty->compile_dir = $current_dir . '/cache/compiled';
$smarty->cache_dir = $current_dir . '/cache';
$smarty->config_dir = $current_dir;
//Loads language files
initialize_lang();
lang_load('core.conf');
////////////////////////////////////////////////////////////////////////////////
///
/// Actions definitions
///
/**
* Actions class
*
* Each method is called by first part of your URL, other parts are arguments
* e.g. /do.php/validate_quux_request/52 = Actions::validate_quux_request(52);
*
* You can also use $_GET, $_POST or better $_REQUEST.
*
* Don't print the value but return it, so we can in the future implement custom
* formats like api_output();
*/
class Actions {
/**
- * Checks the arguments hash and determines wheter it is valid.
+ * Checks the arguments hash and determines whether it is valid.
*
* @param Array $args the arguments, the last being the hash
* @return boolean true if the hash is valid ; otherwise, false.
*/
static private function is_hash_valid ($args) {
global $Config;
return array_pop($args) == md5($_SESSION['ID'] . $Config['SecretKey'] . implode('', $args));
}
/**
* Handles a allow/deny perso request.
*
* @param string $request_flag the request flag to clear
* @param string $store 'perso' or 'registry'
* @param string $key the perso flag or registry key
* @param string $value the value to store
* @param string $hash the security hash
* @return boolean true if the request is valid and have been processed ; otherwise, false.
*/
static function perso_request ($request_flag, $store, $key, $value, $hash)
{
global $CurrentPerso;
//Ensures we've the correct amount of arguments
if (func_num_args() < 4) {
return false;
}
//Checks hash
$args = func_get_args();
if (!self::is_hash_valid($args)) {
return false;
}
//Sets flag
switch ($store) {
case 'perso':
$CurrentPerso->set_flag($key, $value);
break;
case 'registry':
registry_set($key, $value);
break;
default:
//Unknown storage location
return false;
}
//Clears request flag
if ((string)$request_flag !== "0") {
$CurrentPerso->delete_flag($request_flag);
}
return true;
}
/**
* Sets current perso's local location.
*
* We don't require a security hash. If the users want to play with it, no problem.
* You generally move inside a global location as you wish.
* So, if you write a story capturing a perso, use flags to handle this escape!
*
* @param string $location_local the local location
* @return GeoLocation the current perso's GeoLocation object
*/
static function set_local_location ($location_local)
{
global $CurrentPerso;
//Ensures we've the correct amount of arguments
if (func_num_args() < 1) {
return null;
}
//Moves current perso to specified location
$location_local = urldecode($location_local);
$CurrentPerso->move_to(null, $location_local);
//Returns GeoLocation relevant instance
return $CurrentPerso->location;
}
/**
* Moves the current perso's, setting a new local location.
*
* We don't require a security hash. If the users want to play with it, no problem.
* You generally move inside a global location as you wish.
* So, if you write a story capturing a perso, use flags to handle this escape!
*
* @param string $move the move (coordinates or direction)
- * @param int $factor a number multipling the specified move [optional]
+ * @param int $factor a number multiplying the specified move [optional]
* @return GeoLocation the current perso's GeoLocation object
*
* e.g. to move from 2 units to east, you can use one of those instructions:
* local_move('east', 2);
* local_move('2,0,0');
* local_move('1,0,0', 2);
*
* Valid moves string are north, east, south, west, up and down.
* Valid moves coordinates are x,y,z (3 integers, comma as separator)
*/
static function local_move ($move, $factor = 1)
{
global $CurrentPerso;
//Ensures we've the correct amount of arguments
if (func_num_args() < 1) {
return null;
}
//Parses $move
switch ($move) {
case 'north':
$move = array(0, 1, 0);
break;
case 'east':
$move = array(1, 0, 0);
break;
case 'south':
$move = array(0, -1, 0);
break;
case 'west':
$move = array(-1, 0, 0);
break;
case 'up':
$move = array(0, 0, 1);
break;
case 'down':
$move = array(0, 0, -1);
break;
default:
$move = split(',', $move, 3);
foreach ($move as $coordinate) {
if (!is_numeric($coordinate)) {
return null;
}
}
}
//Moves current perso to specified location
if ($location_local = GeoPoint3D::fromString($CurrentPerso->location->local)) {
$location_local->translate($move[0] * $factor, $move[1] * $factor, $move[2] * $factor);
$CurrentPerso->move_to(null, $location_local->sprintf("(%d, %d, %d)"));
//Returns GeoLocation relevant instance
return $CurrentPerso->location;
}
//Old local location weren't a GeoPoint3D
return null;
}
/**
* Moves the current perso's, setting a new local location, using polar+z coordinates.
* Polar+z coordinates are polar coordinates, plus a cartesian z dimension.
*
* We don't require a security hash. If the users want to play with it, no problem.
* You generally move inside a global location as you wish.
* So, if you write a story capturing a perso, use flags to handle this escape!
*
* @param string $move the move (coordinates or direction)
- * @param int $factor a number multipling the specified move [optional]
+ * @param int $factor a number multiplying the specified move [optional]
* @return GeoLocation the current perso's GeoLocation object
*
* Valid moves string are cw, ccw, out, in, up and down.
* r: out = +12 in = -12
* °: cw = +20° ccw = -20
* Valid moves coordinates are r,°,z (3 integers, comma as separator)
* (the medium value can also be integer + °)
*
* e.g. to move of two units (the unit is 20°) clockwise:
* polarz_local_move('cw', 2);
* polarz_local_move('(0, 20°, 0)', 2);
* polarz_local_move('(0, 40°, 0)');
- * Or if you really want to use radiants (PI/9 won't be parsed):
+ * Or if you really want to use radians (PI/9 won't be parsed):
* polarz_local_move('(0, 0.6981317007977318, 0)';
*
*/
static function polarz_local_move ($move, $factor = 1) {
global $CurrentPerso;
//Ensures we've the correct amount of arguments
if (func_num_args() < 1) {
return null;
}
//Parses $move
$move = urldecode($move);
switch ($move) {
case 'cw':
$move = array(0, '20°', 0);
break;
case 'ccw':
$move = array(0, '-20°', 0);
break;
case 'in':
$move = array(+12, 0, 0);
break;
case 'out':
$move = array(-12, 0, 0);
break;
case 'up':
$move = array(0, 0, 1);
break;
case 'down':
$move = array(0, 0, -1);
break;
default:
$move = split(',', $move, 3);
foreach ($move as $coordinate) {
if (!is_numeric($coordinate) && !preg_match("/^[0-9]+ *°$/", $coordinate)) {
return null;
}
}
}
dieprint_r($move);
//Moves current perso to specified location
if ($location_local = GeoPoint3D::fromString($CurrentPerso->location->local)) {
$location_local->translate($move[0] * $factor, $move[1] * $factor, $move[2] * $factor);
$CurrentPerso->move_to(null, $location_local->sprintf("(%d, %d, %d)"));
//Returns GeoLocation relevant instance
return $CurrentPerso->location;
}
//Old local location weren't a GeoPoint3D
return null;
}
/**
* Moves the current perso's, setting a new global and local location.
*
* @param string $location_global The global location
* @param string $location_local The local location
* @return GeoLocation the current perso's GeoLocation object
*/
static function global_move ($location_global, $location_local = null) {
//Ensures we've the correct amount of arguments
if (func_num_args() < 1) {
return null;
}
//Checks hash
$args = func_get_args();
if (!self::is_hash_valid($args)) {
return false;
}
//Moves
global $CurrentPerso;
$CurrentPerso->move_to($location_global, $location_local);
return $CurrentPerso->location;
}
/**
* Handles upload content form.
*
* @return string new content path
*/
static function upload_content () {
global $CurrentPerso, $CurrentUser;
require_once('includes/objects/content.php');
//Initializes a new content instance
$content = new Content();
$content->load_from_form();
$content->user_id = $CurrentUser->id;
$content->perso_id = $CurrentPerso->id;
$content->location_global = $CurrentPerso->location_global;
//Saves file
if ($content->handle_uploaded_file($_FILES['artwork'])) {
$content->save_to_database();
$content->generate_thumbnail();
return true;
}
return false;
}
/**
* Gets multimedia content for the specified location
*
* @param string $location_global The global location (local is to specified in ?location_local parameter)
* @return Array an array of Content instances
*/
static function get_content ($location_global) {
//Ensures we've the correct amount of arguments
if (func_num_args() < 1) {
return null;
}
//Checks hash
$args = func_get_args();
if (!self::is_hash_valid($args)) {
return false;
}
//Checks local location is specified somewhere (usually in $_GET)
if (!array_key_exists('location_local', $_REQUEST)) {
return false;
}
//Gets content
require_once('includes/objects/content.php');
return Content::get_local_content($location_global, $_REQUEST['location_local']);
}
}
////////////////////////////////////////////////////////////////////////////////
///
/// Handles request
///
//Parses URL
$Config['SiteURL'] = get_server_url() . $_SERVER["PHP_SELF"];
$args = get_current_url_fragments();
$method = array_shift($args);
if ($_REQUEST['debug']) {
//Debug version
//Most of E_STRICT errors are evaluated at the compile time thus such errors
//are not reported
ini_set('display_errors', 'stderr');
error_reporting(-1);
if (method_exists('Actions', $method)) {
$result = call_user_func_array(array('Actions', $method), $args);
echo json_encode($result);
} else {
echo "<p>Method doesn't exist: $method</p>";
}
if (array_key_exists('redirectTo', $_REQUEST)) {
//If user JS disabled, you can add ?redirectTo= followed by an URL
echo "<p>Instead to print a callback value, redirects to <a href=\"$_REQUEST[redirectTo]\">$_REQUEST[redirectTo]</a></p>";
}
} else {
//Prod version doesn't prints warning <== silence operator
if (method_exists('Actions', $method)) {
$result = @call_user_func_array(array('Actions', $method), $args);
if (array_key_exists('redirectTo', $_REQUEST)) {
//If user JS disabled, you can add ?redirectTo= followed by an URL
header("location: " . $_REQUEST['redirectTo']);
} else {
echo json_encode($result);
}
}
}
diff --git a/includes/SmartLine/SmartLine.php b/includes/SmartLine/SmartLine.php
index 5234e81..daa2b8f 100755
--- a/includes/SmartLine/SmartLine.php
+++ b/includes/SmartLine/SmartLine.php
@@ -1,537 +1,537 @@
<?php
/**
* SmartLine 0.1
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2007-07-28 01:36 [DcK] Initial release
* 2010-07-02 00:39 [Dck] Documentation
*
* @package Zed
* @subpackage SmartLine
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2007 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/
* @link http://bitbucket.org/dereckson/smartline
* @filesource
///////////////////////////////////////////////////////////////////////////////
// SECTION I - INITIALIZATION
///////////////////////////////////////////////////////////////////////////////
//Constants
/**
* The standard, regular output (like STDOUT on POSIX systems)
*/
if (!defined('STDOUT')) {
define('STDOUT', 1, true);
}
/**
* The error output (like STDERR on POSIX systems)
*/
if (!defined('STDERR')) {
define('STDERR', -1, true);
}
///////////////////////////////////////////////////////////////////////////////
// SECTION Ibis - L10n
///////////////////////////////////////////////////////////////////////////////
//Ensures $lang is a standard array
if (empty($lang) || !is_array($lang)) {
$lang = array();
}
$lang = array_merge($lang, array(
//Errors
'InvalidCommand' => "Invalid command %s. Use <strong>showcommands</strong> to show all commands.",
'RegisteredButNotExistingCommand' => "[CRITICAL ERROR] The command %s has correctly been registered but its method or class doesn't exist.",
'NotYetHelpForThiscommand' => "This command hasn't been documented yet.",
//Help
'DefaultHelp' => "This SmartLine is a command line interface.
<br /><br /><strong>showcommands</strong> prints the list.
<br /><strong>help &lt;command&gt;</strong> prints help for this command.",
'Help' => array(
'help' => "<strong>help &lt;command&gt;</strong> prints command help.",
'showcommands' => 'show available commands'
)
));
///////////////////////////////////////////////////////////////////////////////
// SECTION II - HELPERS FUNCTIONS
///////////////////////////////////////////////////////////////////////////////
/**
* Error handler called during SmartLine command execution.
*
- * Any error occuring during command execution will be set in STDERR.
+ * Any error occurring during command execution will be set in STDERR.
*
* To get an array with all the errors:
* <code>$errors = $yourSmartLine->gets_all(STDERR)</code>
*
* Or to prints all the error:
* <code>$yourSmartLine->prints_all(STDERR)</code>
*
* Or to pops (gets and deletes) only the last error:
* <code>$lastError = $yourSmartLine->gets(STDERR)</code>
*
* @link http://www.php.net/manual/en/function.set-error-handler.php set_error_handler, PHP manual
* @link http://www.php.net/manual/en/errorfunc.examples.php Error handling examples, PHP manual
*
* @param int $level The PHP error level
* @param string $error The error description
- * @param string $file The script where the error occured
- * @param int $line The line where the error occured
+ * @param string $file The script where the error occurred
+ * @param int $line The line where the error occurred
*/
function SmartLineHandler($level, $error, $file, $line) {
switch ($level) {
case E_NOTICE:
$type = 'Notice';
break;
CASE E_WARNING:
$type = 'Warning';
break;
CASE E_ERROR:
$type = 'Error';
break;
default:
$type = "#$level";
}
$_SESSION['SmartLineOutput'][STDERR][] = "[PHP $type] $error in $file line $line.";
return true;
}
///////////////////////////////////////////////////////////////////////////////
// SECTION III - BASE CLASSES
///////////////////////////////////////////////////////////////////////////////
-//SmartLineCommand is a class implemanting a SmartLine command.
+//SmartLineCommand is a class implementing a SmartLine command.
//If you want to create a more complex command, extends this class.
/**
* The SmartLine command base class.
*
* To add a command, create an instance of the class, like:
* <code>
* class HelloWorldSmartLineCommand extends SmartLineCommand {
* public function run ($argv, $argc) {
* $this->SmartLine->puts('Hello World!');
* }
* }
* </code>
*
* Then, registers your command:
* <code>
* $yourSmartLine->register_object('hello', 'HelloWorldSmartLineCommand');
* </code>
*
* @see SmartLine::register_object
*/
class SmartLineCommand {
/**
* Initializes a new instance of the SmartLine Command
*
* @param SmartLine $SmartLine the SmartLine the command belongs
*/
public function __construct ($SmartLine) {
$this->SmartLine = $SmartLine;
}
/**
* Gets the command help text or indicates help should be fetched from $lang array
*
* @return string|bool a string containing the command help or the bool value false, to enable the default behavior (ie prints $lang['help']['nameOfTheCommand'])
*/
public function help () {
return false;
}
/**
* Runs the command
*
* @param array $argv an array of string, each item a command argument
* @param int $argc the number of arguments
*/
public function run ($argv, $argc) {
}
/**
* The SmartLine where this instance of the command is registered
*
* @var SmartLine
*/
public $SmartLine;
}
/**
* This class represents a SmartLine instance
*
* If you use only register_object, you can use it directly.
* If you use register_method, extends this class in your SmartLine.
*/
class SmartLine {
/**
* Initializes a new instance of the SmartLine object.
*/
public function __construct () {
//Assumes we've an empty array where store registered commands.
$this->commands = array();
//Let's register standard commands
$this->register_object('showcommands', 'ShowCommandsSmartLineCommand');
$this->register_object('help', 'HelpSmartLineCommand');
}
/**
* Registers a private method as command.
*
* @param string $command The name of the command to register
- * @param string $method The method to register [OPTIONAL]. If omitted, the method regisered will be the method having the same name as the command.
+ * @param string $method The method to register [OPTIONAL]. If omitted, the method registered will be the method having the same name as the command.
* @param bool $useArgvArgc If true, indicates the method uses $argv, $argc as parameters. If false, indicates the method uses its parameters (default behavior). [OPTIONAL]
*
* @return bool true if the command have successfully been registered ; otherwise, false.
*/
public function register_method ($command, $method = null, $useArgvArgc = false) {
if (is_null($function)) $method = $command;
if (!method_exists($this, $method)) {
$this->lastError = "Registration failed. Unknown method $method";
return false;
}
$className = ucfirst($method) . 'SmartLineCommand';
//If class exists, add a uniqid after function
while (class_exists($method)) {
$className = uniqid(ucfirst($method)) . 'SmartLineCommand';
}
//Creates the class
if ($useArgvArgc) {
$call = "$this->SmartLine->$method(\$argv, \$argc);";
} else {
//We don't know how many args we've, so we use call_user_func_array
$call = "array_shift(\$argv);
call_user_func_array(
array(&\$this->SmartLine, '$method'),
\$argv
);";
}
$code = "class $className extends SmartLineCommand {
public function run (\$argv, \$argc) {
$call
}
}";
eval($code);
$this->register_object($command, $className);
return true;
}
/**
* Registers an object extending SmartLineCommand as command.
*
* @param string $command The name of the command to register
* @param SmartLineCommand|string $object The object extending SmartLineCommand. This can be the name of the class (string) or an instance already initialized of the object (SmartLineCommand).
* @return bool true if the command have successfully been registered ; otherwise, false.
*/
public function register_object ($command, $object) {
if (is_object($object)) {
//Sets SmartLine property
$object->SmartLine = $this;
} elseif (is_string($object) && class_exists($object)) {
//Creates a new instance of $object
$object = new $object($this);
} else {
$this->lastError = "Registration failed. register_object second parameter must be a class name (string) or an already initialized instance of such class (object) and not a " . gettype($object);
return false;
}
if (!$this->caseSensitive) {
$command = strtolower($command);
}
$this->commands[$command] = $object;
return true;
}
/**
- * Determines wheter the specified command have been registered.
+ * Determines whether the specified command have been registered.
*
* @param string $command The name of the command to check
* @return true if the specified command have been registered ; otherwise, false.
*/
public function isRegistered ($command) {
if (!$this->caseSensitive) {
$command = strtolower($command);
}
return array_key_exists($command, $this->commands);
}
/**
* Executes the specified expression.
*
* If an error occurs during the command execution:
* the STDERR output will contains the errors,
- * the value returned by this methos will be false.
+ * the value returned by this methods will be false.
*
* To execute the command and prints error:
* <code>
* $fooSmartLine = new SmartLine();
* //...
* $result = $fooSmartLine->execute($expression);
* $fooSmartLine->prints_all();
* if (!$result) {
* //Errors!
* echo "<h3>Errors</h3>";
* $fooSmartLine->prints_all(STDERR);
* }
* </code>
*
* @param string $expression The expression containing the command to execute
- * @return bool true if the command have been successfuly executed ; otherwise, false.
+ * @return bool true if the command have been successfully executed ; otherwise, false.
*/
public function execute ($expression) {
//Does nothing if blank line
if (!$expression) return;
//Prepares $argv and $argc
$argv = $this->expression2argv($expression);
$argc = count($argv);
//Gets command
$command = $this->caseSensitive ? $argv[0] : strtolower($argv[0]);
//If command doesn't exist, throws an error
if (!array_key_exists($command, $this->commands)) {
global $lang;
$this->puts(sprintf($lang['InvalidCommand'], $command), STDERR);
return false;
}
//Executes command, intercepting error and returns result
set_error_handler("SmartLineHandler");
try {
$result = $this->commands[$command]->run($argv, $argc);
} catch (Exception $ex) {
$this->puts("<pre>$ex</pre>", STDERR);
}
restore_error_handler();
return $result;
}
/**
* Adds a message to the specified output queue.
*
* @param string $message the message to queue
- * @param int $output The output queue (common values are STDERR and STDOUT constants). It's an optionnal parameter ; if ommited, the default value will be STDOUT.
+ * @param int $output The output queue (common values are STDERR and STDOUT constants). It's an optional parameter ; if omitted, the default value will be STDOUT.
*/
public function puts ($message, $output = STDOUT) {
//
$_SESSION['SmartLineOutput'][$output][] = $message;
}
/**
* Truncates the specified output queue.
*
- * @param int $output The output queue (common values are STDERR and STDOUT constants). It's an optionnal parameter ; if ommited, the default value will be STDOUT.
+ * @param int $output The output queue (common values are STDERR and STDOUT constants). It's an optional parameter ; if omitted, the default value will be STDOUT.
*/
public function truncate ($output = STDOUT) {
unset($_SESSION['SmartLineOutput'][$output]);
}
/**
* Pops (gets and clears) the first message from the specified output queue.
*
- * @param int $output The output queue (common values are STDERR and STDOUT constants). It's an optionnal parameter ; if ommited, the default value will be STDOUT.
+ * @param int $output The output queue (common values are STDERR and STDOUT constants). It's an optional parameter ; if omitted, the default value will be STDOUT.
* @return string the message
*/
public function gets ($output = STDOUT) {
if (count($_SESSION['SmartLineOutput'][$output] > 0)) {
return array_pop($_SESSION['SmartLineOutput'][$output]);
}
}
/**
* Gets the number of messages in the specified output queue.
*
- * @param int $output The output queue (common values are STDERR and STDOUT constants). It's an optionnal parameter ; if ommited, the default value will be STDOUT.
+ * @param int $output The output queue (common values are STDERR and STDOUT constants). It's an optional parameter ; if omitted, the default value will be STDOUT.
*/
public function count ($output = STDOUT) {
return count($_SESSION['SmartLineOutput'][$output]);
}
/**
* Gets all the message from the specified output queue.
*
- * @param int $output The output queue (common values are STDERR and STDOUT constants). It's an optionnal parameter ; if ommited, the default value will be STDOUT.
- * @param string $prefix The string to prepend each message with. It's an optionnal parameter ; if ommited, '<p>'.
- * @param string $suffix The string to append each message with. It's an optionnal parameter ; if ommited, '</p>'.
+ * @param int $output The output queue (common values are STDERR and STDOUT constants). It's an optional parameter ; if omitted, the default value will be STDOUT.
+ * @param string $prefix The string to prepend each message with. It's an optional parameter ; if omitted, '<p>'.
+ * @param string $suffix The string to append each message with. It's an optional parameter ; if omitted, '</p>'.
* @return Array an array of string, each item a message from the specified output queue
*/
public function gets_all ($output = STDOUT, $prefix = '<p>', $suffix = '</p>') {
$count = count($_SESSION['SmartLineOutput'][$output]);
if ($count == 0) {
return;
}
for ($i = 0 ; $i < $count ; $i++) {
$buffer .= $prefix . $_SESSION['SmartLineOutput'][$output][$i] . $suffix;
}
unset ($_SESSION['SmartLineOutput'][$output]);
return $buffer;
}
/**
* Prints all the message from the specified output queue.
*
- * @param int $output The output queue (common values are STDERR and STDOUT constants). It's an optionnal parameter ; if ommited, the default value will be STDOUT.
- * @param string $prefix The string to prepend each message with. It's an optionnal parameter ; if ommited, '<p>'.
- * @param string $suffix The string to append each message with. It's an optionnal parameter ; if ommited, '</p>'.
+ * @param int $output The output queue (common values are STDERR and STDOUT constants). It's an optional parameter ; if omitted, the default value will be STDOUT.
+ * @param string $prefix The string to prepend each message with. It's an optional parameter ; if omitted, '<p>'.
+ * @param string $suffix The string to append each message with. It's an optional parameter ; if omitted, '</p>'.
*/
public function prints_all ($output = STDOUT, $prefix = '<p>', $suffix = '</p>') {
$count = count($_SESSION['SmartLineOutput'][$output]);
if ($count == 0) {
return;
}
for ($i = 0 ; $i < $count ; $i++) {
echo $prefix, $_SESSION['SmartLineOutput'][$output][$i], $suffix;
}
unset ($_SESSION['SmartLineOutput'][$output]);
}
/**
* Gets the command help
*
* @param string $command The command to get help from
* @param string The command help
*/
public function gethelp ($command) {
return $this->commands[$command]->help();
}
/**
* Gets an an argv array from the specified expression
*
* @param string $expression The expression to transform into a argv array
* @return Array An array of string, the first item the command, the others those arguments.
*/
private function expression2argv ($expression) {
//Checks if expression contains "
$pos1 = strpos($expression, '"');
//We isolate "subexpression"
if ($pos1 !== false) {
$pos2 = $pos1;
do {
$pos2 = strpos($expression, '"', $pos2 + 1);
} while ($pos2 !== false && ($expression[$pos2 - 1] == "\\" && $expression[$pos2 - 2] != "\\"));
if ($pos2 === false) {
//If final quote is missing, throws a warning and autoadds it.
$this->puts("[Warning] Final \" missing in $expression.", STDERR);
$argv = $this->expression2argv(substr($expression, 0, $pos1));
$argv[] = substr($expression, $pos1 + 1);
return $argv;
}
return array_merge(
$this->expression2argv(substr($expression, 0, $pos1)),
array(substr($expression, $pos1 + 1, $pos2 - $pos1 - 1)),
$this->expression2argv(substr($expression, $pos2 + 1))
);
}
//Standard expression (ie without ")
$argv = array();
$items = explode(' ', $expression);
foreach ($items as $item) {
$item = trim($item);
if (!$item) {
//blank, we ignore
continue;
}
$argv[] = $item;
}
return $argv;
}
//Contains last error
public $lastError = '';
//If true, command isn't equal to Command
public $caseSensitive = true;
}
///////////////////////////////////////////////////////////////////////////////
// SECTION IV - STANDARD COMMANDS
///////////////////////////////////////////////////////////////////////////////
/*
- * These commands are availaible in all default smartlines instance
+ * These commands are available in all default smartlines instance
*/
/**
* The standard command "showcommands"
*
* This command returns a list, with all the available commands
*/
class ShowCommandsSmartLineCommand extends SmartLineCommand {
/**
* Runs the command
*
* @param array $argv an array of string, each item a command argument
* @param int $argc the number of arguments
*/
public function run ($argv, $argc) {
$commands = array_keys($this->SmartLine->commands);
sort($commands);
$this->SmartLine->puts(implode(' ', $commands));
}
}
/**
* The standard command "help"
*
* This command prints command help.
*
* Help could be defined
* in the command classes, as a return value from the help method ;
* in the $lang['Help'] array, at the command key (e.g. $lang['Help']['quux'] for the quux command).
*/
class HelpSmartLineCommand extends SmartLineCommand {
/**
* Runs the command
*
* @param array $argv an array of string, each item a command argument
* @param int $argc the number of arguments
*/
public function run ($argv, $argc) {
global $lang;
if ($argc == 1) {
$this->SmartLine->puts($lang['DefaultHelp']);
} elseif (!$this->SmartLine->isRegistered($argv[1])) {
$this->SmartLine->puts(sprintf($lang['InvalidCommand'], str_replace(' ', '&nbsp;', $argv[1])), STDERR);
} else {
$command = strtolower($argv[1]);
if (!$help = $this->SmartLine->gethelp($command)) {
if (array_key_exists($command, $lang['Help'])) {
$help = $lang['Help'][$command];
} else {
$help = $lang['NotYetHelpForThiscommand'];
}
}
$this->SmartLine->puts($help);
}
}
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/includes/SmartLine/ZedCommands.php b/includes/SmartLine/ZedCommands.php
index 26fe793..e650bbb 100755
--- a/includes/SmartLine/ZedCommands.php
+++ b/includes/SmartLine/ZedCommands.php
@@ -1,492 +1,492 @@
<?php
/**
* Zed SmartLine commands.
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* This is the SmartLine subcontroller.
*
* The SmartLine is a widget allowing to add some basic CLI capability.
*
* It executes any command given in GET or POST request (parameter C).
*
* This files also provides SmartLine history helper: a method log_C to log
* a SmartLine command and some procedural code assigning a SmartLineHistory.
*
* This code is inspired from Viper, a corporate PHP intranet I wrote in 2004.
* There, the SmartLine allowed to change color theme or to find quickly user,
* account, order or server information in a CRM context.
*
* @package Zed
* @subpackage SmartLine
* @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 SettingsSmartLineCommand - understand why dojo floating pane isn't rendered if we est $controller instead to redirect
*/
///
/// Register commands
///
$smartLine->register_object('goto', 'GotoSmartLineCommand');
$smartLine->register_object('guid', 'GUIDSmartLineCommand');
$smartLine->register_object('invite', 'InviteSmartLineCommand');
$smartLine->register_object('invites', 'InviteSmartLineCommand');
$smartLine->register_object('list', 'ListSmartLineCommand');
$smartLine->register_object('requests', 'RequestsSmartLineCommand');
$smartLine->register_object('settings', 'SettingsSmartLineCommand');
$smartLine->register_object('unixtime', 'UnixTimeSmartLineCommand');
$smartLine->register_object('version', 'VersionSmartLineCommand');
$smartLine->register_object('whereami', 'WhereAmISmartLineCommand');
$smartLine->register_object('whoami', 'WhoAmISmartLineCommand');
///
/// Help (todo: move $lang array in lang folder)
///
$lang['Help']['goto'] = "Go to a location";
$lang['Help']['guid'] = "Generate a GUID";
$lang['Help']['invite'] = "Generate an invite. To see the generated invites, invite list.";
$lang['Help']['list'] = "Lists specified objects (bodies, locations or places)";
$lang['Help']['requests'] = "Checks if there are waiting requests";
$lang['Help']['settings'] = 'Go to settings page';
$lang['Help']['unixtime'] = "Prints current unixtime (seconds elapsed since 1970-01-01 00:00, UTC) or the specified unixtime date.";
$lang['Help']['version'] = "Gets Zed's software version info (Mercurial repository version, node id and if you're on the dev or prod site)";
$lang['Help']['whereami'] = "Where am I?";
$lang['Help']['whoami'] = "Who am I?";
/**
* The goto command
*
* Moves to the current perso to the specified location.
*/
class GotoSmartLineCommand extends SmartLineCommand {
/**
* Runs the command
*
* @param array $argv an array of string, each item a command argument
* @param int $argc the number of arguments
*
* @todo allow .goto global local (e.g. .goto B0001001 T2C3)
* @todo determine if we allow rewrite rules to bypass can_travel rules
*/
public function run ($argv, $argc) {
global $CurrentPerso;
if ($argc == 1) {
$this->SmartLine->puts("Where do you want to go?", STDERR);
return;
}
if ($argc > 2) {
$ignored_string = implode(" ", array_slice($argv, 2));
$this->SmartLine->puts("Warning: ignoring $ignored_string", STDERR);
}
require_once("includes/geo/location.php");
require_once("includes/travel/travel.php");
$here = new GeoLocation($CurrentPerso->location_global, $CurrentPerso->location_local);
$travel = Travel::load(); //maps content/travel.xml
//Parses the expression, by order of priority, as :
// - a rewrite rule
// - a new global location
// - a new local location (inside the current global location)
if (!$travel->try_parse_rewrite_rule($argv[1], $here, $place)) {
try {
$place = new GeoLocation($argv[1]);
if ($place->equals($CurrentPerso->location_global)) {
$this->SmartLine->puts("You're already there.");
return;
}
} catch (Exception $ex) {
//Global location failed, trying local location
try {
$place = new GeoLocation($CurrentPerso->location_global, $argv[1]);
} catch (Exception $ex) {
$this->SmartLine->puts($ex->getMessage(), STDERR);
return;
}
if ($place->equals($here)) {
$this->SmartLine->puts("You're already there.");
return;
}
}
}
//Could we really go there?
if (!$travel->can_travel($here, $place)) {
$this->SmartLine->puts("You can't reach that location.");
return;
}
//Moves
$CurrentPerso->move_to($place->global, $place->local);
$this->SmartLine->puts("You travel to that location.");
return;
}
}
/**
* The GUID command
*
* Prints a new GUID.
*
* guid 8 will print 8 guid
*/
class GUIDSmartLineCommand extends SmartLineCommand {
/**
* Runs the command
*
* @param array $argv an array of string, each item a command argument
* @param int $argc the number of arguments
*/
public function run ($argv, $argc) {
if ($argc > 1 && is_numeric($argv[1])) {
for ($i = 0 ; $i < $argv[1] ; $i++) {
$this->SmartLine->puts(new_guid());
}
return;
}
$this->SmartLine->puts(new_guid());
}
}
/**
* The invite command
*
* Manages invites.
*
* invite [add]
* creates a new invite code
*
* invite del <invite code>
* deletes the specified invite
*
* invite list
* prints current invite codes
*/
class InviteSmartLineCommand extends SmartLineCommand {
/**
* Runs the command
*
* @param array $argv an array of string, each item a command argument
* @param int $argc the number of arguments
*/
public function run ($argv, $argc) {
require_once('includes/objects/invite.php');
global $CurrentUser, $CurrentPerso;
$command = ($argc > 1) ? strtolower($argv[1]) : '';
switch ($command) {
case 'list':
$codes = Invite::get_invites_from($CurrentPerso->id);
if (!count($codes)) {
$this->SmartLine->puts("No invite code.");
} else {
foreach ($codes as $code) {
$this->SmartLine->puts($code);
}
}
break;
case 'add':
case '':
$code = Invite::create($CurrentUser->id, $CurrentPerso->id);
$url = get_server_url() . get_url('invite', $code);
$this->SmartLine->puts("New invite code created: $code<br />Invite URL: $url");
break;
case 'del':
$code = $argv[2];
if (!preg_match("/^([A-Z]){3}([0-9]){3}$/i", $code)) {
$this->SmartLine->puts("Invalid code format. Use invite list to get all your invite codes.", STDERR);
} else {
$invite = new Invite($code);
if ($CurrentPerso->id == $invite->from_perso_id) {
$invite->delete();
$this->SmartLine->puts("Deleted");
} else {
$this->SmartLine->puts("Invalid code. Use invite list to get all your invite codes.", STDERR);
}
}
break;
default:
$this->SmartLine->puts("Usage: invite [add|list|del <code>]", STDERR);
break;
}
}
}
/**
* The list command
*
* Prints a list of bodies, locations or places.
*
* This can easily be extended to output any list from any table.
*/
class ListSmartLineCommand extends SmartLineCommand {
/**
* Runs the command
*
* @param array $argv an array of string, each item a command argument
* @param int $argc the number of arguments
*/
public function run ($argv, $argc) {
if ($argc == 1) {
$this->SmartLine->puts("Available lists: bodies, locations, places");
return;
}
switch ($objects = $argv[1]) {
case 'bodies':
$list = $this->get_list(TABLE_BODIES, "CONCAT('B', body_code)", "body_name");
$this->SmartLine->puts($list);
break;
case 'locations':
$list = $this->get_list(TABLE_LOCATIONS, "location_code", "location_name");
$this->SmartLine->puts($list);
break;
case 'places':
if ($argv[2] == "-a" || $argv[2] == "--all") {
//Global bodies places list
$list = $this->get_list(TABLE_PLACES, "CONCAT('B', body_code, place_code)", "place_name");
} else {
//Local places (or equivalent) list
global $CurrentPerso;
switch ($CurrentPerso->location_global[0]) {
case 'B':
$body_code = substr($CurrentPerso->location_global, 1, 5);
$list = $this->get_list(TABLE_PLACES, "CONCAT('B', body_code, place_code)", "place_name", "body_code = $body_code");
break;
case 'S':
$this->SmartLine->puts("I don't have a map of the spaceship.", STDERR);
return;
default:
$this->SmartLine->puts("Unknown location type. Can only handle B or S.", STDERR);
return;
}
}
$this->SmartLine->puts($list);
break;
default:
$this->SmartLine->puts("Unknown objects to list: $objects", STDERR);
}
}
/**
* Gets a custom list from the specified table and fields.
*
* The list will ascendingly ordered by the specified key.
*
* @param $table the table to query from the database
* @param $key the first field to fetch, as key
* @param $value the second field to fetch, as value
- * @param $where the WHERE clause, without the WHERE keyword (optionnal)
+ * @param $where the WHERE clause, without the WHERE keyword (optional)
*/
public function get_list ($table, $key, $value, $where = null) {
global $db;
$sql = "SELECT $key as `key`, $value as value FROM $table ";
if ($where) {
$sql .= "WHERE $where ";
}
$sql .= "ORDER BY `key` ASC";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to fetch list", '', __LINE__, __FILE__, $sql);
}
while ($row = $db->sql_fetchrow($result)) {
$rows .= "<tr><td>$row[key]</td><td>$row[value]</td></tr>";
}
$this->SmartLine->truncate(STDERR); //kludge
return "<table cellspacing=\"8\"><thead style=\"color: white\" scope=\"row\"><tr><th>Key</th><th>Value</th></thead><tbody>$rows</tbody></table>";
}
}
/**
* The requests command
*
* Redirects user the the requests page.
*
* By default only redirect if a flag indicates there's a new request.
*
* To forcefully goes to the request page, requests --force
*/
class RequestsSmartLineCommand extends SmartLineCommand {
/**
* Runs the command
*
* @param array $argv an array of string, each item a command argument
* @param int $argc the number of arguments
*/
public function run ($argv, $argc) {
global $CurrentPerso;
$force = ($argc > 1) && ($argv[1] == "-f" || $argv[1] == "--force");
if ($force || (array_key_exists('site.requests', $CurrentPerso->flags) && $CurrentPerso->flags['site.requests'])) {
global $controller;
$controller = 'controllers/persorequest.php';
} else {
$this->SmartLine->puts("No request waiting.");
}
}
}
/**
* The settings command
*
* Redirects user the the settings page.
*/
class SettingsSmartLineCommand extends SmartLineCommand {
/**
* Runs the command
*
* @param array $argv an array of string, each item a command argument
* @param int $argc the number of arguments
*/
public function run ($argv, $argc) {
if (headers_sent()) {
global $controller;
$controller = 'controllers/settings.php';
} else {
header('location: ' . get_url('settings'));
}
}
}
/**
* The unixtime command
*
* Prints current unixtime (seconds elapsed since 1970-01-01 00:00, UTC)
* or if an unixtime is specified as argument, the matching date.
*/
class UnixTimeSmartLineCommand extends SmartLineCommand {
/**
* Runs the command
*
* @param array $argv an array of string, each item a command argument
* @param int $argc the number of arguments
*/
public function run ($argv, $argc) {
date_default_timezone_set('UTC');
if ($argc == 1) {
$this->SmartLine->puts(time());
} elseif ($argc == 2 && is_numeric($argv[1])) {
$this->SmartLine->puts(strftime("%Y-%m-%d %X", $argv[1]));
$this->SmartLine->puts(get_hypership_time($argv[1]));
} else {
array_shift($argv);
$date = implode(' ', $argv);
if ($time = strtotime($date) !== false) {
$this->SmartLine->puts("Unixtime from $date: <span class=\"highlight\">$time</span>");
} else {
$this->SmartLine->puts("$date isn't a unixtime nor a valid date strtotime is able to parse.", STDERR);
}
}
}
}
/**
* The version command
*
- * Prints current hg revision, if we're in prod or dev environement and
+ * Prints current hg revision, if we're in prod or dev environment and
* the current revision's hash.
*
* The version and env information is extracted from
* .hg/tags.cache (indicating we're in a Mercurial repo and so in a dev environment), or from
- * version.txt file (indicating we've deployed code in a production environement)
+ * version.txt file (indicating we've deployed code in a production environment)
*
* e.g. r130 (development environment)
* Hash: 057bf394741706fd2136541e3bb07c9e60b4963d
*/
class VersionSmartLineCommand extends SmartLineCommand {
/**
* Runs the command
*
* @param array $argv an array of string, each item a command argument
* @param int $argc the number of arguments
*/
public function run ($argv, $argc) {
//Gets .hg revision
if (file_exists('.hg/tags.cache')) {
$content = file_get_contents('.hg/tags.cache');
$info = explode(' ', $content, 2);
$info[] = "development environment";
$this->SmartLine->puts("r$info[0] ($info[2])");
$this->SmartLine->puts("Hash: $info[1]");
} elseif (file_exists('version.txt')) {
$content = file('version.txt');
foreach ($content as $line) {
$this->SmartLine->puts($line);
}
} else {
$this->SmartLine->puts("No version information available.", STDERR);
return false;
}
return true;
}
}
/**
* The whereami (Where am I?) command
*
* Prints current position, e.g. B00001001 - Tour, Hypership
*/
class WhereAmISmartLineCommand extends SmartLineCommand {
/**
* Runs the command
*
* @param array $argv an array of string, each item a command argument
* @param int $argc the number of arguments
*/
public function run ($argv, $argc) {
global $CurrentPerso;
require_once("includes/geo/location.php");
$place = new GeoLocation($CurrentPerso->location_global);
$this->SmartLine->puts($CurrentPerso->location_global . ' - ' . $place);
}
}
/**
* The whoami (Who am I?) command
*
* Prints current position, e.g. B00001001 - Tour, Hypership
*/
class WhoAmISmartLineCommand extends SmartLineCommand {
/**
* Runs the command
*
* @param array $argv an array of string, each item a command argument
* @param int $argc the number of arguments
*/
public function run ($argv, $argc) {
global $CurrentPerso;
$reply = "<span id=\"whoami.nickname\">$CurrentPerso->nickname</span> (<span id=\"whoami.name\">$CurrentPerso->name</span>), <span id=\"whoami.race\">$CurrentPerso->race</span>";
$this->SmartLine->puts($reply);
}
}
diff --git a/includes/api/BeautyXML.class.php b/includes/api/BeautyXML.class.php
index 3c94cb4..4b57d83 100755
--- a/includes/api/BeautyXML.class.php
+++ b/includes/api/BeautyXML.class.php
@@ -1,162 +1,161 @@
<?php
/**
- * XML beautifer
+ * XML beautifier
*
* 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
+ * This class is simple XML beautifier
* 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.
+ * This class is simple XML beautifier.
* 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
+ var $how_to_indent = " "; // 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.
+ * If $wrap is true, determines the line length.
*
- * After this lenght, any text will be wrapped.
+ * After this length, any text will be wrapped.
*
* @see $wrap
* @var @int
*/
var $wrap_cont = 80; // where wrap words
/**
- * Idents the specified string.
+ * Indents 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
+ * @param int $level the indent level, ie the number of indentation to prepend the string with
*/
- function ident (&$str, $level) {
+ function indent (&$str, $level) {
$spaces = '';
$level--;
for ($a = 0; $a < $level; $a++) {
- $spaces .= $this->how_to_ident;
+ $spaces .= $this->how_to_indent;
}
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);
+ $tmp[$a] = $this->indent($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);
+ $tmp[$a] = wordwrap($tmp[$a], $this->wrap_cont, "\n" . $this->how_to_indent . $this->how_to_indent . $this->how_to_indent);
}
if ($add && !@in_array($lan, $stab) && $lan != '') {
array_push($stab, $lan);
}
}
return join("\n", $tmp);
}
}
diff --git a/includes/api/api_helpers.php b/includes/api/api_helpers.php
index e2127ba..0161d98 100755
--- a/includes/api/api_helpers.php
+++ b/includes/api/api_helpers.php
@@ -1,172 +1,172 @@
<?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 there is another array found recursively 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)
+ * @param string $xmlRoot the XML root element name (optional, default value is 'data').
+ * @param string $xmlChildren the XML children elements name (optional, will be deducted from the context if omitted, or, if not possible, 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;
}
}
diff --git a/includes/api/cerbere.php b/includes/api/cerbere.php
index 5061048..6d2e4d7 100755
--- a/includes/api/cerbere.php
+++ b/includes/api/cerbere.php
@@ -1,123 +1,123 @@
<?php
/**
* API security
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* 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')) {
/**
* The table where are located the API keys
*/
define('TABLE_API_KEYS', 'api_keys');
}
/**
- * Checks if creditentials are okay and exits if not
+ * Checks if credentials are okay and exits if not
*
- * If the creditentials aren't valid, it will prints an error message if
+ * If the credentials 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.');
+ cerbere_die('You must add credentials 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;
}
diff --git a/includes/auth/YubiCloudAuthentication.php b/includes/auth/YubiCloudAuthentication.php
index 3652d16..52ad016 100644
--- a/includes/auth/YubiCloudAuthentication.php
+++ b/includes/auth/YubiCloudAuthentication.php
@@ -1,192 +1,192 @@
<?php
/**
* YubiCloud authentication class.
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2013, Dereckson, some rights reserved.
* Released under BSD license.
*
* @package Zed
* @subpackage Auth
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2013 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
require_once('Auth/Yubico.php');
/**
* YubiCloudAuthentication class
*
* Authenticates a user through YubiCloud
*/
class YubiCloudAuthentication implements IAuthentication {
/**
* The key
* @var string
*/
private $key;
/**
* The username who should match the key
* @var string
*/
private $username;
/**
* The user_id
* @var int
*/
private $user_id;
/**
* Indicates if the error MUST be returned to the user
* @var string
*/
private $mustThrowError = false;
/**
* The last validation error
* @var string
*/
public $error;
/**
* Initializes a new instance of the key
*
* @param string $key The key
*/
public function __construct ($key, $username = null) {
$this->username = $username;
$this->key = $key;
}
/**
* Validates the specified key's characters to determine if it looks like an OTP
*
* @return boolean true if the input seems an OTP key; otherwise, false.
*/
function looksValidOTP () {
return preg_match("/^[cbdefghijklnrtuv]{32,48}$/", $this->key);
}
/**
* Gets public identity
*
* @return string Public identity
*/
function getPublicIdentity () {
return substr($this->key, 0, 12);
}
/**
* Validates an OTP key against the YubiCloud servers
*
* @return boolean true if the input is a valid OTP key; otherwise, false.
*/
function isValid () {
global $Config;
-
+
//No need to lost time to query server if format is incorrect.
if (!$this->looksValidOTP()) {
$this->error = "Not the expected YubiKey OTP format.";
return false;
}
-
+
//Query YubiCloud. We stop validation tests if that fails.
$yubi = new Auth_Yubico(
$Config['YubiCloud']['ClientID'],
- $Config['YubiCloud']['SecreyKey']
+ $Config['YubiCloud']['SecretKey']
);
$auth = $yubi->verify($this->key);
if (@PEAR::isError($auth)) {
$this->error = $auth->getMessage();
return false;
}
-
+
//Note: We first query the YubiCloud server, then we check if we can use the key
// as the key is an OTP (*one time* password), this allow to invalidate it.
// If we wouldn't do that, an attacker can reuse this password for another site.
if (!$this->computeUserID()) {
$this->error = "Valid YubiKey OTP. But the key doesn't match any account.";
$this->mustThrowError = true;
return false;
}
-
+
//Finally, if someone puts also a login, we'll check this user ID match this username
if ($this->username) {
$user = User::get($this->user_id);
if ($this->username != $user->name) {
$this->error = "Valid YubiKey OTP but fix or remove your username.";
$this->mustThrowError = true;
return false;
}
}
-
+
return true;
}
/**
* Gets the user_id matching the username
*
* You first need to validate the username, calling the isValid method.
*/
function computeUserID () {
global $db;
-
+
/**
* Here a MySQL record for a valid OTP
* +---------+-----------+---------------+-----------------+---------+
* | auth_id | auth_type | auth_identity | auth_properties | user_id |
* +---------+-----------+---------------+-----------------+---------+
* | 2 | YubiKey | cccccccccccc | NULL | 1234 |
* +---------+-----------+---------------+-----------------+---------+
*/
$authentication_identity = $this->getPublicIdentity();
$sql = "SELECT user_id FROM " . TABLE_USERS_AUTH
. " WHERE auth_type = 'YubiKey' AND auth_identity = '$authentication_identity'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't query users authentication table.", '', __LINE__, __FILE__, $sql);
}
if ($row = $db->sql_fetchrow($result)) {
$this->user_id = $row['user_id'];
return true;
}
return false;
}
/**
* Gets the last authentication error
*
* @return string The last authentication error
*/
function getError () {
return $this->error;
}
/**
* Gets the user_id matching the key
*
* You first need to query the authentication table, calling the computeUserID method.
* This is automatically done by IsValid, as we need to validate key matches someone.
*
* @return int the user ID
*/
function getUserID () {
return $this->user_id;
}
/**
* Determines if the next authentication method could be tried if this one failed.
*
* @return bool true if authentication can go on to the next method; otherwise, false
*/
function canTryNextAuthenticationMethod () {
return !$this->mustThrowError;
}
}
diff --git a/includes/config.php b/includes/config.php
index 967e155..a98f5a3 100755
--- a/includes/config.php
+++ b/includes/config.php
@@ -1,270 +1,270 @@
<?php
/**
* Autogenerable configuration file
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* @package Zed
* @subpackage Keruald
* @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
*/
////////////////////////////////////////////////////////////////////////////////
/// ///
/// I. SQL configuration ///
/// ///
////////////////////////////////////////////////////////////////////////////////
//SQL configuration
$Config['database']['engine'] = 'MySQLi'; //MySQL, MySQLi
$Config['database']['host'] = 'localhost';
$Config['database']['username'] = 'zed';
$Config['database']['password'] = 'zed';
$Config['database']['database'] = 'zed';
//SQL tables
$prefix = '';
define('TABLE_API_KEYS', $prefix . 'api_keys');
define('TABLE_COMMENTS', $prefix . 'comments');
define('TABLE_CONTENT_FILES', $prefix . 'content_files');
define('TABLE_CONTENT_LOCATIONS', $prefix . 'content_locations');
define('TABLE_CONTENT_ZONES', $prefix . 'content_zones');
define('TABLE_CONTENT_ZONES_LOCATIONS', $prefix . 'content_zones_locations');
define('TABLE_LOG', $prefix . 'log');
define('TABLE_LOG_SMARTLINE', $prefix . 'log_smartline');
define('TABLE_MESSAGES', $prefix . 'messages');
define('TABLE_MOTD', $prefix . 'motd');
define('TABLE_PAGES', $prefix . 'pages');
define('TABLE_PAGES_EDITS', $prefix . 'pages_edits');
define('TABLE_PERSOS', $prefix . 'persos');
define('TABLE_PERSOS_FLAGS', $prefix . 'persos_flags');
define('TABLE_PERSOS_NOTES', $prefix . 'persos_notes');
define('TABLE_PORTS', $prefix . 'ports');
define('TABLE_PROFILES', $prefix . 'profiles');
define('TABLE_PROFILES_COMMENTS', $prefix . 'profiles_comments');
define('TABLE_PROFILES_PHOTOS', $prefix . 'profiles_photos');
define('TABLE_PROFILES_TAGS', $prefix . 'profiles_tags');
define('TABLE_REGISTRY', $prefix . 'registry');
define('TABLE_REQUESTS', $prefix . 'requests');
define('TABLE_REQUESTS_REPLIES', $prefix . 'requests_replies');
define('TABLE_SESSIONS', $prefix . 'sessions');
define('TABLE_SHIPS', $prefix . 'ships');
define('TABLE_USERS', $prefix . 'users');
define('TABLE_USERS_INVITES', $prefix . 'users_invites');
define('TABLE_USERS_AUTH', $prefix . 'users_auth');
//Geo tables
define('TABLE_BODIES', $prefix . 'geo_bodies');
define('TABLE_LOCATIONS', $prefix . 'geo_locations'); //Well... it's a view
define('TABLE_PLACES', $prefix . 'geo_places');
////////////////////////////////////////////////////////////////////////////////
/// ///
/// II. Site configuration ///
/// ///
////////////////////////////////////////////////////////////////////////////////
//Default theme
$Config['DefaultTheme'] = "Zed";
//Dates
date_default_timezone_set("UTC");
//Secret key, used for some verification hashes in URLs or forms.
$Config['SecretKey'] = 'Lorem ipsum dolor';
//When reading files, buffer size
define('BUFFER_SIZE', 4096);
////////////////////////////////////////////////////////////////////////////////
/// ///
/// III. Script URLs ///
/// ///
////////////////////////////////////////////////////////////////////////////////
/*
* Apache httpd, without mod_rewrite:
*
* Subdirectory:
* - $Config['SiteURL'] = 'http://zed.dereckson.be/hypership/index.php';
* - $Config['BaseURL'] = '/hypership/index.php';
*
* Root directory:
* - $Config['SiteURL'] = 'http://zed.dereckson.be/index.php';
* - $Config['BaseURL'] = '/index.php';
*
* Apache httpd, with mod_rewrite:
*
* Subdirectory:
* - $Config['SiteURL'] = 'http://zed.dereckson.be/hypership';
* - $Config['BaseURL'] = '/hypership';
*
* In .htaccess or your vhost definition:
* RewriteEngine On
* RewriteBase /hypership/
* RewriteCond %{REQUEST_FILENAME} !-f
* RewriteCond %{REQUEST_FILENAME} !-d
* RewriteRule . /hypership/index.php [L]
*
* Root directory:
* - $Config['SiteURL'] = 'http://zed.dereckson.be';
* - $Config['BaseURL'] = '';
*
* In .htaccess or your vhost definition:
* RewriteEngine On
* RewriteBase /
* RewriteCond %{REQUEST_FILENAME} !-f
* RewriteCond %{REQUEST_FILENAME} !-d
* RewriteRule . /index.php [L]
*
* nginx:
*
* Use same config.php settings than Apache httpd, with mod_rewrite.
*
* In your server block:
* location / {
* #Serves static files if they exists, with one month cache
* if (-f $request_filename) {
* expires 30d;
* break;
* }
*
* #Sends all non existing file or directory requests to index.php
* if (!-e request_filename) {
* rewrite ^(.+)$ /index.php last;
* #Or if you use a subdirectory:
* #rewrite ^(.+)$ /hypership/index.php last;
* }
* }
*
* location ~ \.php$ {
* #Your instructions to pass query to your FastCGI process, like:
* fastcgi_pass 127.0.0.1:9000;
* fastcgi_param SCRIPT_FILENAME /var/www/zed$fastcgi_script_name;
* include fastcgi_params;
* }
*
*
* If you don't want to specify the server domain, you can use get_server_url:
* $Config['SiteURL'] = get_server_url() . '/hypership';
* $Config['SiteURL'] = get_server_url();
*
*
*
* !!! No trailing slash !!!
*
*/
$Config['SiteURL'] = get_server_url();
$Config['BaseURL'] = '';
//AJAX callbacks URL
$Config['DoURL'] = $Config['SiteURL'] . "/do.php";
////////////////////////////////////////////////////////////////////////////////
/// ///
/// IV. Static content ///
/// ///
////////////////////////////////////////////////////////////////////////////////
//Where the static content is located?
//Static content = 4 directories: js, css, img and content
//On default installation, those directories are at site root.
//To improve site performance, you can use a CDN for that.
//
-//Recommanded setting: $Config['StaticContentURL'] = $Config['SiteURL'];
+//Recommended setting: $Config['StaticContentURL'] = $Config['SiteURL'];
//Or if Zed is the site root: $Config['StaticContentURL'] = '';
//With CoralCDN: $Config['StaticContentURL'] = . '.nyud.net';
//
$Config['StaticContentURL'] = '';
//$Config['StaticContentURL'] = get_server_url() . '.nyud.net';
//Scenes
define('SCENE_DIR', 'content/scenes');
define('SCENE_URL', $Config['StaticContentURL'] . '/' . SCENE_DIR);
//Stories
define('STORIES_DIR', "content/stories");
//Profile's photos
define('PHOTOS_DIR', 'content/users/_photos');
define('PHOTOS_URL', $Config['StaticContentURL'] . '/' . PHOTOS_DIR);
//ImageMagick paths
//Be careful on Windows platform convert could match the NTFS convert command.
$Config['ImageMagick']['convert'] = 'convert';
$Config['ImageMagick']['mogrify'] = 'mogrify';
$Config['ImageMagick']['composite'] = 'composite';
$Config['ImageMagick']['identify'] = 'identify';
////////////////////////////////////////////////////////////////////////////////
/// ///
/// V. Caching ///
/// ///
////////////////////////////////////////////////////////////////////////////////
/*
* Some data (Smarty, OpenID and sessions) are cached in the cache directory.
*
* Security tip: you can move this cache directory outside the webserver tree.
*/
define('CACHE_DIR', 'cache');
/*
* Furthermore, you can also enable a cache engine, like memcached, to store
* data from heavy database queries, or frequently accessed stuff.
*
* To use memcached:
* - $Config['cache']['engine'] = 'memcached';
* - $Config['cache']['server'] = 'localhost';
* - $Config['cache']['port'] = 11211;
*
* To disable cache:
* - $Config['cache']['engine'] = 'void';
* (or don't write nothing at all)
*/
$Config['cache']['engine'] = 'void';
////////////////////////////////////////////////////////////////////////////////
/// ///
/// VI. Sessions and authentication code ///
/// ///
////////////////////////////////////////////////////////////////////////////////
//If you want to use a common table of sessions / user handling
//with several websites, specify a different resource id for each site.
$Config['ResourceID'] = 21;
//Enable OpenID authentication
//$Config['OpenID'] = true;
//Enable YubiKey authentication
//API 12940
//For YubiCloud API key - create yours at https://upgrade.yubico.com/getapikey/
//$Config['YubiCloud']['ClientID'] = 12345;
//$Config['YubiCloud']['SecretKey'] = 'Base64SecretKeyHere';
//PHP variables
ini_set('session.serialize_handler', 'wddx');
ini_set('session.save_path', CACHE_DIR . '/sessions');
ini_set('session.gc_maxlifetime', 345600); //4 days, for week-end story pause and continue url
////////////////////////////////////////////////////////////////////////////////
/// ///
/// VII. Builder ///
/// ///
////////////////////////////////////////////////////////////////////////////////
-//Zed can invoke a slighty modified version of HOTGLUE to build zones.
+//Zed can invoke a slightly modified version of HOTGLUE to build zones.
$Config['builder']['hotglue']['enable'] = true;
$Config['builder']['hotglue']['URL'] = '/apps/hotglue/index.php';
diff --git a/includes/content/file.php b/includes/content/file.php
index 0deadcc..8894943 100755
--- a/includes/content/file.php
+++ b/includes/content/file.php
@@ -1,274 +1,274 @@
<?php
/**
* Content file class
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2012-12-03 02:57 Forked from Content
*
* @package Zed
* @subpackage Content
* @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_files table.
*
*/
class ContentFile {
/* -------------------------------------------------------------
Properties
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
public $id;
public $path;
public $user_id;
public $perso_id;
public $title;
/* -------------------------------------------------------------
Constructor, __toString
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
* Initializes a new ContentFile 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 ContentFile (ie fill the properties) from the $_POST array
*
* @param boolean $allowSensibleFields if false, allow only 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 ($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'];
}
}
/**
* Loads the object ContentFile (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$id = $db->sql_escape($this->id);
$sql = "SELECT * FROM content_files 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;
+ $this->lastError = "Content unknown: " . $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'];
}
/**
* 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);
//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();
}
}
/* -------------------------------------------------------------
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) {
$ext = strtolower($ext);
return (is_valid_image_extension($ext) || is_valid_audio_extension($ext)
|| is_valid_video_extension($ext));
}
/**
* 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_image_extension ($ext) {
switch ($ext = strtolower($ext)) {
//Pictures
case 'jpg':
case 'gif':
case 'png':
case 'bmp':
case 'xbm':
return true;
//Denied extension
default:
return false;
}
}
/**
* Determines if the extension is a valid audio file one
*
* @param string $ext The extension (without dot)
* @return boolean true if this extension is valid ; otherwise, false.
*/
function is_valid_audio_extension ($ext) {
switch ($ext = strtolower($ext)) {
//Sounds (HTML5 <audio> formats)
case 'mp3':
case 'ogg':
case 'aac':
case 'wav':
case 'wave':
return true;
//Denied extension
default:
return false;
}
}
/**
* Determines if the extension is a valid video file one
*
* @param string $ext The extension (without dot)
* @return boolean true if this extension is valid ; otherwise, false.
*
* @todo add H.264 extension
*/
function is_valid_video_extension ($ext) {
switch ($ext = strtolower($ext)) {
//Video (HTML5 <video> formats)
case 'ogg':
case 'webm':
return true;
//Denied extension
default:
return false;
}
}
/**
* Creates a directory
*
* @param string $dir the directory to create
*
* @todo set contents chmod in config
*/
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);
}
}
diff --git a/includes/content/location.php b/includes/content/location.php
index 6c0e030..dbd24ff 100755
--- a/includes/content/location.php
+++ b/includes/content/location.php
@@ -1,228 +1,228 @@
<?php
/**
* Content location class
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2010-12-03 2:58 Forked from Content class
*
* @package Zed
* @subpackage Content
* @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 location class
*
* This class maps the content_locations table.
*
- * A content location is defined by 3 paramaters:
+ * A content location is defined by 3 parameters:
* - location_global
* - location_local
* - location_k, an index for the content at the specified location
*
* This class allows to get or set the content_id at this
* (global, local, k) location.
*
* This class also provides a static helper method to
* get local content from a specific location.
*/
class ContentLocation {
/* -------------------------------------------------------------
Properties
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
public $location_global = null;
public $location_local = null;
public $location_k = null;
public $content_id;
/* -------------------------------------------------------------
Constructor, __toString
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
* Initializes a new ContentLocation instance
*
* @param string $location_global the global location
* @param string $location_local the local location
* @param int $location_k the item indice for the specified location
*/
function __construct ($location_global = null, $location_local = null, $location_k = null) {
$this->location_global = $location_global;
$this->location_local = $location_local;
if ($location_k) {
$this->location_k = $location_k;
$this->load_from_database();
} else {
$this->location_k = self::get_free_location_k($location_global, $location_local);
}
}
/**
* Returns a string representation of current Content instance
*
* @return string the content title or path if title is blank.
*/
function __toString () {
$location_global = $this->location_global ? $this->location_global : '?';
$location_local = $this->location_local ? $this->location_local : '?';
$location_k = $this->location_k ? $this->location_k : '?';
return "($location_global, $location_local, $location_k)";
}
/* -------------------------------------------------------------
Load/save class
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
* Loads the object ContentLocation (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$location_global = "'" . $db->sql_escape($this->location_global) . "'";
$location_local = "'" . $db->sql_escape($this->location_local) . "'";
$location_k = "'" . $db->sql_escape($this->location_k) . "'";
$sql = "SELECT * FROM content_locations WHERE location_global = '$location_global' AND location_local = '$location_local' AND location_k = '$location_k'";
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 location unkwown: " . $this->content_id;
+ $this->lastError = "Content location unknown: " . $this->content_id;
return false;
}
$this->load_from_row($row);
return true;
}
/**
* Loads the object from row
*/
function load_from_row ($row) {
$this->content_id = $row['content_id'];
$this->location_global = $row['location_global'];
$this->location_local = $row['location_local'];
$this->location_k = $row['location_k'];
}
/**
* Saves to database
*/
function save_to_database () {
global $db;
$location_global = "'" . $db->sql_escape($this->location_global) . "'";
$location_local = "'" . $db->sql_escape($this->location_local) . "'";
$location_k = "'" . $db->sql_escape($this->location_k) . "'";
$content_id = $this->content_id ? "'" . $db->sql_escape($this->content_id) . "'" : 'NULL';
$sql = "REPLACE INTO content_locations (location_global, location_local, location_k, content_id) VALUES ($location_global, $location_local, $location_k, $content_id)";
if (!$db->sql_query($sql))
message_die(SQL_ERROR, "Can't save content location", '', __LINE__, __FILE__, $sql);
}
/* -------------------------------------------------------------
Helper methods
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
* Gets the next k free value for the specified location
*
* @param string $location_global the global location
* @param string $location_local the local location
*
* @param int $location_k the next free local content indice
*/
function get_free_location_k ($location_global, $location_local) {
$location_global = "'" . $db->sql_escape($location_global) . "'";
$location_local = "'" . $db->sql_escape($location_local) . "'";
$sql = "SELECT MAX(location_k) + 1 FROM content_locations WHERE location_global = '$location_global' AND location_local = '$location_local'";
if (!$result = $db->sql_query($sql))
message_die(SQL_ERROR, "Can't get content location k", '', __LINE__, __FILE__, $sql);
$row = $db->sql_fetchrow($result);
return $row[0];
}
/**
* Deletes this content location from the database
*/
function delete() {
$location_global = "'" . $db->sql_escape($this->location_global) . "'";
$location_local = "'" . $db->sql_escape($this->location_local) . "'";
$location_k = "'" . $db->sql_escape($this->location_k) . "'";
$sql = "DELETE FROM content_locations WHERE location_global = '$location_global' AND location_local = '$location_local' AND location_k = '$location_k' LIMIT 1";
if (!$db->sql_query($sql))
message_die(SQL_ERROR, "Can't delete current content location", '', __LINE__, __FILE__, $sql);
}
/**
* Moves the content into new location
*
* @param string $location_global the target global location
* @param string $location_local the target local location
* @param int $location_k the target local content indice [facultative]
*/
function move ($location_global, $location_local, $location_k = null) {
if ($this->content_id) {
$this->delete();
}
if ($location_k) {
$this->location_k = $location_k;
} else {
$this->location_k = self::get_free_location_k($location_global, $location_local);
}
if ($this->content_id) {
$this->save_to_database();
}
}
/* -------------------------------------------------------------
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 ContentFile instances
*
* The returned array indices are the local_k.
*/
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.* FROM content c WHERE c.location_global = '$location_global' AND c.location_local = '$location_local' 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)) {
$k = $row['location_k'];
$contents[$k] = new ContentFile();
$contents[$k]->load_from_row($row);
}
return $contents;
}
}
diff --git a/includes/content/zone.php b/includes/content/zone.php
index af53276..0f8ab16 100755
--- a/includes/content/zone.php
+++ b/includes/content/zone.php
@@ -1,195 +1,195 @@
<?php
/**
* Zone class
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* @package Zed
* @subpackage Content
* @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 zone class
*
* A zone is a physical place, independent from the location.
* This mechanism allows to more easily move zones.
*
* This class maps the content_zones table.
*/
class ContentZone {
public $id;
public $title;
public $type;
public $params;
public $deleted = false;
/**
* Initializes a new instance of a zone object
*
* @param int $id The zone ID
*/
function __construct ($id = '') {
if ($id) {
$this->id = $id;
return $this->load_from_database();
}
}
/**
* Loads the object zone (ie fill the properties) from the $_POST array
*/
function load_from_form () {
if (array_key_exists('title', $_POST)) $this->user_id = $_POST['title'];
if (array_key_exists('type', $_POST)) $this->user_id = $_POST['type'];
if (array_key_exists('params', $_POST)) $this->user_id = $_POST['params'];
if (array_key_exists('deleted', $_POST)) $this->user_id = $_POST['deleted'];
}
/**
* Loads the object zone (ie fill the properties) from the $row array
*/
function load_from_row ($row) {
$this->id = $row['zone_id'];
$this->title = $row['zone_title'];
$this->type = $row['zone_type'];
$this->params = $row['zone_params'];
$this->deleted = $row['zone_deleted'] ? true : false;
}
/**
* Loads the object zone (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$id = $db->sql_escape($this->id);
$sql = "SELECT * FROM " . TABLE_CONTENT_ZONES . " WHERE zone_id = '" . $id . "'";
if (!$result = $db->sql_query($sql)) message_die(SQL_ERROR, 'Unable to query content_zones', '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
- $this->lastError = 'Zone unkwown: ' . $this->id;
+ $this->lastError = 'Zone unknown: ' . $this->id;
return false;
}
$this->load_from_row($row);
return true;
}
/**
* Saves the object to the database
*/
function save_to_database () {
global $db;
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$title = $db->sql_escape($this->title);
$type = $db->sql_escape($this->type);
$params = $db->sql_escape($this->params);
$deleted = $this->deleted ? 1 : 0;
$sql = "REPLACE INTO " . TABLE_CONTENT_ZONES . " (`zone_id`, `zone_title`, `zone_type`, `zone_params`, `zone_deleted`) VALUES ($id, '$title', '$type', '$params', $deleted)";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
if (!$this->id) {
$this->id = $db->sql_nextid();
}
}
/**
* Assigns the zone at the specified location.
*
* @param string $location_global the global location
* @param string $location_global the local location
* @param bool $delete_old_locations if true, delete old locations
*/
function assign_to ($location_global, $location_local, $delete_old_locations = true) {
if (!$this->id) {
$this->save_to_database();
}
global $db;
if ($delete_old_locations) {
$sql = "DELETE FROM " . TABLE_CONTENT_ZONES_LOCATIONS . " WHERE zone_id = " . $this->id;
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to delete", '', __LINE__, __FILE__, $sql);
}
}
$g = $db->sql_escape($location_global);
$l = $db->sql_escape($location_local);
$sql = "REPLACE INTO " . TABLE_CONTENT_ZONES_LOCATIONS . " (location_global, location_local, zone_id) VALUES ('$g', '$l', $this->id)";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to set zone location", '', __LINE__, __FILE__, $sql);
}
}
/**
* Gets the zone at specified location
*
* @param string $location_global the global location
* @param string $location_global the local location
* @param bool $create if the zone doesn't exist, create it [optional] [default value: false]
* @return ContentZone the zone, or null if the zone doesn't exist and $create is false
*/
static function at ($location_global, $location_local, $create = false) {
global $db;
$g = $db->sql_escape($location_global);
$l = $db->sql_escape($location_local);
$sql = "SELECT * FROM " . TABLE_CONTENT_ZONES_LOCATIONS . " WHERE location_global = '$g' AND location_local = '$l'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to set zone location", '', __LINE__, __FILE__, $sql);
}
if ($row = $db->sql_fetchrow($result)) {
return new ContentZone($row['zone_id']);
} elseif ($create) {
$zone = new ContentZone();
$zone->assign_to($location_global, $location_local);
return $zone;
} else {
return null;
}
}
/**
* Gets all the zones matching the specified location queries
*
* @param string $location_global_query the global location query
* @param string $location_local_query the local location query
* @return Array a ContentZone array, with each item a zone found
*
* [SECURITY] They are passed as is in SQL [R]LIKE queries, you can't inject users expression.
*
* The following properties are added to the ContentZone items of the returned array:
* - location_global
* - location_local
*/
static function search ($location_global_query, $location_local_query, $use_regexp_for_local = false) {
global $db;
$zones = array();
$op = $use_regexp_for_local ? 'RLIKE' : 'LIKE';
$sql = "SELECT * FROM " . TABLE_CONTENT_ZONES_LOCATIONS . " WHERE location_global LIKE '$location_global_query' AND location_local $op '$location_local_query'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to set zone location", '', __LINE__, __FILE__, $sql);
}
while ($row = $db->sql_fetchrow($result)) {
$zone = new ContentZone($row['zone_id']);
$zone->location_global = $row['location_global'];
$zone->location_local = $row['location_local'];
$zones[] = $zone;
}
return $zones;
}
}
?>
diff --git a/includes/core.php b/includes/core.php
index 3ebbd98..9aae9d1 100755
--- a/includes/core.php
+++ b/includes/core.php
@@ -1,664 +1,664 @@
<?php
/**
* Core: helper methods and main libraries loader
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* @package Zed
* @subpackage Keruald
* @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
*/
////////////////////////////////////////////////////////////////////////////////
/// ///
/// Configures PHP and loads site-wide used libraries ///
/// ///
////////////////////////////////////////////////////////////////////////////////
error_reporting(E_ALL & ~E_NOTICE);
include_once("config.php");
include_once("error.php");
include_once("db/Database.php");
$db = Database::load();
Database::cleanupConfiguration();
include_once("sessions.php");
include_once("autoload.php");
////////////////////////////////////////////////////////////////////////////////
/// ///
/// Information helper methods ///
/// ///
////////////////////////////////////////////////////////////////////////////////
/**
* Gets the nickname from the specified perso ID
*
* @param integer $perso_id The specified perso ID
* @return string The perso's nickname
*/
function get_name ($perso_id) {
global $db;
$perso_id = $db->sql_escape($perso_id);
$sql = 'SELECT perso_nickname FROM '. TABLE_PERSOS . " WHERE perso_id = '$perso_id'";
if (!$result = $db->sql_query($sql)) message_die(SQL_ERROR, "Can't query persos table.", '', __LINE__, __FILE__, $sql);
$row = $db->sql_fetchrow($result);
return $row['perso_nickname'];
}
/**
* Gets the user ID from the specified username
*
* @param string $username The username
* @return integer the user ID
*/
function get_userid ($username) {
global $db;
$username = $db->sql_escape($username);
$sql = 'SELECT user_id FROM '. TABLE_USERS . " WHERE username LIKE '$username'";
if (!$result = $db->sql_query($sql)) message_die(SQL_ERROR, "Can't query users table.", '', __LINE__, __FILE__, $sql);
$row = $db->sql_fetchrow($result);
return $row['user_id'];
}
/**
* Gets an information from the application global registry
*
* @param string $key the registry's key
* @return string The key value
*/
function registry_get ($key) {
global $db;
$key = $db->sql_escape($key);
$sql = "SELECT registry_value FROM " . TABLE_REGISTRY . " WHERE registry_key = '$key'";
if (!$result = $db->sql_query($sql)) message_die(SQL_ERROR, "Can't read registry.", '', __LINE__, __FILE__, $sql);
$row = $db->sql_fetchrow($result);
return $row['registry_value'];
}
/**
* Sets an information in the application global registry
*
* @param string $key the registry key
* @param string $value the value to store at the specified registry key
*/
function registry_set ($key, $value) {
global $db;
$key = $db->sql_escape($key);
$value = $db->sql_escape($value);
$sql = "REPLACE INTO " . TABLE_REGISTRY . " (registry_key, registry_value) VALUES ('$key', '$value')";
if (!$db->sql_query($sql))
message_die(SQL_ERROR, "Can't update registry", '', __LINE__, __FILE__, $sql);
}
////////////////////////////////////////////////////////////////////////////////
/// ///
/// Misc helper methods ///
/// ///
////////////////////////////////////////////////////////////////////////////////
/**
* Generates a random string, according the specified format.
*
* <code>
* echo generate_random_string('AAA111'); //this could output SDQ245.
* </code>
*
* @author Pierre Habart <p.habart@ifrance.com>
*
* @param string $format The format e.g. AAA111
* @return string a random string
*/
function generate_random_string ($format) {
mt_srand((double)microtime()*1000000);
$str_to_return="";
$t_alphabet=explode(",","A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z");
$t_number=explode(",","1,2,3,4,5,6,7,8,9,0");
for ($i=0;$i<strlen($format);$i++)
{
if (preg_match("/^[a-zA-Z]/",$format[$i]))
{
$add=$t_alphabet[mt_rand() % sizeof($t_alphabet)];
if (preg_match("/^[a-z]/",$format[$i]))
$add=strtolower($add);
}
elseif(preg_match("/^[0-9]/",$format[$i]))
$add=$t_number[mt_rand() % sizeof($t_number)];
else $add="?";
$str_to_return.=$add;
}
return $str_to_return;
}
//Plural management
/**
* Returns "s" when the $amount request a plural
* This function is a French plural helper.
*
* @param $amount the amount of objects
* @return string 's' if $amount implies a plural ; '' if it implies a singular.
*/
function s ($amount) {
if ($amount >= 2 || $amount <= -2) return "s";
}
/**
* Returns "x" when the $amount request a plural
* This function is a French plural helper.
*
* @param $amount the amount of objects
* @return string 'x' if $amount implies a plural ; '' if it implies a singular.
*/
function x ($amount) {
if ($amount >= 2 || $amount <= -2) return "x";
}
//Debug
/**
* Prints human-readable information about a variable.
*
* It behaves like the print_r command, but the output is enclosed in pre tags,
* to have a preformatted HTML output.
*
* @param mixed $expression The expression to be printed
*/
function dprint_r ($expression) {
echo '<pre>';
print_r($expression);
echo '</pre>';
}
//GUID
/**
* Generates a GUID, or more precisely an UUID
* @link http://en.wikipedia.org/wiki/Universally_Unique_Identifier Wikipedia, Universally Unique Identifier.
*
* A UUID is a 36 chars string of 32 hexadecimal and 4 dashes, with a
* very high probability to be unique.
*
* @return string the UUID
*/
function new_guid() {
$characters = explode(",","a,b,c,d,e,f,0,1,2,3,4,5,6,7,8,9");
$guid = "";
for ($i = 0 ; $i < 36 ; $i++) {
if ($i == 8 || $i == 13 || $i == 18 || $i == 23) {
$guid .= "-";
} else {
$guid .= $characters[mt_rand() % sizeof($characters)];
}
}
return $guid;
}
/**
* Determines if the expression is a valid UUID (a guid without {}).
* @see new_guid
*
- * @param string $expression the expression to chjeck
+ * @param string $expression the expression to check
* @return boolean true if the specified expression is a valid UUID ; otherwise, false.
*/
function is_guid ($expression) {
//We avoid regexp to speed up the check
//A guid is a 36 characters string
if (strlen($expression) != 36) return false;
$expression = strtolower($expression);
for ($i = 0 ; $i < 36 ; $i++) {
if ($i == 8 || $i == 13 || $i == 18 || $i == 23) {
//with dashes
if ($expression[$i] != "-") return false;
} else {
//and numbers
if (!is_numeric($expression[$i]) && $expression[$i] != 'a' && $expression[$i] != 'b' && $expression[$i] != 'c' && $expression[$i] != 'd' && $expression[$i] != 'e' && $expression[$i] != 'f' ) return false;
}
}
return true;
}
/**
* Gets file extension
*
* @param string $file the file to get the extension
- * @return string the extension froùm the specified tfile
+ * @return string the extension from the specified file
*/
function get_extension ($file) {
$dotPosition = strrpos($file, ".");
return substr($file, $dotPosition + 1);
}
/**
* Determines if a string starts with specified substring
*
* @param string $haystack the string to check
* @param string $needle the substring to determines if it's the start
* @param boolean $case_sensitive determines if the search must be case sensitive
* @return boolean true if $haystack starts with $needle ; otherwise, false.
*/
function string_starts_with ($haystack, $needle, $case_sensitive = true) {
if (!$case_sensitive) {
$haystack = strtoupper($haystack);
$needle = strtoupper($needle);
}
if ($haystack == $needle) return true;
return strpos($haystack, $needle) === 0;
}
/**
* Inserts a message into the supralog
*
* @param string $category the entry category
* @param string $message the message to log
* @param string $source the entry source.
*/
function supralog ($category, $message, $source = null) {
global $db, $CurrentUser, $CurrentPerso;
$category = $db->sql_query_express($category);
$message = $db->sql_query_express($message);
$source = $db->sql_query_express($source ? $source : $_SERVER['SERVER_ADDR']);
$ip = $_SERVER['REMOTE_ADDR'];
$sql = "INSERT INTO " . TABLE_LOG .
" (entry_ip, user_id, perso_id, entry_category, entry_message, entry_source) VALUES
('$ip', $CurrentUser->id, $CurrentPerso->id, '$category', '$message', '$source')";
if ( !($result = $db->sql_query($sql)) )
message_die(SQL_ERROR, "Can't log this entry.", '', __LINE__, __FILE__, $sql);
}
////////////////////////////////////////////////////////////////////////////////
/// ///
/// Localization (l10n) ///
/// ///
////////////////////////////////////////////////////////////////////////////////
/**
* Defines the LANG constant, to lang to print
*
* This information is contained in the session, or if not yet defined,
* it's to determine according the user's browser preferences.
* @see find_lang
*/
function initialize_lang () {
//If $_SESSION['lang'] doesn't exist yet, find a common language
if (!array_key_exists('lang', $_SESSION)) {
$lang = find_lang();
$_SESSION['lang'] = $lang ? $lang : '-';
}
if ($_SESSION['lang'] != '-')
define('LANG', $_SESSION['lang']);
}
/**
* Gets a common lang spoken by the site and the user's browser
* @see get_http_accept_languages
*
* @return string the language
*/
function find_lang () {
if (file_exists('lang') && is_dir('lang')) {
//Gets lang/ subdirectories: this is the list of available languages
$handle = opendir('lang');
while ($file = readdir($handle)) {
if ($file != '.' && $file != '..' && is_dir("lang/$file")) {
$langs[] = $file;
}
}
//The array $langs contains now the language available.
//Gets the langs the user should want:
if (!$userlangs = get_http_accept_languages())
return;
//Gets the intersection between the both languages arrays
//If it matches, returns first result
$intersect = array_intersect($userlangs, $langs);
if (count($intersect)) {
return $intersect[0];
}
//Now it's okay with Opera and Firefox but Internet Explorer will
//by default return en-US and not en or fr-BE and not fr, so second pass
foreach ($userlangs as $userlang) {
$lang = explode('-', $userlang);
if (count($lang) > 1)
$userlangs2[] = $lang[0];
}
$intersect = array_intersect($userlangs2, $langs);
if (count($intersect)) {
return $intersect[0];
}
}
}
/**
* Gets the languages accepted by the browser, by order of priority.
*
* This will read the HTTP_ACCEPT_LANGUAGE variable sent by the browser in the
* HTTP request.
*
* @return Array an array of string, each item a language accepted by browser
*/
function get_http_accept_languages () {
//What language to print is sent by browser in HTTP_ACCEPT_LANGUAGE var.
//This will be something like en,fr;q=0.8,fr-fr;q=0.5,en-us;q=0.3
if (!array_key_exists('HTTP_ACCEPT_LANGUAGE', $_SERVER)) {
return null;
}
$http_accept_language = explode(',', $_SERVER["HTTP_ACCEPT_LANGUAGE"]);
foreach ($http_accept_language as $language) {
$userlang = explode(';q=', $language);
if (count($userlang) == 1) {
$userlangs[] = array(1, $language);
} else {
$userlangs[] = array($userlang[1], $userlang[0]);
}
}
rsort($userlangs);
foreach ($userlangs as $userlang) {
$result[] = $userlang[1];
}
return $result;
}
/**
* Loads specified language Smarty configuration file
*
* @param string $file the file to load
* @param mixed $sections array of section names, single section or null
*/
function lang_load ($file, $sections = null) {
global $smarty;
//Loads English file as fallback if some parameters are missing
if (file_exists("lang/en/$file"))
$smarty->configLoad("lang/en/$file", $sections);
//Loads wanted file (if it exists and a language have been defined)
if (defined('LANG') && LANG != 'en' && file_exists('lang/' . LANG . '/' . $file))
$smarty->configLoad('lang/' . LANG . '/' . $file, $sections);
}
/**
* Gets a specified language expression defined in configuration file
*
* @param string $key the configuration key matching the value to get
* @return string The value in the configuration file
*/
function lang_get ($key) {
global $smarty;
$smartyConfValue = $smarty->config_vars[$key];
return $smartyConfValue ? $smartyConfValue : "#$key#";
}
////////////////////////////////////////////////////////////////////////////////
/// ///
/// Zed date and time helper methods ///
/// ///
////////////////////////////////////////////////////////////////////////////////
/**
* Converts a YYYYMMDD or YYYY-MM-DD timestamp to unixtime
* @link http://en.wikipedia.org/wiki/Unix_time Unix time
*
* @param string $timestamp the timestamp to convert
- * @return inteeger the unixtime
+ * @return integer the unixtime
*/
function to_unixtime ($timestamp) {
switch (strlen($timestamp)) {
case 8:
//YYYYMMDD
return mktime(0, 0, 0, substr($timestamp, 4, 2), substr($timestamp, 6, 2), substr($timestamp, 0, 4));
case 10:
//YYYY-MM-DD
return mktime(0, 0, 0, substr($timestamp, 5, 2), substr($timestamp, 8, 2), substr($timestamp, 0, 4));
default:
throw new Exception("timestamp is not a valid YYYYMMDD or YYYY-MM-DD timestamp: $timestamp");
}
}
/**
* Converts a unixtime to the YYYYMMDD or YYYY-MM-DD timestamp format
* @see to_unixtime
*
* @param int $unixtime the time to convert
* @param int $format 8 or 10. If 8 (default), will output YYYYMMDD. If 10, YYYY-MM-DD.
* @return string the timestamp
*/
function to_timestamp ($unixtime = null, $format = 8) {
//If no parameter is specified (or null, or false), current time is used
//==== allows to_timestamp(0) to return correct 1970-1-1 value.
if ($unixtime === null || $unixtime === false) $unixtime = time();
switch ($format) {
case 8:
//YYYYMMDD
return date('Ymd', $unixtime);
case 10:
//YYYY-MM-DD
return date('Y-m-d', $unixtime);
default:
throw new Exception("format must be 8 (YYYYMMDD) or 10 (YYYY-MM-DD) and not $format.");
}
}
/**
* Converts a unixtime to the Hypership time format or gets the current hypership time.
* @link http://en.wikipedia.org/wiki/Unix_time
* @link http://www.purl.org/NET/Zed/blog/HyperShipTime
*
* @param int $unixtime The unixtime to convert to HyperShip time. If omitted, the current unixtime.
* @return string The HyperShip time
*/
function get_hypership_time ($unixtime = null) {
//If unixtime is not specified, it's now
if ($unixtime === null) $unixtime = time();
//Hypership time is a count of days since launch @ 2010-07-03 00:00:00
//Followed by a fraction of the current day /1000, like the internet time
//but in UTC timezone and not Switzerland CET/CEST.
//We don't need to use floor(), as we output the result at int, truncating
//automatically decimal values instead of round it (like in C).
$seconds = $unixtime - 1278115200;
$days = $seconds / 86400;
$fraction = (abs($seconds) % 86400) / 86.4;
return sprintf("%d.%03d", $days, $fraction);
}
////////////////////////////////////////////////////////////////////////////////
/// ///
/// URL helpers functions ///
/// ///
////////////////////////////////////////////////////////////////////////////////
/**
* Gets the URL matching the specified resource.
*
* Example:
* <code>
* $url = get_url('ship', $ship);
* echo $url; //if $ship contains S00001, this should print /ship/S00001
* </code>
*
* @param string $resource,... the resources
* @return string the URL matching the specified resource
*/
function get_url () {
global $Config;
if (func_num_args() > 0) {
$pieces = func_get_args();
return $Config['BaseURL'] . '/' . implode('/', $pieces);
} elseif ($Config['BaseURL'] == "" || $Config['BaseURL'] == $_SERVER["PHP_SELF"]) {
return "/";
} else {
return $Config['BaseURL'];
}
}
/**
* Gets the current page URL
*
* @return string the current page URL
*/
function get_page_url () {
$url = $_SERVER['SCRIPT_NAME'] . $_SERVER['PATH_INFO'];
if (substr($url, -10) == $_SERVER["PHP_SELF"]) {
return substr($url, 0, -9);
}
return $url;
}
/**
* Gets the server URL
* @todo find a way to detect https:// on non standard port
*
* @return string the server URL
*/
function get_server_url () {
switch ($port = $_SERVER['SERVER_PORT']) {
case '80':
return "http://$_SERVER[SERVER_NAME]";
case '443':
return "https://$_SERVER[SERVER_NAME]";
default:
return "http://$_SERVER[SERVER_NAME]:$_SERVER[SERVER_PORT]";
}
}
/**
* Gets $_SERVER['PATH_INFO'] or computes the equivalent if not defined.
*
* This function allows the entry point controllers to get the current URL
* in a consistent way, for any redirection configuration
*
* So with /foo/bar, /index.php/foo/bar, /zed/index.php/foo/bar or /zed/foo/bar
* get_current_url will return /foo/bar
*
* @return string the relevant URL part
*/
function get_current_url () {
global $Config;
//Gets relevant URL part from relevant $_SERVER variables
if (array_key_exists('PATH_INFO', $_SERVER)) {
//Without mod_rewrite, and url like /index.php/controller
//we use PATH_INFO. It's the easiest case.
return $_SERVER["PATH_INFO"];
}
//In other cases, we'll need to get the relevant part of the URL
$current_url = get_server_url() . $_SERVER['REQUEST_URI'];
//Relevant URL part starts after the site URL
$len = strlen($Config['SiteURL']);
//We need to assert it's the correct site
if (substr($current_url, 0, $len) != $Config['SiteURL']) {
dieprint_r(GENERAL_ERROR, "Edit includes/config.php and specify the correct site URL<br /><strong>Current value:</strong> $Config[SiteURL]<br /><strong>Expected value:</strong> a string starting by " . get_server_url(), "Setup");
}
if (array_key_exists('REDIRECT_URL', $_SERVER)) {
//With mod_rewrite, we can use REDIRECT_URL
//We takes the end of the URL, ie *FROM* $len position
return substr(get_server_url() . $_SERVER["REDIRECT_URL"], $len);
}
//Last possibility: use REQUEST_URI, but remove QUERY_STRING
//If you need to edit here, use $_SERVER['REQUEST_URI']
//but you need to discard $_SERVER['QUERY_STRING']
//We takes the end of the URL, ie *FROM* $len position
$url = substr(get_server_url() . $_SERVER["REQUEST_URI"], $len);
//But if there are a query string (?action=... we need to discard it)
if ($_SERVER['QUERY_STRING']) {
return substr($url, 0, strlen($url) - strlen($_SERVER['QUERY_STRING']) - 1);
}
return $url;
}
/**
* Gets an array of url fragments to be processed by controller
* @see get_current_url
*
* This method is used by the controllers entry points to know the URL and
* call relevant subcontrollers.
*
* @return Array an array of string, one for each URL fragment
*/
function get_current_url_fragments () {
$url_source = get_current_url();
if ($url_source == $_SERVER["PHP_SELF"]) return array();
return explode('/', substr($url_source, 1));
}
////////////////////////////////////////////////////////////////////////////////
/// ///
/// URL xmlHttpRequest helpers functions ///
/// ///
////////////////////////////////////////////////////////////////////////////////
/**
* Gets an hash value to check the integrity of URLs in /do.php calls
*
* @param Array $args the args to compute the hash
- * @return the hash paramater for your xmlHttpRequest url
+ * @return the hash parameter for your xmlHttpRequest url
*/
function get_xhr_hash ($args) {
global $Config;
array_shift($args);
return md5($_SESSION['ID'] . $Config['SecretKey'] . implode('', $args));
}
/**
* Gets the URL to call do.php, the xmlHttpRequest controller
*
* @return string the xmlHttpRequest url, with an integrity hash
*/
function get_xhr_hashed_url () {
global $Config;
$args = func_get_args();
$args[] = get_xhr_hash($args);
return $Config['DoURL'] . '/' . implode('/', $args);
}
/**
* Gets the URL to call do.php, the xmlHttpRequest controller
*
* @return string the xmlHttpRequest url
*/
function get_xhr_url () {
global $Config;
$args = func_get_args();
return $Config['DoURL'] . '/' .implode('/', $args);
}
diff --git a/includes/db/MySQL.php b/includes/db/MySQL.php
index aa4b2f2..2fee302 100755
--- a/includes/db/MySQL.php
+++ b/includes/db/MySQL.php
@@ -1,186 +1,186 @@
<?php
/**
* MySQL layer and helper class
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* @package Zed
* @subpackage Keruald
* @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
*/
/**
* SQL database class
*
* This is the MySQL implementation of our SQL abstraction layer
*/
class sql_db {
/*
* @var int the connection identifier
*/
private $id;
/**
* Initializes a new instance of the database abstraction class, for MySQL engine
*
- * @param string $host the SQL server to connect [optionnal, by default localhost]
- * @param string $username the SQL username [optionnal, by default root]
- * @param string $password the SQL password [optionnal, by default blank]
- * @param string $database the database to select [optionnal]
+ * @param string $host the SQL server to connect [optional, by default localhost]
+ * @param string $username the SQL username [optional, by default root]
+ * @param string $password the SQL password [optional, by default blank]
+ * @param string $database the database to select [optional]
*/
function __construct($host = 'localhost', $username = 'root', $password = '' , $database = '') {
//Checks extension requirement
if (!function_exists("mysql_connect")) {
message_die(GENERAL_ERROR, "You've chosen to use a MySQL database engine, but the MySQL extension is missing.", "Setup issue");
}
//Connects to the MySQL server
$this->id = @mysql_connect($host, $username, $password) or $this->sql_die(); //or die ("Can't connect to SQL server.");
//Selects database
if ($database != '') {
mysql_select_db($database, $this->id);
}
}
/**
* Outputs a can't connect to the SQL server message and exits.
* It's called on connect failure
*/
function sql_die () {
//You can custom here code when you can't connect to SQL server
//e.g. in a demo or appliance context, include('start.html'); exit;
//die ("Can't connect to SQL server.");
include('start.html');
exit;
}
/**
* Sends a unique query to the database
*
* @param string $query the query to execute
* @return resource if the query is successful, a resource identifier ; otherwise, false
*/
function sql_query ($query) {
return mysql_query($query, $this->id);
}
/**
* Fetches a row of result into an associative array
*
* @param resource $result The result that is being evaluated, from sql_query
* @return array an associative array with columns names as keys and row values as values
*/
function sql_fetchrow ($result) {
return mysql_fetch_array($result);
}
/**
* Gets last SQL error information
*
* @return array an array with two keys, code and message, containing error information
*/
function sql_error () {
$error['code'] = mysql_errno($this->id);
$error['message'] = mysql_error($this->id);
return $error;
}
/**
* Gets the number of rows affected or returned by a query
*
* @return int the number of rows affected (delete/insert/update) or the number of rows in query result
*/
function sql_numrows ($result) {
return mysql_num_rows($result);
}
/**
* Gets the primary key value of the last query (works only in INSERT context)
*
* @return int the primary key value
*/
function sql_nextid () {
return mysql_insert_id($this->id);
}
/**
* Express query method, returns an immediate and unique result
*
* @param string $query the query to execute
* @param string $error_message the error message
* @param boolean $return_as_string return result as string, and not as an array
* @return mixed the row or the scalar result
*/
function sql_query_express ($query = '', $error_message = "Impossible d'exécuter cette requête.", $return_as_string = true) {
if ($query === '' || $query === false || $query === null) {
//No query, no value
return '';
} elseif (!$result = $this->sql_query($query)) {
message_die(SQL_ERROR, $error_message, '', __LINE__, __FILE__, $query);
} else {
//Fetches row
$row = $this->sql_fetchrow($result);
//If $return_as_string is true, returns first query item (scalar mode) ; otherwise, returns row
return $return_as_string ? $row[0] : $row;
}
}
/**
* Escapes a SQL expression
*
* @param string $expression The expression to escape
* @return string The escaped expression
*/
function sql_escape ($expression) {
return mysql_real_escape_string($expression);
}
/*
* Sets the client character set (requires MySQL 5.0.7+).
*
* @param string $encoding the charset encoding to set
*/
function set_charset ($encoding) {
if (function_exists('mysql_set_charset')) {
//>=PHP 5.2.3
mysql_set_charset($encoding, $this->id);
} else {
//Old PHP version
$this->sql_query("SET NAMES '$encoding'");
}
}
/**
* Loads a database instance, connected and ready to process queries.
*/
static function load () {
global $Config;
//Creates an instance of this database class with configuration values
$db = new self(
$Config['database']['host'],
$Config['database']['username'],
$Config['database']['password'],
$Config['database']['database']
);
//Sets SQL connexion in UTF-8.
$db->set_charset('utf8');
return $db;
}
}
diff --git a/includes/db/MySQLi.php b/includes/db/MySQLi.php
index 6d02930..764263f 100644
--- a/includes/db/MySQLi.php
+++ b/includes/db/MySQLi.php
@@ -1,171 +1,171 @@
<?php
/**
* MySQLi layer and helper class
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, 2014, Dereckson, some rights reserved.
* Released under BSD license.
*
* @package Zed
* @subpackage Keruald
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2014 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
/**
* SQL layer and helper class: MySQLi
*
* @package Keruald
* @subpackage Keruald
* @copyright Copyright (c) 2010, Sébastien Santoro aka Dereckson
* @license Released under BSD license
* @version 0.1
*/
class DatabaseMySQLi {
/*
* @var int the connection identifier
*/
private $db;
/**
* Initializes a new instance of the database abstraction class, for MySQLi engine
*/
function __construct($host = 'localhost', $username = '', $password = '', $database = '') {
//Checks extension requirement
if (!class_exists("mysqli")) {
message_die(GENERAL_ERROR, "You've chosen to use a MySQLi database engine, but the MySQLi extension is missing.", "Setup issue");
}
//Connects to MySQL server
$this->db = new mysqli($host, $username, $password) or $this->sql_die();
//Selects database
if ($database != '') {
$this->db->select_db($database);
}
}
/**
* Outputs a can't connect to the SQL server message and exits.
* It's called on connect failure
*/
private function sql_die () {
//You can custom here code when you can't connect to SQL server
//e.g. in a demo or appliance context, include('start.html'); exit;
die ("Can't connect to SQL server.");
}
/**
* Sends a unique query to the database
*
* @return mixed if the query is successful, a mysqli_result instance ; otherwise, false
*/
function sql_query ($query) {
return $this->db->query($query);
}
/**
* Fetches a row of result into an associative array
*
* @return array an associative array with columns names as keys and row values as values
*/
function sql_fetchrow ($result) {
return $result->fetch_array();
}
/**
* Gets last SQL error information
*
* @return array an array with two keys, code and message, containing error information
*/
function sql_error () {
return [
'code' => $this->db->errno,
'message' => $this->db->error
];
}
/**
* Gets the number of rows affected or returned by a query
*
* @return int the number of rows affected (delete/insert/update) or the number of rows in query result
*/
function sql_numrows ($result) {
return $result->num_rows;
}
/**
* Gets the primary key value of the last query (works only in INSERT context)
*
* @return int the primary key value
*/
function sql_nextid () {
return $this->db->insert_id;
}
/**
* Express query method, returns an immediate and unique result
*
* @param string $query the query to execute
* @param string $error_message the error message
* @param boolean $return_as_string return result as string, and not as an array
* @return mixed the row or the scalar result
*/
function sql_query_express ($query = '', $error_message = "Impossible d'exécuter cette requête.", $return_as_string = true) {
if ($query === '' || $query === false || $query === null) {
//No query, no value
return '';
} elseif (!$result = $this->sql_query($query)) {
- //An error have occured
+ //An error have occurred
message_die(SQL_ERROR, $error_message, '', '', '', $query);
} else {
//Fetches row
$row = $this->sql_fetchrow($result);
//If $return_as_string is true, returns first query item (scalar mode) ; otherwise, returns row
return $return_as_string ? $row[0] : $row;
}
}
/*
* Escapes a SQL expression
* @param string expression The expression to escape
* @return string The escaped expression
*/
function sql_escape ($expression) {
return $this->db->real_escape_string($expression);
}
/**
* Sets charset
*/
function set_charset ($encoding) {
$this->db->set_charset($encoding);
}
/**
* Loads a database instance, connected and ready to process queries.
*/
static function load () {
global $Config;
//Creates an instance of this database class with configuration values
$db = new self(
$Config['database']['host'],
$Config['database']['username'],
$Config['database']['password'],
$Config['database']['database']
);
//Sets SQL connexion in UTF-8.
$db->set_charset('utf8');
return $db;
}
}
diff --git a/includes/error.php b/includes/error.php
index 720a569..5520d84 100755
--- a/includes/error.php
+++ b/includes/error.php
@@ -1,196 +1,196 @@
<?php
/**
* Error handler
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
- * This error handler uses the same idea and message_die methode signature
+ * This error handler uses the same idea and message_die method signature
* of the phpBB 2 one.
*
* @package Zed
* @subpackage Keruald
* @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 delete old_message_die method and write alternative HTML textual output
* in the message_die method
*/
///
/// Error constants
///
/**
* SQL_ERROR is the constant meaning the error is a SQL error.
*
* As a message_die function parameter, it allows to add SQL specific debug information.
*/
define ("SQL_ERROR", 65);
/**
* HACK_ERROR is the constant meaning access is non authorized to the resource.
*
* It encompasses two problematics:
* the URL points to a resource belonging to another user or for the current user have no access right (for malformed URL, pick instead GENERAL_ERROR) ;
* the user is anonymous, instead to be logged in.
*
* A suggested way to handle the second problematic is to store in hidden input
* fields or better in the session the previous form data, and to print a login
* form.
*
* If you implement this, you don't even need to distinguishes between the two
* cases, as once logged in, the regular HACK_ERROR could also be printed.
*/
define ("HACK_ERROR", 99);
/**
* GENERAL_ERROR is the constant meaning the error is general, ie not covered by
* another more specific error constant.
*/
define ("GENERAL_ERROR", 117);
///
/// Error helper functions
///
/**
* Output a general error, with human-readable information about the specified
* expression as error message ; terminates the current script.
*
* @see message_die
*
* @param mixed $expression the expression to be printed
- * @param string $title the message title (optionnal, default will be 'Debug')
+ * @param string $title the message title (optional, default will be 'Debug')
*/
function dieprint_r ($expression, $title = '') {
if (!$title) {
$title = 'Debug'; //if title is omitted or false/null, default title
}
message_die(GENERAL_ERROR, '<pre>' . print_r($expression, true) .'</pre>', $title);
}
/**
* Outputs an error message and terminates the current script.
*
* Error will be output through Smarty one of the following templates :
* error_block.tpl if the header have already been printed ;
- * error.tpl if the error ocurred before the header were called and printed.
+ * error.tpl if the error occurred before the header were called and printed.
*
* If smarty couldn't be loaded, old_message_die method will be called, which
* produces a table output.
*
* @param int $msg_code an integer constant identifying the error (HACK_ERROR, SQL_ERROR, GENERAL_ERROR)
- * @param string $msg_text the error message text (optionnal, but recommanded)
- * @param string $msg_title the error message title (optionnal)
- * @param int $err_line the line number of the file where the error occured (optionnal, suggested value is __LINE__)
- * @param string $err_line the path of file where the error occured (optionnal, suggested value is __FILE__)
- * @param string $sql the SQL query (optionnal, used only if msg_code is SQL_ERROR)
+ * @param string $msg_text the error message text (optional, but recommended)
+ * @param string $msg_title the error message title (optional)
+ * @param int $err_line the line number of the file where the error occurred (optional, suggested value is __LINE__)
+ * @param string $err_line the path of file where the error occurred (optional, suggested value is __FILE__)
+ * @param string $sql the SQL query (optional, used only if msg_code is SQL_ERROR)
*/
function message_die ($msg_code, $msg_text = '', $msg_title = '', $err_line = '', $err_file = '', $sql = '') {
global $smarty, $db;
if ($smarty) {
$debug_text = $msg_text;
if ($err_line && $err_file)
$debug_text .= ' &mdash; ' . $err_file. ', ' . lang_get('line') . ' ' . $err_line ;
switch ($msg_code) {
case HACK_ERROR:
$smarty->assign('TITLE', lang_get('UnauthorizedAccess'));
break;
case SQL_ERROR:
$smarty->assign('TITLE', lang_get('SQLError'));
$sql_error = $db->sql_error();
if ($sql_error['message'] != '') {
$debug_text .= '<br />' . lang_get('Error') . ' n° ' . $sql_error['code'] . lang_get('_t') .
' ' .$sql_error['message'];
}
$debug_text .= "</p><h2>Query:</h2><p>$sql";
break;
default:
$smarty->assign('WAP', "Message code error.<br />Expected: HACK_ERROR, SQL_ERROR, GENERAL_ERROR");
//Falls to GENERAL_ERROR
case GENERAL_ERROR:
if ($msg_title)
$smarty->assign('TITLE', $msg_title);
else
$smarty->assign('TITLE', lang_get('GeneralError'));
break;
}
$smarty->assign('ERROR_TEXT', $debug_text);
$template = (defined('HEADER_PRINTED') && HEADER_PRINTED) ? "error_block.tpl" : "error.tpl";
$smarty->display($template);
exit;
} else {
old_message_die($msg_code, $msg_text, $msg_title, $err_line, $err_file, $sql);
}
}
/**
* Outputs an error message and terminates the current script.
*
* This is the message_die method from Espace Win, used on Zed as fallback if Smarty isn't initialized yet.
* Former "german style" error HTML markups have been removed.
*
* @param int $msg_code an integer constant identifying the error (HACK_ERROR, SQL_ERROR, GENERAL_ERROR)
- * @param string $msg_text the error message text (optionnal, but recommanded)
- * @param string $msg_title the error message title (optionnal)
- * @param int $err_line the line number of the file where the error occured (optionnal, suggested value is __LINE__)
- * @param string $err_line the path of file where the error occured (optionnal, suggested value is __FILE__)
- * @param string $sql the SQL query (optionnal, used only if msg_code is SQL_ERROR)
+ * @param string $msg_text the error message text (optional, but recommended)
+ * @param string $msg_title the error message title (optional)
+ * @param int $err_line the line number of the file where the error occurred (optional, suggested value is __LINE__)
+ * @param string $err_line the path of file where the error occurred (optional, suggested value is __FILE__)
+ * @param string $sql the SQL query (optional, used only if msg_code is SQL_ERROR)
*
* @deprecated since 0.1
*/
function old_message_die($msg_code, $msg_text = '', $msg_title = '', $err_line = '', $err_file = '', $sql = '')
{
global $db, $Utilisateur;
$sql_store = $sql;
if ($msg_code == HACK_ERROR && $Utilisateur[user_id] < 1000) {
die("You must be logged in to access to this resource.");
} elseif ($msg_code == HACK_ERROR) {
$title = "You aren't allowed to access this resource.";
$debug_text = $msg_text;
} elseif ($msg_code == SQL_ERROR) {
$title = "SQL error";
$sql_error = $db->sql_error();
$debug_text = $msg_text;
if ($err_line != '' && $err_file != '') {
$debug_text .= ' in ' . $err_file. ', line ' . $err_line ;
}
if ($sql_error['message'] != '') {
$debug_text .= '<br />Error #' . $sql_error['code'] . ': ' . $sql_error['message'];
}
if ($sql_store != '') {
$debug_text .= "<br /><strong>$sql_store</strong>";
}
} elseif ($msg_code == GENERAL_ERROR) {
$title = $msg_title;
$debug_text = $msg_text;
if ($err_line && $err_file) {
$debug_text .= "<br />$err_file, line $err_line";
}
}
echo '<div id="fatal_error"><h2 class="fatal_error_title">';
echo $title;
echo '</h2><p class="fatal_error_message">';
echo $debug_text;
echo '</p></div';
die;
}
diff --git a/includes/geo/body.php b/includes/geo/body.php
index 86bebfa..e9d7f25 100755
--- a/includes/geo/body.php
+++ b/includes/geo/body.php
@@ -1,172 +1,172 @@
<?php
/**
* 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
* @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
*
* @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
*
* @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;
+ $this->lastError = "body unknown: " . $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 the status field
*
* @return string the status field value (e.g. "asteroid,hidden")
*/
function getStatus () {
$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)
*
* @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.
+ //by priority, as it'll return the first triggered.
//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 = getStatus();
$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();
}
}
}
diff --git a/includes/geo/location.php b/includes/geo/location.php
index 1730620..8be9601 100755
--- a/includes/geo/location.php
+++ b/includes/geo/location.php
@@ -1,434 +1,434 @@
<?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 Initialize $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
+ * @var Array
*/
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
+ //a local location handler. Or a some inheritance, 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 (count($this->data) > 1) ? $this->data[1] : null;
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 Handle 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 equal.
*/
function equals ($expression) {
//Are global location equals?
//TODO: create a better set of rules to define when 2 locations are equal.
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;
case 'x':
$pt = $this->point3D->toSpherical();
return sprintf("(%d, %d°, %d°)", $pt[0], $pt[1], $pt[2]);
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
index 8edfe57..02c2c9f 100755
--- a/includes/geo/place.php
+++ b/includes/geo/place.php
@@ -1,214 +1,214 @@
<?php
/**
* 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
* @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
*/
/**
* 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 " . TABLE_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;
+ $this->lastError = "place unknown: " . $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 getStatus () {
$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->getStatus();
$location_local_format = $db->sql_escape($this->location_local_format);
//Updates or inserts
$sql = "REPLACE INTO " . TABLE_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.
*/
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 " . TABLE_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 " . TABLE_PLACES . " WHERE FIND_IN_SET('start', place_status) > 0 ORDER BY rand() LIMIT 1";
return $db->sql_query_express($sql);
}
}
diff --git a/includes/geo/point3D.php b/includes/geo/point3D.php
index 577163b..82cc85c 100755
--- a/includes/geo/point3D.php
+++ b/includes/geo/point3D.php
@@ -1,239 +1,239 @@
<?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
*/
require_once("galaxy.php");
/**
* Geo point 3D class.
*
* This class represents 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
*
* @param int $x the x coordinate
* @param int $y the y coordinate
* @param int $z the z coordinate
*/
function __construct ($x, $y, $z) {
$this->x = (int)$x;
$this->y = (int)$y;
$this->z = (int)$z;
}
/**
- * Parses a string expression ang gets a GeoPoint3D object
+ * Parses a string expression and gets a GeoPoint3D object
*
* Formats recognized are:
* - xyz: [x, y, z]
* - (x, y, z)
*
* @param string $expression the expression to parse
* @return GeoPoint3D If the specified expression could be parsed, a GeoPoint3D instance ; otherwise, null.
*/
static function fromString ($expression) {
if (string_starts_with($expression, 'xyz:', false)) {
$pos1 = strpos($expression, '[', 4) + 1;
$pos2 = strpos($expression, ']', $pos1);
if ($pos1 > -1 && $pos2 > -1) {
$expression = substr($expression, $pos1, $pos2 - $pos1);
$xyz = explode(',', $expression, 3);
return new GeoPoint3D($xyz[0], $xyz[1], $xyz[2]);
}
} elseif ($expression[0] = '(') {
$expression = substr($expression, 1, -1);
$xyz = explode(',', $expression, 3);
return new GeoPoint3D($xyz[0], $xyz[1], $xyz[2]);
}
return null;
}
/**
* Returns a string representation of the point coordinates.
*
* @param $format the format to use
* @return string a string representation of the coordinates
*
* To print a "xyz: [10, 20, 40]" string:
* $point = new GeoPoint3D(10, 20, 40);
* echo $point->sprintf("xyz: [%d, %d, %d]");
*
- * //Of course, you could have (implicitely) use the __toString method:
+ * //Of course, you could have (implicitly) use the __toString method:
* echo $point;
*
* To print a (10, 20, 40) string:
* $point = new GeoPoint3D(10, 20, 40);
* echo $point->sprintf("(%d, %d, %d)");
*/
function sprintf ($format) {
return sprintf($format, $this->x, $this->y, $this->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 $this->sprintf("xyz: [%d, %d, %d]");
}
/**
* Determines if this point is equal to the specified point.
*
* @param GeoPoint3D $point The point to compare
* @return bool true if the two points are equal ; otherwise, false.
*/
function equals ($point) {
return ($this->x == $point->x) && ($this->y == $point->y) && ($this->z == $point->z);
}
//
// Math
//
/**
* Gets the (ρ, φ, θ) spherical coordinates from the current x, y, z cartesian point
*
* The algo used is from http://fr.wikipedia.org/wiki/Coordonn%C3%A9es_sph%C3%A9riques#Relation_avec_les_autres_syst.C3.A8mes_de_coordonn.C3.A9es_usuels
*
* @return array an array of 3 floats number, representing the (ρ, φ, θ) spherical coordinates
*/
function toSpherical () {
return GeoGalaxy::cartesianToSpherical($this->x, $this->y, $this->z);
}
/**
* Gets the (ρ, φ, θ) spherical coordinates from the current x, y, z cartesian point
*
* The algo used is from http://www.phy225.dept.shef.ac.uk/mediawiki/index.php/Cartesian_to_polar_conversion
*
* @return array an array of 3 floats number, representing the (ρ, φ, θ) spherical coordinates
*/
function toSphericalAlternative () {
return GeoGalaxy::cartesianToSphericalAlternative($this->x, $this->y, $this->z);
}
/**
* Translates the center and rescales.
*
* This method allow to help to represent coordinate in a new system
*
* This method is used to represent Zed objects in dojo with the following
* parameters:
* <code>
* $pointKaos = GeoPoint3D(800, 42, 220);
* $pointKaos->translate(500, 300, 200, 2);
* echo $pointKaos;
* //This will output xyz: [150, -129, 10]
* </code>
*
* @param int $dx the difference between the old x and new x (ie the value of x = 0 in the new system)
* @param int $dy the difference between the old y and new y (ie the value of y = 0 in the new system)
* @param int $dz the difference between the old y and new z (ie the value of z = 0 in the new system)
* @param float $scale if specified, divides each coordinate by this value (optional)
*/
function translate ($dx, $dy, $dz, $scale = 1) {
if ($scale == 1) {
$this->x += $dx;
$this->y += $dy;
$this->z += $dz;
} elseif ($scale == 0) {
$this->x = 0;
$this->y = 0;
$this->z = 0;
} else {
$this->x = $this->x * $scale + $dx;
$this->y = $this->y * $scale + $dy;
$this->z = $this->z * $scale + $dz;
}
}
//
// Implementing IteratorAggregate
//
/**
* Retrieves class iterator. It traverses x, y and z.
*
* @return Traversable the iterator
*/
function getIterator () {
return new ArrayIterator($this);
}
}
diff --git a/includes/geo/pointPolarZ.php b/includes/geo/pointPolarZ.php
index 2dfd7f9..3098089 100755
--- a/includes/geo/pointPolarZ.php
+++ b/includes/geo/pointPolarZ.php
@@ -1,374 +1,374 @@
<?php
/**
* Geo point polar+z class.
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* @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("point3D.php");
/**
* Geo point polar+z class.
*
* This class represents a r, ρ, z point.
*
* They are useful to express coordinates in a cylinder shape, like a tower
* where it make senses to use polar coordinates instead x, y but where the
* height is not relative to a center, like it would be in a sphere.
*
* It implements IteratorAggregate to allow the foreach instruction
* on a GeoPointPolarZ object:
*
* <code>
* $point = new GeoPointPolarZ(17, '24°', -6);
* foreach ($point as $axis => $coordinate) {
* echo "\n\t$axis = $coordinate";
* }
* //This will output:
* // r = 17
* // t = 24°
* // z = -6
* </code>
*
* The point 3D representation is rtz: [ρ, θ, z] ; you can print it as a string
* and get this format:
*
* <code>
* $point = new GeoPointPolarZ(17, '24°', -6);
* echo (string)$point; //will output rρz: [17, 24°, -6]
* </code>
*
*/
class GeoPointPolarZ implements IteratorAggregate {
//
// ρ, θ, z public properties
//
/**
* the ρ coordinate
*
* @var float
*/
public $r;
/**
* the θ coordinate
*
* This coordinate could be expressed as:
* - a string with a float, appended by "°" or " °" (in degree)
* - as a float (in radian)
*
* @var mixed
*/
public $t;
/**
* the z coordinate
*
* @var float
*/
public $z;
//
// constructor / toString
//
/**
* Initializes a new instance of GeoPointPolarZ class
*
* @param float $r the ρ coordinate
* @param mixed $t the θ coordinate, in ° (string) or radian (float)
* @param float $z the z coordinate
*/
function __construct ($r, $t, $z) {
$this->r = (float)$r;
$this->t = trim($t);
$this->z = (float)$z;
}
/**
- * Parses a string expression ang gets a GeoPointPolarZ object
+ * Parses a string expression and gets a GeoPointPolarZ object
*
* Formats recognized are:
* - rtz: [ρ, θ, z]
* - (ρ, θ, z)
*
* @param string $expression the expression to parse
* @return GeoPointPolarZ If the specified expression could be parsed, a GeoPointPolarZ instance ; otherwise, null.
*/
static function fromString ($expression) {
if (string_starts_with($expression, 'rtz:', false)) {
$pos1 = strpos($expression, '[', 4) + 1;
$pos2 = strpos($expression, ']', $pos1);
if ($pos1 > -1 && $pos2 > -1) {
$expression = substr($expression, $pos1, $pos2 - $pos1);
$rtz = explode(',', $expression, 3);
return new GeoPointPolarZ($rtz[0], $rtz[1], $rtz[2]);
}
} elseif ($expression[0] = '(') {
$expression = substr($expression, 1, -1);
$rtz = explode(',', $expression, 3);
return new GeoPointPolarZ($rtz[0], $rtz[1], $rtz[2]);
}
return null;
}
/**
* Returns a string representation of the point coordinates.
*
* @param $format the format to use
* @return string a string representation of the coordinates
*
* To print a "rtz: [10, 20°, 40]" string:
* $point = new GeoPointPolarZ(10, '20°', 40);
* echo $point->sprintf("rtz: [%d, %s, %d]");
*
- * //Of course, you could have (implicitely) use the __toString method:
+ * //Of course, you could have (implicitly) use the __toString method:
* echo $point;
*
* To print a (10, 20°, 40) string:
* $point = new GeoPointPolarZ(10, 20°, 40);
* echo $point->sprintf("(%d, %s, %d)");
*/
function sprintf ($format) {
return sprintf($format, $this->r, self::getDegrees($this->t), $this->z);
}
/**
* Returns a rρz: [r, ρ, z] string representation of the point coordinates.
*
* @return string a rtz: [ρ, θ, z] string representation of the coordinates
*/
function __toString () {
return $this->sprintf("rtz: [%d, %s, %d]");
}
/**
* Determines if this point is equal to the specified point.
*
* @param GeoPointPolarZ $point The point to compare
* @return bool true if the two points are equal ; otherwise, false.
*/
function equals ($point) {
return ($this->r == $point->r) && self::areAngleEqual($this->t, $point->t) && ($this->z == $point->z);
}
/**
- * Detemrines if two angles are equal
- * @param mixed $angle1 the first angle value, ie a float (angle in radian) or a string formed by an integed appended by ° (degrees)
- * @param mixed $angle2 the second angle value, a float (angle in radian) or a string formed by an integed appended by ° (degrees)
+ * Determines if two angles are equal
+ * @param mixed $angle1 the first angle value, ie a float (angle in radian) or a string formed by an integer appended by ° (degrees)
+ * @param mixed $angle2 the second angle value, a float (angle in radian) or a string formed by an integer appended by ° (degrees)
* @return bool true if the angles are equal ; otherwise, false.
*/
static function areAngleEqual ($angle1, $angle2) {
if ($angle1 === $angle2) return true;
if (!is_numerical($angle1)) {
$angle1 = deg2rad((float)$angle1);
}
if (!is_numerical($angle2)) {
$angle2 = deg2rad((float)$angle2);
}
$angle1 = self::normalizeAngle($angle1);
$angle2 = self::normalizeAngle($angle2);
return ($angle1 == $angle2);
}
/**
* Normalizes an angle (in radians) in the interval [0, π[ (or a custom interval)
*
* @param float $angle the angle (in radians)
* @param float $min the radians value the angle must be greater or equal than [optional, default value: 0]
- * @param float $max the radains value the angle must be stricly lesser than [optional, default value: M_PI]
+ * @param float $max the radians value the angle must be strictly lesser than [optional, default value: M_PI]
* @param float $interval the increment interval [optional, default value: 360]
*/
static function normalizeAngle ($angle, $min = 0, $max = M_PI, $interval = M_PI) {
while ($angle < $min) {
$angle += $interval;
}
while ($angle >= $max) {
$angle -= $interval;
}
return $angle;
}
/**
* Normalizes an angle (in degrees) in the interval [0, 360[ (or a custom interval)
*
* @param float $angle the angle to normalize, in degrees
* @param float $min the degrees value the angle must be greater or equal than [optional, default value: 0]
- * @param float $max the degrees value the angle must be stricly lesser than [optional, default value: 360]
+ * @param float $max the degrees value the angle must be strictly lesser than [optional, default value: 360]
* @param float $interval the increment interval [optional, default value: 360]
*/
static function normalizeAngleInDegrees ($angle, $min = 0, $max = 360, $interval = 360) {
while ($angle < $min) {
$angle += $interval;
}
while ($angle >= $max) {
$angle -= $interval;
}
return $angle;
}
/**
* Gets the specified angle in radians
*
* @param mixed $angle the angle, a float in radians or a string (a float + "°" or " °" in degrees
* @return float the angle in radians
*/
static function getRadians ($angle) {
return is_numeric($angle) ? $angle : deg2rad((float)$angle);
}
/**
* Gets the specified angle in degrees
*
* @param mixed $angle the angle, a float in radians or a string (a float + "°" or " °" in degrees
* @return string the angle (float) in degrees followed by "°"
*/
static function getDegrees ($angle) {
return is_numeric($angle) ? rad2deg((float)$angle) . '°' : $angle;
}
/**
* Converts a polar coordinate angle to a 0-360° CW angle
*/
static function getNaturalDegrees ($angle) {
return self::normalizeAngleinDegrees(90 - self::getDegrees($angle));
}
//
// Math
//
/**
* Gets the (x, y, z) cartesian coordinates from the current ρ, θ, z polar+z point
*
* @return array an array of 3 floats number, representing the (x, y, z) cartesian coordinates
*/
function toCartesian () {
$x = $this->r * cos(self::getRadians($this->t));
$y = $this->r * sin(self::getRadians($this->t));
return array($x, $y, $this->z);
}
/**
* Converts the current GeoPointPolarZ instance to a GeoPoint3D instance
*
* @return GeoPoint3D an instance of the GeoPoint3D class representing the (x, y, z) cartesian coordinates
*/
function toPoint3D () {
$pt = $this->toCartesian();
return new GeoPoint3D($pt[0], $pt[1], $pt[2]);
}
/**
* Gets the (ρ, φ, θ) spherical coordinates from the current (ρ, θ, z) polar+z point
*
* The algo used is from http://fr.wikipedia.org/wiki/Coordonn%C3%A9es_sph%C3%A9riques#Relation_avec_les_autres_syst.C3.A8mes_de_coordonn.C3.A9es_usuels
*
* @return array an array of 3 floats number, representing the (ρ, φ, θ) spherical coordinates
*/
function toSpherical () {
$pt = $this->toCartesian();
return GeoGalaxy::cartesianToSpherical($pt[0], $pt[1], $pt[2]);
}
/**
* Gets the (ρ, φ, θ) spherical coordinates from the current (ρ, θ, z) polar+z point
*
* The algo used is from http://www.phy225.dept.shef.ac.uk/mediawiki/index.php/Cartesian_to_polar_conversion
*
* @return array an array of 3 floats number, representing the (ρ, φ, θ) spherical coordinates
*/
function toSphericalAlternative () {
$pt = $this->toCartesian();
return GeoGalaxy::cartesianToSphericalAlternative($pt[0], $pt[1], $pt[2]);
}
/**
* Translates the center and rescales.
*
* This method allow to help to represent coordinate in a new system
*
* This method is used to represent Zed objects in dojo with the following
* parameters:
* <code>
* $pointKaos = GeoPointPolarZ(800, 42, 220);
* $pointKaos->translate(500, 300, 200, 2);
* echo $pointKaos;
* //This will output rρz: [150, -129, 10]
* </code>
*
* @param float $dr the difference between the old ρ and new ρ (ie the value of ρ = 0 in the new system)
* @param float $dt the difference between the old θ and new θ (ie the value of θ = 0 in the new system)
* @param float $dz the difference between the old y and new z (ie the value of z = 0 in the new system)
* @param int $scale if specified, divides each coordinate by this value (optional)
*/
function translate ($dr, $dt, $dz, $scale = 1) {
if ($scale == 1) {
$this->r += $dr;
$this->t += $dt;
$this->z += $dz;
} elseif ($scale == 0) {
$this->r = 0;
$this->t = 0;
$this->z = 0;
} else {
$this->r = $this->r * $scale + $dr;
$this->t = $this->t * $scale + $dt;
$this->z = $this->z * $scale + $dz;
}
}
/**
* Calculates the section number the specified angle belongs
*
* @param $angle float The natural angle in degree (North 0°, East 90°, etc. clockwise)
* @param int $count the number of sections (default value: 6)
* @return $int the section number
*/
static function calculateSection ($angle, $count = 6) {
if ($angle < 90) {
$angle += 270;
} else {
$angle -= 90;
}
return 1 + (int)($angle / (360/$count));
}
/**
* Gets the section number the θ angle belongs to.
*
* @param int $count the number of sections
* @return $int the section number
*/
function getSection ($count = 6) {
return self::calculateSection(self::getNaturalDegrees($this->t), $count);
}
//
// Implementing IteratorAggregate
//
/**
* Retrieves class iterator. It traverses ρ, θ and z.
*
* @return Traversable the iterator
*/
function getIterator () {
return new ArrayIterator($this);
}
}
diff --git a/includes/geo/sceneindex.php b/includes/geo/sceneindex.php
index 5217ec5..e1f3cba 100755
--- a/includes/geo/sceneindex.php
+++ b/includes/geo/sceneindex.php
@@ -1,218 +1,218 @@
<?php
/**
* Geo scene index class.
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* @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
*
* This class implements a singleton pattern.
*/
require_once('includes/cache/cache.php');
/**
* Geo scene class
*
* This class provides an index of available scene template files.
*/
class GeoSceneIndex {
/**
* Global location templates array
*
* Keys are global location codes.
* Values the relevant template file.
*
* @var Array
*/
public $global_templates;
/**
- * Rocal location templates 2D array
+ * Local location templates 2D array
*
- * Keys are global and local ocation codes.
+ * Keys are global and local location codes.
* Values the relevant template file.
*
* e.g. $local_templates['B00017001']['(10, 50, 8)'] => 'B00017_port.tpl'
*
* @var Array
*/
public $local_templates;
/**
* Time of the last updated file in the scenes directory
*
* @var int
*/
public $updated;
/**
* The directory where templates are stored
*
* @var string
*/
public $directory;
/**
* The current index instance array
*
* Keys are scene directories (string)
* Items are GeoSceneIndex instances
*
* @var Array
*/
static $instance = array();
/**
* Gets the index instance, initializing it if needed
*
* @return index the index instance
*/
static function load ($directory) {
//Creates the index object if needed
if (!array_key_exists($directory, self::$instance)) {
self::$instance[$directory] = new GeoSceneIndex($directory);
}
return self::$instance[$directory];
}
/**
- * Initializes a new GeoSceneIndex istance
+ * Initializes a new GeoSceneIndex instance
*
* @param string $directory the scene templates directory
*/
public function __construct ($directory) {
$this->directory = $directory;
if (!$this->get_cached_information() || !$this->is_up_to_date()) {
$this->refresh_information();
$this->set_cached_information();
}
}
/**
* Caches index data
*/
public function set_cached_information () {
$cache = Cache::load();
$cache->set('zed_sceneindex', serialize($this));
}
/**
* Gets index from cache
*/
public function get_cached_information () {
$cache = Cache::load();
$cached_index =$cache->get('zed_sceneindex');
if ($index = unserialize($cache->get('zed_sceneindex'))) {
$index = unserialize($cache->get('zed_sceneindex'));
$this->global_templates = $index->global_templates;
$this->local_templates = $index->local_templates;
$this->updated = $index->updated;
$this->directory = $index->directory;
return true;
}
return false;
}
/**
* Reads scene templates and indexes information
*/
public function refresh_information () {
$this->global_templates = array();
$this->local_templates = array();
$this->updated = filemtime($this->directory);
if ($handle = opendir($this->directory)) {
while (false !== ($file = readdir($handle))) {
if (GeoScene::get_file_extension($file) == 'tpl') {
$template = file_get_contents($this->directory . '/' . $file, false, NULL, 0, 1024);
$location = self::get_template_location($template);
if ($location[1] !== NULL) {
$this->local_templates[$location[0]][$location[1]] = $file;
} elseif ($location[0] != NULL) {
$this->global_templates[$location[0]] = $file;
}
}
}
closedir($handle);
}
}
/**
* Determines if the information is still up to date
*
* @return bool true if the information is up to date ; otherwise, false.
*/
public function is_up_to_date () {
return ($this->updated == filemtime($this->directory));
}
/**
* Gets template location
*
* @return Array an string array of the location (two items; global, local)
* At key 0, a string with global location, or NULL if not specified
* At key 1, a string with local location, or NULL if not specified
*/
private static function get_template_location ($template) {
$location = array(NULL, NULL);
//Gets global location
$pos1 = strpos($template, "Global location: ");
if ($pos1 === false) {
throw new Exception("No location in template. Any template file must contain a comment line with the string 'Global location: ' followed by the global location matching the template. It should also contains a line 'Local location: ' when applicable.");
}
$pos1 += 17;
$pos2 = strpos($template, "\n", $pos1);
$location[0] = trim(substr($template, $pos1, $pos2 - $pos1));
//Gets local location
$pos1 = strpos($template, "Local location: ");
if ($pos1 !== false) {
$pos1 += 16;
$pos2 = strpos($template, "\n", $pos1);
$location[1] = trim(substr($template, $pos1, $pos2 - $pos1));
}
return $location;
}
/**
* Gets local template file from index
*
* @param string $location_global the global location
* @param string $location_global the local location
- * @return string the relevant template scene file, or NULL if not existant
+ * @return string the relevant template scene file, or NULL if not existing
*/
public function get_local_template ($location_global, $location_local) {
if (isset($this->local_templates[$location_global][$location_local])) {
return $this->local_templates[$location_global][$location_local];
}
return NULL;
}
/**
* Gets global template file from index
*
* @param string $location_global the global location
- * @return string the relevant template scene file, or NULL if not existant
+ * @return string the relevant template scene file, or NULL if not existing
*/
public function get_global_template ($location_global) {
if (isset($this->global_templates[$location_global])) {
return $this->global_templates[$location_global];
}
return NULL;
}
}
diff --git a/includes/objects/application.php b/includes/objects/application.php
index 5443741..5dc2589 100755
--- a/includes/objects/application.php
+++ b/includes/objects/application.php
@@ -1,175 +1,175 @@
<?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
* @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;
+ $this->lastError = "Application unknown: " . $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)
+ * @param string $userkey User application key GUID (optional)
* @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;
}
}
diff --git a/includes/objects/content.php b/includes/objects/content.php
index 159c72c..5560ba6 100755
--- a/includes/objects/content.php
+++ b/includes/objects/content.php
@@ -1,302 +1,302 @@
<?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
*
* @deprecated
*/
/**
* 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.
*
* [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
+ * If a content have more than one location, only the first occurrence 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.
*
* @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
*
* @deprecated
*/
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;
+ $this->lastError = "Content unknown: " . $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;
}
}
diff --git a/includes/objects/invite.php b/includes/objects/invite.php
index b91198a..995096e 100755
--- a/includes/objects/invite.php
+++ b/includes/objects/invite.php
@@ -1,197 +1,197 @@
<?php
/**
* User invite class
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* 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;
/**
* 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 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;
+ $this->lastError = "Invite code unknown: " . $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.
+ * Determines whether 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
index ee2fb3e..9755f3f 100755
--- a/includes/objects/message.php
+++ b/includes/objects/message.php
@@ -1,156 +1,156 @@
<?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
*
* 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;
+ $this->lastError = "Message unknown: " . $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 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
index fd5afa6..0780c6e 100755
--- a/includes/objects/motd.php
+++ b/includes/objects/motd.php
@@ -1,95 +1,95 @@
<?php
/**
* MOTD class
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* 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;
/**
* 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;
+ $this->lastError = "MOTD unknown: " . $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);
}
}
}
?>
diff --git a/includes/objects/perso.php b/includes/objects/perso.php
index 35b3eac..bd07c49 100755
--- a/includes/objects/perso.php
+++ b/includes/objects/perso.php
@@ -1,579 +1,579 @@
<?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
* 0.4 2012-07-04 11:37 Refactoring: moving code from index.php
*
* @package Zed
* @subpackage Model
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010, 2012 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 $lastError;
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;
}
if (!$this->load_from_database()) {
message_die(GENERAL_ERROR, $this->lastError, "Can't authenticate perso");
}
} else {
$this->generate_id();
}
}
/**
* Initializes a new Perso instance if needed or get already available one.
*
* @param mixed $data perso ID or nickname
* @return 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;
+ $this->lastError = "Perso unknown: " . $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 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)
+ * @param int $threshold value the flags must strictly 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
+ * Determines whether the perso is online
*
* @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();
}
/**
* This event method is called when the perso is created
*/
public function on_create () {
- //Notifies inviter
+ //Notifies host
$this->notify_inviter();
}
/**
* Creates a new perso, from a parameter form
*
* @param int $user The user to attach the perso to
* @param Perso $perso A reference to the created perso (don't initialize it, give it a null value)
* @param array $errors A reference to the arrays containing errors (should be an empty array, or the method will always return false)
* @return boolean true if the perso has ben created ; otherwise, false
*/
public static function create_perso_from_form ($user, &$perso, &$errors) {
$perso = new Perso();
$perso->load_from_form();
$perso->user_id = $user->id;
//Validates forms
if (!$perso->name) $errors[] = lang_get("NoFullnameSpecified");
if (!$perso->race) {
$errors[] = lang_get("NoRaceSpecified");
$perso->race = "being";
}
if (!$perso->sex) $errors[] = lang_get("NoSexSpecified");
if (!$perso->nickname) {
$errors[] = lang_get("NoNicknameSpecified");
} elseif (!Perso::is_available_nickname($perso->nickname)) {
$errors[] = lang_get("UnavailableNickname");
}
if (count($errors)) return false;
//Creates perso
$perso->save_to_database();
$perso->on_create();
return true;
}
/**
* Notifies the person having invited this perso
*/
public function notify_inviter() {
require_once('includes/objects/message.php');
require_once('includes/objects/invite.php');
$message = new Message();
$message->from = 0;
$message->to = invite::who_invited($this->id);
$message->text = sprintf(
lang_get('InvitePersoCreated'),
$this->name,
get_server_url() . get_url('who', $this->nickname)
);
$message->send();
}
}
diff --git a/includes/objects/port.php b/includes/objects/port.php
index def95e8..ba0b664 100755
--- a/includes/objects/port.php
+++ b/includes/objects/port.php
@@ -1,197 +1,197 @@
<?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
*
* 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;
+ $this->lastError = "Port unknown: " . $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 getStatus () {
$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->getStatus();
//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);
}
/**
* 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);
}
}
diff --git a/includes/objects/profile.php b/includes/objects/profile.php
index 8f3a49f..0d35852 100755
--- a/includes/objects/profile.php
+++ b/includes/objects/profile.php
@@ -1,146 +1,146 @@
<?php
/**
* 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
*/
/**
* Profile 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
*/
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
*/
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;
+ $this->lastError = "Profile unknown: " . $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
*/
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;
}
}
diff --git a/includes/objects/profilecomment.php b/includes/objects/profilecomment.php
index 0a56b6c..9432035 100755
--- a/includes/objects/profilecomment.php
+++ b/includes/objects/profilecomment.php
@@ -1,130 +1,130 @@
<?php
/**
* 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
*/
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
*/
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;
+ $this->lastError = "comment unknown: " . $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
*/
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
* @todo Add events on publish
*/
function publish () {
$this->save_to_database();
}
/**
* 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
index 91e7e5f..5b58ee2 100755
--- a/includes/objects/profilephoto.php
+++ b/includes/objects/profilephoto.php
@@ -1,202 +1,202 @@
<?php
/**
* Profile 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
*
* @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
*/
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;
+ $this->lastError = "photo unknown: " . $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;
}
/**
* 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
*/
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;
}
}
}
diff --git a/includes/objects/request.php b/includes/objects/request.php
index 9a434dc..14b5b56 100755
--- a/includes/objects/request.php
+++ b/includes/objects/request.php
@@ -1,123 +1,123 @@
<?php
/**
* Request class
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2011, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2011-06-13 21:16 Autogenerated by Pluton Scaffolding
*
* @package Zed
* @subpackage Model
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2011 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
*/
/**
* Request class
*
* This class maps the requests table.
*/
class Request {
public $id;
public $code;
public $title;
public $date;
public $author;
public $to;
public $message;
public $location_global;
public $location_local;
public $status;
/**
* 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->status = 'NEW';
}
}
/**
* Loads the object Request (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('title', $_POST)) $this->title = $_POST['title'];
if (array_key_exists('date', $_POST)) $this->date = $_POST['date'];
if (array_key_exists('author', $_POST)) $this->author = $_POST['author'];
if (array_key_exists('to', $_POST)) $this->to = $_POST['to'];
if (array_key_exists('message', $_POST)) $this->message = $_POST['message'];
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('status', $_POST)) $this->status = $_POST['status'];
}
/**
* Loads the object Request (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$id = $db->sql_escape($this->id);
$sql = "SELECT * FROM " . TABLE_REQUESTS . " WHERE request_id = '" . $id . "'";
if (!$result = $db->sql_query($sql)) message_die(SQL_ERROR, "Unable to query requests", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
- $this->lastError = "Request unkwown: " . $this->id;
+ $this->lastError = "Request unknown: " . $this->id;
return false;
}
$this->code = $row['request_code'];
$this->title = $row['request_title'];
$this->date = $row['request_date'];
$this->author = $row['request_author'];
$this->message = $row['request_message'];
$this->to = $row['request_to'];
$this->location_global = $row['location_global'];
$this->location_local = $row['location_local'];
$this->status = $row['request_status'];
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);
$title = $db->sql_escape($this->title);
$date = $db->sql_escape($this->date);
$author = $db->sql_escape($this->author);
$message = $db->sql_escape($this->message);
$to = $db->sql_escape($this->to);
$location_global = $db->sql_escape($this->location_global);
$location_local = $db->sql_escape($this->location_local);
$status = $db->sql_escape($this->status);
//Updates or inserts
$sql = "REPLACE INTO " . TABLE_REQUESTS . " (`request_id`, `request_code`, `request_title`, `request_date`, `request_author`, `request_message`, `request_to`, `location_global`, `location_local`, `request_status`) VALUES ('$id', '$code', '$title', '$date', '$author', '$message', '$to', '$location_global', '$location_local', '$status')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
if (!$this->id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
}
}
diff --git a/includes/objects/requestreply.php b/includes/objects/requestreply.php
index 688bbb0..6a3828e 100755
--- a/includes/objects/requestreply.php
+++ b/includes/objects/requestreply.php
@@ -1,100 +1,100 @@
<?php
/**
* RequestReply class
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2011, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2011-06-13 21:20 Autogenerated by Pluton Scaffolding
*
* @package Zed
* @subpackage Model
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2011 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
*/
/**
* RequestReply class
*
* This class maps the requests_replies table.
*/
class RequestReply {
public $id;
public $request_id;
public $author;
public $date;
public $text;
/**
* 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 RequestReply (ie fill the properties) from the $_POST array
*/
function load_from_form () {
if (array_key_exists('request_id', $_POST)) $this->request_id = $_POST['request_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 RequestReply (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$id = $db->sql_escape($this->id);
$sql = "SELECT * FROM " . TABLE_REQUESTS_REPLIES . " WHERE request_reply_id = '" . $id . "'";
if (!$result = $db->sql_query($sql)) message_die(SQL_ERROR, "Unable to query requests_replies", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
- $this->lastError = "RequestReply unkwown: " . $this->id;
+ $this->lastError = "RequestReply unknown: " . $this->id;
return false;
}
$this->request_id = $row['request_id'];
$this->author = $row['request_reply_author'];
$this->date = $row['request_reply_date'];
$this->text = $row['request_reply_text'];
return true;
}
/**
* Saves to database
*/
function save_to_database () {
global $db;
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$request_id = $db->sql_escape($this->request_id);
$author = $db->sql_escape($this->author);
$date = $db->sql_escape($this->date);
$text = $db->sql_escape($this->text);
//Updates or inserts
$sql = "REPLACE INTO " . TABLE_REQUESTS_REPLIES . "(`request_reply_id`, `request_id`, `request_reply_author`, `request_reply_date`, `request_reply_text`) VALUES ('$id', '$request_id', '$author', '$date', '$text')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
if (!$this->id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
}
}
diff --git a/includes/objects/ship.php b/includes/objects/ship.php
index 31a193a..d018853 100755
--- a/includes/objects/ship.php
+++ b/includes/objects/ship.php
@@ -1,325 +1,325 @@
<?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
* @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
* @return Ship the ship instance
*/
static function get ($data = null) {
if ($data !== null) {
if (preg_match("/^S[0-9]{5}$/", $id)) {
$id = substr($data, 1);
} else {
$id = $data;
}
//Checks in the hashtable if we already have loaded this instance
if (array_key_exists($id, 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;
+ $this->lastError = "Ship unknown: " . $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 hashtable
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 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) {
$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
+ //Cleans 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
index 37de251..52c839f 100755
--- a/includes/objects/user.php
+++ b/includes/objects/user.php
@@ -1,244 +1,244 @@
<?php
/**
* User class
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* [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
*
* 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;
public static $hashtable_id = array();
public static $hashtable_name = array();
/**
* Initializes a new instance
*
* @param int $id the primary key
*/
function __construct ($id = null) {
if ($id) {
$this->id = $id;
$this->load_from_database();
}
}
/**
* Initializes a new User instance if needed or get already available one.
*
* @param mixed $data user ID or name
* @return User the user 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, User::$hashtable_id)) {
return User::$hashtable_id[$data];
}
} else {
if (array_key_exists($data, User::$hashtable_name)) {
return User::$hashtable_name[$data];
}
}
}
$user = new User($data);
return $user;
}
/**
* 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;
+ $this->lastError = "User unknown: " . $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'];
//Puts object in hashtables
Perso::$hashtable_id[$this->id] = $this;
Perso::$hashtable_name[$this->name] = $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);
$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
*/
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_AUTH . " WHERE auth_type = 'OpenID' AND 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_AUTH . " (auth_type, auth_identity, user_id) VALUES ('OpenID', '$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
*
* @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
*
* @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;
}
}
diff --git a/includes/settings/page.php b/includes/settings/page.php
index d89eb15..3e6e9a8 100755
--- a/includes/settings/page.php
+++ b/includes/settings/page.php
@@ -1,156 +1,156 @@
<?php
/**
* Settings: a settings page class
*
* 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
*/
require_once("setting.php");
/**
* 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;
/**
* 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;
}
/**
* 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.";
+ $errors[] = $setting->lastError ? $setting->lastError : "An error have occurred 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));
}
}
}
}
}
diff --git a/includes/settings/setting.php b/includes/settings/setting.php
index 8b5c7b8..aaf3ddf 100755
--- a/includes/settings/setting.php
+++ b/includes/settings/setting.php
@@ -1,174 +1,174 @@
<?php
/**
* Settings: an individual setting class
*
* 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
*/
/**
* 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");
+ message_die(GENERAL_ERROR, "Setting $this->key haven't any set indication. Please set <object> (and whether <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/story/choice.php b/includes/story/choice.php
index 4b2ff30..cfff352 100755
--- a/includes/story/choice.php
+++ b/includes/story/choice.php
@@ -1,110 +1,110 @@
<?php
/**
* Story choice.
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* @package Zed
* @subpackage Story
* @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
*/
/**
* Story choice class
*
* This class is a PHP mapping from the Story XML format's <choice> tag.
*
* <code>
* $xml = "<choice goto=\"city.entry\">Descendre vers le centre ville</choice>";
* $parser = new SimpleXmlElement($xml);
* $choice = StoryChoice::from_xml($parser);
*
* echo $choice->text; //That will output Descendre vers le centre ville
* echo $choice->goto; //That will output city.entry
* echo $choice->guid; //That will output any guid generated for this instance
*
* $thesamechoice = StoryChoice::from_xml($parser);
- * echo $thesamechoice->guid; //That will ouput another guid
+ * echo $thesamechoice->guid; //That will output another guid
* </code>
*/
class StoryChoice {
/**
* The section key this choices links to
*
* @var string
*/
public $goto;
/**
* The choice text
*
* @var string
*/
public $text;
/**
* The choice GUID
*
* It will be automatically generated by the constructor, and so is an
- * ephemere data for this StoryChoice instance.
+ * ephemeral data for this StoryChoice instance.
*
* @see new_guid
*
* @var string
*/
public $guid;
/**
* Constructor
*/
function __construct () {
//The guid allows to build temporary URLs to get to right choice
$this->guid = new_guid();
}
/**
* Gets the story text as a string representation of the class
*
* @return string The story text
*/
function __toString () {
return $this->text;
}
/**
* Initializes a new instance of StoryChoice class from a XML element
*
* @param SimpleXMLElement the xml element to parse
* @return StoryChoice the story choice class
*/
static function from_xml ($xml) {
$choice = new StoryChoice();
//Parses attribute
foreach ($xml->attributes() as $key => $value) {
switch ($key) {
case 'goto':
$choice->$key = (string)$value;
break;
default:
message_die(GENERAL_ERROR, "Unknown attribute: $key = \"$value\"", "Story error");
}
}
//Parses content
$choice->text = (string)$xml;
return $choice;
}
}
diff --git a/includes/travel/place.php b/includes/travel/place.php
index f3b1918..99634d3 100755
--- a/includes/travel/place.php
+++ b/includes/travel/place.php
@@ -1,150 +1,150 @@
<?php
/**
* TravelPlace class
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2010-07-19 22:10 DcK
*
* @package Zed
* @subpackage Travel
* @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
*/
/**
* TravelPlace class
*
* The TravelPlace class is a set of rules determining which moves are valid
* in a specific place.
*
* @see GeoPlace
*
*/
class TravelPlace {
/**
* The place code
*
* @var string
*/
public $code;
/**
* Determines if any local location move is valid
*
* @var bool
*/
public $freeLocalMove = false;
/**
* Array of strings, each item another place reachable
*
* This matches GlobalTravelTo XML tags.
*
* @var Array
*/
public $globalTravelTo = array();
/**
- * Aray of array, containing [location, alias, name] entries
+ * Array of array, containing [location, alias, name] entries
*
* This matches LocalMove XML tags.
*
* @var Array
*/
public $localMoves = array();
/**
- * Aray of array, containing [expression, global_location, local_location] entries
+ * Array of array, containing [expression, global_location, local_location] entries
*
* This matches RewriteRule XML tags.
*
* @var Array
*/
public $rewriteRules = array();
/**
* Initializes a new TravelPlace instance, from the specified XML fragment
*
* @param string $xml the XML fragment to parse
- * @return TravelPlace the TravelPlace instance maching the specified XML fragment
+ * @return TravelPlace the TravelPlace instance matching the specified XML fragment
*/
static function from_xml ($xml) {
$travelPlace = new TravelPlace();
//Reads attributes: <TravelPlace code="B00001001" freeLocalMove="true">
foreach ($xml->attributes() as $key => $value) {
switch ($key) {
case 'code':
$travelPlace->code = (string)$value;
break;
case 'freeLocalMove':
$travelPlace->freeLocalMove = (boolean)$value;
break;
}
}
//<GlobalTravelTo code="B00001002" />
foreach ($xml->GlobalTravelTo as $globalTravelToXml) {
foreach ($globalTravelToXml->attributes() as $key => $value) {
if ($key == "code") {
$travelPlace->globalTravelTo[] = (string)$value;
}
}
}
//<LocalMove local_location="(0, 0, 0)" alias="C0" name="Core" />
foreach ($xml->LocalMove as $localMoveXml) {
$localMove = array(null, null, null);
foreach ($localMoveXml->attributes() as $key => $value) {
switch ($key) {
case 'local_location':
$localMove[0] = (string)$value;
break;
case 'alias':
$localMove[1] = (string)$value;
break;
case 'name':
$localMove[2] = (string)$value;
break;
}
}
$travelPlace->localMoves[] = $localMove;
}
//<RewriteRule expression="/^T([1-9][0-9]*)$/" global_location="B00001001" local_location="T$1C1" />
foreach ($xml->RewriteRule as $rewriteRuleXml) {
$rewriteRule = array(null, null, null);
foreach ($rewriteRuleXml->attributes() as $key => $value) {
switch ($key) {
case 'expression':
$rewriteRule[0] = (string)$value;
break;
case 'global_location':
$rewriteRule[1] = (string)$value;
break;
case 'local_location':
$rewriteRule[2] = (string)$value;
break;
}
}
$travelPlace->rewriteRules[] = $rewriteRule;
}
return $travelPlace;
}
}
diff --git a/index.php b/index.php
index 42a1508..eefd55b 100644
--- a/index.php
+++ b/index.php
@@ -1,201 +1,201 @@
<?php
/**
* Application 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 split the different tasks (especially
* perso select/create into several files)
*/
////////////////////////////////////////////////////////////////////////////////
///
/// Initialization
///
-//Keruald (formelly Pluton) library
+//Keruald (formerly Pluton) library
include('includes/core.php');
//Session
$IP = encode_ip($_SERVER["REMOTE_ADDR"]);
require_once('includes/story/story.php'); //this class can be stored in session
session_start();
$_SESSION[ID] = session_id();
session_update(); //updates or creates the session
include("includes/login.php"); //login/logout
-$CurrentUser = get_logged_user(); //Gets current user infos
+$CurrentUser = get_logged_user(); //Gets current user information
//Gets current perso
require_once('includes/objects/perso.php');
if ($perso_id = $CurrentUser->session['perso_id']) {
$CurrentPerso = new Perso($perso_id);
}
//Skin and accent to load
define('THEME', $CurrentUser->session['Skin']);
define('ACCENT', $CurrentUser->session['Skin_accent']);
//Loads Smarty
require('includes/Smarty/Smarty.class.php');
$smarty = new Smarty();
$current_dir = dirname(__FILE__);
$smarty->setTemplateDir($current_dir . '/skins/' . THEME);
$smarty->compile_dir = CACHE_DIR . '/compiled';
$smarty->cache_dir = CACHE_DIR;
$smarty->config_dir = $current_dir;
$smarty->config_vars['StaticContentURL'] = $Config['StaticContentURL'];
//Loads language files
initialize_lang();
lang_load('core.conf');
//Gets URL
$url = get_current_url_fragments();
//If the user isn't logged in (is anonymous), prints login/invite page & dies.
if ($CurrentUser->id < 1000) {
include('controllers/anonymous.php');
exit;
}
////////////////////////////////////////////////////////////////////////////////
///
/// Perso (=character) selector
///
//Handles form
if ($_POST['form'] == 'perso.create') {
$perso = null;
$errors = array();
if (Perso::create_perso_from_form($CurrentUser, $perso, $errors)) {
//Notifies and logs in
$smarty->assign('NOTIFY', lang_get('NewCharacterCreated'));
$CurrentPerso = $perso;
set_info('perso_id', $perso->id);
$CurrentPerso->set_flag("site.lastlogin", $_SERVER['REQUEST_TIME']);
} else {
//Prints again perso create form, so the user can fix it
$smarty->assign('WAP', join("<br />", $errors));
$smarty->assign('perso', $perso);
}
}
if ($_GET['action'] == 'perso.logout' && $CurrentPerso != null) {
//User wants to change perso
$CurrentPerso->on_logout();
$CurrentPerso = null;
} elseif ($_GET['action'] == 'perso.select') {
//User has selected a perso
$CurrentPerso = new Perso($_GET['perso_id']);
if ($CurrentPerso->user_id != $CurrentUser->id) {
//User have made an error in the URL
message_die(HACK_ERROR, "This isn't your perso.");
}
$CurrentPerso->on_select();
}
if (!$CurrentPerso) {
switch ($count = Perso::get_persos_count($CurrentUser->id)) {
case 0:
//User have to create a perso
$smarty->display("perso_create.tpl");
exit;
case 1:
//Autoselects only perso
$CurrentPerso = Perso::get_first_perso($CurrentUser->id);
$CurrentPerso->on_select();
break;
default:
//User have to pick a perso
$persos = Perso::get_persos($CurrentUser->id);
$smarty->assign("PERSOS", $persos);
$smarty->display("perso_select.tpl");
$_SESSION['UserWithSeveralPersos'] = true;
exit;
}
}
//Assigns current perso object as Smarty variable
$smarty->assign('CurrentPerso', $CurrentPerso);
////////////////////////////////////////////////////////////////////////////////
///
/// Tasks to execute before calling the URL controller:
/// - assert the perso is somewhere
/// - executes the smartline
///
//If the perso location is unknown, ejects it to an asteroid
if (!$CurrentPerso->location_global) {
require_once('includes/geo/place.php');
$smarty->assign('NOTIFY', lang_get('NewLocationNotify'));
$CurrentPerso->move_to(GeoPlace::get_start_location());
}
//SmartLine
include("includes/SmartLine/ZedSmartLine.php");
//Redirects user to user request controller if site.requests flag on
if (defined('PersoSelected') && array_key_exists('site.requests', $CurrentPerso->flags) && $CurrentPerso->flags['site.requests']) {
include('controllers/persorequest.php');
}
////////////////////////////////////////////////////////////////////////////////
///
/// Calls the specific controller to serve the requested page
///
switch ($controller = $url[0]) {
case '':
include('controllers/home.php');
break;
case 'builder':
case 'explore':
case 'page':
case 'request':
case 'settings':
case 'ship':
include("controllers/$controller.php");
break;
case 'who':
include('controllers/profile.php'); //Azhàr controller
break;
case 'push':
include('controllers/motd.php'); //Azhàr controller
break;
case 'quux':
//It's like a test/debug console/sandbox, you put what you want into
if (file_exists('dev/quux.php')) {
include('dev/quux.php');
} else {
message_die(GENERAL_ERROR, "Quux lost in Hollywood.", "Nay");
}
break;
default:
//TODO: returns a prettier 404 page
header("Status: 404 Not Found");
dieprint_r($url, 'Unknown URL');
}
diff --git a/js/FCKeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.php b/js/FCKeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.php
index 61d161a..30ad48a 100644
--- a/js/FCKeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.php
+++ b/js/FCKeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.php
@@ -1,196 +1,196 @@
<?php
header('Content-type: text/html; charset=utf-8');
// The following variables values must reflect your installation needs.
//$aspell_prog = '"C:\Program Files\Aspell\bin\aspell.exe"'; // by FredCK (for Windows)
$aspell_prog = 'aspell'; // by FredCK (for Linux)
$lang = 'fr';
$aspell_opts = "-a --lang=$lang --encoding=utf-8 -H"; // by FredCK
$tempfiledir = "./";
$spellercss = '../spellerStyle.css'; // by FredCK
$word_win_src = '../wordWindow.js'; // by FredCK
$textinputs = $_POST['textinputs']; # array
$input_separator = "A";
# set the JavaScript variable to the submitted text.
# textinputs is an array, each element corresponding to the (url-encoded)
# value of the text control submitted for spell-checking
function print_textinputs_var() {
global $textinputs;
foreach( $textinputs as $key=>$val ) {
# $val = str_replace( "'", "%27", $val );
echo "textinputs[$key] = decodeURIComponent(\"" . $val . "\");\n";
}
}
# make declarations for the text input index
function print_textindex_decl( $text_input_idx ) {
echo "words[$text_input_idx] = [];\n";
echo "suggs[$text_input_idx] = [];\n";
}
# set an element of the JavaScript 'words' array to a misspelled word
function print_words_elem( $word, $index, $text_input_idx ) {
echo "words[$text_input_idx][$index] = '" . escape_quote( $word ) . "';\n";
}
# set an element of the JavaScript 'suggs' array to a list of suggestions
function print_suggs_elem( $suggs, $index, $text_input_idx ) {
echo "suggs[$text_input_idx][$index] = [";
foreach( $suggs as $key=>$val ) {
if( $val ) {
echo "'" . escape_quote( $val ) . "'";
if ( $key+1 < count( $suggs )) {
echo ", ";
}
}
}
echo "];\n";
}
# escape single quote
function escape_quote( $str ) {
return preg_replace ( "/'/", "\\'", $str );
}
# handle a server-side error.
function error_handler( $err ) {
echo "error = '" . escape_quote( $err ) . "';\n";
}
## get the list of misspelled words. Put the results in the javascript words array
## for each misspelled word, get suggestions and put in the javascript suggs array
function print_checker_results() {
global $aspell_prog;
global $aspell_opts;
global $tempfiledir;
global $textinputs;
global $input_separator;
$aspell_err = "";
# create temp file
$tempfile = tempnam( $tempfiledir, 'aspell_data_' );
# open temp file, add the submitted text.
if( $fh = fopen( $tempfile, 'w' )) {
for( $i = 0; $i < count( $textinputs ); $i++ ) {
$text = urldecode( $textinputs[$i] );
$lines = explode( "\n", $text );
fwrite ( $fh, "%\n" ); # exit terse mode
fwrite ( $fh, "^$input_separator\n" );
fwrite ( $fh, "!\n" ); # enter terse mode
foreach( $lines as $key=>$value ) {
# use carat on each line to escape possible aspell commands
fwrite( $fh, "^$value\n" );
}
}
fclose( $fh );
# exec aspell command - redirect STDERR to STDOUT
$cmd = "$aspell_prog $aspell_opts < $tempfile 2>&1";
if( $aspellret = shell_exec( $cmd )) {
$linesout = explode( "\n", $aspellret );
$index = 0;
$text_input_index = -1;
# parse each line of aspell return
foreach( $linesout as $key=>$val ) {
$chardesc = substr( $val, 0, 1 );
# if '&', then not in dictionary but has suggestions
# if '#', then not in dictionary and no suggestions
# if '*', then it is a delimiter between text inputs
# if '@' then version info
if( $chardesc == '&' || $chardesc == '#' ) {
$line = explode( " ", $val, 5 );
print_words_elem( $line[1], $index, $text_input_index );
if( isset( $line[4] )) {
$suggs = explode( ", ", $line[4] );
} else {
$suggs = array();
}
print_suggs_elem( $suggs, $index, $text_input_index );
$index++;
} elseif( $chardesc == '*' ) {
$text_input_index++;
print_textindex_decl( $text_input_index );
$index = 0;
} elseif( $chardesc != '@' && $chardesc != "" ) {
# assume this is error output
$aspell_err .= $val;
}
}
if( $aspell_err ) {
$aspell_err = "Error executing `$cmd`\\n$aspell_err";
error_handler( $aspell_err );
}
} else {
error_handler( "System error: Aspell program execution failed (`$cmd`)" );
}
} else {
error_handler( "System error: Could not open file '$tempfile' for writing" );
}
# close temp file, delete file
unlink( $tempfile );
}
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="<?php echo $spellercss ?>" />
<script language="javascript" src="<?php echo $word_win_src ?>"></script>
<script language="javascript">
var suggs = new Array();
var words = new Array();
var textinputs = new Array();
var error;
<?php
print_textinputs_var();
print_checker_results();
?>
var wordWindowObj = new wordWindow();
wordWindowObj.originalSpellings = words;
wordWindowObj.suggestions = suggs;
wordWindowObj.textInputs = textinputs;
function init_spell() {
- // check if any error occured during server-side processing
+ // check if any error occurred during server-side processing
if( error ) {
alert( error );
} else {
// call the init_spell() function in the parent frameset
if (parent.frames.length) {
parent.init_spell( wordWindowObj );
} else {
alert('This page was loaded outside of a frameset. It might not display properly');
}
}
}
</script>
</head>
<!-- <body onLoad="init_spell();"> by FredCK -->
<body onLoad="init_spell();" bgcolor="#ffffff">
<script type="text/javascript">
wordWindowObj.writeBody();
</script>
</body>
</html>
diff --git a/js/login.js b/js/login.js
index 6b55e12..8d3e297 100644
--- a/js/login.js
+++ b/js/login.js
@@ -1,115 +1,115 @@
/* -------------------------------------------------------------
Zed
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Author: Dereckson
Tags: animation
Filename: login.js
Version: 1.0
Created: 2010-02-08
Updated: 2010-02-08
Licence: Dual licensed: BSD and Creative Commons BY 3.0.
Dependencies: Prototype (for .setStyle method)
Scriptaculous + effects (not required for slide)
------------------------------------------------------------- */
/*
* Slides an item from top to bottom
*/
var slide = {
//The element to slide
element: null,
//The slider height
height: 120,
//Let's track where we are
currentHeight: null,
//Down step pixels each iteration
step: 5,
//Time in ms between 2 iteration
interval: 1,
//Time before to start
startDelay: 250,
//Moves the element at current iteration
move: function () {
//Get current slider height
if (this.currentHeight > 0) {
//- step px (but we don't down after 0)
this.currentHeight -= this.step;
if (this.currentHeight < 0) {
this.currentHeight = 0;
}
}
//Sets the margin
$(this.element).setStyle("margin-top: -" + this.currentHeight + "px;");
//Next move
if (this.currentHeight > 0) {
setTimeout('slide.move()', this.interval);
} else {
slide.end();
}
},
//When we've finished the move, what to do?
end: function () {
//Er... nothing for now.
var errorElement = document.getElementById("error");
if (errorElement != null)
Effect.Pulsate(errorElement);
},
//Start position, timer setup
initialize: function (elementId) {
this.element = document.getElementById(elementId);
if (this.element != null) {
this.currentHeight = this.height;
$(this.element).setStyle("margin-top: -" + this.height + "px;");
setTimeout('slide.move()', this.startDelay);
} else {
throw "null element"
}
}
}
/*
* Checks if fields are filled.
* If so, hides error and ok button (useful as OpenID takes some time)
* If not, highlight the missing fields
*/
function OnLoginSubmit (submitButton) {
//Checks all fields are completed
if (document.getElementById("openid").value != "") {
- //OpenID is prefered login way, so we're okay.
+ //OpenID is preferred login way, so we're okay.
} else {
haveUsername = document.getElementById("username").value != "";
havePassword = document.getElementById("password").value != "";
haveBoth = haveUsername && havePassword;
if (!haveBoth) {
if (!haveUsername) {
Effect.Pulsate(document.getElementById("username"));
}
if (!havePassword) {
Effect.Pulsate(document.getElementById("password"));
}
return false;
}
//If both are filled, we're okay and can proceed.
}
//Hides error and ok item
var errorElement = document.getElementById('error');
if (errorElement != null) {
Effect.Puff(errorElement);
}
Effect.Puff(submitButton);
//We can submit
return true;
}
\ No newline at end of file

File Metadata

Mime Type
text/x-diff
Expires
Mon, Nov 25, 06:15 (13 h, 17 m ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
20854
Default Alt Text
(413 KB)

Event Timeline