Page MenuHomeCode

No OneTemporary

diff --git a/api.php b/api.php
index c601d6c..3253188 100644
--- a/api.php
+++ b/api.php
@@ -1,332 +1,332 @@
<?php
/**
* API entry point
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* @package Zed
* @subpackage EntryPoints
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
* @todo Consider to output documentation on / and /ship queries
* @todo /app/getdata
*/
//API preferences
define('URL', 'http://' . $_SERVER['HTTP_HOST'] . '/index.php');
//Pluton library
require_once('includes/core.php');
require_once('includes/config.php');
//API libs
require_once('includes/api/api_helpers.php');
require_once('includes/api/cerbere.php');
//Use our URL controller method if you want to mod_rewrite the API
$Config['SiteURL'] = get_server_url() . $_SERVER["PHP_SELF"];
$url = get_current_url_fragments();
switch ($module = $url[0]) {
/* -------------------------------------------------------------
Site API
/time
/location
/coordinates
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case '':
//Nothing to do
//TODO: offer documentation instead
die();
case 'time':
//Hypership time
api_output(get_hypership_time(), "time");
break;
case 'location':
//Checks credentials
cerbere();
//Gets location info
require_once("includes/geo/location.php");
$location = new GeoLocation($url[1], $url[2]);
api_output($location, "location");
break;
case 'coordinates':
//Checks credentials
cerbere();
//Get coordinates
api_output(GeoGalaxy::getCoordinates(), 'galaxy', 'object');
break;
/* -------------------------------------------------------------
Ship API
/authenticate
/appauthenticate
/appauthenticated
/move
/land
/flyout
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case 'ship':
//Ship API
//Gets ship from Ship API key (distinct of regular API keys)
require_once('includes/objects/ship.php');
$ship = Ship::from_api_key($_REQUEST['key']) or cerbere_die("Invalid ship API key");
switch ($command = $url[1]) {
case '':
//Nothing to do
//TODO: offer documentation instead
die();
case 'authenticate':
//TODO: web authenticate
break;
case 'appauthenticate':
//Allows desktop application to authenticate an user
$tmp_session_id = $url[2] or cerbere_die("/appauthenticate/ must be followed by any session identifier");
if ($_REQUEST['name']) {
//Perso will be offered auth invite at next login.
//Handy for devices like PDA, where it's not easy to auth.
$perso = new Perso($_REQUEST['name']);
if ($perso->lastError) {
cerbere_die($perso->lastError);
}
if (!$ship->is_perso_authenticated($perso->id)) {
$ship->request_perso_authenticate($perso->id);
}
$ship->request_perso_confirm_session($tmp_session_id, $perso->id);
} else {
//Delivers an URL. App have to redirects user to this URL
//launching a browser or printing the link.
$ship_code = $ship->get_code();
registry_set("api.ship.session.$ship_code.$tmp_session_id", -1);
$url = get_server_url() . get_url() . "?action=api.ship.appauthenticate&session_id=" . $tmp_session_id;
api_output($url, "URL");
}
break;
case 'appauthenticated':
//Checks the user authentication
$tmp_session_id = $url[2] or cerbere_die("/appauthenticated/ must be followed by any session identifier you used in /appauthenticate");
$perso_id = $ship->get_perso_from_session($tmp_session_id);
if (!$isPersoAuth = $ship->is_perso_authenticated($perso_id)) {
//Global auth not ok/revoked.
$auth->status = -1;
} else {
$perso = Perso::get($perso_id);
$auth->status = 1;
$auth->perso->id = $perso->id;
$auth->perso->nickname = $perso->nickname;
$auth->perso->name = $perso->name;
//$auth->perso->location = $perso->location;
//Is the perso on board? Yes if its global location is S...
$auth->perso->onBoard = (
$perso->location_global[0] == 'S' &&
substr($perso->location_global, 1, 5) == $ship->id
);
if ($auth->perso->onBoard) {
//If so, give local location
$auth->perso->location_local = $perso->location_local;
}
}
api_output($auth, "auth");
break;
case 'move':
//Moves the ship to a new location, given absolute coordinates
//TODO: handle relative moves
if (count($url) < 2) {
cerbere_die("/move/ must be followed by a location expression");
}
//Gets location class
//It's allow: (1) to normalize locations between formats
// (2) to ensure the syntax
//==> if the ship want to communicate free forms coordinates, must be added on GeoLocation a free format
try {
$location = new GeoLocation($url[2]);
} catch (Exception $ex) {
$reply->success = 0;
$reply->error = $ex->getMessage();
api_output($reply, "move");
break;
}
$ship->location_global = $location->global;
$ship->save_to_database();
$reply->success = 1;
$reply->location = $ship->location;
api_output($reply, "move");
break;
case 'land':
case 'flyin':
//Flies in
try {
$location = new GeoLocation($location);
} catch (Exception $ex) {
$reply->success = 0;
$reply->error = $ex->getMessage();
api_output($reply, "land");
break;
}
break;
case 'flyout':
//Flies out
break;
}
break;
/* -------------------------------------------------------------
Application API
/checkuserkey
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case 'app':
//Application API
require_once("includes/objects/application.php");
$app = Application::from_api_key($_REQUEST['key']) or cerbere_die("Invalid application API key");
switch ($command = $url[1]) {
case '':
//Nothing to do
//TODO: offer documentation instead
die();
case 'checkuserkey':
if (count($url) < 2) {
cerbere_die("/checkuserkey/ must be followed by an user key");
}
$reply = (boolean)$app->get_perso_id($url[2]);
api_output($reply, "check");
break;
case 'pushuserdata':
if (count($url) < 3) {
cerbere_die("/pushuserdata/ must be followed by an user key");
}
$perso_id = $app->get_perso_id($url[2]) or cerbere_die("Invalid application user key");
//then, falls to 'pushdata'
case 'pushdata':
- $data_id = $_REQUEST['data'] ? $_REQUEST['data'] : new_guid();
+ $data_id = $_REQUEST['data'] ?: new_guid();
//Gets data
switch ($mode = $_REQUEST['mode']) {
case '':
cerbere_die("Add in your data posted or in the URL mode=file to read data from the file posted (one file per api call) or mode=request to read data from \$_REQUEST['data'].");
case 'request':
$data = $_REQUEST['data'];
$format = "raw";
break;
case 'file':
$file = $_FILES['datafile']['tmp_name'] or cerbere_die("File is missing");
if (!is_uploaded_file($file)) {
cerbere_die("Invalid form request");
}
$data = "";
if (preg_match('/\.tar$/', $file)) {
$format = "tar";
$data = file_get_contents($file);
} elseif (preg_match('/\.tar\.bz2$/', $file)) {
$format = "tar";
} elseif (preg_match('/\.bz2$/', $file)) {
$format = "raw";
} else {
$format = "raw";
$data = file_get_contents($file);
}
if ($data === "") {
//.bz2
$bz = bzopen($file, "r") or cerbere_die("Couldn't open $file");
while (!feof($bz)) {
$data .= bzread($bz, BUFFER_SIZE);
}
bzclose($bz);
}
unlink($file);
break;
default:
cerbere_die("Invalid mode. Expected: file, request");
}
//Saves data
global $db;
$data_id = $db->sql_escape($data_id);
$data = $db->sql_escape($data);
- $perso_id = $perso_id ? $perso_id : 'NULL';
+ $perso_id = $perso_id ?: 'NULL';
$sql = "REPLACE INTO applications_data (application_id, data_id, data_content, data_format, perso_id) VALUES ('$app->id', '$data_id', '$data', '$format', $perso_id)";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't save data", '', __LINE__, __FILE__, $sql);
}
//cerbere_die("Can't save data");
//Returns
api_output($data_id);
break;
case 'getuserdata':
// /api.php/getuserdata/data_id/perso_key
// /api.php/getdata/data_id
if (count($url) < 3) {
cerbere_die("/getuserdata/ must be followed by an user key");
}
$perso_id = $app->get_perso_id($url[2]) or cerbere_die("Invalid application user key");
//then, falls to 'getdata'
case 'getdata':
if (count($url) < 2) {
cerbere_die('/' . $url[0] . '/ must be followed by the data ID');
}
if (!$perso_id) {
$perso_id = 'NULL';
}
$data_id = $db->sql_escape($url[1]);
$sql = "SELECT data_content FROM applications_data WHERE application_id = '$app->id' AND data_id = '$data_id' AND perso_id = $perso_id";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to query the table", '', __LINE__, __FILE__, $sql);
}
while ($row = $db->sql_fetchrow($result)) {
}
break;
default:
echo "Unknown module:";
dprint_r($url);
break;
}
break;
default:
echo "Unknown module:";
dprint_r($url);
break;
}
diff --git a/controllers/profile.php b/controllers/profile.php
index ae7b7d3..e11fad7 100644
--- a/controllers/profile.php
+++ b/controllers/profile.php
@@ -1,353 +1,353 @@
<?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 profile
* /who/edit/account edits its account (disabled on Zed, cf. settings),
* /who/edit/photo(s) manages its profile's photos,
* /who/edit/photo/edit/<photo id> edits a photo properties,
* /who/edit/photo/delete/<photo id> deletes a photo,
* /who/edit/photo/avatar/<photo id> promotes a photo to avatar.
*
* The following views are used:
* profile.tpl,
* profile_edit.tpl,
* user_account.tpl,
* profile_photo.tpl,
* profile_photo_edit.tpl.
*
* The following models are used:
* Profile,
* ProfilePhoto,
* ProfileComment.
*
* The view profile_tags.tpl is indirectly used by the Profile model.
*
* This code is maintained in // with Azhàr.
*
* @package Zed
* @subpackage Controllers
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
//Loads language file
lang_load('profile.conf');
//Gets perso nickname from URL
$who = $url[1];
switch ($who) {
case 'edit':
$mode = 'edit';
$who = $CurrentPerso->nickname;
break;
case 'random':
$mode = 'view';
$who = $db->sql_query_express("SELECT perso_id FROM " . TABLE_PROFILES . " ORDER BY rand() LIMIT 1");
break;
default:
$mode = 'view';
}
if (!$who) {
message_die(GENERAL_ERROR, "Who?", "URL error");
}
//Libs
require_once('includes/objects/profile.php');
require_once('includes/objects/profilecomment.php');
require_once('includes/objects/profilephoto.php');
//Gets perso information
require_once('includes/objects/perso.php');
$perso = Perso::get($who);
if ($perso->lastError) {
message_die(GENERAL_ERROR, $perso->lastError, "Error");
}
$smarty->assign('perso', $perso);
//Gets profile
$profile = new Profile($perso->id);
//Handles form
if ($_POST['EditProfile']) {
$profile->load_from_form();
$profile->updated = time();
$profile->save_to_database();
$mode = 'view';
} elseif ($_POST['UserAccount']) {
$smarty->assign('WAP', "This form have been deprecated. You can write instead settings in the SmartLine");
} elseif ($_POST['message_type'] == 'private_message') {
//Sends a message
require_once('includes/objects/message.php');
$msg = new Message();
$msg->from = $CurrentPerso->id;
$msg->to = $perso->id;
$msg->text = $_POST['message'];
$msg->send();
if ($msg->from == $msg->to) {
$smarty->assign('NOTIFY', lang_get('MessageSentSelf'));
} else {
$smarty->assign('NOTIFY', lang_get('MessageSent'));
}
} elseif ($_POST['message_type'] == 'profile_comment') {
//New profile comment
$comment = new ProfileComment();
$comment->author = $CurrentPerso->id;
$comment->perso_id = $perso->id;
$comment->text = $_POST['message'];
$comment->publish();
$smarty->assign('NOTIFY', lang_get('CommentPublished'));
} elseif ($_FILES['photo']) {
#We've a file !
$hash = md5(microtime() . serialize($_FILES));
$extension = get_extension($_FILES['photo']['name']);
$filename = $CurrentPerso->id . '_' . $hash . '.' . $extension;
#We ignore $_FILES[photo][error] 4, this means no file has been uploaded
#(so user doesn't want upload a new file)
#See http:/www.php.net/features.file-upload and http://www.php.net/manual/en/features.file-upload.errors.php about common errors
#Not valid before PHP 4.2.0
switch ($_FILES['photo']['error']) {
case 0:
#There is no error, the file uploaded with success.
if (!move_uploaded_file($_FILES['photo']['tmp_name'], PHOTOS_DIR . '/' . $filename)) {
$errors[] = "Upload successful, but error saving it.";
} else {
//Attaches the picture to the profile
$photo = new ProfilePhoto();
$photo->name = $filename;
$photo->perso_id = $CurrentPerso->id;
$photo->description = $_POST['description'];
if ($photo->avatar) {
$photo->promote_to_avatar();
}
$photo->save_to_database();
//Generates thumbnail
if (!$photo->generate_thumbnail()) {
$smarty->assign('WAP', "Error generating thumbnail.");
}
$smarty->assign('NOTIFY', lang_get('PhotoUploaded'));
$mode = 'view';
}
break;
case 1:
$errors[] = "The file is too large.";
break;
#TODO : more explicit error messages
default:
$errors[] = "Unknown error (#" . $_FILES['photo']['error'] . ")";
break;
}
if (count($errors)) {
$smarty->assign('WAP', join('<br />', $errors));
}
} 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);
+ $smarty->assign('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', ['prototype.js', 'effects.js', 'lightbox.js']);
$smarty->assign('PICS', $photos);
}
//Serves header
$css[] = THEME . "/profile.css";
$smarty->assign('PAGE_CSS', $css);
$smarty->assign('PAGE_TITLE', $perso->name);
include('header.php');
//Serves content
if ($template) {
$smarty->display($template);
}
//Serves footer
include('footer.php');
diff --git a/controllers/usersearch.php b/controllers/usersearch.php
index eac0ad1..4a0f4a3 100644
--- a/controllers/usersearch.php
+++ b/controllers/usersearch.php
@@ -1,118 +1,118 @@
<?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;
+ $name = $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');
diff --git a/includes/content/file.php b/includes/content/file.php
index 9a23857..9890072 100644
--- a/includes/content/file.php
+++ b/includes/content/file.php
@@ -1,284 +1,284 @@
<?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;
+ return $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 unknown: " . $this->id;
return false;
}
$this->load_from_row($row);
return true;
}
/**
* Loads the object from row
*/
function load_from_row ($row) {
$this->id = $row['content_id'];
$this->path = $row['content_path'];
$this->user_id = $row['user_id'];
$this->perso_id = $row['perso_id'];
$this->title = $row['content_title'];
}
/**
* Saves to database
*/
function save_to_database () {
global $db;
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$path = $db->sql_escape($this->path);
$user_id = $db->sql_escape($this->user_id);
$perso_id = $db->sql_escape($this->perso_id);
$title = $db->sql_escape($this->title);
//Updates or inserts
$sql = "REPLACE INTO content_files (`content_id`, `content_path`, `user_id`, `perso_id`, `content_title`) VALUES ($id, '$path', '$user_id', '$perso_id', '$title')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't save content", '', __LINE__, __FILE__, $sql);
}
if (!$this->id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
}
/* -------------------------------------------------------------
File handling helper methods
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
* Determines if the extension is valid
*
* @param string $ext The extension (without dot)
* @return boolean true if this extension is valid ; otherwise, false.
*/
function is_valid_extension ($ext) {
$ext = strtolower($ext);
return (is_valid_image_extension($ext) || is_valid_audio_extension($ext)
|| is_valid_video_extension($ext));
}
/**
* Determines if the extension is valid
*
* @param string $ext The extension (without dot)
* @return boolean true if this extension is valid ; otherwise, false.
*/
function is_valid_image_extension ($ext) {
switch ($ext = strtolower($ext)) {
//Pictures
case 'jpg':
case 'gif':
case 'png':
case 'bmp':
case 'xbm':
return true;
//Denied extension
default:
return false;
}
}
/**
* Determines if the extension is a valid audio file one
*
* @param string $ext The extension (without dot)
* @return boolean true if this extension is valid ; otherwise, false.
*/
function is_valid_audio_extension ($ext) {
switch ($ext = strtolower($ext)) {
//Sounds (HTML5 <audio> formats)
case 'mp3':
case 'ogg':
case 'aac':
case 'wav':
case 'wave':
return true;
//Denied extension
default:
return false;
}
}
/**
* Determines if the extension is a valid video file one
*
* @param string $ext The extension (without dot)
* @return boolean true if this extension is valid ; otherwise, false.
*
* @todo add H.264 extension
*/
function is_valid_video_extension ($ext) {
switch ($ext = strtolower($ext)) {
//Video (HTML5 <video> formats)
case 'ogg':
case 'webm':
return true;
//Denied extension
default:
return false;
}
}
/**
* Creates a directory
*
* @param string $dir the directory to create
*
* @todo set contents chmod in config
*/
function create_directory ($directory) {
if (!file_exists($directory)) {
@mkdir($directory); //Creates new directory, chmod 777
}
}
/**
* Handles uploaded file
*
* @return bool true if the file have been handled
*/
function handle_uploaded_file ($fileArray) {
if (count($fileArray) && $fileArray['error'] == 0) {
$this->create_directory("content/users/$this->user_id");
$this->path = "content/users/$this->user_id/$fileArray[name]";
if (!self::is_valid_extension(get_extension($fileArray[name]))) {
return false;
}
if (move_uploaded_file($fileArray['tmp_name'], $this->path)) {
return true;
} else {
$this->path = null;
return false;
}
} else {
return false;
}
}
/**
* Generates a thumbnail using ImageMagick binary
*
* @return boolean true if the thumbnail command returns 0 as program exit code ; otherwise, false
*/
function generate_thumbnail () {
global $Config;
//Builds thumbnail filename
$sourceFile = $this->path;
$pos = strrpos($this->path, '.');
$thumbnailFile = substr($sourceFile, 0, $pos) . 'Square' . substr($sourceFile, $pos);
//Executes imagemagick command
$command = $Config['ImageMagick']['convert'] . " \"$sourceFile\" -resize 162x162 \"$thumbnailFile\"";
@system($command, $code);
//Returns true if the command have exited with errorcode 0 (= ok)
return ($code == 0);
}
}
diff --git a/includes/content/location.php b/includes/content/location.php
index 05acac4..13b9eee 100644
--- a/includes/content/location.php
+++ b/includes/content/location.php
@@ -1,233 +1,233 @@
<?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 parameters:
* - location_global
* - location_local
* - location_k, an index for the content at the specified location
*
* This class allows to get or set the content_id at this
* (global, local, k) location.
*
* This class also provides a static helper method to
* get local content from a specific location.
*/
class ContentLocation {
/* -------------------------------------------------------------
Properties
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
public $location_global = null;
public $location_local = null;
public $location_k = null;
public $content_id;
/* -------------------------------------------------------------
Constructor, __toString
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
* Initializes a new ContentLocation instance
*
* @param string $location_global the global location
* @param string $location_local the local location
* @param int $location_k the item indice for the specified location
*/
function __construct ($location_global = null, $location_local = null, $location_k = null) {
$this->location_global = $location_global;
$this->location_local = $location_local;
if ($location_k) {
$this->location_k = $location_k;
$this->load_from_database();
} else {
$this->location_k = self::get_free_location_k($location_global, $location_local);
}
}
/**
* Returns a string representation of current Content instance
*
* @return string the content title or path if title is blank.
*/
function __toString () {
- $location_global = $this->location_global ? $this->location_global : '?';
- $location_local = $this->location_local ? $this->location_local : '?';
- $location_k = $this->location_k ? $this->location_k : '?';
+ $location_global = $this->location_global ?: '?';
+ $location_local = $this->location_local ?: '?';
+ $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 unknown: " . $this->content_id;
return false;
}
$this->load_from_row($row);
return true;
}
/**
* Loads the object from row
*/
function load_from_row ($row) {
$this->content_id = $row['content_id'];
$this->location_global = $row['location_global'];
$this->location_local = $row['location_local'];
$this->location_k = $row['location_k'];
}
/**
* Saves to database
*/
function save_to_database () {
global $db;
$location_global = "'" . $db->sql_escape($this->location_global) . "'";
$location_local = "'" . $db->sql_escape($this->location_local) . "'";
$location_k = "'" . $db->sql_escape($this->location_k) . "'";
$content_id = $this->content_id ? "'" . $db->sql_escape($this->content_id) . "'" : 'NULL';
$sql = "REPLACE INTO content_locations (location_global, location_local, location_k, content_id) VALUES ($location_global, $location_local, $location_k, $content_id)";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't save content location", '', __LINE__, __FILE__, $sql);
}
}
/* -------------------------------------------------------------
Helper methods
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
* Gets the next k free value for the specified location
*
* @param string $location_global the global location
* @param string $location_local the local location
*
* @param int $location_k the next free local content indice
*/
function get_free_location_k ($location_global, $location_local) {
$location_global = "'" . $db->sql_escape($location_global) . "'";
$location_local = "'" . $db->sql_escape($location_local) . "'";
$sql = "SELECT MAX(location_k) + 1 FROM content_locations WHERE location_global = '$location_global' AND location_local = '$location_local'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't get content location k", '', __LINE__, __FILE__, $sql);
}
$row = $db->sql_fetchrow($result);
return $row[0];
}
/**
* Deletes this content location from the database
*/
function delete() {
$location_global = "'" . $db->sql_escape($this->location_global) . "'";
$location_local = "'" . $db->sql_escape($this->location_local) . "'";
$location_k = "'" . $db->sql_escape($this->location_k) . "'";
$sql = "DELETE FROM content_locations WHERE location_global = '$location_global' AND location_local = '$location_local' AND location_k = '$location_k' LIMIT 1";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't delete current content location", '', __LINE__, __FILE__, $sql);
}
}
/**
* Moves the content into new location
*
* @param string $location_global the target global location
* @param string $location_local the target local location
* @param int $location_k the target local content indice [facultative]
*/
function move ($location_global, $location_local, $location_k = null) {
if ($this->content_id) {
$this->delete();
}
if ($location_k) {
$this->location_k = $location_k;
} else {
$this->location_k = self::get_free_location_k($location_global, $location_local);
}
if ($this->content_id) {
$this->save_to_database();
}
}
/* -------------------------------------------------------------
Gets content
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
* Gets content at specified location
*
* @param string $location_global global content location
* @param string $location_local local content location
* @return Array array of ContentFile instances
*
* The returned array indices are the local_k.
*/
static function get_local_content ($location_global, $location_local) {
global $db;
//Get contents at this location
$location_global = $db->sql_escape($location_global);
$location_local = $db->sql_escape($location_local);
$sql = "SELECT c.* FROM content c WHERE c.location_global = '$location_global' AND c.location_local = '$location_local' ORDER BY location_k ASC";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't get content", '', __LINE__, __FILE__, $sql);
}
//Fills content array
$contents = [];
while ($row = $db->sql_fetchrow($result)) {
$k = $row['location_k'];
$contents[$k] = new ContentFile();
$contents[$k]->load_from_row($row);
}
return $contents;
}
}
diff --git a/includes/content/zone.php b/includes/content/zone.php
index e0d7713..418e475 100644
--- a/includes/content/zone.php
+++ b/includes/content/zone.php
@@ -1,203 +1,203 @@
<?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;
+ $this->deleted = (bool)$row['zone_deleted'];
}
/**
* 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 unknown: ' . $this->id;
return false;
}
$this->load_from_row($row);
return true;
}
/**
* Saves the object to the database
*/
function save_to_database () {
global $db;
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$title = $db->sql_escape($this->title);
$type = $db->sql_escape($this->type);
$params = $db->sql_escape($this->params);
$deleted = $this->deleted ? 1 : 0;
$sql = "REPLACE INTO " . TABLE_CONTENT_ZONES . " (`zone_id`, `zone_title`, `zone_type`, `zone_params`, `zone_deleted`) VALUES ($id, '$title', '$type', '$params', $deleted)";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
if (!$this->id) {
$this->id = $db->sql_nextid();
}
}
/**
* Assigns the zone at the specified location.
*
* @param string $location_global the global location
* @param string $location_global the local location
* @param bool $delete_old_locations if true, delete old locations
*/
function assign_to ($location_global, $location_local, $delete_old_locations = true) {
if (!$this->id) {
$this->save_to_database();
}
global $db;
if ($delete_old_locations) {
$sql = "DELETE FROM " . TABLE_CONTENT_ZONES_LOCATIONS . " WHERE zone_id = " . $this->id;
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to delete", '', __LINE__, __FILE__, $sql);
}
}
$g = $db->sql_escape($location_global);
$l = $db->sql_escape($location_local);
$sql = "REPLACE INTO " . TABLE_CONTENT_ZONES_LOCATIONS . " (location_global, location_local, zone_id) VALUES ('$g', '$l', $this->id)";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to set zone location", '', __LINE__, __FILE__, $sql);
}
}
/**
* Gets the zone at specified location
*
* @param string $location_global the global location
* @param string $location_global the local location
* @param bool $create if the zone doesn't exist, create it [optional] [default value: false]
* @return ContentZone the zone, or null if the zone doesn't exist and $create is false
*/
static function at ($location_global, $location_local, $create = false) {
global $db;
$g = $db->sql_escape($location_global);
$l = $db->sql_escape($location_local);
$sql = "SELECT * FROM " . TABLE_CONTENT_ZONES_LOCATIONS . " WHERE location_global = '$g' AND location_local = '$l'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to set zone location", '', __LINE__, __FILE__, $sql);
}
if ($row = $db->sql_fetchrow($result)) {
return new ContentZone($row['zone_id']);
} elseif ($create) {
$zone = new ContentZone();
$zone->assign_to($location_global, $location_local);
return $zone;
} else {
return null;
}
}
/**
* Gets all the zones matching the specified location queries
*
* @param string $location_global_query the global location query
* @param string $location_local_query the local location query
* @return Array a ContentZone array, with each item a zone found
*
* [SECURITY] They are passed as is in SQL [R]LIKE queries, you can't inject users expression.
*
* The following properties are added to the ContentZone items of the returned array:
* - location_global
* - location_local
*/
static function search ($location_global_query, $location_local_query, $use_regexp_for_local = false) {
global $db;
$zones = [];
$op = $use_regexp_for_local ? 'RLIKE' : 'LIKE';
$sql = "SELECT * FROM " . TABLE_CONTENT_ZONES_LOCATIONS . " WHERE location_global LIKE '$location_global_query' AND location_local $op '$location_local_query'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to set zone location", '', __LINE__, __FILE__, $sql);
}
while ($row = $db->sql_fetchrow($result)) {
$zone = new ContentZone($row['zone_id']);
$zone->location_global = $row['location_global'];
$zone->location_local = $row['location_local'];
$zones[] = $zone;
}
return $zones;
}
}
diff --git a/includes/core.php b/includes/core.php
index 0a84fc7..9e908ab 100644
--- a/includes/core.php
+++ b/includes/core.php
@@ -1,694 +1,694 @@
<?php
/**
* Core: helper methods and main libraries loader
*
* Zed. The immensity of stars. The HyperShip. The people.
*
* (c) 2010, Dereckson, some rights reserved.
* Released under BSD license.
*
* @package Zed
* @subpackage Keruald
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
////////////////////////////////////////////////////////////////////////////////
/// ///
/// Configures PHP and loads site-wide used libraries ///
/// ///
////////////////////////////////////////////////////////////////////////////////
require_once(__DIR__ . "/../vendor/autoload.php");
error_reporting(E_ALL & ~E_NOTICE);
include_once("config.php");
include_once("error.php");
include_once("db/Database.php");
$db = Database::load();
Database::cleanupConfiguration();
include_once("sessions.php");
include_once("autoload.php");
////////////////////////////////////////////////////////////////////////////////
/// ///
/// Information helper methods ///
/// ///
////////////////////////////////////////////////////////////////////////////////
/**
* Gets the nickname from the specified perso ID
*
* @param integer $perso_id The specified perso ID
* @return string The perso's nickname
*/
function get_name ($perso_id) {
global $db;
$perso_id = $db->sql_escape($perso_id);
$sql = 'SELECT perso_nickname FROM '. TABLE_PERSOS . " WHERE perso_id = '$perso_id'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't query persos table.", '', __LINE__, __FILE__, $sql);
}
$row = $db->sql_fetchrow($result);
return $row['perso_nickname'];
}
/**
* Gets the user ID from the specified username
*
* @param string $username The username
* @return integer the user ID
*/
function get_userid ($username) {
global $db;
$username = $db->sql_escape($username);
$sql = 'SELECT user_id FROM '. TABLE_USERS . " WHERE username LIKE '$username'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't query users table.", '', __LINE__, __FILE__, $sql);
}
$row = $db->sql_fetchrow($result);
return $row['user_id'];
}
/**
* Gets an information from the application global registry
*
* @param string $key the registry's key
* @return string The key value
*/
function registry_get ($key) {
global $db;
$key = $db->sql_escape($key);
$sql = "SELECT registry_value FROM " . TABLE_REGISTRY . " WHERE registry_key = '$key'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't read registry.", '', __LINE__, __FILE__, $sql);
}
$row = $db->sql_fetchrow($result);
return $row['registry_value'];
}
/**
* Sets an information in the application global registry
*
* @param string $key the registry key
* @param string $value the value to store at the specified registry key
*/
function registry_set ($key, $value) {
global $db;
$key = $db->sql_escape($key);
$value = $db->sql_escape($value);
$sql = "REPLACE INTO " . TABLE_REGISTRY . " (registry_key, registry_value) VALUES ('$key', '$value')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't update registry", '', __LINE__, __FILE__, $sql);
}
}
////////////////////////////////////////////////////////////////////////////////
/// ///
/// Misc helper methods ///
/// ///
////////////////////////////////////////////////////////////////////////////////
/**
* Generates a random string, according the specified format.
*
* <code>
* echo generate_random_string('AAA111'); //this could output SDQ245.
* </code>
*
* @author Pierre Habart <p.habart@ifrance.com>
*
* @param string $format The format e.g. AAA111
* @return string a random string
*/
function generate_random_string ($format) {
mt_srand((double)microtime()*1000000);
$str_to_return="";
$t_alphabet=explode(",", "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z");
$t_number=explode(",", "1,2,3,4,5,6,7,8,9,0");
for ($i=0;$i<strlen($format);$i++) {
if (preg_match("/^[a-zA-Z]/", $format[$i])) {
$add=$t_alphabet[mt_rand() % sizeof($t_alphabet)];
if (preg_match("/^[a-z]/", $format[$i])) {
$add=strtolower($add);
}
} elseif(preg_match("/^[0-9]/", $format[$i])) {
$add=$t_number[mt_rand() % sizeof($t_number)];
} else {
$add="?";
}
$str_to_return.=$add;
}
return $str_to_return;
}
//Plural management
/**
* Returns "s" when the $amount request a plural
* This function is a French plural helper.
*
* @param $amount the amount of objects
* @return string 's' if $amount implies a plural ; '' if it implies a singular.
*/
function s ($amount) {
if ($amount >= 2 || $amount <= -2) {
return "s";
}
}
/**
* Returns "x" when the $amount request a plural
* This function is a French plural helper.
*
* @param $amount the amount of objects
* @return string 'x' if $amount implies a plural ; '' if it implies a singular.
*/
function x ($amount) {
if ($amount >= 2 || $amount <= -2) {
return "x";
}
}
//Debug
/**
* Prints human-readable information about a variable.
*
* It behaves like the print_r command, but the output is enclosed in pre tags,
* to have a preformatted HTML output.
*
* @param mixed $expression The expression to be printed
*/
function dprint_r ($expression) {
echo '<pre>';
print_r($expression);
echo '</pre>';
}
//GUID
/**
* Generates a GUID, or more precisely an UUID
* @link http://en.wikipedia.org/wiki/Universally_Unique_Identifier Wikipedia, Universally Unique Identifier.
*
* A UUID is a 36 chars string of 32 hexadecimal and 4 dashes, with a
* very high probability to be unique.
*
* @return string the UUID
*/
function new_guid() {
$characters = explode(",", "a,b,c,d,e,f,0,1,2,3,4,5,6,7,8,9");
$guid = "";
for ($i = 0 ; $i < 36 ; $i++) {
if ($i == 8 || $i == 13 || $i == 18 || $i == 23) {
$guid .= "-";
} else {
$guid .= $characters[mt_rand() % sizeof($characters)];
}
}
return $guid;
}
/**
* Determines if the expression is a valid UUID (a guid without {}).
* @see new_guid
*
* @param string $expression the expression to check
* @return boolean true if the specified expression is a valid UUID ; otherwise, false.
*/
function is_guid ($expression) {
//We avoid regexp to speed up the check
//A guid is a 36 characters string
if (strlen($expression) != 36) {
return false;
}
$expression = strtolower($expression);
for ($i = 0 ; $i < 36 ; $i++) {
if ($i == 8 || $i == 13 || $i == 18 || $i == 23) {
//with dashes
if ($expression[$i] != "-") {
return false;
}
} else {
//and numbers
if (!is_numeric($expression[$i]) && $expression[$i] != 'a' && $expression[$i] != 'b' && $expression[$i] != 'c' && $expression[$i] != 'd' && $expression[$i] != 'e' && $expression[$i] != 'f' ) {
return false;
}
}
}
return true;
}
/**
* Gets file extension
*
* @param string $file the file to get the extension
* @return string the extension from the specified file
*/
function get_extension ($file) {
$dotPosition = strrpos($file, ".");
return substr($file, $dotPosition + 1);
}
/**
* Determines if a string starts with specified substring
*
* @param string $haystack the string to check
* @param string $needle the substring to determines if it's the start
* @param boolean $case_sensitive determines if the search must be case sensitive
* @return boolean true if $haystack starts with $needle ; otherwise, false.
*/
function string_starts_with ($haystack, $needle, $case_sensitive = true) {
if (!$case_sensitive) {
$haystack = strtoupper($haystack);
$needle = strtoupper($needle);
}
if ($haystack == $needle) {
return true;
}
return strpos($haystack, $needle) === 0;
}
/**
* Inserts a message into the supralog
*
* @param string $category the entry category
* @param string $message the message to log
* @param string $source the entry source.
*/
function supralog ($category, $message, $source = null) {
global $db, $CurrentUser, $CurrentPerso;
$category = $db->sql_query_express($category);
$message = $db->sql_query_express($message);
- $source = $db->sql_query_express($source ? $source : $_SERVER['SERVER_ADDR']);
+ $source = $db->sql_query_express($source ?: $_SERVER['SERVER_ADDR']);
$ip = $_SERVER['REMOTE_ADDR'];
$sql = "INSERT INTO " . TABLE_LOG .
" (entry_ip, user_id, perso_id, entry_category, entry_message, entry_source) VALUES
('$ip', $CurrentUser->id, $CurrentPerso->id, '$category', '$message', '$source')";
if ( !($result = $db->sql_query($sql)) ) {
message_die(SQL_ERROR, "Can't log this entry.", '', __LINE__, __FILE__, $sql);
}
}
////////////////////////////////////////////////////////////////////////////////
/// ///
/// Localization (l10n) ///
/// ///
////////////////////////////////////////////////////////////////////////////////
/**
* Defines the LANG constant, to lang to print
*
* This information is contained in the session, or if not yet defined,
* it's to determine according the user's browser preferences.
* @see find_lang
*/
function initialize_lang () {
//If $_SESSION['lang'] doesn't exist yet, find a common language
if (!array_key_exists('lang', $_SESSION)) {
$lang = find_lang();
- $_SESSION['lang'] = $lang ? $lang : '-';
+ $_SESSION['lang'] = $lang ?: '-';
}
if ($_SESSION['lang'] != '-') {
define('LANG', $_SESSION['lang']);
}
}
/**
* Gets a common lang spoken by the site and the user's browser
* @see get_http_accept_languages
*
* @return string the language
*/
function find_lang () {
if (file_exists('lang') && is_dir('lang')) {
//Gets lang/ subdirectories: this is the list of available languages
$handle = opendir('lang');
while ($file = readdir($handle)) {
if ($file != '.' && $file != '..' && is_dir("lang/$file")) {
$langs[] = $file;
}
}
//The array $langs contains now the language available.
//Gets the langs the user should want:
if (!$userlangs = get_http_accept_languages()) {
return;
}
//Gets the intersection between the both languages arrays
//If it matches, returns first result
$intersect = array_intersect($userlangs, $langs);
if (count($intersect)) {
return $intersect[0];
}
//Now it's okay with Opera and Firefox but Internet Explorer will
//by default return en-US and not en or fr-BE and not fr, so second pass
foreach ($userlangs as $userlang) {
$lang = explode('-', $userlang);
if (count($lang) > 1) {
$userlangs2[] = $lang[0];
}
}
$intersect = array_intersect($userlangs2, $langs);
if (count($intersect)) {
return $intersect[0];
}
}
}
/**
* Gets the languages accepted by the browser, by order of priority.
*
* This will read the HTTP_ACCEPT_LANGUAGE variable sent by the browser in the
* HTTP request.
*
* @return Array an array of string, each item a language accepted by browser
*/
function get_http_accept_languages () {
//What language to print is sent by browser in HTTP_ACCEPT_LANGUAGE var.
//This will be something like en,fr;q=0.8,fr-fr;q=0.5,en-us;q=0.3
if (!array_key_exists('HTTP_ACCEPT_LANGUAGE', $_SERVER)) {
return null;
}
$http_accept_language = explode(',', $_SERVER["HTTP_ACCEPT_LANGUAGE"]);
foreach ($http_accept_language as $language) {
$userlang = explode(';q=', $language);
if (count($userlang) == 1) {
$userlangs[] = [1, $language];
} else {
$userlangs[] = [$userlang[1], $userlang[0]];
}
}
rsort($userlangs);
foreach ($userlangs as $userlang) {
$result[] = $userlang[1];
}
return $result;
}
/**
* Loads specified language Smarty configuration file
*
* @param string $file the file to load
* @param mixed $sections array of section names, single section or null
*/
function lang_load ($file, $sections = null) {
global $smarty;
//Loads English file as fallback if some parameters are missing
if (file_exists("lang/en/$file")) {
$smarty->configLoad("lang/en/$file", $sections);
}
//Loads wanted file (if it exists and a language have been defined)
if (defined('LANG') && LANG != 'en' && file_exists('lang/' . LANG . '/' . $file)) {
$smarty->configLoad('lang/' . LANG . '/' . $file, $sections);
}
}
/**
* Gets a specified language expression defined in configuration file
*
* @param string $key the configuration key matching the value to get
* @return string The value in the configuration file
*/
function lang_get ($key) {
global $smarty;
$smartyConfValue = $smarty->config_vars[$key];
- return $smartyConfValue ? $smartyConfValue : "#$key#";
+ return $smartyConfValue ?: "#$key#";
}
////////////////////////////////////////////////////////////////////////////////
/// ///
/// Zed date and time helper methods ///
/// ///
////////////////////////////////////////////////////////////////////////////////
/**
* Converts a YYYYMMDD or YYYY-MM-DD timestamp to unixtime
* @link http://en.wikipedia.org/wiki/Unix_time Unix time
*
* @param string $timestamp the timestamp to convert
* @return integer the unixtime
*/
function to_unixtime ($timestamp) {
switch (strlen($timestamp)) {
case 8:
//YYYYMMDD
return mktime(0, 0, 0, substr($timestamp, 4, 2), substr($timestamp, 6, 2), substr($timestamp, 0, 4));
case 10:
//YYYY-MM-DD
return mktime(0, 0, 0, substr($timestamp, 5, 2), substr($timestamp, 8, 2), substr($timestamp, 0, 4));
default:
throw new Exception("timestamp is not a valid YYYYMMDD or YYYY-MM-DD timestamp: $timestamp");
}
}
/**
* Converts a unixtime to the YYYYMMDD or YYYY-MM-DD timestamp format
* @see to_unixtime
*
* @param int $unixtime the time to convert
* @param int $format 8 or 10. If 8 (default), will output YYYYMMDD. If 10, YYYY-MM-DD.
* @return string the timestamp
*/
function to_timestamp ($unixtime = null, $format = 8) {
//If no parameter is specified (or null, or false), current time is used
//==== allows to_timestamp(0) to return correct 1970-1-1 value.
if ($unixtime === null || $unixtime === false) {
$unixtime = time();
}
switch ($format) {
case 8:
//YYYYMMDD
return date('Ymd', $unixtime);
case 10:
//YYYY-MM-DD
return date('Y-m-d', $unixtime);
default:
throw new Exception("format must be 8 (YYYYMMDD) or 10 (YYYY-MM-DD) and not $format.");
}
}
/**
* Converts a unixtime to the Hypership time format or gets the current hypership time.
* @link http://en.wikipedia.org/wiki/Unix_time
* @link http://www.purl.org/NET/Zed/blog/HyperShipTime
*
* @param int $unixtime The unixtime to convert to HyperShip time. If omitted, the current unixtime.
* @return string The HyperShip time
*/
function get_hypership_time ($unixtime = null) {
//If unixtime is not specified, it's now
if ($unixtime === null) {
$unixtime = time();
}
//Hypership time is a count of days since launch @ 2010-07-03 00:00:00
//Followed by a fraction of the current day /1000, like the internet time
//but in UTC timezone and not Switzerland CET/CEST.
//We don't need to use floor(), as we output the result at int, truncating
//automatically decimal values instead of round it (like in C).
$seconds = $unixtime - 1278115200;
$days = $seconds / 86400;
$fraction = (abs($seconds) % 86400) / 86.4;
return sprintf("%d.%03d", $days, $fraction);
}
////////////////////////////////////////////////////////////////////////////////
/// ///
/// URL helpers functions ///
/// ///
////////////////////////////////////////////////////////////////////////////////
/**
* Gets the URL matching the specified resource.
*
* Example:
* <code>
* $url = get_url('ship', $ship);
* echo $url; //if $ship contains S00001, this should print /ship/S00001
* </code>
*
* @param string $resource,... the resources
* @return string the URL matching the specified resource
*/
function get_url () {
global $Config;
if (func_num_args() > 0) {
$pieces = func_get_args();
return $Config['BaseURL'] . '/' . implode('/', $pieces);
} elseif ($Config['BaseURL'] == "" || $Config['BaseURL'] == $_SERVER["PHP_SELF"]) {
return "/";
} else {
return $Config['BaseURL'];
}
}
/**
* Gets the current page URL
*
* @return string the current page URL
*/
function get_page_url () {
$url = $_SERVER['SCRIPT_NAME'] . $_SERVER['PATH_INFO'];
if (substr($url, -10) == $_SERVER["PHP_SELF"]) {
return substr($url, 0, -9);
}
return $url;
}
/**
* Gets the server URL
* @todo find a way to detect https:// on non standard port
*
* @return string the server URL
*/
function get_server_url () {
switch ($port = $_SERVER['SERVER_PORT']) {
case '80':
return "http://$_SERVER[SERVER_NAME]";
case '443':
return "https://$_SERVER[SERVER_NAME]";
default:
return "http://$_SERVER[SERVER_NAME]:$_SERVER[SERVER_PORT]";
}
}
/**
* Gets $_SERVER['PATH_INFO'] or computes the equivalent if not defined.
*
* This function allows the entry point controllers to get the current URL
* in a consistent way, for any redirection configuration
*
* So with /foo/bar, /index.php/foo/bar, /zed/index.php/foo/bar or /zed/foo/bar
* get_current_url will return /foo/bar
*
* @return string the relevant URL part
*/
function get_current_url () {
global $Config;
//Gets relevant URL part from relevant $_SERVER variables
if (array_key_exists('PATH_INFO', $_SERVER)) {
//Without mod_rewrite, and url like /index.php/controller
//we use PATH_INFO. It's the easiest case.
return $_SERVER["PATH_INFO"];
}
//In other cases, we'll need to get the relevant part of the URL
$current_url = get_server_url() . $_SERVER['REQUEST_URI'];
//Relevant URL part starts after the site URL
$len = strlen($Config['SiteURL']);
//We need to assert it's the correct site
if (substr($current_url, 0, $len) != $Config['SiteURL']) {
dieprint_r(GENERAL_ERROR, "Edit includes/config.php and specify the correct site URL<br /><strong>Current value:</strong> $Config[SiteURL]<br /><strong>Expected value:</strong> a string starting by " . get_server_url(), "Setup");
}
if (array_key_exists('REDIRECT_URL', $_SERVER)) {
//With mod_rewrite, we can use REDIRECT_URL
//We takes the end of the URL, ie *FROM* $len position
return substr(get_server_url() . $_SERVER["REDIRECT_URL"], $len);
}
//Last possibility: use REQUEST_URI, but remove QUERY_STRING
//If you need to edit here, use $_SERVER['REQUEST_URI']
//but you need to discard $_SERVER['QUERY_STRING']
//We takes the end of the URL, ie *FROM* $len position
$url = substr(get_server_url() . $_SERVER["REQUEST_URI"], $len);
//But if there are a query string (?action=... we need to discard it)
if ($_SERVER['QUERY_STRING']) {
return substr($url, 0, strlen($url) - strlen($_SERVER['QUERY_STRING']) - 1);
}
return $url;
}
/**
* Gets an array of url fragments to be processed by controller
* @see get_current_url
*
* This method is used by the controllers entry points to know the URL and
* call relevant subcontrollers.
*
* @return Array an array of string, one for each URL fragment
*/
function get_current_url_fragments () {
return explode('/', substr(get_current_url(), 1));
}
////////////////////////////////////////////////////////////////////////////////
/// ///
/// URL xmlHttpRequest helpers functions ///
/// ///
////////////////////////////////////////////////////////////////////////////////
/**
* Gets an hash value to check the integrity of URLs in /do.php calls
*
* @param Array $args the args to compute the hash
* @return the hash parameter for your xmlHttpRequest url
*/
function get_xhr_hash ($args) {
global $Config;
array_shift($args);
return md5($_SESSION['ID'] . $Config['SecretKey'] . implode('', $args));
}
/**
* Gets the URL to call do.php, the xmlHttpRequest controller
*
* @return string the xmlHttpRequest url, with an integrity hash
*/
function get_xhr_hashed_url () {
global $Config;
$args = func_get_args();
$args[] = get_xhr_hash($args);
return $Config['DoURL'] . '/' . implode('/', $args);
}
/**
* Gets the URL to call do.php, the xmlHttpRequest controller
*
* @return string the xmlHttpRequest url
*/
function get_xhr_url () {
global $Config;
$args = func_get_args();
return $Config['DoURL'] . '/' .implode('/', $args);
}
diff --git a/includes/geo/location.php b/includes/geo/location.php
index 026e8a4..9626797 100644
--- a/includes/geo/location.php
+++ b/includes/geo/location.php
@@ -1,446 +1,446 @@
<?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
*/
use Hypership\Geo\Point3D;
require_once('body.php');
require_once('place.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 Array
*/
private $data;
/**
* A body object
*
* It contains a GeoBody value when the global location is a body
* ie if $this->data[0][0] == 'B'
*
* Otherwise, its value is null.
*
* @var GeoBody
*/
public $body = null;
/**
* A place object
*
* It contains a GeoPlacevalue when the global location is a place
* ie if $this->data[0][0] == 'B' && strlen($this->data[0]) == 9
*
* Otherwise, its value is null.
*
* @var GeoPlace
*/
public $place = null;
/**
* A point identified by x, y, z coordinates
*/
public Point3D|null $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 = [];
} 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 inheritance, like a class
//HypershipGeoLocation extending GeoLocation.
if ($local !== null) {
$this->data[1] = $local;
}
$this->load_classes();
}
/**
* Gets $place, $body and $ship instances if they're needed
*/
function load_classes () {
//No data, no class to load
if (!count($this->data)) {
return;
}
//Loads global classes
$global = $this->data[0];
$code = substr($global, 1, 5);
switch ($global[0]) {
case 'B':
switch (strlen($global)) {
case 9:
$this->place = GeoPlace::from_code($global);
case 6:
$this->body = new GeoBody($code);
break;
}
break;
case 'S':
$this->ship = new Ship($code);
break;
case 'x':
$coords = sscanf($global, "xyz: [%f, %f, %f]");
if (count($coords) == 3) {
$this->point3D = new Point3D(...$coords);
}
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');
+ $location[] = $body->name ?: lang_get('UnknownBody');
if (strlen($this->data[0]) == 9) {
$place = GeoPlace::from_code($this->data[0]);
$location[] = $place->name ? $place->name : lang_get('UnknownPlace');
}
break;
case 'x':
$pt = $this->point3D->toSpherical();
return sprintf("(%d, %d°, %d°)", $pt[0], $pt[1], $pt[2]);
default:
message_die(GENERAL_ERROR, "Unknown location identifier: $type.<br />Expected: B or S.");
}
return implode(", ", array_reverse($location));
}
/**
* Magic method called when a unknown property is set.
*
* Handles $global, $local, $type, $body_code, $ship_code, $place_code
*/
function __set ($variable, $value) {
switch ($variable) {
/* main variables */
case 'global':
$this->data[0] = $value;
break;
case 'local':
$this->data[1] = $value;
break;
/* global location */
case 'type':
if ($value == 'B' || $value == 'S') {
if (!$this->data[0]) {
$this->data[0] = $value;
} else {
$this->data[0][0] = $value;
}
}
break;
case 'body_code':
if (preg_match("/[0-9]{1,5}/", $value)) {
$value = sprintf("%05d", $value);
if (!$this->data[0]) {
$this->data[0] = "B" . $value;
return;
} elseif ($this->data[0][0] == 'B') {
$this->data[0] = "B" . $value . substr($this->data[0], 6);
return;
}
throw new Exception("Global location isn't a body.");
}
throw new Exception("$value isn't a valid body code");
case 'ship_code':
if (preg_match("/[0-9]{1,5}/", $value)) {
$value = sprintf("%05d", $value);
if (!$this->data[0]) {
$this->data[0] = "S" . $value;
return;
} elseif ($this->data[0][0] == 'S') {
$this->data[0] = "S" . $value . substr($this->data[0], 6);
return;
}
throw new Exception("Global location isn't a ship.");
}
throw new Exception("$value isn't a valid ship code");
case 'place_code':
if (!preg_match("/[0-9]{1,3}/", $value)) {
throw new Exception("$value isn't a valid place code");
}
$value = sprintf("%03d", $value);
if ($this->data[0][0] == 'B') {
$this->data[0] = substr($this->data[0], 0, 6) . $value;
}
throw new Exception("Global location isn't a body.");
default:
throw new Exception("Unknown variable: $variable");
break;
}
}
}
diff --git a/includes/geo/place.php b/includes/geo/place.php
index 81b5d28..70025f2 100644
--- a/includes/geo/place.php
+++ b/includes/geo/place.php
@@ -1,230 +1,230 @@
<?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 unknown: " . $this->id;
return false;
}
$this->body_code = $row['body_code'];
$this->code = $row['place_code'];
$this->name = $row['place_name'];
$this->description = $row['place_description'];
$this->location_local_format = $row['location_local_format'];
//Explodes place_status SET field in boolean variables
if ($row['place_status']) {
$flags = explode(',', $row['place_status']);
foreach ($flags as $flag) {
$this->$flag = true;
}
}
return true;
}
/**
* Gets status field value
*
* @return string the status field value (e.g. "requiresPTA,default")
*/
function getStatus () {
$flags = ['start', 'hidden'];
foreach ($flags as $flag) {
if ($this->$flag == true) {
$status[] = $flag;
}
}
return implode(',', $status);
}
/**
* Saves to database
*/
function save_to_database () {
global $db;
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$body_code = $db->sql_escape($this->body_code);
$code = $db->sql_escape($this->code);
$name = $db->sql_escape($this->name);
$description = $db->sql_escape($this->description);
$status = $this->getStatus();
$location_local_format = $db->sql_escape($this->location_local_format);
//Updates or inserts
$sql = "REPLACE INTO " . TABLE_PLACES . " (`place_id`, `body_code`, `place_code`, `place_name`, `place_description`, `place_status`, `location_local_format`) VALUES ($id, '$body_code', '$code', '$name', '$description', '$status', '$location_local_format')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
if (!$id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
}
/**
* Determines if the specified local location looks valid
*
* @param string $local_location the local location
* @return boolean true if the specified local location looks valid ; otherwise, false.
*/
function is_valid_local_location ($local_location) {
- $format = $this->location_local_format ? $this->location_local_format : LOCATION_LOCAL_DEFAULT_FORMAT;
+ $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/objects/content.php b/includes/objects/content.php
index 21f4d58..9479600 100644
--- a/includes/objects/content.php
+++ b/includes/objects/content.php
@@ -1,323 +1,323 @@
<?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 occurrence in
* content_locations table will be considered.
*
* If a content have no location, it will be ignored.
*
* If you edit content location, then call saveToDatabase, you will create
* a new location but future instances will contain first not deleted location.
*
* @todo remove dbc temporary limitations (cf. /do.php upload_content and infra)
* @todo create a class ContentLocation and move location fields there
* @todo validate SQL schema and add in config.php TABLE_CONTENT tables
*
* @deprecated
*/
class Content {
/* -------------------------------------------------------------
Properties
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
public $id;
public $path;
public $user_id;
public $perso_id;
public $title;
public $location_global = null;
public $location_local = null;
public $location_k = null;
public $perso_name;
public $perso_nickname;
/* -------------------------------------------------------------
Constructor, __toString
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
* Initializes a new Content instance
*
* @param int $id the primary key
*/
function __construct ($id = null) {
if ($id) {
$this->id = $id;
$this->load_from_database();
}
}
/**
* Returns a string representation of current Content instance
*
* @return string the content title or path if title is blank.
*/
function __toString () {
- return $this->title ? $this->title : $this->path;
+ return $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 unknown: " . $this->id;
return false;
}
$this->load_from_row($row);
return true;
}
/**
* Loads the object from row
*/
function load_from_row ($row) {
$this->id = $row['content_id'];
$this->path = $row['content_path'];
$this->user_id = $row['user_id'];
$this->perso_id = $row['perso_id'];
$this->title = $row['content_title'];
$this->location_global = $row['location_global'];
$this->location_local = $row['location_local'];
$this->location_k = $row['location_k'];
if (array_key_exists('perso_name', $row)) {
$this->perso_name = $row['perso_name'];
}
if (array_key_exists('perso_nickname', $row)) {
$this->perso_nickname = $row['perso_nickname'];
}
}
/**
* Saves to database
*/
function save_to_database () {
global $db;
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$path = $db->sql_escape($this->path);
$user_id = $db->sql_escape($this->user_id);
$perso_id = $db->sql_escape($this->perso_id);
$title = $db->sql_escape($this->title);
$location_global = ($this->location_global !== null) ? "'" . $db->sql_escape($this->location_global) . "'" : 'NULL';
$location_local = ($this->location_local !== null) ? "'" . $db->sql_escape($this->location_local) . "'" : 'NULL';
$location_k = ($this->location_k !== null) ? "'" . $db->sql_escape($this->location_k) . "'" : 'NULL';
//Updates or inserts
$sql = "REPLACE INTO content_files (`content_id`, `content_path`, `user_id`, `perso_id`, `content_title`) VALUES ($id, '$path', '$user_id', '$perso_id', '$title')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't save content", '', __LINE__, __FILE__, $sql);
}
if (!$this->id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
//Saves location
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$sql = "REPLACE INTO content_locations (location_global, location_local, location_k, content_id) VALUES ($location_global, $location_local, $location_k, $id)";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't save content location", '', __LINE__, __FILE__, $sql);
}
}
/* -------------------------------------------------------------
File handling helper methods
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
* Determines if the extension is valid
*
* @param string $ext The extension (without dot)
* @return boolean true if this extension is valid ; otherwise, false.
*/
function is_valid_extension ($ext) {
switch ($ext = strtolower($ext)) {
//Pictures
case 'jpg':
case 'gif':
case 'png':
case 'bmp':
case 'xbm':
return true;
//Denied extension
default:
return false;
}
}
/**
* Creates a directory
*
* @param string $dir the directory to create
*/
function create_directory ($directory) {
if (!file_exists($directory)) {
@mkdir($directory); //Creates new directory, chmod 777
}
}
/**
* Handles uploaded file
*
* @return bool true if the file have been handled
*/
function handle_uploaded_file ($fileArray) {
if (count($fileArray) && $fileArray['error'] == 0) {
$this->create_directory("content/users/$this->user_id");
$this->path = "content/users/$this->user_id/$fileArray[name]";
if (!self::is_valid_extension(get_extension($fileArray[name]))) {
return false;
}
if (move_uploaded_file($fileArray['tmp_name'], $this->path)) {
return true;
} else {
$this->path = null;
return false;
}
} else {
return false;
}
}
/**
* Generates a thumbnail using ImageMagick binary
*
* @return boolean true if the thumbnail command returns 0 as program exit code ; otherwise, false
*/
function generate_thumbnail () {
global $Config;
//Builds thumbnail filename
$sourceFile = $this->path;
$pos = strrpos($this->path, '.');
$thumbnailFile = substr($sourceFile, 0, $pos) . 'Square' . substr($sourceFile, $pos);
//Executes imagemagick command
$command = $Config['ImageMagick']['convert'] . " \"$sourceFile\" -resize 162x162 \"$thumbnailFile\"";
@system($command, $code);
//Returns true if the command have exited with errorcode 0 (= ok)
return ($code == 0);
}
/* -------------------------------------------------------------
Gets content
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
* Gets content at specified location
*
* @param string $location_global global content location
* @param string $location_local local content location
* @return Array array of Content instances
*/
static function get_local_content ($location_global, $location_local) {
global $db;
//Get contents at this location
$location_global = $db->sql_escape($location_global);
$location_local = $db->sql_escape($location_local);
$sql = "SELECT c.*, p.perso_nickname, p.perso_name FROM content c, persos p WHERE c.location_global = '$location_global' AND c.location_local = '$location_local' AND p.perso_id = c.perso_id ORDER BY location_k ASC";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't get content", '', __LINE__, __FILE__, $sql);
}
//Fills content array
$contents = [];
while ($row = $db->sql_fetchrow($result)) {
$content = new Content();
$content->load_from_row($row);
$contents[] = $content;
}
return $contents;
}
}
diff --git a/includes/objects/port.php b/includes/objects/port.php
index 750276a..59a1da1 100644
--- a/includes/objects/port.php
+++ b/includes/objects/port.php
@@ -1,211 +1,211 @@
<?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;
+ $this->hidden = (bool)$_POST['hidden'];
}
if (array_key_exists('requiresPTA', $_POST)) {
- $this->requiresPTA = $_POST['requiresPTA'] ? true : false;
+ $this->requiresPTA = (bool)$_POST['requiresPTA'];
}
if (array_key_exists('default', $_POST)) {
- $this->hidden = $_POST['default'] ? true : false;
+ $this->hidden = (bool)$_POST['default'];
}
}
/**
* 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 unknown: " . $this->id;
return false;
}
$this->location_global = $row['location_global'];
$this->location_local = $row['location_local'];
$this->name = $row['port_name'];
//Explodes place_status SET field in boolean variables
if ($row['place_status']) {
$flags = explode(',', $row['port_status']);
foreach ($flags as $flag) {
$this->$flag = true;
}
}
return true;
}
/**
* Gets status field value
*
* @return string the status field value (e.g. "requiresPTA,default")
*/
function getStatus () {
$flags = ['hidden', 'requiresPTA', 'default'];
foreach ($flags as $flag) {
if ($this->$flag) {
$status[] = $flag;
}
}
return implode(',', $status);
}
/**
* Saves to database
*/
function save_to_database () {
global $db;
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$location_global = $db->sql_escape($this->location_global);
$location_local = $db->sql_escape($this->location_local);
$name = $db->sql_escape($this->name);
$status = $this->getStatus();
//Updates or inserts
$sql = "REPLACE INTO " . TABLE_PORTS . " (`port_id`, `location_global`, `location_local`, `port_name`, `port_status`) VALUES ($id, '$location_global', '$location_local', '$name', '$status')";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
if (!$id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
}
/**
* Determines if the specified location have a port
*
* @param string $location_global the global location
* @return boolean true if there is a spatioport exactly at the specified location ; otherwise, false.
*/
static function have_port ($location_global) {
return (get_port_id($location_global) !== null);
}
/**
* Gets the port situated exactly at the specified global location
*
* @param string $location_global the global location
* @return int the port ID
*/
static function get_port_id ($location_global) {
global $db;
$location_global = $db->sql_escape($location_global);
$sql = "SELECT port_id FROM " . TABLE_PORTS . " WHERE location_global = '$location_global'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to get ports", '', __LINE__, __FILE__, $sql);
}
if ($row = $db->sql_fetchrow($result)) {
return $row['port_id'];
}
return null;
}
/**
* Gets default port, from specified global location
*
* @param string $location_global the global location
* @return Port the port near this location ; null if there isn't port there.
*/
static function from_location ($location_global) {
$havePlace = strlen($location_global) == 9;
$port_id = null;
if ($havePlace) {
//Checks if there's a port at specified location
$port_id = self::get_port_id($location_global);
}
if ($port_id == null) {
//Nearest default port.
//If place have been specified (B0001001), we've to found elsewhere
//==> B00001%
global $db;
$loc = $db->sql_escape(substr($location_global, 0, 6));
$sql = "SELECT port_id FROM " . TABLE_PORTS . " WHERE location_global LIKE '$loc%'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't get port", '', __LINE__, __FILE__, $sql);
}
if ($row = $db->sql_fetchrow($result)) {
$port_id = $row['port_id'];
} else {
return null;
}
}
return new Port($port_id);
}
}
diff --git a/includes/objects/profilephoto.php b/includes/objects/profilephoto.php
index 099bd34..f84ffc0 100644
--- a/includes/objects/profilephoto.php
+++ b/includes/objects/profilephoto.php
@@ -1,214 +1,214 @@
<?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;
+ $this->avatar = (bool)$_POST['avatar'];
}
}
/**
* 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 unknown: " . $this->id;
return false;
}
$this->perso_id = $row['perso_id'];
$this->name = $row['photo_name'];
$this->description = $row['photo_description'];
$this->avatar = $row['photo_avatar'];
return true;
}
/**
* Promotes the photo to avatar
*/
function promote_to_avatar () {
global $db;
//1 - locally
$sql = "UPDATE " . TABLE_PROFILES_PHOTOS . " SET photo_avatar = 0 WHERE perso_id = " . $this->perso_id;
$db->sql_query_express($sql);
$this->avatar = true;
//2 - in perso table
$perso = Perso::get($this->perso_id);
$perso->avatar = $this->name;
$perso->saveToDatabase();
}
/**
* Saves the object to the database
*/
function save_to_database () {
global $db;
//Escapes fields
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$perso_id = $db->sql_escape($this->perso_id);
$name = $db->sql_escape($this->name);
$description = $db->sql_escape($this->description);
$avatar = $this->avatar ? 1 : 0;
//Saves
$sql = "REPLACE INTO " . TABLE_PROFILES_PHOTOS . " (`photo_id`, `perso_id`, `photo_name`, `photo_description`, `photo_avatar`) VALUES ($id, '$perso_id', '$name', '$description', $avatar)";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
if (!$id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
}
/**
* Deletes the photo
*/
function delete () {
global $db;
//Deletes from disk
$pic_tn = PHOTOS_DIR . '/' . $this->name;
$pic_genuine = PHOTOS_DIR . '/tn/' . $this->name;
unlink($pic_tn);
unlink($pic_genuine);
//Deletes from database
$id = $db->sql_escape($this->id);
$sql = "DELETE FROM " . TABLE_PROFILES_PHOTOS . " WHERE photo_id = '$id' LIMIT 1";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't delete photo", '', __LINE__, __FILE__, $sql);
}
}
/**
* Generates a thumbnail using ImageMagick binary
*
* @return boolean true if the thumbnail command returns 0 as program exit code ; otherwise, false
*/
function generate_thumbnail () {
global $Config;
$sourceFile = PHOTOS_DIR . DIRECTORY_SEPARATOR . $this->name;
$thumbnailFile = PHOTOS_DIR . DIRECTORY_SEPARATOR . 'tn' . DIRECTORY_SEPARATOR . $this->name;
$command = $Config['ImageMagick']['convert'] . " $sourceFile -resize 1000x80 $thumbnailFile";
@system($command, $code);
return ($code == 0);
}
/**
* Gets photos from the specified perso
*
* @param int $perso_id the perso ID
* @param bool $allowUnsafe if false, don't include not safe for work photos
*/
static function get_photos ($perso_id, $allowUnsafe = true) {
global $db;
$sql = "SELECT photo_id FROM " . TABLE_PROFILES_PHOTOS . " WHERE perso_id = " . $db->sql_escape($perso_id);
if (!$allowUnsafe) {
$sql .= " AND photo_safe = 0";
}
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to get photos", '', __LINE__, __FILE__, $sql);
}
while ($row = $db->sql_fetchrow($result)) {
$photos[] = new ProfilePhoto($row[0]);
}
return $photos;
}
/**
* Gets perso avatar
*
* @param integer $perso_id the perso to get the avatar ID
* @param string $username the username to put in title tag
*/
static function get_avatar ($perso_id, $username = '') {
global $db;
$perso_id = $db->sql_escape($perso_id);
$sql = "SELECT photo_description, photo_name FROM " . TABLE_PROFILES_PHOTOS . " WHERE perso_id = '$perso_id' and photo_avatar = 1";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to get avatar", '', __LINE__, __FILE__, $sql);
}
if ($row = $db->sql_fetchrow($result)) {
if (!$username) {
$username = get_name($perso_id);
}
$description = $row['photo_description'] ? "$row[photo_description] ($username's avatar)" : "$username's avatar";
$url = PHOTOS_URL . '/tn/' . $row['photo_name'];
return "<img src=\"$url\" title=\"$username\" alt=\"$description\" />";
} else {
return null;
}
}
}
diff --git a/includes/objects/user.php b/includes/objects/user.php
index f579b1f..9628612 100644
--- a/includes/objects/user.php
+++ b/includes/objects/user.php
@@ -1,262 +1,262 @@
<?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 = [];
public static $hashtable_name = [];
/**
* 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 unknown: " . $this->id;
return false;
}
$this->name = $row['username'];
$this->password = $row['user_password'];
$this->active = $row['user_active'];
$this->actkey = $row['user_actkey'];
$this->email = $row['user_email'];
$this->regdate = $row['user_regdate'];
//Puts object in hashtables
Perso::$hashtable_id[$this->id] = $this;
Perso::$hashtable_name[$this->name] = $this;
return true;
}
/**
* Saves to database
*/
function save_to_database () {
global $db;
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$name = $db->sql_escape($this->name);
$password = $db->sql_escape($this->password);
$active = $db->sql_escape($this->active);
$actkey = $db->sql_escape($this->actkey);
$email = $db->sql_escape($this->email);
$regdate = $this->regdate ? "'" . $db->sql_escape($this->regdate) . "'" : 'NULL';
//Updates or inserts
$sql = "REPLACE INTO " . TABLE_USERS . " (`user_id`, `username`, `user_password`, `user_active`, `user_actkey`, `user_email`, `user_regdate`) VALUES ($id, '$name', '$password', '$active', '$actkey', '$email', $regdate)";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
if (!$id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
}
/**
* Updates the specified field in the database record
*/
function save_field ($field) {
global $db;
if (!$this->id) {
message_die(GENERAL_ERROR, "You're trying to update a record not yet saved in the database");
}
$id = $db->sql_escape($this->id);
$value = $db->sql_escape($this->$field);
$sql = "UPDATE " . TABLE_USERS . " SET `$field` = '$value' WHERE user_id = '$id'";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save $field field", '', __LINE__, __FILE__, $sql);
}
}
/**
* Generates a unique user id
*/
function generate_id () {
global $db;
do {
$this->id = rand(2001, 5999);
$sql = "SELECT COUNT(*) FROM " . TABLE_USERS . " WHERE user_id = $this->id LOCK IN SHARE MODE;";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't access users table", '', __LINE__, __FILE__, $sql);
}
$row = $db->sql_fetchrow($result);
} while ($row[0]);
}
/**
* Fills password field with encrypted version of the specified clear password
*
* @param string $newpassword The user's new password
*/
public function set_password ($newpassword) {
$this->password = md5($newpassword);
}
/**
* Deletes OpenID for this user
*/
public function delete_OpenID () {
$this->set_OpenID('');
}
/**
* Sets OpenID for this user
*
* @param string $url OpenID endpoint URL
*/
public function set_OpenID ($url) {
global $db;
if (!$this->id) {
$this->save_to_database();
}
$url = $db->sql_escape($url);
$sql = "DELETE FROM " . TABLE_USERS_AUTH . " WHERE auth_type = 'OpenID' AND user_id = $this->id";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't delete old OpenID", '', __LINE__, __FILE__, $sql);
}
if ($url != '') {
$sql = "INSERT INTO " . TABLE_USERS_AUTH . " (auth_type, auth_identity, user_id) VALUES ('OpenID', '$url', $this->id)";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't add new OpenID", '', __LINE__, __FILE__, $sql);
}
}
}
/**
* Checks if a login is available
*
* @param string $login the login to check
* @return bool true if the specified login is available ; otherwise, false.
*/
- public static function is_available_login ($login) {
+ public static function is_available_login ($login) : bool {
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);
+ return !$row[0];
}
/**
* 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;
}
}

File Metadata

Mime Type
text/x-diff
Expires
Sun, Nov 3, 16:48 (3 w, 5 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
21107
Default Alt Text
(132 KB)

Event Timeline