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/apps/HelloWorldWebService.php b/apps/HelloWorldWebService.php
index 9931eac..54a5e21 100644
--- a/apps/HelloWorldWebService.php
+++ b/apps/HelloWorldWebService.php
@@ -1,27 +1,25 @@
<?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 a930796..3031825 100644
--- a/apps/pazaak/debug.php
+++ b/apps/pazaak/debug.php
@@ -1,63 +1,61 @@
<?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/content/stories/B00003001.xml b/content/stories/B00003001.xml
index 6ecddaf..08f5f54 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.
-->
<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.
</description>
</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>
<choice goto="panorama">Retourner en ville</choice>
</choices>
</section>
-</story>
\ No newline at end of file
+</story>
diff --git a/content/stories/B00004001.xml b/content/stories/B00004001.xml
index 7559e82..645e312 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
</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>
<local>3</local>
</section>
<!--
Le temple
-->
-</story>
\ No newline at end of file
+</story>
diff --git a/content/travel.xml b/content/travel.xml
index 542e8e4..837bbdd 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
+</Travel>
diff --git a/controllers/anonymous.php b/controllers/anonymous.php
index 5c627fa..a700391 100644
--- a/controllers/anonymous.php
+++ b/controllers/anonymous.php
@@ -1,152 +1,150 @@
<?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/builder.php b/controllers/builder.php
index eec0eb3..1254627 100644
--- a/controllers/builder.php
+++ b/controllers/builder.php
@@ -1,137 +1,135 @@
<?php
/**
* Builder
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* @package Zed
* @subpackage Controllers
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/gpl-2.0.php GPLv2
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
require_once('includes/content/zone.php');
//
// Helper methods
//
/**
* Determines if a specified location is buildable
*
* @param GeoLocation $location the location to check
* @param string if the location isn't buidable, a textual description of why.
* @return bool true if the location is buildable ; otherwise, false
*
* @todo create a build.xml document to set what's buildable, and by who
*/
function is_buildable ($location, &$error = '') {
//We currently allow build only in the hypership tower and core.
if (!$location->body->hypership) {
$error = "You can only invoke the HyperShip builder facilities inside the HyperShip.";
return false;
}
//if ($build_location->place->code == "001") {
// //Don't allow custom builds in the corridor (T?C?)
//}
if ($build_location->place->code == "003") {
message_die("Bays aren't buildable.");
return false;
}
return true;
}
//
// Determines mode and initializes resources
//
switch ($build_mode = $url[1]) {
case 'map':
require_once('includes/geo/octocube.php');
$build_mode = 'map';
//Get zones at this floor
if ($CurrentPerso->location->global == 'B00001002') {
$point = GeoPoint3D::fromString($CurrentPerso->location->local);
$sector = GeoOctocube::get_sector_from_point3D($point);
$pattern = GeoOctocube::get_rlike_pattern_from_sector($sector, $point->z);
$zones = ContentZone::search($CurrentPerso->location->global, $pattern, true);
} else {
message_die(GENERAL_ERROR, "Can't map this area.", "Builder :: Map");
}
//Template
define('DOJO', true);
$smarty->assign('zones', $zones);
$template = "builder_map.tpl";
break;
case '':
case 'hotglue':
//Temporary initialization code, to allow some build during the Zed alphatest
$build_location = $CurrentPerso->location;
$build_mode = 'hotglue';
$error = '';
if (!is_buildable($build_location, $error)) {
message_die(GENERAL_ERROR, $error, "Can't build");
}
//Gets or creates a new zone at build location
$zone = ContentZone::at($build_location->global, $build_location->local, true);
switch ($zone->type) {
case 'hotglue':
//All rulez
break;
case '':
//New zone
$zone->title = "Sandbox hotglue zone for $build_location->global $build_location->local";
$zone->type = 'hotglue';
$zone->save_to_database();
break;
default:
message_die("This isn't a zone managed by hotglue.");
}
unset($error);
//Template
$smarty->assign('location', $build_location);
$smarty->assign('zone', $zone);
$smarty->assign('IFRAME_SRC', '/apps/hotglue/index.php?zone_' . $zone->id . '/edit');
$template = 'builder_hotglue.tpl';
break;
default:
message_die(GENERAL_ERROR, "Unknown build mode: $build_mode");
}
//
// HTML output
//
//Serves header
$smarty->assign('PAGE_TITLE', 'Builder');
include('header.php');
//Serves content
$smarty->display($template);
//Serves footer
include('footer.php');
-
-?>
diff --git a/controllers/explore.php b/controllers/explore.php
index 0319d04..4145af5 100644
--- a/controllers/explore.php
+++ b/controllers/explore.php
@@ -1,51 +1,49 @@
<?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/footer.php b/controllers/footer.php
index 3a8e04b..9312f98 100644
--- a/controllers/footer.php
+++ b/controllers/footer.php
@@ -1,54 +1,52 @@
<?php
/**
* Footer
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* This is a redirect controller to call the relevant controller,
* according to the location.
*
* It handles and prints the footer elements (tutorial, SmartLine, html footer)
*
* @package Zed
* @subpackage Controllers
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
if (!defined('NO_FOOTER_EXTRA')) {
///
/// Tutorials div
///
if ($controller != 'explore' && (!array_key_exists('hypership.reached', $CurrentPerso->flags) || $CurrentPerso->flags['hypership.reached'] < 1)) {
if (!DOJO) $smarty->display('tutorial/dojo.tpl');
lang_load("tutorials.conf", "ReachHypership");
$smarty->assign('controller', $controller);
$smarty->display('tutorial/hypership_reach.tpl');
}
///
/// Footer options
///
$smarty->assign('MultiPerso', isset($_SESSION['UserWithSeveralPersos']) && $_SESSION['UserWithSeveralPersos']);
$smarty->assign('SmartLinePrint', (string)$CurrentPerso->get_flag('site.smartline.show') != "0");
$smarty->assign('SmartLineFormMethod', $CurrentPerso->get_flag('site.smartline.method'));
}
///
/// HTML output
///
lang_load('footer.conf');
$smarty->display('footer.tpl');
-
-?>
diff --git a/controllers/header.php b/controllers/header.php
index e9bec5d..625f296 100644
--- a/controllers/header.php
+++ b/controllers/header.php
@@ -1,62 +1,61 @@
<?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/home.php b/controllers/home.php
index 8abe01d..906b7a3 100644
--- a/controllers/home.php
+++ b/controllers/home.php
@@ -1,103 +1,101 @@
<?php
/**
* Homepage
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* This controller handle the / URL.
*
* It prints:
* a scene rendering from where the perso is ;
* the home.tpl view ;
* the messages, using the messages.tpl view.
*
* The controller also handle messages, marking them red and allowing their
* suppression: /?action=msg_delete&id=8 to delete the message #8.
*
* @package Zed
* @subpackage Controllers
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*
* @todo The homepage requires Dojo but Dojo loading here is currently a kludge, as dojo is required by hypership .tpl scene. We should create an optionnal .meta xml file format to set this kind of options.
*/
//
// Gets and manage messages
//
require_once('includes/objects/message.php');
//Deletes a message if user have clicked the X
if ($_GET['action'] == 'msg_delete') {
//Deletes message $_GET['id']
$id = $_GET['id'];
$messageToDelete = new Message($id);
if ($messageToDelete->to != $CurrentPerso->id) {
//Not one of user message
$smarty->assign('WAP', lang_get('NotYourMessage'));
} elseif ($messageToDelete->flag == 2) {
//Already deleted
$smarty->assign('WAP', lang_get('MessageAlreadyDeleted'));
} else {
$messageToDelete->delete();
$smarty->assign('NOTIFY', lang_get('MessageDeleted'));
}
}
//Gets messages
$newMessagesCount = 0;
$messages = Message::get_messages($CurrentPerso->id, true, $newMessagesCount);
if ($newMessagesCount > 0) {
$smarty->assign('NOTIFY', sprintf(lang_get("NewMessages"), $newMessagesCount, s($newMessagesCount)));
}
//Gets scene
require_once("includes/geo/scene.php");
$scene = new GeoScene($CurrentPerso->location);
$smarty->assign('SCENE', $scene);
//
// HTML output
//
//Serves header
//TODO: Dojo loading here is currently a kludge, as dojo is required by
//hypership .tpl scene. We should create an optionnal .meta xml file format
//to set this kind of options
if (!defined('DIJIT')) {
/**
* This constant indicates we need to load the Dijit (and so Dojo) library.
*/
define('DIJIT', true);
}
$smarty->assign('PAGE_TITLE', lang_get('Welcome'));
include('header.php');
//Serves content
if (!$scene->lastError)
$scene->render();
$smarty->display('home.tpl');
if ($messages) {
$smarty->assign('MESSAGES', $messages);
$smarty->display('messages.tpl');
}
//Serves footer
$smarty->assign("screen", "Home console");
include('footer.php');
-
-?>
diff --git a/controllers/motd.php b/controllers/motd.php
index a5e66e3..5867b80 100644
--- a/controllers/motd.php
+++ b/controllers/motd.php
@@ -1,56 +1,54 @@
<?php
/**
* MOTD
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* This controller handle the /push "secret" URL.
*
* It allows to add a message in the MOTD (messages printed in the header on
* the top of each page).
*
* It usees the motd_add.tpl view and the MOTD class.
*
* @package Zed
* @subpackage Controllers
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
//
// Handles form
//
if ($_REQUEST['text']) {
require_once('includes/objects/motd.php');
$motd = new MOTD();
$motd->text = $_REQUEST['text'];
$motd->perso_id = $CurrentPerso->id;
$motd->save_to_database();
$smarty->assign('WAP', lang_get('Published'));
}
//
// HTML output
//
//Serves header
$smarty->assign('PAGE_TITLE', lang_get('PushMessage'));
include('header.php');
//Serves content
$smarty->display('motd_add.tpl');
//Servers footer
include('footer.php');
-
-?>
\ No newline at end of file
diff --git a/controllers/page.php b/controllers/page.php
index d548153..4bc306c 100644
--- a/controllers/page.php
+++ b/controllers/page.php
@@ -1,135 +1,133 @@
<?php
/**
* Page
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* This controller handle the /page URL.
*
* It allows to prints a content page.
*
* The code of the content page to print must be included in the URL:
* /page/quux will print the quux page.
*
* To edit a page, append ?mode=edit to the URL.
*
* It usees the page_edit.tpl view to edit and the raw.tpl view to print pages.
*
* Versions of the edited pages are saved in a separate table
* but it's not a wiki, it's for backup purposes.
*
* @package Zed
* @subpackage Controllers
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*
* @todo move "handle editor form" and some of the "gets page" code to a includes/objets/page.php file (rationale: cleaner model/controller separation)
*/
if (!$code = $db->sql_escape($url[1])) {
message_die(HACK_ERROR, "/page/ must be followed by page code");
}
//
// Handles editor form
//
if ($_POST['code']) {
//Ask flag admin.pages.editor
$CurrentPerso->request_flag('admin.pages.editor');
//Gets version
$sql = "SELECT MAX(page_version) + 1 FROM " . TABLE_PAGES_EDITS .
" WHERE page_code = '$code'";
if (!$result = $db->sql_query($sql)) message_die(SQL_ERROR, "Can't fetch pages", '', __LINE__, __FILE__, $sql);
$row = $db->sql_fetchrow($result);
$page_version = ($row[0] == "") ? 0 : $row[0];
//Gets other fields
$page_code = $db->sql_escape($code);
$page_title = $db->sql_escape($_POST['title']);
$page_content = $db->sql_escape($_POST['content']);
$page_edit_reason = $db->sql_escape($_POST['edit_reason']);
$page_edit_user_id = $CurrentPerso->user_id;
$page_edit_time = time();
//Saves archive version
$sql = "INSERT INTO " . TABLE_PAGES_EDITS . " (`page_code`, `page_version`, `page_title`, `page_content`, `page_edit_reason`, `page_edit_user_id`, `page_edit_time`) VALUES ('$page_code', '$page_version', '$page_title', '$page_content', '$page_edit_reason', '$page_edit_user_id', '$page_edit_time')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't save page", '', __LINE__, __FILE__, $sql);
}
//Saves prod version
$sql = "REPLACE INTO " . TABLE_PAGES . " (`page_code`, `page_title`, `page_content`) VALUES ('$page_code', '$page_title', '$page_content')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't save page", '', __LINE__, __FILE__, $sql);
}
$smarty->assign('NOTIFY', "Page $page_code saved, version $page_version.");
}
//
// Gets page
//
$sql = "SELECT page_title, page_content, page_code FROM " . TABLE_PAGES . " WHERE page_code LIKE '$code'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Can't get pages", '', __LINE__, __FILE__, $sql);
$row = $db->sql_fetchrow($result);
switch ($_GET['mode']) {
case 'edit':
$CurrentPerso->request_flag('admin.pages.editor');
$template = 'page_edit.tpl';
if ($row) {
$smarty->assign('PAGE_TITLE', $row['page_title']);
$smarty->assign('page', $row);
} else {
$smarty->assign('PAGE_TITLE', $code);
$page['page_code'] = $code;
$smarty->assign('page', $page);
unset($page);
}
$smarty->assign('PAGE_JS', 'FCKeditor/fckeditor.js');
break;
default:
if ($row) {
$smarty->assign('PAGE_TITLE', $row['page_title']);
$content = $row['page_content'];
} else {
$smarty->assign('PAGE_TITLE', lang_get('PageNotFound'));
$content = lang_get('PageNotFound');
}
//Adds edit link
if ($CurrentPerso->flags['admin.pages.editor']) {
$content .= '<p class="info" style="text-align: right">[ <a href="?mode=edit">Edit page</a> ]</p>';
}
$template = 'raw.tpl';
$smarty->assign('CONTENT', $content);
break;
}
//
// HTML output
//
//Serves header
include('header.php');
//Serves content
$smarty->display($template);
//Serves footer
include('footer.php');
-
-?>
\ No newline at end of file
diff --git a/controllers/persorequest.php b/controllers/persorequest.php
index 5814bfc..afca926 100644
--- a/controllers/persorequest.php
+++ b/controllers/persorequest.php
@@ -1,168 +1,166 @@
<?php
/**
* Persos' requests
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* This controller handle the /requests URL.
*
* It can also be called with the requests SmartLine command.
*
* It allows to prints a content page.
*
* This controllers uses the persorequests.tpl view.
*
* This controller offer AJAX capabilities but degrades gracefully in JS.
*
* @package Zed
* @subpackage Controllers
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*
* @todo Document the request system in the API documentation
*/
///
/// Helper class and method
///
/**
* A perso request
*/
class PersoRequest {
public $message;
public $requestFlag;
public $flag;
public $store = 'perso';
public $value_allow = 1;
public $value_deny = 0;
/**
* Initialies a perso request
*
* @param string $requestFlag the request's flag
* @param string $message the message to print
* @param string $message the flag to set, according the request approve/denial
*/
function __construct ($requestFlag, $message, $flag) {
$this->requestFlag = $requestFlag;
$this->message = $message;
$this->flag = $flag;
}
}
/**
* Gets request allow URL
*
* @param PersoRequest $request the perso request to confirm
* @return string the URL to allow the request
*/
function get_request_allow_url ($request) {
return get_request_url($request->requestFlag, $request->store, $request->flag, $request->value_allow);
}
/**
* Gets request deny URL
*
* @param PersoRequest $request the perso request to confirm
* @return string the URL to deny the request
*/
function get_request_deny_url ($request) {
return get_request_url($request->requestFlag, $request->store, $request->flag, $request->value_deny);
}
/**
* Gets request URL
*
* @param string $store 'perso' or 'registry'
* @param string $key the perso flag or registry key
* @param string $value the value to store
* @return the request URL
*/
function get_request_url ($requestFlag, $store, $key, $value) {
global $Config;
$hash = md5($_SESSION['ID'] . $Config['SecretKey'] . $requestFlag . $store . $key . $value);
return "$Config[DoURL]/perso_request/$requestFlag/$store/$key/$value/$hash";
}
///
/// Get requests
///
//Loads perso request language file
lang_load('persorequest.conf');
//The array request will be passed to Smarty and will contain PersoRequest items.
$requests = array();
foreach ($CurrentPerso->flags as $flag => $value) {
if ($value && substr($flag, 0, 8) == "request.") {
if (string_starts_with($flag, 'request.api.ship.auth.')) {
//Gets ship
require_once('include/objects/ship.php');
$ship_code = substr($flag, 22);
$ship = Ship::get($ship_code);
//Adds request
$message = sprintf(lang_get('RequestShipAPIAuthenticate'), $ship->name);
$requests[] = new PersoRequest($flag, $message, substr($flag, 8));
} elseif (string_starts_with($flag, 'request.api.ship.session.')) {
//Gets ship
require_once('include/objects/ship.php');
$ship_code = substr($flag, 25, 6);
$ship = Ship::get($ship_code);
//Adds request
$message = sprintf(lang_get('RequestShipAPISessionConfirm'), $ship->name);
$request = new PersoRequest($flag, $message, substr($flag, 8));
$request->value_allow = $CurrentPerso->id;
$request->value_deny = -1;
$request->store = 'registry';
$requests[] = $request;
} else {
message_die(GENERAL_ERROR, "Unknown request flag: $flag. Please report this bug.");
}
}
}
///
/// Requests handling
///
if (count($requests) == 0) {
//If site.requests flag is at 1 but we don't have request, ignore processing
$CurrentPerso->set_flag('site.requests', 0);
//We don't die, so next controller takes relay
} else {
///
/// HTML output
///
//Serves header
define('DOJO', true);
$smarty->assign('PAGE_TITLE', lang_get('PersoRequests'));
include('header.php');
//Serves content
$smarty->assign('requests', $requests);
$smarty->display('persorequests.tpl');
//Serves footer
$smarty->assign("screen", "Perso requests");
include('footer.php');
//Dies
exit;
}
-
-?>
\ No newline at end of file
diff --git a/controllers/profile.php b/controllers/profile.php
index 2b293a2..79fb198 100644
--- a/controllers/profile.php
+++ b/controllers/profile.php
@@ -1,346 +1,344 @@
<?php
/**
* User profile
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* This is a controller allowing user profile view and edit.
*
* It handles the following URLs:
* /who/<perso nickname> views the nickname's profile,
* /who/random views a random profile,
* /who/edit/profile edits its profileq
* /who/edit/account edits its account (disabled on Zed, cf. settings),
* /who/edit/photo(s) manages its profile's photos,
* /who/edit/photo/edit/<photo id> edits a photo properties,
* /who/edit/photo/delete/<photo id> deletes a photo,
* /who/edit/photo/avatar/<photo id> promotes a photo to avatar.
*
* The following views are used:
* profile.tpl,
* profile_edit.tpl,
* user_account.tpl,
* profile_photo.tpl,
* profile_photo_edit.tpl.
*
* The following models are used:
* Profile,
* ProfilePhoto,
* ProfileComment.
*
* The view profile_tags.tpl is indirectly used by the Profile model.
*
* This code is maintained in // with Azhàr.
*
* @package Zed
* @subpackage Controllers
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
//Loads language file
lang_load('profile.conf');
//Gets perso nickname from URL
$who = $url[1];
switch ($who) {
case 'edit':
$mode = 'edit';
$who = $CurrentPerso->nickname;
break;
case 'random':
$mode = 'view';
$who = $db->sql_query_express("SELECT perso_id FROM " . TABLE_PROFILES . " ORDER BY rand() LIMIT 1");
break;
default:
$mode = 'view';
}
if (!$who) {
message_die(GENERAL_ERROR, "Who?", "URL error");
}
//Libs
require_once('includes/objects/profile.php');
require_once('includes/objects/profilecomment.php');
require_once('includes/objects/profilephoto.php');
//Gets perso information
require_once('includes/objects/perso.php');
$perso = Perso::get($who);
if ($perso->lastError) {
message_die(GENERAL_ERROR, $perso->lastError, "Error");
}
$smarty->assign('perso', $perso);
//Gets profile
$profile = new Profile($perso->id);
//Handles form
if ($_POST['EditProfile']) {
$profile->load_from_form();
$profile->updated = time();
$profile->save_to_database();
$mode = 'view';
} elseif ($_POST['UserAccount']) {
$smarty->assign('WAP', "This form have been deprecated. You can write instead settings in the SmartLine");
} elseif ($_POST['message_type'] == 'private_message') {
//Sends a message
require_once('includes/objects/message.php');
$msg = new Message();
$msg->from = $CurrentPerso->id;
$msg->to = $perso->id;
$msg->text = $_POST['message'];
$msg->send();
if ($msg->from == $msg->to) {
$smarty->assign('NOTIFY', lang_get('MessageSentSelf'));
} else {
$smarty->assign('NOTIFY', lang_get('MessageSent'));
}
} elseif ($_POST['message_type'] == 'profile_comment') {
//New profile comment
$comment = new ProfileComment();
$comment->author = $CurrentPerso->id;
$comment->perso_id = $perso->id;
$comment->text = $_POST['message'];
$comment->publish();
$smarty->assign('NOTIFY', lang_get('CommentPublished'));
} elseif ($_FILES['photo']) {
#We've a file !
$hash = md5(microtime() . serialize($_FILES));
$extension = get_extension($_FILES['photo']['name']);
$filename = $CurrentPerso->id . '_' . $hash . '.' . $extension;
#We ignore $_FILES[photo][error] 4, this means no file has been uploaded
#(so user doesn't want upload a new file)
#See http:/www.php.net/features.file-upload and http://www.php.net/manual/en/features.file-upload.errors.php about common errors
#Not valid before PHP 4.2.0
switch ($_FILES['photo']['error']) {
case 0:
#There is no error, the file uploaded with success.
if (!move_uploaded_file($_FILES['photo']['tmp_name'], PHOTOS_DIR . '/' . $filename)) {
$errors[] = "Upload successful, but error saving it.";
} else {
//Attaches the picture to the profile
$photo = new ProfilePhoto();
$photo->name = $filename;
$photo->perso_id = $CurrentPerso->id;
$photo->description = $_POST['description'];
if ($photo->avatar) $photo->promote_to_avatar();
$photo->save_to_database();
//Generates thumbnail
if (!$photo->generate_thumbnail()) {
$smarty->assign('WAP', "Error generating thumbnail.");
}
$smarty->assign('NOTIFY', lang_get('PhotoUploaded'));
$mode = 'view';
}
break;
case 1:
$errors[] = "The file is too large.";
break;
#TODO : more explicit error messages
default:
$errors[] = "Unknown error (#" . $_FILES['photo']['error'] . ")";
break;
}
if (count($errors)) {
$smarty->assign('WAP', join($errors, '<br />'));
}
} elseif ($_POST['id']) {
//Edits photo properties
$photo = new ProfilePhoto($_POST['id']);
if ($photo->lastError) {
$smarty->assign('WAP', $photo->lastError);
$mode = 'view';
} elseif ($photo->perso_id != $CurrentPerso->id) {
$smarty->assign('WAP', lang_get('NotYourPic'));
$mode = 'view';
} else {
//OK
$wereAvatar = $photo->avatar;
$photo->load_from_form();
if (!$wereAvatar && $photo->avatar) {
//Promote to avatar
$photo->promote_to_avatar();
}
$photo->save_to_database();
}
}
//Prepares output
if ($profile->text) {
//Profile
$smarty->assign('PROFILE_TEXT', $profile->text);
$smarty->assign('PROFILE_FIXEDWIDTH', $profile->fixedwidth);
}
if ($mode == 'view') {
require_once('includes/objects/profilephoto.php');
//Self profile?
$self = $CurrentPerso->id == $profile->perso_id;
//Gets profiles comments, photos, tags
$comments = ProfileComment::get_comments($profile->perso_id);
$photos = ProfilePhoto::get_photos($profile->perso_id);
$tags = $profile->get_cached_tags();
//Records timestamp, to be able to track new comments
if ($self) $CurrentPerso->set_flag('profile.lastvisit', time());
//Template
$smarty->assign('PROFILE_COMMENTS', $comments);
$smarty->assign('PROFILE_SELF', $self);
if ($tags) $smarty->assign('PROFILE_TAGS', $tags);
$smarty->assign('USERNAME', $perso->username);
$smarty->assign('NAME', $perso->name ? $perso->name : $perso->nickname);
$template = 'profile.tpl';
} elseif ($mode == 'edit') {
switch ($url[2]) {
case 'profile':
$smarty->assign('USERNAME', $perso->name);
$smarty->assign('DIJIT', true);
$css[] = THEME . '/forms.css';
$template = 'profile_edit.tpl';
break;
case 'account':
$smarty->assign('user', $CurrentUser);
$smarty->assign('DIJIT', true);
$css[] = THEME . '/forms.css';
$template = 'user_account.tpl';
break;
case '':
$smarty->assign('NOTIFY', "What do you want to edit ? Append /profile, /account or /photos to the URL");
break;
case 'photo':
case 'photos':
$smarty->assign('USERNAME', $perso->name);
switch ($action = $url[3]) {
case '':
//Nothing to do
break;
case 'delete':
//Deletes a picture
if (!$id = $url[4]) {
$smarty->assign('WAP', "URL error. Parameter missing: picture id.");
} else {
$photo = new ProfilePhoto($id);
if ($photo->lastError) {
//Probably an non existent id (e.g. double F5, photo already deleted)
$smarty->assign('WAP', $photo->lastError);
} elseif ($photo->perso_id != $CurrentPerso->id) {
$smarty->assign('WAP', lang_get('NotYourPic'));
} else {
//OK we can delete it
$photo->delete();
$smarty->assign('NOTIFY', lang_get('PictureDeleted'));
}
}
break;
case 'edit':
if (!$id = $url[4]) {
$smarty->assign('WAP', "URL error. Parameter missing: picture id.");
} else {
$photo = new ProfilePhoto($id);
if ($photo->lastError) {
//Probably an non existent id (e.g. double F5, photo already deleted)
$smarty->assign('WAP', $photo->lastError);
} elseif ($photo->perso_id != $CurrentPerso->id) {
$smarty->assign('WAP', lang_get('NotYourPic'));
} else {
//Photo information edit form
$smarty->assign('photo', $photo);
$template = 'profile_photo_edit.tpl';
}
}
break;
case 'avatar':
//Promotes a picture to avatar
if (!$id = $url[4]) {
$smarty->assign('WAP', "URL error. Parameter missing: picture id.");
} else {
$photo = new ProfilePhoto($id);
if ($photo->lastError) {
$smarty->assign('WAP', $photo->lastError);
} elseif ($photo->perso_id != $CurrentPerso->id) {
$smarty->assign('WAP', lang_get('NotYourPic'));
} else {
//OK, promote it to avatar
$photo->promote_to_avatar();
$photo->save_to_database();
$smarty->assign('NOTIFY', lang_get('PromotedToAvatar'));
}
}
break;
default:
$smarty->assign('WAP', "Unknown URL. To delete a picture it's /delete/<picture id>. To edit it /edit/<picture id>");
break;
}
if (!$template) {
$photos = ProfilePhoto::get_photos($profile->perso_id);
if (!$smarty->tpl_vars['NOTIFY'])
$smarty->assign('NOTIFY', "Your feedback is valued. Report any bug or suggestion on the graffiti wall.");
$template = 'profile_photo.tpl';
}
break;
default:
$smarty->assign('WAP', "URL error. You can use /edit with profile, account or photos.");
break;
}
}
//
// HTML output
//
//Photos
if (count($photos) || $photo) {
$smarty->assign('URL_PICS', PHOTOS_URL);
$css[] = 'lightbox.css';
$smarty->assign('PAGE_JS', array('prototype.js', 'effects.js', 'lightbox.js'));
$smarty->assign('PICS', $photos);
}
//Serves header
$css[] = THEME . "/profile.css";
$smarty->assign('PAGE_CSS', $css);
$smarty->assign('PAGE_TITLE', $perso->name);
include('header.php');
//Serves content
if ($template) $smarty->display($template);
//Serves footer
include('footer.php');
-
-?>
\ No newline at end of file
diff --git a/controllers/raw.php b/controllers/raw.php
index 3a6cf97..8aa63bc 100644
--- a/controllers/raw.php
+++ b/controllers/raw.php
@@ -1,63 +1,61 @@
<?php
/**
* Raw text ou HTML content
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* This is a controller printing HTML content as is.
*
* It prints the raw.tpl view containing two variables:
* - PAGE_TITLE (optionnal), to add a H1 page title
* - 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 da796f2..a5dcd57 100644
--- a/controllers/request.php
+++ b/controllers/request.php
@@ -1,95 +1,93 @@
<?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 3374cb8..536117c 100644
--- a/controllers/settings.php
+++ b/controllers/settings.php
@@ -1,97 +1,95 @@
<?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 8e2e24a..bc18340 100644
--- a/controllers/ship.php
+++ b/controllers/ship.php
@@ -1,91 +1,89 @@
<?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');
//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 42394a7..eb4f569 100644
--- a/controllers/story.php
+++ b/controllers/story.php
@@ -1,131 +1,129 @@
<?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 d19c5c8..6875c32 100644
--- a/controllers/usersearch.php
+++ b/controllers/usersearch.php
@@ -1,119 +1,117 @@
<?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 d4a75e1..e21801a 100644
--- a/controllers/void.php
+++ b/controllers/void.php
@@ -1,37 +1,35 @@
<?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/dev/quux.php b/dev/quux.php
index 7eada22..3384dac 100644
--- a/dev/quux.php
+++ b/dev/quux.php
@@ -1,159 +1,157 @@
<?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" />
</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/tests/GeoOctocubeTest.php b/dev/tests/GeoOctocubeTest.php
index 374a7f0..bc49440 100644
--- a/dev/tests/GeoOctocubeTest.php
+++ b/dev/tests/GeoOctocubeTest.php
@@ -1,44 +1,43 @@
<?php
/**
* Unit testing : class GeoOctocube
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* @package Zed
* @subpackage Tests
* @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/octocube.php');
/**
* Test cases for the class GeoPlace
*/
class GeoOctocubeTest extends PHPUnit_Framework_TestCase {
/**
* Tests the GeoPlace::is_valid_local_location($local_location) method.
*/
public function testGetSector () {
//Testing HyperShip Tower T2C3 format
$this->assertTrue(GeoOctocube::get_sector(0, 0, 0) == 0);
$this->assertTrue(GeoOctocube::get_sector(-10, 6, -4) == 1);
$this->assertTrue(GeoOctocube::get_sector(10, 6, -4) == 2);
$this->assertTrue(GeoOctocube::get_sector(-10, -6, -4) == 3);
$this->assertTrue(GeoOctocube::get_sector(10, -6, -4) == 4);
$this->assertTrue(GeoOctocube::get_sector(-10, 6, 4) == 5);
$this->assertTrue(GeoOctocube::get_sector(10, 6, 4) == 6);
$this->assertTrue(GeoOctocube::get_sector(-10, -6, 4) == 7);
$this->assertTrue(GeoOctocube::get_sector(10, -6, 4) == 8);
}
}
-?>
diff --git a/dev/tests/GeoPlaceTest.php b/dev/tests/GeoPlaceTest.php
index 4e8737c..d730a4a 100644
--- a/dev/tests/GeoPlaceTest.php
+++ b/dev/tests/GeoPlaceTest.php
@@ -1,75 +1,74 @@
<?php
/**
* Unit testing : class GeoPlace
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* @package Zed
* @subpackage Tests
* @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/place.php');
/**
* Test cases for the class GeoPlace
*/
class GeoPlaceTest extends PHPUnit_Framework_TestCase {
/**
* Tests the GeoPlace::is_valid_local_location($local_location) method.
*/
public function testIsValidLocation () {
//Testing HyperShip Tower T2C3 format
$p0 = new GeoPlace();
$p0->location_local_format = '/^T[1-9][0-9]*C[1-6]$/';
$this->assertTrue($p0->is_valid_local_location("T1C1")); // 1
$this->assertTrue($p0->is_valid_local_location("T14C1")); // 2
$this->assertTrue($p0->is_valid_local_location("T14C6")); // 3
$this->assertTrue($p0->is_valid_local_location("T140C6")); // 4
$this->assertTrue($p0->is_valid_local_location("T14000C6")); // 5
$this->assertFalse($p0->is_valid_local_location("C1T6")); // 6
$this->assertFalse($p0->is_valid_local_location("T14000 C6")); // 7
$this->assertFalse($p0->is_valid_local_location("T4C7")); // 8
$this->assertFalse($p0->is_valid_local_location("T4C0")); // 9
$this->assertFalse($p0->is_valid_local_location("T0C0")); //10
//Unit testing is useful: this test led to fix the regexp
//from T[0-9]+C[1-6] to T[1-9][0-9]*C[1-6]
$this->assertFalse($p0->is_valid_local_location("T0C1")); //11
//Testing default format
$p1 = new GeoPlace();
$this->assertTrue($p1->is_valid_local_location("(4,62,35)")); //12
$this->assertTrue($p1->is_valid_local_location("(4, 62, 35)")); //13
$this->assertTrue($p1->is_valid_local_location("(4, 62,35)")); //14
$this->assertFalse($p1->is_valid_local_location("(4,62,-35)")); //15
$this->assertFalse($p1->is_valid_local_location("(4, 62)")); //16
//Testing (x, y, -z) format
$p2 = new GeoPlace();
$p2->location_local_format = '/^\(\-?[0-9]+( )*,( )*\-?[0-9]+( )*,( )*\-?[0-9]+\)$/';
$this->assertTrue($p2->is_valid_local_location("(4,62,35)")); //17
$this->assertTrue($p2->is_valid_local_location("(4, 62, 35)")); //18
$this->assertTrue($p2->is_valid_local_location("(4, 62,35)")); //19
$this->assertTrue($p2->is_valid_local_location("(4,62,-35)")); //20
$this->assertFalse($p2->is_valid_local_location("(4,62,- 35)")); //21
$this->assertFalse($p2->is_valid_local_location("(4,62, - 35)")); //22
$this->assertFalse($p2->is_valid_local_location("(4, 62)")); //23
}
}
-?>
diff --git a/includes/SmartLine/SmartLine.php b/includes/SmartLine/SmartLine.php
index 863a19c..d4211a4 100755
--- a/includes/SmartLine/SmartLine.php
+++ b/includes/SmartLine/SmartLine.php
@@ -1,523 +1,522 @@
<?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
$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]);
//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
*
* @param string $expression The expression to transform into a argv array
* @return Array An array of string, the first item the command, the others those arguments.
*/
private function expression2argv ($expression) {
//Checks if expression contains "
$pos1 = strpos($expression, '"');
//We isolate "subexpression"
if ($pos1 !== false) {
$pos2 = $pos1;
do {
$pos2 = strpos($expression, '"', $pos2 + 1);
} while ($pos2 !== false && ($expression[$pos2 - 1] == "\\" && $expression[$pos2 - 2] != "\\"));
if ($pos2 === false) {
//If final quote is missing, throws a warning and autoadds it.
$this->puts("[Warning] Final \" missing in $expression.", STDERR);
$argv = $this->expression2argv(substr($expression, 0, $pos1));
$argv[] = substr($expression, $pos1 + 1);
return $argv;
}
return array_merge(
$this->expression2argv(substr($expression, 0, $pos1)),
array(substr($expression, $pos1 + 1, $pos2 - $pos1 - 1)),
$this->expression2argv(substr($expression, $pos2 + 1))
);
}
//Standard expression (ie without ")
$argv = array();
$items = explode(' ', $expression);
foreach ($items as $item) {
$item = trim($item);
if (!$item) {
//blank, we ignore
continue;
}
$argv[] = $item;
}
return $argv;
}
//Contains last error
public $lastError = '';
//If true, command isn't equal to Command
public $caseSensitive = true;
}
///////////////////////////////////////////////////////////////////////////////
// SECTION IV - STANDARD COMMANDS
///////////////////////////////////////////////////////////////////////////////
/*
* These commands are availaible in all default smartlines instance
*/
/**
* 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 a3cb956..cee5252 100755
--- a/includes/SmartLine/ZedCommands.php
+++ b/includes/SmartLine/ZedCommands.php
@@ -1,472 +1,470 @@
<?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;
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 b86c5c6..89c6079 100755
--- a/includes/SmartLine/ZedSmartLine.php
+++ b/includes/SmartLine/ZedSmartLine.php
@@ -1,107 +1,105 @@
<?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))
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/api/BeautyXML.class.php b/includes/api/BeautyXML.class.php
index bdb8573..9289833 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
* it's very, very, very simple - feature version will be better :-)
*
* IMPORTANT NOTE
* there is no warranty, implied or otherwise with this software.
*
* version 0.1 | August 2004
*
* released under a LGPL licence.
*
* Slawomir Jasinski,
* http://www.jasinski.us (polish only - my home page)
* http://www.cgi.csd.pl (english & polish)
* contact me - sj@gex.pl
*
* @package Zed
* @subpackage API
* @author Slawomir Jasinski <sj@gex.pl>
* @copyright 2004 Slawomir Jasinski, 2010 Sébastien Santoro aka Dereckson
* @license http://www.gnu.org/licenses/lgpl.html LGPL
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*
* @todo Contact Slawomir Jasinski and ask it if the current code could be
* relicensed under BSD license. If not, rewrite from scratch under BSD license.
*/
/**
* This class is simple XML beautifer.
* It's very, very, very simple - feature version will be better :-)
*
* @author Slawomir Jasinski <sj@gex.pl>
*/
class BeautyXML {
/**
* Indicates what characters to use to indent.
*
* If you wish a regular tabulation, the suggested value is \t ;
* If you wish spaces instead, put the correct amount of spaces as value.
*
* @var string
*/
var $how_to_ident = " "; // you can user also \t or more/less spaces
/**
* Determines if long text have to be wrapped.
*
* If true, the text will be wrapped ; otherwise, long lines will be kept.
*
* @var bool
*/
var $wrap = false;
/**
* If $wrap is true, determines the line lenght.
*
* After this lenght, any text will be wrapped.
*
* @see $wrap
* @var @int
*/
var $wrap_cont = 80; // where wrap words
/**
* Idents the specified string.
*
* @param string $str the string to indent
* @param int $level the ident level, ie the number of identation to prepend the string with
*/
function ident (&$str, $level) {
$spaces = '';
$level--;
for ($a = 0; $a < $level; $a++)
$spaces .= $this->how_to_ident;
return $spaces .= $str;
}
/**
* Formats the specified string, beautifying it, with proper indent.
*
* This is the main class method.
*
* @param $str the XML fragment to beautify
* @return string the beautified XML fragment
*/
function format ($str) {
$str = preg_replace("/<\?[^>]+>/", "", $str);
$tmp = explode("\n", $str); // extracting string into array
// cleaning string from spaces and other stuff like \n \r \t
for ($a = 0, $c = count($tmp); $a < $c; $a++)
$tmp[$a] = trim($tmp[$a]);
// joining to string ;-)
$newstr = join("", $tmp);
$newstr = preg_replace("/>([\s]+)<\//", "></", $newstr);
// adding \n lines where tags ar near
$newstr = str_replace("><", ">\n<", $newstr);
// exploding - each line is one XML tag
$tmp = explode("\n", $newstr);
// preparing array for list of tags
$stab = array('');
// lets go :-)
for ($a = 0, $c = count($tmp); $a <= $c; $a++) {
$add = true;
preg_match("/<([^\/\s>]+)/", $tmp[$a], $match);
$lan = trim(strtr($match[0], "<>", " "));
$level = count($stab);
if (in_array($lan, $stab) && substr_count($tmp[$a], "</$lan") == 1) {
$level--;
$s = array_pop($stab);
$add = false;
}
if (substr_count($tmp[$a], "<$lan") == 1 && substr_count($tmp[$a], "</$lan") == 1)
$add = false;
if (preg_match("/\/>$/", $tmp[$a], $match))
$add = false;
$tmp[$a] = $this->ident($tmp[$a], $level);
if ($this->wrap) $tmp[$a] = wordwrap($tmp[$a], $this->wrap_cont, "\n" . $this->how_to_ident . $this->how_to_ident . $this->how_to_ident);
if ($add && !@in_array($lan, $stab) && $lan != '') array_push($stab, $lan);
}
return join("\n", $tmp);
}
-}
\ No newline at end of file
+}
diff --git a/includes/api/api_helpers.php b/includes/api/api_helpers.php
index b6f6313..5b001a5 100755
--- a/includes/api/api_helpers.php
+++ b/includes/api/api_helpers.php
@@ -1,166 +1,164 @@
<?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 81fc919..628b78e 100755
--- a/includes/api/cerbere.php
+++ b/includes/api/cerbere.php
@@ -1,124 +1,122 @@
<?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.");
}
} else {
cerbere_die("Key doesn't exist.");
}
}
/**
* Prints a message in raw or API format, then exits.
*
* The error message will be formatted through api_output if the constant
* FORMAT_ERROR is defined and true. Otherwise, it will be printed as is.
*
* @param string $message The error message to print
*/
function cerbere_die ($message) {
if (OUTPUT_ERROR) {
if (FORMAT_ERROR) {
api_output($message, 'error');
} else {
echo $message;
}
}
exit;
}
-
-?>
\ No newline at end of file
diff --git a/includes/cache/cache.php b/includes/cache/cache.php
index d007c6f..ce4d391 100755
--- a/includes/cache/cache.php
+++ b/includes/cache/cache.php
@@ -1,91 +1,89 @@
<?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_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 0af21d2..44b8a0c 100755
--- a/includes/cache/memcached.php
+++ b/includes/cache/memcached.php
@@ -1,112 +1,111 @@
<?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
*/
static $instance = null;
/**
* The Memcached object
*
* @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 () {
//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 84f119d..082250a 100755
--- a/includes/cache/void.php
+++ b/includes/cache/void.php
@@ -1,81 +1,80 @@
<?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 () {
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 a18633d..0deadcc 100755
--- a/includes/content/file.php
+++ b/includes/content/file.php
@@ -1,276 +1,274 @@
<?php
/**
* Content file class
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2012-12-03 02:57 Forked from Content
*
* @package Zed
* @subpackage Content
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
/**
* Content class
*
* This class maps the content_files table.
*
*/
class ContentFile {
/* -------------------------------------------------------------
Properties
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
public $id;
public $path;
public $user_id;
public $perso_id;
public $title;
/* -------------------------------------------------------------
Constructor, __toString
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
* Initializes a new ContentFile instance
*
* @param int $id the primary key
*/
function __construct ($id = null) {
if ($id) {
$this->id = $id;
$this->load_from_database();
}
}
/**
* Returns a string representation of current Content instance
*
* @return string the content title or path if title is blank.
*/
function __toString () {
return $this->title ? $this->title : $this->path;
}
/* -------------------------------------------------------------
Load/save class
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
* Loads the object ContentFile (ie fill the properties) from the $_POST array
*
* @param boolean $allowSensibleFields if false, allow only title to be defined ; otherwise, allow all fields.
*/
function load_from_form ($allowSensibleFields = false) {
if (array_key_exists('title', $_POST)) $this->title = $_POST['title'];
if ($allowSensibleFields) {
if (array_key_exists('path', $_POST)) $this->path = $_POST['path'];
if (array_key_exists('user_id', $_POST)) $this->user_id = $_POST['user_id'];
if (array_key_exists('perso_id', $_POST)) $this->perso_id = $_POST['perso_id'];
}
}
/**
* Loads the object ContentFile (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$id = $db->sql_escape($this->id);
$sql = "SELECT * FROM content_files WHERE content_id = '" . $id . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query content", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "Content unkwown: " . $this->id;
return false;
}
$this->load_from_row($row);
return true;
}
/**
* Loads the object from row
*/
function load_from_row ($row) {
$this->id = $row['content_id'];
$this->path = $row['content_path'];
$this->user_id = $row['user_id'];
$this->perso_id = $row['perso_id'];
$this->title = $row['content_title'];
}
/**
* Saves to database
*/
function save_to_database () {
global $db;
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$path = $db->sql_escape($this->path);
$user_id = $db->sql_escape($this->user_id);
$perso_id = $db->sql_escape($this->perso_id);
$title = $db->sql_escape($this->title);
//Updates or inserts
$sql = "REPLACE INTO content_files (`content_id`, `content_path`, `user_id`, `perso_id`, `content_title`) VALUES ($id, '$path', '$user_id', '$perso_id', '$title')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't save content", '', __LINE__, __FILE__, $sql);
}
if (!$this->id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
}
/* -------------------------------------------------------------
File handling helper methods
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
* Determines if the extension is valid
*
* @param string $ext The extension (without dot)
* @return boolean true if this extension is valid ; otherwise, false.
*/
function is_valid_extension ($ext) {
$ext = strtolower($ext);
return (is_valid_image_extension($ext) || is_valid_audio_extension($ext)
|| is_valid_video_extension($ext));
}
/**
* Determines if the extension is valid
*
* @param string $ext The extension (without dot)
* @return boolean true if this extension is valid ; otherwise, false.
*/
function is_valid_image_extension ($ext) {
switch ($ext = strtolower($ext)) {
//Pictures
case 'jpg':
case 'gif':
case 'png':
case 'bmp':
case 'xbm':
return true;
//Denied extension
default:
return false;
}
}
/**
* Determines if the extension is a valid audio file one
*
* @param string $ext The extension (without dot)
* @return boolean true if this extension is valid ; otherwise, false.
*/
function is_valid_audio_extension ($ext) {
switch ($ext = strtolower($ext)) {
//Sounds (HTML5 <audio> formats)
case 'mp3':
case 'ogg':
case 'aac':
case 'wav':
case 'wave':
return true;
//Denied extension
default:
return false;
}
}
/**
* Determines if the extension is a valid video file one
*
* @param string $ext The extension (without dot)
* @return boolean true if this extension is valid ; otherwise, false.
*
* @todo add H.264 extension
*/
function is_valid_video_extension ($ext) {
switch ($ext = strtolower($ext)) {
//Video (HTML5 <video> formats)
case 'ogg':
case 'webm':
return true;
//Denied extension
default:
return false;
}
}
/**
* Creates a directory
*
* @param string $dir the directory to create
*
* @todo set contents chmod in config
*/
function create_directory ($directory) {
if (!file_exists($directory)) {
@mkdir($directory); //Creates new directory, chmod 777
}
}
/**
* Handles uploaded file
*
* @return bool true if the file have been handled
*/
function handle_uploaded_file ($fileArray) {
if (count($fileArray) && $fileArray['error'] == 0) {
$this->create_directory("content/users/$this->user_id");
$this->path = "content/users/$this->user_id/$fileArray[name]";
if (!self::is_valid_extension(get_extension($fileArray[name]))) {
return false;
}
if (move_uploaded_file($fileArray['tmp_name'], $this->path)) {
return true;
} else {
$this->path = null;
return false;
}
} else {
return false;
}
}
/**
* Generates a thumbnail using ImageMagick binary
*
* @return boolean true if the thumbnail command returns 0 as program exit code ; otherwise, false
*/
function generate_thumbnail () {
global $Config;
//Builds thumbnail filename
$sourceFile = $this->path;
$pos = strrpos($this->path, '.');
$thumbnailFile = substr($sourceFile, 0, $pos) . 'Square' . substr($sourceFile, $pos);
//Executes imagemagick command
$command = $Config['ImageMagick']['convert'] . " \"$sourceFile\" -resize 162x162 \"$thumbnailFile\"";
@system($command, $code);
//Returns true if the command have exited with errorcode 0 (= ok)
return ($code == 0);
}
}
-
-?>
\ No newline at end of file
diff --git a/includes/content/location.php b/includes/content/location.php
index 21ff058..6c0e030 100755
--- a/includes/content/location.php
+++ b/includes/content/location.php
@@ -1,230 +1,228 @@
<?php
/**
* Content location class
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2010-12-03 2:58 Forked from Content class
*
* @package Zed
* @subpackage Content
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
/**
* Content location class
*
* This class maps the content_locations table.
*
* A content location is defined by 3 paramaters:
* - location_global
* - location_local
* - location_k, an index for the content at the specified location
*
* This class allows to get or set the content_id at this
* (global, local, k) location.
*
* This class also provides a static helper method to
* get local content from a specific location.
*/
class ContentLocation {
/* -------------------------------------------------------------
Properties
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
public $location_global = null;
public $location_local = null;
public $location_k = null;
public $content_id;
/* -------------------------------------------------------------
Constructor, __toString
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
* Initializes a new ContentLocation instance
*
* @param string $location_global the global location
* @param string $location_local the local location
* @param int $location_k the item indice for the specified location
*/
function __construct ($location_global = null, $location_local = null, $location_k = null) {
$this->location_global = $location_global;
$this->location_local = $location_local;
if ($location_k) {
$this->location_k = $location_k;
$this->load_from_database();
} else {
$this->location_k = self::get_free_location_k($location_global, $location_local);
}
}
/**
* Returns a string representation of current Content instance
*
* @return string the content title or path if title is blank.
*/
function __toString () {
$location_global = $this->location_global ? $this->location_global : '?';
$location_local = $this->location_local ? $this->location_local : '?';
$location_k = $this->location_k ? $this->location_k : '?';
return "($location_global, $location_local, $location_k)";
}
/* -------------------------------------------------------------
Load/save class
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
* Loads the object ContentLocation (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$location_global = "'" . $db->sql_escape($this->location_global) . "'";
$location_local = "'" . $db->sql_escape($this->location_local) . "'";
$location_k = "'" . $db->sql_escape($this->location_k) . "'";
$sql = "SELECT * FROM content_locations WHERE location_global = '$location_global' AND location_local = '$location_local' AND location_k = '$location_k'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query content", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "Content location unkwown: " . $this->content_id;
return false;
}
$this->load_from_row($row);
return true;
}
/**
* Loads the object from row
*/
function load_from_row ($row) {
$this->content_id = $row['content_id'];
$this->location_global = $row['location_global'];
$this->location_local = $row['location_local'];
$this->location_k = $row['location_k'];
}
/**
* Saves to database
*/
function save_to_database () {
global $db;
$location_global = "'" . $db->sql_escape($this->location_global) . "'";
$location_local = "'" . $db->sql_escape($this->location_local) . "'";
$location_k = "'" . $db->sql_escape($this->location_k) . "'";
$content_id = $this->content_id ? "'" . $db->sql_escape($this->content_id) . "'" : 'NULL';
$sql = "REPLACE INTO content_locations (location_global, location_local, location_k, content_id) VALUES ($location_global, $location_local, $location_k, $content_id)";
if (!$db->sql_query($sql))
message_die(SQL_ERROR, "Can't save content location", '', __LINE__, __FILE__, $sql);
}
/* -------------------------------------------------------------
Helper methods
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
* Gets the next k free value for the specified location
*
* @param string $location_global the global location
* @param string $location_local the local location
*
* @param int $location_k the next free local content indice
*/
function get_free_location_k ($location_global, $location_local) {
$location_global = "'" . $db->sql_escape($location_global) . "'";
$location_local = "'" . $db->sql_escape($location_local) . "'";
$sql = "SELECT MAX(location_k) + 1 FROM content_locations WHERE location_global = '$location_global' AND location_local = '$location_local'";
if (!$result = $db->sql_query($sql))
message_die(SQL_ERROR, "Can't get content location k", '', __LINE__, __FILE__, $sql);
$row = $db->sql_fetchrow($result);
return $row[0];
}
/**
* Deletes this content location from the database
*/
function delete() {
$location_global = "'" . $db->sql_escape($this->location_global) . "'";
$location_local = "'" . $db->sql_escape($this->location_local) . "'";
$location_k = "'" . $db->sql_escape($this->location_k) . "'";
$sql = "DELETE FROM content_locations WHERE location_global = '$location_global' AND location_local = '$location_local' AND location_k = '$location_k' LIMIT 1";
if (!$db->sql_query($sql))
message_die(SQL_ERROR, "Can't delete current content location", '', __LINE__, __FILE__, $sql);
}
/**
* Moves the content into new location
*
* @param string $location_global the target global location
* @param string $location_local the target local location
* @param int $location_k the target local content indice [facultative]
*/
function move ($location_global, $location_local, $location_k = null) {
if ($this->content_id) {
$this->delete();
}
if ($location_k) {
$this->location_k = $location_k;
} else {
$this->location_k = self::get_free_location_k($location_global, $location_local);
}
if ($this->content_id) {
$this->save_to_database();
}
}
/* -------------------------------------------------------------
Gets content
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
* Gets content at specified location
*
* @param string $location_global global content location
* @param string $location_local local content location
* @return Array array of ContentFile instances
*
* The returned array indices are the local_k.
*/
static function get_local_content ($location_global, $location_local) {
global $db;
//Get contents at this location
$location_global = $db->sql_escape($location_global);
$location_local = $db->sql_escape($location_local);
$sql = "SELECT c.* FROM content c WHERE c.location_global = '$location_global' AND c.location_local = '$location_local' ORDER BY location_k ASC";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't get content", '', __LINE__, __FILE__, $sql);
}
//Fills content array
$contents = array();
while ($row = $db->sql_fetchrow($result)) {
$k = $row['location_k'];
$contents[$k] = new ContentFile();
$contents[$k]->load_from_row($row);
}
return $contents;
}
}
-
-?>
\ No newline at end of file
diff --git a/includes/content/zone.php b/includes/content/zone.php
index 5f1d09f..af53276 100755
--- a/includes/content/zone.php
+++ b/includes/content/zone.php
@@ -1,196 +1,195 @@
<?php
/**
* Zone class
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* @package Zed
* @subpackage Content
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
/**
* Content zone class
*
* A zone is a physical place, independent from the location.
* This mechanism allows to more easily move zones.
*
* This class maps the content_zones table.
*/
class ContentZone {
public $id;
public $title;
public $type;
public $params;
public $deleted = false;
/**
* Initializes a new instance of a zone object
*
* @param int $id The zone ID
*/
function __construct ($id = '') {
if ($id) {
$this->id = $id;
return $this->load_from_database();
}
}
/**
* Loads the object zone (ie fill the properties) from the $_POST array
*/
function load_from_form () {
if (array_key_exists('title', $_POST)) $this->user_id = $_POST['title'];
if (array_key_exists('type', $_POST)) $this->user_id = $_POST['type'];
if (array_key_exists('params', $_POST)) $this->user_id = $_POST['params'];
if (array_key_exists('deleted', $_POST)) $this->user_id = $_POST['deleted'];
}
/**
* Loads the object zone (ie fill the properties) from the $row array
*/
function load_from_row ($row) {
$this->id = $row['zone_id'];
$this->title = $row['zone_title'];
$this->type = $row['zone_type'];
$this->params = $row['zone_params'];
$this->deleted = $row['zone_deleted'] ? true : false;
}
/**
* Loads the object zone (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$id = $db->sql_escape($this->id);
$sql = "SELECT * FROM " . TABLE_CONTENT_ZONES . " WHERE zone_id = '" . $id . "'";
if (!$result = $db->sql_query($sql)) message_die(SQL_ERROR, 'Unable to query content_zones', '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = 'Zone unkwown: ' . $this->id;
return false;
}
$this->load_from_row($row);
return true;
}
/**
* Saves the object to the database
*/
function save_to_database () {
global $db;
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$title = $db->sql_escape($this->title);
$type = $db->sql_escape($this->type);
$params = $db->sql_escape($this->params);
$deleted = $this->deleted ? 1 : 0;
$sql = "REPLACE INTO " . TABLE_CONTENT_ZONES . " (`zone_id`, `zone_title`, `zone_type`, `zone_params`, `zone_deleted`) VALUES ($id, '$title', '$type', '$params', $deleted)";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
if (!$this->id) {
$this->id = $db->sql_nextid();
}
}
/**
* Assigns the zone at the specified location.
*
* @param string $location_global the global location
* @param string $location_global the local location
* @param bool $delete_old_locations if true, delete old locations
*/
function assign_to ($location_global, $location_local, $delete_old_locations = true) {
if (!$this->id) {
$this->save_to_database();
}
global $db;
if ($delete_old_locations) {
$sql = "DELETE FROM " . TABLE_CONTENT_ZONES_LOCATIONS . " WHERE zone_id = " . $this->id;
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to delete", '', __LINE__, __FILE__, $sql);
}
}
$g = $db->sql_escape($location_global);
$l = $db->sql_escape($location_local);
$sql = "REPLACE INTO " . TABLE_CONTENT_ZONES_LOCATIONS . " (location_global, location_local, zone_id) VALUES ('$g', '$l', $this->id)";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to set zone location", '', __LINE__, __FILE__, $sql);
}
}
/**
* Gets the zone at specified location
*
* @param string $location_global the global location
* @param string $location_global the local location
* @param bool $create if the zone doesn't exist, create it [optional] [default value: false]
* @return ContentZone the zone, or null if the zone doesn't exist and $create is false
*/
static function at ($location_global, $location_local, $create = false) {
global $db;
$g = $db->sql_escape($location_global);
$l = $db->sql_escape($location_local);
$sql = "SELECT * FROM " . TABLE_CONTENT_ZONES_LOCATIONS . " WHERE location_global = '$g' AND location_local = '$l'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to set zone location", '', __LINE__, __FILE__, $sql);
}
if ($row = $db->sql_fetchrow($result)) {
return new ContentZone($row['zone_id']);
} elseif ($create) {
$zone = new ContentZone();
$zone->assign_to($location_global, $location_local);
return $zone;
} else {
return null;
}
}
/**
* Gets all the zones matching the specified location queries
*
* @param string $location_global_query the global location query
* @param string $location_local_query the local location query
* @return Array a ContentZone array, with each item a zone found
*
* [SECURITY] They are passed as is in SQL [R]LIKE queries, you can't inject users expression.
*
* The following properties are added to the ContentZone items of the returned array:
* - location_global
* - location_local
*/
static function search ($location_global_query, $location_local_query, $use_regexp_for_local = false) {
global $db;
$zones = array();
$op = $use_regexp_for_local ? 'RLIKE' : 'LIKE';
$sql = "SELECT * FROM " . TABLE_CONTENT_ZONES_LOCATIONS . " WHERE location_global LIKE '$location_global_query' AND location_local $op '$location_local_query'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to set zone location", '', __LINE__, __FILE__, $sql);
}
while ($row = $db->sql_fetchrow($result)) {
$zone = new ContentZone($row['zone_id']);
$zone->location_global = $row['location_global'];
$zone->location_local = $row['location_local'];
$zones[] = $zone;
}
return $zones;
}
}
?>
-
diff --git a/includes/geo/body.php b/includes/geo/body.php
index 128c538..15cd881 100755
--- a/includes/geo/body.php
+++ b/includes/geo/body.php
@@ -1,174 +1,172 @@
<?php
/**
* Geo body class.
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* A 3D grid of objects
*
* 0.1 2010-01-27 21:51 Autogenerated by Pluton Scaffolding
*
* @package Zed
* @subpackage Geo
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
/**
* Geo body class
*/
class GeoBody {
public $code;
public $name;
public $hypership;
public $asteroid;
public $moon;
public $planet;
public $star;
public $orbital;
public $hidden;
public $location;
public $description;
public $lastError;
/**
* Initializes a new instance
*
* @param int $code the primary key
*/
function __construct ($code = null) {
if ($code) {
$this->code = $code;
$this->load_from_database();
}
}
/**
* Loads the object body (ie fill the properties) from the $_POST array
*
* @param bool $readBoolean if false, don't read any form item matching a boolean field to avoid to set it to false if there are absent from a form.
*/
function load_from_form ($readBoolean = true) {
if (array_key_exists('name', $_POST)) $this->name = $_POST['name'];
if ($readBoolean) {
if (array_key_exists('hypership', $_POST)) $this->hypership = $_POST['hypership'];
if (array_key_exists('star', $_POST)) $this->start = $_POST['star'];
if (array_key_exists('asteroid', $_POST)) $this->hypership = $_POST['asteroid'];
if (array_key_exists('moon', $_POST)) $this->start = $_POST['moon'];
if (array_key_exists('planet', $_POST)) $this->start = $_POST['planet'];
if (array_key_exists('orbital', $_POST)) $this->start = $_POST['orbital'];
if (array_key_exists('hidden', $_POST)) $this->start = $_POST['hidden'];
}
if (array_key_exists('location', $_POST)) $this->location = $_POST['location'];
if (array_key_exists('description', $_POST)) $this->description = $_POST['description'];
}
/**
* Loads the object body (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$sql = "SELECT * FROM " . TABLE_BODIES . " WHERE body_code = '" . $this->code . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query geo_bodies", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "body unkwown: " . $this->code;
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 20010c8..4e538f4 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";
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 a4e2957..91f1aca 100755
--- a/includes/geo/location.php
+++ b/includes/geo/location.php
@@ -1,436 +1,434 @@
<?php
/**
* Geo location class.
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2010-01-28 18:52 DcK
*
* @package Zed
* @subpackage Geo
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
require_once('body.php');
require_once('place.php');
require_once('point3D.php');
require_once('includes/objects/ship.php');
/**
* Geo location class
*
* This class contains properties to get, set or compare a location and
* explore the geo classes linked to.
*
* It quickly allow to parse through the location classes in templates and
* controllers.
*
* @todo Initialize $point3D from $body or $ship own locations
* @todo Improve GeoLocation documentation (especially magic properties)
*/
class GeoLocation {
/**
* An array of strings containing location data.
*
* In the current class implementation,
* the first element is the global location
* and the second element is the local location.
*
* @var Aray
*/
private $data;
/**
* A body object
*
* It contains a GeoBody value when the global location is a body
* ie if $this->data[0][0] == 'B'
*
* Otherwise, its value is null.
*
* @var GeoBody
*/
public $body = null;
/**
* A place object
*
* It contains a GeoPlacevalue when the global location is a place
* ie if $this->data[0][0] == 'B' && strlen($this->data[0]) == 9
*
* Otherwise, its value is null.
*
* @var GeoPlace
*/
public $place = null;
/**
* A point identified by x, y, z coordinates
*
* @var GeoPoint3D
*/
public $point3D = null;
/**
* A ship object
*
* It contains a Ship value when the global location is a ship
* ie if $this->data[0][0] == 'S'
*
* Otherwise, its value is null.
*
* @var Ship
*/
public $ship = null;
/**
* Initializes a new location instance
*
* @param string $global the global location
* @param string local the locallocation
*
* @todo Improve local location handling
*/
function __construct ($global = null, $local = null) {
if (!$global) {
$this->data = array();
} elseif (preg_match("/[BS][0-9]{5}[0-9]{3}/", $global)) {
$this->data[0] = $global;
} elseif (preg_match("/[BS][0-9]{5}/", $global)) {
$this->data[0] = $global;
} elseif (preg_match("/^xyz\:/", $global)) {
$coords = sscanf($global, "xyz: [%d, %d, %d]");
if (count($coords) == 3) {
$this->data[0] = $global;
} else {
throw new Exception("Invalid expression: $global");
}
} else {
global $db;
$name = $db->sql_escape($global);
$sql = "SELECT location_code FROM " . TABLE_LOCATIONS . " WHERE location_name LIKE '$name'";
$code = $db->sql_query_express($sql);
if ($code) {
$this->data[0] = $code;
return;
}
throw new Exception("Invalid expression: $global");
}
//TODO: handle $local in a better way: from the global location, gets
//a local location handler. Or a some inheriance, like a class
//HypershipGeoLocation extending GeoLocation.
if ($local !== null) $this->data[1] = $local;
$this->load_classes();
}
/**
* Gets $place, $body and $ship instances if they're needed
*/
function load_classes () {
//No data, no class to load
if (!count($this->data))
return;
//Loads global classes
$global = $this->data[0];
$code = substr($global, 1, 5);
switch ($global[0]) {
case 'B':
switch (strlen($global)) {
case 9:
$this->place = GeoPlace::from_code($global);
case 6:
$this->body = new GeoBody($code);
break;
}
break;
case 'S':
$this->ship = new Ship($code);
break;
case 'x':
$coords = sscanf($global, "xyz: [%d, %d, %d]");
if (count($coords) == 3) {
$this->point3D = new GeoPoint3D($coords[0], $coords[1], $coords[2]);
}
break;
}
}
/**
* Magic method called when a unknown property is get.
*
* Handles $global, $local, $type, $body_code, $ship_code, $place_code,
* $body_kind, $containsGlobalLocation, $containsLocalLocation.
*/
function __get ($variable) {
switch ($variable) {
/* main variables */
case 'global':
return $this->data[0];
break;
case 'local':
return (count($this->data) > 1) ? $this->data[1] : null;
break;
/* global location */
case 'type':
return $this->data[0][0];
case 'body_code':
if ($this->data[0][0] == 'B') {
return substr($this->data[0], 1, 5);
}
return null;
case 'place_code':
if ($this->data[0][0] == 'B') {
return substr($this->data[0], 6, 3);
}
return null;
case 'ship_code':
if ($this->data[0][0] == 'S') {
return substr($this->data[0], 1, 5);
}
return null;
case 'body_kind':
if ($this->data[0][0] == 'B' && $this->body != null) {
if ($kind = $this->body->kind()) {
return $kind;
}
} elseif ($this->data[0][0] == 'S') {
return 'ship';
}
return 'place';
case 'containsGlobalLocation':
return count($this->data) > 0;
case 'containsLocalLocation':
return count($this->data) > 1;
default:
throw new Exception("Unknown variable: $variable");
break;
}
}
/**
* Checks if the place exists
*
* @return bool true if the place exists ; otherwise, false.
*
* @todo Handle alias
*/
function exists () {
$n = count($this->data);
//If not defined, it doesn't exist
if ($n == 0) return false;
//Checks global location
switch ($this->data[0][0]) {
case 'B':
switch (strlen($this->data[0])) {
case 9:
if (!$place = GeoPlace::from_code($this->data[0]))
return false;
break;
case 6:
$body = new GeoBody(substr($this->data[0], 1));
if ($body->lastError) return false;
break;
default:
message_die(GENERAL_ERROR, "Invalid global location expression size: " . $this->data[0], "GeoLocation exists method", __LINE__, __FILE__);
}
break;
case 'S':
$ship = new Ship(substr($this->data[0], 1));
if ($body->lastError) return false;
break;
default:
message_die(GENERAL_ERROR, "Invalid global location expression size: " . $this->data[0], "GeoLocation exists method", __LINE__, __FILE__);
return false;
}
if ($n > 1) {
if (!isset($place)) {
message_die(GENERAL_ERROR, "Can't check if a local place exists for the following location: " . $this->data[0], "GeoLocation exists method", __LINE__, __FILE__);
}
if (!$place->is_valid_local_location($this->data[1])) {
return false;
}
}
return true;
}
/**
* Checks if the place is equals at the specified expression or place
*
* @return bool true if the places are equals ; otherwise, false.
*
* @todo Create a better set of rules to define when 2 locations are equal.
*/
function equals ($expression) {
//Are global location equals?
//TODO: create a better set of rules to define when 2 locations are equal.
if (is_a($expression, 'GeoLocation')) {
if (!$this->equals($expression->data[0])) {
return false;
}
if (count($expression->data) + count($this->data) > 2) {
return $expression->data[1] == $this->data[1];
}
}
if ($expression == $this->data[0]) return true;
$n1 = strlen($expression);
$n2 = strlen($this->data[0]);
if ($n1 > $n2) {
return substr($expression, 0, $n2) == $this->data[0];
}
return false;
}
/**
* Represents the current location instance as a string
*
* @return string a string representing the current location
*/
function __toString () {
if (!$this->data[0])
return "";
switch ($this->data[0][0]) {
case 'S':
$ship = new Ship($this->ship_code);
$location[] = $ship->name;
break;
case 'B':
$body = new GeoBody($this->body_code);
$location[] = $body->name ? $body->name : lang_get('UnknownBody');
if (strlen($this->data[0]) == 9) {
$place = GeoPlace::from_code($this->data[0]);
$location[] = $place->name ? $place->name : lang_get('UnknownPlace');
}
break;
case 'x':
$pt = $this->point3D->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));
}
/**
* Magic method called when a unknown property is set.
*
* Handles $global, $local, $type, $body_code, $ship_code, $place_code
*/
function __set ($variable, $value) {
switch ($variable) {
/* main variables */
case 'global':
$this->data[0] = $value;
break;
case 'local':
$this->data[1] = $value;
break;
/* global location */
case 'type':
if ($value == 'B' || $value == 'S') {
if (!$this->data[0]) {
$this->data[0] = $value;
} else {
$this->data[0][0] = $value;
}
}
break;
case 'body_code':
if (preg_match("/[0-9]{1,5}/", $value)) {
$value = sprintf("%05d", $value);
if (!$this->data[0]) {
$this->data[0] = "B" . $value;
return;
} elseif ($this->data[0][0] == 'B') {
$this->data[0] = "B" . $value . substr($this->data[0], 6);
return;
}
throw new Exception("Global location isn't a body.");
}
throw new Exception("$value isn't a valid body code");
case 'ship_code':
if (preg_match("/[0-9]{1,5}/", $value)) {
$value = sprintf("%05d", $value);
if (!$this->data[0]) {
$this->data[0] = "S" . $value;
return;
} elseif ($this->data[0][0] == 'S') {
$this->data[0] = "S" . $value . substr($this->data[0], 6);
return;
}
throw new Exception("Global location isn't a ship.");
}
throw new Exception("$value isn't a valid ship code");
case 'place_code':
if (!preg_match("/[0-9]{1,3}/", $value)) {
throw new Exception("$value isn't a valid place code");
}
$value = sprintf("%03d", $value);
if ($this->data[0][0] == 'B') {
$this->data[0] = substr($this->data[0], 0, 6) . $value;
}
throw new Exception("Global location isn't a body.");
default:
throw new Exception("Unknown variable: $variable");
break;
}
}
}
-
-?>
diff --git a/includes/geo/octocube.php b/includes/geo/octocube.php
index 917a539..f038445 100755
--- a/includes/geo/octocube.php
+++ b/includes/geo/octocube.php
@@ -1,143 +1,141 @@
<?php
/**
* Geo octocube 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
*/
/**
* Geo octocube class
*
* An octocube is a cube divided in 8 parts (sliced in two in x, y and z)
*
* The coordinates (0, 0, 0) represents the octocube center.
*/
class GeoOctocube {
/**
* Gets the sector from the (x, y, z) specified coordinates
*
* Sector will be:
* <code>
* // _____ _____
* // / 5 / 6 /|
* // /- - -/- - -/ |
* // /_____/____ /| |
* // | | | |/|
* // | 7 | 8 | / | 2
* // |_____|_____|/| |
* // | | | |/
* // | 3 | 4 | /
* // |_____|_____|/
* </code>
*
* @param int $x the x coordinate
* @param int $y the y coordinate
* @param int $z the z coordinate
* @return int the number of the sector (0 if x = y = z = 0 ; otherwise, 1 to 8)
*/
static function get_sector ($x, $y, $z) {
//Cube center
if ($x == 0 && $y == 0 && $z == 0) return 0;
//One of the 8 cubes
$sector = 1;
if ($x >= 0) $sector++; //we're at right
if ($y < 0) $sector += 2; //we're at bottom
if ($z >= 0) $sector += 4; //we're on the top layer
return $sector;
}
/**
* Gets the sector from the (x, y, z) specified coordinates
* @see get_sector
*
* @param mixed $pt a GeoPoint3D object for the x, y, z coordinates or a parsable string
* @return int the number of the sector (0 if x = y = z 0 ; otherwise, 1 to 8)
*/
static function get_sector_from_point3D ($pt) {
if (is_string($pt)) {
$pt = GeoPoint3D::fromString($pt);
}
return self::get_sector($pt->x, $pt->y, $pt->z);
}
/**
* Gets the base vector for the specified sector
*
* Example code:
*
* $vector = GeoOctocube::get_base_vector(4);
* //$vector is a (1, -1, -1) array
*
* @param int $sector the sector number (0-8)
* @return array if the sector is 0, (0, 0, 0) ; otherwise, an array with three signed 1 values.
*/
static function get_base_vector ($sector) {
switch ($sector) {
case 0: return array(0, 0, 0);
case 1: return array(-1, 1, -1);
case 2: return array(1, 1, -1);
case 3: return array(-1, -1, -1);
case 4: return array(1, -1, -1);
case 5: return array(-1, 1, 1);
case 6: return array(1, 1, 1);
case 7: return array(-1, -1, 1);
case 8: return array(1, -1, 1);
default: message_die(GENERAL_ERROR, "Invalid sector: $sector", "GeoOctocube::get_base_vector");
}
}
/**
* Gets SQL RLIKE pattern for the specified sector
*
* @param int $sector the sector number (0-8)
* @param int $z if not null, limits the query to the specified z coordinate [optional]
* @return string a SQL clause like "([0-9]+, -[0,9]+, [0,9]+)"
*/
static function get_rlike_pattern_from_sector ($sector, $z = null) {
if ($sector == 0) return "(0, 0, 0)";
$vector = self::get_base_vector($sector);
//x
if ($vector[0] == 1)
$query = "([0-9]+, ";
else
$query = "(-[0-9]+, ";
//y
if ($vector[1] == 1)
$query .= "[0-9]+, ";
else
$query .= "-[0-9]+, ";
//z
if ($z !== null) {
$query .= "$z)";
} elseif ($vector[2] == "1") {
$query .= "[0-9]+)";
} else {
$query .= "-[0-9]+)";
}
return $query;
}
}
-
-?>
diff --git a/includes/geo/place.php b/includes/geo/place.php
index a604200..1e85432 100755
--- a/includes/geo/place.php
+++ b/includes/geo/place.php
@@ -1,216 +1,214 @@
<?php
/**
* Geo place class.
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2010-01-28 01:48 Autogenerated by Pluton Scaffolding
*
* @package Zed
* @subpackage Geo
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
/**
* Default local location format
*
* The local_location format is a PCRE regular expression
*
* By default, local_location format is an (x, y, z) expression
*/
define('LOCATION_LOCAL_DEFAULT_FORMAT', '/^\([0-9]+( )*,( )*[0-9]+( )*,( )*[0-9]+\)$/');
/**
* Geo place
*
* A place is a city or a hypership district.
*
* It's identified by a 9 chars geocode like B0001001.
* The 5 first chars indicates the body (class GeoBody) where the place is and
* the 3 last digits is the place number.
*
* This class maps the geo_places table.
*/
class GeoPlace {
public $id;
public $body_code;
public $code;
public $name;
public $description;
public $location_local_format;
public $start;
public $hidden;
/**
* Initializes a new instance
*
* @param int $id the primary key
*/
function __construct ($id = null) {
if ($id) {
$this->id = $id;
$this->load_from_database();
}
}
/**
* Loads the object place (ie fill the properties) from the $_POST array
*/
function load_from_form () {
if (array_key_exists('body_code', $_POST)) $this->body_code = $_POST['body_code'];
if (array_key_exists('code', $_POST)) $this->code = $_POST['code'];
if (array_key_exists('name', $_POST)) $this->name = $_POST['name'];
if (array_key_exists('description', $_POST)) $this->description = $_POST['description'];
if (array_key_exists('status', $_POST)) $this->status = $_POST['status'];
if (array_key_exists('location_local_format', $_POST)) $this->location_local_format = $_POST['location_local_format'];
}
/**
* Loads the object place (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$sql = "SELECT * FROM " . TABLE_PLACES . " WHERE place_id = '" . $this->id . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query geo_places", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "place unkwown: " . $this->id;
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;
$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 3c700a3..1d4491b 100755
--- a/includes/geo/point3D.php
+++ b/includes/geo/point3D.php
@@ -1,241 +1,239 @@
<?php
/**
* Geo point 3D class.
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2010-02-23 14:14 DcK
*
* @package Zed
* @subpackage Geo
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
require_once("galaxy.php");
/**
* Geo point 3D class.
*
* This class represents a x, y, z point.
*
* It implements IteratorAggregate to allow the foreach instruction
* on a GeoPoint3D object:
*
* <code>
* $point = new GeoPoint3D(17, 24, -6);
* foreach ($point as $axis => $coordinate) {
* echo "\n\t$axis = $coordinate";
* }
* //This will output:
* // x = 17
* // y = 24
* // z = -6
* </code>
*
* The point 3D representation is xyz: [x, y, z] ; you can print it as a string
* and get this format:
*
* <code>
* $point = new GeoPoint3D(17, 24, -6);
* echo (string)$point; //will output xyz: [17, 24, -6]
* </code>
*
*/
class GeoPoint3D implements IteratorAggregate {
//
// x, y, z public properties
//
/**
* the x coordinate
*
* @var integer
*/
public $x;
/**
* the y coordinate
*
* @var integer
*/
public $y;
/**
* the z coordinate
*
* @var integer
*/
public $z;
//
// constructor / toString
//
/**
* Initializes a new instance of GeoPoint3D class
*
* @param int $x the x coordinate
* @param int $y the y coordinate
* @param int $z the z coordinate
*/
function __construct ($x, $y, $z) {
$this->x = (int)$x;
$this->y = (int)$y;
$this->z = (int)$z;
}
/**
* Parses a string expression ang gets a GeoPoint3D object
*
* 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/pointPolarZ.php b/includes/geo/pointPolarZ.php
index 5549612..45513ab 100755
--- a/includes/geo/pointPolarZ.php
+++ b/includes/geo/pointPolarZ.php
@@ -1,376 +1,374 @@
<?php
/**
* Geo point polar+z class.
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* @package Zed
* @subpackage Geo
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
require_once("point3D.php");
/**
* Geo point polar+z class.
*
* This class represents a r, ρ, z point.
*
* They are useful to express coordinates in a cylinder shape, like a tower
* where it make senses to use polar coordinates instead x, y but where the
* height is not relative to a center, like it would be in a sphere.
*
* It implements IteratorAggregate to allow the foreach instruction
* on a GeoPointPolarZ object:
*
* <code>
* $point = new GeoPointPolarZ(17, '24°', -6);
* foreach ($point as $axis => $coordinate) {
* echo "\n\t$axis = $coordinate";
* }
* //This will output:
* // r = 17
* // t = 24°
* // z = -6
* </code>
*
* The point 3D representation is rtz: [ρ, θ, z] ; you can print it as a string
* and get this format:
*
* <code>
* $point = new GeoPointPolarZ(17, '24°', -6);
* echo (string)$point; //will output rρz: [17, 24°, -6]
* </code>
*
*/
class GeoPointPolarZ implements IteratorAggregate {
//
// ρ, θ, z public properties
//
/**
* the ρ coordinate
*
* @var float
*/
public $r;
/**
* the θ coordinate
*
* This coordinate could be expressed as:
* - a string with a float, appended by "°" or " °" (in degree)
* - as a float (in radian)
*
* @var mixed
*/
public $t;
/**
* the z coordinate
*
* @var float
*/
public $z;
//
// constructor / toString
//
/**
* Initializes a new instance of GeoPointPolarZ class
*
* @param float $r the ρ coordinate
* @param mixed $t the θ coordinate, in ° (string) or radian (float)
* @param float $z the z coordinate
*/
function __construct ($r, $t, $z) {
$this->r = (float)$r;
$this->t = trim($t);
$this->z = (float)$z;
}
/**
* Parses a string expression ang gets a GeoPointPolarZ object
*
* Formats recognized are:
* - rtz: [ρ, θ, z]
* - (ρ, θ, z)
*
* @param string $expression the expression to parse
* @return GeoPointPolarZ If the specified expression could be parsed, a GeoPointPolarZ instance ; otherwise, null.
*/
static function fromString ($expression) {
if (string_starts_with($expression, 'rtz:', false)) {
$pos1 = strpos($expression, '[', 4) + 1;
$pos2 = strpos($expression, ']', $pos1);
if ($pos1 > -1 && $pos2 > -1) {
$expression = substr($expression, $pos1, $pos2 - $pos1);
$rtz = explode(',', $expression, 3);
return new GeoPointPolarZ($rtz[0], $rtz[1], $rtz[2]);
}
} elseif ($expression[0] = '(') {
$expression = substr($expression, 1, -1);
$rtz = explode(',', $expression, 3);
return new GeoPointPolarZ($rtz[0], $rtz[1], $rtz[2]);
}
return null;
}
/**
* Returns a string representation of the point coordinates.
*
* @param $format the format to use
* @return string a string representation of the coordinates
*
* To print a "rtz: [10, 20°, 40]" string:
* $point = new GeoPointPolarZ(10, '20°', 40);
* echo $point->sprintf("rtz: [%d, %s, %d]");
*
* //Of course, you could have (implicitely) use the __toString method:
* echo $point;
*
* To print a (10, 20°, 40) string:
* $point = new GeoPointPolarZ(10, 20°, 40);
* echo $point->sprintf("(%d, %s, %d)");
*/
function sprintf ($format) {
return sprintf($format, $this->r, self::get_degrees($this->t), $this->z);
}
/**
* Returns a rρz: [r, ρ, z] string representation of the point coordinates.
*
* @return string a rtz: [ρ, θ, z] string representation of the coordinates
*/
function __toString () {
return $this->sprintf("rtz: [%d, %s, %d]");
}
/**
* Determines if this point is equal to the specified point.
*
* @param GeoPointPolarZ $point The point to compare
* @return bool true if the two points are equal ; otherwise, false.
*/
function equals ($point) {
return ($this->r == $point->r) && self::angle_equals($this->t, $point->t) && ($this->z == $point->z);
}
/**
* Detemrines if two angles are equal
* @param mixed $angle1 the first angle value, ie a float (angle in radian) or a string formed by an integed appended by ° (degrees)
* @param mixed $angle2 the second angle value, a float (angle in radian) or a string formed by an integed appended by ° (degrees)
* @return bool true if the angles are equal ; otherwise, false.
*/
static function angle_equals ($angle1, $angle2) {
if ($angle1 === $angle2) return true;
if (!is_numerical($angle1)) {
$angle1 = deg2rad((float)$angle1);
}
if (!is_numerical($angle2)) {
$angle2 = deg2rad((float)$angle2);
}
$angle1 = self::normalize_angle($angle1);
$angle2 = self::normalize_angle($angle2);
return ($angle1 == $angle2);
}
/**
* Normalizes an angle (in radians) in the interval [0, π[ (or a custom interval)
*
* @param float $angle the angle (in radians)
* @param float $min the radians value the angle must be greater or equal than [optional, default value: 0]
* @param float $max the radains value the angle must be stricly lesser than [optional, default value: M_PI]
* @param float $interval the increment interval [optional, default value: 360]
*/
static function normalize_angle ($angle, $min = 0, $max = M_PI, $interval = M_PI) {
while ($angle < $min) {
$angle += $interval;
}
while ($angle >= $max) {
$angle -= $interval;
}
return $angle;
}
/**
* Normalizes an angle (in degrees) in the interval [0, 360[ (or a custom interval)
*
* @param float $angle the angle to normalize, in degrees
* @param float $min the degrees value the angle must be greater or equal than [optional, default value: 0]
* @param float $max the degrees value the angle must be stricly lesser than [optional, default value: 360]
* @param float $interval the increment interval [optional, default value: 360]
*/
static function normalize_angle_deg ($angle, $min = 0, $max = 360, $interval = 360) {
while ($angle < $min) {
$angle += $interval;
}
while ($angle >= $max) {
$angle -= $interval;
}
return $angle;
}
/**
* Gets the specified angle in radians
*
* @param mixed $angle the angle, a float in radians or a string (a float + "°" or " °" in degrees
* @return float the angle in radians
*/
static function get_radians ($angle) {
return is_numeric($angle) ? $angle : deg2rad((float)$angle);
}
/**
* Gets the specified angle in degrees
*
* @param mixed $angle the angle, a float in radians or a string (a float + "°" or " °" in degrees
* @return string the angle (float) in degrees followed by "°"
*/
static function get_degrees ($angle) {
return is_numeric($angle) ? rad2deg((float)$angle) . '°' : $angle;
}
/**
* Converts a polar coordinate angle to a 0-360° CW angle
*/
static function get_natural_degrees ($angle) {
return self::normalize_angle_deg(90 - self::get_degrees($angle));
}
//
// Math
//
/**
* Gets the (x, y, z) cartesian coordinates from the current ρ, θ, z polar+z point
*
* @return array an array of 3 floats number, representing the (x, y, z) cartesian coordinates
*/
function to_cartesian () {
$x = $this->r * cos(self::get_radians($this->t));
$y = $this->r * sin(self::get_radians($this->t));
return array($x, $y, $this->z);
}
/**
* Converts the current GeoPointPolarZ instance to a GeoPoint3D instance
*
* @return GeoPoint3D an instance of the GeoPoint3D class representing the (x, y, z) cartesian coordinates
*/
function to_Point3D () {
$pt = $this->to_cartesian();
return new GeoPoint3D($pt[0], $pt[1], $pt[2]);
}
/**
* Gets the (ρ, φ, θ) spherical coordinates from the current (ρ, θ, z) polar+z point
*
* The algo used is from http://fr.wikipedia.org/wiki/Coordonn%C3%A9es_sph%C3%A9riques#Relation_avec_les_autres_syst.C3.A8mes_de_coordonn.C3.A9es_usuels
*
* @return array an array of 3 floats number, representing the (ρ, φ, θ) spherical coordinates
*/
function to_spherical () {
$pt = $this->to_cartesian();
return GeoGalaxy::cartesian_to_spherical($pt[0], $pt[1], $pt[2]);
}
/**
* Gets the (ρ, φ, θ) spherical coordinates from the current (ρ, θ, z) polar+z point
*
* The algo used is from http://www.phy225.dept.shef.ac.uk/mediawiki/index.php/Cartesian_to_polar_conversion
*
* @return array an array of 3 floats number, representing the (ρ, φ, θ) spherical coordinates
*/
function to_spherical2 () {
$pt = $this->to_cartesian();
return GeoGalaxy::cartesian_to_spherical2($pt[0], $pt[1], $pt[2]);
}
/**
* Translates the center and rescales.
*
* This method allow to help to represent coordinate in a new system
*
* This method is used to represent Zed objects in dojo with the following
* parameters:
* <code>
* $pointKaos = GeoPointPolarZ(800, 42, 220);
* $pointKaos->translate(500, 300, 200, 2);
* echo $pointKaos;
* //This will output rρz: [150, -129, 10]
* </code>
*
* @param float $dr the difference between the old ρ and new ρ (ie the value of ρ = 0 in the new system)
* @param float $dt the difference between the old θ and new θ (ie the value of θ = 0 in the new system)
* @param float $dz the difference between the old y and new z (ie the value of z = 0 in the new system)
* @param int $scale if specified, divides each coordinate by this value (optional)
*/
function translate ($dr, $dt, $dz, $scale = 1) {
if ($scale == 1) {
$this->r += $dr;
$this->t += $dt;
$this->z += $dz;
} elseif ($scale == 0) {
$this->r = 0;
$this->t = 0;
$this->z = 0;
} else {
$this->r = $this->r * $scale + $dr;
$this->t = $this->t * $scale + $dt;
$this->z = $this->z * $scale + $dz;
}
}
/**
* Calculates the section number the specified angle belongs
*
* @param $angle float The natural angle in degree (North 0°, East 90°, etc. clockwise)
* @param int $count the number of sections (default value: 6)
* @return $int the section number
*/
static function calculate_section ($angle, $count = 6) {
if ($angle < 90) {
$angle += 270;
} else {
$angle -= 90;
}
return 1 + (int)($angle / (360/$count));
}
/**
* Gets the section number the θ angle belongs to.
*
* @param int $count the number of sections
* @return $int the section number
*/
function get_section ($count = 6) {
return self::calculate_section(self::get_natural_degrees($this->t), $count);
}
//
// Implementing IteratorAggregate
//
/**
* Retrieves class iterator. It traverses ρ, θ and z.
*
* @return Traversable the iterator
*/
function getIterator () {
return new ArrayIterator($this);
}
}
-
-?>
diff --git a/includes/geo/scene.php b/includes/geo/scene.php
index c2310ab..ae2d4a6 100755
--- a/includes/geo/scene.php
+++ b/includes/geo/scene.php
@@ -1,214 +1,212 @@
<?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/geo/sceneindex.php b/includes/geo/sceneindex.php
index e98059d..c9dbd5c 100755
--- a/includes/geo/sceneindex.php
+++ b/includes/geo/sceneindex.php
@@ -1,216 +1,214 @@
<?php
/**
* Geo scene index class.
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* @package Zed
* @subpackage Geo
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*
* This class implements a singleton pattern.
*/
require_once('includes/cache/cache.php');
/**
* Geo scene class
*
* This class provides an index of available scene template files.
*/
class GeoSceneIndex {
/**
* Global location templates array
*
* Keys are global location codes.
* Values the relevant template file.
*
* @var Array
*/
public $global_templates;
/**
* Rocal location templates 2D array
*
* Keys are global and local ocation codes.
* Values the relevant template file.
*
* e.g. $local_templates['B00017001']['(10, 50, 8)'] => 'B00017_port.tpl'
*
* @var Array
*/
public $local_templates;
/**
* Time of the last updated file in the scenes directory
*
* @var int
*/
public $updated;
/**
* The directory where templates are stored
*
* @var string
*/
public $directory;
/**
* The current index instance array
*
* Keys are scene directories (string)
* Items are GeoSceneIndex instances
*
* @var Array
*/
static $instance = array();
/**
* Gets the index instance, initializing it if needed
*
* @return index the index instance
*/
static function load ($directory) {
//Creates the index object if needed
if (!array_key_exists($directory, self::$instance)) {
self::$instance[$directory] = new GeoSceneIndex($directory);
}
return self::$instance[$directory];
}
/**
* Initializes a new GeoSceneIndex istance
*
* @param string $directory the scene templates directory
*/
public function __construct ($directory) {
$this->directory = $directory;
if (!$this->get_cached_information() || !$this->is_up_to_date()) {
$this->refresh_information();
$this->set_cached_information();
}
}
/**
* Caches index data
*/
public function set_cached_information () {
$cache = Cache::load();
$cache->set('zed_sceneindex', serialize($this));
}
/**
* Gets index from cache
*/
public function get_cached_information () {
$cache = Cache::load();
$cached_index =$cache->get('zed_sceneindex');
if ($index = unserialize($cache->get('zed_sceneindex'))) {
$index = unserialize($cache->get('zed_sceneindex'));
$this->global_templates = $index->global_templates;
$this->local_templates = $index->local_templates;
$this->updated = $index->updated;
$this->directory = $index->directory;
return true;
}
return false;
}
/**
* Reads scene templates and indexes information
*/
public function refresh_information () {
$this->global_templates = array();
$this->local_templates = array();
$this->updated = filemtime($this->directory);
if ($handle = opendir($this->directory)) {
while (false !== ($file = readdir($handle))) {
if (GeoScene::get_file_extension($file) == 'tpl') {
$template = file_get_contents($this->directory . '/' . $file, false, NULL, 0, 1024);
$location = self::get_template_location($template);
if ($location[1] !== NULL) {
$this->local_templates[$location[0]][$location[1]] = $file;
} elseif ($location[0] != NULL) {
$this->global_templates[$location[0]] = $file;
}
}
}
closedir($handle);
}
}
/**
* Determines if the information is still up to date
*
* @return bool true if the information is up to date ; otherwise, false.
*/
public function is_up_to_date () {
return ($this->updated == filemtime($this->directory));
}
/**
* Gets template location
*
* @return Array an string array of the location (two items; global, local)
* At key 0, a string with global location, or NULL if not specified
* At key 1, a string with local location, or NULL if not specified
*/
private static function get_template_location ($template) {
$location = array(NULL, NULL);
//Gets global location
$pos1 = strpos($template, "Global location: ") + 17;
$pos2 = strpos($template, "\n", $pos1);
$location[0] = trim(substr($template, $pos1, $pos2 - $pos1));
//Gets local location
$pos1 = strpos($template, "Local location: ");
if ($pos1 !== false) {
$pos1 += 16;
$pos2 = strpos($template, "\n", $pos1);
$location[1] = trim(substr($template, $pos1, $pos2 - $pos1));
}
return $location;
}
/**
* Gets local template file from index
*
* @param string $location_global the global location
* @param string $location_global the local location
* @return string the relevant template scene file, or NULL if not existant
*/
public function get_local_template ($location_global, $location_local) {
if (isset($this->local_templates[$location_global][$location_local])) {
return $this->local_templates[$location_global][$location_local];
}
return NULL;
}
/**
* Gets global template file from index
*
* @param string $location_global the global location
* @return string the relevant template scene file, or NULL if not existant
*/
public function get_global_template ($location_global) {
if (isset($this->global_templates[$location_global])) {
return $this->global_templates[$location_global];
}
return NULL;
}
}
-
-?>
\ No newline at end of file
diff --git a/includes/login.php b/includes/login.php
index 280629a..8436677 100755
--- a/includes/login.php
+++ b/includes/login.php
@@ -1,157 +1,156 @@
<?php
/**
* Login/logout
*
* 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
*
* @todo Pick between DumbStore and FileStore and cleans the file accordingly.
*/
///
/// OpenID helper code
///
$useOpenID = isset($Config['OpenID']) && $Config['OpenID'];
if ($useOpenID) {
require_once('Auth/OpenID/Consumer.php');
require_once('Auth/OpenID/FileStore.php');
}
/**
* Gets an Auth_OpenID_Consumer instance
*
* @return Auth_OpenID_Consumer the instance
*/
function get_openid_consumer () {
if (!file_exists('/dev/urandom')) {
//We don't have a reliable source of random numbers
define('Auth_OpenID_RAND_SOURCE', null);
}
$fs = new Auth_OpenID_FileStore(CACHE_DIR . '/openid');
return new Auth_OpenID_Consumer($fs);
}
/**
* Logs in the user if the OpenID is recognized.
* Otherwise, sets an error message.
*
* @param string $url The OpenID URL
*/
function openid_login ($url) {
global $db, $_SESSION, $LoginError, $LoginSuccessful;
$url = $db->sql_escape($url);
$sql = 'SELECT user_id FROM ' . TABLE_USERS_AUTH
. " WHERE auth_type = 'OpenID' AND auth_identity LIKE '$url'";
if ($user_id = $db->sql_query_express($sql)) {
$sql = "UPDATE " . TABLE_SESSIONS . " SET user_id = '$user_id' WHERE session_id LIKE '$_SESSION[ID]'";
if (!$db->sql_query($sql)) message_die(SQL_ERROR, "Can't update session table", '', __LINE__, __FILE__, $sql);
$LoginSuccessful = true;
setcookie("LastOpenID", $url, time() + 2592000);
header("location: " . get_url());
} else {
$LoginError = "Read the source to get an invite.";
}
}
///
/// Login procedural code
///
$action = isset($_GET['action']) ? $_GET['action'] : '';
if ($action == 'openid.login') {
//Gets Auth_OpenID_Consumer instance, completes the OpenID transaction
//and processes the result.
if (!$useOpenID()) {
header("Status: 403 Forbidden");
die("OpenID disabled.");
}
$consumer = get_openid_consumer();
$reply = $consumer->complete(get_server_url() . $_SERVER['REQUEST_URI']);
if ($reply->status == Auth_OpenID_SUCCESS) {
openid_login($reply->endpoint->claimed_id);
} elseif ($reply->message) {
//TODO: $reply->message could be rather long and won't fit in the UI
//space. You can wish to add code to print $LoginError elsewhere if
//too long.
$LoginError = "[OpenID] $reply->message";
} else {
$LoginError = "[OpenID] $reply->status";
}
} elseif (isset($_POST['LogIn'])) {
//User have filled login form
if ($_POST['openid'] && $useOpenID) {
//Gets Auth_OpenID_Consumer instance
$consumer = get_openid_consumer();
//Starts the OpenID transaction and redirects user to provider url
if ($request = $consumer->begin($_POST['openid'])) {
$url = $request->redirectURL(get_server_url(), "$Config[SiteURL]/?action=openid.login", false);
header("location: $url");
$LoginError = '<a href="' . $url . '">Click here to continue login</a>';
} else {
$LoginError = 'Invalid OpenID URL.';
}
} else {
//Login
//Authentications way, the user/password in last.
//OpenID is handled by a separate logic.
$Login = $_POST['username'];
$authentications = array();
if ($useYubiCloud = array_key_exists('YubiCloud', $Config) ) {
$authentications[] = new YubiCloudAuthentication($_POST['password'], $Login);
}
if ($Login) {
$authentications[] = new UserPasswordAuthentication($Login, $_POST['password']);
}
$loginSuccessful = false;
foreach ($authentications as $authentication) {
if ($authentication->isValid()) {
$loginSuccessful = true;
//Logs in user
login($authentication->getUserID(), $Login);
} else {
$loginError = $authentication->getError();
}
if (!$authentication->canTryNextAuthenticationMethod()) {
break;
}
}
//Tests if the password wouldn't match an invite code
//If so, redirects people using login page as invitation claim page
if (!$LoginSuccessful) {
$code = $db->sql_escape($_POST['password']);
$sql = "SELECT * FROM " . TABLE_USERS_INVITES . " WHERE invite_code = '$code'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't get invites", '', __LINE__, __FILE__, $sql);
}
if ($row = $db->sql_fetchrow($result)) {
$url = get_url('invite', $_POST['password']);
header('location: ' . $url);
}
}
}
} elseif (isset($_POST['LogOut']) || $action == "user.logout") {
Logout();
}
-
diff --git a/includes/objects/application.php b/includes/objects/application.php
index f612937..5443741 100755
--- a/includes/objects/application.php
+++ b/includes/objects/application.php
@@ -1,177 +1,175 @@
<?php
/**
* Application class
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2010-02-10 02:40 Autogenerated by Pluton Scaffolding
* Some API bits
*
* @package Zed
* @subpackage Model
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
require_once('perso.php');
/**
* Application class
*
* This class maps the Application table.
*
* This class also provides methods application API helper methods, to generate
* an application user key or to gets the perso ID from such a key.
*/
class Application {
public $id;
public $code;
public $name;
public $api_key;
public $description;
/**
* Initializes a new instance
*
* @param int $id the primary key
*/
function __construct ($id = null) {
if ($id) {
$this->id = $id;
$this->load_from_database();
}
}
/**
* Loads the object Application (ie fill the properties) from the $_POST array
*/
function load_from_form () {
if (array_key_exists('code', $_POST)) $this->code = $_POST['code'];
if (array_key_exists('name', $_POST)) $this->name = $_POST['name'];
if (array_key_exists('api_key', $_POST)) $this->api_key = $_POST['api_key'];
if (array_key_exists('description', $_POST)) $this->description = $_POST['description'];
}
/**
* Loads the object Application (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$id = $db->sql_escape($this->id);
$sql = "SELECT * FROM applications WHERE application_id = '" . $id . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query applications", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "Application unkwown: " . $this->id;
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 4796c33..159c72c 100755
--- a/includes/objects/content.php
+++ b/includes/objects/content.php
@@ -1,304 +1,302 @@
<?php
/**
* Content class
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2010-02-24 15:57 Autogenerated by Pluton Scaffolding
*
* @package Zed
* @subpackage Model
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*
* @deprecated
*/
/**
* Content class
*
* This class maps the content view.
*
* This view shows the content_files and content_locations tables.
*
* This class also provides helper methods, to handle files, generate thumbnails
* or get local content from a specific location.
*
* [DESIGN BY CONTRACT] This class works only with the following assertions:
* i. Each content have EXACTLY ONE location
* ii. Location fields will not be modified
*
* If a content have more than one location, only the first occurence in
* content_locations table will be considered.
*
* If a content have no location, it will be ignored.
*
* If you edit content location, then call saveToDatabase, you will create
* a new location but future instances will contain first not deleted location.
*
* @todo remove dbc temporary limitations (cf. /do.php upload_content and infra)
* @todo create a class ContentLocation and move location fields there
* @todo validate SQL schema and add in config.php TABLE_CONTENT tables
*
* @deprecated
*/
class Content {
/* -------------------------------------------------------------
Properties
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
public $id;
public $path;
public $user_id;
public $perso_id;
public $title;
public $location_global = null;
public $location_local = null;
public $location_k = null;
public $perso_name;
public $perso_nickname;
/* -------------------------------------------------------------
Constructor, __toString
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
* Initializes a new Content instance
*
* @param int $id the primary key
*/
function __construct ($id = null) {
if ($id) {
$this->id = $id;
$this->load_from_database();
}
}
/**
* Returns a string representation of current Content instance
*
* @return string the content title or path if title is blank.
*/
function __toString () {
return $this->title ? $this->title : $this->path;
}
/* -------------------------------------------------------------
Load/save class
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
* Loads the object Content (ie fill the properties) from the $_POST array
*
* @param boolean $allowSensibleFields if false, allow only location_local, location_k and title to be defined ; otherwise, allow all fields.
*/
function load_from_form ($allowSensibleFields = false) {
if (array_key_exists('title', $_POST)) $this->title = $_POST['title'];
if (array_key_exists('location_local', $_POST)) $this->location_local = $_POST['location_local'];
if (array_key_exists('location_k', $_POST)) $this->location_k = $_POST['location_k'];
if ($allowSensibleFields) {
if (array_key_exists('path', $_POST)) $this->path = $_POST['path'];
if (array_key_exists('user_id', $_POST)) $this->user_id = $_POST['user_id'];
if (array_key_exists('perso_id', $_POST)) $this->perso_id = $_POST['perso_id'];
if (array_key_exists('location_global', $_POST)) $this->location_global = $_POST['location_global'];
}
}
/**
* Loads the object Content (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$id = $db->sql_escape($this->id);
$sql = "SELECT * FROM content WHERE content_id = '" . $id . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query content", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "Content unkwown: " . $this->id;
return false;
}
$this->load_from_row($row);
return true;
}
/**
* Loads the object from row
*/
function load_from_row ($row) {
$this->id = $row['content_id'];
$this->path = $row['content_path'];
$this->user_id = $row['user_id'];
$this->perso_id = $row['perso_id'];
$this->title = $row['content_title'];
$this->location_global = $row['location_global'];
$this->location_local = $row['location_local'];
$this->location_k = $row['location_k'];
if (array_key_exists('perso_name', $row)) $this->perso_name = $row['perso_name'];
if (array_key_exists('perso_nickname', $row)) $this->perso_nickname = $row['perso_nickname'];
}
/**
* Saves to database
*/
function save_to_database () {
global $db;
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$path = $db->sql_escape($this->path);
$user_id = $db->sql_escape($this->user_id);
$perso_id = $db->sql_escape($this->perso_id);
$title = $db->sql_escape($this->title);
$location_global = ($this->location_global !== null) ? "'" . $db->sql_escape($this->location_global) . "'" : 'NULL';
$location_local = ($this->location_local !== null) ? "'" . $db->sql_escape($this->location_local) . "'" : 'NULL';
$location_k = ($this->location_k !== null) ? "'" . $db->sql_escape($this->location_k) . "'" : 'NULL';
//Updates or inserts
$sql = "REPLACE INTO content_files (`content_id`, `content_path`, `user_id`, `perso_id`, `content_title`) VALUES ($id, '$path', '$user_id', '$perso_id', '$title')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't save content", '', __LINE__, __FILE__, $sql);
}
if (!$this->id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
//Saves location
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$sql = "REPLACE INTO content_locations (location_global, location_local, location_k, content_id) VALUES ($location_global, $location_local, $location_k, $id)";
if (!$db->sql_query($sql))
message_die(SQL_ERROR, "Can't save content location", '', __LINE__, __FILE__, $sql);
}
/* -------------------------------------------------------------
File handling helper methods
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
* Determines if the extension is valid
*
* @param string $ext The extension (without dot)
* @return boolean true if this extension is valid ; otherwise, false.
*/
function is_valid_extension ($ext) {
switch ($ext = strtolower($ext)) {
//Pictures
case 'jpg':
case 'gif':
case 'png':
case 'bmp':
case 'xbm':
return true;
//Denied extension
default:
return false;
}
}
/**
* Creates a directory
*
* @param string $dir the directory to create
*/
function create_directory ($directory) {
if (!file_exists($directory)) {
@mkdir($directory); //Creates new directory, chmod 777
}
}
/**
* Handles uploaded file
*
* @return bool true if the file have been handled
*/
function handle_uploaded_file ($fileArray) {
if (count($fileArray) && $fileArray['error'] == 0) {
$this->create_directory("content/users/$this->user_id");
$this->path = "content/users/$this->user_id/$fileArray[name]";
if (!self::is_valid_extension(get_extension($fileArray[name]))) {
return false;
}
if (move_uploaded_file($fileArray['tmp_name'], $this->path)) {
return true;
} else {
$this->path = null;
return false;
}
} else {
return false;
}
}
/**
* Generates a thumbnail using ImageMagick binary
*
* @return boolean true if the thumbnail command returns 0 as program exit code ; otherwise, false
*/
function generate_thumbnail () {
global $Config;
//Builds thumbnail filename
$sourceFile = $this->path;
$pos = strrpos($this->path, '.');
$thumbnailFile = substr($sourceFile, 0, $pos) . 'Square' . substr($sourceFile, $pos);
//Executes imagemagick command
$command = $Config['ImageMagick']['convert'] . " \"$sourceFile\" -resize 162x162 \"$thumbnailFile\"";
@system($command, $code);
//Returns true if the command have exited with errorcode 0 (= ok)
return ($code == 0);
}
/* -------------------------------------------------------------
Gets content
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
* Gets content at specified location
*
* @param string $location_global global content location
* @param string $location_local local content location
* @return Array array of Content instances
*/
static function get_local_content ($location_global, $location_local) {
global $db;
//Get contents at this location
$location_global = $db->sql_escape($location_global);
$location_local = $db->sql_escape($location_local);
$sql = "SELECT c.*, p.perso_nickname, p.perso_name FROM content c, persos p WHERE c.location_global = '$location_global' AND c.location_local = '$location_local' AND p.perso_id = c.perso_id ORDER BY location_k ASC";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't get content", '', __LINE__, __FILE__, $sql);
}
//Fills content array
$contents = array();
while ($row = $db->sql_fetchrow($result)) {
$content = new Content();
$content->load_from_row($row);
$contents[] = $content;
}
return $contents;
}
}
-
-?>
\ No newline at end of file
diff --git a/includes/objects/invite.php b/includes/objects/invite.php
index 0b790a3..b91198a 100755
--- a/includes/objects/invite.php
+++ b/includes/objects/invite.php
@@ -1,198 +1,197 @@
<?php
/**
* User invite class
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2010-06-29 02:13 Initial version [DcK]
*
* @package Zed
* @subpackage Model
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
/**
* User invite class
*
* This class maps the users_invites table.
*/
class Invite {
public $code;
public $date;
public $from_user_id;
public $from_perso_id;
/**
* The user_id who have been claimed the invite
* Will be NULL as long as the invite haven't been claimed
*
* @var int
*/
public $to_user_id = NULL;
/**
* Initializes a new instance
*
* @param int $code the primary key
*/
function __construct ($code = NULL) {
if ($code) {
$this->code = $code;
$this->load_from_database();
} else {
//New invite code
$this->generate_code();
$this->date = time();
}
}
/**
* Generates a unique invite code and sets it in the code property.
*/
function generate_code () {
global $db;
do {
$this->code = generate_random_string("AAA111");
$sql = "SELECT COUNT(*) FROM " . TABLE_USERS_INVITES . " WHERE invite_code = '$this->code' LOCK IN SHARE MODE;";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't access invite users table", '', __LINE__, __FILE__, $sql);
}
$row = $db->sql_fetchrow($result);
} while ($row[0]);
}
/**
* Loads the object Invite (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$code = $db->sql_escape($this->code);
$sql = "SELECT * FROM " . TABLE_USERS_INVITES . " WHERE invite_code = '" . $code . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query invite codes", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "Invite code unkwown: " . $this->code;
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 8912e72..ee2fb3e 100755
--- a/includes/objects/message.php
+++ b/includes/objects/message.php
@@ -1,157 +1,156 @@
<?php
/**
* Message class
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2010-01-28 01:47 Autogenerated by Pluton Scaffolding
*
* @package Zed
* @subpackage Model
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
/**
* Message class
*
* This class maps the messages table.
*
* It also provides a static method to get perso's messages.
*/
class Message {
public $id;
public $date;
public $from;
public $to;
public $text;
public $flag;
/**
* Initializes a new instance
*
* @param int $id the primary key
*/
function __construct ($id = null) {
if ($id) {
$this->id = $id;
$this->load_from_database();
} else {
$this->date = time();
$this->flag = 0; //unread
}
}
/**
* Loads the object Message (ie fill the properties) from the $_POST array
*/
function load_from_form () {
if (array_key_exists('date', $_POST)) $this->date = $_POST['date'];
if (array_key_exists('from', $_POST)) $this->from = $_POST['from'];
if (array_key_exists('to', $_POST)) $this->to = $_POST['to'];
if (array_key_exists('text', $_POST)) $this->text = $_POST['text'];
if (array_key_exists('flag', $_POST)) $this->flag = $_POST['flag'];
}
/**
* Loads the object Message (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$sql = "SELECT * FROM messages WHERE message_id = '" . $this->id . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query messages", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "Message unkwown: " . $this->id;
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 c701c6a..fd5afa6 100755
--- a/includes/objects/motd.php
+++ b/includes/objects/motd.php
@@ -1,96 +1,95 @@
<?php
/**
* MOTD class
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2010-02-03 21:11 Import from Azhàr code
*
* @package Zed
* @subpackage Model
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
/**
* MOTD class
*
* This class maps the motd table.
*/
class MOTD {
public $id;
public $perso_id;
public $text;
public $date;
/**
* Initializes a new instance of a MOTD object
*
* @param int $id The MOTD ID
*/
function __construct ($id = '') {
if ($id) {
$this->id = $id;
return $this->load_from_database();
} else {
$this->date = time();
return true;
}
}
/**
* Loads the object MOTD (ie fill the properties) from the $_POST array
*/
function load_from_form () {
if (array_key_exists('perso_id', $_POST)) $this->user_id = $_POST['user_id'];
if (array_key_exists('text', $_POST)) $this->text = $_POST['text'];
if (array_key_exists('date', $_POST)) $this->date = $_POST['date'];
}
/**
* Loads the object MOTD (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$id = $db->sql_escape($this->id);
$sql = "SELECT * FROM " . TABLE_MOTD . " WHERE motd_id = '" . $id . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query azhar_motd", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "MOTD unkwown: " . $this->id;
return false;
}
$this->perso_id = $row['perso_id'];
$this->text = $row['motd_text'];
$this->date = $row['motd_date'];
return true;
}
/**
* Saves the object to the database
*/
function save_to_database () {
global $db;
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$perso_id = $db->sql_escape($this->perso_id);
$text = $db->sql_escape($this->text);
$date = $db->sql_escape($this->date);
$sql = "REPLACE INTO " . TABLE_MOTD . " (`motd_id`, `perso_id`, `motd_text`, `motd_date`) VALUES ($id, '$perso_id', '$text', '$date')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
}
}
?>
-
diff --git a/includes/objects/perso.php b/includes/objects/perso.php
index 7c21556..bcc74c5 100755
--- a/includes/objects/perso.php
+++ b/includes/objects/perso.php
@@ -1,581 +1,579 @@
<?php
/**
* Perso class
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2010-01-27 00:39 Autogenerated by Pluton Scaffolding
* 0.2 2010-01-29 14:39 Adding flags support
* 0.3 2010-02-06 17:50 Adding static perso hashtable
* 0.4 2012-07-04 11:37 Refactoring: moving code from index.php
*
* @package Zed
* @subpackage Model
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010, 2012 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
require_once("includes/geo/location.php");
/**
* Perso class
*
* This class maps the persos table.
*
* The class also provides methods
* to move or locate a perso,
* to gets and sets perso's flags and notes (tables persos_flags and persos_notes),
* to gets user's perso or check if a perso is online,
* to handle on select and logout events.
*
*/
class Perso {
public $id;
public $user_id;
public $name;
public $nickname;
public $race;
public $sex;
public $avatar;
public $location_global;
public $location_local;
public $flags;
public $lastError;
public static $hashtable_id = array();
public static $hashtable_name = array();
/**
* Initializes a new instance
*
* @param mixed $data perso ID or nickname
*/
function __construct ($data = null) {
if ($data) {
if (is_numeric($data)) {
$this->id = $data;
} else {
$this->nickname = $data;
}
if (!$this->load_from_database()) {
message_die(GENERAL_ERROR, $this->lastError, "Can't authenticate perso");
}
} else {
$this->generate_id();
}
}
/**
* Initializes a new Perso instance if needed or get already available one.
*
* @param mixed $data perso ID or nickname
* @return Perso the perso instance
*/
static function get ($data = null) {
if ($data) {
//Checks in the hashtables if we already have loaded this instance
if (is_numeric($data)) {
if (array_key_exists($data, Perso::$hashtable_id)) {
return Perso::$hashtable_id[$data];
}
} else {
if (array_key_exists($data, Perso::$hashtable_name)) {
return Perso::$hashtable_name[$data];
}
}
}
$perso = new Perso($data);
return $perso;
}
/**
* Loads the object Perso (ie fill the properties) from the $_POST array
*/
function load_from_form () {
if (array_key_exists('user_id', $_POST)) $this->user_id = $_POST['user_id'];
if (array_key_exists('name', $_POST)) $this->name = $_POST['name'];
if (array_key_exists('nickname', $_POST)) $this->nickname = $_POST['nickname'];
if (array_key_exists('race', $_POST)) $this->race = $_POST['race'];
if (array_key_exists('sex', $_POST)) $this->sex = $_POST['sex'];
if (array_key_exists('avatar', $_POST)) $this->avatar = $_POST['avatar'];
if (array_key_exists('location_global', $_POST)) $this->location_global = $_POST['location_global'];
if (array_key_exists('location_local', $_POST)) $this->location_local = $_POST['location_local'];
}
/**
* Loads the object Perso (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
//Gets perso
$sql = "SELECT * FROM " . TABLE_PERSOS;
if ($this->id) {
$id = $db->sql_escape($this->id);
$sql .= " WHERE perso_id = '" . $id . "'";
} else {
$nickname = $db->sql_escape($this->nickname);
$sql .= " WHERE perso_nickname = '" . $nickname . "'";
}
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query persos", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "Perso unkwown: " . $this->id;
return false;
}
$this->id = $row['perso_id'];
$this->user_id = $row['user_id'];
$this->name = $row['perso_name'];
$this->nickname = $row['perso_nickname'];
$this->race = $row['perso_race'];
$this->sex = $row['perso_sex'];
$this->avatar = $row['perso_avatar'];
$this->location_global = $row['location_global'];
$this->location_local = $row['location_local'];
//Gets flags
$sql = "SELECT flag_key, flag_value FROM " . TABLE_PERSOS_FLAGS .
" WHERE perso_id = $this->id";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't get flags", '', __LINE__, __FILE__, $sql);
}
while ($row = $db->sql_fetchrow($result)) {
$this->flags[$row["flag_key"]] = $row["flag_value"];
}
//Gets location
$this->location = new GeoLocation(
$this->location_global,
$this->location_local
);
//Puts object in hashtables
Perso::$hashtable_id[$this->id] = $this;
Perso::$hashtable_name[$this->nickname] = $this;
return true;
}
/**
* Saves to database
*/
function save_to_database () {
global $db;
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$user_id = $db->sql_escape($this->user_id);
$name = $db->sql_escape($this->name);
$nickname = $db->sql_escape($this->nickname);
$race = $db->sql_escape($this->race);
$sex = $db->sql_escape($this->sex);
$avatar = $db->sql_escape($this->avatar);
$location_global = $this->location_global ? "'" . $db->sql_escape($this->location_global) . "'" : 'NULL';
$location_local = $this->location_local ? "'" . $db->sql_escape($this->location_local) . "'" : 'NULL';
//Updates or inserts
$sql = "REPLACE INTO " . TABLE_PERSOS . " (`perso_id`, `user_id`, `perso_name`, `perso_nickname`, `perso_race`, `perso_sex`, `perso_avatar`, `location_global`, `location_local`) VALUES ($id, '$user_id', '$name', '$nickname', '$race', '$sex', '$avatar', $location_global, $location_local)";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
if (!$id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
}
/**
* Updates the specified field in the database record
*
* @param string $field The field to save
*/
function save_field ($field) {
global $db;
if (!$this->id) {
message_die(GENERAL_ERROR, "You're trying to update a perso record not yet saved in the database: $field");
}
$id = $db->sql_escape($this->id);
$value = $db->sql_escape($this->$field);
$sql = "UPDATE " . TABLE_PERSOS . " SET `$field` = '$value' WHERE perso_id = '$id'";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save $field field", '', __LINE__, __FILE__, $sql);
}
}
/**
* Gets perso location
*
* @return string The location names
*/
public function where () {
return $this->location->__toString();
}
/**
* Moves the perso to a new location
*
* @param string $global the global target location
* @param string $global the local target location
*/
public function move_to ($global = null, $local = null) {
//Sets global location
if ($global != null) {
$this->location_global = $global;
}
//Sets local location
if ($local != null) {
$this->location_local = $local;
}
//Updates database record
if ($global != null && $local != null) {
global $db;
$perso_id = $db->sql_escape($this->id);
$g = $db->sql_escape($this->location_global);
$l = $db->sql_escape($this->location_local);
$sql = "UPDATE " . TABLE_PERSOS .
" SET location_global = '$g', location_local = '$l'" .
" WHERE perso_id = '$perso_id'";
if (!$db->sql_query($sql))
message_die(SQL_ERROR, "Can't save new $global $local location.", '', __LINE__, __FILE__, $sql);
} elseif ($global != null) {
$this->save_field('location_global');
} elseif ($local != null) {
$this->save_field('location_local');
}
//Updates location member
$this->location = new GeoLocation(
$this->location_global,
$this->location_local
);
}
/**
* Gets the specified flag value
*
* @param string $key flag key
* @param mixed $defaultValue default value if the flag doesn't exist
* @return mixed the flag value (string) or null if not existing
*/
public function get_flag ($key, $defaultValue = null) {
return $this->flag_exists($key) ? $this->flags[$key] : $defaultValue;
}
/**
* Determines if the specified flag exists
*
* @param string $key the flag key to check
* @return boolean true if the specified flag exists ; otherwise, false.
*/
public function flag_exists ($key) {
return array_key_exists($key, $this->flags);
}
/**
* Sets the specified flag
*
* @param string $key flag key
* @param string $value flag value (optional, default value: 1)
*/
public function set_flag ($key, $value = 1) {
//Checks if flag isn't already set at this value
if ($this->flags != null && array_key_exists($key, $this->flags) && $this->flags[$key] === $value)
return;
//Saves flag to database
global $db;
$id = $db->sql_escape($this->id);
$key = $db->sql_escape($key);
$value = $db->sql_escape($value);
$sql = "REPLACE " . TABLE_PERSOS_FLAGS . " SET perso_id = '$id', flag_key = '$key', flag_value = '$value'";
if (!$db->sql_query($sql))
message_die(SQL_ERROR, "Can't save flag", '', __LINE__, __FILE__, $sql);
//Sets flag in this perso instance
$this->flags[$key] = $value;
}
/**
* Deletes the specified flag
*
* @param string $key flag key
*/
public function delete_flag ($key) {
global $db;
if (!array_key_exists($key, $this->flags)) return;
$id = $db->sql_escape($this->id);
$key = $db->sql_escape($key);
$sql = "DELETE FROM " . TABLE_PERSOS_FLAGS .
" WHERE flag_key = '$key' AND perso_id = '$id' LIMIT 1";
if (!$db->sql_query($sql))
message_die(SQL_ERROR, "Can't delete flag", '', __LINE__, __FILE__, $sql);
}
/**
* Ensures the current perso have the specified flag or exits.
*
*
* @param string $flag the flag to assert
* @param int $threshold value the flasg must stricly be greater than (optional, the default value is 0)
*
* Example:
* <code>
* $perso->set_flag('quux.foo', 1);
* //The perso wants to read quux, which we allow with the flag quux.foo
* $perso->request_flag('quux.foo'); //will be okay
*
* //The perso wants also to write quux, which we all allow if quux.foo = 2
* //The threshold will so be 1, as 2 > 1
* $perso->request_flag('quux.foo', 1); //Will exits, with a "You don't have quux.foo permission" message
* </code>
*/
public function request_flag ($flag, $threshold = 0) {
if (!array_key_exists($flag, $this->flags) || $this->flags[$flag] <= $threshold) {
message_die(HACK_ERROR, "You don't have $flag permission.", "Permissions");
}
}
/**
* Gets the specified note
*
* @param string $code the note code
* @return string the note content
*/
public function get_note ($code) {
global $db;
$id = $db->sql_escape($this->id);
$code = $db->sql_escape($code);
$sql = "SELECT note_text FROM " . TABLE_PERSOS_NOTES . " WHERE perso_id = '$id' AND note_code LIKE '$code'";
return $db->sql_query_express($sql);
}
/**
* Sets the specified note
*
* @param string $code the note code
* @param string $text the note content
*/
public function set_note ($code, $text) {
global $db;
$id = $db->sql_escape($this->id);
$code = $db->sql_escape($code);
$text = $db->sql_escape($text);
$sql = "REPLACE INTO " . TABLE_PERSOS_NOTES . " (perso_id, note_code, note_text) VALUES ('$id', '$code', '$text')";
if (!$db->sql_query($sql))
message_die(SQL_ERROR, "Can't save note", '', __LINE__, __FILE__, $sql);
}
/**
* Counts the amount of notes the perso have saved
*
* @return int the amount of notes assigned to the this perso
*/
public function count_notes () {
global $db;
$id = $db->sql_escape($this->id);
$sql = "SELECT COUNT(*) FROM " . TABLE_PERSOS_NOTES . " WHERE perso_id = '$id'";
return $db->sql_query_express($sql);
}
/*
* Determines if the specified ID is available
*
* @param integer $id The perso ID to check
* @return boolean true if the specified ID is available ; otherwise, false
*/
public static function is_available_id ($id) {
global $db;
$sql = "SELECT COUNT(*) FROM " . TABLE_PERSOS . " WHERE perso_id = $id LOCK IN SHARE MODE";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't access users table", '', __LINE__, __FILE__, $sql);
}
$row = $db->sql_fetchrow($result);
return ($row[0] == 0);
}
/**
* Generates a unique ID for the current object
*/
private function generate_id () {
do {
$this->id = rand(2001, 5999);
} while (!Perso::is_available_id($this->id));
}
/**
* Checks if the nickname is available
*
* @param string $nickname the nickname to check
*/
public static function is_available_nickname ($nickname) {
global $db;
$nickname = $db->sql_escape($nickname);
$sql = "SELECT COUNT(*) FROM " . TABLE_PERSOS . " WHERE perso_nickname LIKE '$nickname' LOCK IN SHARE MODE;";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Utilisateurs non parsable", '', __LINE__, __FILE__, $sql);
}
$row = $db->sql_fetchrow($result);
return ($row[0] == 0);
}
/**
* Counts the perso a user have
*
* @param int user_id the user ID
* @return the user's perso count
*/
public static function get_persos_count ($user_id) {
global $db;
$sql = "SELECT COUNT(*) FROM " . TABLE_PERSOS . " WHERE user_id = $user_id";
return $db->sql_query_express($sql);
}
/**
* Gets an array with all the perso of the specified user
*
* @param int $user_id the user ID
*/
public static function get_persos ($user_id) {
global $db;
$user_id = $db->sql_escape($user_id);
$sql = "SELECT perso_id FROM " . TABLE_PERSOS . " WHERE user_id = $user_id";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't get persos", '', __LINE__, __FILE__, $sql);
}
while ($row = $db->sql_fetchrow($result)) {
$persos[] = Perso::get($row[perso_id]);
}
return $persos;
}
/**
* Gets the first perso a user have
* (typically to be used when get_persos_count returns 1 to autoselect)
*
* @param int user_id the user ID
*/
public static function get_first_perso ($user_id) {
global $db;
$sql = "SELECT perso_id FROM " . TABLE_PERSOS ." WHERE user_id = $user_id LIMIT 1";
if ($perso_id = $db->sql_query_express($sql)) {
return new Perso($perso_id);
}
}
/**
* Determines wheter the perso is online
*
* @return bool true if the perso is online ; otherwise, false.
*/
public function is_online () {
global $db;
$id = $db->sql_escape($this->id);
$sql = "SELECT MAX(online) FROM " . TABLE_SESSIONS ." WHERE perso_id = $id";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to query the table", '', __LINE__, __FILE__, $sql);
}
$row = $db->sql_fetchrow($result);
return ($row[0] == 1);
}
/**
* This event method is called when the user selects a new perso
*/
public function on_select () {
//Session
set_info('perso_id', $this->id);
$this->set_flag("site.lastlogin", $_SERVER['REQUEST_TIME']);
define("PersoSelected", true);
}
/**
* This event method is called when the user logs off its account or perso
*/
public function on_logout () {
//Clears perso information in $_SESSION and session table
set_info('perso_id', null);
clean_session();
}
/**
* This event method is called when the perso is created
*/
public function on_create () {
//Notifies inviter
$this->notify_inviter();
}
/**
* Creates a new perso, from a parameter form
*
* @param int $user The user to attach the perso to
* @param Perso $perso A reference to the created perso (don't initialize it, give it a null value)
* @param array $errors A reference to the arrays containing errors (should be an empty array, or the method will always return false)
* @return boolean true if the perso has ben created ; otherwise, false
*/
public static function create_perso_from_form ($user, &$perso, &$errors) {
$perso = new Perso();
$perso->load_from_form();
$perso->user_id = $user->id;
//Validates forms
if (!$perso->name) $errors[] = lang_get("NoFullnameSpecified");
if (!$perso->race) {
$errors[] = lang_get("NoRaceSpecified");
$perso->race = "being";
}
if (!$perso->sex) $errors[] = lang_get("NoSexSpecified");
if (!$perso->nickname) {
$errors[] = lang_get("NoNicknameSpecified");
} else if (!Perso::is_available_nickname($perso->nickname)) {
$errors[] = lang_get("UnavailableNickname");
}
if (count($errors)) return false;
//Creates perso
$perso->save_to_database();
$perso->on_create();
return true;
}
/**
* Notifies the person having invited this perso
*/
public function notify_inviter() {
require_once('includes/objects/message.php');
require_once('includes/objects/invite.php');
$message = new Message();
$message->from = 0;
$message->to = invite::who_invited($this->id);
$message->text = sprintf(
lang_get('InvitePersoCreated'),
$this->name,
get_server_url() . get_url('who', $this->nickname)
);
$message->send();
}
}
-
-?>
diff --git a/includes/objects/port.php b/includes/objects/port.php
index e819b2f..81c236c 100755
--- a/includes/objects/port.php
+++ b/includes/objects/port.php
@@ -1,199 +1,197 @@
<?php
/**
* Port class
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2010-02-09 19:17 Autogenerated by Pluton Scaffolding
*
* @package Zed
* @subpackage Model
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
require_once("includes/geo/location.php");
/**
* Port class
*
* This class maps the ports table.
*
* The class also provides helper methods to handle ports at specified location.
*/
class Port {
public $id;
public $location_global;
public $location_local;
public $name;
public $hidden;
public $requiresPTA;
public $default;
/**
* Initializes a new instance
* @param int $id the primary key
*/
function __construct ($id = NULL) {
if ($id) {
$this->id = $id;
$this->load_from_database();
}
}
/**
* Loads the object Port (ie fill the properties) from the $_POST array
*/
function load_from_form () {
if (array_key_exists('location_global', $_POST)) $this->location_global = $_POST['location_global'];
if (array_key_exists('location_local', $_POST)) $this->location_local = $_POST['location_local'];
if (array_key_exists('name', $_POST)) $this->name = $_POST['name'];
if (array_key_exists('hidden', $_POST)) $this->hidden = $_POST['hidden'] ? true : false;
if (array_key_exists('requiresPTA', $_POST)) $this->requiresPTA = $_POST['requiresPTA'] ? true : false;
if (array_key_exists('default', $_POST)) $this->hidden = $_POST['default'] ? true : false;
}
/**
* Loads the object Port (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$id = $db->sql_escape($this->id);
$sql = "SELECT * FROM " . TABLE_PORTS . " WHERE port_id = '" . $id . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query ports", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "Port unkwown: " . $this->id;
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);
}
/**
* Gets the port situated exactly at the specified global location
*
* @param string $location_global the global location
* @return int the port ID
*/
static function get_port_id ($location_global) {
global $db;
$location_global = $db->sql_escape($location_global);
$sql = "SELECT port_id FROM " . TABLE_PORTS . " WHERE location_global = '$location_global'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to get ports", '', __LINE__, __FILE__, $sql);
}
if ($row = $db->sql_fetchrow($result)) {
return $row['port_id'];
}
return null;
}
/**
* Gets default port, from specified global location
*
* @param string $location_global the global location
* @return Port the port near this location ; null if there isn't port there.
*/
static function from_location ($location_global) {
$havePlace = strlen($location_global) == 9;
$port_id = null;
if ($havePlace) {
//Checks if there's a port at specified location
$port_id = self::get_port_id($location_global);
}
if ($port_id == null) {
//Nearest default port.
//If place have been specified (B0001001), we've to found elsewhere
//==> B00001%
global $db;
$loc = $db->sql_escape(substr($location_global, 0, 6));
$sql = "SELECT port_id FROM " . TABLE_PORTS . " WHERE location_global LIKE '$loc%'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't get port", '', __LINE__, __FILE__, $sql);
}
if ($row = $db->sql_fetchrow($result)) {
$port_id = $row['port_id'];
} else {
return null;
}
}
return new Port($port_id);
}
}
-
-?>
\ No newline at end of file
diff --git a/includes/objects/profile.php b/includes/objects/profile.php
index c2f1924..8f3a49f 100755
--- a/includes/objects/profile.php
+++ b/includes/objects/profile.php
@@ -1,148 +1,146 @@
<?php
/**
* Profile class
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2010-01-02 16:49 Autogenerated by Pluton Scaffolding
* Import from Azhàr
* 0.2 2010-07-05 03:56 Tags
*
* @package Zed
* @subpackage Model
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
/**
* Profile class
*
* This class maps the profiles table.
*
* The class also provides methods to handle and cache tags.
*/
class Profile {
public $perso_id;
public $text;
public $updated;
public $fixedwidth;
/**
* Initializes a new instance of the Profile class
*
* @param int $perso_id the perso ID
*/
function __construct ($perso_id) {
$this->perso_id = $perso_id;
$this->load_from_database();
}
/**
* Loads the object Profile (ie fill the properties) from the $_POST array
*/
function load_from_form ($read_boolean = true) {
if (array_key_exists('perso_id', $_POST)) $this->perso_id = $_POST['perso_id'];
if (array_key_exists('text', $_POST)) $this->text = $_POST['text'];
if (array_key_exists('updated', $_POST)) $this->updated = $_POST['updated'];
if ($read_boolean) {
if (array_key_exists('fixedwidth', $_POST)) $this->fixedwidth = $_POST['fixedwidth'];
}
}
/**
* Loads the object Profile (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$id = $db->sql_escape($this->perso_id);
$sql = "SELECT * FROM " . TABLE_PROFILES . " WHERE perso_id = '$id'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query azhar_profiles", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "Profile unkwown: " . $this->perso_id;
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 19a78a0..0a56b6c 100755
--- a/includes/objects/profilecomment.php
+++ b/includes/objects/profilecomment.php
@@ -1,131 +1,130 @@
<?php
/**
* Profile comments class
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2010-01-03 01:02 Autogenerated by Pluton Scaffolding
*
* @package Zed
* @subpackage Model
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
/**
* Profile comments class
*
* This class maps the profiles_comments table.
*/
class ProfileComment {
public $id;
public $perso_id;
public $author;
public $authorname; //should be read-only
public $date;
public $text;
/**
* Initializes a new instance of the ProfileComment class
*
* @param int $id the comment ID
*/
function __construct ($id = '') {
if ($id) {
$this->id = $id;
$this->load_from_database();
} else {
$this->date = time();
}
}
/**
* Loads the object comment (ie fill the properties) from the $_POST array
*/
function load_from_form () {
if (array_key_exists('perso_id', $_POST)) $this->perso_id = $_POST['perso_id'];
if (array_key_exists('author', $_POST)) $this->author = $_POST['author'];
if (array_key_exists('date', $_POST)) $this->date = $_POST['date'];
if (array_key_exists('text', $_POST)) $this->text = $_POST['text'];
}
/**
* Loads the object comment (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$id = $db->sql_escape($this->id);
$sql = "SELECT c.*, p.perso_name as author FROM " . TABLE_PROFILES_COMMENTS . " c, " . TABLE_PERSOS . " p WHERE c.comment_id = '$id' AND p.perso_id = c.comment_author";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query azhar_profiles_comments", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "comment unkwown: " . $this->id;
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 dca5577..91e7e5f 100755
--- a/includes/objects/profilephoto.php
+++ b/includes/objects/profilephoto.php
@@ -1,203 +1,202 @@
<?php
/**
* Profile photo class
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2010-01-03 21:00 Autogenerated by Pluton Scaffolding
* 0.2 2010-02-02 00:52 Thumbnail ImageMagick generation code
*
* @package Zed
* @subpackage Model
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
/**
* Profile photo class
*
* This class maps the profile_photos table.
*
* It also provides helper methods to handle avatars or get all the photos
* from a specified perso.
*/
class ProfilePhoto {
public $id;
public $perso_id;
public $name;
public $description;
public $avatar;
/**
* Initializes a new instance of the ProfilePhoto class
*/
function __construct ($id = '') {
if ($id) {
$this->id = $id;
$this->load_from_database();
}
}
/**
* Loads the object photo (ie fill the properties) from the $_POST array
*
* @param bool $readBoolean if false, don't read the bool avatar field to avoid to set by error false if the field weren't in the form.
*/
function load_from_form ($readBoolean = true) {
if (array_key_exists('perso_id', $_POST)) $this->perso_id = $_POST['perso_id'];
if (array_key_exists('name', $_POST)) $this->name = $_POST['name'];
if (array_key_exists('description', $_POST)) $this->description = $_POST['description'];
if ($readBoolean) {
$this->avatar = $_POST['avatar'] ? true : false;
}
}
/**
* Loads the object photo (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$id = $db->sql_escape($this->id);
$sql = "SELECT * FROM " . TABLE_PROFILES_PHOTOS . " WHERE photo_id = '" . $id . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query azhar_profiles_photos", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "photo unkwown: " . $this->id;
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/request.php b/includes/objects/request.php
index 69eb13a..9a434dc 100755
--- a/includes/objects/request.php
+++ b/includes/objects/request.php
@@ -1,125 +1,123 @@
<?php
/**
* Request class
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2011, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2011-06-13 21:16 Autogenerated by Pluton Scaffolding
*
* @package Zed
* @subpackage Model
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2011 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
/**
* Request class
*
* This class maps the requests table.
*/
class Request {
public $id;
public $code;
public $title;
public $date;
public $author;
public $to;
public $message;
public $location_global;
public $location_local;
public $status;
/**
* Initializes a new instance
* @param int $id the primary key
*/
function __construct ($id = NULL) {
if ($id) {
$this->id = $id;
$this->load_from_database();
} else {
$this->date = time();
$this->status = 'NEW';
}
}
/**
* Loads the object Request (ie fill the properties) from the $_POST array
*/
function load_from_form () {
if (array_key_exists('code', $_POST)) $this->code = $_POST['code'];
if (array_key_exists('title', $_POST)) $this->title = $_POST['title'];
if (array_key_exists('date', $_POST)) $this->date = $_POST['date'];
if (array_key_exists('author', $_POST)) $this->author = $_POST['author'];
if (array_key_exists('to', $_POST)) $this->to = $_POST['to'];
if (array_key_exists('message', $_POST)) $this->message = $_POST['message'];
if (array_key_exists('location_global', $_POST)) $this->location_global = $_POST['location_global'];
if (array_key_exists('location_local', $_POST)) $this->location_local = $_POST['location_local'];
if (array_key_exists('status', $_POST)) $this->status = $_POST['status'];
}
/**
* Loads the object Request (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$id = $db->sql_escape($this->id);
$sql = "SELECT * FROM " . TABLE_REQUESTS . " WHERE request_id = '" . $id . "'";
if (!$result = $db->sql_query($sql)) message_die(SQL_ERROR, "Unable to query requests", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "Request unkwown: " . $this->id;
return false;
}
$this->code = $row['request_code'];
$this->title = $row['request_title'];
$this->date = $row['request_date'];
$this->author = $row['request_author'];
$this->message = $row['request_message'];
$this->to = $row['request_to'];
$this->location_global = $row['location_global'];
$this->location_local = $row['location_local'];
$this->status = $row['request_status'];
return true;
}
/**
* Saves to database
*/
function save_to_database () {
global $db;
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$code = $db->sql_escape($this->code);
$title = $db->sql_escape($this->title);
$date = $db->sql_escape($this->date);
$author = $db->sql_escape($this->author);
$message = $db->sql_escape($this->message);
$to = $db->sql_escape($this->to);
$location_global = $db->sql_escape($this->location_global);
$location_local = $db->sql_escape($this->location_local);
$status = $db->sql_escape($this->status);
//Updates or inserts
$sql = "REPLACE INTO " . TABLE_REQUESTS . " (`request_id`, `request_code`, `request_title`, `request_date`, `request_author`, `request_message`, `request_to`, `location_global`, `location_local`, `request_status`) VALUES ('$id', '$code', '$title', '$date', '$author', '$message', '$to', '$location_global', '$location_local', '$status')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
if (!$this->id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
}
}
-
-?>
diff --git a/includes/objects/requestreply.php b/includes/objects/requestreply.php
index ae52b92..688bbb0 100755
--- a/includes/objects/requestreply.php
+++ b/includes/objects/requestreply.php
@@ -1,102 +1,100 @@
<?php
/**
* RequestReply class
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2011, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2011-06-13 21:20 Autogenerated by Pluton Scaffolding
*
* @package Zed
* @subpackage Model
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2011 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
/**
* RequestReply class
*
* This class maps the requests_replies table.
*/
class RequestReply {
public $id;
public $request_id;
public $author;
public $date;
public $text;
/**
* Initializes a new instance
* @param int $id the primary key
*/
function __construct ($id = NULL) {
if ($id) {
$this->id = $id;
$this->load_from_database();
}
}
/**
* Loads the object RequestReply (ie fill the properties) from the $_POST array
*/
function load_from_form () {
if (array_key_exists('request_id', $_POST)) $this->request_id = $_POST['request_id'];
if (array_key_exists('author', $_POST)) $this->author = $_POST['author'];
if (array_key_exists('date', $_POST)) $this->date = $_POST['date'];
if (array_key_exists('text', $_POST)) $this->text = $_POST['text'];
}
/**
* Loads the object RequestReply (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$id = $db->sql_escape($this->id);
$sql = "SELECT * FROM " . TABLE_REQUESTS_REPLIES . " WHERE request_reply_id = '" . $id . "'";
if (!$result = $db->sql_query($sql)) message_die(SQL_ERROR, "Unable to query requests_replies", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "RequestReply unkwown: " . $this->id;
return false;
}
$this->request_id = $row['request_id'];
$this->author = $row['request_reply_author'];
$this->date = $row['request_reply_date'];
$this->text = $row['request_reply_text'];
return true;
}
/**
* Saves to database
*/
function save_to_database () {
global $db;
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$request_id = $db->sql_escape($this->request_id);
$author = $db->sql_escape($this->author);
$date = $db->sql_escape($this->date);
$text = $db->sql_escape($this->text);
//Updates or inserts
$sql = "REPLACE INTO " . TABLE_REQUESTS_REPLIES . "(`request_reply_id`, `request_id`, `request_reply_author`, `request_reply_date`, `request_reply_text`) VALUES ('$id', '$request_id', '$author', '$date', '$text')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
if (!$this->id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
}
}
-
-?>
diff --git a/includes/objects/ship.php b/includes/objects/ship.php
index afa1ec7..31a193a 100755
--- a/includes/objects/ship.php
+++ b/includes/objects/ship.php
@@ -1,327 +1,325 @@
<?php
/**
* Ship class
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2010-02-05 18:51 Autogenerated by Pluton Scaffolding
* 0.2 2010-02-06 17:30 Ship API
*
* @package Zed
* @subpackage Model
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
require_once("perso.php");
require_once("includes/geo/location.php");
/**
* Ship class
*
* This class maps the ship table.
*
* It also provides helper methods to handle landing and fly out,
* or locate the ship.
*
* The class also provides methods for the ship API.
*/
class Ship {
/*
* ----------------------------------------------------------------------- *
* Ship class definition
* ----------------------------------------------------------------------- *
*/
public $id;
public $name;
public $location_global;
public $location_local;
public $api_key;
public $description;
private static $hashtable = array();
/**
* Initializes a new instance
*
* @param int $id the primary key
*/
function __construct ($id = null) {
if ($id) {
if (preg_match("/^S[0-9]{5}$/", $id)) {
$id = substr($id, 1);
}
$this->id = $id;
$this->load_from_database();
}
}
/**
* Initializes a new Ship instance if needed or gets already available one.
*
* @param mixed $data ship ID
* @return Ship the ship instance
*/
static function get ($data = null) {
if ($data !== null) {
if (preg_match("/^S[0-9]{5}$/", $id)) {
$id = substr($data, 1);
} else {
$id = $data;
}
//Checks in the hashtable if we already have loaded this instance
if (array_key_exists($id, self::$hashtable)) {
return self::$hashtable[$data];
}
}
$ship = new Ship($data);
return $ship;
}
/**
* Loads the object Ship (ie fill the properties) from the $_POST array
*/
function load_from_form () {
if (array_key_exists('name', $_POST)) $this->name = $_POST['name'];
if (array_key_exists('location_global', $_POST)) $this->location = $_POST['location_global'];
if (array_key_exists('location_local', $_POST)) $this->location = $_POST['location_local'];
if (array_key_exists('api_key', $_POST)) $this->api_key = $_POST['api_key'];
if (array_key_exists('description', $_POST)) $this->description = $_POST['description'];
}
/**
* Loads the object Ship (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$id = $db->sql_escape($this->id);
$sql = "SELECT * FROM ships WHERE ship_id = '" . $id . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query Ships", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "Ship unkwown: " . $this->id;
return false;
}
$this->name = $row['ship_name'];
$this->location_global = $row['location_global'];
$this->location_local = $row['location_local'];
$this->api_key = $row['api_key'];
$this->description = $row['ship_description'];
//Puts object in hashtable
self::$hashtable[$this->id] = $this;
return true;
}
/**
* Saves to database
*/
function save_to_database () {
global $db;
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$name = $db->sql_escape($this->name);
$location_global = $db->sql_escape($this->location_global);
$location_local = $db->sql_escape($this->location_local);
$api_key = $db->sql_escape($this->api_key);
$description = $db->sql_escape($this->description);
//Updates or inserts
$sql = "REPLACE INTO ships (`ship_id`, `ship_name`, `location_global`, `location_local`, `api_key`, `ship_description`) VALUES ($id, '$name', '$location_global', '$location_location', '$api_key', '$description')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
if (!$id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
}
/**
* Gets the ship code, as a string representation of the instance.
*
* @return the ship's code
*/
function __toString () {
return $this->get_code();
}
/**
* Get ships at specified location
*
* @param string $location_global global location
* @param string $location_local local location
* @return array An array of Ship items, each one a ship at the specified location
*/
static function get_ships_at ($location_global, $location_local = null) {
global $db;
//Gets ships
$sql = "SELECT ship_id, location_global, location_local FROM " . TABLE_SHIPS . " WHERE location_global IS NOT NULL";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't get ships", '', __LINE__, __FILE__, $sql);
}
$ships = array();
$location = new GeoLocation($location_global, $location_local);
while ($row = $db->sql_fetchrow($result)) {
$shipLocation = new GeoLocation($row['location_global'], $row['location_local']);
if ($location->equals($shipLocation)) {
$ships[] = self::get($row['ship_id']);
}
}
return $ships;
}
/*
* ----------------------------------------------------------------------- *
* Helper methods
* ----------------------------------------------------------------------- *
*/
/**
* Gets ship code, e.g. S00001
*
* @return string the ship code
*/
function get_code () {
return sprintf("S%05d", $this->id);
}
/**
* Determines if the ship is at a spatioport (or assimilated)
*
* @return bool true if the ship is at a spatioport ; false if the ship is in space
*/
function in_spatioport () {
return $this->location_local !== null;
}
/**
* Flies in the sip
*
* @param string $location_local the spatioport location
*
* @todo Completes location global e.g. B00001 -> B00001003
*/
function fly_in ($location_local = null) {
$this->location_local = ($location_local == null) ? 0 : $location_local;
}
/**
* Flies out.
*/
function fly_out () {
$this->location_local = null;
}
/*
* ----------------------------------------------------------------------- *
* Ship API methods
* ----------------------------------------------------------------------- *
*/
/**
* Requests the specified perso to authenticate to this ship
*
* @param mixed $perso_data the perso id or name
*/
function request_perso_authenticate ($perso_data) {
$perso = Perso::get($perso_data);
$flag = sprintf("request.api.ship.auth.%s", $this->get_code());
$perso->set_flag($flag);
$perso->set_flag("site.requests");
}
/**
* Determines if a perso is authenticated to this ship
*
* @param mixed $perso_data the perso id or name
* @return boolean true if the specified perso name is authenticated to this ship ; otherwise, false.
*/
function is_perso_authenticated ($perso_data) {
$flag = sprintf("api.ship.auth.%s", $this->get_code());
return Perso::get($perso_data)->flags[$flag] == 1;
}
/**
* Requests the specified perso to confirm the ship API session
*
* @param string $session_id a session ID provided by calling application
* @param mixed $perso_data the perso id or name
*/
function request_perso_confirm_session ($session_id, $perso_data) {
$perso = Perso::get($perso_data);
$flag = sprintf("request.api.ship.session.%s.%s", $this->get_code(), $session_id);
$perso->set_flag($flag);
$perso->set_flag("site.requests");
}
/**
* Cleans ship API temporary sessions
*/
static function clean_ship_sessions () {
//Cleans old sessions
global $db;
$sql = "DELETE FROM " . TABLE_REGISTRY . " WHERE registry_key LIKE 'api.ship.session.%' AND registry_updated < NOW() - 7200";
if (!$db->sql_query($sql))
message_die(SQL_ERROR, "Can't delete old ship API sessions", '', __LINE__, __FILE__, $sql);
}
/**
* Gets perso id from specified session
*
* @param string $session_id a session ID provided by calling application
* @return mixed the session
*/
function get_perso_from_session ($session_id) {
//Cleands old session
self::clean_ship_sessions();
//Reads api.ship.session.S00001.$session_id
//This registry key contains perso_id if it exists and valid
$key = sprintf("api.ship.session.%s.%s", $this->get_code(), $session_id);
return registry_get($key);
}
/**
* Loads a Ship object from its API key
*
* @param string $key API key GUID
* @return Ship the ship matching the API key
*/
static function from_api_key ($key) {
global $db;
$key = $db->sql_escape($key);
$sql = "SELECT * FROM ships WHERE api_key = '" . $key . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query ships", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result))
return null;
//Fills ship information
$ship = new Ship();
$ship->id = $row['ship_id'];
$ship->name = $row['ship_name'];
$ship->location = $row['ship_location'];
$ship->api_key = $row['api_key'];
$ship->description = $row['ship_description'];
return $ship;
}
}
-
-?>
diff --git a/includes/objects/user.php b/includes/objects/user.php
index 30ccb63..37de251 100755
--- a/includes/objects/user.php
+++ b/includes/objects/user.php
@@ -1,246 +1,244 @@
<?php
/**
* User class
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* [DESIGN BY CONTRACT NOTE] No more than one OpenID per user
*
* @package Zed
* @subpackage Model
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
/**
* User class
*
* This class maps the users and users_openid tables.
*
* It also provides helper methods to check if a login is available,
* or to retrieve a username from e-mail address.
*/
class User {
public $id;
public $name;
public $password;
public $active = 0;
public $actkey;
public $email;
public $regdate;
public static $hashtable_id = array();
public static $hashtable_name = array();
/**
* Initializes a new instance
*
* @param int $id the primary key
*/
function __construct ($id = null) {
if ($id) {
$this->id = $id;
$this->load_from_database();
}
}
/**
* Initializes a new User instance if needed or get already available one.
*
* @param mixed $data user ID or name
* @return User the user instance
*/
static function get ($data = null) {
if ($data) {
//Checks in the hashtables if we already have loaded this instance
if (is_numeric($data)) {
if (array_key_exists($data, User::$hashtable_id)) {
return User::$hashtable_id[$data];
}
} else {
if (array_key_exists($data, User::$hashtable_name)) {
return User::$hashtable_name[$data];
}
}
}
$user = new User($data);
return $user;
}
/**
* Loads the object User (ie fill the properties) from the $_POST array
*/
function load_from_form () {
if (array_key_exists('name', $_POST)) $this->name = $_POST['name'];
if (array_key_exists('password', $_POST)) $this->password = $_POST['password'];
if (array_key_exists('active', $_POST)) $this->active = $_POST['active'];
if (array_key_exists('actkey', $_POST)) $this->actkey = $_POST['actkey'];
if (array_key_exists('email', $_POST)) $this->email = $_POST['email'];
if (array_key_exists('regdate', $_POST)) $this->regdate = $_POST['regdate'];
}
/**
* Loads the object User (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$sql = "SELECT * FROM " . TABLE_USERS . " WHERE user_id = '" . $this->id . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query users", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "User unkwown: " . $this->id;
return false;
}
$this->name = $row['username'];
$this->password = $row['user_password'];
$this->active = $row['user_active'];
$this->actkey = $row['user_actkey'];
$this->email = $row['user_email'];
$this->regdate = $row['user_regdate'];
//Puts object in hashtables
Perso::$hashtable_id[$this->id] = $this;
Perso::$hashtable_name[$this->name] = $this;
return true;
}
/**
* Saves to database
*/
function save_to_database () {
global $db;
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$name = $db->sql_escape($this->name);
$password = $db->sql_escape($this->password);
$active = $db->sql_escape($this->active);
$actkey = $db->sql_escape($this->actkey);
$email = $db->sql_escape($this->email);
$regdate = $this->regdate ? "'" . $db->sql_escape($this->regdate) . "'" : 'NULL';
//Updates or inserts
$sql = "REPLACE INTO " . TABLE_USERS . " (`user_id`, `username`, `user_password`, `user_active`, `user_actkey`, `user_email`, `user_regdate`) VALUES ($id, '$name', '$password', '$active', '$actkey', '$email', $regdate)";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
if (!$id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
}
/**
* Updates the specified field in the database record
*/
function save_field ($field) {
global $db;
if (!$this->id) {
message_die(GENERAL_ERROR, "You're trying to update a record not yet saved in the database");
}
$id = $db->sql_escape($this->id);
$value = $db->sql_escape($this->$field);
$sql = "UPDATE " . TABLE_USERS . " SET `$field` = '$value' WHERE user_id = '$id'";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save $field field", '', __LINE__, __FILE__, $sql);
}
}
/**
* Generates a unique user id
*/
function generate_id () {
global $db;
do {
$this->id = rand(2001, 5999);
$sql = "SELECT COUNT(*) FROM " . TABLE_USERS . " WHERE user_id = $this->id LOCK IN SHARE MODE;";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't access users table", '', __LINE__, __FILE__, $sql);
}
$row = $db->sql_fetchrow($result);
} while ($row[0]);
}
/**
* Fills password field with encrypted version of the specified clear password
*
* @param string $newpassword The user's new password
*/
public function set_password ($newpassword) {
$this->password = md5($newpassword);
}
/**
* Deletes OpenID for this user
*/
public function delete_OpenID () {
$this->set_OpenID('');
}
/**
* Sets OpenID for this user
*
* @param string $url OpenID endpoint URL
*/
public function set_OpenID ($url) {
global $db;
if (!$this->id) $this->save_to_database();
$url = $db->sql_escape($url);
$sql = "DELETE FROM " . TABLE_USERS_AUTH . " WHERE auth_type = 'OpenID' AND user_id = $this->id";
if (!$db->sql_query($sql))
message_die(SQL_ERROR, "Can't delete old OpenID", '', __LINE__, __FILE__, $sql);
if ($url != '') {
$sql = "INSERT INTO " . TABLE_USERS_AUTH . " (auth_type, auth_identity, user_id) VALUES ('OpenID', '$url', $this->id)";
if (!$db->sql_query($sql))
message_die(SQL_ERROR, "Can't add new OpenID", '', __LINE__, __FILE__, $sql);
}
}
/**
* Checks if a login is available
*
* @param string $login the login to check
* @return bool true if the specified login is available ; otherwise, false.
*/
public static function is_available_login ($login) {
global $db;
$sql = "SELECT COUNT(*) FROM " . TABLE_USERS . " WHERE username LIKE '$login' LOCK IN SHARE MODE;";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Utilisateurs non parsable", '', __LINE__, __FILE__, $sql);
}
$row = $db->sql_fetchrow($result);
return ($row[0] ? false : true);
}
/**
* Gets username from specified e-mail
*
* @param string $mail the mail to search
* @return string|bool the username matching the mail if found ; otherwise, false.
*/
public static function get_username_from_email ($mail) {
global $db;
$sql = "SELECT username FROM " . TABLE_USERS . " WHERE user_email LIKE '$mail' LOCK IN SHARE MODE;";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Utilisateurs non parsable", '', __LINE__, __FILE__, $sql);
}
if ($row = $db->sql_fetchrow($result)) {
return $row['username'];
}
return false;
}
}
-
-?>
diff --git a/includes/settings/page.php b/includes/settings/page.php
index b930577..d89eb15 100755
--- a/includes/settings/page.php
+++ b/includes/settings/page.php
@@ -1,156 +1,156 @@
<?php
/**
* Settings: a settings page class
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* @package Zed
* @subpackage Settings
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
require_once("setting.php");
/**
* This class maps the page XML element, from our Settings XML schema
*
* <page id="account" title="Account">
* <setting ...>
* ...
* </setting>
* <setting ...>
* ...
* </setting>
* <page>
*
* It provides method to print a form built from this page and to handle form.
*/
class SettingsPage {
/**
* The page ID
*
* This property maps the id attribute from the page XML tag
*
* @var string the page ID
*/
public $id;
/**
* The page's title
*
* This property maps the title attribute from the page XML tag
*
* @var string the page title
*/
public $title;
/**
* The settings
*
* This property is an array of Setting items and maps the <setting> tags
* @var Array
*/
public $settings = array();
/**
* Initializes a new instance of SettingsPage class
*
* @param string $id the page ID
*/
function __construct ($id) {
$this->id = $id;
}
/**
* Initializes a settings page from an SimpleXMLElement XML fragment
*
* @param SimpleXMLElement $xml the XML fragment
* @return SettingsPage the section instance
*/
static function from_xml ($xml) {
//Reads attributes
$id = ''; $title = '';
foreach ($xml->attributes() as $key => $value) {
switch ($key) {
case 'title':
case 'id':
$$key = (string)$value;
break;
default:
message_die(GENERAL_ERROR, "Unknown attribute: $key = \"$value\"", "Settings error");
}
}
//id attribute is mandatory
if (!$id) {
message_die(GENERAL_ERROR, "Section without id. Please add id='' in <section> tag", "Story error");
}
//Initializes new SettingsPage instance
$page = new SettingsPage($id);
$page->title = $title;
//Gets settings
if ($xml->setting) {
foreach ($xml->setting as $settingXml) {
$setting = Setting::from_xml($settingXml);
$page->settings[$setting->key] = $setting;
}
}
return $page;
}
/**
* Handles form reading $_POST array, set new settings values and saves.
*
* @param Array $errors an array where the errors will be filled
* @return boolean true if there isn't error ; otherwise, false.
*/
function handle_form (&$errors = array()) {
$objects = array();
//Sets new settings values
foreach ($this->settings as $setting) {
$value = $_POST[$setting->key];
if ($setting->field == "password" && !$value) {
//We don't erase passwords if not set
continue;
}
//If the setting value is different of current one, we update it
$currentValue = $setting->get();
if ($setting->field == "checkbox" || $currentValue != $value) {
if (!$setting->set($value)) {
$errors[] = $setting->lastError ? $setting->lastError : "An error have occured in $setting->key field.";
}
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 557eeae..da7554f 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>
</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>
</setting>
<setting id="nickname">
<key>Nickname</key>
<field>validationtext</field>
<regExp>[a-z][a-z0-9 ]+</regExp>
<object>CurrentPerso</object>
<property>nickname</property>
</setting>
<setting id="race">
<key>Race</key>
<field>text</field>
<object>CurrentPerso</object>
<property>race</property>
</setting>
<setting id="sex">
<key>Sex</key>
<field>filteredlist</field>
<object>CurrentPerso</object>
<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>
diff --git a/includes/settings/setting.php b/includes/settings/setting.php
index f1b566f..8b5c7b8 100755
--- a/includes/settings/setting.php
+++ b/includes/settings/setting.php
@@ -1,175 +1,174 @@
<?php
/**
* Settings: an individual setting class
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* @package Zed
* @subpackage Settings
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
/**
* Setting class
*
* This class map the <setting> XML block, from our settings XML format
*/
class Setting {
public $key;
//Rendering variables
public $field;
public $regExp;
public $choices;
//get/set variables
public $object;
private $property;
private $method;
private $handler;
//error variable
public $lastError;
/**
* Gets the current setting value
*
* @return string the setting value
*/
function get () {
//1 - Evaluates custom handler
if (array_key_exists('get', $this->handler)) {
return eval($this->handler['get']);
}
//2 - Gets object property
if ($this->object && $property = $this->property) {
return $GLOBALS[$this->object]->$property;
}
if ($this->field == "password") {
//Okay not to have a value for password fields
return;
}
message_die(GENERAL_ERROR, "Setting $this->key haven't any get indication. Please set <object> and <property> / or a custom <handler><get></get></handler> block.", "Settings error");
}
/**
* Sets a new value
*
* @param $value the setting new value
* @return boolean true if the setting have been successfully set ; otherwise, false.
*/
function set ($value) {
//Validates data
if ($this->regExp) {
if (!preg_match('/^' . $this->regExp . '$/', $value)) {
$this->lastError = "Invalid format for $this->key setting";
return false;
}
}
//Tries to set value
//1 - Evaluates custom handler
if (array_key_exists('set', $this->handler)) {
return eval($this->handler['set']);
}
//2 - Calls object method
//3 - Sets object property
if ($this->object) {
$object = $GLOBALS[$this->object];
if ($this->method) {
return call_user_func(array($object, $this->method), $value);
} elseif ($property = $this->property) {
$object->$property = $value;
return true;
}
}
message_die(GENERAL_ERROR, "Setting $this->key haven't any set indication. Please set <object> (and wheter <method>, whether <property>) or a custom <handler><set></set></handler> block.", "Settings error");
}
/**
* 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 bda0b54..1503736 100755
--- a/includes/settings/settings.php
+++ b/includes/settings/settings.php
@@ -1,84 +1,83 @@
<?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 b86eb6d..4b2ff30 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 5922e1d..01bdfa4 100755
--- a/includes/story/hook.php
+++ b/includes/story/hook.php
@@ -1,101 +1,99 @@
<?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
*/
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 0bc2d83..ed9637f 100755
--- a/includes/story/hook_demo.php
+++ b/includes/story/hook_demo.php
@@ -1,77 +1,76 @@
<?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 53e761a..8f03fd3 100755
--- a/includes/story/hook_spatioport.php
+++ b/includes/story/hook_spatioport.php
@@ -1,132 +1,130 @@
<?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);
}
}
-
-?>
diff --git a/includes/story/section.php b/includes/story/section.php
index c08e658..0a7912c 100755
--- a/includes/story/section.php
+++ b/includes/story/section.php
@@ -1,160 +1,158 @@
<?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 23c1959..b3adc6c 100755
--- a/includes/story/story.php
+++ b/includes/story/story.php
@@ -1,135 +1,131 @@
<?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
*/
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 816bd98..f3b1918 100755
--- a/includes/travel/place.php
+++ b/includes/travel/place.php
@@ -1,152 +1,150 @@
<?php
/**
* TravelPlace class
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* 0.1 2010-07-19 22:10 DcK
*
* @package Zed
* @subpackage Travel
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
/**
* TravelPlace class
*
* The TravelPlace class is a set of rules determining which moves are valid
* in a specific place.
*
* @see GeoPlace
*
*/
class TravelPlace {
/**
* The place code
*
* @var string
*/
public $code;
/**
* Determines if any local location move is valid
*
* @var bool
*/
public $freeLocalMove = false;
/**
* Array of strings, each item another place reachable
*
* This matches GlobalTravelTo XML tags.
*
* @var Array
*/
public $globalTravelTo = array();
/**
* Aray of array, containing [location, alias, name] entries
*
* 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 913d027..98ba92f 100755
--- a/includes/travel/travel.php
+++ b/includes/travel/travel.php
@@ -1,175 +1,173 @@
<?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
*/
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)
if (!array_key_exists($from->global, $this->globalTravelTo)) {
return false;
}
$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) {
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/index.php b/index.php
index b4750fa..369d3a5 100644
--- a/index.php
+++ b/index.php
@@ -1,201 +1,200 @@
<?php
/**
* Application entry point
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* @package Zed
* @subpackage EntryPoints
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
* @todo Consider to split the different tasks (especially
* perso select/create into several files)
*/
////////////////////////////////////////////////////////////////////////////////
///
/// Initialization
///
//Keruald (formelly Pluton) library
include('includes/core.php');
//Session
$IP = encode_ip($_SERVER["REMOTE_ADDR"]);
require_once('includes/story/story.php'); //this class can be stored in session
session_start();
$_SESSION[ID] = session_id();
session_update(); //updates or creates the session
include("includes/login.php"); //login/logout
$CurrentUser = get_logged_user(); //Gets current user infos
//Gets current perso
require_once('includes/objects/perso.php');
if ($perso_id = $CurrentUser->session['perso_id']) {
$CurrentPerso = new Perso($perso_id);
}
//Skin and accent to load
define('THEME', $CurrentUser->session['Skin']);
define('ACCENT', $CurrentUser->session['Skin_accent']);
//Loads Smarty
require('includes/Smarty/Smarty.class.php');
$smarty = new Smarty();
$current_dir = dirname(__FILE__);
$smarty->setTemplateDir($current_dir . '/skins/' . THEME);
$smarty->compile_dir = CACHE_DIR . '/compiled';
$smarty->cache_dir = CACHE_DIR;
$smarty->config_dir = $current_dir;
$smarty->config_vars['StaticContentURL'] = $Config['StaticContentURL'];
//Loads language files
initialize_lang();
lang_load('core.conf');
//Gets URL
$url = get_current_url_fragments();
//If the user isn't logged in (is anonymous), prints login/invite page & dies.
if ($CurrentUser->id < 1000) {
include('controllers/anonymous.php');
exit;
}
////////////////////////////////////////////////////////////////////////////////
///
/// Perso (=character) selector
///
//Handles form
if ($_POST['form'] == 'perso.create') {
$perso = null; $errors = array();
if (Perso::create_perso_from_form($CurrentUser, $perso, $errors)) {
//Notifies and logs in
$smarty->assign('NOTIFY', lang_get('NewCharacterCreated'));
$CurrentPerso = $perso;
set_info('perso_id', $perso->id);
$CurrentPerso->set_flag("site.lastlogin", $_SERVER['REQUEST_TIME']);
} else {
//Prints again perso create form, so the user can fix it
$smarty->assign('WAP', join("<br />", $errors));
$smarty->assign('perso', $perso);
}
}
if ($_GET['action'] == 'perso.logout' && $CurrentPerso != null) {
//User wants to change perso
$CurrentPerso->on_logout();
$CurrentPerso = null;
} elseif ($_GET['action'] == 'perso.select') {
//User has selected a perso
$CurrentPerso = new Perso($_GET['perso_id']);
if ($CurrentPerso->user_id != $CurrentUser->id) {
//User have made an error in the URL
message_die(HACK_ERROR, "This isn't your perso.");
}
$CurrentPerso->on_select();
}
if (!$CurrentPerso) {
switch ($count = Perso::get_persos_count($CurrentUser->id)) {
case 0:
//User have to create a perso
$smarty->display("perso_create.tpl");
exit;
case 1:
//Autoselects only perso
$CurrentPerso = Perso::get_first_perso($CurrentUser->id);
$CurrentPerso->on_select();
break;
default:
//User have to pick a perso
$persos = Perso::get_persos($CurrentUser->id);
$smarty->assign("PERSOS", $persos);
$smarty->display("perso_select.tpl");
$_SESSION['UserWithSeveralPersos'] = true;
exit;
}
}
//Assigns current perso object as Smarty variable
$smarty->assign('CurrentPerso', $CurrentPerso);
////////////////////////////////////////////////////////////////////////////////
///
/// Tasks to execute before calling the URL controller:
/// - assert the perso is somewhere
/// - executes the smartline
///
//If the perso location is unknown, ejects it to an asteroid
if (!$CurrentPerso->location_global) {
require_once('includes/geo/place.php');
$smarty->assign('NOTIFY', lang_get('NewLocationNotify'));
$CurrentPerso->move_to(GeoPlace::get_start_location());
}
//SmartLine
include("includes/SmartLine/ZedSmartLine.php");
//Redirects user to user request controller if site.requests flag on
if (defined('PersoSelected') && array_key_exists('site.requests', $CurrentPerso->flags) && $CurrentPerso->flags['site.requests']) {
include('controllers/persorequest.php');
}
////////////////////////////////////////////////////////////////////////////////
///
/// Calls the specific controller to serve the requested page
///
switch ($controller = $url[0]) {
case '':
include('controllers/home.php');
break;
case 'builder':
case 'explore':
case 'page':
case 'request':
case 'settings':
case 'ship':
include("controllers/$controller.php");
break;
case 'who':
include('controllers/profile.php'); //Azhàr controller
break;
case 'push':
include('controllers/motd.php'); //Azhàr controller
break;
case 'quux':
//It's like a test/debug console/sandbox, you put what you want into
if (file_exists('dev/quux.php')) {
include('dev/quux.php');
} else {
message_die(GENERAL_ERROR, "Quux lost in Hollywood.", "Nay");
}
break;
default:
//TODO: returns a prettier 404 page
header("Status: 404 Not Found");
dieprint_r($url, 'Unknown URL');
}
-

File Metadata

Mime Type
text/x-diff
Expires
Sun, Nov 24, 05:27 (12 h, 57 m ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
20931
Default Alt Text
(400 KB)

Event Timeline