Page MenuHomeCode

No OneTemporary

This file is larger than 256 KB, so syntax highlighting was skipped.
This document is not UTF8. It was detected as ISO-8859-1 (Latin 1) and converted to UTF8 for display.
diff --git a/README b/README
index 2132dc5..6f04dc6 100644
--- a/README
+++ b/README
@@ -1,164 +1,164 @@
- ZzzzzzZ zz
+ ZzzzzzZ zz
Z z z The spatial gallery / social network / lounge
z z (c) 2010, Dereckson, some rights reserved.
- z zzzzz zzzzz
+ z zzzzz zzzzz
z z z z z 0.1 alpha technical preview
z zzzzzzz z z
z z z z Last update hypership time: 5.096
z Z z z z z
ZzzzzzZ zzzzz zzzzzz
=========
INSTALL
=========
* Zed is a PHP 5.3 application.
-
+
* You can import dev/schema-mysql.sql as original SQL schema
-
+
* The configuration file is includes/config.php
-
+
* Files are cached in 3 directories of the cache folder, sets appropriate
write permissions to:
compiled openid sessions
-
+
* Zed needs but doesn't include in its code the Janrain OpenID PHP libraries:
http://www.janrain.com/openid-enabled - http://github.com/openid/php-openid
-
+
Put the Auth folder somewhere in your include_dir path.
-
+
bcmath and GMP php extensions are recommended (required?) for OpenID.
Our dev environment outputs a white page without error if GMP isn't here.
-
+
If you don't wish to enable OpenID, replace your includes/login.php by
http://hg.dereckson.be/zed/src/0ffd1b08f33c/includes/login.php
-
+
* Another used PHP extension is the WDDX one, to store session information in
a human-readable format, easier to debug.
-
+
If you don't want that, comment the following line from includes/config.php:
ini_set('session.serialize_handler', 'wddx');
-
+
=========
UPGRADE
=========
-
+
* For our main prod install, we use a script exporting last repo revision with
hg archive and applying a patch to config.php.
===========
LOCATIONS
===========
* Global location is a 9 letters code
<B,S> <body or spaceship id> <place where you are in this body/spaceship>
zerofilled 5 digits zerofilled 3 digits
-
+
You can also find 6 digits expressions e.g. B00001 is the hypership
-
+
* Local location varies of the place.
- On hypership core (B00001002): Sector C<0-8> Level <z> Zone <x-y>
- 0 is the gravity center
- 1-8 the 8 cubes surrounding it: 1-4 below, 5-8 above
- On the ship tower (B00001001): Sector T<z> Couloir <1-6>
- z is the level
- couloir depends of your x, y position (polar coordinates could help)
=================
HYPERSHIP TIME?
=================
* The amount of days since hypership launch, July 3rd 2010 00:00 UTC
* So the decimal part is like internet time, but in GMT and not CET/CEST
===============
SIDE PROJECTS
===============
* A pazaak game, to have something to play
* Will be an Arzakon client
-
+
=================
I WANT TO HELP!
=================
* You can create new SmartLine commands
-
+
* You can translate it in a new language
Start point: http://zed.dereckson.be/lang/en/core.conf
-
+
* You can code a bit of adventure, places description, stuff to do
as long you don't transform it in ogame clone (we're building a community
who want or don't want to play, but not a mechanic game)
and as long no money is involved (if you ask why, read Iain M. Banks novels)
in the hypership (in far asteroids, orbitals, planets you do what you want)
============
KNOWN BUGS
============
* Javascript get_hypership_time will returns 5.94 instead 5.094
-
+
Some %03d to add in /js/misc.js
-
+
* The floater rendering adds a black line under Opera
-
+
dojox.layout.floatingPane bug, need to check with last dojo version
-
+
* API /location query will break indent on location->body->location
-
+
beautify XML code to improve
-
+
* do.php allows any local location move, discarding FrL status
-
+
* The upload artwork dojo form can't be closed under Opera
-
+
=======================
API - General methods
=======================
* /api.php/time
-
+
Returns hypership time
Public access
-
+
* /api.php/perso/<perso_id>
-
+
Returns perso object
Created only to test extensively recursivity of api xml output
It's disabled since 10.811 on zed.dereckson.be, if you need an alternative,
open a bug report with the fields you need. Ship API should be able to manage
inventory if user is on. Ship API must also be able to get/set custom flags.
Requires a key
-
+
* /api.php/location/<location code or name>
-
+
Returns location object
Tip: to get the full name, use string eg /api.php/location/Zeta?format=string
Requires a key
-
+
* GET/POST API parameters
-
+
- key
API key, ask it at zed at dereckson be, object [DEV] api key request
-
+
- format
- preview print_r representation, so you've an idea of the object
- json json_encode() output
- php serialize() output
- wddx WDDX were an early universal serialization attempt
- xml XML document
- string output "as is" (or if it's an object, calls __toString())
-
+
============
API - Ship
=============
* /api.php/ship/authenticate/<perso nickname>
-
+
=================
ACKNOWLEDGEMENT
=================
Elfix, to have let me figure a regexp correction, instead to throw away regexp
validation for places local location.
diff --git a/api.php b/api.php
index b9770ff..d1d1610 100644
--- a/api.php
+++ b/api.php
@@ -1,320 +1,320 @@
<?php
/**
* API entry point
*
* Zed. The immensity of stars. The HyperShip. The people.
- *
+ *
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
- *
+ *
* @package Zed
* @subpackage EntryPoints
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
* @todo Consider to output documentation on / and /ship queries
* @todo /app/getdata
*/
//API Preferences
define('URL', 'http://' . $_SERVER['HTTP_HOST'] . '/index.php');
//Pluton library
require_once('includes/core.php');
require_once('includes/config.php');
//API libs
require_once('includes/api/api_helpers.php');
require_once('includes/api/cerbere.php');
//Use our URL controller method if you want to mod_rewrite the API
$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
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
cerbere();
//Get coordiantes
api_output(GeoGalaxy::get_coordinates(), '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->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/apps/HelloWorldWebService.php b/apps/HelloWorldWebService.php
index 474548e..9931eac 100644
--- a/apps/HelloWorldWebService.php
+++ b/apps/HelloWorldWebService.php
@@ -1,27 +1,27 @@
<?php
/**
* Hello World webservice client
*
* This file allows to see if the SOAP server is operationnal.
*
* Zed. The immensity of stars. The HyperShip. The people.
- *
+ *
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
- *
+ *
* @package Zed
* @subpackage Pazaak
* @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
*/
$client = new SoapClient("http://10.0.0.4:49319/Service1.asmx?WSDL");
echo $client->HelloWorld()->HelloWorldResult;
?>
\ No newline at end of file
diff --git a/apps/pazaak/debug.php b/apps/pazaak/debug.php
index 8fa3803..a930796 100644
--- a/apps/pazaak/debug.php
+++ b/apps/pazaak/debug.php
@@ -1,63 +1,63 @@
<?php
/**
* Pazaak webservice client, debug console
*
* This is a sandbox to test the Pazaak web service.
*
* 2010-07-20: Pazaak will be noted as a deprecated project at 2010-09-15.
- *
+ *
* @package Zed
* @subpackage Pazaak
* @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
*/
/**
* Prints human-readable information about a variable (like the print_r command),
* enclosed in <div class="debugCode"><pre></pre></div> tags,
* to have a preformatted HTML output.
*
* @param mixed The expression to be printed
*/
function dprint_r ($expression) {
echo '<div class="debugCode"><pre>';
print_r($expression);
echo '</pre></div>';
}
$client = new SoapClient('http://10.0.0.4:49319/PazaakService.asmx?WSDL');
$game = $client->QuickQuickStart()->QuickQuickStartResult;
echo "<h1>Game $game->GUID</h1>";
echo "<h2>Table</h2>";
$cards = $game->PlayerTable->string;
if (is_array($cards)) {
echo "<table><tr>";
foreach ($cards as $card)
echo "<td>$card</td>";
echo "</tr></table>";
} else {
echo "<p>$cards</p>";
}
echo "<h2>Your hand</h2>";
$cards = $game->PlayerHand->string;
if (count($cards)) {
echo "<table><tr>";
foreach ($cards as $card)
echo "<td>$card</td>";
echo "</tr></table>";
} else {
echo "<p>-</p>";
}
echo "<h2>Debug</h2>";
dprint_r($game);
?>
\ No newline at end of file
diff --git a/cache/compiled/index.html b/cache/compiled/index.html
index 492df2b..3910a7d 100644
--- a/cache/compiled/index.html
+++ b/cache/compiled/index.html
@@ -1,20 +1,20 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd"
>
<html lang="en">
<head>
<title>Restricted directory</title>
<link rel="Stylesheet" href="../../css/zed/theme.css" type="text/css" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div style="width: 960px; margin: auto; margin-top: 3em;">
<h1 style="font-size: 3em;">Zed</h1>
<h2>Restricted directory</h2>
<p>As you can guess from the URL, this directory contains <em>precompiled</em> cached information.</p>
-
+
<h3>Security tip</h3>
<p>To improve security, please move the <tt>/cache</tt> directory outside the webserver hierarchy.</p>
</div>
</body>
</html>
\ No newline at end of file
diff --git a/cache/index.html b/cache/index.html
index 48eb53f..aa43447 100644
--- a/cache/index.html
+++ b/cache/index.html
@@ -1,20 +1,20 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd"
>
<html lang="en">
<head>
<title>Restricted directory</title>
<link rel="Stylesheet" href="../css/zed/theme.css" type="text/css" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div style="width: 960px; margin: auto; margin-top: 3em;">
<h1 style="font-size: 3em;">Zed</h1>
<h2>Restricted directory</h2>
<p>As you can guess from the URL, this directory contains cached information.</p>
-
+
<h3>Security tip</h3>
<p>To improve security, please move the <tt>/cache</tt> directory outside the webserver hierarchy.</p>
</div>
</body>
</html>
diff --git a/cache/openid/index.html b/cache/openid/index.html
index 1ffdf6c..a40e71a 100644
--- a/cache/openid/index.html
+++ b/cache/openid/index.html
@@ -1,20 +1,20 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd"
>
<html lang="en">
<head>
<title>Restricted directory</title>
<link rel="Stylesheet" href="../../css/zed/theme.css" type="text/css" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div style="width: 960px; margin: auto; margin-top: 3em;">
<h1 style="font-size: 3em;">Zed</h1>
<h2>Restricted directory</h2>
<p>As you can guess from the URL, this directory contains <em>OpenID</em> cached information.</p>
-
+
<h3>Security tip</h3>
<p>To improve security, please move the <tt>/cache</tt> directory outside the webserver hierarchy.</p>
</div>
</body>
</html>
\ No newline at end of file
diff --git a/cache/sessions/index.html b/cache/sessions/index.html
index e601ea2..35f3b28 100644
--- a/cache/sessions/index.html
+++ b/cache/sessions/index.html
@@ -1,20 +1,20 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd"
>
<html lang="en">
<head>
<title>Restricted directory</title>
<link rel="Stylesheet" href="../../css/zed/theme.css" type="text/css" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div style="width: 960px; margin: auto; margin-top: 3em;">
<h1 style="font-size: 3em;">Zed</h1>
<h2>Restricted directory</h2>
<p>As you can guess from the URL, this directory contains sessions information.</p>
-
+
<h3>Security tip</h3>
<p>To improve security, please move the <tt>/cache</tt> directory outside the webserver hierarchy.</p>
</div>
</body>
</html>
diff --git a/content/scenes/B00001001.tpl b/content/scenes/B00001001.tpl
index 3adf6e8..8d18458 100644
--- a/content/scenes/B00001001.tpl
+++ b/content/scenes/B00001001.tpl
@@ -1,212 +1,212 @@
<!--
Global location: B00001001
-->
<!-- Tower navigation and passage CSS -->
<style>
body {
overflow: hidden;
}
-
+
/* Tower map */
-
+
#tower {
background-image: url({$SCENE_URL}/{$CurrentPerso->location_global}/all.png);
background-position: left;
background-repeat: no-repeat;
height: 442px;
}
-
+
#tower_hl {
position: relative;
}
-
+
/* Passage */
#passage {
width: 960px;
height: 401px;
-
+
background-image: url({$SCENE_URL}/{$CurrentPerso->location_global}/couloir/bay/void.png);
background-position: top left;
background-repeat: no-repeat;
}
-
+
#passage_left {
position: relative;
background-image: url({$SCENE_URL}/{$CurrentPerso->location_global}/couloir/GoLeft.png);
width: 38px;
height: 38px;
}
-
+
#passage_right {
position: relative;
background-image: url({$SCENE_URL}/{$CurrentPerso->location_global}/couloir/GoRight.png);
width: 38px;
height: 38px;
}
-
+
#passage_gallery ul {
position: relative;
top: 145px;
left: 120px;
-
+
margin-top: inherit;
margin-bottom: inherit;
}
-
+
#passage_gallery li {
display: block;
float: left;
margin-right: 60px;
-
+
width: 170px;
height: 170px;
-
+
padding: 4px 4px;
-
+
background-image: url({$SCENE_URL}/{$CurrentPerso->location_global}/couloir/frame.png);
background-repeat: no-repeat;
background-position: top left;
}
-
+
#screen {
position: absolute;
left: 10%;
top: 10%;
width: 80%;
height: 80%;
}
-
+
#screen img {
position: absolute;
cursor: pointer;
visibility: hidden;
width: 0px;
height: 0px;
}
-
+
#screen .tvover {
border: solid #343434;
opacity: 1;
filter: alpha(opacity=100);
}
-
+
#screen .tvout {
border: solid #fff;
opacity: 0.7;
}
-
+
#bankImages {
display: none;
}
-
+
#uploadDialog label {
color: black;
}
/* Couloir info */
#couloir_info {
background-image: url({$SCENE_URL}/{$CurrentPerso->location_global}/couloir/info.png);
height: 42px;
padding-top: 20px;
color: black;
}
#couloir_info a {
color: white;
}
#couloir_info a:hover {
font-weight: 900;
}
#domain_name {
margin-left: 1em;
}
</style>
-
+
<!-- Javascript bits: dojo -->
<script>
dojo.require("dojo.parser");
dojo.require("dijit.Dialog");
dojo.require("dijit.form.Button");
dojo.require("dijit.form.TextBox");
</script>
-
+
<!-- Tower -->
<!--<div id="tower"></div>-->
-
+
<!-- Navigation -->
{$loc = explode('C', $CurrentPerso->location_local)}{$loc[0] = substr($loc[0], 1)}
<div class="grid_7 alpha">
{#Sector#} T<span id="TowerFloor">{$loc[0]}</span>
</div>
<div class="grid_2" style="text-align: center">
{#Couloir#} <span id="TowerCouloir">{$loc[1]}</span>
</div>
<div class="grid_7 omega" style="text-align: right">
<a href="{if $loc[0] == 1}#{else}/do.php/set_local_location/T{$loc[0] - 1}C{$loc[1]}?redirectTo={get_url()}{/if}" onClick="passage.goUp(); return false;">{#GoUp#}</a> | <a href="/do.php/set_local_location/T{$loc[0] + 1}C{$loc[1]}?redirectTo={get_url()}" onClick="passage.goDown(); return false;">{#GoDown#}</a>
</div>
<!-- Passage -->
<div class="grid_16 alpha omega">
<div id="passage">
<div id="passage_gallery"></div>
<!-- Navigation -->
</div>
</div>
<div class="clear"></div>
<!-- Info -->
<div id="couloir_info">
<div class="grid_6 prefix_2 alpha">
<span id="domain_name">{#FreeDomain#}</span>
</div>
<div class="grid_6 suffix_2 omega" style="text-align: right">
<span id="domain_owner">{sprintf(#ClaimDomain#, '#')}</span>
</div>
<div class="clear"></div>
</div>
<div class="clear"></div>
-
+
<!-- Upload dialog -->
<div dojoType="dijit.Dialog" id="uploadDialog" style="display: none;" title="{#UploadNewArtwork#}">
<p>{#UploadNewArtworkDescription#}</p>
<form method="post" id="test" action="{get_xhr_hashed_url('upload_content', {$CurrentPerso->location_global})}?redirectTo={get_url()}" enctype="multipart/form-data">
<input type="hidden" id="location_local" name="location_local" value='{$CurrentPerso->location_local}' />
<input type="hidden" id="i" name="location_k" value="-1">
<div class="row">
<label for="artwork" class="firstLabel">{#UploadNewArtworkPicture#} (max. {ini_get('upload_max_filesize')})</label>
<input type="file" name="artwork" id="artwork" class="long" />
</div>
<div class="row">
<label for="title" class="firstLabel">{#UploadNewArtworkTitle#}</label>
<input dojoType="dijit.form.TextBox" name="title" id="title" type="text" class="long" />
</div>
<div class="row center">
<button dojoType="dijit.form.Button" iconClass="dijitEditorIcon dijitEditorIconSave" type="submit" value="Save" />OK</button>
</div>
</form>
</div>
-
+
<!-- Javascript bits: script.aculo.us -->
<script src="{#StaticContentURL#}/js/prototype.js"></script>
<script src="{#StaticContentURL#}/js/effects.js"></script>
<!-- Javascript bits: tower and couloir/passage/corridor/gallery/whatNameYouGiveToIt -->
<script src="{$SCENE_URL}/{$CurrentPerso->location_global}/tower.js"></script>
<script>
//Initializes tower map
//tower.hl = '{$SCENE_URL}/{$CurrentPerso->location_global}/hl.png';
//tower.highlight(1);
-
+
//Initializes passage view
passage.bayPath = '{$SCENE_URL}/{$CurrentPerso->location_global}/couloir/bay/';
passage.initialize('{$location->global}', '{$CurrentPerso->location_local}');
-
+
//Initializes gallery
gallery.initialize('{#StaticContentURL#}', '{get_xhr_hashed_url('get_content', {$CurrentPerso->location_global})}');
</script>
diff --git a/content/scenes/B00001001/tower.js b/content/scenes/B00001001/tower.js
index 2d8d138..01f7f87 100644
--- a/content/scenes/B00001001/tower.js
+++ b/content/scenes/B00001001/tower.js
@@ -1,608 +1,608 @@
/* -------------------------------------------------------------
Zed hypership tower javascript code
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Authors: Dereckson (tower, passage and gallery classes)
G. Fernandez (tv, Library classes)
Tags: animation upload presentation diaporama
Filename: tower.js
Version: 1.0
Created: 2010-01-31
Updated: 2010-02-23
Licences: Dereckson code is dual licensed:
BSD and Creative Commons BY 3.0.
G. Fernandez code is licensed under CC-BY-NC 2.0.
Dependencies: dojo (xhr calls, dialog ui)
------------------------------------------------------------- */
/* -------------------------------------------------------------
Tower class
- Prints a tower map, with hl on current corridor
+ Prints a tower map, with hl on current corridor
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
+
var tower = {
//The source to highlight picture
hl: 'hl.png',
-
+
//The highlighted corridor (1-6). 0 = no hl
i: 0,
-
+
//The corridor 4 (top) hl starts at:
hlStartPosition: [163, 93],
-
+
//Gets CurrentPerso html code
getHighlightCode: function () {
return '<img id="tower_hl" src="' + this.hl + '" alt="Corridor ' + this.i + '" />';
},
-
+
highlight: function (i) {
//If already there, nothing to do
if (this.i == i) return;
-
+
//Puts hl
this.i = i;
var tower = document.getElementById("tower");
if (tower != null) {
tower.innerHTML = this.getHighlightCode();
var towerHl = document.getElementById("tower_hl");
if (towerHl != null) {
towerHl.style.left = this.hlStartPosition[0] + "px";
towerHl.style.top = this.hlStartPosition[1] + "px";
-
+
//The 4 is okay
if (i == 4) return;
-
+
//Gets rotation angle
if (i > 4) {
angle = 60 * (i - 4);
} else {
angle = 180 + (i -1) * 60;
}
}
}
}
}
/* -------------------------------------------------------------
Passage class
Prints relevant bay
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
//Corridors are like art galleries
var passage = {
//Parameters
shipGlobalLocation: null,
persoLocalLocation: null,
bayPath: '',
id: 'passage',
-
+
//gets hyperspace bay
//randomly selected from 23 choices
getHyperspaceBay: function () {
var n = Math.floor(Math.random() * 23 + 1);
return 'hyper/' + ((n.toString().length == 1) ? "0" + n : n) + '.png';
},
-
+
getBay: function () {
//The bay depends of ship location
if (this.shipGlobalLocation[0] == 'B') {
//TODO: handle orientation of the ship and objects
//{$bay = substr($location->global, 0, 6)}
return this.shipGlobalLocation.substring(0, 6) + '.png';
} else {
//TODO: check if we're really in hyperspace.
//If not, we should fallback on default.png
return this.getHyperspaceBay();
}
-
+
return 'default.png'; //will be reachable, cf. upper
},
-
+
updateBay: function () {
var bgImage = 'url("' + this.bayPath + this.getBay() + '")';
document.getElementById(this.id).style.backgroundImage = bgImage;
},
-
+
getLocalLocation: function () {
//Splits TtCc expression at C
// '0' => "T2"
// '1' => "1"
var location = this.persoLocalLocation.split('C');
-
+
if (location.length == 2 && location[0][0] == 'T') {
//Current t, c coordinates
var t = location[0].substring(1);
var c = location[1];
}
-
+
return [t, c];
},
-
+
goLeft: function () {
//TxC1 -> TxC6 -> TxC5 -> TxC4 -> TxC3 -> TxC2 -> TxC1
tc = this.getLocalLocation();
t = tc[0];
c = tc[1];
//New c coordinates
var nc = (c == 1) ? 6 : c - 1;
-
+
this.moveTo(t, nc);
},
-
+
goUp: function () {
//TxCy -> T[x+1]Cy
tc = this.getLocalLocation();
t = tc[0];
c = tc[1];
if (t > 1) {
this.moveTo(--t, c);
}
},
-
+
goDown: function () {
//TxCy -> T[x+1]Cy
tc = this.getLocalLocation();
t = tc[0];
c = tc[1];
-
+
this.moveTo(++t, c);
},
-
+
goRight: function () {
//TxC1 -> TxC2 -> TxC3 -> TxC4 -> TxC5 -> TxC6 -> TxC1
tc = this.getLocalLocation();
t = tc[0];
c = tc[1];
//New c coordinates
var nc = (c == 6) ? 1 : eval(c) + 1;
-
+
this.moveTo(t, nc);
},
-
+
moveTo: function (t, c) {
//New local location
local_location = 'T' + t + 'C' + c;
passage.persoLocalLocation = local_location;
-
+
//Updates coordinates
dojo.byId('TowerCouloir').innerHTML = c;
dojo.byId('TowerFloor').innerHTML = t;
dojo.byId('location_local').value = local_location;
//Updates bays
//passage.updateBay();
-
+
//TODO: make url parameter compatible to any URL scheme
//TODO: check in dojo doc if the local_location have to be encoded
dojo.xhrGet({
handleAs: "json",
url: "/do.php/set_local_location/" + local_location,
preventCache: true,
handle: function (response, ioArgs) {
//Loads new gallery content
if (gallery.initialized) {
gallery.loadPics();
}
}
});
},
-
+
onGalleryInitialized: function () {
//Adds left and right arrows
this.addLeftArrow();
this.addRightArrow();
},
-
+
addLeftArrow: function () {
//Adds left arrow
var element = document.getElementById(this.id);
var left = element.offsetLeft + 28;
var top = element.offsetTop + 173;
-
+
element.innerHTML += '<div id="passage_left" onClick="passage.goLeft()" style="display: none; position: absolute; top: ' + top + 'px; left: ' + left + 'px"></div>';
},
-
+
addRightArrow: function () {
//Adds right arrow
var element = document.getElementById(this.id);
var left = element.offsetLeft + 898;
var top = element.offsetTop + 173;
-
+
element.innerHTML += '<div id="passage_right" onClick="passage.goRight()" style="display: none; position: absolute; top: ' + top + 'px; left: ' + left + 'px"></div>';
},
-
+
displayArrows: function (state) {
//Displays left and right arrows?
var display = [false, false];
-
+
switch (state) {
case "left":
display[0] = true;
break;
-
+
case "right":
display[1] = true;
break;
}
-
+
document.getElementById("passage_left").style.display = display[0] ? 'block' : 'none';
document.getElementById("passage_right").style.display = display[1] ? 'block' : 'none';
},
-
+
onmousemove: function () {
var element = document.getElementById(this.id);
var left = element.offsetLeft;
var top = element.offsetTop;
-
+
//alert(element.offsetWidth);
var inPassage = (
mouse.x >= left && mouse.y >= top &&
mouse.x <= left + element.offsetWidth &&
mouse.y <= top + element.offsetHeight
)
-
+
if (inPassage) {
var x = mouse.x - left;
var y = mouse.y - top;
if (x < 130) {
this.displayArrows('left');
} else if (x > 830) {
this.displayArrows('right');
} else {
this.displayArrows('none');
}
}
},
-
+
isValidLocalLocation: function (localLocation) {
return /^T[1-9][0-9]*C[1-6]$/.test(localLocation);
},
-
+
initialize: function (shipGlobalLocation, persoLocalLocation) {
this.shipGlobalLocation = shipGlobalLocation;
this.persoLocalLocation = persoLocalLocation;
if (!this.isValidLocalLocation(persoLocalLocation)) {
this.moveTo(2, 1);
-
+
//Notify (this code requires prototype.js (or jquery, but in this case, simplify it with a insertAfter call))
//TODO: ensure this code have dojo as only dependency
$("header").replace('<div id="header">' + $("header").innerHTML + '</div><div class="container_16"><div class="grid_16 alpha omega"><div class="notify">As you were losing yourself in the hypership tower, your paths guide you to the second floor.</div></div></div>');
}
this.updateBay();
}
}
/* -------------------------------------------------------------
Gallery class
Prints the gallery and calls artwork script
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
var gallery = {
pics: [],
-
+
initialized: false,
-
+
artworkDisplayMode: false,
-
+
currentPic: -1,
-
+
path: '',
-
+
loadXhrUrl: null,
-
+
getSquare: function (url) {
//Gets extension position (last . position)
var pos = url.lastIndexOf('.');
-
+
return url.substring(0, pos) + 'Square' + url.substring(pos);
},
-
+
showGallery: function () {
var html = '<ul>';
for (var i = 0 ; i < this.pics.length ; i++) {
if (this.pics[i] != null) {
//Shows artwork
html += '\n\t<li><img src="' + this.getSquare(this.pics[i]) + '" onClick="gallery.show(' + i + ')" /></li>';
} else {
//Shows placeholder
html += '\n\t<li onClick="gallery.uploadDialog(' + i + ');"></li>';
}
}
html += '\n</ul>';
document.getElementById('passage_gallery').innerHTML = html;
passage.onGalleryInitialized();
},
-
+
hideGallery: function () {
var elem = document.getElementById('passage_gallery');
Effect.Puff(elem);
},
-
+
loadPics: function () {
dojo.xhrGet({
handleAs: 'json',
url: this.loadXhrUrl + '?location_local=' + passage.persoLocalLocation,
preventCache: true,
handle: function (response, ioArgs) {
//TODO: in the future, we should print some metadata,
// and the objects will be useful.
// Meanwhile, we transform it to an array line.
-
+
var pics = [null, null, null];
-
+
//Builds pics array
for (var i = 0 ; i < response.length ; i++) {
if (response[i]['location_k'] > -1 && response[i]['location_k'] < 3) {
pics[response[i]['location_k']] = gallery.path + '/' + response[i]['path'];
}
}
-
+
//alert(dump(response));
gallery.loadPicsCallback(pics);
}
});
},
-
+
loadPicsCallback: function (pics) {
//Sets pics array
this.pics = pics;
-
+
//Show gallery
this.showGallery();
-
+
//Init done
if (!this.initialized) {
this.initialized = true;
}
},
-
+
show: function (i) {
//Hides gallery
this.hideGallery();
-
+
//Shows image
setTimeout('gallery.showImage(' + i + ')', 800);
},
-
+
showImage: function (i) {
//Sets image information
this.currentPic = i; //currently not used
this.artworkDisplayMode = true; //to handle properly ESC key down.
-
+
//New HTML passage code
document.getElementById('passage').innerHTML = '<div id="screen"></div><div id="bankImages"><img src="' + this.pics[i] + '" /></div>';
-
+
//Calls Photo3D script
onresize = tv.resize;
tv.init();
},
-
+
backToGallery: function () {
//Fades current picture
Effect.Fade(document.getElementById('screen'));
-
+
//Rebuilds gallery (in 800 ms, to let time to fading effect)
setTimeout("document.getElementById('passage').innerHTML = '<div id=\"passage_gallery\"></div>'; gallery.showGallery()", 800);
-
+
//Sets image information
this.currentPic = -1; //currently not used
this.artworkDisplayMode = false; //to handle properly ESC key down.
},
-
+
uploadDialog: function (i) {
document.getElementById('i').value = i;
dijit.byId('uploadDialog').show();
},
-
+
initialize: function (path, loadXhrUrl) {
//Sets load xhr url
this.path = path;
this.loadXhrUrl = loadXhrUrl;
-
+
//Loads pics
this.loadPics();
-
+
//Listens ESC key
document.onkeydown = function (e) {
if (e.keyCode == 27) {
if (gallery.artworkDisplayMode) {
gallery.backToGallery();
} else {
gallery.hideGallery();
}
}
}
}
}
/* -------------------------------------------------------------
Photo3D G. Fernandez script
http://www.dhteumeuleu.com/runscript.php?scr=photo3D.html
-
+
TODO: simplify code to handle one picture, and not an array
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
var gridsize = 1;
var Library = {};
Library.ease = function() {
this.target = 0;
-
+
this.position = 0;
-
+
this.move = function(_1, _2) {
this.position += (_1 - this.position) * _2;
};
};
var tv = {
- O: [],
-
+ O: [],
+
screen: {},
-
+
grid: {
size: gridsize,
borderSize: 6,
zoomed: false
},
-
+
angle: {
x: new Library.ease(),
y: new Library.ease()
},
-
+
camera: {
x: new Library.ease(),
y: new Library.ease(),
zoom: new Library.ease(),
focalLength: 750
},
-
+
init: function() {
this.screen.obj = document.getElementById("screen");
var images = document.getElementById("bankImages").getElementsByTagName("img");
-
+
this.screen.obj.onselectstart = function () {
return false;
};
this.screen.obj.ondrag = function () {
return false;
};
var ni = 0;
var n = (tv.grid.size / 2) - 0.5;
for (var y = - n ; y <= n ; y++) {
for (var x = - n ; x <= n; x++) {
var o = document.createElement("img");
var i = images[(ni++) % images.length];
o.className = "tvout";
o.src = i.src;
tv.screen.obj.appendChild(o);
o.point3D = {
x: x,
y: y,
z: new Library.ease()
};
o.point2D = {};
o.ratioImage = 1;
tv.O.push(o);
-
+
o.onmouseover = function () {
if (!tv.grid.zoomed) {
if (tv.o) {
tv.o.point3D.z.target = 0;
tv.o.className = "tvout";
}
this.className = "tvover";
this.point3D.z.target = - 0.5;
tv.o = this;
}
};
-
+
o.onclick = function () {
if (!tv.grid.zoomed) {
tv.camera.x.target = this.point3D.x;
tv.camera.y.target = this.point3D.y;
tv.camera.zoom.target = tv.screen.w * 1.25;
tv.grid.zoomed = this;
} else {
if (this == tv.grid.zoomed) {
tv.camera.x.target = 0;
tv.camera.y.target = 0;
tv.camera.zoom.target = tv.screen.w / (tv.grid.size + 0.1);
tv.grid.zoomed = false;
}
}
};
-
+
o.calc = function () {
this.point3D.z.move(this.point3D.z.target, 0.5);
var x = (this.point3D.x - tv.camera.x.position) * tv.camera.zoom.position;
var y = (this.point3D.y - tv.camera.y.position) * tv.camera.zoom.position;
var z = this.point3D.z.position * tv.camera.zoom.position;
var xy = tv.angle.cx * y - tv.angle.sx * z;
var xz = tv.angle.sx * y+tv.angle.cx * z;
var yz = tv.angle.cy * xz - tv.angle.sy * x;
var yx = tv.angle.sy * xz+tv.angle.cy * x;
this.point2D.scale = tv.camera.focalLength / (tv.camera.focalLength+yz);
this.point2D.x = yx * this.point2D.scale;
this.point2D.y = xy * this.point2D.scale;
this.point2D.w = Math.round(Math.max(0, this.point2D.scale * tv.camera.zoom.position * 0.8));
if (this.ratioImage > 1) {
this.point2D.h = Math.round(this.point2D.w / this.ratioImage);
} else {
this.point2D.h = this.point2D.w;this.point2D.w = Math.round(this.point2D.h * this.ratioImage);
}
};
-
+
o.draw = function () {
if (this.complete) {
if (!this.loaded) {
if (!this.img) {
this.img = new Image();
this.img.src = this.src;
}
if (this.img.complete) {
this.style.visibility = "visible";
this.ratioImage = this.img.width / this.img.height;
this.loaded = true;this.img = false;
}
}
this.style.left = Math.round(this.point2D.x * this.point2D.scale + tv.screen.w - this.point2D.w * 0.5) + "px";
this.style.top = Math.round(this.point2D.y * this.point2D.scale + tv.screen.h - this.point2D.h * 0.5) + "px";
this.style.width = this.point2D.w + "px";
this.style.height = this.point2D.h + "px";
this.style.borderWidth = Math.round(Math.max(this.point2D.w, this.point2D.h) * tv.grid.borderSize * 0.01) + "px";
this.style.zIndex = Math.floor(this.point2D.scale * 100);
}
};
}
}
tv.resize();
mouse.y = tv.screen.y+tv.screen.h;
mouse.x = tv.screen.x+tv.screen.w;
tv.run();
},
-
+
resize: function() {
var o = tv.screen.obj;
tv.screen.w = o.offsetWidth / 2;
tv.screen.h = o.offsetHeight / 2;
tv.camera.zoom.target = tv.screen.w / (tv.grid.size + 0.1);
for (tv.screen.x = 0, tv.screen.y = 0 ; o != null ; o = o.offsetParent) {
tv.screen.x += o.offsetLeft;
tv.screen.y = o.offsetTop;
}
},
-
+
run: function () {
tv.angle.x.move(-(mouse.y - tv.screen.h - tv.screen.y) * 0.0025, 0.1);
tv.angle.y.move((mouse.x - tv.screen.w - tv.screen.x) * 0.0025, 0.1);
tv.camera.x.move(tv.camera.x.target, tv.grid.zoomed ? 0.25: 0.025);
tv.camera.y.move(tv.camera.y.target, tv.grid.zoomed ? 0.25: 0.025);
tv.camera.zoom.move(tv.camera.zoom.target, 0.05);
tv.angle.cx = Math.cos(tv.angle.x.position);
tv.angle.sx = Math.sin(tv.angle.x.position);
tv.angle.cy = Math.cos(tv.angle.y.position);
tv.angle.sy = Math.sin(tv.angle.y.position);
for (var i = 0, o ; o = tv.O[i] ; i++) {
o.calc();
o.draw();
}
setTimeout(tv.run, 32);
}
};
var mouse = {x: 0, y: 0};
document.onmousemove = function (e) {
if (window.event) {
e = window.event;
}
mouse.x = e.clientX;
mouse.y = e.clientY;
passage.onmousemove();
return false;
};
diff --git a/content/scenes/B00001002.tpl b/content/scenes/B00001002.tpl
index 1ee6cd0..309d6c8 100644
--- a/content/scenes/B00001002.tpl
+++ b/content/scenes/B00001002.tpl
@@ -1,56 +1,56 @@
<!--
Global location: B00001002
-->
<div class="grid_7 alpha">
{$xyz = explode(',', substr($CurrentPerso->location_local, 1, -1))}
{$x = $xyz[0]}{$y = $xyz[1]}{$z = $xyz[2]}
{#Sector#} C<span id="sector">{GeoOctocube::get_sector($x, $y, $z)}</span>
</div>
<div class="grid_2" style="text-align: center;">
{#Zone#} <span id="area">{abs($x)}-{abs($y)}</span>
</div>
<div class="grid_7 omega" style="text-align: right; margin-bottom: 1em;">
{#Level#} <span id="level">{abs($z)}</span>
</div>
-
+
<div class="clear"></div>
{if $zone}
{if $zone->type == "hotglue"}
<!-- Content iframe -->
<script type="text/javascript">
function hijacklinks(iframe){
var as = iframe.contentDocument.getElementsByTagName('a');
for(i=0;i<as.length;i++){
as[i].setAttribute('target','_parent');
}
}
</script>
<iframe src="{$HOTGLUE}?zone_{$zone->id}" width="960" height="600" id="content_iframe" frameborder="0" scrolling="no" style="margin-bottom: 1em" onload="hijacklinks(this)"></iframe>
{else}
<p>{#CantRender#}</p>
{dprint_r($zone)}
{/if}
{else}
<div class="content_wrapper">
<h1>{#Builder#}</h1>
<div class="grid_9 suffix_1 content alpha">
{#BuildInfo#}
</div>
<div class="grid_6 omega">
<p><a href="{get_url('builder')}">{#StartBuild#}</a></p>
-
+
<p><a href="{get_url('do.php')}/local_move/0,1,0?redirectTo=/">{#GoNorth#}</a><br />
<a href="{get_url('do.php')}/local_move/1,0,0?redirectTo=/">{#GoEast#}</a><br />
<a href="{get_url('do.php')}/local_move/0,-1,0?redirectTo=/">{#GoSouth#}</a><br />
<a href="{get_url('do.php')}/local_move/-1,0,0?redirectTo=/">{#GoWest#}</a></p>
-
+
<p><a href="{get_url('do.php')}/local_move/0,0,1?redirectTo=/">{#GoUp#}</a><br />
<a href="{get_url('do.php')}/local_move/0,0,-1?redirectTo=/">{#GoDown#}</a></p>
<p><a href="{get_url('builder', 'map')}">{#ViewMap#}</a></p>
<p><a href="{get_xhr_hashed_url('global_move', 'B00001001', 'T2C3')}?redirectTo={get_url()}">{#GoTower#}</a></p>
</div>
<div class="clear fixclear"></div>
</div>
{/if}
diff --git a/content/scenes/B00001002_C0.tpl b/content/scenes/B00001002_C0.tpl
index 5d0d4cf..9e756af 100644
--- a/content/scenes/B00001002_C0.tpl
+++ b/content/scenes/B00001002_C0.tpl
@@ -1,34 +1,34 @@
<!--
Global location: B00001002
Local location: (0, 0, 0)
-->
<div class="grid_7 alpha">
{#Sector#} C<span id="sector">0</span>
</div>
<div class="grid_9 omega" style="text-align: right; margin-bottom: 1em;">
{#Core#}
</div>
-
+
<div class="clear"></div>
-
+
<div class="content_wrapper">
<h1>{#Core#}</h1>
<div class="grid_9 suffix_1 content alpha">
<h2>{#YouAreInCore#}</h2>
{#CoreInfo#}
<h2>{#ShipNavigationControl#}</h2>
<p><strong>{#CurrentLocation#}{#_t#}</strong> {$location}</p>
</div>
<div class="grid_6 omega">
<p><a href="{get_url('do.php')}/local_move/-1,1,-1?redirectTo=/">C1</a><br>
<a href="{get_url('do.php')}/local_move/1,1,-1?redirectTo=/">C2</a><br>
<a href="{get_url('do.php')}/local_move/-1,-1,-1?redirectTo=/">C3</a><br>
<a href="{get_url('do.php')}/local_move/1,-1,-1?redirectTo=/">C4</a><br></p>
<p><a href="{get_url('do.php')}/local_move/-1,1,1?redirectTo=/">C5</a><br>
<a href="{get_url('do.php')}/local_move/1,1,1?redirectTo=/">C6</a><br>
<a href="{get_url('do.php')}/local_move/-1,-1,1?redirectTo=/">C7</a><br>
- <a href="{get_url('do.php')}/local_move/1,-1,1?redirectTo=/">C8</a><br></p>
+ <a href="{get_url('do.php')}/local_move/1,-1,1?redirectTo=/">C8</a><br></p>
</div>
<div class="clear fixclear"></div>
</div>
diff --git a/content/stories/B00003001.xml b/content/stories/B00003001.xml
index 99a7981..6ecddaf 100644
--- a/content/stories/B00003001.xml
+++ b/content/stories/B00003001.xml
@@ -1,176 +1,176 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Zeta, Kaos
Dereckson, 2010-01-31 ; Dereckson, Dédé, Mystique 2010-06-25.
TODO: It's a start location. So it should provide a way to to reach hypership
TODO: <section id="mines.entry"></section>
TODO: .en
TODO: Écrire les chapitres The hole
-->
<story>
<title>Zeta, Kaos</title>
<section start="true" id="panorama">
<title>Panorama</title>
<description>
Zeta est une ville venteuse, plongée dans la nuit et le bruit.
-
+
Ce qui ressemble à de petites créatures illuminent la route s'étendant devant vous et serpentant vers le centre ville.
-
+
À la surface travaillent d'honnêtes mineur de cobalt et de davyrium, les mines ceinturant le sud de la ville.
-
+
Au nord, The Hole, une ancienne mine dont les mineurs évitent de parler.
-
+
À l'est, un petit spatioport.
</description>
<choices>
<choice goto="city.entry">Descendre vers le centre ville</choice>
<choice goto="hole.entry">Se diriger vers The Hole</choice>
<choice goto="spatioport.entry">Se rendre au spatioport</choice>
<choice goto="mines.entry">Vers les mines</choice>
</choices>
<local>1</local>
</section>
<!--
Le centre ville
-
- Sa bibliothèque. Son bar.
+
+ Sa bibliothèque. Son bar.
-->
<section id="city.entry">
<title>Le centre ville</title>
<description>
- Le centre ville de Zeta alterne des zones plongées dans l'obscurité et des zones suréclairées au néon.
+ Le centre ville de Zeta alterne des zones plongées dans l'obscurité et des zones suréclairées au néon.
</description>
- </section>
-
+ </section>
+
<!--
Le spatioport
-->
<section id="spatioport.entry">
<title>Spatioport</title>
<description>
Le spatioport se présente sous la forme d'un large dôme cobalt où se reflète la lueur de Thétys, un astéroïde gravitant autour de Kaos tel une lune.
-
+
À l'arrière, un cratère évasé peut accueillir une trentaine de vaisseaux de taille modeste et de conception variée.
</description>
<hooks>
<hook type="spatioport" />
</hooks>
<choices>
<choice goto="panorama">Retourner en ville</choice>
</choices>
-
+
<local>3</local>
</section>
-
+
<!--
The Hole
-
+
Lieu d'exil de ce secteur de la galaxie. Lieu de tous les traffics. The Hole.
-->
<section id="hole.entry">
<title>The Hole</title>
<description>
The Hole. Une ancienne mine désaffectée depuis trois siècles. Aujourd'hui, un squat. L'endroit où tout se passe sur Zeta. Refuge des rebelles. Lieu d'exil de ce secteur de la galaxie. Lieu de tous les traffics. The Hole.
-
+
Une bande d'une douzaine de jeunes armés de lasers et de fouets neuroniques en garde l'entrée, deux vous regardant d'un œil plutôt menaçant.
-
+
Ils vous refusent le passage.
</description>
<choices>
<choice goto="hole.entry.chat">Dialoguer avec les jeunes de l'entrée</choice>
<choice goto="spatioport.entry">Se rendre au spatioport</choice>
<choice goto="mines.entry">Vers les mines</choice>
<choice goto="panorama">Retourner en ville</choice>
</choices>
<local>2</local>
</section>
<section id="hole.entry.chat">
<title>The Hole</title>
<description>
Vous vous avancez prudemment, tout en observant le garde de gauche qui pose la main sur son blaster, duquel clignote le mot CRÉMATORIUM.
</description>
<choices>
<choice goto="hole.entry.chat.Zeta">Obtenir des informations sur Zeta</choice>
<choice goto="hole.entry.chat.Hole">Se renseigner sur cet endroit</choice>
<choice goto="hole.entry.chat.weapons">Leur demander pourquoi ils sont armés.</choice>
<choice goto="hole.entry.chat.fear">Vérifier qu'il est possible de partir sans heurt ni date de décès prématurée.</choice>
<choice goto="hole.entry.chat.goaway">Reculer</choice>
</choices>
</section>
<section id="hole.entry.chat.fear">
<title>The Hole</title>
<description>
Vous rassurez les gardes en leur disant que vous ne faites que passer, et s'il est possible de faire demi tour.
-
+
Un garde aux rangers noires, pantalon argenté troué, non rasé depuis trois jours, une cicatrice près de l'arcade sourcillière : « wesh et très vite ».
-
+
L'on entend à l'arrière « Court Forest, court » pendant que le second garde émet deux érecutements successifs de la gorge, tout en pointant son arme vers vous.
</description>
<choices>
<choice goto="panorama">Obtempérer et retourner en ville</choice>
<choice goto="hole.entry.chat.Zeta">Tenter d'obtenir des informations sur Zeta</choice>
<choice goto="hole.entry.chat.Hole">Se renseigner sur cet endroit</choice>
<choice goto="hole.entry.chat.weapons">Leur demander pourquoi ils sont armés.</choice>
</choices>
</section>
<section id="hole.entry.chat.Zeta">
<title>The Hole</title>
<description>
Un jeune de grande taille s'avance, ses deux étranges cornes sortent des avants-bras, un de ses lobes d'oreilles descendant vers le bas, d'étranges inscriptions ressemblant à des tatouages sur le haut de son crâne dégarni.
-
+
Il vous indique le bas de la colline, et vous invite à retourner en ville.
-
+
Vous insistez quelque peu, il se contente de vous dire qu'il n'est pas guide touristique.
-
+
Ils refusent de répondre à toute autre question et vous ignorent.
</description>
<choices>
<choice goto="panorama">Retourner en ville</choice>
</choices>
</section>
<section id="hole.entry.chat.Hole">
<title>The Hole</title>
<description>
– « Qu'est-ce que vous gardez d'aussi important ? Pourquoi les mineurs évitent d'en parler ? »
-
+
– « Revenez quand vous saurez. »
</description>
<choices>
<choice goto="panorama">Obtempérer et retourner en ville</choice>
<choice goto="hole.entry.chat.Zeta">Tenter d'obtenir des informations sur Zeta</choice>
<choice goto="hole.entry.chat.Hole">Se renseigner sur cet endroit</choice>
<choice goto="hole.entry.chat.weapons">Leur demander pourquoi ils sont armés.</choice>
</choices>
</section>
<section id="hole.entry.chat.weapons">
<title>The Hole</title>
<description>
Vous leur demandez pourquoi sont-ils aussi bien vêtus, en espérant qu'ils comprennent l'allusion aux armes.
-
+
Ne semblant pas obtenir de réponse, vous leur demandez ce que sont leurs jouets.
-
+
Un garde sourit, s'avance, et appuie sur son fouet neuronique.
-
+
Les autres éclatent de rire pendant que vous vous tordez au sol, pris de convulsions.
</description>
<choices>
<choice goto="panorama">Se relever et partir en courant</choice>
<choice goto="panorama">Se relever en tentant de conserver un peu de dignité et partir doucement</choice>
</choices>
</section>
<section id="hole.entry.chat.goaway">
<title>The Hole</title>
<description>
Vous reculez prudemment, tout doucement, avec un grand sourire.
-
+
Un des gardes vous regarde vexé, scrutant le moindre signe supplémentaire de provocation.
- </description>
-
- <choices>
+ </description>
+
+ <choices>
<choice goto="panorama">Retourner en ville</choice>
</choices>
</section>
</story>
\ No newline at end of file
diff --git a/content/stories/B00004001.xml b/content/stories/B00004001.xml
index 28b1e71..7559e82 100644
--- a/content/stories/B00004001.xml
+++ b/content/stories/B00004001.xml
@@ -1,77 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Gné
Dimi, Inferno, DcK 2010-07-04
TODO: .en
TODO: playtesting
-->
<story>
<title>Gné, Gné</title>
<section start="true" id="panorama">
<title>Gné</title>
<description>
L'air est nauséabond, difficilement respirable, comme l'odeur des effluves d'une centaine d'humanoïdes crasseux et suant de tous pores.
-
+
Aucune vie animale ni végétale aux alentours, si ce n'est une étrange mousse ressemblant quelque peu à de la moisissure.
L'on distingue peu de bâtiments, au profit de petites huttes dispersées dans un capharnaüm apparent.
Derrière, s'élève un grand temple en terre cuite, aux formes tantôt arrondies, tantôt acerbes.
</description>
<choices>
<choice goto="huttes.entry">Explorer les huttes</choice>
<choice goto="temple.entry">Entrer dans le temple</choice>
<choice goto="spatioport.entry">Se rendre au spatioport</choice>
</choices>
<local>1</local>
</section>
<!--
Les huttes
-->
<section id="huttes.entry">
<title>Les huttes</title>
<description>
Quatre huttes retiennent particulièrement votre attention :
</description>
<choices>
<choice goto="huttes.A"></choice>
<choice goto="huttes.B"></choice>
<choice goto="huttes.C"></choice>
<choice goto="huttes.D">Se rendre dans la hutte où l'on entend des tambours</choice>
</choices>
<local>1</local>
</section>
-
+
<section id="huttes.D">
<title>Les huttes</title>
<description>
Quatre huttes retiennent particulièrement votre attention :
</description>
<choices>
- Des femmes dénudées
+ Des femmes dénudées
</choices>
</section>
-
+
<!--
Le spatioport
-->
<section id="spatioport.entry">
<title>Spatioport</title>
<description>
Le spatioport, à l'architecture se voulant l'allégorie de la sobriétété, ne comporte ni tourelle, ni dôme, ni technologie apparente, ni lumière accueillante, ni aide à l'amerrisage, comme s'il s'agissait d'un des tous premiers spatioport construit.
</description>
<hooks>
<hook type="spatioport" />
</hooks>
<choices>
<choice goto="panorama">Quitter le spatioport</choice>
- </choices>
+ </choices>
<local>3</local>
</section>
-
+
<!--
Le temple
-->
</story>
\ No newline at end of file
diff --git a/content/travel.xml b/content/travel.xml
index a79413e..542e8e4 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 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>
\ No newline at end of file
diff --git a/controllers/anonymous.php b/controllers/anonymous.php
index 75ac6a3..5c627fa 100644
--- a/controllers/anonymous.php
+++ b/controllers/anonymous.php
@@ -1,152 +1,152 @@
<?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 ;
* /invite the page to claim the invites.
*
* In all other cases, it prints the login form.
*
* @package Zed
* @subpackage Controllers
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
//
// Prepares the page
//
switch ($url[0]) {
case 'tour':
//The user have forgotten .html, let's redirect him
header('Location: ' . $Config['StaticContentURL'] . '/tour.html');
exit;
-
+
case 'invite':
//Invite form
if ($_POST['form'] == 'account.create') {
//User tries to claim its invite to create an account
require_once('includes/objects/invite.php');
require_once('includes/objects/user.php');
-
+
//Gets invite
$invite = new Invite($_POST['invite_code']);
if ($invite->lastError != '') {
//Not existant invite.
$smarty->assign('NOTIFY', lang_get("IncorrectInviteCode"));
} elseif ($invite->is_claimed()) {
//The invitation have already claimed by someone else.
$smarty->assign('NOTIFY', lang_get("InviteCodeAlreadyClaimed"));
} else {
//Checks if the given information is correct
//We ignore bad mails. All we really need is a login and a pass.
//We fill our array $errors with all the errors
$errors = array();
if (!$_POST['username']) {
$errors[] = lang_get('MissingUsername');
} elseif (!User::is_available_login($_POST['username'])) {
$errors[] = lang_get('LoginUnavailable');
}
-
+
if (User::get_username_from_email($_POST['email']) !== false) {
$errors[] = "There is already an account with this e-mail.";
}
-
+
if (!$_POST['passwd']) {
$errors[] = lang_get('MissingPassword');
}
-
+
if (count($errors)) {
$smarty->assign('WAP', join('<br />', $errors));
} else {
//Creates account
$user = new User();
$user->regdate = time();
$user->generate_id();
$user->name = $_POST['username'];
$user->active = 1;
$user->email = $_POST['email'];
$user->set_password($_POST['passwd']);
$user->save_to_database();
-
+
//Updates invite
$invite->to_user_id = $user->id;
$invite->save_to_database();
-
+
//Notifies inviter
require_once('includes/objects/message.php');
$message = new Message();
$message->from = 0;
$message->to = $invite->from_perso_id;
$message->text = sprintf(lang_get('InviteHaveBeenClaimed'), $invite->code);
$message->send();
-
+
//Logs in user
login($user->id, $user->name);
-
+
//Prints confirm message
$smarty->assign('WAP', lang_get("AccountCreated"));
-
+
//Redirects users to homepage
header('refresh: 5; url=' . get_url());
//Calls void controller
$smarty->assign('screen', 'user.create');
define('NO_FOOTER_EXTRA', true);
include("void.php");
exit;
}
}
-
+
//Keeps username, email, invite code printed on account create form
$smarty->assign('username', $_POST['username']);
$smarty->assign('invite_code', $_POST['invite_code']);
$smarty->assign('email', $_POST['email']);
}
-
+
//If the invite code is specified, checks format
if ($url[1]) {
if (preg_match("/^([A-Z]){3}([0-9]){3}$/i", $url[1])) {
$smarty->assign('invite_code', strtoupper($url[1]));
} else {
$smarty->assign('NOTIFY', lang_get("IncorrectInviteCode"));
}
}
-
+
$template = 'account_create.tpl';
break;
-
+
default:
//Login form
if (array_key_exists('LastUsername', $_COOKIE))
$smarty->assign('username', $_COOKIE['LastUsername']);
if (array_key_exists('LastOpenID', $_COOKIE))
$smarty->assign('OpenID', $_COOKIE['LastOpenID']);
$smarty->assign('LoginError', $loginError);
$template = 'login.tpl';
break;
}
//
// HTML output
//
if ($template) $smarty->display($template);
?>
diff --git a/controllers/explore.php b/controllers/explore.php
index d2f5c28..0319d04 100644
--- a/controllers/explore.php
+++ b/controllers/explore.php
@@ -1,51 +1,51 @@
<?php
/**
* Explore current location
*
* Zed. The immensity of stars. The HyperShip. The people.
- *
+ *
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* This is a redirect controller to call the relevant controller,
* according to the location.
*
* It handles /explore URL
*
* @package Zed
* @subpackage Controllers
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
//
// Determines the kind of content user wants to explore
//
$explore_controller = '';
if (file_exists(STORIES_DIR . '/' . $CurrentPerso->location_global . '.xml')) {
$explore_controller = 'story';
}
//
// No relevant controller found
//
if ($explore_controller == '') {
message_die(GENERAL_ERROR, "<p>Congratulations! You've just found a shiny new place.</p><p>You've so the opportunity to define what this place should be, writing a story, preparing a puzzle or some images.</p><p>If you're interested, contact Dereckson.</p>", "Exploration error");
}
//
// Calls relevant controller
//
include($explore_controller . '.php');
?>
\ No newline at end of file
diff --git a/controllers/header.php b/controllers/header.php
index f3879a1..e9bec5d 100644
--- a/controllers/header.php
+++ b/controllers/header.php
@@ -1,62 +1,62 @@
<?php
/**
* Header
* Zed. The immensity of stars. The HyperShip. The people.
- *
+ *
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* This controller handle the header (MOTD, html header)
*
* @package Zed
* @subpackage Controllers
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*
* @todo cache MOTD fragments (sql performance)
*/
-
+
//
// MOTD
//
//TODO: this is a potentially very intensive SQL query
$sql = 'SELECT p.perso_nickname as username, p.perso_name as name, m.motd_text FROM ' . TABLE_PERSOS . ' p, ' . TABLE_MOTD . ' m WHERE p.perso_id = m.perso_id ORDER BY rand() LIMIT 1';
if (!$result = $db->sql_query($sql)) message_die(SQL_ERROR, "Can't query MOTD", '', __LINE__, __FILE__, $sql);
$row = $db->sql_fetchrow($result);
$smarty->assign('WALL_TEXT', $row['motd_text']);
$smarty->assign('WALL_USER', $row['name']);
$smarty->assign('WALL_USER_URL', get_url('who', $row['username']));
//
// HTML output
//
//Defines DOJO if needed, and assigns DOJO/DIJIT smarty variables
if (!defined('DOJO')) {
/**
* Determines if the dojo library have or not been loaded
*
* If true, there's a code like <script src="js/dojo/dojo/dojo.js"><script>
* in the <head> block of the code.
*/
define('DOJO', defined('DIJIT'));
}
if (defined('DIJIT')) $smarty->assign('DIJIT', true);
$smarty->assign('DOJO', DOJO);
//Prints the template
$smarty->display('header.tpl');
/**
* This constant indicates the header have been printed
*/
define('HEADER_PRINTED', true);
?>
diff --git a/controllers/motd.php b/controllers/motd.php
index 8f6dcbc..a5e66e3 100644
--- a/controllers/motd.php
+++ b/controllers/motd.php
@@ -1,56 +1,56 @@
<?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.
*
* @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');
+include('header.php');
//Serves content
$smarty->display('motd_add.tpl');
//Servers footer
include('footer.php');
-
+
?>
\ No newline at end of file
diff --git a/controllers/page.php b/controllers/page.php
index 8736322..d548153 100644
--- a/controllers/page.php
+++ b/controllers/page.php
@@ -1,135 +1,135 @@
<?php
/**
* Page
* Zed. The immensity of stars. The HyperShip. The people.
- *
+ *
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* This controller handle the /page URL.
*
* It allows to prints a content page.
*
* The code of the content page to print must be included in the URL:
* /page/quux will print the quux page.
*
* To edit a page, append ?mode=edit to the URL.
*
* It usees the page_edit.tpl view to edit and the raw.tpl view to print pages.
*
* Versions of the edited pages are saved in a separate table
* but it's not a wiki, it's for backup purposes.
*
* @package Zed
* @subpackage Controllers
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*
* @todo move "handle editor form" and some of the "gets page" code to a includes/objets/page.php file (rationale: cleaner model/controller separation)
*/
if (!$code = $db->sql_escape($url[1])) {
message_die(HACK_ERROR, "/page/ must be followed by page code");
}
//
// Handles editor form
//
if ($_POST['code']) {
//Ask flag admin.pages.editor
$CurrentPerso->request_flag('admin.pages.editor');
-
+
//Gets version
$sql = "SELECT MAX(page_version) + 1 FROM " . TABLE_PAGES_EDITS .
" WHERE page_code = '$code'";
if (!$result = $db->sql_query($sql)) message_die(SQL_ERROR, "Can't fetch pages", '', __LINE__, __FILE__, $sql);
$row = $db->sql_fetchrow($result);
$page_version = ($row[0] == "") ? 0 : $row[0];
-
+
//Gets other fields
$page_code = $db->sql_escape($code);
$page_title = $db->sql_escape($_POST['title']);
$page_content = $db->sql_escape($_POST['content']);
$page_edit_reason = $db->sql_escape($_POST['edit_reason']);
$page_edit_user_id = $CurrentPerso->user_id;
$page_edit_time = time();
-
+
//Saves archive version
$sql = "INSERT INTO " . TABLE_PAGES_EDITS . " (`page_code`, `page_version`, `page_title`, `page_content`, `page_edit_reason`, `page_edit_user_id`, `page_edit_time`) VALUES ('$page_code', '$page_version', '$page_title', '$page_content', '$page_edit_reason', '$page_edit_user_id', '$page_edit_time')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't save page", '', __LINE__, __FILE__, $sql);
}
-
+
//Saves prod version
$sql = "REPLACE INTO " . TABLE_PAGES . " (`page_code`, `page_title`, `page_content`) VALUES ('$page_code', '$page_title', '$page_content')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't save page", '', __LINE__, __FILE__, $sql);
}
-
+
$smarty->assign('NOTIFY', "Page $page_code saved, version $page_version.");
}
//
// Gets page
//
$sql = "SELECT page_title, page_content, page_code FROM " . TABLE_PAGES . " WHERE page_code LIKE '$code'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Can't get pages", '', __LINE__, __FILE__, $sql);
$row = $db->sql_fetchrow($result);
-switch ($_GET['mode']) {
+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:
+
+ 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');
+include('header.php');
//Serves content
$smarty->display($template);
//Serves footer
include('footer.php');
-
+
?>
\ No newline at end of file
diff --git a/controllers/persorequest.php b/controllers/persorequest.php
index b43694a..5814bfc 100644
--- a/controllers/persorequest.php
+++ b/controllers/persorequest.php
@@ -1,168 +1,168 @@
<?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
*
* @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 {
+} else {
///
/// HTML output
///
-
+
//Serves header
define('DOJO', true);
$smarty->assign('PAGE_TITLE', lang_get('PersoRequests'));
- include('header.php');
-
+ include('header.php');
+
//Serves content
$smarty->assign('requests', $requests);
$smarty->display('persorequests.tpl');
-
+
//Serves footer
$smarty->assign("screen", "Perso requests");
include('footer.php');
-
+
//Dies
exit;
}
?>
\ No newline at end of file
diff --git a/controllers/profile.php b/controllers/profile.php
index 3f4e002..2b293a2 100644
--- a/controllers/profile.php
+++ b/controllers/profile.php
@@ -1,346 +1,346 @@
<?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/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'));
+ $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';
+ $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');
-
+
?>
\ No newline at end of file
diff --git a/controllers/raw.php b/controllers/raw.php
index 4431fcf..3a6cf97 100644
--- a/controllers/raw.php
+++ b/controllers/raw.php
@@ -1,63 +1,63 @@
<?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
* - 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');
?>
\ No newline at end of file
diff --git a/controllers/request.php b/controllers/request.php
index 4ccd910..da796f2 100644
--- a/controllers/request.php
+++ b/controllers/request.php
@@ -1,95 +1,95 @@
<?php
/**
* Requests controller
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* This controller allows the perso to send requests to the HyperShip,
* to a specified ship, or to a specify port requiring PTA.
*
* It handles all the forms output, handling and notifications
* for queries from users to users.
*
* It handles /request URL, is called from tutorial.
*
* @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 complete requests implementation
* @todo call this controller from Ship fly out if port is a PTA
* @todo call this controller from HyperShip entrance perso request
* @todo add hook to launch some events on a new request, reply or status change.
*/
//
// Prepare fields
//
if (count($url) < 3) message_die(HACK_ERROR, "Expected URL: /request/code_to/code_object");
//
// Handles or print form
//
if (false) {
//Saves the request reply
} elseif ($_POST['title'] || $_POST['message']) {
//Saves the request
require_once('includes/objects/request.php');
$request = new Request();
$request->load_from_form();
$request->author = $CurrentPerso->id;
$request->to = $url[1];
$request->code = $url[2];
$request->location_global = $CurrentPerso->location_global;
$request->location_local = $CurrentPerso->location_local;
$request->save_to_database();
//Confirmation
$template = "requests/confirm.tpl";
} else {
$request->to = $url[1];
$request->obj = $url[2];
//Checks if the request template exists
if (!file_exists(sprintf("skins/%s/requests/%s.tpl", THEME, $request->obj))) {
message_die(HACK_ERROR, "$url[2] isn't a valid request object code");
}
$template = "requests/$request->obj.tpl";
switch ($request->obj) {
case "aid.reach":
if ($request->to == "B00001")
$request->title = "Shuttle pick up request";
break;
}
}
//
// HTML output
//
//Serves header
define('DIJIT', true);
$smarty->assign('PAGE_TITLE', lang_get('Request'));
include('header.php');
//Serves content
$smarty->assign('request', $request);
$smarty->display($template);
//Serves footer
$smarty->assign("screen", "$url[2] request");
include('footer.php');
-
+
?>
\ No newline at end of file
diff --git a/controllers/settings.php b/controllers/settings.php
index 8fb8482..3374cb8 100644
--- a/controllers/settings.php
+++ b/controllers/settings.php
@@ -1,97 +1,97 @@
<?php
/**
* Settings
*
* Zed. The immensity of stars. The HyperShip. The people.
- *
+ *
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* This controller allows user to set its preferences, according the Settings
* classes and the preferences.xml document.
*
* It handles the /settings URL.
*
* @package Zed
* @subpackage Controllers
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*
* @todo replace the on the fly preferences.xml code generation by a cached code generation
* @todo reduce the number of for loops in this controller
*/
//
// Loads settings
//
lang_load('settings.conf');
include('includes/settings/settings.php');
$settings = new Settings('includes/settings/preferences.xml');
//Selects relevant settings page
$pages = $settings->pages;
if (count($url) > 1) {
//From url: /settings/account -> page account
if (array_key_exists($url[1], $settings->pages)) {
$page = $pages[$url[1]];
} else {
message_die(GENERAL_ERROR, "/settings/$url[1] isn't a valid setting page");
}
} else {
//Default page
$page = array_shift($pages);
}
//Pages links
foreach ($settings->pages as $tmppage) {
$pagesLinks[$tmppage->id] = $tmppage->title;
}
//
// Handles form
//
if (array_key_exists('settings_page', $_POST)) {
if ($_POST['settings_page'] == $page->id) {
//Updates settings
$errors = array();
$page->handle_form($errors);
if (count($errors)) {
//Prints error message
$smarty->assign('WAP', implode('<br />', $errors));
}
} else {
//The field settings.page isn't the current page
//Prints an HACK_ERROR to avoid to save properties with the same names.
$id_current = $page->id;
$id_toSave = $_POST['settings_page'];
message_die(HACK_ERROR, "You're on /settings/$id_current but you want to update /settings/$id_toSave");
}
}
//
// HTML output
//
//Serves header
define('DIJIT', true);
$title = lang_get('Settings');
$smarty->assign('PAGE_TITLE', $title);
include('header.php');
//Serves settings page;
$smarty->assign('page', $page);
$smarty->assign('pages', $pagesLinks);
$smarty->display('settings_page.tpl');
//Servers footer
include('footer.php');
?>
\ No newline at end of file
diff --git a/controllers/ship.php b/controllers/ship.php
index e6c2124..8e2e24a 100644
--- a/controllers/ship.php
+++ b/controllers/ship.php
@@ -1,91 +1,91 @@
<?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
if (!$code = $CurrentPerso->location->ship_code) {
message_die(GENERAL_ERROR, "/ship/ must be followed by valid ship code.<br />/ship alone only works when you're aboard a ship", "URL error");
}
$code = 'S' . $code;
} else {
//Code have been specified
$code = $url[1];
if (!preg_match("/^S[0-9]{5}$/", $code)) {
message_die(GENERAL_ERROR, "/ship/ must be followed by valid ship code", "URL error");
}
}
//Gets ship information
$ship = Ship::get($code);
//Gets perso note about this ship
$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');
+include('header.php');
//Serves content
$smarty->assign('note', $note);
$smarty->assign('ship', $ship);
$smarty->display('ship.tpl');
//Serves footer
include('footer.php');
-
+
?>
\ No newline at end of file
diff --git a/controllers/story.php b/controllers/story.php
index ba8fbc9..42394a7 100644
--- a/controllers/story.php
+++ b/controllers/story.php
@@ -1,131 +1,131 @@
<?php
/**
* Story
*
* Zed. The immensity of stars. The HyperShip. The people.
- *
+ *
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* This controller is a storytelling engine allowing to explore a place like
* in fighting fantasy gamebooks / livres dont vous êtes le héros.
*
* This controller is called by the explore controller and handles /explore URL.
*
* It uses the Story classes, the story.tpl view and content/stories/*.xml as
* stories content datasource.
*
* @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 Create a separate release from Zed based on this controller and the Story library.
* @todo Add code to handle actions defined in choices like inventory management
*/
//
// Helper method
//
/**
* Gets section to print to the user
* @param Story the story the section to get (yep, we could've global $story)
* @return StorySection the section, or null if not found
*/
function get_section ($story) {
global $url, $smarty, $CurrentPerso;
-
+
//If the URL contains a choice guid, use it as story progress source
//e.g. /explore/143f7200-766b-7b8b-e3f4-9fbfeeaeb5dd
if (count($url) > 1) {
$guid = $url[1];
-
+
//Ensures we've a StorySection object in the Story variable
if (!array_key_exists('StoryChoices', $_SESSION)) {
$smarty->assign('WAP', lang_get('ExpiredStorySession'));
} else {
//Gets StoryChoice (creating a dummy section to use get_choice method)
$section = new StorySection("void");
$section->choices = $_SESSION['StoryChoices'];
if (!$choice = $section->get_choice($guid)) {
$smarty->assign('WAP', lang_get('InvalidStoryGUID'));
}
-
+
//TODO: add code here to handle actions defined in choices
//e.g. item added to inventory
-
+
//Gets section
if ($section_id = $choice->goto) {
if (!array_key_exists($section_id, $story->sections)) {
message_die(GENERAL_ERROR, "Choice <em>$choice->text</em> redirects to <em>$section_id</em> but this section doesn't exist.", "Story error");
}
return $story->sections[$section_id];
}
}
}
-
+
if (!$CurrentPerso->location_local) {
//Gets start section
return $story->get_start_section();
}
-
+
//Gets section matching perso location
return $story->get_section_from_location($CurrentPerso->location_local);
}
//
// Opens .xml file
//
$file = STORIES_DIR . '/' . $CurrentPerso->location_global . '.xml';
if (!file_exists($file)) {
message_die(GENERAL_ERROR, "If you want to write a story for this place, contact Dereckson — $file", "No story defined");
}
//
// Gets story
//
//Loads story and tries to get the section
require_once('includes/story/story.php');
$story = new Story($file);
$section = get_section($story);
//Ensures we've a section
if (!$section) {
message_die(GENERAL_ERROR, "Nothing to do at this location. Contact Dereckson if you think it's a bug or you want to write a story here.", "Story");
}
//Performs section actions
if ($section->location_local) {
//Moves perso to section local location
$CurrentPerso->move_to(null, $section->location_local);
}
//Saves section in session, for choices handling
$_SESSION['StoryChoices'] = $section->choices;
//
// HTML output
//
//Serves header
$smarty->assign('PAGE_TITLE', $story->title);
include('header.php');
//Serves content
$smarty->assign("section", $section);
$smarty->display('story.tpl');
//Serves footer
$smarty->assign('screen', "Story, section $section->id");
include('footer.php');
-
+
?>
\ No newline at end of file
diff --git a/controllers/usersearch.php b/controllers/usersearch.php
index 666700d..d19c5c8 100644
--- a/controllers/usersearch.php
+++ b/controllers/usersearch.php
@@ -1,119 +1,119 @@
<?php
/**
* User search
*
* Zed. The immensity of stars. The HyperShip. The people.
- *
+ *
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* This is a controller doing nothing else than call header and footer.
*
* The controller uses the usersearch.tpl and directory views (cf. Azhàr code)
*
* Not yet implemented, It should handle /users URL
*
* @package Zed
* @subpackage Controllers
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*
* @todo implement it
*/
//Libs
require_once('includes/objects/ProfilePhoto.php');
//
// Does the search
//
//Search type
switch ($resource = $url[1]) {
case '':
-
+
break;
-
+
case 'online':
$sql = "SELECT u.username, u.user_id, u.user_longname FROM " .
TABLE_USERS . " u, " . TABLE_SESSIONS .
" s WHERE s.online = 1 AND u.user_id = s.user_id
ORDER BY HeureLimite DESC";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to query the table", '', __LINE__, __FILE__, $sql);
}
$i = 0;
while ($row = $db->sql_fetchrow($result)) {
$users[$i]->id = $row['user_id'];
$users[$i]->username = $row['username'];
$users[$i]->longname = $row['user_longname'];
$i++;
}
$title = sprintf(lang_get('UsersOnline'), $i, s($i));
break;
-
+
case 'directory':
$sql = 'SELECT username, user_longname FROM ' . TABLE_USERS .
' WHERE user_active < 2 ORDER by user_longname ASC';
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to query the table", '', __LINE__, __FILE__, $sql);
}
$i = 0;
while ($row = $db->sql_fetchrow($result)) {
$users[$i]->username = $row['username'];
$users[$i]->longname = $row['user_longname'];
$i++;
}
$title = lang_get('Directory');
$mode = 'directory';
break;
-
+
default:
$smarty->assign('WAP', lang_get('Nay'));
break;
}
switch ($mode) {
case 'directory':
$template = 'directory.tpl';
$smarty->assign('USERS', $users);
break;
-
+
default:
//Prepares avatars
if (count($users)) {
foreach ($users as $user) {
$name = $user->longname ? $user->longname : $user->username;
$user->avatar = ProfilePhoto::get_avatar($user->id, $name);
}
}
$template = 'usersearch.tpl';
$smarty->assign('TITLE', $title);
$smarty->assign('USERS', $users);
break;
}
//
// HTML output
//
//Serves header
$smarty->assign('PAGE_CSS', 'usersearch.css');
$smarty->assign('PAGE_TITLE', $title);
include('header.php');
-
+
//Serves content
if ($template)
$smarty->display($template);
//Serves footer
include('footer.php');
-
+
?>
\ No newline at end of file
diff --git a/controllers/void.php b/controllers/void.php
index ccb25a9..d4a75e1 100644
--- a/controllers/void.php
+++ b/controllers/void.php
@@ -1,37 +1,37 @@
<?php
/**
* Void content
*
* Zed. The immensity of stars. The HyperShip. The people.
- *
+ *
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* This is a controller doing nothing else than call header and footer.
*
* @package Zed
* @subpackage Controllers
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
//
// HTML output
//
//Serves header
$smarty->assign('PAGE_TITLE', $title);
include('header.php');
//Doesn't serve any content;
//Servers footer
include('footer.php');
-
+
?>
\ No newline at end of file
diff --git a/cron.php b/cron.php
index 776c200..690abe0 100644
--- a/cron.php
+++ b/cron.php
@@ -1,57 +1,57 @@
<?php
/**
* Cron
*
* Zed. The immensity of stars. The HyperShip. The people.
- *
+ *
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* This file contains tasks to execute periodically.
* When editing this file, ensure it works from the command line, so it's
* possible to run it from a crontab calling PHP CLI.
- *
+ *
* @package Zed
* @subpackage Utilities
* @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 Adds some periodicity (e.g. hourly, daily, monthly)
*/
////////////////////////////////////////////////////////////////////////////////
///
/// Initialization
///
//Pluton library
include('includes/core.php');
//Debug mode?
$debug = false;
////////////////////////////////////////////////////////////////////////////////
///
/// Daily tasks
///
//Orders perso table by nickname.
//Rationale: prints an ordered perso select list, help for new persos, printed at end
$queries[] = "ALTER TABLE " . TABLE_PERSOS . " ORDER BY perso_nickname";
////////////////////////////////////////////////////////////////////////////////
///
/// Executes tasks
///
foreach ($queries as $query) {
if (!$db->sql_query($sql) && $debug)
message_die(SQL_ERROR, "Can't execute query", '', __LINE__, __FILE__, $sql);
}
?>
\ No newline at end of file
diff --git a/css/layout.css b/css/layout.css
index 0f71542..482efca 100644
--- a/css/layout.css
+++ b/css/layout.css
@@ -1,523 +1,523 @@
/*
-----------------------------------------------
Grey Box Method - Layout CSS
----------------------------------------------- */
body {
background: #eee;
border-top: 5px solid #000;
color: #333;
font-size: 11px;
padding: 0 0 40px;
}
/* anchors
----------------------------------------------- */
a {
color: #000;
font-weight:bold;
text-decoration: none;
}
a:hover {
color:#333;
}
/* 960 grid system container background
----------------------------------------------- */
.container_12,
.container_16 {
background:#fff;
}
/* headings
----------------------------------------------- */
h1, h2, h3, h4, h5, h6 {line-height:1.2em; margin-bottom:.3em;}
h2 {margin-top:1em;}
h5 {font-size:1.2em;}
h6 {font-size:1em; text-transform:uppercase;}
h1 a {
font-weight:normal;
}
/* branding
----------------------------------------------- */
h1#branding {
font-weight:normal;
font-size:3em;
text-align:left;
background:#aaa;
padding:.7em 1em;
margin-bottom:0;
}
/* page heading
----------------------------------------------- */
h2#page-heading {
font-weight:normal;
padding:.5em;
margin:0 0 10px 0;
border-bottom:1px solid #ccc;
}
/* boxes
----------------------------------------------- */
.box {
background:#ddd;
margin-bottom:20px;
padding:10px 10px 1px 10px;
}
.box h2 {
font-size:1em;
font-weight:normal;
text-transform:uppercase;
color:#fff;
background:#333;
margin:-10px -10px 0 -10px;
padding:6px 12px;
}
.box h2 a,
.box h2 a.visible {
color:#fff;
background:#333 url("../img/switch_minus.gif") 97% 50% no-repeat;
display:block;
padding:6px 12px;
margin:-6px -12px;
border:none;
}
.grid_4 .box h2 a {
background-position: 97% 50%;
}
.grid_5 .box h2 a {
background-position: 98% 50%;
}
.grid_12 .box h2 a {
background-position: 99% 50%;
}
.box h2 a.hidden,
.box h2 a.hidden:hover {
background-image: url("../img/switch_plus.gif");
}
.box h2 a:hover {
background-color:#111;
}
.block {
padding-top:10px;
}
div.menu {
padding:0;
}
div.menu h2 {
margin:0;
}
div.menu .block {
padding-top:0;
}
/* paragraphs, quotes and lists
----------------------------------------------- */
p {
margin-bottom:1em;
}
blockquote {
font-family: Georgia, 'Times New Roman', serif;
font-size:1.2em;
padding-left:1em;
border-left:4px solid #ccc;
}
blockquote cite {
font-size:.9em;
}
ul, ol {
padding-top:0;
}
/* menus
----------------------------------------------- */
ul.menu {
list-style:none;
border-top:1px solid #bbb;
}
ul.menu li {
margin:0;
}
ul.menu li a {
display:block;
padding:4px 10px;
border-bottom:1px solid #ccc;
}
ul.menu li a:hover {
background:#eee;
}
ul.menu li a:active {
background:#ccc;
}
/* submenus
----------------------------------------------- */
ul.menu ul {
list-style:none;
margin:0;
}
ul.menu ul li a {
padding-left:30px;
}
/* section menus
----------------------------------------------- */
ul.section {
border-top:0;
margin-bottom:0;
}
ul.section li {
text-transform:uppercase;
}
ul.section li a {
background:#bbb;
}
ul.section li a:hover {
background:#aaa;
}
ul.section li a:active {
color:#fff;
background:#666;
}
ul.section li li a {
background:#ddd;
border-bottom:1px solid #eee;
}
ul.section li li a:hover {
background:#ccc;
}
ul.section li li a:active {
color:#000;
background:#fff;
}
ul.section ul li {
text-transform:none;
}
ul.section ul.current li a {
background:#eee;
border-bottom:1px solid #fff;
}
ul.section ul.current li a:hover {
background:#ddd;
}
ul.section ul.current li a:active {
background:#fff;
}
ul.section li a.current {
color:#fff;
background:#666;
}
ul.section li a.current:hover {
background:#555;
}
ul.section li a.current:active {
background:#444;
}
ul.section li a.active {
background:#fff;
cursor:default;
}
ul.section li.current > a.active,
ul.section li.current > a.active:hover {
color:#fff;
background:#666;
cursor:default;
}
/* table
----------------------------------------------- */
table {
width:100%;
border:1px solid #bbb;
margin-bottom:10px;
}
col.colC {
width:8em;
}
th, td {
padding:.2em 1em;
text-align:left;
}
thead th {
border-bottom:2px solid #888;
background:#bbb;
padding:.4em 1em .2em;
}
thead th.table-head {
font-size:1em;
font-weight:normal;
text-transform:uppercase;
color:#fff;
background:#555;
border:1px solid #555;
}
tbody th,
tbody td {
border-top:1px solid #bbb;
border-bottom:1px solid #bbb;
background:#eee;
}
tbody tr.odd th,
tbody tr.odd td {
background:#fff;
}
tfoot th,
tfoot td {
border-top:2px solid #666;
background:#eee;
}
tfoot tr.total th,
tfoot tr.total td {
border-top:6px double #666;
}
tfoot tr.total th {
text-transform:uppercase;
}
th.currency,
td.currency {
text-align:right;
}
/* forms
----------------------------------------------- */
form {
overflow:hidden;
}
fieldset {
border:1px solid #bbb;
padding:10px;
position:relative;
background:#e9e9e9;
margin-bottom:10px;
}
legend {
font-size:1.1em;
padding:.4em .8em;
background:#fff;
border:1px solid #bbb;
}
fieldset.login p {
margin-bottom:1em;
margin-top:0pt;
}
fieldset p label {
width:98%;
}
fieldset p input {
width:98%;
}
fieldset p select {
width:99%;
}
fieldset.login p label {
float:left;
line-height:2em;
margin-right:3%;
text-align:right;
width:32%;
}
fieldset.login p input {
width:60%;
}
fieldset.login input.button {
margin-left:35%;
}
form p.notice {
font-weight:bold;
}
input.search.text {
width:66%;
}
input.search.button {
width:28%;
margin-left:2%;
}
/* articles
----------------------------------------------- */
.articles {
padding:0;
}
.articles h2 {
margin:0;
}
#articles {
padding-top:0;
}
.article {
border-top:1px solid #666;
padding-top:.5em;
}
.box .article {
border-top:3px solid #fff;
padding:13px 10px 0 10px;
}
.article h2 {
font-size:2em;
font-weight:normal;
text-transform:none;
color:#333;
background:transparent;
padding:0;
margin:0;
border:none;
}
.article h3 {
margin-bottom:.2em;
font-size:1.6em;
}
.box .first {
border-top:none;
}
.article h4 {
font-size:1.2em;
text-transform:uppercase;
margin-bottom:.5em;
}
.article a.image {
- float:left;
- margin:3px 10px 3px 0;
+ float:left;
+ margin:3px 10px 3px 0;
padding:4px;
border:1px solid #bbb;
background:#fff;
}
.article a.image:hover {
border:1px solid #666;
}
.article a.image img {
- float:left;
+ float:left;
}
.article p.meta {
color:#666;
border-top:1px dotted #999;
border-bottom:1px dotted #999;
padding:.3em 0;
margin-bottom:.8em;
}
/* site information
----------------------------------------------- */
#site_info .box {
color:#ccc;
background:#666;
margin-bottom:10px;
}
#site_info a {
color:#fff;
}
#site_info a:hover {
color:#000;
}
/* AJAX sliding shelf
----------------------------------------------- */
#loading {float:right; margin-right:14px; margin-top:-2px;}
.block {padding-bottom:1px;}
/* Accordian
----------------------------------------------- */
.toggler {
color: #222;
margin: 0;
padding: 2px 5px;
background: #eee;
border-bottom: 1px solid #ddd;
border-right: 1px solid #ddd;
border-top: 1px solid #f5f5f5;
border-left: 1px solid #f5f5f5;
font-size:1.1em;
font-weight: normal;
}
.element h4 {
margin: 0;
padding:4px;
line-height:1.2em;
}
.element p {
margin: 0;
padding: 4px;
}
.float-right {
padding:10px 20px;
float:right;
}
#accordian-block {
padding-bottom:10px;
}
/* Mootools Kwicks
----------------------------------------------- */
-#kwick-box {
+#kwick-box {
padding:0;
overflow:hidden;
}
-#kwick-box h2 {
+#kwick-box h2 {
margin:0;
}
#kwick {
position: relative;
}
#kwick .kwicks {
display: block;
background: #999;
height: 470px;
list-style:none;
margin:0;
overflow:hidden;
}
#kwick li {
float: left;
margin:0;
padding:0;
}
#kwick .kwick {
display: block;
cursor: pointer;
overflow: hidden;
height: 470px;
width: 215px;
padding: 10px;
background: #fff;
}
#kwick .kwick span {
color:#fff;
}
#kwick .one {
background: #666;
background-image: url(../img/tour/What.jpg);
}
#kwick .two {
background: #777;
}
#kwick .three {
background: #888;
-
+
}
#kwick .four {
background: #999;
background-image: url(../img/tour/Where.jpg);
}
diff --git a/css/zed/login.css b/css/zed/login.css
index 7de7ac6..b911b48 100644
--- a/css/zed/login.css
+++ b/css/zed/login.css
@@ -1,122 +1,122 @@
@charset "utf-8";
/* -------------------------------------------------------------
Zed
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Author: Dereckson
Tags: space retro futurist
Filename: login.css
Version: 1.0
Created: 2010-01-27
Updated: 2010-02-09
Licence: Creative Commons BY 3.0
------------------------------------------------------------- */
/* -------------------------------------------------------------
Page
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
body {
margin: 0 0 0 0;
background-color: #343434;
font-family: "FixedSys", monospace;
}
/* -------------------------------------------------------------
Login form
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#LoginBox {
background-image: url("../../img/login/bg.jpg");
width: 341px;
height: 516px;
margin: 0 auto 0 auto;
}
#LoginBox label { display:none; }
#LoginBox input {
width: 150px;
font-weight: 900;
border: none;
background-color: #3b3f55;
color: white;
}
#LoginBox #username {
position: relative;
top: 250px;
left: 150px;
}
#LoginBox #password {
position: relative;
top: 300px;
left: 150px;
}
#LoginBox #openid {
position: relative;
top: 390px;
width: 230px;
left: 50px;
-
+
/* OpenID */
background-image: url("../../img/login/openid.png");
background-position: 0% 50%;
background-repeat: no-repeat;
padding-left: 20px;
}
#LoginBox #submit {
position: relative;
top: 420px;
left: 250px;
width: 50px;
}
-
+
.error {
position: relative;
width: 290px;
margin: 0 10px 0 10px;
text-align: right;
color: #3b3f55;
top: 274px;
}
/* -------------------------------------------------------------
Bottom right vertical links
-
+
Inspiration: mono lab "monochrome" wordpress theme
http://www.mono-lab.net
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#link_tour a {
position: absolute;
position: fixed;
right: 15px;
bottom: 15px;
width: 18px;
height: 84px;
display: block;
background: url("../../img/login/tour.png") no-repeat left top;
}
#link_tour a:hover {
background:url("../../img/login/tour.png") no-repeat right top;
}
#link_blog a {
position:absolute;
position:fixed;
right:35px;
bottom:15px;
width:18px;
height:84px;
display:block;
background:url("../../img/login/blog.png") no-repeat left top;
}
#link_blog a:hover {
background:url("../../img/login/blog.png") no-repeat right top;
}
\ No newline at end of file
diff --git a/css/zed/profile.css b/css/zed/profile.css
index fd8f51d..9b9c21c 100644
--- a/css/zed/profile.css
+++ b/css/zed/profile.css
@@ -1,140 +1,140 @@
@charset "utf-8";
/* -------------------------------------------------------------
Zed
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Author: Dereckson
Tags: space retro futurist
Filename: profile.css
Version: 1.0
Created: 2010-01-27
Updated: 2010-02-11
Licence: Creative Commons BY 3.0
------------------------------------------------------------- */
/* -------------------------------------------------------------
Profile header
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
.profile_id {
height: 40px;
line-height: 1.2em;
background-color: black;
color: white;
}
.profile_id H1 {
color: #04acf8;
}
.profile_info {
float: right;
font-size: 0.90em;
padding-right: 1em;
}
.profile_info a {
color: white;
}
.profile_info a:hover {
color: white;
font-weight: bold;
}
.profile_nick {
float: left;
margin-top: 0;
height: 30px;
padding-left: 12px;
padding-top: 10px;
font-size: 1.25em;
font-weight: 500;
border-left: solid #04acf8 6px;
}
/* -------------------------------------------------------------
Profile
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
.profile {
background-color: black;
color: white;
margin-bottom: 20px;
border: 2px solid #04acf8;
}
.profile_text, .profile_message, .profile_tags {
margin-left: 10px;
margin-right: 10px;
}
.profile_text {
padding-top: 1em;
font-size: 1em;
text-align: justify;
}
.profile_text img {
border: 0px;
}
.profile_text.fixedwidth {
font-family: "Fixedsys Excelsior 3.01", Fixedsys, Fixed;
white-space: pre;
}
.profile_separator_light {
height: 1em;
border-bottom: 1px solid #04acf8;
}
.profile_tags dt {
font-weight: 900;
color: #04acf8;
}
.profile_tags dd {
text-align: justify;
}
/* -------------------------------------------------------------
Profile comments
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
+
.profile_comments {
background-color: #fafafa;
- border: solid 1px #dedede;
+ border: solid 1px #dedede;
}
.profile_comments_info {
font-style: italic;
}
.profile_comments_text {
font-size: 1.25em;
}
/* -------------------------------------------------------------
Profile editor
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
+
.photos {
}
.photo img {
margin: 8px 0px 12px 20px;
border: 0;
}
.photo {
float: left;
}
/* -------------------------------------------------------------
Profile sidebar
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#sidebar {
color: white;
}
diff --git a/css/zed/theme.css b/css/zed/theme.css
index 6abeb56..a123a22 100644
--- a/css/zed/theme.css
+++ b/css/zed/theme.css
@@ -1,417 +1,417 @@
@charset "utf-8";
/* -------------------------------------------------------------
Zed
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Author: Dereckson
Tags: space retro futurist
Filename: theme.css
Version: 1.1
Created: 2010-01-27
Updated: 2010-07-02
Licence: Creative Commons BY 3.0
------------------------------------------------------------- */
/* -------------------------------------------------------------
Page settings
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
body {
margin: 0.5em 0 0 0;
-
+
background-attachment: fixed;
background-color: #343434;
background-image: url("../../img/zed/bg.jpg");
background-position: top left;
background-repeat: no-repeat;
font-family: "Calibri", "Lucida Sans Unicode", "Trebuchet MS", "Helvetica", "Arial", sans-serif;
min-height: 1200px;
}
.container_16 {
color: white;
}
h1 {
color: #19B5E7;
font-size: 21px;
font-weight: normal;
}
h2, h3, h4, h5, h6 {
color: #04acf8;
font-weight: normal;
}
h2 {
font-size: 19px;
}
h3 {
color: #04acf8;
font-size: 16px;
}
pre {
font-family: FixedSys, monospace;
}
/* -------------------------------------------------------------
Links
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
a {
color: #1AC8E8;
text-decoration: none;
}
a:visited {
color: gray;
}
a:hover {
color: red;
text-decoration: none;
}
/* -------------------------------------------------------------
Notify messages
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
.notify {
padding-top: 25px;
padding-bottom: 25px;
margin-bottom: 10px;
-
+
text-align: center;
background: #eeeeee;
font-size: 1.5em;
color: black;
-
+
border: 5px solid #1AC8E8;
width: 950px;
}
.wap {
padding-top: 50px;
padding-bottom: 50px;
- margin-bottom: 10px;
-
+ margin-bottom: 10px;
+
text-align: center;
background: #eeeeee;
font-size: 2em;
color: black;
border: 5px solid indianred;
width: 950px;
-
+
}
/* -------------------------------------------------------------
Header
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#header {
background-image: url("../../img/zed/bg_header.png");
background-repeat: no-repeat;
margin: auto auto;
margin-bottom: 0.5em;
height: 104px;
width: 978px;
}
#header_content {
padding-top: 26px;
}
#HypershipTime {
color: white;
font-size: 0.8em;
background-image: url("../../img/zed/time.png");
background-position: center left;
background-repeat: no-repeat;
text-indent: 2em;
}
/* -------------------------------------------------------------
Header - wall
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
.wall {
text-align: left;
float:left;
color: white;
font-size: 0.8em;
background-image: url("../../img/zed/quote.png");
background-position: top left;
background-repeat: no-repeat;
text-indent: 2em;
margin-bottom: 0.8em;
}
.wall_info {
display: block;
text-align: right;
/* font-size: 80%; */
}
.wall a {
color: #a9a49e;
}
.wall a:hover {
color: #fd9800;
}
/* -------------------------------------------------------------
Content (e.g. stories in /explore)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
.content_wrapper {
background-color: #171717;
border: solid 5px black;
margin-bottom: 1em;
}
.content_wrapper .content {
padding: 0 2em 0 2em;
color: white;
}
.content_wrapper H1 {
margin-top: 0;
padding: 0.25em 0 0.75em 1em;
background-color: black;
height: 1em;
}
/* -------------------------------------------------------------
Avatars wall
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
+
.avatar {
float: left;
margin-bottom: 2em;
margin-right: 2em;
text-align: center;
}
.avatar img {
border: solid 1px;
}
.avatar_name {
display: block;
}
.avatar a:hover {
color: white;
}
/* -------------------------------------------------------------
Messages
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
+
.message {
margin-bottom: 17px;
padding: 8px 9px 8px 9px;
width: 940px;
font-size: 80%;
}
.message.light {
background-color: #fafafa;
border: 3px solid #dedede;
width: 938px;
color: black;
}
.message.light a {color: #343434;}
.message.dark {
background-color: #acc0c3;
border: solid 3px #4e5758;
width: 938px;
color: #000033;
-
+
}
.message.dark a {color: #154c4c;}
.message a:hover {
font-weight: 900;
}
.message_info {
text-align: right;
margin-bottom: 1em;
}
.message_text {
font-size: 1.25em;
}
.message_info {
color: #343434;
}
/* -------------------------------------------------------------
Helper classes
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
.center {
text-align: center;
}
/* -------------------------------------------------------------
Color boxes
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
.plum {
background-color: plum;
border: 1px solid #800080;
color: black;
}
.plum a { color: #800080; }
.green {
background-color: beige;
border: 1px solid darkgreen;
color: black;
}
.green a { color: darkgreen; }
.skyblue {
background-color: lightskyblue;
border: 1px solid #6e47fe;
}
.skyblue a { color:navy }
.indigo {
background-color: #AE97E1;
border: 1px solid #C97FFF;
-
+
}
.indigo a {color: #800080;}
.yellow {
background-color: #FFFFCC;
border: 1px solid #C4B963;
-
+
}
.yellow a {color: navy;}
.orange {
background-color: #FDD9AC;
border: 1px solid #eaaf67;
}
.orange a {color: #43392e;}
.red {
background-color: #FFE4E1;
border: solid 1px #DC7777;
color: #220000;
-
+
}
.red a {color: #993333;}
.black {
background-color: black;
color: #ccc;
border: solid 2px #555;
}
.plum a:hover,
.green a:hover,
.skyblue a:hover,
.indigo a:hover,
.yellow a:hover,
.orange a:hover,
.red a:hover{
font-weight: bold;
}
/* -------------------------------------------------------------
SmartLine
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#SmartLine {
width: 100%;
}
#SmartLine .left {
-
+
}
#SmartLine .right {
float: right;
text-align: right;
}
/* TODO: ajouter un sélecteur de SmarLine pour chat/commandes (60px) */
/* grid_1 alpha -> sélecteur, grid_3 -> history, grid_12 > bar */
#SmartLineHistory {
width: 115%; /* dépasse de sa bordure */
}
#SmartLineBar{
/* 99.6% for alignment with .message.light */
width: 99.6%;
}
#SmartLineResults {
font-family: "Fixedsys Excelsior 3.01", FixedSys, Terminal;
font-size: 12pt;
}
#SmartLineResults .highlight {
color: #16c3cc;
}
#SmartLineResults .error {
color: red;
}
#SmartLineResults p {
padding-left: 1em;
}
/* -------------------------------------------------------------
Floating panes
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
.floatingPaneTutorial {
width: 957.5px;
margin-bottom: 1em;
color: black;
}
.floatingPaneTutorial a {
color: navy;
}
.floatingPaneTutorial a:hover {
color: #5f0505;
}
.floatingPaneTutorial p {
color: black;
margin: 0;
- padding: 5px 10px 0px 10px;
+ padding: 5px 10px 0px 10px;
}
.dojoxDockList {
color: black;
}
/* -------------------------------------------------------------
Footer
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#footer {
font-size: 80%;
color: white;
}
\ No newline at end of file
diff --git a/dev/objects_viewer.html b/dev/objects_viewer.html
index ffb0fc0..9478e67 100644
--- a/dev/objects_viewer.html
+++ b/dev/objects_viewer.html
@@ -1,219 +1,219 @@
<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
<head>
<title>Zed galaxy :: objects representation</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="Stylesheet" href="../css/zed/theme.css" type="text/css" />
<style type="text/css">
@import "/js/dojo/dojo/resources/dojo.css";
@import "/js/dojo/dijit/tests/css/dijitTests.css";
@import "/js/dojo/dijit/themes/tundra/tundra.css";
-
+
body {
margin-left: auto;
margin-right: auto;
}
-
+
.viewscreen {
width: 500px; height: 500px;
background-color: black;
background-image: url('20081126_heart.jpg');
}
</style>
<script type="text/javascript" src="/js/misc.js" djConfig="isDebug: false"></script>
<script type="text/javascript" src="/js/dojo/dojo/dojo.js" djConfig="isDebug: false"></script>
<script type="text/javascript" src="/js/dojo/dojox/gfx3d/object.js"></script>
<script type="text/javascript" src="/js/dojo/dojox/gfx3d/scheduler.js"></script>
<script type="text/javascript">
dojo.require("dojox.gfx3d");
-
+
viewer = {
angles: {x: 30, y: 30, z: 0},
view: null,
objects: null,
-
+
getObjects: function() {
var url = 'http://zed51.dereckson.be/api.php/coordinates?key=303392c7-97c6-11df-a1e9-000c2923380c&format=json';
-
+
dojo.xhrGet({
handleAs: "json",
url: url,
preventCache: true,
handle: function (response, ioArgs) {
viewer.objects = response;
viewer.drawObjects();
}
});
},
-
+
initialize: function() {
viewer.getObjects();
},
-
+
drawObjects: function () {
viewer.makeObjects();
-
+
//Some cones to help understand the axis rotation
//(thanks Alphos for the tip)
var coneZ = [
- {x: 0, y: 0, z: 15},
+ {x: 0, y: 0, z: 15},
{x: 5, y: 0, z: 0},
{x: 0, y: 5, z: 0},
{x: -5, y: 0, z: 0},
{x: 0, y: -5, z: 0}
];
-
+
var coneX = [
- {x: 15, y: 0, z: 0},
+ {x: 15, y: 0, z: 0},
{x: 0, y: 5, z: 0},
{x: 0, y: 0, z: 5},
{x: 0, y: -5, z: 0},
{x: 0, y: 0, z: -5}
];
-
+
var coneY = [
- {x: 0, y: 15, z: 0},
+ {x: 0, y: 15, z: 0},
{x: 0, y: 0, z: 5},
{x: 5, y: 0, z: 0},
{x: 0, y: 0, z: -5},
{x: -5, y: 0, z: 0}
];
view.createTriangles(coneZ, "fan")
.setStroke({color: "blue", width: 1})
.setFill("blue")
.applyTransform(dojox.gfx3d.matrix.translate({x: 0, y: 0, z: 200}));
-
+
view.createTriangles(coneX, "fan")
.setStroke({color: "red", width: 1})
.setFill("red")
.applyTransform(dojox.gfx3d.matrix.translate({x: 200, y: 0, z: 0}));
-
+
view.createTriangles(coneY, "fan")
.setStroke({color: "green", width: 1})
.setFill("green")
.applyTransform(dojox.gfx3d.matrix.translate({x: 0, y: 200, z: 0}));
-
+
//Zed objects
for (i = 0 ; i < this.objects.length ; i++) {
var object = this.objects[i];
switch (object[1]) {
case 'ship':
//Spaceship -> blue cube
var c = {bottom: object[2], top: {x: object[2].x + 10, y: object[2].y + 10, z: object[2].z + 10}};
view.createCube(c).setFill({ type: "plastic", finish: "dull", color: "blue" });
break;
-
+
case 'hypership':
//Hypership -> Yellow cylinder
var c = {center: object[2], height: 15, radius: 8}
view.createCylinder(c)
.setStroke("black")
.setFill({type: "plastic", finish: "dull", color: "yellow"});
break;
-
+
case 'asteroid':
//Asteroid -> Red orbit
var o = {center: object[2], radius: 8}
view.createOrbit(o)
.setStroke({color: "red", width: 1});
break;
-
+
default:
alert('Not handled object type: ' + object[1]);
-
+
}
}
},
-
+
rotate: function() {
var m = dojox.gfx3d.matrix;
-
+
if(dojo.byId('rx').checked){
viewer.angles.x += 1;
}
if(dojo.byId('ry').checked){
viewer.angles.y += 1;
}
if(dojo.byId('rz').checked){
viewer.angles.z += 1;
}
var t = m.normalize([
m.cameraTranslate(-300, -200, 0),
- m.cameraRotateXg(viewer.angles.x),
- m.cameraRotateYg(viewer.angles.y),
+ m.cameraRotateXg(viewer.angles.x),
+ m.cameraRotateYg(viewer.angles.y),
m.cameraRotateZg(viewer.angles.z)
]);
// console.debug(t);
view.setCameraTransform(t);
view.render();
},
makeObjects: function(){
var surface = dojox.gfx.createSurface("test", 500, 500);
view = surface.createViewport();
-
+
view.setLights([
{ direction: { x: -10, y: -5, z: 5 }, color: "white"}
- ],
+ ],
{ color:"white", intensity: 2 },
"white"
);
-
+
var xaxis = [{x: 0, y: 0, z: 0}, {x: 200, y: 0, z: 0}];
var yaxis = [{x: 0, y: 0, z: 0}, {x: 0, y: 200, z: 0}];
var zaxis = [{x: 0, y: 0, z: 0}, {x: 0, y: 0, z: 200}];
-
+
var m = dojox.gfx3d.matrix;
-
+
view.createEdges(xaxis).setStroke({color: "red", width: 1});
view.createEdges(yaxis).setStroke({color: "green", width: 1});
view.createEdges(zaxis).setStroke({color: "blue", width: 1});
-
+
var camera = dojox.gfx3d.matrix.normalize([
m.cameraTranslate(-300, -200, 0),
- m.cameraRotateXg(this.angles.x),
- m.cameraRotateYg(this.angles.y),
+ m.cameraRotateXg(this.angles.x),
+ m.cameraRotateYg(this.angles.y),
m.cameraRotateZg(this.angles.z)
]);
-
+
view.applyCameraTransform(camera);
view.render();
setInterval(viewer.rotate, 50);
}
};
-
+
dojo.addOnLoad(viewer.initialize);
</script>
</head>
<body class="tundra">
<div style="width: 960px; margin: auto; margin-top: 1em;" class="container_16">
<div style="float: right; width: 400px;">
<h1>Zed objects viewer</h1>
<h2>Objects viewer</h2>
<p>This page shows the different objects in the Zed galaxy.</p>
<p>This is based on the camera rotate <a href="http://archive.dojotoolkit.org/nightly/dojotoolkit/dojox/gfx3d/tests/test_camerarotate_shaded.html">dojox.gfx3d demo</a>.
<br />The background is an <a href="http://www.salzgeber.at/astro/pics/20081126_heart/index.html">Andromeda's planetary nebula</a> from Philipp Salzgeber, under <a rel="license" href="http://creativecommons.org/licenses/by-sa/2.0/at/">CC-BY 2.0 license</a>.</p>
<h2>Controls</h2>
<form>
- <input id="rx" type="checkbox" name="rotateX" checked="true" value="on"/>
+ <input id="rx" type="checkbox" name="rotateX" checked="true" value="on"/>
<label for="rx"> Rotate around X-axis (red)</label> <br/>
- <input id="ry" type="checkbox" name="rotateY" checked="false" value="off"/>
+ <input id="ry" type="checkbox" name="rotateY" checked="false" value="off"/>
<label for="ry"> Rotate around Y-axis (green)</label> <br/>
- <input id="rz" type="checkbox" name="rotateZ" checked="false" value="off"/>
+ <input id="rz" type="checkbox" name="rotateZ" checked="false" value="off"/>
<label for="rz"> Rotate around Z-axis (blue)</label> <br/>
</form>
<h2>Legend</h2>
<ul>
<li>Blue cube: ship</li>
<li>Yellow cylinder: hypership</li>
<li>Red orbit: asteroid</li>
</ul>
</div>
<div id="test" class="viewscreen"></div>
</div>
</body>
</html>
diff --git a/dev/quux.php b/dev/quux.php
index 526af8b..7eada22 100644
--- a/dev/quux.php
+++ b/dev/quux.php
@@ -1,159 +1,159 @@
<?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']);
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::get_coordinates();
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->to_spherical()), ')</td>';
echo '<td>(', implode(', ', $pt->to_spherical2()), ')</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" />
+ <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 42ffa1c..706e443 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.
# 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
+#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/dev/test_content.sql b/dev/test_content.sql
index a66b4a0..4a4f52d 100644
--- a/dev/test_content.sql
+++ b/dev/test_content.sql
@@ -1,56 +1,56 @@
-- Adds two accounts (copyright holders from some of the test content).
-- Login/pass are dereckson / dereckson (1148) and jeronimo / jeronimo (6200)
REPLACE INTO users
(user_id, username, user_password, user_active)
VALUES
(1148, 'dereckson', MD5('dereckson'), 1),
(6200, 'jeronimo', MD5('jeronimo'), 1);
REPLACE INTO persos
(perso_id, perso_name, perso_nickname, perso_race, perso_sex,
user_id, location_global, location_local)
VALUES
(1148, 'Dereckson', 'dereckson', 'human', 'M',
1148, 'B00001001', 'T2C3'),
(6200, 'jeronimo', 'jeronimo', 'human', 'M',
6200, 'B00001002', '(26, -11, -12)');
-- Empties the contents table and inserts content in the repository's info
DELETE FROM content_files WHERE perso_id = 1148 OR perso_id = 6200;
-- [1148] Tower artwork
-- TODO: add T2 content from prod server (into _files and _locations tables)
-- [1148] Composition test files
REPLACE INTO content_files
(content_path, content_title, user_id, perso_id)
VALUES
('users/1148/BlueMetalDrakes.png', 'Blue metal drakes', 1148, 1148),
('users/1148/ktor.png', 'Ktor', 1148, 1148);
-- [1148] Item test (ringbell for tower appartments)
REPLACE INTO content_files
(content_path, content_title, user_id, perso_id)
VALUES
('users/1148/plate.jpg', 'DcK plate', 1148, 1148),
('users/1148/warning.mp3', 'Warning sound', 1148, 1148);
-
+
-- [6200] core Ghost Metro content
REPLACE INTO content_files
(content_path, content_title, user_id, perso_id)
VALUES
('users/6200/ghostmetro-A-01.jpg', 'Ghost Metro, set A, image 1', 6200, 6200),
('users/6200/ghostmetro-A-02.jpg', 'Ghost Metro, set A, image 2', 6200, 6200),
('users/6200/ghostmetro-A-03.jpg', 'Ghost Metro, set A, image 3', 6200, 6200),
('users/6200/ghostmetro-A-04.jpg', 'Ghost Metro, set A, image 4', 6200, 6200),
('users/6200/ghostmetro-A-05-a.jpg', 'Ghost Metro, set A, image 5a', 6200, 6200),
('users/6200/ghostmetro-A-05-b.jpg', 'Ghost Metro, set A, image 5b', 6200, 6200),
('users/6200/ghostmetro-A-05-c.jpg', 'Ghost Metro, set A, image 5c', 6200, 6200),
('users/6200/ghostmetro-A-06.png', 'Ghost Metro, set A, image 6', 6200, 6200),
('users/6200/ghostmetro-A-07.jpg', 'Ghost Metro, set A, image 7', 6200, 6200),
('users/6200/ghostmetro-A-08.jpg', 'Ghost Metro, set A, image 8', 6200, 6200),
('users/6200/ghostmetro-A-09.jpg', 'Ghost Metro, set A, image 9', 6200, 6200),
('users/6200/ghostmetro-A-10.jpg', 'Ghost Metro, set A, image 10', 6200, 6200),
('users/6200/ghostmetro-A-11.jpg', 'Ghost Metro, set A, image 11', 6200, 6200);
\ No newline at end of file
diff --git a/dev/time.html b/dev/time.html
index ae07e6e..c5b26b7 100644
--- a/dev/time.html
+++ b/dev/time.html
@@ -1,82 +1,82 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd"
>
<html lang="en">
<head>
<title>HyperShip Time</title>
<link rel="Stylesheet" href="../css/zed/theme.css" type="text/css" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-
+
<script type="text/javascript" src="/js/dojo/dojo/dojo.js" djConfig="isDebug:false, parseOnLoad: true"></script>
</head>
<body>
<div style="width: 960px; margin: auto; margin-top: 1em;" class="container_16">
<h1 style="font-size: 3em;">Zed</h1>
<h2>HyperShip time</h2>
<script type="text/javascript">
dojo.require("dojox.charting.Chart2D");
dojo.require("dojox.date.php");
dojo.require("dijit.form.NumberSpinner");
-
+
var chartTime;
-
+
//A method to get the decimal part of hypership time
function get_hypership_hour () {
//Gets time
date = new Date();
unixtime = Math.floor(date.getTime() / 1000);
seconds = unixtime - 1278115200;
return Math.floor((seconds % 86400) / 86.4);
}
-
+
// The data to use.
var time = get_hypership_hour();
var timeData = [time, 1000 - time];
-
+
// This function creates the chart, and is really all you
// need. All other code is to allow you to update it on the
// fly.
dojo.addOnLoad(function(){
chartTime = new dojox.charting.Chart2D("timechart");
chartTime.addPlot("default", {
type: "Pie",
fontColor: "white",
labelOffset: 40,
radius: 100
});
chartTime.addSeries("Time", timeData);
dojo.require("dojox.charting.themes.PlotKit.cyan");
chartTime.setTheme(dojox.charting.themes.PlotKit['cyan']);
chartTime.render();
-
+
update_time(chartTime);
});
-
+
function update_time (chart) {
//Updates chart
var time = get_hypership_hour();
chart.updateSeries("Time", [time, 1000 - time]);
chart.render();
-
+
//Updates legend
var now = new Date();
dojo.byId("currentTime").innerHTML = dojox.date.php.format(now, 'H:i');
dojo.byId("currentTimeUTC").innerHTML = now.getUTCHours() + ':' + now.getUTCMinutes();
dojo.byId("currentHyperShipTime").innerHTML = time;
}
-
- </script>
+
+ </script>
<dl>
<dt>Heure actuelle (fuseau local) :</dt>
<dd><span id="currentTime"></span></dd>
<dt>Heure actuelle (fuseau horaire UTC) :</dt>
<dd><span id="currentTimeUTC"></span></dd>
<dt>Heure actuelle (HyperShip Time) :</dt>
<dd><span id="currentHyperShipTime"></span></dd>
</dl>
<div id="timechart" style="width: 300px; height: 300px;"></div>
</div>
</body>
</html>
\ No newline at end of file
diff --git a/includes/SmartLine/SmartLine.php b/includes/SmartLine/SmartLine.php
index 5221dfb..863a19c 100755
--- a/includes/SmartLine/SmartLine.php
+++ b/includes/SmartLine/SmartLine.php
@@ -1,523 +1,523 @@
<?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.
- *
+ *
* 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
*/
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.
//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 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
+ //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)) {
//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.
*
* @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.
*
* 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.
*/
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]);
-
+ $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.
*/
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.
*/
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.
* @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.
*/
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>'.
* @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>'.
*/
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
+ * 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 ")
+
+ //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
*/
/**
* 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);
}
}
}
///////////////////////////////////////////////////////////////////////////////
?>
\ No newline at end of file
diff --git a/includes/SmartLine/ZedCommands.php b/includes/SmartLine/ZedCommands.php
index caa7402..a3cb956 100755
--- a/includes/SmartLine/ZedCommands.php
+++ b/includes/SmartLine/ZedCommands.php
@@ -1,472 +1,472 @@
<?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');
///
/// 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?";
/**
* 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;
-
+ 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)
*/
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
* 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)
*
* 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]");
} else if (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);
}
}
?>
diff --git a/includes/SmartLine/ZedSmartLine.php b/includes/SmartLine/ZedSmartLine.php
index 5f7540d..b86c5c6 100755
--- a/includes/SmartLine/ZedSmartLine.php
+++ b/includes/SmartLine/ZedSmartLine.php
@@ -1,107 +1,107 @@
<?php
/**
* The Zed SmartLine subcontroller.
*
* 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 Caches SmartLine history
*/
///
/// Helpers
///
/**
* Logs a Smartline command
- *
+ *
* @param string $command the command to log
* @param bool $isError indicates if the command is an error
*/
function log_C ($command, $isError = false) {
global $db, $CurrentPerso;
$isError = $isError ? 1 : 0;
$command = $db->sql_escape($command);
$sql = "INSERT INTO " . TABLE_LOG_SMARTLINE . " (perso_id, command_time, command_text, isError)
VALUES ($CurrentPerso->id, UNIX_TIMESTAMP(), '$command', $isError)";
- if (!$db->sql_query($sql))
+ if (!$db->sql_query($sql))
message_die(SQL_ERROR, "Can't log SmartLine command", '', __LINE__, __FILE__, $sql);
}
///
/// Executes command
///
-
+
if ($C = $_REQUEST['C']) {
//Initializes SmartLine object
require_once("SmartLine.php");
$smartLine = new SmartLine();
-
+
require_once("ZedCommands.php");
-
+
//Executes SmartLine
$controller = '';
$smartLine->execute($C);
-
+
$error = $smartLine->count(STDERR) > 0;
-
+
if ($smartLine->count(STDOUT) > 0)
$smarty->assign("SmartLine_STDOUT", $smartLine->gets_all(STDOUT, '', '<br />'));
-
+
if ($error)
$smarty->assign("SmartLine_STDERR", $smartLine->gets_all(STDERR, '', '<br />'));
-
+
if ($controller != '') {
include($controller);
}
-
+
log_C($C, $error);
}
///
/// Gets SmartLine history
///
$perso_id = $db->sql_escape($CurrentPerso->id);
$sql = "SELECT command_time, command_text FROM log_smartline
WHERE isError = 0 AND perso_id = '$perso_id'
ORDER BY command_time DESC LIMIT 100";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't get SmartLine history", '', __LINE__, __FILE__, $sql);
}
$i = 0;
while ($row = $db->sql_fetchrow($result)) {
$commands[$i]['time'] = get_hypership_time($row['command_time']);
$commands[$i]['text'] = $row['command_text'];
$i++;
}
$smarty->assign("SmartLineHistory", $commands);
?>
\ No newline at end of file
diff --git a/includes/Smarty/Smarty.class.php b/includes/Smarty/Smarty.class.php
index 63398b6..3160544 100755
--- a/includes/Smarty/Smarty.class.php
+++ b/includes/Smarty/Smarty.class.php
@@ -1,1518 +1,1518 @@
<?php
/**
* Project: Smarty: the PHP compiling template engine
* File: Smarty.class.php
* SVN: $Id: Smarty.class.php 4614 2012-05-24 15:13:19Z rodneyrehm $
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For questions, help, comments, discussion, etc., please join the
* Smarty mailing list. Send a blank e-mail to
* smarty-discussion-subscribe@googlegroups.com
*
* @link http://www.smarty.net/
* @copyright 2008 New Digital Group, Inc.
* @author Monte Ohrt <monte at ohrt dot com>
* @author Uwe Tews
* @author Rodney Rehm
* @package Smarty
* @version 3.1.10
*/
/**
* define shorthand directory separator constant
*/
if (!defined('DS')) {
define('DS', DIRECTORY_SEPARATOR);
}
/**
* set SMARTY_DIR to absolute path to Smarty library files.
* Sets SMARTY_DIR only if user application has not already defined it.
*/
if (!defined('SMARTY_DIR')) {
define('SMARTY_DIR', dirname(__FILE__) . DS);
}
/**
* set SMARTY_SYSPLUGINS_DIR to absolute path to Smarty internal plugins.
* Sets SMARTY_SYSPLUGINS_DIR only if user application has not already defined it.
*/
if (!defined('SMARTY_SYSPLUGINS_DIR')) {
define('SMARTY_SYSPLUGINS_DIR', SMARTY_DIR . 'sysplugins' . DS);
}
if (!defined('SMARTY_PLUGINS_DIR')) {
define('SMARTY_PLUGINS_DIR', SMARTY_DIR . 'plugins' . DS);
}
if (!defined('SMARTY_MBSTRING')) {
define('SMARTY_MBSTRING', function_exists('mb_strlen'));
}
if (!defined('SMARTY_RESOURCE_CHAR_SET')) {
// UTF-8 can only be done properly when mbstring is available!
/**
* @deprecated in favor of Smarty::$_CHARSET
*/
define('SMARTY_RESOURCE_CHAR_SET', SMARTY_MBSTRING ? 'UTF-8' : 'ISO-8859-1');
}
if (!defined('SMARTY_RESOURCE_DATE_FORMAT')) {
/**
* @deprecated in favor of Smarty::$_DATE_FORMAT
*/
define('SMARTY_RESOURCE_DATE_FORMAT', '%b %e, %Y');
}
/**
* register the class autoloader
*/
if (!defined('SMARTY_SPL_AUTOLOAD')) {
define('SMARTY_SPL_AUTOLOAD', 0);
}
if (SMARTY_SPL_AUTOLOAD && set_include_path(get_include_path() . PATH_SEPARATOR . SMARTY_SYSPLUGINS_DIR) !== false) {
$registeredAutoLoadFunctions = spl_autoload_functions();
if (!isset($registeredAutoLoadFunctions['spl_autoload'])) {
spl_autoload_register();
}
} else {
spl_autoload_register('smartyAutoload');
}
/**
* Load always needed external class files
*/
include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_data.php';
include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_templatebase.php';
include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_template.php';
include_once SMARTY_SYSPLUGINS_DIR.'smarty_resource.php';
include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_resource_file.php';
include_once SMARTY_SYSPLUGINS_DIR.'smarty_cacheresource.php';
include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_cacheresource_file.php';
/**
* This is the main Smarty class
* @package Smarty
*/
class Smarty extends Smarty_Internal_TemplateBase {
/**#@+
* constant definitions
*/
/**
* smarty version
*/
const SMARTY_VERSION = 'Smarty-3.1.10';
/**
* define variable scopes
*/
const SCOPE_LOCAL = 0;
const SCOPE_PARENT = 1;
const SCOPE_ROOT = 2;
const SCOPE_GLOBAL = 3;
/**
* define caching modes
*/
const CACHING_OFF = 0;
const CACHING_LIFETIME_CURRENT = 1;
const CACHING_LIFETIME_SAVED = 2;
/**
* define compile check modes
*/
const COMPILECHECK_OFF = 0;
const COMPILECHECK_ON = 1;
const COMPILECHECK_CACHEMISS = 2;
/**
* modes for handling of "<?php ... ?>" tags in templates.
*/
const PHP_PASSTHRU = 0; //-> print tags as plain text
const PHP_QUOTE = 1; //-> escape tags as entities
const PHP_REMOVE = 2; //-> escape tags as entities
const PHP_ALLOW = 3; //-> escape tags as entities
/**
* filter types
*/
const FILTER_POST = 'post';
const FILTER_PRE = 'pre';
const FILTER_OUTPUT = 'output';
const FILTER_VARIABLE = 'variable';
/**
* plugin types
*/
const PLUGIN_FUNCTION = 'function';
const PLUGIN_BLOCK = 'block';
const PLUGIN_COMPILER = 'compiler';
const PLUGIN_MODIFIER = 'modifier';
const PLUGIN_MODIFIERCOMPILER = 'modifiercompiler';
/**#@-*/
/**
* assigned global tpl vars
*/
public static $global_tpl_vars = array();
/**
* error handler returned by set_error_hanlder() in Smarty::muteExpectedErrors()
*/
public static $_previous_error_handler = null;
/**
* contains directories outside of SMARTY_DIR that are to be muted by muteExpectedErrors()
*/
public static $_muted_directories = array();
/**
* Flag denoting if Multibyte String functions are available
*/
public static $_MBSTRING = SMARTY_MBSTRING;
/**
* The character set to adhere to (e.g. "UTF-8")
*/
public static $_CHARSET = SMARTY_RESOURCE_CHAR_SET;
/**
* The date format to be used internally
* (accepts date() and strftime())
*/
public static $_DATE_FORMAT = SMARTY_RESOURCE_DATE_FORMAT;
/**
* Flag denoting if PCRE should run in UTF-8 mode
*/
public static $_UTF8_MODIFIER = 'u';
-
+
/**
* Flag denoting if operating system is windows
*/
public static $_IS_WINDOWS = false;
-
+
/**#@+
* variables
*/
/**
* auto literal on delimiters with whitspace
* @var boolean
*/
public $auto_literal = true;
/**
* display error on not assigned variables
* @var boolean
*/
public $error_unassigned = false;
/**
* look up relative filepaths in include_path
* @var boolean
*/
public $use_include_path = false;
/**
* template directory
* @var array
*/
private $template_dir = array();
/**
* joined template directory string used in cache keys
* @var string
*/
public $joined_template_dir = null;
/**
* joined config directory string used in cache keys
* @var string
*/
public $joined_config_dir = null;
/**
* default template handler
* @var callable
*/
public $default_template_handler_func = null;
/**
* default config handler
* @var callable
*/
public $default_config_handler_func = null;
/**
* default plugin handler
* @var callable
*/
public $default_plugin_handler_func = null;
/**
* compile directory
* @var string
*/
private $compile_dir = null;
/**
* plugins directory
* @var array
*/
private $plugins_dir = array();
/**
* cache directory
* @var string
*/
private $cache_dir = null;
/**
* config directory
* @var array
*/
private $config_dir = array();
/**
* force template compiling?
* @var boolean
*/
public $force_compile = false;
/**
* check template for modifications?
* @var boolean
*/
public $compile_check = true;
/**
* use sub dirs for compiled/cached files?
* @var boolean
*/
public $use_sub_dirs = false;
/**
* allow ambiguous resources (that are made unique by the resource handler)
* @var boolean
*/
public $allow_ambiguous_resources = false;
/**
* caching enabled
* @var boolean
*/
public $caching = false;
/**
* merge compiled includes
* @var boolean
*/
public $merge_compiled_includes = false;
/**
* cache lifetime in seconds
* @var integer
*/
public $cache_lifetime = 3600;
/**
* force cache file creation
* @var boolean
*/
public $force_cache = false;
/**
* Set this if you want different sets of cache files for the same
* templates.
*
* @var string
*/
public $cache_id = null;
/**
* Set this if you want different sets of compiled files for the same
* templates.
*
* @var string
*/
public $compile_id = null;
/**
* template left-delimiter
* @var string
*/
public $left_delimiter = "{";
/**
* template right-delimiter
* @var string
*/
public $right_delimiter = "}";
/**#@+
* security
*/
/**
* class name
*
* This should be instance of Smarty_Security.
*
* @var string
* @see Smarty_Security
*/
public $security_class = 'Smarty_Security';
/**
* implementation of security class
*
* @var Smarty_Security
*/
public $security_policy = null;
/**
* controls handling of PHP-blocks
*
* @var integer
*/
public $php_handling = self::PHP_PASSTHRU;
/**
* controls if the php template file resource is allowed
*
* @var bool
*/
public $allow_php_templates = false;
/**
* Should compiled-templates be prevented from being called directly?
*
* {@internal
* Currently used by Smarty_Internal_Template only.
* }}
*
* @var boolean
*/
public $direct_access_security = true;
/**#@-*/
/**
* debug mode
*
* Setting this to true enables the debug-console.
*
* @var boolean
*/
public $debugging = false;
/**
* This determines if debugging is enable-able from the browser.
* <ul>
* <li>NONE => no debugging control allowed</li>
* <li>URL => enable debugging when SMARTY_DEBUG is found in the URL.</li>
* </ul>
* @var string
*/
public $debugging_ctrl = 'NONE';
/**
* Name of debugging URL-param.
*
* Only used when $debugging_ctrl is set to 'URL'.
* The name of the URL-parameter that activates debugging.
*
* @var type
*/
public $smarty_debug_id = 'SMARTY_DEBUG';
/**
* Path of debug template.
* @var string
*/
public $debug_tpl = null;
/**
* When set, smarty uses this value as error_reporting-level.
* @var int
*/
public $error_reporting = null;
/**
* Internal flag for getTags()
* @var boolean
*/
public $get_used_tags = false;
/**#@+
* config var settings
*/
/**
* Controls whether variables with the same name overwrite each other.
* @var boolean
*/
public $config_overwrite = true;
/**
* Controls whether config values of on/true/yes and off/false/no get converted to boolean.
* @var boolean
*/
public $config_booleanize = true;
/**
* Controls whether hidden config sections/vars are read from the file.
* @var boolean
*/
public $config_read_hidden = false;
/**#@-*/
/**#@+
* resource locking
*/
/**
* locking concurrent compiles
* @var boolean
*/
public $compile_locking = true;
/**
* Controls whether cache resources should emply locking mechanism
* @var boolean
*/
public $cache_locking = false;
/**
* seconds to wait for acquiring a lock before ignoring the write lock
* @var float
*/
public $locking_timeout = 10;
/**#@-*/
/**
* global template functions
* @var array
*/
public $template_functions = array();
/**
* resource type used if none given
*
* Must be an valid key of $registered_resources.
* @var string
*/
public $default_resource_type = 'file';
/**
* caching type
*
* Must be an element of $cache_resource_types.
*
* @var string
*/
public $caching_type = 'file';
/**
* internal config properties
* @var array
*/
public $properties = array();
/**
* config type
* @var string
*/
public $default_config_type = 'file';
/**
* cached template objects
* @var array
*/
public $template_objects = array();
/**
* check If-Modified-Since headers
* @var boolean
*/
public $cache_modified_check = false;
/**
* registered plugins
* @var array
*/
public $registered_plugins = array();
/**
* plugin search order
* @var array
*/
public $plugin_search_order = array('function', 'block', 'compiler', 'class');
/**
* registered objects
* @var array
*/
public $registered_objects = array();
/**
* registered classes
* @var array
*/
public $registered_classes = array();
/**
* registered filters
* @var array
*/
public $registered_filters = array();
/**
* registered resources
* @var array
*/
public $registered_resources = array();
/**
* resource handler cache
* @var array
*/
public $_resource_handlers = array();
/**
* registered cache resources
* @var array
*/
public $registered_cache_resources = array();
/**
* cache resource handler cache
* @var array
*/
public $_cacheresource_handlers = array();
/**
* autoload filter
* @var array
*/
public $autoload_filters = array();
/**
* default modifier
* @var array
*/
public $default_modifiers = array();
/**
* autoescape variable output
* @var boolean
*/
public $escape_html = false;
/**
* global internal smarty vars
* @var array
*/
public static $_smarty_vars = array();
/**
* start time for execution time calculation
* @var int
*/
public $start_time = 0;
/**
* default file permissions
* @var int
*/
public $_file_perms = 0644;
/**
* default dir permissions
* @var int
*/
public $_dir_perms = 0771;
/**
* block tag hierarchy
* @var array
*/
public $_tag_stack = array();
/**
* self pointer to Smarty object
* @var Smarty
*/
public $smarty;
/**
* required by the compiler for BC
* @var string
*/
public $_current_file = null;
/**
* internal flag to enable parser debugging
* @var bool
*/
public $_parserdebug = false;
/**
* Saved parameter of merged templates during compilation
*
* @var array
*/
public $merged_templates_func = array();
/**#@-*/
/**
* Initialize new Smarty object
*
*/
public function __construct()
{
// selfpointer needed by some other class methods
$this->smarty = $this;
if (is_callable('mb_internal_encoding')) {
mb_internal_encoding(Smarty::$_CHARSET);
}
$this->start_time = microtime(true);
// set default dirs
$this->setTemplateDir('.' . DS . 'templates' . DS)
->setCompileDir('.' . DS . 'templates_c' . DS)
->setPluginsDir(SMARTY_PLUGINS_DIR)
->setCacheDir('.' . DS . 'cache' . DS)
->setConfigDir('.' . DS . 'configs' . DS);
$this->debug_tpl = 'file:' . dirname(__FILE__) . '/debug.tpl';
if (isset($_SERVER['SCRIPT_NAME'])) {
$this->assignGlobal('SCRIPT_NAME', $_SERVER['SCRIPT_NAME']);
}
}
/**
* Class destructor
*/
public function __destruct()
{
// intentionally left blank
}
/**
* <<magic>> set selfpointer on cloned object
*/
public function __clone()
{
$this->smarty = $this;
}
/**
* <<magic>> Generic getter.
*
* Calls the appropriate getter function.
* Issues an E_USER_NOTICE if no valid getter is found.
*
* @param string $name property name
* @return mixed
*/
public function __get($name)
{
$allowed = array(
'template_dir' => 'getTemplateDir',
'config_dir' => 'getConfigDir',
'plugins_dir' => 'getPluginsDir',
'compile_dir' => 'getCompileDir',
'cache_dir' => 'getCacheDir',
);
if (isset($allowed[$name])) {
return $this->{$allowed[$name]}();
} else {
trigger_error('Undefined property: '. get_class($this) .'::$'. $name, E_USER_NOTICE);
}
}
/**
* <<magic>> Generic setter.
*
* Calls the appropriate setter function.
* Issues an E_USER_NOTICE if no valid setter is found.
*
* @param string $name property name
* @param mixed $value parameter passed to setter
*/
public function __set($name, $value)
{
$allowed = array(
'template_dir' => 'setTemplateDir',
'config_dir' => 'setConfigDir',
'plugins_dir' => 'setPluginsDir',
'compile_dir' => 'setCompileDir',
'cache_dir' => 'setCacheDir',
);
if (isset($allowed[$name])) {
$this->{$allowed[$name]}($value);
} else {
trigger_error('Undefined property: ' . get_class($this) . '::$' . $name, E_USER_NOTICE);
}
}
/**
* Check if a template resource exists
*
* @param string $resource_name template name
* @return boolean status
*/
public function templateExists($resource_name)
{
// create template object
$save = $this->template_objects;
$tpl = new $this->template_class($resource_name, $this);
// check if it does exists
$result = $tpl->source->exists;
$this->template_objects = $save;
return $result;
}
/**
* Returns a single or all global variables
*
* @param object $smarty
* @param string $varname variable name or null
* @return string variable value or or array of variables
*/
public function getGlobal($varname = null)
{
if (isset($varname)) {
if (isset(self::$global_tpl_vars[$varname])) {
return self::$global_tpl_vars[$varname]->value;
} else {
return '';
}
} else {
$_result = array();
foreach (self::$global_tpl_vars AS $key => $var) {
$_result[$key] = $var->value;
}
return $_result;
}
}
/**
* Empty cache folder
*
* @param integer $exp_time expiration time
* @param string $type resource type
* @return integer number of cache files deleted
*/
function clearAllCache($exp_time = null, $type = null)
{
// load cache resource and call clearAll
$_cache_resource = Smarty_CacheResource::load($this, $type);
Smarty_CacheResource::invalidLoadedCache($this);
return $_cache_resource->clearAll($this, $exp_time);
}
/**
* Empty cache for a specific template
*
* @param string $template_name template name
* @param string $cache_id cache id
* @param string $compile_id compile id
* @param integer $exp_time expiration time
* @param string $type resource type
* @return integer number of cache files deleted
*/
public function clearCache($template_name, $cache_id = null, $compile_id = null, $exp_time = null, $type = null)
{
// load cache resource and call clear
$_cache_resource = Smarty_CacheResource::load($this, $type);
Smarty_CacheResource::invalidLoadedCache($this);
return $_cache_resource->clear($this, $template_name, $cache_id, $compile_id, $exp_time);
}
/**
* Loads security class and enables security
*
* @param string|Smarty_Security $security_class if a string is used, it must be class-name
* @return Smarty current Smarty instance for chaining
* @throws SmartyException when an invalid class name is provided
*/
public function enableSecurity($security_class = null)
{
if ($security_class instanceof Smarty_Security) {
$this->security_policy = $security_class;
return $this;
} elseif (is_object($security_class)) {
throw new SmartyException("Class '" . get_class($security_class) . "' must extend Smarty_Security.");
}
if ($security_class == null) {
$security_class = $this->security_class;
}
if (!class_exists($security_class)) {
throw new SmartyException("Security class '$security_class' is not defined");
} elseif ($security_class !== 'Smarty_Security' && !is_subclass_of($security_class, 'Smarty_Security')) {
throw new SmartyException("Class '$security_class' must extend Smarty_Security.");
} else {
$this->security_policy = new $security_class($this);
}
return $this;
}
/**
* Disable security
* @return Smarty current Smarty instance for chaining
*/
public function disableSecurity()
{
$this->security_policy = null;
return $this;
}
/**
* Set template directory
*
* @param string|array $template_dir directory(s) of template sources
* @return Smarty current Smarty instance for chaining
*/
public function setTemplateDir($template_dir)
{
$this->template_dir = array();
foreach ((array) $template_dir as $k => $v) {
if (is_array($v)) $v = $v[0];
$this->template_dir[$k] = rtrim($v, '/\\') . DS;
}
$this->joined_template_dir = join(DIRECTORY_SEPARATOR, $this->template_dir);
return $this;
}
/**
* Add template directory(s)
*
* @param string|array $template_dir directory(s) of template sources
* @param string $key of the array element to assign the template dir to
* @return Smarty current Smarty instance for chaining
* @throws SmartyException when the given template directory is not valid
*/
public function addTemplateDir($template_dir, $key=null)
{
// make sure we're dealing with an array
$this->template_dir = (array) $this->template_dir;
if (is_array($template_dir)) {
foreach ($template_dir as $k => $v) {
if (is_int($k)) {
// indexes are not merged but appended
$this->template_dir[] = rtrim($v, '/\\') . DS;
} else {
// string indexes are overridden
$this->template_dir[$k] = rtrim($v, '/\\') . DS;
}
}
} elseif ($key !== null) {
// override directory at specified index
$this->template_dir[$key] = rtrim($template_dir, '/\\') . DS;
} else {
// append new directory
$this->template_dir[] = rtrim($template_dir, '/\\') . DS;
}
$this->joined_template_dir = join(DIRECTORY_SEPARATOR, $this->template_dir);
return $this;
}
/**
* Get template directories
*
* @param mixed index of directory to get, null to get all
* @return array|string list of template directories, or directory of $index
*/
public function getTemplateDir($index=null)
{
if ($index !== null) {
return isset($this->template_dir[$index]) ? $this->template_dir[$index] : null;
}
return (array)$this->template_dir;
}
/**
* Set config directory
*
* @param string|array $template_dir directory(s) of configuration sources
* @return Smarty current Smarty instance for chaining
*/
public function setConfigDir($config_dir)
{
$this->config_dir = array();
foreach ((array) $config_dir as $k => $v) {
$this->config_dir[$k] = rtrim($v, '/\\') . DS;
}
$this->joined_config_dir = join(DIRECTORY_SEPARATOR, $this->config_dir);
return $this;
}
/**
* Add config directory(s)
*
* @param string|array $config_dir directory(s) of config sources
* @param string key of the array element to assign the config dir to
* @return Smarty current Smarty instance for chaining
*/
public function addConfigDir($config_dir, $key=null)
{
// make sure we're dealing with an array
$this->config_dir = (array) $this->config_dir;
if (is_array($config_dir)) {
foreach ($config_dir as $k => $v) {
if (is_int($k)) {
// indexes are not merged but appended
$this->config_dir[] = rtrim($v, '/\\') . DS;
} else {
// string indexes are overridden
$this->config_dir[$k] = rtrim($v, '/\\') . DS;
}
}
} elseif( $key !== null ) {
// override directory at specified index
$this->config_dir[$key] = rtrim($config_dir, '/\\') . DS;
} else {
// append new directory
$this->config_dir[] = rtrim($config_dir, '/\\') . DS;
}
$this->joined_config_dir = join(DIRECTORY_SEPARATOR, $this->config_dir);
return $this;
}
/**
* Get config directory
*
* @param mixed index of directory to get, null to get all
* @return array|string configuration directory
*/
public function getConfigDir($index=null)
{
if ($index !== null) {
return isset($this->config_dir[$index]) ? $this->config_dir[$index] : null;
}
return (array)$this->config_dir;
}
/**
* Set plugins directory
*
* @param string|array $plugins_dir directory(s) of plugins
* @return Smarty current Smarty instance for chaining
*/
public function setPluginsDir($plugins_dir)
{
$this->plugins_dir = array();
foreach ((array)$plugins_dir as $k => $v) {
$this->plugins_dir[$k] = rtrim($v, '/\\') . DS;
}
return $this;
}
/**
* Adds directory of plugin files
*
* @param object $smarty
* @param string $ |array $ plugins folder
* @return Smarty current Smarty instance for chaining
*/
public function addPluginsDir($plugins_dir)
{
// make sure we're dealing with an array
$this->plugins_dir = (array) $this->plugins_dir;
if (is_array($plugins_dir)) {
foreach ($plugins_dir as $k => $v) {
if (is_int($k)) {
// indexes are not merged but appended
$this->plugins_dir[] = rtrim($v, '/\\') . DS;
} else {
// string indexes are overridden
$this->plugins_dir[$k] = rtrim($v, '/\\') . DS;
}
}
} else {
// append new directory
$this->plugins_dir[] = rtrim($plugins_dir, '/\\') . DS;
}
$this->plugins_dir = array_unique($this->plugins_dir);
return $this;
}
/**
* Get plugin directories
*
* @return array list of plugin directories
*/
public function getPluginsDir()
{
return (array)$this->plugins_dir;
}
/**
* Set compile directory
*
* @param string $compile_dir directory to store compiled templates in
* @return Smarty current Smarty instance for chaining
*/
public function setCompileDir($compile_dir)
{
$this->compile_dir = rtrim($compile_dir, '/\\') . DS;
if (!isset(Smarty::$_muted_directories[$this->compile_dir])) {
Smarty::$_muted_directories[$this->compile_dir] = null;
}
return $this;
}
/**
* Get compiled directory
*
* @return string path to compiled templates
*/
public function getCompileDir()
{
return $this->compile_dir;
}
/**
* Set cache directory
*
* @param string $cache_dir directory to store cached templates in
* @return Smarty current Smarty instance for chaining
*/
public function setCacheDir($cache_dir)
{
$this->cache_dir = rtrim($cache_dir, '/\\') . DS;
if (!isset(Smarty::$_muted_directories[$this->cache_dir])) {
Smarty::$_muted_directories[$this->cache_dir] = null;
}
return $this;
}
/**
* Get cache directory
*
* @return string path of cache directory
*/
public function getCacheDir()
{
return $this->cache_dir;
}
/**
* Set default modifiers
*
* @param array|string $modifiers modifier or list of modifiers to set
* @return Smarty current Smarty instance for chaining
*/
public function setDefaultModifiers($modifiers)
{
$this->default_modifiers = (array) $modifiers;
return $this;
}
/**
* Add default modifiers
*
* @param array|string $modifiers modifier or list of modifiers to add
* @return Smarty current Smarty instance for chaining
*/
public function addDefaultModifiers($modifiers)
{
if (is_array($modifiers)) {
$this->default_modifiers = array_merge($this->default_modifiers, $modifiers);
} else {
$this->default_modifiers[] = $modifiers;
}
return $this;
}
/**
* Get default modifiers
*
* @return array list of default modifiers
*/
public function getDefaultModifiers()
{
return $this->default_modifiers;
}
/**
* Set autoload filters
*
* @param array $filters filters to load automatically
* @param string $type "pre", "output", … specify the filter type to set. Defaults to none treating $filters' keys as the appropriate types
* @return Smarty current Smarty instance for chaining
*/
public function setAutoloadFilters($filters, $type=null)
{
if ($type !== null) {
$this->autoload_filters[$type] = (array) $filters;
} else {
$this->autoload_filters = (array) $filters;
}
return $this;
}
/**
* Add autoload filters
*
* @param array $filters filters to load automatically
* @param string $type "pre", "output", … specify the filter type to set. Defaults to none treating $filters' keys as the appropriate types
* @return Smarty current Smarty instance for chaining
*/
public function addAutoloadFilters($filters, $type=null)
{
if ($type !== null) {
if (!empty($this->autoload_filters[$type])) {
$this->autoload_filters[$type] = array_merge($this->autoload_filters[$type], (array) $filters);
} else {
$this->autoload_filters[$type] = (array) $filters;
}
} else {
foreach ((array) $filters as $key => $value) {
if (!empty($this->autoload_filters[$key])) {
$this->autoload_filters[$key] = array_merge($this->autoload_filters[$key], (array) $value);
} else {
$this->autoload_filters[$key] = (array) $value;
}
}
}
return $this;
}
/**
* Get autoload filters
*
* @param string $type type of filter to get autoloads for. Defaults to all autoload filters
* @return array array( 'type1' => array( 'filter1', 'filter2', … ) ) or array( 'filter1', 'filter2', …) if $type was specified
*/
public function getAutoloadFilters($type=null)
{
if ($type !== null) {
return isset($this->autoload_filters[$type]) ? $this->autoload_filters[$type] : array();
}
return $this->autoload_filters;
}
/**
* return name of debugging template
*
* @return string
*/
public function getDebugTemplate()
{
return $this->debug_tpl;
}
/**
* set the debug template
*
* @param string $tpl_name
* @return Smarty current Smarty instance for chaining
* @throws SmartyException if file is not readable
*/
public function setDebugTemplate($tpl_name)
{
if (!is_readable($tpl_name)) {
throw new SmartyException("Unknown file '{$tpl_name}'");
}
$this->debug_tpl = $tpl_name;
return $this;
}
/**
* creates a template object
*
* @param string $template the resource handle of the template file
* @param mixed $cache_id cache id to be used with this template
* @param mixed $compile_id compile id to be used with this template
* @param object $parent next higher level of Smarty variables
* @param boolean $do_clone flag is Smarty object shall be cloned
* @return object template object
*/
public function createTemplate($template, $cache_id = null, $compile_id = null, $parent = null, $do_clone = true)
{
if (!empty($cache_id) && (is_object($cache_id) || is_array($cache_id))) {
$parent = $cache_id;
$cache_id = null;
}
if (!empty($parent) && is_array($parent)) {
$data = $parent;
$parent = null;
} else {
$data = null;
}
// default to cache_id and compile_id of Smarty object
$cache_id = $cache_id === null ? $this->cache_id : $cache_id;
$compile_id = $compile_id === null ? $this->compile_id : $compile_id;
// already in template cache?
if ($this->allow_ambiguous_resources) {
$_templateId = Smarty_Resource::getUniqueTemplateName($this, $template) . $cache_id . $compile_id;
} else {
$_templateId = $this->joined_template_dir . '#' . $template . $cache_id . $compile_id;
}
if (isset($_templateId[150])) {
$_templateId = sha1($_templateId);
}
if ($do_clone) {
if (isset($this->template_objects[$_templateId])) {
// return cached template object
$tpl = clone $this->template_objects[$_templateId];
$tpl->smarty = clone $tpl->smarty;
$tpl->parent = $parent;
$tpl->tpl_vars = array();
$tpl->config_vars = array();
} else {
$tpl = new $this->template_class($template, clone $this, $parent, $cache_id, $compile_id);
}
} else {
if (isset($this->template_objects[$_templateId])) {
// return cached template object
$tpl = $this->template_objects[$_templateId];
$tpl->parent = $parent;
$tpl->tpl_vars = array();
$tpl->config_vars = array();
} else {
$tpl = new $this->template_class($template, $this, $parent, $cache_id, $compile_id);
}
}
// fill data if present
if (!empty($data) && is_array($data)) {
// set up variable values
foreach ($data as $_key => $_val) {
$tpl->tpl_vars[$_key] = new Smarty_variable($_val);
}
}
return $tpl;
}
/**
* Takes unknown classes and loads plugin files for them
* class name format: Smarty_PluginType_PluginName
* plugin filename format: plugintype.pluginname.php
*
* @param string $plugin_name class plugin name to load
* @param bool $check check if already loaded
* @return string |boolean filepath of loaded file or false
*/
public function loadPlugin($plugin_name, $check = true)
{
// if function or class exists, exit silently (already loaded)
if ($check && (is_callable($plugin_name) || class_exists($plugin_name, false))) {
return true;
}
// Plugin name is expected to be: Smarty_[Type]_[Name]
$_name_parts = explode('_', $plugin_name, 3);
// class name must have three parts to be valid plugin
// count($_name_parts) < 3 === !isset($_name_parts[2])
if (!isset($_name_parts[2]) || strtolower($_name_parts[0]) !== 'smarty') {
throw new SmartyException("plugin {$plugin_name} is not a valid name format");
return false;
}
// if type is "internal", get plugin from sysplugins
if (strtolower($_name_parts[1]) == 'internal') {
$file = SMARTY_SYSPLUGINS_DIR . strtolower($plugin_name) . '.php';
if (file_exists($file)) {
require_once($file);
return $file;
} else {
return false;
}
}
// plugin filename is expected to be: [type].[name].php
$_plugin_filename = "{$_name_parts[1]}.{$_name_parts[2]}.php";
-
+
$_stream_resolve_include_path = function_exists('stream_resolve_include_path');
// loop through plugin dirs and find the plugin
foreach($this->getPluginsDir() as $_plugin_dir) {
$names = array(
$_plugin_dir . $_plugin_filename,
$_plugin_dir . strtolower($_plugin_filename),
);
foreach ($names as $file) {
if (file_exists($file)) {
require_once($file);
return $file;
}
if ($this->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_plugin_dir)) {
// try PHP include_path
if ($_stream_resolve_include_path) {
$file = stream_resolve_include_path($file);
} else {
$file = Smarty_Internal_Get_Include_Path::getIncludePath($file);
}
-
+
if ($file !== false) {
require_once($file);
return $file;
}
}
}
}
// no plugin loaded
return false;
}
/**
* Compile all template files
*
* @param string $extension file extension
* @param bool $force_compile force all to recompile
* @param int $time_limit
* @param int $max_errors
* @return integer number of template files recompiled
*/
public function compileAllTemplates($extention = '.tpl', $force_compile = false, $time_limit = 0, $max_errors = null)
{
return Smarty_Internal_Utility::compileAllTemplates($extention, $force_compile, $time_limit, $max_errors, $this);
}
/**
* Compile all config files
*
* @param string $extension file extension
* @param bool $force_compile force all to recompile
* @param int $time_limit
* @param int $max_errors
* @return integer number of template files recompiled
*/
public function compileAllConfig($extention = '.conf', $force_compile = false, $time_limit = 0, $max_errors = null)
{
return Smarty_Internal_Utility::compileAllConfig($extention, $force_compile, $time_limit, $max_errors, $this);
}
/**
* Delete compiled template file
*
* @param string $resource_name template name
* @param string $compile_id compile id
* @param integer $exp_time expiration time
* @return integer number of template files deleted
*/
public function clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null)
{
return Smarty_Internal_Utility::clearCompiledTemplate($resource_name, $compile_id, $exp_time, $this);
}
/**
* Return array of tag/attributes of all tags used by an template
*
* @param object $templae template object
* @return array of tag/attributes
*/
public function getTags(Smarty_Internal_Template $template)
{
return Smarty_Internal_Utility::getTags($template);
}
/**
* Run installation test
*
* @param array $errors Array to write errors into, rather than outputting them
* @return boolean true if setup is fine, false if something is wrong
*/
public function testInstall(&$errors=null)
{
return Smarty_Internal_Utility::testInstall($this, $errors);
}
/**
* Error Handler to mute expected messages
*
* @link http://php.net/set_error_handler
* @param integer $errno Error level
* @return boolean
*/
public static function mutingErrorHandler($errno, $errstr, $errfile, $errline, $errcontext)
{
$_is_muted_directory = false;
// add the SMARTY_DIR to the list of muted directories
if (!isset(Smarty::$_muted_directories[SMARTY_DIR])) {
$smarty_dir = realpath(SMARTY_DIR);
Smarty::$_muted_directories[SMARTY_DIR] = array(
'file' => $smarty_dir,
'length' => strlen($smarty_dir),
);
}
// walk the muted directories and test against $errfile
foreach (Smarty::$_muted_directories as $key => &$dir) {
if (!$dir) {
// resolve directory and length for speedy comparisons
$file = realpath($key);
$dir = array(
'file' => $file,
'length' => strlen($file),
);
}
if (!strncmp($errfile, $dir['file'], $dir['length'])) {
$_is_muted_directory = true;
break;
}
}
// pass to next error handler if this error did not occur inside SMARTY_DIR
// or the error was within smarty but masked to be ignored
if (!$_is_muted_directory || ($errno && $errno & error_reporting())) {
if (Smarty::$_previous_error_handler) {
return call_user_func(Smarty::$_previous_error_handler, $errno, $errstr, $errfile, $errline, $errcontext);
} else {
return false;
}
}
}
/**
* Enable error handler to mute expected messages
*
* @return void
*/
public static function muteExpectedErrors()
{
/*
error muting is done because some people implemented custom error_handlers using
http://php.net/set_error_handler and for some reason did not understand the following paragraph:
It is important to remember that the standard PHP error handler is completely bypassed for the
error types specified by error_types unless the callback function returns FALSE.
error_reporting() settings will have no effect and your error handler will be called regardless -
however you are still able to read the current value of error_reporting and act appropriately.
Of particular note is that this value will be 0 if the statement that caused the error was
prepended by the @ error-control operator.
Smarty deliberately uses @filemtime() over file_exists() and filemtime() in some places. Reasons include
- @filemtime() is almost twice as fast as using an additional file_exists()
- between file_exists() and filemtime() a possible race condition is opened,
which does not exist using the simple @filemtime() approach.
*/
$error_handler = array('Smarty', 'mutingErrorHandler');
$previous = set_error_handler($error_handler);
// avoid dead loops
if ($previous !== $error_handler) {
Smarty::$_previous_error_handler = $previous;
}
}
/**
* Disable error handler muting expected messages
*
* @return void
*/
public static function unmuteExpectedErrors()
{
restore_error_handler();
}
}
// Check if we're running on windows
Smarty::$_IS_WINDOWS = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
// let PCRE (preg_*) treat strings as ISO-8859-1 if we're not dealing with UTF-8
if (Smarty::$_CHARSET !== 'UTF-8') {
Smarty::$_UTF8_MODIFIER = '';
}
/**
* Smarty exception class
* @package Smarty
*/
class SmartyException extends Exception {
}
/**
* Smarty compiler exception class
* @package Smarty
*/
class SmartyCompilerException extends SmartyException {
}
/**
* Autoloader
*/
function smartyAutoload($class)
{
$_class = strtolower($class);
$_classes = array(
'smarty_config_source' => true,
'smarty_config_compiled' => true,
'smarty_security' => true,
'smarty_cacheresource' => true,
'smarty_cacheresource_custom' => true,
'smarty_cacheresource_keyvaluestore' => true,
'smarty_resource' => true,
'smarty_resource_custom' => true,
'smarty_resource_uncompiled' => true,
'smarty_resource_recompiled' => true,
);
if (!strncmp($_class, 'smarty_internal_', 16) || isset($_classes[$_class])) {
include SMARTY_SYSPLUGINS_DIR . $_class . '.php';
}
}
?>
diff --git a/includes/api/BeautyXML.class.php b/includes/api/BeautyXML.class.php
index 62fa3d5..bdb8573 100755
--- a/includes/api/BeautyXML.class.php
+++ b/includes/api/BeautyXML.class.php
@@ -1,157 +1,157 @@
<?php
/**
* XML beautifer
*
* Zed. The immensity of stars. The HyperShip. The people.
- *
+ *
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
*
- * This class is simple XML beautifer
+ * This class is simple XML beautifer
* it's very, very, very simple - feature version will be better :-)
- *
+ *
* IMPORTANT NOTE
* there is no warranty, implied or otherwise with this software.
- *
+ *
* version 0.1 | August 2004
*
* released under a LGPL licence.
- *
- * Slawomir Jasinski,
- * http://www.jasinski.us (polish only - my home page)
+ *
+ * Slawomir Jasinski,
+ * http://www.jasinski.us (polish only - my home page)
* http://www.cgi.csd.pl (english & polish)
* contact me - sj@gex.pl
- *
+ *
* @package Zed
* @subpackage API
* @author Slawomir Jasinski <sj@gex.pl>
* @copyright 2004 Slawomir Jasinski, 2010 Sébastien Santoro aka Dereckson
* @license http://www.gnu.org/licenses/lgpl.html LGPL
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*
* @todo Contact Slawomir Jasinski and ask it if the current code could be
* relicensed under BSD license. If not, rewrite from scratch under BSD license.
*/
/**
* This class is simple XML beautifer.
* It's very, very, very simple - feature version will be better :-)
*
* @author Slawomir Jasinski <sj@gex.pl>
*/
class BeautyXML {
/**
* Indicates what characters to use to indent.
*
* If you wish a regular tabulation, the suggested value is \t ;
* If you wish spaces instead, put the correct amount of spaces as value.
- *
+ *
* @var string
*/
var $how_to_ident = " "; // you can user also \t or more/less spaces
-
+
/**
* Determines if long text have to be wrapped.
*
* If true, the text will be wrapped ; otherwise, long lines will be kept.
*
* @var bool
*/
var $wrap = false;
-
+
/**
* If $wrap is true, determines the line lenght.
*
* After this lenght, any text will be wrapped.
*
* @see $wrap
* @var @int
*/
- var $wrap_cont = 80; // where wrap words
+ var $wrap_cont = 80; // where wrap words
/**
* Idents the specified string.
*
* @param string $str the string to indent
* @param int $level the ident level, ie the number of identation to prepend the string with
*/
function ident (&$str, $level) {
$spaces = '';
$level--;
- for ($a = 0; $a < $level; $a++)
+ for ($a = 0; $a < $level; $a++)
$spaces .= $this->how_to_ident;
return $spaces .= $str;
}
/**
* Formats the specified string, beautifying it, with proper indent.
*
* This is the main class method.
*
* @param $str the XML fragment to beautify
* @return string the beautified XML fragment
*/
function format ($str) {
-
+
$str = preg_replace("/<\?[^>]+>/", "", $str);
-
+
$tmp = explode("\n", $str); // extracting string into array
-
+
// cleaning string from spaces and other stuff like \n \r \t
- for ($a = 0, $c = count($tmp); $a < $c; $a++)
+ 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
+
+ // 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)
+
+ if (substr_count($tmp[$a], "<$lan") == 1 && substr_count($tmp[$a], "</$lan") == 1)
$add = false;
-
+
if (preg_match("/\/>$/", $tmp[$a], $match))
$add = false;
-
+
$tmp[$a] = $this->ident($tmp[$a], $level);
-
+
if ($this->wrap) $tmp[$a] = wordwrap($tmp[$a], $this->wrap_cont, "\n" . $this->how_to_ident . $this->how_to_ident . $this->how_to_ident);
-
+
if ($add && !@in_array($lan, $stab) && $lan != '') array_push($stab, $lan);
-
+
}
-
+
return join("\n", $tmp);
}
-
+
}
\ No newline at end of file
diff --git a/includes/api/api_helpers.php b/includes/api/api_helpers.php
index 903e552..b6f6313 100755
--- a/includes/api/api_helpers.php
+++ b/includes/api/api_helpers.php
@@ -1,166 +1,166 @@
<?php
/**
* API helper functions
*
* Zed. The immensity of stars. The HyperShip. The people.
- *
+ *
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* This file provides a functions to output the API message in several formats.
*
* The supported formats are preview (PHP dump), XML, PHP serialize, WDDX
* and json.
*
* The XML outputs code uses the following codes:
* - http://www.thedeveloperday.com/xml-beautifier-tool/
* - http://snipplr.com/view/3491/convert-php-array-to-xml-or-simple-xml-object-if-you-wish/
- *
+ *
* @package Zed
* @subpackage API
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
/**
* The main function for converting to an XML document.
- *
+ *
* Pass in a multi dimensional array and this recursively loops through
* and builds up an XML document.
*
* @param mixed $data
* @param string $rootNodeName What you want the root node to be - defaultsto data.
* @param SimpleXMLElement $xml Should only be used recursively
* @param string $unknownNodeName Name to give to unknown (numeric) keys
* @return string XML
*/
function toXml($data, $rootNodeName = 'data', $xml = null, $unknownNodeName = 'unknownNode')
{
if (!$rootNodeName) $rootNodeName = 'data';
if (!$unknownNodeName) $unknownNodeName = 'unknownNode';
-
+
// turn off compatibility mode as simple xml throws a wobbly if you don't.
if (ini_get('zend.ze1_compatibility_mode') == 1)
ini_set('zend.ze1_compatibility_mode', 0);
-
+
if ($xml == null) {
if (!is_array($data) && !is_object($data)) {
//We've a singleton
if (is_bool($data)) $data = $data ? 'true' : 'false';
return "<?xml version='1.0' encoding='utf-8'?><$rootNodeName>$data</$rootNodeName>";
}
//Starts with simple document
$xml = simplexml_load_string("<?xml version='1.0' encoding='utf-8'?><$rootNodeName />");
}
-
+
// loop through the data passed in.
foreach($data as $key => $value) {
// no numeric keys in our xml please!
if (is_numeric($key)) {
// make string key...
$key = $unknownNodeName . '_'. (string) $key;
}
-
+
// replace anything not alpha numeric
$key = preg_replace('/[^a-z]/i', '', $key);
-
+
//If there is another array found recrusively call this function
if (is_array($value)) {
$node = $xml->addChild($key);
//Recursive call.
toXml($value, $rootNodeName, $node, $unknownNodeName);
} elseif (is_object($value)) {
$node = $xml->addChild($key);
foreach ($value as $subkey => $subvalue) {
if ($subkey == "lastError") continue;
if ($subvalue === null) {
//Ignore null values
continue;
} elseif (is_array($subvalue) || is_object($subvalue)) {
//TODO: test this
//Recursive call.
$subnode = $node->addChild($subkey);
toXml($subvalue, $rootNodeName, $subnode, $unknownNodeName);
} elseif (is_bool($subvalue)) {
$node->addChild($subkey, $subvalue ? 'true' : 'false');
} else {
$node->addChild($subkey, htmlentities($subvalue));
}
}
//die();
//$array = array();
//$node = $xml->addChild($key);
//toXml($value, $rootNodeName, $node, $unknownNodeName);
} elseif (is_bool($value)) {
$xml->addChild($key, $value ? 'true' : 'false');
} else {
//Adds single node.
if ($value || $value === 0) {
$value = htmlentities($value);
$xml->addChild($key,$value);
}
}
-
+
}
// pass back as string. or simple xml object if you want!
return $xml->asXML();
}
/**
* Outputs API reply, printing it in the specified format.
*
* The format will be read form $_REQUEST['format'].
*
* @param mixed $reply the reply to format
* @param string $xmlRoot the XML root element name (optionnal, default value is 'data').
* @param string $xmlChildren the XML children elements name (optionnal, will be deducted from the context if ommited, or, if not posssible, will be unknownNode)
*/
function api_output ($reply, $xmlRoot = null, $xmlChildren = null) {
$format = isset($_REQUEST['format']) ? $_REQUEST['format'] : 'preview';
switch ($format) {
case 'preview':
echo '<pre>';
print_r($reply);
echo '</pre>';
break;
-
+
case 'php':
echo serialize($reply);
break;
-
+
case 'wddx':
require_once('BeautyXML.class.php');
$bc = new BeautyXML();
echo $bc->format(wddx_serialize_value($reply));
break;
-
+
case 'json':
echo json_encode($reply);
break;
-
+
case 'xml':
require_once('BeautyXML.class.php');
$bc = new BeautyXML();
echo '<?xml version="1.0" encoding="utf-8"?>';
echo "\n";
echo $bc->format(toXml($reply, $xmlRoot, null, $xmlChildren));
break;
-
+
case 'string':
echo $reply;
break;
-
+
default:
echo "Unknown API format: $_GET[format]";
break;
}
}
?>
\ No newline at end of file
diff --git a/includes/api/cerbere.php b/includes/api/cerbere.php
index ffea3ec..81fc919 100755
--- a/includes/api/cerbere.php
+++ b/includes/api/cerbere.php
@@ -1,124 +1,124 @@
<?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
*
* If the creditentials aren't valid, it will prints an error message if
* OUTPUT_ERROR is defined and true.
*
* This error message will be formatted through the api_output function if
* FORMAT_ERROR is defined and true ; otherwise, it will be print as is.
*
* To help debug, you can also define ALLOW_LOCALHOST. If this constant is
* defined and true, any call from localhost will be accepted, without checking
* the key.
*
* @see cerbere_die
*/
function cerbere () {
//If ALLOW_LOCALHOST is true, we allow 127.0.0.1 queries
//If you use one of your local IP in your webserver vhost like 10.0.0.3
//it could be easier to create yourself a test key
if (ALLOW_LOCALHOST && $_SERVER['REMOTE_ADDR'] == '127.0.0.1') {
return;
}
-
+
//No key, no authentication
if (!$guid = $_REQUEST['key']) {
cerbere_die('You must add creditentials to your request.');
}
-
+
//Authenticates user
global $db;
$guid = $db->sql_escape($guid);
$sql = "SELECT key_active FROM " . TABLE_API_KEYS .
" WHERE key_guid like '$guid'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't get key", '', __LINE__, __FILE__, $sql);
}
if ($row = $db->sql_fetchrow($result)) {
if ($row['key_active']) {
//key_hits++
$sql = "UPDATE " . TABLE_API_KEYS . " SET key_hits = key_hits + 1" .
" WHERE key_guid like '$guid'";
if (!$db->sql_query($sql))
message_die(SQL_ERROR, "Can't record api call", '', __LINE__, __FILE__, $sql);
} else {
- cerbere_die("Key disabled.");
+ cerbere_die("Key disabled.");
}
} else {
- cerbere_die("Key doesn't exist.");
+ cerbere_die("Key doesn't exist.");
}
}
/**
* Prints a message in raw or API format, then exits.
*
* The error message will be formatted through api_output if the constant
* FORMAT_ERROR is defined and true. Otherwise, it will be printed as is.
*
* @param string $message The error message to print
*/
function cerbere_die ($message) {
if (OUTPUT_ERROR) {
if (FORMAT_ERROR) {
api_output($message, 'error');
} else {
echo $message;
}
}
exit;
}
?>
\ No newline at end of file
diff --git a/includes/cache/cache.php b/includes/cache/cache.php
index a545c7b..d007c6f 100755
--- a/includes/cache/cache.php
+++ b/includes/cache/cache.php
@@ -1,91 +1,91 @@
<?php
/**
* Cache calling class.
*
* Zed. The immensity of stars. The HyperShip. The people.
- *
+ *
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* This file provides a calling class, which read the configuration, ensures
* the cache class for the cache engine given in config exists and initializes
* it.
*
* You'll find a sample of implementation in the CacheMemcached.
* @see CacheMemcached
*
* If no caching mechanism, a "blackhole" void cache will be used.
* @see CacheVoid.
*
* The class to call is determined from the following preference:
* <code>
* $Config['cache']['engine'] = 'memcached'; //will use CacheMemcached class.
* </code>
*
* 0.1 2010-07-06 22:45 Initial version [DcK]
- *
+ *
* @package Zed
* @subpackage Cache
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
/**
* Cache caller
*/
class Cache {
/**
* Gets the cache instance, initializing it if needed
*
* The correct cache instance to initialize will be determined from the
* $Config['cache']['engine'] preference.
*
* The class cache to use will be Cache + (preference engine, capitalized)
*
* This method will creates an instance of the specified object,
* calling the load static method from this object class.
*
* Example:
* <code>
* $Config['cache']['engine'] = 'quux';
* $cache = Cache::load(); //Cache:load() will call CacheQuux:load();
* </code>
- *
+ *
* @return Cache the cache instance, or null if nothing is cached
*/
static function load () {
global $Config;
if (
!array_key_exists('cache', $Config) ||
!array_key_exists('engine', $Config['cache'])
) {
//cache is not configured or engine is not specified
$engine = 'void';
} else {
//engine is specified in the configuration
- $engine = $Config['cache']['engine'];
+ $engine = $Config['cache']['engine'];
}
-
+
$engine_file = 'includes/cache/' . $engine . '.php';
$engine_class = 'Cache' . ucfirst($engine);
-
+
if (!file_exists($engine_file)) {
message_die(GENERAL_ERROR, "Can't initialize $engine cache engine.<br />$engine_file not found.", 'Cache');
}
-
+
require_once($engine_file);
if (!class_exists($engine_class)) {
message_die(GENERAL_ERROR, "Can't initialize $engine cache engine.<br />$engine_class class not found.", 'Cache');
}
-
+
return call_user_func(array($engine_class, 'load'));
}
}
?>
\ No newline at end of file
diff --git a/includes/cache/memcached.php b/includes/cache/memcached.php
index 6193a16..0af21d2 100755
--- a/includes/cache/memcached.php
+++ b/includes/cache/memcached.php
@@ -1,112 +1,112 @@
<?php
/**
* Memcached cache.
*
* Zed. The immensity of stars. The HyperShip. The people.
- *
+ *
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* Cache class: memcached
*
* 0.1 2010-07-06 22:55 Initial version [DcK]
*
* @package Zed
* @subpackage Cache
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
/**
* Memcached cache
- *
+ *
* !!! This class uses the Memcached extension AND NOT the Memcache ext !!!!
*
* References:
* @link http://www.php.net/manual/en/book/memcached.php
* @link http://memcached.org
*
* This class implements a singleton pattern.
*/
class CacheMemcached {
-
+
/**
* The current cache instance
*
- * @var CacheMemcached
+ * @var CacheMemcached
*/
static $instance = null;
/**
* The Memcached object
*
- * @var Memcached
- */
+ * @var Memcached
+ */
private $memcached = null;
-
+
/**
* Gets the cache instance, initializing it if needed
- *
+ *
* @return Cache the cache instance, or null if nothing is cached
*/
- static function load () {
+ static function load () {
//Checks extension is okay
if (!extension_loaded('memcached')) {
if (extension_loaded('memcache')) {
message_die(GENERAL_ERROR, "Can't initialize $engine cache engine.<br />PHP extension memcached not loaded.<br /><strong>!!! This class uses the Memcached extension AND NOT the Memcache extension (this one is loaded) !!!</strong>", 'Cache');
} else {
message_die(GENERAL_ERROR, "Can't initialize $engine cache engine.<br />PHP extension memcached not loaded.", 'Cache');
}
}
-
+
//Creates the Memcached object if needed
if (self::$instance === null) {
global $Config;
-
+
self::$instance = new CacheMemcached();
self::$instance->memcached = new Memcached();
self::$instance->memcached->addServer(
$Config['cache']['server'],
$Config['cache']['port']
);
}
-
+
return self::$instance;
}
-
+
/**
* Gets the specified key's data
*
* @param string $key the key to fetch
* @return mixed the data at the specified key
*/
function get ($key) {
return $this->memcached->get($key);
}
/**
* Sets the specified data at the specified key
*
* @param string $key the key where to store the specified data
* @param mixed $value the data to store
*/
function set ($key, $value) {
return $this->memcached->set($key, $value);
}
/**
* Deletes the specified key's data
*
* @param string $key the key to delete
*/
function delete ($key) {
return $this->memcached->delete($key);
}
}
?>
\ No newline at end of file
diff --git a/includes/cache/void.php b/includes/cache/void.php
index 2d203fd..84f119d 100755
--- a/includes/cache/void.php
+++ b/includes/cache/void.php
@@ -1,81 +1,81 @@
<?php
/**
* "Blackhole" void cache.
*
* Zed. The immensity of stars. The HyperShip. The people.
- *
+ *
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* Cache class: void
*
* 0.1 2010-07-06 22:55 Initial version [DcK]
*
* @package Zed
* @subpackage Cache
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
/**
* "blackhole" void cache
*
* This class doesn't cache information, it'a void wrapper
* get will always return null
* set and delete do nothing
*
* It will be used by default if no cache is specified.
*
* This class implements a singleton pattern.
*/
class CacheVoid {
/**
* @var CacheVoid the current cache instance
*/
static $instance = null;
-
+
/**
* Gets the cache instance, initializing it if needed
- *
+ *
* @return Cache the cache instance, or null if nothing is cached
*/
- static function load () {
+ static function load () {
if (self::$instance === null) {
self::$instance = new CacheVoid();
}
-
+
return self::$instance;
}
-
+
/**
* Gets the specified key's data
*
* @param string $key the key to fetch
* @return mixed the data at the specified key
*/
function get ($key) {
return null;
}
/**
* Sets the specified data at the specified key
*
* @param string $key the key where to store the specified data
* @param mixed $value the data to store
- */
+ */
function set ($key, $value) { }
/**
* Deletes the specified key's data
*
* @param string $key the key to delete
*/
function delete ($key) { }
}
?>
\ No newline at end of file
diff --git a/includes/content/file.php b/includes/content/file.php
index 0e018e0..a18633d 100755
--- a/includes/content/file.php
+++ b/includes/content/file.php
@@ -1,276 +1,276 @@
<?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 $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'];
-
+ 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;
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)) {
+ 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)) {
+ 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
+ //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);
}
}
-
+
?>
\ No newline at end of file
diff --git a/includes/content/location.php b/includes/content/location.php
index f8df52e..21ff058 100755
--- a/includes/content/location.php
+++ b/includes/content/location.php
@@ -1,230 +1,230 @@
<?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:
* - 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
+ * 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;
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);
+ $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;
}
}
-
+
?>
\ No newline at end of file
diff --git a/includes/core.php b/includes/core.php
index 4cb1a06..bafd362 100755
--- a/includes/core.php
+++ b/includes/core.php
@@ -1,666 +1,666 @@
<?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 ///
/// ///
////////////////////////////////////////////////////////////////////////////////
//No register globals
ini_set('register_globals', 'off');
error_reporting(E_ALL & ~E_NOTICE);
//Load libraries
include_once("config.php"); //Site config
include_once("error.php"); //Error management
include_once("mysql.php"); //MySQL layer
include_once("sessions.php"); //Sessions handler
include_once("autoload.php"); //__autoload()
////////////////////////////////////////////////////////////////////////////////
/// ///
/// 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
+ * 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
+ * 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
* @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
*/
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
+ " (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.
- *
+ * 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
*/
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) {
+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)
+
+ //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
*/
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 () {
+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/error.php b/includes/error.php
index 3fdc236..1258ba5 100755
--- a/includes/error.php
+++ b/includes/error.php
@@ -1,260 +1,260 @@
<?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
* 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')
*/
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.
*
* 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)
*/
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.
*
* @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)
*
* @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) {
global $LoginResult;
foreach ($_POST as $name => $value) {
$champs .= "<input type=hidden name=$name value=\"$value\" />";
}
$titre = "Qui êtes-vous ?";
$debug_text = "Vous devez être authentifié pour accéder à cette page.";
$debug_text .= "
<FORM method='post'>
$champs
<table border='0'>
<tr>
<td><STRONG>Login</STRONG></td>
<td><input name='Login' type='text' id='Login' value='$_POST[Login]' size='10' /></td>
<td><STRONG>Mot de passe</STRONG></td>
<td>
<input name='MotDePasse' type='password' id='MotDePasse' size='10' />
<input type='submit' name='LoginBox' value='Connexion' />
</td>
</tr>
- <tr>
+ <tr>
<td align=center COLSPAN=4><a href='/?Topic=My&Article=Enregistrer'>Je d&eacute;sire ouvrir un compte</a></td>
</tr>
</TABLE><span class=error>$LoginResult</span>
</FORM>
";
} elseif ($msg_code == HACK_ERROR) {
$titre = "Accès non autorisé";
$debug_text = $msg_text;
} elseif ($msg_code == SQL_ERROR) {
$titre = "Erreur dans la requête SQL";
$sql_error = $db->sql_error();
$debug_text = $msg_text;
if ( $err_line != '' && $err_file != '') $debug_text .= ' dans ' . $err_file. ', ligne ' . $err_line ;
if ( $sql_error['message'] != '' ) $debug_text .= '<br />Erreur n° ' . $sql_error['code'] . ' : ' . $sql_error['message'];
if ( $sql_store != '' ) $debug_text .= "<br /><strong>$sql_store</strong>";
} elseif ($msg_code == GENERAL_ERROR) {
$titre = $msg_title;
$debug_text = $msg_text;
if ($err_line && $err_file) {
$debug_text .= "<BR />$err_file, ligne $err_line";
}
- }
-
+ }
+
echo "
<TABLE height='100%' cellSpacing=0 cellPadding=0 width='100%' border=0>
<TBODY>
<TR>
<TD vAlign=top align=middle>
<TABLE cellSpacing=0 cellPadding=0 border=0>
- <TBODY>
+ <TBODY>
<TR>
- <TD vAlign=top rowSpan=5><IMG height=177 alt=''
+ <TD vAlign=top rowSpan=5><IMG height=177 alt=''
src='/_pict/error/notfound.jpg' width=163 border=0></TD>
- <TD colSpan=4><IMG height=2 alt='' src='/_pict/error/mrblue.gif'
+ <TD colSpan=4><IMG height=2 alt='' src='/_pict/error/mrblue.gif'
width=500 border=0></TD>
- <TD><IMG height=2 alt='' src='/_pict/error/undercover.gif' width=1
+ <TD><IMG height=2 alt='' src='/_pict/error/undercover.gif' width=1
border=0></TD></TR>
<TR>
- <TD vAlign=bottom rowSpan=4 bgcolor='#FFFFFF'><IMG height=43 alt=''
+ <TD vAlign=bottom rowSpan=4 bgcolor='#FFFFFF'><IMG height=43 alt=''
src='/_pict/error/ecke.gif' width=14 border=0></TD>
- <TD vAlign=center align=middle rowSpan=2 bgcolor='#FFFFFF'>
+ <TD vAlign=center align=middle rowSpan=2 bgcolor='#FFFFFF'>
<TABLE cellSpacing=1 cellPadding=0 width=470 border=0>
<TBODY>
<TR>
- <TD><FONT face='Verdana, Helvetica, sans-serif' color=red
+ <TD><FONT face='Verdana, Helvetica, sans-serif' color=red
size=4><B>$titre</B></FONT><BR>
- <IMG height=5 alt=''
+ <IMG height=5 alt=''
src='/_pict/error/undercover.gif' width=14 border=0><BR></TD></TR>
<TR>
- <TD><FONT face='Verdana, Helvetica, sans-serif' color=black
+ <TD><FONT face='Verdana, Helvetica, sans-serif' color=black
size=2>$debug_text</FONT></TD></TR></TBODY></TABLE></TD>
- <TD align=right width=2 rowSpan=2 bgcolor='#FFFFFF'><IMG height=146 alt=''
+ <TD align=right width=2 rowSpan=2 bgcolor='#FFFFFF'><IMG height=146 alt=''
src='/_pict/error/mrblue.gif' width=2 border=0></TD>
- <TD bgcolor='#FFFFFF'><IMG height=132 alt='' src='/_pict/error/undercover.gif' width=1
+ <TD bgcolor='#FFFFFF'><IMG height=132 alt='' src='/_pict/error/undercover.gif' width=1
border=0></TD>
</TR>
<TR>
- <TD><IMG height=14 alt='' src='/_pict/error/undercover.gif' width=1
+ <TD><IMG height=14 alt='' src='/_pict/error/undercover.gif' width=1
border=0></TD></TR>
<TR>
- <TD colSpan=2><IMG height=2 alt='' src='/_pict/error/mrblue.gif'
+ <TD colSpan=2><IMG height=2 alt='' src='/_pict/error/mrblue.gif'
width=486 border=0></TD>
- <TD><IMG height=2 alt='' src='/_pict/error/undercover.gif' width=1
+ <TD><IMG height=2 alt='' src='/_pict/error/undercover.gif' width=1
border=0></TD></TR>
<TR>
- <TD colSpan=2><IMG height=27 alt='' src='/_pict/error/undercover.gif'
+ <TD colSpan=2><IMG height=27 alt='' src='/_pict/error/undercover.gif'
width=486 border=0></TD>
- <TD><IMG height=27 alt='' src='/_pict/error/undercover.gif' width=1
+ <TD><IMG height=27 alt='' src='/_pict/error/undercover.gif' width=1
border=0></TD></TR></TBODY></TABLE>
<P>&nbsp;</P>
</TD></TR></TBODY></TABLE>
";
-
+
exit;
}
?>
\ No newline at end of file
diff --git a/includes/geo/body.php b/includes/geo/body.php
index 03c279f..128c538 100755
--- a/includes/geo/body.php
+++ b/includes/geo/body.php
@@ -1,174 +1,174 @@
<?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 $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;
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 get_status () {
$flags = array('hypership','asteroid','moon','planet','star','orbital','hidden');
foreach ($flags as $flag) {
if ($this->$flag) {
$status[] = $flag;
}
}
return implode(',', $status);
}
-
+
/**
* Gets the kind of place the body is (e.g. asteroid)
*
* @return string the kind of place
*/
function kind () {
//If a location can be described by 2 flags, order the relevant flags list
//by priority, as it'll return the first trigerred.
//e.g. a moon converted in hypership will be "hypership" and not "moon".
$relevantFlags = array('hypership','asteroid','moon','planet','star','orbital');
foreach ($relevantFlags as $flag) {
if ($this->$flag) {
return $flag;
}
}
return "";
}
-
+
/**
* Gets the name of the body, as a string representation of the object
*
* @return string the name of the body
*/
function __toString () {
return $this->name;
}
-
+
/**
* Saves to database
*/
function save_to_database () {
global $db;
-
+
$code = $this->code ? "'" . $db->sql_escape($this->code) . "'" : 'NULL';
$name = $db->sql_escape($this->name);
$status = get_status();
$location = $db->sql_escape($this->location);
$description = $db->sql_escape($this->description);
//Updates or inserts
$sql = "REPLACE INTO " . TABLE_BODIES . " (`body_code`, `body_name`, `body_status`, `body_location`, `body_description`) VALUES ($code, '$name', '$status', '$location', '$description')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
-
+
if (!$code) {
//Gets new record code value
$this->code = $db->sql_nextid();
}
}
}
-
+
?>
\ No newline at end of file
diff --git a/includes/geo/galaxy.php b/includes/geo/galaxy.php
index e4aa072..20010c8 100755
--- a/includes/geo/galaxy.php
+++ b/includes/geo/galaxy.php
@@ -1,119 +1,119 @@
<?php
/**
* Geo galaxy class.
- *
+ *
* Zed. The immensity of stars. The HyperShip. The people.
- *
+ *
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* A 3D grid of objects
*
* 0.1 2010-02-08 14:02 Initial version [DcK]
* 0.2 2010-07-25 9:20 Spherical conversion, get objects
- *
+ *
* @package Zed
* @subpackage Geo
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
/**
* Geo galaxy class
*
* This class provides methods to convert coordinate polars.
*
* @todo create a unit testing file dev/tests/GeoGalaxyTest.php
* @todo add unit testing for the normalize_angle method in dev/tests/GeoGalaxyTest.php
*/
class GeoGalaxy {
/*
* ----------------------------------------------------------------------- *
* Objects fetchers
* ----------------------------------------------------------------------- *
*/
-
+
/**
* Gets all the coordinates of the objects in the galaxy.
*
* @return array An array of array. Each item is [string object_name, string object_type, GeoPoint3D coordinates]
*/
static function get_coordinates () {
global $db;
- $sql = "SELECT * FROM geo_coordinates";
+ $sql = "SELECT * FROM geo_coordinates";
if (!$result = $db->sql_query($sql)) message_die(SQL_ERROR, "Can't query geo_coordinates view.", '', __LINE__, __FILE__, $sql);
-
+
$objects = array();
while ($row = $db->sql_fetchrow($result)) {
//Demios ship xyz: [-50, 30, 40]
//Kaos asteroid xyz: [150, -129, 10]
$objects[] = array($row[0], $row[1], GeoPoint3D::fromString($row[2]));
}
return $objects;
}
-
+
/*
* ----------------------------------------------------------------------- *
* Helper methods - math
* ----------------------------------------------------------------------- *
*/
-
+
/**
* Normalizes an angle, so 0 =< angle < 2 PI
- *
+ *
* @param float $angle angle in radians (use deg2rad() if you've degrees)
* @return an angle in the 0 =< angle < 2 PI interval
*/
static function normalize_angle ($angle) {
while ($angle < 0) {
$angle += 2 * M_PI;
}
while ($angle >= 2 * M_PI) {
$angle -= 2 * M_PI;
}
return $angle;
}
-
+
/**
* Converts (x, y, z) cartesian to (ρ, φ, θ) spherical coordinates
*
* 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
*
* @param int $x the x coordinate
* @param int $y the y coordinate
* @param int $z the z coordinate
* @return array an array of 3 floats number, representing the (ρ, φ, θ) spherical coordinates
*/
static function cartesian_to_spherical ($x, $y, $z) {
$rho = sqrt($x * $x + $y * $y + $z * $z); //ρ = sqrt(x² + y² + z²)
$theta= acos($z / $rho); //φ = acos z/φ
$phi = acos($x / sqrt($x * $x + $y * $y)); //θ = acos x / sqrt(x² + y²)
if (y < 0) $phi = 2 * M_PI - $phi; //∀ y < 0 θ = 2π - θ
-
+
return array(round($rho, 2), round(rad2deg($theta), 2), round(rad2deg($phi), 2));
}
-
+
/**
* Converts (x, y, z) cartesian to (ρ, φ, θ) spherical coordinates
*
* The algo used is from http://www.phy225.dept.shef.ac.uk/mediawiki/index.php/Cartesian_to_polar_conversion
*
* @param int $x the x coordinate
* @param int $y the y coordinate
* @param int $z the z coordinate
* @return array an array of 3 floats number, representing the (ρ, φ, θ) spherical coordinates
*/
static function cartesian_to_spherical2 ($x, $y, $z) {
$rho = sqrt($x * $x + $y * $y + $z * $z); //ρ = sqrt(x² + y² + z²)
$theta= atan2($y, $x); //φ = atan2 $y $x
$phi = acos($z / $rho); //θ = acos z/φ
-
+
return array(round($rho, 2), round(rad2deg($theta), 2), round(rad2deg($phi), 2));
}
}
\ No newline at end of file
diff --git a/includes/geo/location.php b/includes/geo/location.php
index 31d0704..004a78b 100755
--- a/includes/geo/location.php
+++ b/includes/geo/location.php
@@ -1,436 +1,436 @@
<?php
/**
* Geo location class.
*
* Zed. The immensity of stars. The HyperShip. The people.
- *
+ *
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2010-01-28 18:52 DcK
*
* @package Zed
* @subpackage Geo
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
require_once('body.php');
require_once('place.php');
require_once('point3D.php');
require_once('includes/objects/ship.php');
/**
* Geo location class
*
* This class contains properties to get, set or compare a location and
* explore the geo classes linked to.
*
* It quickly allow to parse through the location classes in templates and
* controllers.
*
* @todo initializes $point3D from $body or $ship own locations;
* @todo improve GeoLocation documentation (especially magic properties)
*/
class GeoLocation {
/**
* An array of strings containing location data.
*
* In the current class implementation,
- * the first element is the global location
+ * the first element is the global location
* and the second element is the local location.
- *
+ *
* @var Aray
*/
private $data;
/**
* A body object
*
* It contains a GeoBody value when the global location is a body
* ie if $this->data[0][0] == 'B'
*
* Otherwise, its value is null.
*
- * @var GeoBody
+ * @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
+ *
+ * @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");
+ throw new Exception("Invalid expression: $global");
}
} else {
global $db;
$name = $db->sql_escape($global);
$sql = "SELECT location_code FROM " . TABLE_LOCATIONS . " WHERE location_name LIKE '$name'";
$code = $db->sql_query_express($sql);
if ($code) {
$this->data[0] = $code;
return;
}
throw new Exception("Invalid expression: $global");
}
-
+
//TODO: handle $local in a better way: from the global location, gets
//a local location handler. Or a some inheriance, like a class
//HypershipGeoLocation extending GeoLocation.
if ($local !== null) $this->data[1] = $local;
-
+
$this->load_classes();
}
-
+
/**
* Gets $place, $body and $ship instances if they're needed
*/
function load_classes () {
//No data, no class to load
if (!count($this->data))
return;
-
+
//Loads global classes
$global = $this->data[0];
$code = substr($global, 1, 5);
switch ($global[0]) {
case 'B':
switch (strlen($global)) {
case 9:
$this->place = GeoPlace::from_code($global);
-
+
case 6:
$this->body = new GeoBody($code);
break;
}
break;
-
+
case 'S':
$this->ship = new Ship($code);
break;
-
+
case 'x':
$coords = sscanf($global, "xyz: [%d, %d, %d]");
if (count($coords) == 3) {
$this->point3D = new GeoPoint3D($coords[0], $coords[1], $coords[2]);
}
break;
}
}
-
+
/**
* Magic method called when a unknown property is get.
- *
+ *
* Handles $global, $local, $type, $body_code, $ship_code, $place_code,
* $body_kind, $containsGlobalLocation, $containsLocalLocation.
*/
function __get ($variable) {
switch ($variable) {
/* main variables */
-
+
case 'global':
return $this->data[0];
break;
-
+
case 'local':
return (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;
+ break;
}
}
-
+
/**
* Checks if the place exists
*
* @return bool true if the place exists ; otherwise, false.
- *
+ *
* @todo handles alias
*/
function exists () {
$n = count($this->data);
-
+
//If not defined, it doesn't exist
if ($n == 0) return false;
-
+
//Checks global location
switch ($this->data[0][0]) {
case 'B':
switch (strlen($this->data[0])) {
case 9:
if (!$place = GeoPlace::from_code($this->data[0]))
return false;
break;
-
+
case 6:
$body = new GeoBody(substr($this->data[0], 1));
if ($body->lastError) return false;
break;
-
+
default:
message_die(GENERAL_ERROR, "Invalid global location expression size: " . $this->data[0], "GeoLocation exists method", __LINE__, __FILE__);
-
+
}
break;
-
+
case 'S':
$ship = new Ship(substr($this->data[0], 1));
if ($body->lastError) return false;
break;
-
+
default:
message_die(GENERAL_ERROR, "Invalid global location expression size: " . $this->data[0], "GeoLocation exists method", __LINE__, __FILE__);
return false;
}
-
+
if ($n > 1) {
if (!isset($place)) {
message_die(GENERAL_ERROR, "Can't check if a local place exists for the following location: " . $this->data[0], "GeoLocation exists method", __LINE__, __FILE__);
}
if (!$place->is_valid_local_location($this->data[1])) {
return false;
}
}
-
+
return true;
}
-
+
/**
* Checks if the place is equals at the specified expression or place
*
* @return bool true if the places are equals ; otherwise, false.
*
* @todo Create a better set of rules to define when 2 locations are equall.
*/
function equals ($expression) {
//Are global location equals?
-
+
//TODO: create a better set of rules to define when 2 locations are equa l.
if (is_a($expression, 'GeoLocation')) {
if (!$this->equals($expression->data[0])) {
return false;
}
if (count($expression->data) + count($this->data) > 2) {
return $expression->data[1] == $this->data[1];
}
}
if ($expression == $this->data[0]) return true;
-
+
$n1 = strlen($expression);
$n2 = strlen($this->data[0]);
-
+
if ($n1 > $n2) {
return substr($expression, 0, $n2) == $this->data[0];
}
-
+
return false;
}
-
+
/**
* Represents the current location instance as a string
*
* @return string a string representing the current location
*/
function __toString () {
if (!$this->data[0])
return "";
-
+
switch ($this->data[0][0]) {
case 'S':
$ship = new Ship($this->ship_code);
$location[] = $ship->name;
break;
-
+
case 'B':
$body = new GeoBody($this->body_code);
$location[] = $body->name ? $body->name : lang_get('UnknownBody');
-
+
if (strlen($this->data[0]) == 9) {
$place = GeoPlace::from_code($this->data[0]);
$location[] = $place->name ? $place->name : lang_get('UnknownPlace');
}
break;
-
+
case 'x':
$pt = $this->point3D->to_spherical();
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));
+
+ 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;
+ break;
}
}
}
?>
diff --git a/includes/geo/place.php b/includes/geo/place.php
index 18a60f7..a604200 100755
--- a/includes/geo/place.php
+++ b/includes/geo/place.php
@@ -1,216 +1,216 @@
<?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 $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;
return false;
}
$this->body_code = $row['body_code'];
$this->code = $row['place_code'];
$this->name = $row['place_name'];
$this->description = $row['place_description'];
$this->location_local_format = $row['location_local_format'];
//Explodes place_status SET field in boolean variables
if ($row['place_status']) {
$flags = explode(',', $row['place_status']);
foreach ($flags as $flag) {
$this->$flag = true;
}
}
return true;
}
-
+
/**
* Gets status field value
*
* @return string the status field value (e.g. "requiresPTA,default")
*/
function get_status () {
$flags = array('start', 'hidden');
foreach ($flags as $flag) {
if ($this->$flag == true) {
$status[] = $flag;
}
}
return implode(',', $status);
}
-
+
/**
* Saves to database
*/
function save_to_database () {
global $db;
-
+
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$body_code = $db->sql_escape($this->body_code);
$code = $db->sql_escape($this->code);
$name = $db->sql_escape($this->name);
$description = $db->sql_escape($this->description);
$status = $this->get_status();
$location_local_format = $db->sql_escape($this->location_local_format);
//Updates or inserts
$sql = "REPLACE INTO " . 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;
+ 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 ccd9ec8..3c700a3 100755
--- a/includes/geo/point3D.php
+++ b/includes/geo/point3D.php
@@ -1,241 +1,241 @@
<?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
*
* 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:
* 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 to_spherical () {
return GeoGalaxy::cartesian_to_spherical($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 to_spherical2 () {
return GeoGalaxy::cartesian_to_spherical2($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/scene.php b/includes/geo/scene.php
index e289a63..c2310ab 100755
--- a/includes/geo/scene.php
+++ b/includes/geo/scene.php
@@ -1,214 +1,214 @@
<?php
/**
* Geo scene 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('location.php');
require_once('octocube.php');
require_once('sceneindex.php');
if (!defined('SCENE_DIR')) {
/**
* The directory containing scenes files
*/
define('SCENE_DIR', 'content/scenes');
}
/**
* Geo scene class
*
* This class provides methods to determine and renders the local scene.
*/
class GeoScene {
/**
* Last error or warning
*
* @var string
*/
public $lastError;
/**
* File scene to serve
*
* @var string
*/
public $sceneFile;
/**
* The location of the scene to print
*
* @var GeoLocation
*/
public $location;
/**
* Initializes a new GeoScene instance
*
* @param GeoLocation $location location the scene is to print
*/
function __construct ($location) {
$this->location = $location;
//Gets local scene
if ($location->containsLocalLocation) {
if ($this->get_local_scene()) return;
}
//Gets global scene
if ($location->containsGlobalLocation) {
if ($this->get_global_scene()) return;
}
//If not scene found, let's set a warning
$this->lastError = "No scene found.";
}
/**
* Gets local scene
*
* @return boolean true if a scene have been found ; otherwise, false.
*/
private function get_local_scene () {
//From the index
$index = GeoSceneIndex::Load(SCENE_DIR);
if ($tpl = $index->get_local_template($this->location->global, $this->location->local)) {
$this->sceneFile = SCENE_DIR . '/' . $tpl;
return true;
}
-
+
//From filename
$expression = $this->location->global . ' ' . $this->location->local;
if ($this->try_get_scene($expression)) {
return true;
}
return false;
}
/**
* Gets global scene
*
* @return boolean true if a scene have been found ; otherwise, false.
*/
private function get_global_scene () {
$location = $this->location;
if ($location->place) {
if ($this->try_get_scene($location->global)) {
return true;
}
}
if ($location->body) {
if ($this->try_get_scene('B' . $location->body->code)) {
return true;
}
}
return false;
}
/**
* Gets file extension
*
* @param string $file the file path
* @return string the file extension
*/
public static function get_file_extension ($file) {
$pathinfo = pathinfo($file);
return $pathinfo['extension'];
}
/**
* Renders the file
*
* @todo Add standard code to render .swf Flash/ShockWave files.
*/
public function render () {
if ($file = $this->sceneFile) {
switch ($ext = GeoScene::get_file_extension($file)) {
case 'png':
case 'jpg':
case 'gif':
case 'bmp':
echo "<img src=\"$file\" />";
break;
case 'tpl':
global $smarty, $Config;
$template_dir = $smarty->template_dir;
$smarty->template_dir = array(getcwd(), $template_dir);
//$this->location is the object reference
//Some objects like the hypership move, so we also need to know where there are.
//From the template, this object location is assigned to $location
//To get $this->location from template, use $CurrentPerso->location
if ($this->location->body) {
$smarty->assign("location", new GeoLocation($this->location->body->location));
} elseif ($this->location->ship) {
$smarty->assign("location", new GeoLocation($this->location->ship->location));
}
//Gets zone information
require_once('includes/content/zone.php');
if ($zone = ContentZone::at($this->location->global, $this->location->local)) {
$smarty->assign('zone', $zone);
}
//Scene-specific variables
$smarty->assign("SCENE_URL", defined('SCENE_URL') ? SCENE_URL : '/' . SCENE_DIR);
if ($Config['builder']['hotglue']['enable']) {
$smarty->assign("HOTGLUE", $Config['builder']['hotglue']['URL']);
}
lang_load('scenes.conf', $this->location->global);
//Displays scene, then restores regular settings
$smarty->display($file);
$smarty->template_dir = $template_dir;
break;
case 'php':
message_die(HACK_ERROR, ".php scene files not allowed without review", '', __LINE__, __FILE__);
default:
message_die(GENERAL_ERROR, "Can't handle $ext extension for $file scene", 'GeoScene render error', __LINE__, __FILE__);
}
echo "\n\n";
}
}
/**
* Tries to get the scene file.
*
* It will tries to find in the scene directory a file with $code as name,
* and .tpl .png .gif .bmp .swf .html or .php as extension.
*
* @param string the location code (and filename)
* @return bool true if a scene file have been found and set ; otherwise, false.
*/
private function try_get_scene ($code) {
$file = SCENE_DIR . "/$code";
$extensions = array('tpl', 'png', 'jpg', 'gif', 'bmp', 'swf', 'html', 'php');
foreach ($extensions as $ext) {
if (file_exists("$file.$ext")) {
$this->sceneFile = "$file.$ext";
return true;
}
}
return false;
}
}
?>
diff --git a/includes/mysql.php b/includes/mysql.php
index f3178b1..6e15b75 100755
--- a/includes/mysql.php
+++ b/includes/mysql.php
@@ -1,183 +1,183 @@
<?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
*/
if (!defined('SQL_LAYER')) {
/**
* Defines the SQL engine layer implented for our SQL abstraction class:
* MySQL
*/
define('SQL_LAYER', 'mysql');
-
+
/**
* 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]
*/
function __construct($host = 'localhost', $username = 'root', $password = '' , $database = '') {
//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;
+ 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'");
}
}
}
-
+
/**
* The main sql_db instance
- *
+ *
* @global sql_db $db
*/
$db = new sql_db($Config['sql']['host'], $Config['sql']['username'], $Config['sql']['password'], $Config['sql']['database']);
$db->set_charset('utf8');
-
+
//By security, we unset the SQL parameters, so you can safely output Zed
//config parts (there's still the problem of the secret key, but it's less
//a security problem than database password)
- unset($Config['sql']);
+ unset($Config['sql']);
}
?>
\ No newline at end of file
diff --git a/includes/objects/application.php b/includes/objects/application.php
index b0a50e7..f612937 100755
--- a/includes/objects/application.php
+++ b/includes/objects/application.php
@@ -1,177 +1,177 @@
<?php
/**
* Application class
*
* Zed. The immensity of stars. The HyperShip. The people.
- *
+ *
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2010-02-10 02:40 Autogenerated by Pluton Scaffolding
* Some API bits
- *
+ *
* @package Zed
* @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 $id;
public $code;
public $name;
public $api_key;
public $description;
-
+
/**
* Initializes a new instance
- *
+ *
* @param int $id the primary key
*/
function __construct ($id = null) {
if ($id) {
$this->id = $id;
$this->load_from_database();
}
}
-
+
/**
* Loads the object Application (ie fill the properties) from the $_POST array
*/
function load_from_form () {
if (array_key_exists('code', $_POST)) $this->code = $_POST['code'];
if (array_key_exists('name', $_POST)) $this->name = $_POST['name'];
if (array_key_exists('api_key', $_POST)) $this->api_key = $_POST['api_key'];
if (array_key_exists('description', $_POST)) $this->description = $_POST['description'];
}
-
+
/**
* Loads the object Application (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$id = $db->sql_escape($this->id);
$sql = "SELECT * FROM applications WHERE application_id = '" . $id . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query applications", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "Application unkwown: " . $this->id;
return false;
}
$this->code = $row['application_code'];
$this->name = $row['application_name'];
$this->api_key = $row['api_key'];
$this->description = $row['application_description'];
return true;
}
-
+
/**
* Saves to database
*/
function save_to_database () {
global $db;
-
+
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$code = $db->sql_escape($this->code);
$name = $db->sql_escape($this->name);
$api_key = $db->sql_escape($this->api_key);
$description = $db->sql_escape($this->description);
//Updates or inserts
$sql = "REPLACE INTO applications (`application_id`, `application_code`, `application_name`, `api_key`, `application_description`) VALUES ($id, '$code', '$name', '$api_key', '$description')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
-
+
if (!$id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
}
-
+
/*
* ----------------------------------------------------------------------- *
* Application API methods
* ----------------------------------------------------------------------- *
*/
-
+
/**
* Loads an Application object from its API key
- *
+ *
* @param string Application API key GUID
* @return Application the application matching the API key
*/
static function from_api_key ($key) {
global $db;
$key = $db->sql_escape($key);
$sql = "SELECT * FROM applications WHERE api_key = '" . $key . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query applications", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result))
return null;
//Fills app information
$app = new Application();
$app->id = $row['application_id'];
$app->code = $row['application_code'];
$app->name = $row['application_name'];
$app->api_key = $row['api_key'];
$app->description = $row['application_description'];
-
+
return $app;
}
-
+
/**
* Gets the perso ID from an application user key
- *
+ *
* @param string $userkey User application key GUID
* @return int the perso ID
*/
function get_perso_id ($userkey) {
global $db;
-
+
$id = $db->sql_escape($this->id);
$userkey = $db->sql_escape($userkey);
-
+
$sql = "SELECT perso_id FROM applications_userkeys WHERE api_userkey = '$userkey' AND application_id = '$id'";
return $db->sql_query_express($sql);
}
-
+
/**
* Generates a key for the specified perso and current application.
- *
+ *
* @param int $perso_id The perso ID
* @param string $userkey User application key GUID (optionnal)
* @return Application User application key GUID
*/
function generate_userkey ($perso_id = null, $userkey = null) {
global $CurrentPerso;
-
+
//Ensures we've a key and someone to be assigned it
if ($userkey === null) $userkey = new_guid();
$perso = ($perso_id === null) ? $CurrentPerso : Perso::get($perso_id);
-
+
//Saves key
$perso->set_flag('api.app.keys.' . $this->id, $userkey);
-
+
//Returns it
return $userkey;
}
}
-
+
?>
\ No newline at end of file
diff --git a/includes/objects/content.php b/includes/objects/content.php
index 3e91334..4796c33 100755
--- a/includes/objects/content.php
+++ b/includes/objects/content.php
@@ -1,304 +1,304 @@
<?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
* 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 $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'];
+ 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'];
+ if (array_key_exists('location_global', $_POST)) $this->location_global = $_POST['location_global'];
}
}
-
+
/**
* Loads the object Content (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$id = $db->sql_escape($this->id);
$sql = "SELECT * FROM content WHERE content_id = '" . $id . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query content", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "Content unkwown: " . $this->id;
return false;
}
$this->load_from_row($row);
return true;
}
-
+
/**
* Loads the object from row
*/
function load_from_row ($row) {
$this->id = $row['content_id'];
$this->path = $row['content_path'];
$this->user_id = $row['user_id'];
$this->perso_id = $row['perso_id'];
$this->title = $row['content_title'];
$this->location_global = $row['location_global'];
$this->location_local = $row['location_local'];
$this->location_k = $row['location_k'];
-
+
if (array_key_exists('perso_name', $row)) $this->perso_name = $row['perso_name'];
if (array_key_exists('perso_nickname', $row)) $this->perso_nickname = $row['perso_nickname'];
}
-
+
/**
* Saves to database
*/
function save_to_database () {
global $db;
-
+
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$path = $db->sql_escape($this->path);
$user_id = $db->sql_escape($this->user_id);
$perso_id = $db->sql_escape($this->perso_id);
$title = $db->sql_escape($this->title);
-
+
$location_global = ($this->location_global !== null) ? "'" . $db->sql_escape($this->location_global) . "'" : 'NULL';
$location_local = ($this->location_local !== null) ? "'" . $db->sql_escape($this->location_local) . "'" : 'NULL';
$location_k = ($this->location_k !== null) ? "'" . $db->sql_escape($this->location_k) . "'" : 'NULL';
//Updates or inserts
$sql = "REPLACE INTO content_files (`content_id`, `content_path`, `user_id`, `perso_id`, `content_title`) VALUES ($id, '$path', '$user_id', '$perso_id', '$title')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't save content", '', __LINE__, __FILE__, $sql);
}
-
+
if (!$this->id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
-
+
//Saves location
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$sql = "REPLACE INTO content_locations (location_global, location_local, location_k, content_id) VALUES ($location_global, $location_local, $location_k, $id)";
if (!$db->sql_query($sql))
message_die(SQL_ERROR, "Can't save content location", '', __LINE__, __FILE__, $sql);
}
/* -------------------------------------------------------------
File handling helper methods
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
+
/**
* Determines if the extension is valid
- *
+ *
* @param string $ext The extension (without dot)
* @return boolean true if this extension is valid ; otherwise, false.
*/
function is_valid_extension ($ext) {
switch ($ext = strtolower($ext)) {
//Pictures
case 'jpg':
case 'gif':
case 'png':
case 'bmp':
case 'xbm':
return true;
-
+
//Denied extension
default:
return false;
}
}
-
+
/**
* Creates a directory
*
* @param string $dir the directory to create
*/
function create_directory ($directory) {
if (!file_exists($directory)) {
@mkdir($directory); //Creates new directory, chmod 777
}
}
-
+
/**
* Handles uploaded file
*
* @return bool true if the file have been handled
*/
function handle_uploaded_file ($fileArray) {
if (count($fileArray) && $fileArray['error'] == 0) {
$this->create_directory("content/users/$this->user_id");
$this->path = "content/users/$this->user_id/$fileArray[name]";
if (!self::is_valid_extension(get_extension($fileArray[name]))) {
return false;
}
if (move_uploaded_file($fileArray['tmp_name'], $this->path)) {
return true;
} else {
$this->path = null;
return false;
}
} else {
return false;
}
}
-
+
/**
* Generates a thumbnail using ImageMagick binary
- *
+ *
* @return boolean true if the thumbnail command returns 0 as program exit code ; otherwise, false
*/
function generate_thumbnail () {
global $Config;
- //Builds thumbnail filename
+ //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
+ * @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);
+ $location_local = $db->sql_escape($location_local);
$sql = "SELECT c.*, p.perso_nickname, p.perso_name FROM content c, persos p WHERE c.location_global = '$location_global' AND c.location_local = '$location_local' AND p.perso_id = c.perso_id ORDER BY location_k ASC";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't get content", '', __LINE__, __FILE__, $sql);
}
-
+
//Fills content array
$contents = array();
while ($row = $db->sql_fetchrow($result)) {
$content = new Content();
$content->load_from_row($row);
$contents[] = $content;
}
-
+
return $contents;
}
}
-
+
?>
\ No newline at end of file
diff --git a/includes/objects/invite.php b/includes/objects/invite.php
index c92af77..0b790a3 100755
--- a/includes/objects/invite.php
+++ b/includes/objects/invite.php
@@ -1,198 +1,198 @@
<?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]);
+ } while ($row[0]);
}
-
+
/**
* Loads the object Invite (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$code = $db->sql_escape($this->code);
$sql = "SELECT * FROM " . TABLE_USERS_INVITES . " WHERE invite_code = '" . $code . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query invite codes", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "Invite code unkwown: " . $this->code;
return false;
}
$this->code = $row['invite_code'];
$this->date = $row['invite_date'];
$this->from_user_id = $row['invite_from_user_id'];
$this->from_perso_id = $row['invite_from_perso_id'];
$this->to_user_id = $row['invite_to_user_id'];
return true;
}
-
+
/**
* Determines wheter the current invite code have been claimed by an user.
- *
+ *
* @return true if the code have been claimed ; otherwise, false.
*/
function is_claimed () {
return (bool)$this->to_user_id;
}
-
+
/**
* Saves to database
*/
function save_to_database () {
global $db;
-
+
$code = $db->sql_escape($this->code);
$date = $db->sql_escape($this->date);
$from_user_id = $db->sql_escape($this->from_user_id);
$from_perso_id = $db->sql_escape($this->from_perso_id);
$to_user_id = $this->to_user_id ? "'" . $db->sql_escape($this->to_user_id) . "'" : 'NULL';
//Updates or inserts
$sql = "REPLACE INTO " . TABLE_USERS_INVITES . " (`invite_code`, `invite_date`, `invite_from_user_id`, `invite_from_perso_id`, `invite_to_user_id`) VALUES ('$code', '$date', '$from_user_id', '$from_perso_id', $to_user_id)";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save invite code", '', __LINE__, __FILE__, $sql);
}
}
-
+
/**
* Deletes the invite
*/
function delete () {
global $db;
$code = $db->sql_escape($this->code);
$sql = "DELETE FROM " . TABLE_USERS_INVITES . " WHERE invite_code = '$code'";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save delete code", '', __LINE__, __FILE__, $sql);
}
}
-
+
/**
* Creates an invite code
- *
+ *
* @param int $user_id user id
* @param int $perso_id perso id
* @return string the invite code
*/
static function create ($user_id, $perso_id) {
$invite = new Invite();
$invite->from_perso_id = $perso_id;
$invite->from_user_id = $user_id;
$invite->save_to_database();
return $invite->code;
}
-
+
/**
* Gets invites generated by the specified perso ID
- *
+ *
* @param int $perso_id the perso whom to get the invites
* @return Array an array of string, each line being an invite code
*/
static function get_invites_from ($perso_id) {
global $db;
$sql = "SELECT invite_code FROM " . TABLE_USERS_INVITES
. " WHERE invite_from_perso_id = $perso_id AND invite_to_user_id IS NULL ORDER BY invite_date ASC";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't access invite users table", '', __LINE__, __FILE__, $sql);
}
$codes = array();
while ($row = $db->sql_fetchrow($result)) {
$codes[] = $row['invite_code'];
}
return $codes;
}
-
+
/**
* Gets the perso ID who invited the specified perso
*
* @param int $perso_id the perso whom to get the invites
* @return int|null the perso whom to get the invites ; or null, if nobody have invited him
*/
static function who_invited ($perso_id) {
global $db;
$perso = Perso::get($perso_id);
-
+
if ($user_id = $perso->user_id) {
$sql = "SELECT invite_from_perso_id FROM " . TABLE_USERS_INVITES . " WHERE invite_to_user_id = '$user_id'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't access invite users table", '', __LINE__, __FILE__, $sql);
}
if ($row = $db->sql_fetchrow($result)) {
return $row[0];
}
}
-
+
return null;
}
-
+
}
-
+
?>
diff --git a/includes/objects/message.php b/includes/objects/message.php
index 1ef8004..8912e72 100755
--- a/includes/objects/message.php
+++ b/includes/objects/message.php
@@ -1,157 +1,157 @@
<?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 $id;
public $date;
public $from;
public $to;
public $text;
public $flag;
-
+
/**
* Initializes a new instance
- *
+ *
* @param int $id the primary key
*/
function __construct ($id = null) {
if ($id) {
$this->id = $id;
$this->load_from_database();
} else {
$this->date = time();
$this->flag = 0; //unread
}
}
-
+
/**
* Loads the object Message (ie fill the properties) from the $_POST array
*/
function load_from_form () {
if (array_key_exists('date', $_POST)) $this->date = $_POST['date'];
if (array_key_exists('from', $_POST)) $this->from = $_POST['from'];
if (array_key_exists('to', $_POST)) $this->to = $_POST['to'];
if (array_key_exists('text', $_POST)) $this->text = $_POST['text'];
if (array_key_exists('flag', $_POST)) $this->flag = $_POST['flag'];
}
-
+
/**
* Loads the object Message (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$sql = "SELECT * FROM messages WHERE message_id = '" . $this->id . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query messages", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "Message unkwown: " . $this->id;
return false;
}
$this->date = $row['message_date'];
$this->from = $row['message_from'];
$this->to = $row['message_to'];
$this->text = $row['message_text'];
$this->flag = $row['message_flag'];
return true;
}
-
+
/**
* Saves to database
*/
function save_to_database () {
global $db;
-
+
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$date = $db->sql_escape($this->date);
$from = $db->sql_escape($this->from);
$to = $db->sql_escape($this->to);
$text = $db->sql_escape($this->text);
$flag = $db->sql_escape($this->flag);
//Updates or inserts
$sql = "REPLACE INTO messages (`message_id`, `message_date`, `message_from`, `message_to`, `message_text`, `message_flag`) VALUES ($id, '$date', '$from', '$to', '$text', '$flag')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
-
+
if (!$id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
}
-
+
/**
* Sends the message
*/
function send () {
$this->save_to_database();
//TODO: triggers new message notifier
}
-
+
/**
* Deletes 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 d330ce2..c701c6a 100755
--- a/includes/objects/motd.php
+++ b/includes/objects/motd.php
@@ -1,96 +1,96 @@
<?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;
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/port.php b/includes/objects/port.php
index f24ac40..e819b2f 100755
--- a/includes/objects/port.php
+++ b/includes/objects/port.php
@@ -1,199 +1,199 @@
<?php
/**
* Port class
*
* Zed. The immensity of stars. The HyperShip. The people.
- *
+ *
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2010-02-09 19:17 Autogenerated by Pluton Scaffolding
- *
+ *
* @package Zed
* @subpackage Model
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
require_once("includes/geo/location.php");
/**
* Port class
*
* This class maps the ports table.
*
* The class also provides helper methods to handle ports at specified location.
*/
class Port {
- public $id;
+ public $id;
public $location_global;
public $location_local;
public $name;
-
+
public $hidden;
public $requiresPTA;
public $default;
-
+
/**
* Initializes a new instance
* @param int $id the primary key
*/
function __construct ($id = NULL) {
if ($id) {
$this->id = $id;
$this->load_from_database();
}
}
-
+
/**
* Loads the object Port (ie fill the properties) from the $_POST array
*/
function load_from_form () {
if (array_key_exists('location_global', $_POST)) $this->location_global = $_POST['location_global'];
if (array_key_exists('location_local', $_POST)) $this->location_local = $_POST['location_local'];
if (array_key_exists('name', $_POST)) $this->name = $_POST['name'];
-
+
if (array_key_exists('hidden', $_POST)) $this->hidden = $_POST['hidden'] ? true : false;
if (array_key_exists('requiresPTA', $_POST)) $this->requiresPTA = $_POST['requiresPTA'] ? true : false;
if (array_key_exists('default', $_POST)) $this->hidden = $_POST['default'] ? true : false;
}
-
+
/**
* Loads the object Port (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$id = $db->sql_escape($this->id);
$sql = "SELECT * FROM " . TABLE_PORTS . " WHERE port_id = '" . $id . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query ports", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "Port unkwown: " . $this->id;
return false;
}
$this->location_global = $row['location_global'];
$this->location_local = $row['location_local'];
$this->name = $row['port_name'];
-
+
//Explodes place_status SET field in boolean variables
if ($row['place_status']) {
$flags = explode(',', $row['port_status']);
foreach ($flags as $flag) {
$this->$flag = true;
}
}
return true;
}
-
+
/**
* Gets status field value
*
* @return string the status field value (e.g. "requiresPTA,default")
*/
function get_status () {
$flags = array('hidden', 'requiresPTA', 'default');
foreach ($flags as $flag) {
if ($this->$flag) {
$status[] = $flag;
}
}
return implode(',', $status);
}
-
+
/**
* Saves to database
*/
function save_to_database () {
global $db;
-
+
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$location_global = $db->sql_escape($this->location_global);
$location_local = $db->sql_escape($this->location_local);
$name = $db->sql_escape($this->name);
$status = $this->get_status();
//Updates or inserts
$sql = "REPLACE INTO " . TABLE_PORTS . " (`port_id`, `location_global`, `location_local`, `port_name`, `port_status`) VALUES ($id, '$location_global', '$location_local', '$name', '$status')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
-
+
if (!$id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
}
-
+
/**
* Determines if the specified location have a port
- *
+ *
* @param string $location_global the global location
* @return boolean true if there is a spatioport exactly at the specified location ; otherwise, false.
*/
static function have_port ($location_global) {
- return (get_port_id($location_global) !== NULL);
+ 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 $row['port_id'];
}
return null;
}
-
+
/**
* Gets default port, from specified global location
- *
+ *
* @param string $location_global the global location
* @return Port the port near this location ; null if there isn't port there.
*/
static function from_location ($location_global) {
$havePlace = strlen($location_global) == 9;
$port_id = null;
-
+
if ($havePlace) {
//Checks if there's a port at specified location
$port_id = self::get_port_id($location_global);
}
-
+
if ($port_id == null) {
//Nearest default port.
//If place have been specified (B0001001), we've to found elsewhere
//==> B00001%
global $db;
$loc = $db->sql_escape(substr($location_global, 0, 6));
$sql = "SELECT port_id FROM " . TABLE_PORTS . " WHERE location_global LIKE '$loc%'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't get port", '', __LINE__, __FILE__, $sql);
}
if ($row = $db->sql_fetchrow($result)) {
$port_id = $row['port_id'];
} else {
return null;
}
}
-
+
return new Port($port_id);
}
}
-
+
?>
\ No newline at end of file
diff --git a/includes/objects/profile.php b/includes/objects/profile.php
index 9b8c9b6..c2f1924 100755
--- a/includes/objects/profile.php
+++ b/includes/objects/profile.php
@@ -1,148 +1,148 @@
<?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;
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;
}
}
-
+
?>
\ No newline at end of file
diff --git a/includes/objects/profilecomment.php b/includes/objects/profilecomment.php
index cbf8980..19a78a0 100755
--- a/includes/objects/profilecomment.php
+++ b/includes/objects/profilecomment.php
@@ -1,131 +1,131 @@
<?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;
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 efba394..dca5577 100755
--- a/includes/objects/profilephoto.php
+++ b/includes/objects/profilephoto.php
@@ -1,203 +1,203 @@
<?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;
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;
}
}
-}
+}
?>
\ No newline at end of file
diff --git a/includes/objects/ship.php b/includes/objects/ship.php
index 4ee3a6f..afa1ec7 100755
--- a/includes/objects/ship.php
+++ b/includes/objects/ship.php
@@ -1,327 +1,327 @@
<?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;
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
+
+ //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
+ * 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
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/settings/page.php b/includes/settings/page.php
index 9640e8f..b930577 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
+ * @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.";
}
if ($setting->object) $objects[] = $setting->object;
}
}
-
+
//Saves object (when the SETTINGS_SAVE_METHOD save method exists)
if (count($objects)) {
$objects = array_unique($objects);
foreach ($objects as $object) {
$object = $GLOBALS[$object];
if (method_exists($object, SETTINGS_SAVE_METHOD)) {
call_user_func(array($object, SETTINGS_SAVE_METHOD));
}
}
}
-
+
}
}
\ No newline at end of file
diff --git a/includes/settings/preferences.xml b/includes/settings/preferences.xml
index acad745..557eeae 100644
--- a/includes/settings/preferences.xml
+++ b/includes/settings/preferences.xml
@@ -1,148 +1,148 @@
<?xml version="1.0" encoding="UTF-8"?>
<settings>
<page id="account" title="Account">
<setting id="username">
<key>Username</key>
<field>text</field>
<object>CurrentUser</object>
<property>name</property>
</setting>
<setting id="password">
<key>Password</key>
<field>password</field>
<object>CurrentUser</object>
<handler>
<get>
return "";
</get>
<set>
<![CDATA[
if ($value) {
global $CurrentUser;
$CurrentUser->set_password($value);
return true;
}
]]>
</set>
</handler>
</setting>
<setting id="email">
<key>Email</key>
<field>text</field>
<object>CurrentUser</object>
- <property>email</property>
+ <property>email</property>
</setting>
<setting id="OpenID">
<key>OpenID</key>
<field>text</field>
<handler>
<get>
<![CDATA[
global $db, $CurrentUser;
$sql = "SELECT auth_identity FROM " . TABLE_USERS_AUTH . " WHERE auth_type = 'OpenID' AND user_id = $CurrentUser->id LIMIT 1";
return $db->sql_query_express($sql);
]]>
</get>
<set>
<![CDATA[
global $db, $CurrentUser, $smarty;
$openid = $db->sql_escape($value);
$sql = "SELECT user_id FROM users_auth WHERE auth_type = 'OpenID' AND auth_identity LIKE '$openid'";
if ($user_id = $db->sql_query_express($sql)) {
if ($user_id == $CurrentUser->id) {
$smarty->assign('WAP', "This OpenID is already linked to your account.");
} else {
$smarty->assign('WAP', "This OpenID is currently linked to another account.");
supralog('security', "User tried to add OpenID $openid which belongs to $user_id", "preferences");
}
return false;
}
$CurrentUser->set_OpenID($value);
return true;
]]>
</set>
</handler>
</setting>
</page>
-
+
<page id="perso" title="Information">
<setting id="longname">
<key>Name</key>
<field>text</field>
<object>CurrentPerso</object>
- <property>name</property>
+ <property>name</property>
</setting>
<setting id="nickname">
<key>Nickname</key>
<field>validationtext</field>
<regExp>[a-z][a-z0-9 ]+</regExp>
<object>CurrentPerso</object>
- <property>nickname</property>
+ <property>nickname</property>
</setting>
<setting id="race">
<key>Race</key>
<field>text</field>
<object>CurrentPerso</object>
- <property>race</property>
+ <property>race</property>
</setting>
<setting id="sex">
<key>Sex</key>
<field>filteredlist</field>
<object>CurrentPerso</object>
- <property>sex</property>
+ <property>sex</property>
<choices>
<choice>
<key>male</key>
<value>M</value>
</choice>
<choice>
<key>female</key>
<value>F</value>
</choice>
<choice>
<key>neutral</key>
<value>N</value>
</choice>
<choice>
<key>both</key>
<value>2</value>
</choice>
</choices>
</setting>
</page>
-
+
<page id="smartline" title="SmartLine">
<setting id="show">
<key>SmartlineShow</key>
<field>checkbox</field>
<handler>
<set><![CDATA[
global $CurrentPerso;
$flag_value = $value ? 1 : 0;
$CurrentPerso->set_flag('site.smartline.show', $flag_value);
return true;
]]></set>
<get><![CDATA[
global $CurrentPerso;
return (bool)$CurrentPerso->get_flag('site.smartline.show', true);
]]></get>
</handler>
</setting>
<setting id="method">
<key>SmartlineMethod</key>
<field>checkbox</field>
<handler>
<set><![CDATA[
global $CurrentPerso;
$CurrentPerso->set_flag('site.smartline.method', $value ? 'post' : 'get');
return true;
]]></set>
<get><![CDATA[
global $CurrentPerso;
$flag = $CurrentPerso->get_flag('site.smartline.method', 'post');
return $flag != "get";
]]></get>
</handler>
</setting>
</page>
-</settings>
\ No newline at end of file
+</settings>
\ No newline at end of file
diff --git a/includes/settings/setting.php b/includes/settings/setting.php
index 05adca2..f1b566f 100755
--- a/includes/settings/setting.php
+++ b/includes/settings/setting.php
@@ -1,175 +1,175 @@
<?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");
}
-
+
/**
* Saves setting
- *
+ *
* @return mixed the SETTINGS_SAVE_METHOD method value, or false if there's no method call;
*/
function save () {
if ($this->object) {
$object = $GLOBALS[$this->object];
if (method_exists($object, SETTINGS_SAVE_METHOD)) {
return call_user_func(array($object, SETTINGS_SAVE_METHOD));
}
}
-
+
return false;
}
/**
* Initializes a new instance of Setting class from a XML element
- *
+ *
* @param SimpleXMLElement the xml element to parse
* @return Setting the setting class
*/
static function from_xml ($xml) {
//Reads attributes
$id = '';
foreach ($xml->attributes() as $key => $value) {
switch ($key) {
case 'id':
$id = (string)$value;
break;
-
+
default:
message_die(GENERAL_ERROR, "Unknown attribute: $key = \"$value\"", "Settings error");
}
}
-
+
//id attribute is mandatory
if (!$id) {
message_die(GENERAL_ERROR, "Setting without id. Please add id='' in <setting> tag", "Settings error");
}
-
+
//Initializes new Setting instance
$setting = new Setting($id);
-
+
//Parses simple <tag>value</tag>
$properties = array('key', 'field', 'object', 'property', 'method', 'regExp');
foreach ($properties as $property) {
if ($xml->$property)
$setting->$property = (string)$xml->$property;
}
-
+
//Parses <handler>
$setting->handler = array();
if ($xml->handler) {
if ($xml->handler->get) $setting->handler['get'] = (string)$xml->handler->get;
if ($xml->handler->set) $setting->handler['set'] = (string)$xml->handler->set;
}
-
+
//Parses <choices>
if ($xml->choices) {
foreach ($xml->choices->choice as $choiceXml) {
$setting->choices[(string)$choiceXml->key] = (string)$choiceXml->value;
-
+
}
}
return $setting;
}
}
?>
diff --git a/includes/settings/settings.php b/includes/settings/settings.php
index e64f3cc..bda0b54 100755
--- a/includes/settings/settings.php
+++ b/includes/settings/settings.php
@@ -1,84 +1,84 @@
<?php
/**
* Settings
*
* Zed. The immensity of stars. The HyperShip. The people.
- *
+ *
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* @package Zed
* @subpackage Settings
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
/**
* The method to call in your objects, to save data.
*/
define("SETTINGS_SAVE_METHOD", "save_to_database");
require_once("page.php");
/**
* Settings
*
* This class maps the Settings format (preferences.xml)
*
* It allows to generate settings web forms and handle replies, from a
* XML document.
*/
class Settings {
-
+
/**
* The file path
- *
+ *
* @var string
*/
public $file;
-
+
/**
* A collection of SettingsPage items
- *
+ *
* @var Array
*/
public $pages;
-
+
/**
* Initializes a new instance of Settings class
*
* @param string $xmlFile The XML document which defines the settings.
*/
function __construct ($xmlFile) {
//Opens .xml
if (!file_exists($xmlFile)) {
message_die(GENERAL_ERROR, "$xmlFile not found.", "Settings load error");
}
$this->file = $xmlFile;
-
+
//Parses it
$this->parse();
}
/**
* Parses XML file
*/
function parse () {
//Parses it
$xml = simplexml_load_file($this->file);
foreach ($xml->page as $page) {
//Gets page
$page = SettingsPage::from_xml($page);
-
+
//Adds to sections array
$this->pages[$page->id] = $page;
}
}
}
?>
\ No newline at end of file
diff --git a/includes/story/choice.php b/includes/story/choice.php
index a7cb0a3..b86eb6d 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
* </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.
*
* @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;
}
}
\ No newline at end of file
diff --git a/includes/story/hook.php b/includes/story/hook.php
index 453d56e..5922e1d 100755
--- a/includes/story/hook.php
+++ b/includes/story/hook.php
@@ -1,101 +1,101 @@
<?php
/**
* Story hook class
*
* 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 hook class
*
* This class allows to hook PHP code to a textual story.
*
* It allows the story to be completed by site elements.
*
* For a class implementation example:
* @see DemoStoryHook
*/
abstract class StoryHook {
/**
* The current story
- *
+ *
* @var Story
*/
public $story;
-
+
/*
* The current story section
- *
+ *
* @var StorySection
*/
public $section;
-
+
/**
* The character involved in the story
*
- * @var Perso
+ * @var Perso
*/
public $perso;
-
+
/**
* Constructor
*
* @param Story $story The story including this hook
* @param StorySection $section The section including this hook
*/
function __construct ($story, $section) {
$this->story = $story;
$this->section = $section;
$this->perso = $GLOBALS['CurrentPerso'];
-
+
$this->initialize();
}
-
+
/**
* Initializes hook. Called after constructor.
*/
abstract function initialize ();
-
+
/**
* Gets choices extra links
- *
+ *
* @param Array $links the hooks links array
*/
function get_choices_links (&$links) {}
-
+
/**
* Updates description
- *
+ *
* @param string the description text (from section and previous hooks)
*/
function update_description (&$description) {}
/**
* Adds HTML code *AT THE END* of the story content block
- *
+ *
* @return string HTML code to print
*/
function add_content () {}
-
+
/**
* Adds HTML code *AFTER* the content block
- *
+ *
* @return string HTML code to print
*/
function add_html () {}
}
?>
\ No newline at end of file
diff --git a/includes/story/hook_demo.php b/includes/story/hook_demo.php
index d5fefe5..0bc2d83 100755
--- a/includes/story/hook_demo.php
+++ b/includes/story/hook_demo.php
@@ -1,77 +1,77 @@
<?php
/**
* Story hook class: example code
*
* Zed. The immensity of stars. The HyperShip. The people.
- *
+ *
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* This class illustrates how to use the StoryHook class.
- *
+ *
* @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
*/
$class = "DemoStoryHook";
/**
* Story hook demo class
*/
class DemoStoryHook extends StoryHook {
/**
* Initializes resources
*
* @see StoryHook::initialize
*
* The initialize method is called after the constructor and is mandatory,
* even if you've nothing to initialize, as it's an abstract method.
*/
function initialize () {}
/**
* Updates the current section description.
- *
+ *
* @see StoryHook::update_description
*
* @param string $description the description to update
*/
function update_description (&$description) {
//Performs the rot13 transform of the current description
$description = str_rot13($description);
-
+
//Appends a string to the current description
$description .= "\n\nWazzzzzzzzzzzzzzzzaaaaaaaaaaaaaaaaaaaaaa";
}
-
+
/**
* Updates the current section choices
*
* @see StoryHook::get_choices_links
*
* @param Array $links the section links
*/
function get_choices_links (&$links) {
//Adds a link to /push
$links[] = array(lang_get("PushMessage"), get_url('push'));
}
-
+
/**
* Adds content after our story content block
*
* @see StoryHook::add_html
*/
function add_html () {
//Adds a html block
return '<div class="black">Lorem ipsum dolor</div>';
}
}
?>
\ No newline at end of file
diff --git a/includes/story/hook_spatioport.php b/includes/story/hook_spatioport.php
index aedb90a..53e761a 100755
--- a/includes/story/hook_spatioport.php
+++ b/includes/story/hook_spatioport.php
@@ -1,132 +1,132 @@
-<?php
+<?php
/**
* Story hook class :: spatioport
*
* Zed. The immensity of stars. The HyperShip. The people.
- *
+ *
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* This class allows to hook spatioport content to a story.
*
* It lists the ship inside the spatioport and in the surrounding space.
*
* @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
*
* @todo Adds spatioport services, like ship repair & co
* @todo Adds a map of the sky, with ship around
* @todo Consider to use the Port class instead and to move get_ships methods there.
*/
require_once('includes/objects/ship.php');
require_once('includes/geo/location.php');
$class = 'SpatioportStoryHook';
/**
* Spatioport story hook class
*/
class SpatioportStoryHook extends StoryHook {
/**
* The spatioport location
- *
+ *
* @var GeoLocation
*/
public $location;
/**
* The spatioport global location
- *
+ *
* @var string
- */
+ */
public $location_global;
-
+
/**
* The spatioport local location
- *
+ *
* @var string
- */
+ */
public $location_local;
-
-
+
+
/**
* Updates and gets the current section choices
- *
+ *
* @param Array $links The story links
- */
+ */
function get_choices_links (&$links) {
//$links[] = array('Examiner les vaisseaux', get_url('port','ships'));
}
-
+
/**
* Initializes instance location properties
*/
function initialize () {
$this->location_global = $this->perso->location_global;
$this->location_local = $this->section->location_local;
$this->location = new GeoLocation($this->location_global, $this->location_local);
}
-
+
/**
* Appends ship list to the story description
*/
function add_content () {
$ships = $this->get_ships();
if (count($ships)) {
echo "\n<h2>Ships</h2>";
echo "<p>Amongst the ships are at the spatioport:</p>";
echo "\n<ul>";
foreach ($ships as $ship) {
$url = get_url('ship', $ship);
echo "\n\t<li><a href=\"$url\">$ship->name</a></li>";
}
echo "\n</ul>";
}
-
+
$ships = $this->get_ships_in_space();
if (count($ships)) {
echo "\n<h2>In orbit</h2>";
$place = (string)$this->location->body;
echo "<p>Those ships are in space around $place:</p>";
echo "\n<ul>";
foreach ($ships as $ship) {
$url = get_url('ship', $ship);
echo "\n\t<li><a href=\"$url\">$ship->name</a></li>";
}
echo "\n</ul>";
}
}
-
+
/**
* Get ships in the spatioports
- *
+ *
* @param string $location_global global location
* @param string $location_local local location
* @return array The ships in the spatioport
*/
private function get_ships () {
return Ship::get_ships_at($this->location_global, $this->location_local);
}
-
-
+
+
/**
* Get ships in the space surrounding the spatioport
- *
+ *
* @param string $location_global global location
* @param string $location_local local location
* @return array The ships in the space around the spatioport
- */
+ */
private function get_ships_in_space () {
- return Ship::get_ships_at($this->location_global, null);
+ return Ship::get_ships_at($this->location_global, null);
}
}
?>
diff --git a/includes/story/section.php b/includes/story/section.php
index 86d949b..c08e658 100755
--- a/includes/story/section.php
+++ b/includes/story/section.php
@@ -1,160 +1,160 @@
<?php
/**
* Story section class
*
* 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
*/
require_once('choice.php');
require_once('hook.php');
/**
* Story section class
*
* This class is a PHP mapping from the Story XML format's <section> tag.
*
* This class also a method to get the section where a specific choice links to.
*/
class StorySection {
/**
* The section ID
*
* @var string
*/
public $id;
/**
* The section title
*
* @var string
*/
public $title;
/**
* The section description
*
* @var string
*/
public $description;
-
+
/**
* @var string the local location
*/
public $location_local;
-
+
/**
* @var Array the section choices (array of StoryChoice items)
*/
public $choices = array();
/*
* @var Array the section hooks (array of StoryHook items)
- */
+ */
public $hooks = array();
-
+
/**
* @var boolean if true, it's the story start ; otherwise, false;
*/
public $start;
/**
* @var Story the story calling the section
*/
public $story;
-
+
/**
* Initializes a new instance of StorySection class
*/
function __construct ($id, $story = null) {
$this->id = $id;
if ($story !== null) {
$this->story = $story;
}
}
/**
* Gets choice from specified guid
- *
+ *
* @return StoryChoice the wanted choice, or null if it doesn't exist
*/
function get_choice ($guid) {
foreach ($this->choices as $choice) {
if ($choice->guid == $guid)
return $choice;
}
return null;
}
-
+
/**
* Initializes a story section from an SimpleXMLElement XML fragment
- *
+ *
* @param SimpleXMLElement $xml the XML fragment
* @param Story $story the calling story
* @return StorySection the section instance
*/
static function from_xml ($xml, $story = null) {
//Reads attributes
$id = '';
$start = false;
foreach ($xml->attributes() as $key => $value) {
switch ($key) {
case 'start':
if ($value) $start = true;
break;
-
+
case 'id':
$id = (string)$value;
break;
-
+
default:
message_die(GENERAL_ERROR, "Unknown attribute: $key = \"$value\"", "Story error");
}
}
-
+
if (!$id) {
message_die(GENERAL_ERROR, "Section without id. Please add id='' in <section> tag", "Story error");
}
-
+
$section = new StorySection($id, $story);
$section->title = (string)$xml->title;
$section->description = (string)$xml->description;
$section->location_local = (string)$xml->local;
$section->start = $start;
-
+
//Adds choices
if ($xml->choices) {
foreach ($xml->choices->choice as $choice) {
$section->choices[] = StoryChoice::from_xml($choice);
}
}
-
+
//Adds hooks
if ($xml->hooks) {
foreach ($xml->hooks->hook as $hook) {
//<hook type="spatioport" /> will assign 'spatioport' to $hook;
$hook = (string)$hook->attributes()->type;
require_once("hook_$hook.php");
$section->hooks[] = new $class($section->story, $section);
}
}
-
+
return $section;
}
}
?>
diff --git a/includes/story/story.php b/includes/story/story.php
index 40e63bf..23c1959 100755
--- a/includes/story/story.php
+++ b/includes/story/story.php
@@ -1,135 +1,135 @@
<?php
/**
* Story class
*
* 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
*/
require_once('section.php');
/**
* Story class
*
* This class is a PHP mapping from the Story XML format.
*
* This class also provides a collection of helper methods to explore the story.
*/
class Story {
/**
* The file path
- *
+ *
* @var string
*/
public $file;
-
+
/**
* The story title
- *
+ *
* @var string
*/
public $title;
-
+
/**
* An array of StorySection elements
*
- * @var Array
+ * @var Array
*/
public $sections = array();
-
+
/**
* The SimpleXML parser
*
* @var SimpleXMLElement
*/
private $xml;
-
+
/**
* The index of start section in sections array
*
* @var string
*/
private $startSection = null;
-
+
/**
* An array of StorySection elements, indexed by location
*
* @var Array
*/
private $sectionsByLocation = array();
-
+
function __construct ($file) {
//Opens .xml
if (!file_exists($file)) {
message_die(GENERAL_ERROR, "$file not found.", "Story loading error");
}
-
+
$this->file = $file;
$this->parse();
}
-
+
/**
* Gets start section
- *
+ *
* @return StorySection the section where the story starts, or null if not defined
*/
function get_start_section () {
return ($this->startSection != null) ? $this->sections[$this->startSection] : null;
}
-
+
/**
* Gets section from local location
- *
+ *
* @return StorySection the default section at this location, or null if not defined
*/
function get_section_from_location ($location) {
return array_key_exists($location, $this->sectionsByLocation) ? $this->sectionsByLocation[$location] : null;
}
-
+
/**
* Parses XML file
*/
function parse () {
//Parses it
$this->xml = simplexml_load_file($this->file);
$this->title = (string)$this->xml->title;
foreach ($this->xml->section as $section) {
//Gets section
$section = StorySection::from_xml($section, $this);
-
+
//Have we a start section?
if ($section->start) {
//Ensures we've only one start section
if ($this->startSection != null) {
message_die(GENERAL_ERROR, "Two sections have start=\"true\": $section->id and $this->startSection.", "Story error");
}
$this->startSection = $section->id;
}
-
+
//By location
if ($section->location_local) {
$this->sectionsByLocation[$section->location_local] = $section;
}
-
+
//Adds to sections array
$this->sections[$section->id] = $section;
}
}
}
?>
diff --git a/includes/travel/place.php b/includes/travel/place.php
index 5a9b5e3..816bd98 100755
--- a/includes/travel/place.php
+++ b/includes/travel/place.php
@@ -1,152 +1,152 @@
<?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
- */
+ *
+ * @var bool
+ */
public $freeLocalMove = false;
-
+
/**
* Array of strings, each item another place reachable
*
* This matches GlobalTravelTo XML tags.
*
- * @var Array
- */
+ * @var Array
+ */
public $globalTravelTo = array();
-
+
/**
* Aray 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
*
* 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
*/
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;
}
}
?>
\ No newline at end of file
diff --git a/includes/travel/travel.php b/includes/travel/travel.php
index 50fcd37..ad1ae7b 100755
--- a/includes/travel/travel.php
+++ b/includes/travel/travel.php
@@ -1,172 +1,172 @@
<?php
/**
* Travel helper class
*
* Zed. The immensity of stars. The HyperShip. The people.
- *
+ *
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2010-07-18 22:05 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
*/
require_once('place.php');
/**
* Travel helper class
*
* The Travel class reads content/travel.xml to get travel special rules
*
* It so be able to provide methods determining if a move is or not valid.
*
* This class implements a singleton pattern.
*/
class Travel {
/**
* Array of TravelPlace, each one a custom travel rule
- *
+ *
* This array is indexed by TravelPlace code.
- *
+ *
* @var Array
- */
+ */
public $globalTravelTo;
-
+
/**
* Constructor
*/
function __construct () {
//Initializes array
$this->globalTravelTo = array();
}
-
+
/**
* Gets and initializes if needed the Travel instance
*
* @return Travel the Travel instance
*/
static function load () {
require_once('includes/cache/cache.php');
$cache = Cache::load();
-
+
if (!$travel = $cache->get('zed_travel')) {
//Initializes resource and caches it
$travel = new Travel();
$travel->load_xml("content/travel.xml");
$cache->set('zed_travel', serialize($travel));
return $travel;
}
-
+
return unserialize($travel);
}
-
+
/**
* Loads a travel configuration XML file
- *
- * @param string the path to the travel XML file
+ *
+ * @param string the path to the travel XML file
*/
function load_xml ($file) {
$xml = simplexml_load_file($file);
foreach ($xml->TravelPlace as $travelPlaceXml) {
$travelPlace = TravelPlace::from_xml($travelPlaceXml);
$this->globalTravelTo[$travelPlace->code] = $travelPlace;
}
}
-
+
/**
* Tries to parse the specified expression, according the rewrite rules
* (for example defined by the <RewriteRule> xml tags)
*
* @param string $expression the expression to parse
* @param GeoLocation the location where the perso is
* @param GeoLocation the location where the perso wants to go
*
* @return boolean true if the expression have been parsed ; otherwise, false.
*/
function try_parse_rewrite_rule ($expression, $from, &$to) {
//Relevant write rules depends from the location the perso is ($from)
$travelPlace = $this->globalTravelTo[$from->global];
foreach ($travelPlace->rewriteRules as $rule) {
//$rule is an array [expression, global_location, local_location]
$subpatterns = array();
$result = preg_match($rule[0], $expression, $subpatterns);
if ($result > 0) {
//$subpatterns is an array with:
// - at indice 0, the full matched regexp
// - from 1 to n, the (groups) inside the regexp
//We need so to replace $1 by $subpatterns[1] and so on.
for ($i = count($subpatterns) - 1 ; $i > 0 ; $i--) {
$rule[1] = str_replace('$' . $i, $subpatterns[$i], $rule[1]);
$rule[2] = str_replace('$' . $i, $subpatterns[$i], $rule[2]);
}
$to = new GeoLocation($rule[1], $rule[2]);
return true;
}
}
return false;
}
-
+
/**
* Determines if a perso can travel from $from to $to
- *
+ *
* If an alias have been used for $to local location, set correct location.
- *
+ *
* @param GeoLocation the location where the perso is
* @param GeoLocation the location where the perso wants to go
* @return boolean true if the travel move is valid ; otherwise, false.
*
* @todo From B00001002, goto C1 doesn't work. Alias seems ignored.
*/
- function can_travel ($from, &$to) {
+ function can_travel ($from, &$to) {
if ($from->global != $to->global) {
//Checks if we can locally from $from to $to place
if (!array_key_exists($from->global, $this->globalTravelTo)) {
return false;
}
$travelPlace = $this->globalTravelTo[$from->global];
if (!in_array($to->global, $travelPlace->globalTravelTo)) {
return false;
}
}
if ($to->containsLocalLocation) {
//Determines if we've custom rules about local moves in $to
if (!array_key_exists($to->global, $this->globalTravelTo)) {
return false;
}
$travelPlace = $this->globalTravelTo[$to->global];
-
+
//Is it's an especially allowed movement?
foreach ($travelPlace->localMoves as $move) {
//move is a [location, alias, name] array
//If any of those 3 parameters matches $to->local, it's okay
if (in_array($to->local, $move)) {
$to->local = $move[0];
return true;
}
}
-
+
if ($travelPlace->freeLocalMove) {
//We can move freely, perfect
return true;
}
//Local move not allowed
return false;
}
-
+
return true;
}
}
?>
diff --git a/js/builder/map.js b/js/builder/map.js
index 05b2c0c..7a1e2b5 100644
--- a/js/builder/map.js
+++ b/js/builder/map.js
@@ -1,103 +1,103 @@
/* -------------------------------------------------------------
Zed
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Author: Dereckson
Tags: map
Filename: map.js
Version: 1.0
Created: 2010-12-23
Updated: 2010-12-23
Licence: Dual licensed: BSD and Creative Commons BY 3.0.
Dependencies: dojo
------------------------------------------------------------- */
/**
* Map
*/
var map = {
id: null,
zones: null,
bounds: null,
init: function (id, zones) {
map.id = id;
map.zones = zones;
map.render();
},
/**
* Get coordinates
*
* @returns An array [x, y, z]
*/
get_coordinates: function (expr) {
- var coordinates = expr.substring(1, expr.length - 1).split(', ');
+ var coordinates = expr.substring(1, expr.length - 1).split(', ');
return [parseInt(coordinates[0]), parseInt(coordinates[1]), parseInt(coordinates[2])];
},
/**
* Calculates the zones bounds and stores the result in bounds property
*/
calculate_bounds: function () {
var start = map.get_coordinates(map.zones[0][0]);
map.bounds = [
[start[0], start[0]],
[start[1], start[1]],
[start[2], start[2]]
];
for (i = 1 ; i < map.zones.length ; i++) {
point = map.get_coordinates(map.zones[i][0]);
if (point[0] < map.bounds[0][0]) map.bounds[0][0] = point[0];
if (point[1] < map.bounds[1][0]) map.bounds[1][0] = point[1];
if (point[2] < map.bounds[2][0]) map.bounds[2][0] = point[2];
if (point[0] > map.bounds[0][1]) map.bounds[0][1] = point[0];
if (point[1] > map.bounds[1][1]) map.bounds[1][1] = point[1];
if (point[2] > map.bounds[2][1]) map.bounds[2][1] = point[2];
}
},
render_zone: function (x, y, z) {
var location = "(" + x + ", " + y + ", " + z + ")";
for (i = 0 ; i < map.zones.length ; i++) {
if (location == map.zones[i][0]) {
return '<span class="zone zone-edit" id="zone-' + map.zones[i][1] + '" onMouseOut="map.reset_info()" onMouseOver="map.set_info(\'' + location + '\')" onClick="map.menu_edit(\'' + location + '\', ' + map.zones[i][1] + ');"><img src="/img/map/map-kub-top.png" alt="Built" /></span>';
}
- }
+ }
return '<span class="zone zone-build" onMouseOut="map.reset_info()" onMouseOver="map.set_info(\'' + location + '\')" onClick="map.menu_build(\'' + location + '\');"><img src="/img/map/map-kub-top-build.png" alt="Build" /></span>';
},
render: function () {
map.calculate_bounds();
var html = "";
z = map.bounds[2][0];
for (y = map.bounds[1][1] ; y >= map.bounds[1][0] ; y--) {
for (x = map.bounds[0][0] ; x <= map.bounds[0][1] ; x++) {
html += '<div class="grid_1">' + map.render_zone(x, y, z) + "</div>";
}
html += '</div><div class="clear fixclear"></div>';
dojo.byId(map.id).innerHTML = html;
}
},
menu_edit: function (local_location, zone_id) {
//alert("Goto or edit #" + zone_id);
//map/zone-edit.png
//map/zone-goto.png
window.location = "/do.php/set_local_location/" + local_location + "?redirectTo=/";
},
menu_build: function (local_location) {
//alert("Build at " + local_location);
//map/zone-build.png
//window.location = "/do.php/set_local_location/" + escape(local_location) + "?redirectTo=/builder";
window.location = "/do.php/set_local_location/" + local_location + "?redirectTo=/";
},
set_info: function (local_location) {
coord = map.get_coordinates(local_location);
dojo.byId("info_area").innerHTML = 'Zone <span id="area">' + Math.abs(coord[0]) + '-' + Math.abs(coord[1]) + '</span>';
},
reset_info: function () {
dojo.byId("info_area").innerHTML = "&nbsp;";
}
}
diff --git a/js/login.js b/js/login.js
index 605952a..6b55e12 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
+ //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.
} 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
diff --git a/js/misc.js b/js/misc.js
index 13d7224..2c14ab1 100644
--- a/js/misc.js
+++ b/js/misc.js
@@ -1,159 +1,159 @@
/* Updates SmartLine */
function UpdateSmartLine() {
document.forms.SmartLine.C.value = document.forms.SmartLine.SmartLineHistory.value;
document.forms.SmartLine.C.focus();
}
/* Hypership time */
function get_hypership_time () {
//Gets time
date = new Date();
unixtime = Math.floor(date.getTime() / 1000);
seconds = unixtime - 1278115200;
days = Math.floor(seconds / 86400);
fraction = Math.floor((seconds % 86400) / 86.4);
-
+
//Zerofills fraction
switch (new String(fraction).length) {
case 1: return days + "." + "00" + fraction;
case 2: return days + "." + "0" + fraction;
default: return days + "." + fraction;
}
}
/* We need to trigger an update in ... ms */
function next_hypership_increase_in () {
date = new Date();
unixtime = Math.floor(date.getTime() / 1000);
seconds = unixtime - 1278115200;
days = Math.floor(seconds / 86400);
fraction1 = (seconds % 86400) / 86.4;
fraction2 = Math.ceil(fraction1);
return (fraction2 - fraction1) * 86400;
}
//Autoupdates every 20 seconds
//(should be every 86.4 seconds, after first timed call)
function update_hypership_time () {
var item = document.getElementById("HypershipTime");
if (item != undefined) {
item.innerHTML = get_hypership_time();
setTimeout('update_hypership_time()', 86400);
}
}
setTimeout('update_hypership_time()', next_hypership_increase_in());
/* Dumps a variable */
function dump(arr,level) {
var dumped_text = "";
if(!level) level = 0;
-
+
//The padding given at the beginning of the line.
var level_padding = "";
for(var j=0;j<level+1;j++) level_padding += " ";
-
- if(typeof(arr) == 'object') { //Array/Hashes/Objects
+
+ if(typeof(arr) == 'object') { //Array/Hashes/Objects
for(var item in arr) {
var value = arr[item];
-
+
if(typeof(value) == 'object') { //If it is an array,
dumped_text += level_padding + "'" + item + "' ...\n";
//dumped_text += dump(value,level+1);
} else {
dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
}
}
} else { //Stings/Chars/Numbers etc.
dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
}
return dumped_text;
}
/* A code for an hidden function */
var ar2215 = {
input: "",
pattern: "38384040373937396665",
clear: setTimeout('ar2215.clear_input()', 2000),
load: function () {
window.document.onkeydown = function (e) {
ar2215.input += e ? e.keyCode : event.keyCode;
if (ar2215.input == ar2215.pattern) {
ar2215.code("/push");
clearTimeout(ar2215.clear);
return;
}
clearTimeout(ar2215.clear);
ar2215.clear = setTimeout("ar2215.clear_input()", 2000);
}
this.iphone.load("/index.php/push");
},
code: function (link) {
window.location = link;
},
clear_input: function () {
ar2215.input = "";
clearTimeout(ar2215.clear);
},
iphone:{
start_x: 0,
start_y: 0,
stop_x: 0,
stop_y: 0,
tap: false,
capture: false,
keys: ["UP","UP","DOWN","DOWN","LEFT","RIGHT","LEFT","RIGHT","TAP","TAP"],
code: function (link) { window.location = link },
load: function (link) {
document.ontouchmove = function (e) {
if (e.touches.length == 1 && ar2215.iphone.capture == true) {
var touch = e.touches[0];
ar2215.iphone.stop_x = touch.pageX;
ar2215.iphone.stop_y = touch.pageY;
ar2215.iphone.tap = false;
ar2215.iphone.capture = false;
ar2215.iphone.check_direction();
}
}
document.ontouchend = function (evt) {
if (ar2215.iphone.tap == true)
ar2215.iphone.check_direction();
}
document.ontouchstart = function(evt) {
ar2215.iphone.start_x = evt.changedTouches[0].pageX;
ar2215.iphone.start_y = evt.changedTouches[0].pageY;
ar2215.iphone.tap = true;
ar2215.iphone.capture = true;
}
},
check_direction: function () {
x_magnitude = Math.abs(this.start_x - this.stop_x);
y_magnitude = Math.abs(this.start_y - this.stop_y);
x = ((this.start_x - this.stop_x) < 0) ? "RIGHT": "LEFT";
y = ((this.start_y - this.stop_y) < 0) ? "DOWN" : "UP";
result = (x_magnitude > y_magnitude) ? x : y;
result = (this.tap == true) ? "TAP" : result;
if (result == this.keys[0])
this.keys = this.keys.slice(1, this.keys.length);
if (this.keys.length == 0)
this.code(this.link)
}
}
}
ar2215.load();
/* Visual effects */
function set_opacity (id, opacity) {
element = document.getElementById(id);
if (element != null) {
if (opacity == 0) {
element.style.backgroundImage = 'inherit';
} else {
property = 'url("/img/zed/opaque_' + opacity + '.png")';
element.style.backgroundImage = property;
}
}
}
diff --git a/js/tour2.js b/js/tour2.js
index 029a4f0..f56a43f 100644
--- a/js/tour2.js
+++ b/js/tour2.js
@@ -1,148 +1,148 @@
/* -------------------------------------------------------------
Zed
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Author: Dereckson
Tags: animation jquery l10n
Filename: tour.js
Version: 1.0
Created: 2010-01-25
Updated: 2010-02-03
Licence: Dual licensed: BSD and Creative Commons BY 3.0.
Dependencies: jQuery (for dom elements selection and dimensions.js)
dimensions.js
------------------------------------------------------------- */
-var tour = {
+var tour = {
//Default language
lang: "en",
-
+
//Translated in
langs: "en,fr",
-
+
//Current highlight showed
current: -1,
-
+
//File extension
extension: "png",
-
+
//Highlights files and position
//File: /img/tour/{filename}.{extension}
highlights: [
["create", 13, 18],
["lounge", 339, 107],
["play", 22, 345],
["explore", 325, 373]
],
-
+
//The center x, y coordinate
//It's used to determinate what highlight to print
center: [368, 390],
-
+
//Gets the highlight index, from position
where: function(x, y) {
if (x < this.center[0]) {
//We're at left from center point
return (y < this.center[1]) ? 0 : 2;
} else {
//We're at right from center point
return (y < this.center[1]) ? 1 : 3;
}
},
-
+
//Determines if we're inside the #Tour id
isInside: function (pageX, pageY) {
var tourOffset = $("#Tour").offset();
return pageX >= tourOffset.left && pageY >= tourOffset.top
&& pageX <= tourOffset.left + $("#Tour").width()
&& pageY <= tourOffset.top + $("#Tour").height();
},
-
+
//Shows the highlight at specified the page position
showAt: function (pageX, pageY) {
var tourOffset = $("#Tour").offset();
this.show(
this.where(pageX - tourOffset.left , pageY - tourOffset.top)
);
},
-
+
//Shows the specified highlight
show: function (i) {
if (this.current != i) {
var filename = this.highlights[i][0] + "_" + this.lang + "." + this.extension;
var code = '<img src="http://zed.espace-win.org.nyud.net/img/tour/' + filename + '" alt="' + this.highlights[i][0] + '" />';
$('#TourHighlight').empty().html(code);
var o = document.getElementById("TourHighlight");
o.style.left = this.highlights[i][1] + "px";
o.style.top = this.highlights[i][2] + "px";
this.current = i;
}
},
-
+
//Hides highlight
hideall: function () {
if (this.current > -1) {
this.current = -1;
$('#TourHighlight').empty();
}
},
-
+
//Runs the animation
run: function (delay) {
//Highlight order
//[0, 1, 3, 2] is a counterwise move
var order = [0, 1, 3, 2];
-
+
//Prints first hightlight
this.show(order[0]);
-
+
//Prints next highlights
n = this.highlights.length;
for (i = 1 ; i < n ; i++) {
setTimeout('tour.show(' + order[i] + ')', delay * i);
}
-
+
//Prints back the first, and enables rollover
setTimeout('tour.show(' + order[0] + ')', delay * n);
setTimeout('tour.enableRollover()', delay * n);
},
-
+
//Enables rollovers
enableRollover: function () {
//Enables panel on click
$('#Tour').bind("mousemove mouseout", function(e) {
if (tour.isInside(e.pageX, e.pageY)) {
tour.showAt(e.pageX, e.pageY);
} else {
tour.hideall();
- }
+ }
});
- },
-
+ },
+
//Gets client language (Firefox) or preferences content language (IE)
getLanguage: function () {
var lang = navigator.language;
if (lang == undefined) lang = navigator.userLanguage;
if (lang == undefined) return "";
-
+
//fr-be -> fr
var pos = lang.indexOf('-');
if (pos > -1) lang = lang.substring(0, pos);
-
+
return lang.toLowerCase();
},
-
+
//Initializes tour
init: function () {
//Tries to localize
var lang = this.getLanguage();
if (this.langs.indexOf(lang) > -1) this.lang = lang;
-
+
//Runs tour animation
//The rollover will be enabled at anim end
this.run(900);
}
}
-
+
$(document).ready(function() {
- tour.init();
+ tour.init();
});
\ No newline at end of file
diff --git a/lang/en/profile.conf b/lang/en/profile.conf
index 4f04ede..c804d32 100644
--- a/lang/en/profile.conf
+++ b/lang/en/profile.conf
@@ -1,103 +1,103 @@
#Zed language config file - Profiles
#Language: English
#Code: en
#Author: Dereckson
###
### profile.tpl - main profile
###
#<img src=".../mail.png" title="E-mail" alt="@"... />
Mail = E-mail
MailAlt = @
Online = Online
###
### profile.tpl - communication area
###
DropMessage = Drop a message
SendMessage = Send a message to %s
AddComment = "Add a comment to %s's profile"
Send = Send
Publish = Publish
###
### profile.tpl - sidebar - Edit account preferences and profile content
###
EditMyPage = Edit my page
EditProfile = Edit my text
EditAccount = Edit my information
ManagePhotos = Manage photos
AddPhoto = Add a photo
###
### profile_edit.tpl - edit
###
ProfileTextTitle = My best words to express myself
SaveProfile = Save profile
ProfileFont = Profile fontz
Calibri = Calibri (regular font)
FixedSys = FixedSys (fixed width)
###
### user_account.tpl - edit my information
###
Login = Login
-LongName = Full character name
+LongName = Full character name
UpdateAccountInfo = Update account information
###
### profile_photo.tpl - photo manager - add a photo to my profile
###
AddPhoto = Add a photo to my profile
AddPhotoExplanations = You can upload here a personal photo with you as main subject.<br />Note you can also host any kind of pictures in various Zed places, like in the HyperShip's tower.
ShortDescription = Short description
SafeForWorkLabel = Check this box if the picture is "<strong>safe for work</strong>", you can view it without problem from any public computer.
###
### profile_photo.tpl - photo manager - manage current photos
###
ManageCurrentPhotos = Manage current photos
PictureProperties = Picture properties
EditPictureProperties = Edit this picture description or safe status
Delete = Delete
DeleteThisPicture = Delete this picture
###
### profile_photo_edit.tpl - edit individual photo properties
###
EditPhoto = Edit photo
PhotoInfo = Photo information
Description = Description
SafeForWork = Safe for work
UseAsAvatar = Use as avatar
OtherActions = Other actions
DeletePicture = Delete this picture
BackToPhotoManager = Back to photo manager
###
### profile.php
###
UnknownUser = Unknown being
Who = Who?
WhoIsUser = Who is %s?
MessageSent = Message sent.
MessageSentSelf = Message sent to yourself.
CommentPublished = Comment published.
PhotoUploaded = Photo uploaded.
NotYourPic = Hey, this photo is not one of yours.
PictureDeleted = Picture deleted.
InactivatedUser = "This being's account isn't active yet."
diff --git a/lang/fr/profile.conf b/lang/fr/profile.conf
index 477caa6..201b916 100644
--- a/lang/fr/profile.conf
+++ b/lang/fr/profile.conf
@@ -1,104 +1,104 @@
#Zed language config file - Profiles
#Language: French
#Code: fr
#Author: Dereckson
###
### profile.tpl - main profile
###
#<img src=".../mail.png" title="E-mail" alt="@"... />
Mail = Courriel
MailAlt = @
Online = Online
###
### profile.tpl - communication area
###
DropMessage = Laisser un message
SendMessage = "Envoyer un message privé <!-- %s -->"
AddComment = "Publier un commentaire sur ce profil <!--%s-->"
Send = Envoyer
Publish = Publier
###
### profile.tpl - sidebar - Edit account preferences and profile content
###
EditMyPage = Éditer ma page
EditProfile = Éditer mon texte
EditAccount = Éditer mes infos
ManagePhotos = Gérer mes photos
AddPhoto = Upload une photo
###
-### profile_edit.tpl - edit my text
+### profile_edit.tpl - edit my text
###
ProfileTextTitle = Texte
SaveProfile = Enregistrer mon texte
ProfileFont = Police
Calibri = Calibri (police à chasse variable)
FixedSys = FixedSys (police à chasse fixe)
###
### user_account.tpl - edit my information
###
Login = Login
-LongName = Nom complet
+LongName = Nom complet
UpdateAccountInfo = Mettre à jour mon compte
###
### profile_photo.tpl - photo manager - add a photo to my profile
###
AddPhotoToProfile = Ajouter une photo à mon profil
AddPhotoExplanations = Vous pouvez upload ici toute photo dont vous êtes le sujet principal. Celles-ci seront affichées sur votre profil.<br />Pour partager toute autre photo, placez là quelque part dans la galaxie, comme par exemple dans la tour de Zed.
ShortDescription = Courte description
SafeForWorkLabel = Cochez la case "<strong>safe for work</strong>", si la photo peut être regardée sans problème par tout en chacun depuis tout lieu public.
###
### profile_photo.tpl - photo manager - manage current photos
###
ManageCurrentPhotos = Gérer les photos
PictureProperties = Propriétés de la photo
EditPictureProperties = Modifier les propriétés
Delete = Effacer
DeleteThisPicture = Effacer cette image
###
### profile_photo_edit.tpl - edit individual photo properties
###
EditPhoto = Photo — Propriétés
PhotoInfo = Info sur cette photo
Description = Description
SafeForWork = Safe for work
UseAsAvatar = Avatar
OtherActions = Autres actions
DeletePicture = Effacer cette photo
BackToPhotoManager = < Retourner au gestionnaire de photos
###
### profile.php
###
UnknownUser = Inconnu au bataillon.
Who = Qui ?
WhoIsUser = Qui est %s?
MessageSent = Message envoyé.
MessageSentSelf = Message personnel envoyé.
CommentPublished = Commentaire publié.
PhotoUploaded = Photo enregistrée.
NotYourPic = Same player, try again.
PictureDeleted = Photo effacée.
PromotedToAvatar = Hop, un nouvel avatar.
InactivatedUser = "Attention, ce compte n'est pas encore actif."
diff --git a/skins/zed/builder_hotglue.tpl b/skins/zed/builder_hotglue.tpl
index a3fad7a..f0f8e8b 100644
--- a/skins/zed/builder_hotglue.tpl
+++ b/skins/zed/builder_hotglue.tpl
@@ -1,9 +1,9 @@
<div class="content_wrapper">
<h1>HyperShip builder</h1>
<div class="content">
<p style="width: 40%; float: left;">{$location}<br />{$location->global} {$location->local}</p>
<p style="width: 40%; float: right; text-align: right;">Zone {$zone->id}</p>
<div class="clear"></div>
- </div>
+ </div>
</div>
{include file="iframe.tpl"}
diff --git a/skins/zed/error.tpl b/skins/zed/error.tpl
index f6420b5..01beb4b 100644
--- a/skins/zed/error.tpl
+++ b/skins/zed/error.tpl
@@ -1,60 +1,60 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>{#SiteTitle#}</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="{#StaticContentURL#}/css/960.css" media="screen" />
<link rel="stylesheet" href="{#StaticContentURL#}/css/zed/theme.css" />
</head>
<body>
<!-- Header -->
<div id="header">
<div id="header_content">
<div class="container_16">
<div class="grid_9">
<div id="HypershipTime">{get_hypership_time()}</div>
</div>
<div class="grid_7">
<a href="{get_url()}"><img src="{#StaticContentURL#}/img/zed/logo.png" src="Zed logo" border="0" /></a>
</div>
</div>
</div>
</div>
<div class="clear"></div>
<div class="container_16">
{if $WAP}
-
+
<!-- WAP -->
<div class="grid_16 alpha omega">
<div class="wap">{$WAP}</div>
</div>
{/if}
{if $NOTIFY}
-
+
<!-- Notify -->
<div class="grid_16 alpha omega">
<div class="notify">{$NOTIFY}</div>
</div>
{/if}
<!-- Error -->
<div class="content_wrapper">
<h1>{$TITLE}</h1>
<div class="content">
<p>{$ERROR_TEXT}</p>
<p><a href="{get_url()}">{#BackToHome#}</a></p>
</div>
</div>
<div class="clear"></div>
<hr />
<div id="footer">
<div class="grid_12 alpha">
<p>[ {#Product#} / {#FatalErrorScreen#} ]</p>
</div>
<div class="grid_4 omega">
<p style="text-align: right">[ <a href="{get_url()}?action=user.logout">{#Logout#}</a> ]</p>
</div>
</div>
</div>
</body>
</html>
\ No newline at end of file
diff --git a/skins/zed/header.tpl b/skins/zed/header.tpl
index 2c1a9c2..8c6ebc1 100644
--- a/skins/zed/header.tpl
+++ b/skins/zed/header.tpl
@@ -1,69 +1,69 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>{$PAGE_TITLE} - {#SiteTitle#}</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="{#StaticContentURL#}/css/960.css" media="screen" />
<link rel="stylesheet" href="{#StaticContentURL#}/css/zed/theme.css" />
<script type="text/javascript" src="{#StaticContentURL#}/js/misc.js"></script>
{foreach from=$PAGE_CSS item=css}
<link rel="stylesheet" href="{#StaticContentURL#}/css/{$css}" />
{/foreach}
{foreach from=$PAGE_JS item=js}
<script src="{#StaticContentURL#}/js/{$js}"></script>
{/foreach}
{if $DOJO}
<!-- DOJO -->
<script type="text/javascript" src="{#StaticContentURL#}/js/dojo/dojo/dojo.js" djConfig="isDebug:false, parseOnLoad: true" ></script>
{if $DIJIT}
<link rel="stylesheet" type="text/css" href="{#StaticContentURL#}/css/zed/forms.css" />
{/if}
{/if}
</head>
<body{if $DIJIT} class="tundra"{/if}>
<!-- Header -->
<div id="header">
<div id="header_content">
<div class="container_16">
<div class="grid_9">
<div class="wall" id="header_wall">
{$WALL_TEXT}
<br />
<span class="wall_info">- - <a href="{$WALL_USER_URL}">{$WALL_USER}</a></span>
</div>
<div class="clear"></div>
<div id="HypershipTime">{get_hypership_time()}</div>
</div>
<div class="grid_7">
<a href="{get_url()}"><img src="{#StaticContentURL#}/img/zed/logo.png" alt="Zed logo" border="0" /></a>
</div>
<div class="clear"></div>
</div>
</div>
</div>
<div class="clear"></div>
<!-- Content -->
<div class="container_16">
{if $WAP}
-
+
<!-- WAP -->
<div class="grid_16 alpha omega">
<div class="wap">{$WAP}</div>
</div>
<div class="clear"></div>
{/if}
{if $NOTIFY}
-
+
<!-- Notify -->
<div class="grid_16 alpha omega">
<div class="notify">{$NOTIFY}</div>
</div>
<div class="clear"></div>
{/if}
{if $SmartLine_STDOUT || $SmartLine_STDERR}
{include file="smartline_results.tpl"}
{/if}
diff --git a/skins/zed/login.tpl b/skins/zed/login.tpl
index 1272be8..ebacbd8 100644
--- a/skins/zed/login.tpl
+++ b/skins/zed/login.tpl
@@ -1,78 +1,78 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>{#SiteTitle#}</title>
<link rel="Stylesheet" href="{#StaticContentURL#}/css/zed/login.css" type="text/css" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="js/login.js"></script>
<script type="text/javascript" src="js/misc.js"></script>
<script type="text/javascript" src="js/prototype.js"></script>
- <script type="text/javascript" src="js/effects.js"></script>
+ <script type="text/javascript" src="js/effects.js"></script>
</head>
<body>
-
+
<!-- Login form -->
<div id="LoginBox">
<form method="post" action="{get_url()}">
<div class="row">
<label for="username">{#Login#}{#_t#}</label>
<input type="text" id="username" name="username" value="{$username}" />
</div>
<div class="row">
<label for="password">{#Password#}{#_t#}</label>
<input type="password" id="password" name="password" />
</div>
<div class="row">
<label for="openid">{#OpenID#}{#_t#}</label>
<input type="text" id="openid" name="openid" value="{$OpenID}" />
</div>
<div class="row">
<input type="submit" id="submit" name="LogIn" value="{#OK#}" onclick="return OnLoginSubmit(this);" />
</div>
</form>
{if $LoginError}
<!-- Ooops, something wrong -->
<div class=row>
<p id="error" class="error">&nbsp;&nbsp;&nbsp;&nbsp;{$LoginError}</p>
</div>
{/if}
</div>
<!-- Links -->
<div id="link_tour"><a href="/tour.html"></a></div>
<div id="link_blog"><a href="/blog"></a></div>
{$code = generate_random_string('AAA111')}
<!--
XXXXXXX XX
X X X
X X Invitation code:
X XXXXX XXXXX {$code}
X X X X X
X XXXXXXX X X
X X X X
X X X X X X
XXXXXXX XXXXX XXXXXX
Welcome to the Zed beta. We're happy you're reading the source :)
If you want to know what we're building, check http://zed.dereckson.be/tour.html
If you wish an access, send a mail to zedinvite (alt+64) dereckson.be
and specify the following code: {$code}
* * * *
-
+
Bienvenue dans la version bêta de Zed. Heureux que vous consultiez la source.
Un petit aperçu de ce que l'on crée est sur http://zed.dereckson.be/tour.html
Pour obtenir un accès, envoyez un mail à zedinvite (alt+64) dereckson.be
en spécifiant le code suivant : {$code}
-->
<script type="text/javascript">
slide.initialize('LoginBox');
</script>
</body>
</html>
\ No newline at end of file
diff --git a/skins/zed/page_edit.tpl b/skins/zed/page_edit.tpl
index f5a8799..e767ec1 100644
--- a/skins/zed/page_edit.tpl
+++ b/skins/zed/page_edit.tpl
@@ -1,26 +1,25 @@
<div class="content_wrapper">
<h1>Page editor</h1>
-
+
<!-- Page editor form -->
<form method="post" action="{get_url('page', $page['page_code'])}">
<p><input id="title" type="text" size="80" maxsize="255" name="title" value="{$page['page_title']}" /> ◄ <label for="title">Page title</label>
<br />
<input id="edit_reason" type=text size="80" maxsize="255" name="edit_reason" /> ◄ <label for="edit_reason">Edit summary</label></p>
<textarea id="PageEditorContent" name="content" style="width: 100%" rows=20>{$page['page_content']}</textarea>
<br />
<input type=hidden name="code" value='{$page['page_code']}' />
- <input type=submit value='Enregistrer' />
+ <input type=submit value='Enregistrer' />
</form>
</div>
-
+
<!-- Loads FCKeditor -->
<script>
var oFCKeditor = new FCKeditor('content');
oFCKeditor.BasePath = '/js/FCKeditor/';
oFCKeditor.Config['SkinPath'] = oFCKeditor.BasePath + 'editor/skins/silver/';
oFCKeditor.Config['BaseHref'] = 'http://zed.dereckson.be/page/';
oFCKeditor.Height = 480;
oFCKeditor.ReplaceTextarea();
</script>
-
\ No newline at end of file
diff --git a/skins/zed/perso_header.tpl b/skins/zed/perso_header.tpl
index c09a11c..1f9f44e 100644
--- a/skins/zed/perso_header.tpl
+++ b/skins/zed/perso_header.tpl
@@ -1,56 +1,56 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>{#SiteTitle#}</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="{#StaticContentURL#}/css/960.css" media="screen" />
<link rel="stylesheet" href="{#StaticContentURL#}/css/zed/theme.css" />
-
+
<!-- Calls dojo -->
<script src="/{#StaticContentURL#}js/dojo/dojo/dojo.js" type="text/javascript"
djConfig="isDebug: false, parseOnLoad: true"></script>
<link rel="stylesheet" href="{#StaticContentURL#}/css/zed/forms.css" />
<script type="text/javascript">
dojo.require("dijit.form.Form");
-
+
dojo.require("dijit.form.ValidationTextBox");
dojo.require("dijit.form.TextBox");
dojo.require("dijit.form.FilteringSelect");
dojo.require("dijit.form.Button");
-
+
dojo.require("dojox.validate.regexp");
dojo.require("dojox.form.PasswordValidator");
-
+
dojo.require("dojo.parser");
</script>
</head>
<body class="tundra">
<!-- Header -->
<div id="header">
<div id="header_content">
<div class="container_16">
<div class="grid_4 alpha omega suffix_8">
<a href="{get_url()}"><img src="{#StaticContentURL#}/img/zed/logo.png" src="Zed logo" border="0" /></a>
</div>
<div class="clear"></div>
</div>
</div>
</div>
<div class="clear"></div>
<!-- Content -->
<div class="container_16">
{if $WAP}
-
+
<!-- WAP -->
<div class="grid_16 alpha omega">
<div class="wap">{$WAP}</div>
</div>
{/if}
{if $NOTIFY}
-
+
<!-- Notify -->
<div class="grid_16 alpha omega">
<div class="notify">{$NOTIFY}</div>
</div>
{/if}
diff --git a/skins/zed/perso_select.tpl b/skins/zed/perso_select.tpl
index e07d6ba..23b64ae 100644
--- a/skins/zed/perso_select.tpl
+++ b/skins/zed/perso_select.tpl
@@ -1,18 +1,18 @@
{include file="perso_header.tpl"}
<div class="grid_16">
<h2>{#PickPerso#}</h2>
{foreach from=$PERSOS item=perso}
<!-- {$perso->name} -->
<div class="avatar">
<a href="{get_url()}?action=perso.select&perso_id={$perso->id}">
{if $perso->avatar}
<img src="{#StaticContentURL#}/content/users/_avatars/{$perso->avatar}" />
{else}
<img src="{#StaticContentURL#}/img/misc/NoAvatar.png" alt="{#NoAvatar#}" />
{/if}
</a>
<span class="avatar_name"><a href="{get_url()}?action=perso.select&perso_id={$perso->id}">{$perso->name}</a></span>
</div>
-
+
{/foreach}
{include file="perso_footer.tpl"}
\ No newline at end of file
diff --git a/skins/zed/persorequests.tpl b/skins/zed/persorequests.tpl
index b52d26a..7b292b4 100644
--- a/skins/zed/persorequests.tpl
+++ b/skins/zed/persorequests.tpl
@@ -1,89 +1,89 @@
<!-- Javascript bits for request handling -->
<script type="text/javascript">
-
+
//The amount of requests printed on the page.
//When it falls to 0, request_reply_callback will print a temporary exit
//message and then redirects to the homepage.
var requestsQuantity = {count($requests)};
-
+
//Performs an AJAX call
// id the request DOM element id
// url the URL to query
//
//The reply will be handled by request_reply_callback function.
function request_reply (id, url) {
dojo.xhrGet({
handleAs: "json",
url: url,
preventCache: true,
handle: function (response, ioArgs) {
request_reply_callback(response, id);
}
});
}
-
+
//Prints a wap message
// message the error message to print
function wap (message) {
var html = '<div class="wap">' + message + '</div><div class="clear"></div>';
document.getElementById('RequestsWap').innerHTML = html;
}
-
+
//Prints a notify message
// message the warning message to print
function notify (message) {
var html = '<div class="notify">' + message + '</div><div class="clear"></div>';
document.getElementById('RequestsNotify').innerHTML = html;
}
-
+
//This function is called when there isn't requests anymore.
//It prints a close message, clears the site.requests flag and redirects to
//Zed homepage.
function no_more_site_requests () {
document.getElementById('RequestsBody').style.display = 'none';
notify("{#CallbackDone#}");
setTimeout('document.location = "{get_url()}";', 3000);
dojo.xhrGet({
url: '{get_request_url(0, 'perso' , 'site.requests', 0)}',
preventCache: true
});
}
-
+
//Handles the reply
// reply ajax reply ; a boolean is expected, so true or false.
// id the request DOM element id
//
//If the reply is true hides request id.
//If the reply is false outputs a WAP error.
function request_reply_callback (reply, id) {
if (reply == true) {
document.getElementById(id).style.display = 'none';
requestsQuantity--;
if (requestsQuantity == 0) {
no_more_site_requests();
}
} else {
wap("{#CallbackError#}");
}
}
</script>
<!-- Perso requests -->
<div id="RequestsWap"></div>
<div id="RequestsNotify"></div>
<div id="RequestsBody">
<h1>{#Requests#}</h1>
<div class="grid_16 alpha omega">
{foreach from=$requests item=request}
{$i = {counter}}
<div id="request{$i}" class="request message {cycle values="dark,light"}">
<p>{$request->message}</p>
<ul>
<li><a onclick="request_reply('request{$i}', '{get_request_allow_url($request)}'); return false;" href="{get_request_allow_url($request)}?redirectTo={get_url()}">{#Allow#}</li>
<li><a onclick="request_reply('request{$i}', '{get_request_deny_url($request)}'); return false;" href="{get_request_deny_url($request)}?redirectTo={get_url()}">{#Deny#}</a></li>
</ul>
</div>
{/foreach}
</div>
<p><a href="{get_request_url(0, 'perso', 'site.requests', 0)}?redirectTo={get_url()}">{#IgnoreAll#}</a></p>
</div>
\ No newline at end of file
diff --git a/skins/zed/profile.tpl b/skins/zed/profile.tpl
index 2c500ea..b181e4c 100644
--- a/skins/zed/profile.tpl
+++ b/skins/zed/profile.tpl
@@ -1,80 +1,80 @@
<!-- Profile -->
<div class="clear">&nbsp;</div>
<div class="grid_11 alpha">
<!-- Profile header -->
<div class="profile_id clearfix">
<h1 class="profile_nick">{$perso->name}</h1>
<div class="profile_info">
{$perso->location}&nbsp;<br />
{if $perso->is_online()}{#Online#}{/if}
</div>
</div>
<div class="clear">&nbsp;</div>
<div class="profile">
{if $PICS}
<!-- Photos -->
<div class="profile_photos">
{foreach from=$PICS item=photo}
<a rel="lightbox" href="{$URL_PICS}/{$photo->name}" title="{$photo->description}"><img src="{$URL_PICS}/tn/{$photo->name}" alt="{$photo->description}" /></a>
{/foreach}
</div>
{/if}
<!-- Text -->
<div class="profile_text{if $PROFILE_FIXEDWIDTH} fixedwidth{/if}">{if $PROFILE_TEXT != ""}{if $PROFILE_FIXEDWIDTH}{$PROFILE_TEXT}{else}{$PROFILE_TEXT|nl2br}{/if}{else}{if $PROFILE_SELF}<a href="{get_url('who')}/edit/profile">{/if}<img src="{#StaticContentURL#}/img/zed/empty_profile.png" width="642" height="392" alt="Be creative ! Fill this space with your best words." />{if $PROFILE_SELF}</a>{/if}{/if}</div>
-
+
{$PROFILE_TAGS}
-
+
<!-- Leave a message -->
<div class="profile_separator_light"></div>
<div class="profile_message">
<h2 id="Message">{#DropMessage#}</h2>
<form method="post" action="{get_url('who')}/{$perso->nickname}">
<div class="grid_4 alpha">
<input type="radio" name="message_type" value="private_message" checked onclick="document.getElementById('MessageSubmit').value = '{#Send#}';">{sprintf(#SendMessage#, $NAME)}
</div>
<div class="grid_6 omega">
<input type="radio" name="message_type" value="profile_comment" onclick="document.getElementById('MessageSubmit').value = '{#Publish#}';">{sprintf(#AddComment#, $NAME)}
</div>
<p><textarea rows="7" cols="64" name="message"></textarea></p>
<p><input id="MessageSubmit" type="submit" name="MessageSubmit" value="{#Send#}" /></p>
</form>
</div>
- </div>
+ </div>
</div>
-
+
<!-- User content -->
<div class="grid_5 omega">
<div class="sidebar_border"></div>
<div id="sidebar">
- <div class="border_top"></div>
+ <div class="border_top"></div>
<div class="sidebar_content">
-
+
{if $PROFILE_SELF}
<!-- {{counter name=section}|romanize}. edit profile, account, photos -->
<h2>{#EditMyPage#}</h2>
<ul>
<li><a href="{get_url('who','edit','profile')}">{#EditProfile#}</a></li>
<li><a href="{get_url('settings','perso')}">{#EditAccount#}</a></li>
<li><a href="{get_url('who','edit','photos')}">{if $PICS}{#ManagePhotos#}{else}{#AddPhoto#}{/if}</a></li>
</ul>
{/if}
<!-- {{counter name=section}|romanize}. sidebar placeholder/explanation -->
<h2>Sidebar</h2>
<p>Here will be published new art submission, request/offers post it, external content imported, etc.</p>
</div>
<div class="border_bottom"></div>
</div>
</div>
-
-{if $PROFILE_COMMENTS}
+
+{if $PROFILE_COMMENTS}
<!-- Profile comments -->
<div class="grid_16 alpha omega profile_comments" id="comments" style="margin-bottom: 1em;">
{foreach from=$PROFILE_COMMENTS item=comment}
<div class="comment black">
<div class="profile_comments_text"><p>{$comment->text|nl2br}</p></div>
<div class="profile_comments_info">-- <a href="{get_url('who')}/{$comment->author}">{$comment->authorname}</a>, {get_hypership_time($comment->date)}</div>
</div>
{/foreach}
</div>
{/if}
diff --git a/skins/zed/profile_edit.tpl b/skins/zed/profile_edit.tpl
index 8c49243..595b91c 100644
--- a/skins/zed/profile_edit.tpl
+++ b/skins/zed/profile_edit.tpl
@@ -1,59 +1,59 @@
<!-- Calls dojo -->
<script src="/js/dojo/dojo/dojo.js" type="text/javascript"
djConfig="isDebug: false, parseOnLoad: true"></script>
<script type="text/javascript">
dojo.require("dijit.form.Form");
dojo.require("dijit.form.CheckBox");
dojo.require("dijit.form.Button");
-
+
function SetWidgetFont(id, font) {
//TODO: document.getElementById(id).style.font = font;
}
</script>
<!-- Edit profile -->
<div class="grid_11 alpha profile">
<div class="profile_id clearfix">
<h1 class="profile_nick" id="UserLongname">{$USERNAME}</h1>
</div>
<div class="profile_separator"></div>
<div class="profile_text">
<form action="" method="post">
<input type="hidden" name="EditProfile" value="1" />
<h2>{#ProfileTextTitle#}</h2>
<textarea style="font-family: Calibri" id="ProfileText" rows="16" cols="72" name="text" class="text">{$PROFILE_TEXT}</textarea><br />
<div class="row" style="background-color: white; color: black;">
<span>{#ProfileFont#}{#_t#}</span>
<input type="radio" name="fixedwidth" id="fixedwidthNo" value="0" dojoType="dijit.form.RadioButton" {if !$PROFILE_FIXEDWIDTH}checked{/if} onclick="SetWidgetFont('ProfileText', 'Calibri')" />
<label for="fixedwidthNo"><span style="font-family: Calibri, Arial; font-weight: 100; font-size: 1.25em; color: black;">{#Calibri#}</span></label>
<input type="radio" name="fixedwidth" id="fixedwidthYes" value="1" dojoType="dijit.form.RadioButton" {if $PROFILE_FIXEDWIDTH}checked={/if} onclick="SetWidgetFont('ProfileText', 'FixedSys')" />
<label for="fixedwidthYes"><span style='font-family: "Fixedsys Excelsior 3.01", Fixedsys, Fixed; font-weight: 100; color: black;'>{#FixedSys#}</span></label>
</div>
<div class="row">
<button dojoType="dijit.form.Button" iconClass="dijitEditorIcon dijitEditorIconSave" type=submit onclick="document.forms[0].submit()">
{#SaveProfile#}
</button>
<noscript>
<input type="submit" value="{#SaveProfile#} {#JavaScriptSafeMessage#}" />
</noscript>
</div>
</form>
</div>
</div>
-
+
<!-- Faerie content -->
<div class="grid_5 omega">
<div class="sidebar_border"></div>
<div id="sidebar">
- <div class="border_top"></div>
+ <div class="border_top"></div>
<div class="sidebar_content">
<h2>{#EditMyPage#}</h2>
<ul>
<li>{#EditProfile#}</li>
<li><a href="{get_url('settings','perso')}">{#EditAccount#}</a></li>
<li><a href="{get_url('who')}/edit/photos">{if $PICS}{#ManagePhotos#}{else}{#AddPhoto#}{/if}</a></li>
</ul>
</div>
<div class="border_bottom"></div>
</div>
</div>
\ No newline at end of file
diff --git a/skins/zed/profile_photo.tpl b/skins/zed/profile_photo.tpl
index e39f09d..34dbe5f 100644
--- a/skins/zed/profile_photo.tpl
+++ b/skins/zed/profile_photo.tpl
@@ -1,50 +1,50 @@
<!-- Add a photo -->
<div class="grid_11 alpha profile">
<div class="profile_id clearfix">
<h1 class="profile_nick" id="UserLongname">{$USERNAME}</h1>
</div>
<div class="profile_separator"></div>
<div class="profile_text">
<h2>{#AddPhotoToProfile#}</h2>
<form name="PhotoUpload" method="post" enctype="multipart/form-data">
<p>{#AddPhotoExplanations#}</p>
<p><label>Photo{#_t#}</label> <input type="file" name="photo" /></p>
<p><label>{#ShortDescription#}{#_t#}</label> <input type="text" maxlength="63" size="32" name="description" /></p>
<p><input type="checkbox" name="SafeForWork" id="SafeForWork" value="0" /> <label for="SafeForWork">{#SafeForWorkLabel#}</label></p>
<p><input type="submit" value="{#Upload#}" /></p>
</form>
</div>
</div>
-
+
<div class="grid_5 omega">
<div class="sidebar_border"></div>
<div id="sidebar" style="min-height: inherit;">
- <div class="border_top"></div>
+ <div class="border_top"></div>
<div class="sidebar_content">
<h2>{#EditMyPage#}</h2>
<ul>
<li><a href="{get_url('who')}/edit/profile">{#EditProfile#}</a></li>
<li><a href="{get_url('settings','perso')}">{#EditAccount#}</a></li>
<li>{if $PICS}{#ManagePhotos#}{else}{#AddPhoto#}{/if}</li>
</ul>
</div>
<div class="border_bottom"></div>
</div>
</div>
-
+
{if $PICS}
<!-- Manage current photos -->
<div class="grid_16 alpha omega profile_comments">
<h2>{#ManageCurrentPhotos#}</h2>
<div class="photos">
{foreach from=$PICS item=photo}
<div class="photo" style="float: left">
<a rel="lightbox" href="{$URL_PICS}/{$photo->name}" title="{$photo->description}"><img src="{$URL_PICS}/tn/{$photo->name}" alt="{$photo->description}" /></a>
<br />
<a href="{get_url('who')}/edit/photos/edit/{$photo->id}" title="{#EditPictureProperties#}"><img src="/skins/VacuumCleanerBridge/images/open.gif" alt="{#PictureProperties#}"></a>
<a href="{get_url('who')}/edit/photos/delete/{$photo->id}" title="{#DeleteThisPicture#}"><img src="/skins/VacuumCleanerBridge/images/del.gif" alt="{#Delete#}"></a>
</div>
{/foreach}
</div>
{/if}
</div>
\ No newline at end of file
diff --git a/skins/zed/profile_photo_edit.tpl b/skins/zed/profile_photo_edit.tpl
index 9a02a51..2ea8093 100644
--- a/skins/zed/profile_photo_edit.tpl
+++ b/skins/zed/profile_photo_edit.tpl
@@ -1,36 +1,36 @@
<div class="grid_11 alpha">
<h1>{#EditPhoto#}</h1>
<a rel="lightbox" href="{$URL_PICS}/{$photo->name}" title="{$photo->description}"><img src="{$URL_PICS}/tn/{$photo->name}" alt="{$photo->description}" /></a>
<h2>{#PhotoInfo#}</h2>
<form method=post><input type="hidden" name="id" value="{$photo->id}" />
<blockquote>
<table>
<tr><td><strong><label for="description">{#Description#}</label></strong></td><td><input type='text' id='description' name='description' maxlength=63 value="{$photo->description}" /></td></tr>
<tr><td><strong><label for="safe">{#SafeForWork#}</label></strong></td><td><input type='checkbox' id='safe' name='safe' maxlength=3 size=5 value=1{if $photo->safe} checked{/if} /></td></tr>
<tr><td><strong><label for="avatar">{#UseAsAvatar#}</label></strong></td><td><input type='checkbox' id='avatar' name='avatar' maxlength=3 size=5 value=1{if $photo->avatar} checked{/if} /></td></tr>
<tr><td>&nbsp;</td><td><input type="submit" value="{#Save#}" /></td></tr>
</table>
</blockquote>
</form>
<h2>{#OtherActions#}</h2>
<ul>
<li><a href="{get_url('who')}/edit/photos/delete/{$photo->id}" title="{#DeletePicture#}">{#DeletePicture#}</a></li>
<li><a href="{get_url('who')}/edit/photos">{#BackToPhotoManager#}</a></li>
</ul>
</div>
-
+
<div class="grid_5 omega">
<div class="sidebar_border"></div>
<div id="sidebar" style="min-height: inherit;">
- <div class="border_top"></div>
+ <div class="border_top"></div>
<div class="sidebar_content">
<h2>{#EditMyPage#}</h2>
<ul>
<li><a href="{get_url('who')}/edit/profile">{#EditProfile#}</a></li>
<li><a href="{get_url('settings','perso')}">{#EditAccount#}</a></li>
<li>{if $PICS}{#ManagePhotos#}{else}{#AddPhoto#}{/if}</a></li>
</ul>
</div>
<div class="border_bottom"></div>
</div>
</div>
\ No newline at end of file
diff --git a/skins/zed/requests/aid.reach.tpl b/skins/zed/requests/aid.reach.tpl
index 8de64c3..5761830 100644
--- a/skins/zed/requests/aid.reach.tpl
+++ b/skins/zed/requests/aid.reach.tpl
@@ -1,24 +1,24 @@
<!-- DIJIT -->
<script type="text/javascript">
dojo.require("dijit.form.Form");
dojo.require("dijit.form.ValidationTextBox");
dojo.require("dijit.form.Button");
</script>
-
+
<!-- Request form: aid.reach -->
<h1>{#Communicator#}</h1>
<h2>{#SendRequestToHyperShip#}</h2>
<form dojoType="dijit.form.Form" name="aid.reach" method="post">
<div class="row">
<label class="firstLabel" for="PostTitle">{#Title#}</label>
<input dojoType="dijit.form.ValidationTextBox" value="{$request->title}" type="text" id="PostTitle" name="title" class="long" required="true" />
</div>
<div class="row">
<label class="firstLabel" for="PostMessage">{#Message#}</label>
<textarea id="PostMessage" name="message" cols="80" rows="8"></textarea>
</div>
<div class="row">
<button dojoType="dijit.form.Button" iconClass="dijitEditorIcon dijitEditorIconSave" type="submit" value="Save" />{#Send#}</button>
</div>
<p><strong>{#Warning#}</strong> {#RequestHandledByHumans#}</p>
</form>
\ No newline at end of file
diff --git a/skins/zed/requests/confirm.tpl b/skins/zed/requests/confirm.tpl
index aa5992b..4aa146f 100644
--- a/skins/zed/requests/confirm.tpl
+++ b/skins/zed/requests/confirm.tpl
@@ -1,6 +1,6 @@
<div class="content_wrapper">
<h1>{#Communicator#}</h1>
<div class="content">
<p>{#RequestSent#}</p>
- </div>
+ </div>
</div>
\ No newline at end of file
diff --git a/skins/zed/settings_page.tpl b/skins/zed/settings_page.tpl
index b4bcb5c..699d574 100644
--- a/skins/zed/settings_page.tpl
+++ b/skins/zed/settings_page.tpl
@@ -1,67 +1,67 @@
<!-- DIJIT -->
<script type="text/javascript">
dojo.require("dijit.form.Form");
dojo.require("dijit.form.TextBox");
dojo.require("dijit.form.ValidationTextBox");
dojo.require("dijit.form.Button");
dojo.require("dijit.form.FilteringSelect");
dojo.require("dijit.form.CheckBox");
-
+
dojo.require("dojox.form.PasswordValidator");
</script>
<!-- Settings - #{$page->id} -->
<div class="grid_12 alpha">
<h2>{#$page->title#}</h2>
<form method="post">
<input type="hidden" name="settings.page" value="{$page->id}" />
{foreach from=$page->settings item=setting}
<div class="row">
{if $setting->field == "validationtext"}
<label for="{$setting->key}" class="firstLabel ">{#$setting->key#}</label>
<input dojoType="dijit.form.ValidationTextBox" regExp="{$setting->regExp}" id="{$setting->key}" name="{$setting->key}" type="text" value="{$setting->get()}" class="long" />
{elseif $setting->field == "text"}
<label for="{$setting->key}" class="firstLabel ">{#$setting->key#}</label>
<input dojoType="dijit.form.TextBox" id="{$setting->key}" name="{$setting->key}" type="text" value="{$setting->get()}" class="long" />
{elseif $setting->field == "password"}
<div dojoType="dojox.form.PasswordValidator" name="{$setting->key}">
<label for="{$setting->key}" class="firstLabel ">{#$setting->key#}</label>
<input type="password" pwType="new" id="{$setting->key}" name="{$setting->key}" value="{$setting->get()}" class="long" />
<br />
<label for="{$setting->key}_confirm" class="firstLabel">{#$setting->key#} {#PasswordConfirm#}</label>
<input type="password" pwType="verify" id="{$setting->key}_confirm" name="{$setting->key}_confirm" value="{$setting->get()}" class="long" />
</div>
{elseif $setting->field == "filteredlist"}
<label for="{$setting->key}" class="firstLabel ">{#$setting->key#}</label>
<select id="{$setting->key}" name="{$setting->key}" dojoType="dijit.form.FilteringSelect" class="long">
{foreach from=$setting->choices item=value key=key}
<option value="{$value}">{#$key#}</option>
{/foreach}
</select>
{elseif $setting->field == "checkbox"}
<input type="checkbox" dojoType="dijit.form.CheckBox" id="{$setting->key}" name="{$setting->key}" value="1" {if $setting->get()}checked="true" {/if}/> <label for="{$setting->key}">{#$setting->key#}</label>
{else}{dprint_r($setting)}
{/if}
</div>
{/foreach}
<div class="row">
<button dojoType="dijit.form.Button" iconClass="dijitEditorIcon dijitEditorIconSave" type="submit" value="Save" />{#SaveSettings#}</button>
</div>
</form>
</div>
-
+
<div class="grid_4 omega">
<h2>Settings</h2>
<ul style="list-style-type: cjk-ideographic; line-height: 2em;">
{foreach from=$pages item=value key=key}
{if $key == $page->id}
<li>{$value}</li>
{else}
<li><a href="{get_url('settings', $key)}">{$value}</a></li>
{/if}
{/foreach}
<li><a href="{get_url('who', 'edit', 'profile')}">{#EditProfile#}</a></li>
</ul>
</div>
-
+
<div class="clear"></div>
\ No newline at end of file
diff --git a/skins/zed/ship.tpl b/skins/zed/ship.tpl
index 3aaaab1..3d6cce7 100644
--- a/skins/zed/ship.tpl
+++ b/skins/zed/ship.tpl
@@ -1,30 +1,30 @@
<!-- Ship CSS -->
<style>
.content textarea {
background-color: inherit;
color: white;
border: dashed #343434 2px;
width: 100%;
background-image: url("/img/zed/opaque_20.png");
}
</style>
-
+
<!-- Ship content -->
<div class="content_wrapper">
<h1>{$ship->name}</h1>
<div class="content">
<p>Lorem ipsum dolor</p>
<h2>{#PersonalNotes#}</h2>
<form method="POST">
<input type="hidden" name="action" value="ship.setnote">
<textarea id="ShipNote" name="note" rows="8" onfocus="set_opacity(this.id, 20)" onBlur="set_opacity(this.id, 0)">{$note}</textarea>
<br />
<input type="submit" value="{#SaveNote#}" />
</form>
</div>
</div>
-
+
<script>
//Sets the focus on note textarea
document.getElementById('ShipNote').focus();
</script>
\ No newline at end of file
diff --git a/skins/zed/smartline.tpl b/skins/zed/smartline.tpl
index b41fb94..c3f137d 100644
--- a/skins/zed/smartline.tpl
+++ b/skins/zed/smartline.tpl
@@ -1,26 +1,26 @@
<!-- SmartLine -->
<div class="grid_16 alpha omega" id="SmartLine">
<form name="SmartLine" method="{if $SmartLineFormMethod}{$SmartLineFormMethod}{else}post{/if}" action="{get_current_url()}">
{if $SmartLineHistory}
<!-- SmartLine history -->
<div class="grid_4 left alpha">
<select id="SmartLineHistory" class="black" onchange="UpdateSmartLine()">
<option value="">[ {#SmartLineHistory#} ]</option>
{foreach from=$SmartLineHistory item=command}
<option value="{$command.text|escape}">{$command.time} | {$command.text|escape}</option>
{/foreach}
</select>
</div>
<!-- SmartLine line -->
<div class="grid_12 right omega">
{else}
<!-- SmartLine line -->
<div class="grid_16 alpha omega left" style="width: 100.2%">
{/if}
<input name="C" type="text" id="SmartLineBar" maxlength="255" class="black" style="text-align: left;" />
</div>
</form>
</div>
-
+
<div class="clear"></div>
diff --git a/skins/zed/smartline_results.tpl b/skins/zed/smartline_results.tpl
index d230e2e..b539520 100644
--- a/skins/zed/smartline_results.tpl
+++ b/skins/zed/smartline_results.tpl
@@ -1,14 +1,13 @@
<!-- SmartLine output -->
<div id="SmartLineResults" class="black">
{if $SmartLine_STDOUT}
<p>{$SmartLine_STDOUT}</p>
{/if}
{if $SmartLine_STDERR}
<p class="error">{$SmartLine_STDERR}</p>
{/if}
-
+
</div>
-
+
<p class="clear"></p>
-
-
\ No newline at end of file
+
diff --git a/skins/zed/story.tpl b/skins/zed/story.tpl
index b5a5cab..7d8d33a 100644
--- a/skins/zed/story.tpl
+++ b/skins/zed/story.tpl
@@ -1,30 +1,30 @@
{$description = $section->description|trim}
{foreach from=$section->hooks item=hook}
{$hook->update_description($description)}
{/foreach}
<!-- Story -->
<div class="content_wrapper">
<h1>{$PAGE_TITLE}</h1>
<div class="content">
<h2>{$section->title}</h2>
<p>{$description|text2html}</p>
<ul>
{if $section->choices}
{foreach from=$section->choices item=choice}
<li><a href="{get_url('explore', $choice->guid)}">{$choice->text}</a></li>{/foreach}{/if}
{$links = array()}
{foreach from=$section->hooks item=hook}
{$hook->get_choices_links($links)}
{/foreach}
{foreach from=$links item=link}
<li><a href="{$link[1]}">{$link[0]}</a></li>{/foreach}
</ul>
{foreach from=$section->hooks item=hook}
{$hook->add_content()}
{/foreach}
</div>
</div>
-
+
{foreach from=$section->hooks item=hook}
{$hook->add_html()}
{/foreach}
\ No newline at end of file
diff --git a/skins/zed/user_account.tpl b/skins/zed/user_account.tpl
index 6772398..c864ce9 100644
--- a/skins/zed/user_account.tpl
+++ b/skins/zed/user_account.tpl
@@ -1,88 +1,88 @@
<!-- Calls dojo -->
<script src="/js/dojo/dojo/dojo.js" type="text/javascript"
djConfig="isDebug: false, parseOnLoad: true"></script>
<script type="text/javascript">
dojo.require("dijit.form.Form");
dojo.require("dijit.form.ValidationTextBox");
dojo.require("dijit.form.CheckBox");
dojo.require("dijit.form.Button");
function updateMail (mail) {
document.getElementById('UserEmail').innerHTML =
'<a href="mailto:' + mail + '">' + mail + '</a>';
}
</script>
-
+
<!-- Edit user account form -->
<div class="grid_11 alpha profile">
<div class="profile_id clearfix">
<h1 class="profile_nick" id="UserLongname">{$user->longname}</h1>
<div class="profile_info">
<br />
<img src="/skins/VacuumCleanerBridge/images/mail.png" title="{#Mail#}" alt="{#MailAlt#}" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span id="UserEmail">{mailto address=$user->email}</span>&nbsp;
</div>
</div>
<div class="profile_separator"></div>
<div class="profile_text">
<br />
- <form dojoType="dijit.form.Form" name="UserAccount" method="POST">
+ <form dojoType="dijit.form.Form" name="UserAccount" method="POST">
<input type="hidden" name="UserAccount" value="1" />
<div class="row">
<span class="firstLabel">{#Login#}</span>
{$user->username}
</div>
<div class="row">
<label class="firstLabel" for="longname">{#LongName#}</label>
<input type="text" id="longname" name="longname" class="long"
value="{$user->longname}"
dojoType="dijit.form.ValidationTextBox"
required="false"
onchange="document.getElementById('UserLongname').innerHTML = document.getElementById('longname').value;";
/>
- </div>
+ </div>
<div class="row">
<label class="firstLabel" for="realname">{#RealName#}</label>
<input type="text" id="realname" name="realname" class="long"
value="{$user->realname}"
dojoType="dijit.form.ValidationTextBox"
- required="false"
+ required="false"
/>
<span class="dojotooltip" dojoType="dijit.Tooltip" connectId="realname">{#RealNameToolTip#}</span>
</div>
<div class="row">
<label class="firstLabel" for="email">{#Mail#}</label>
<input type="text" id="email" name="email" class="long"
value="{$user->email}"
dojoType="dijit.form.ValidationTextBox"
- required="false"
+ required="false"
onchange="javascript:updateMail(arguments[0]);"
/>
</div>
<div class="row">
<button dojoType="dijit.form.Button" iconClass="dijitEditorIcon dijitEditorIconSave" type="submit" onclick="document.forms[0].submit()">
{#UpdateAccountInfo#}
</button>
<noscript>
<input type="submit" value="{#UpdateAccountInfo#} {#JavaScriptSafeMessage#}" />
</noscript>
</div>
</form>
</div>
</div>
<!-- Faerie content -->
<div class="grid_5 omega">
<div class="sidebar_border"></div>
<div id="sidebar">
- <div class="border_top"></div>
+ <div class="border_top"></div>
<div class="sidebar_content">
<h2>{#EditMyPage#}</h2>
<ul>
<li><a href="{get_url('who')}/edit/profile">{#EditProfile#}</a></li>
<li>{#EditAccount#}</li>
<li><a href="{get_url('who')}/edit/photos">{if $PICS}{#ManagePhotos#}{else}{#AddPhoto#}{/if}</a></li>
</ul>
</div>
<div class="border_bottom"></div>
</div>
</div>
\ No newline at end of file
diff --git a/start.html b/start.html
index 6badb10..d93219f 100644
--- a/start.html
+++ b/start.html
@@ -1,30 +1,30 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd"
>
<html lang="en">
<head>
<title>Zed. The future is our dreams.</title>
<style>
body {
background-color: #303030;
margin: 0 0 0 0;
overflow: hidden;
}
-
+
#start {
margin: auto;
width: 960px;
height: 4000px;
background-color: #343434;
background-image: url(img/misc/start.png);
background-position: top left;
background-repeat: no-repeat;
border-left: dashed 3px white;
border-right: dashed 3px white;
}
</style>
</head>
<body>
<div id="start"></div>
</body>
</html>
diff --git a/tour.html b/tour.html
index 31838e3..bdb50e3 100644
--- a/tour.html
+++ b/tour.html
@@ -1,44 +1,44 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Enter</title>
<link rel="stylesheet" type="text/css" href="css/grid.css" media="screen" />
<script type="text/javascript" src="js/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="js/dimensions.js"></script>
<script type="text/javascript" src="js/tour.js"></script>
<style type="text/css">
body {
background-color: #343434;
overflow: hidden;
}
-
+
H1 {
font-family: Helvetica, Arial;
}
-
+
#Tour {
background-image: url(img/tour/bg.jpg);
height: 748px;
width: 748px;
margin: auto auto auto auto;
z-index: 20;
}
-
+
#TourHighlight {
position: relative;
z-index: 50;
}
</style>
</head>
<body>
<div class="container_16">
<div class="grid_16">
<div id="Tour">
<div id="TourHighlight"></div>
</div>
</div>
<div class="clear"></div>
</div>
</body>
</html>
\ No newline at end of file
diff --git a/tour2.html b/tour2.html
index 3b1ce8a..7e388c3 100644
--- a/tour2.html
+++ b/tour2.html
@@ -1,46 +1,46 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Enter</title>
<link rel="stylesheet" type="text/css" href="css/grid.css" media="screen" />
<script src="http://zed.espace-win.org.nyud.net/js/jquery-1.3.2.min.js"></script>
<script src="http://zed.espace-win.org.nyud.net/js/dimensions.js"></script>
<script src="http://zed.espace-win.org.nyud.net/js/tour2.js"></script>
<script>
</script>
<style>
body {
background-color: #343434;
}
-
+
H1 {
font-family: Helvetica, Arial;
}
-
+
#Tour {
background-image: url(http://zed.espace-win.org.nyud.net/img/tour/bg.jpg);
height: 748px;
width: 748px;
margin: auto auto auto auto;
z-index: 20;
}
-
+
#TourHighlight {
position: relative;
z-index: 50;
}
</style>
</head>
<body>
<div class="container_16">
<div class="grid_16">
<div id="Tour">
<div id="TourHighlight"></div>
</div>
</div>
<div class="clear"></div>
</div>
</body>
</html>
\ No newline at end of file

File Metadata

Mime Type
text/x-diff
Expires
Mon, Nov 11, 11:07 (2 w, 3 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
20949
Default Alt Text
(574 KB)

Event Timeline