Page MenuHomeCode

No OneTemporary

diff --git a/controllers/settings.php b/controllers/settings.php
new file mode 100644
--- /dev/null
+++ b/controllers/settings.php
@@ -0,0 +1,83 @@
+<?php
+
+/*
+ * Zed
+ * (c) 2010, Dereckson, some rights reserved
+ * Released under BSD license
+ *
+ * Settings
+ *
+ * TODO: replace the on the fly preferences.xml code generation by a
+ * cached code generation
+ *
+ * TODO: reduce the number of for loops in this controller
+ */
+
+//
+// Loads settings
+//
+
+lang_load('settings.conf');
+
+include('includes/settings/settings.php');
+$settings = new Settings('includes/settings/preferences.xml');
+
+//Selects relevant settings page
+$pages = $settings->pages;
+if (count($url) > 1) {
+ //From url: /settings/account -> page account
+ if (array_key_exists($url[1], $settings->pages)) {
+ $page = $pages[$url[1]];
+ } else {
+ message_die(GENERAL_ERROR, "/settings/$url[1] isn't a valid setting page");
+ }
+} else {
+ //Default page
+ $page = array_shift($pages);
+}
+
+//Pages links
+foreach ($settings->pages as $tmppage) {
+ $pagesLinks[$tmppage->id] = $tmppage->title;
+}
+
+//
+// Handles form
+//
+if (array_key_exists('settings_page', $_POST)) {
+ if ($_POST['settings_page'] == $page->id) {
+ //Updates settings
+ $errors = array();
+ $page->handle_form($errors);
+ if (count($errors)) {
+ //Prints error message
+ $smarty->assign('WAP', implode('<br />', $errors));
+ }
+ } else {
+ //The field settings.page isn't the current page
+ //Prints an HACK_ERROR to avoid to save properties with the same names.
+ $id_current = $page->id;
+ $id_toSave = $_POST['settings_page'];
+ message_die(HACK_ERROR, "You're on /settings/$id_current but you want to update /settings/$id_toSave");
+ }
+}
+
+//
+// HTML output
+//
+
+//Serves header
+define('DIJIT', true);
+$title = lang_get('Settings');
+$smarty->assign('PAGE_TITLE', $title);
+include('header.php');
+
+//Serves settings page;
+$smarty->assign('page', $page);
+$smarty->assign('pages', $pagesLinks);
+$smarty->display('settings_page.tpl');
+
+//Servers footer
+include('footer.php');
+
+?>
\ No newline at end of file
diff --git a/includes/SmartLine/ZedCommands.php b/includes/SmartLine/ZedCommands.php
--- a/includes/SmartLine/ZedCommands.php
+++ b/includes/SmartLine/ZedCommands.php
@@ -1,264 +1,283 @@
<?php
/*
* Zed
* (c) 2010, Dereckson, some rights reserved
* Released under BSD license
*
* SmartLine
- *
+ *
+ * TODO: SettingsSmartLineCommand - understand why dojo floating pane isn't
+ * rendered if we est $controller instead to redirect
*/
///
/// Register commands
///
$smartLine->register_object('goto', 'GotoSmartLineCommand');
$smartLine->register_object('guid', 'GUIDSmartLineCommand');
$smartLine->register_object('invite', 'InviteSmartLineCommand');
$smartLine->register_object('invites', 'InviteSmartLineCommand');
$smartLine->register_object('list', 'ListSmartLineCommand');
+$smartLine->register_object('requests', 'RequestsSmartLineCommand');
+$smartLine->register_object('settings', 'SettingsSmartLineCommand');
$smartLine->register_object('unixtime', 'UnixTimeSmartLineCommand');
-$smartLine->register_object('requests', 'RequestsSmartLineCommand');
$smartLine->register_object('whereami', 'WhereAmISmartLineCommand');
///
/// Help (todo: move $lang array in lang folder)
///
$lang['Help']['goto'] = "Go to a location";
$lang['Help']['guid'] = "Generate a GUID";
$lang['Help']['list'] = "Lists specified objects (bodies, locations or places)";
$lang['Help']['requests'] = "Checks if there are waiting requests";
$lang['Help']['unixtime'] = "Prints current unixtime (seconds elapsed since 1970-01-01 00:00, UTC) or the specified unixtime date.";
$lang['Help']['whereami'] = "Where am I?";
$lang['Help']['invite'] = "Generate an invite. To see the generated invites, invite list.";
///
/// whereami
///
class WhereAmISmartLineCommand extends SmartLineCommand {
public function run ($argv, $argc) {
- global $CurrentPerso;
- require_once("includes/geo/location.php");
- $place = new GeoLocation($CurrentPerso->location_global);
- $this->SmartLine->puts($CurrentPerso->location_global . ' - ' . $place);
+ global $CurrentPerso;
+
+ require_once("includes/geo/location.php");
+ $place = new GeoLocation($CurrentPerso->location_global);
+ $this->SmartLine->puts($CurrentPerso->location_global . ' - ' . $place);
}
}
///
/// GUID
///
class GUIDSmartLineCommand extends SmartLineCommand {
public function run ($argv, $argc) {
- if ($argc > 1 && is_numeric($argv[1])) {
- for ($i = 0 ; $i < $argv[1] ; $i++) {
- $this->SmartLine->puts(new_guid());
- }
- return;
- }
+ if ($argc > 1 && is_numeric($argv[1])) {
+ for ($i = 0 ; $i < $argv[1] ; $i++) {
+ $this->SmartLine->puts(new_guid());
+ }
+ return;
+ }
- $this->SmartLine->puts(new_guid());
+ $this->SmartLine->puts(new_guid());
}
}
///
/// Requests
///
class RequestsSmartLineCommand extends SmartLineCommand {
public function run ($argv, $argc) {
- global $CurrentPerso;
- $force = ($argc > 1) && ($argv[1] == "-f" || $argv[1] == "--force");
- if ($force || (array_key_exists('site.requests', $CurrentPerso->flags) && $CurrentPerso->flags['site.requests'])) {
- global $controller;
- $controller = 'controllers/persorequest.php';
- } else {
- $this->SmartLine->puts("No request waiting.");
- }
+ global $CurrentPerso;
+ $force = ($argc > 1) && ($argv[1] == "-f" || $argv[1] == "--force");
+ if ($force || (array_key_exists('site.requests', $CurrentPerso->flags) && $CurrentPerso->flags['site.requests'])) {
+ global $controller;
+ $controller = 'controllers/persorequest.php';
+ } else {
+ $this->SmartLine->puts("No request waiting.");
+ }
+ }
+}
+
+///
+/// Settings
+///
+
+class SettingsSmartLineCommand extends SmartLineCommand {
+ public function run ($argv, $argc) {
+ if (headers_sent()) {
+ global $controller;
+ $controller = 'controllers/settings.php';
+ } else {
+ header('location: ' . get_url('settings'));
+ }
}
}
///
/// goto
///
class GotoSmartLineCommand extends SmartLineCommand {
public function run ($argv, $argc) {
global $CurrentPerso;
if ($argc == 1) {
$this->SmartLine->puts("Where do you want to go?", STDERR);
return;
}
require_once("includes/geo/location.php");
try {
$place = new GeoLocation($argv[1]);
} catch (Exception $ex) {
$this->SmartLine->puts($ex->getMessage(), STDERR);
return;
}
if ($place->equals($CurrentPerso->location_global)) {
$this->SmartLine->puts("You're already there.");
return;
}
if (!$place->exists()) {
$this->SmartLine->puts("This place doesn't seem to exist.");
return;
}
$this->SmartLine->puts("TODO: code travel assistant");
}
}
///
/// list
///
class ListSmartLineCommand extends SmartLineCommand {
public function run ($argv, $argc) {
if ($argc == 1) {
$this->SmartLine->puts("Available lists: bodies, locations, places");
return;
}
switch ($objects = $argv[1]) {
case 'bodies':
$list = $this->get_list(TABLE_BODIES, "CONCAT('B', body_code)", "body_name");
$this->SmartLine->puts($list);
break;
case 'locations':
$list = $this->get_list(TABLE_LOCATIONS, "location_code", "location_name");
$this->SmartLine->puts($list);
break;
case 'places':
if ($argv[2] == "-a" || $argv[2] == "--all") {
//Global bodies places list
$list = $this->get_list(TABLE_PLACES, "CONCAT('B', body_code, place_code)", "place_name");
} else {
//Local places (or equivalent) list
global $CurrentPerso;
switch ($CurrentPerso->location_global[0]) {
case 'B':
$body_code = substr($CurrentPerso->location_global, 1, 5);
$list = $this->get_list(TABLE_PLACES, "CONCAT('B', body_code, place_code)", "place_name", "body_code = $body_code");
break;
case 'S':
$this->SmartLine->puts("I don't have a map of the spaceship.", STDERR);
return;
default:
$this->SmartLine->puts("Unknown location type. Can only handle B or S.", STDERR);
return;
}
}
$this->SmartLine->puts($list);
break;
default:
$this->SmartLine->puts("Unknown objects to list: $objects", STDERR);
}
}
public function get_list ($table, $key, $value, $where = null) {
global $db;
$sql = "SELECT $key as `key`, $value as value FROM $table ";
if ($where) $sql .= "WHERE $where ";
$sql .= "ORDER BY `key` ASC";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to fetch list", '', __LINE__, __FILE__, $sql);
}
while ($row = $db->sql_fetchrow($result)) {
$rows .= "<tr><td>$row[key]</td><td>$row[value]</td></tr>";
}
$this->SmartLine->truncate(STDERR);
return "<table cellspacing=\"8\"><thead style=\"color: white\" scope=\"row\"><tr><th>Key</th><th>Value</th></thead><tbody>$rows</tbody></table>";
}
}
///
/// unixtime
///
class UnixTimeSmartLineCommand extends SmartLineCommand {
public function run ($argv, $argc) {
date_default_timezone_set('UTC');
if ($argc == 1) {
$this->SmartLine->puts(time());
} elseif ($argc == 2 && is_numeric($argv[1])) {
$this->SmartLine->puts(strftime("%Y-%m-%d %X", $argv[1]));
} else {
array_shift($argv);
$date = implode(' ', $argv);
if ($time = strtotime($date) !== false) {
$this->SmartLine->puts("Unixtime from $date: <span class=\"highlight\">$time</span>");
} else {
$this->SmartLine->puts("$date isn't a unixtime nor a valid date strtotime is able to parse.", STDERR);
}
}
}
}
///
/// invite
///
class InviteSmartLineCommand extends SmartLineCommand {
public function run ($argv, $argc) {
require_once('includes/objects/invite.php');
global $CurrentUser, $CurrentPerso;
$command = ($argc > 1) ? strtolower($argv[1]) : '';
switch ($command) {
case 'list':
$codes = Invite::get_invites_from($CurrentPerso->id);
if (!count($codes)) {
$this->SmartLine->puts("No invite code.");
} else {
foreach ($codes as $code) {
$this->SmartLine->puts($code);
}
}
break;
case 'add':
case '':
$code = Invite::create($CurrentUser->id, $CurrentPerso->id);
$url = get_server_url() . get_url('invite', $code);
$this->SmartLine->puts("New invite code created: $code<br />Invite URL: $url");
break;
case 'del':
$code = $argv[2];
if (!preg_match("/^([A-Z]){3}([0-9]){3}$/i", $code)) {
$this->SmartLine->puts("Invalid code format. Use invite list to get all your invite codes.", STDERR);
} else {
$invite = new Invite($code);
if ($CurrentPerso->id == $invite->from_perso_id) {
$invite->delete();
$this->SmartLine->puts("Deleted");
} else {
$this->SmartLine->puts("Invalid code. Use invite list to get all your invite codes.", STDERR);
}
}
break;
default:
$this->SmartLine->puts("Usage: invite [add|list|del <code>]", STDERR);
break;
}
}
}
?>
\ No newline at end of file
diff --git a/includes/objects/user.php b/includes/objects/user.php
--- a/includes/objects/user.php
+++ b/includes/objects/user.php
@@ -1,169 +1,184 @@
<?php
/*
* User class
*
* 0.1 2010-01-27 00:33 Autogenerated by Pluton Scaffolding
* 0.2 2010-02-18 11:25 Compliance with strict mode
*
+ * [DESIGN BY CONTRACT NOTE] No more than one OpenID per user
+ *
* @package Zed
* @copyright Copyright (c) 2010, Dereckson
* @license Released under BSD license
* @version 0.1
*
*/
class User {
public $id;
public $name;
public $password;
public $active = 0;
public $actkey;
public $email;
public $regdate;
/*
* Initializes a new instance
* @param int $id the primary key
*/
function __construct ($id = null) {
if ($id) {
$this->id = $id;
$this->load_from_database();
}
}
/*
* Loads the object User (ie fill the properties) from the $_POST array
*/
function load_from_form () {
if (array_key_exists('name', $_POST)) $this->name = $_POST['name'];
if (array_key_exists('password', $_POST)) $this->password = $_POST['password'];
if (array_key_exists('active', $_POST)) $this->active = $_POST['active'];
if (array_key_exists('actkey', $_POST)) $this->actkey = $_POST['actkey'];
if (array_key_exists('email', $_POST)) $this->email = $_POST['email'];
if (array_key_exists('regdate', $_POST)) $this->regdate = $_POST['regdate'];
}
/*
* Loads the object User (ie fill the properties) from the database
*/
function load_from_database () {
global $db;
$sql = "SELECT * FROM " . TABLE_USERS . " WHERE user_id = '" . $this->id . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query users", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "User unkwown: " . $this->id;
return false;
}
$this->name = $row['username'];
$this->password = $row['user_password'];
$this->active = $row['user_active'];
$this->actkey = $row['user_actkey'];
$this->email = $row['user_email'];
$this->regdate = $row['user_regdate'];
return true;
}
/*
* Saves to database
*/
function save_to_database () {
global $db;
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$name = $db->sql_escape($this->name);
$password = $db->sql_escape($this->password);
$active = $db->sql_escape($this->active);
$actkey = $db->sql_escape($this->actkey);
$email = $db->sql_escape($this->email);
$regdate = $this->regdate ? "'" . $db->sql_escape($this->regdate) . "'" : 'NULL';
//Updates or inserts
$sql = "REPLACE INTO " . TABLE_USERS . " (`user_id`, `username`, `user_password`, `user_active`, `user_actkey`, `user_email`, `user_regdate`) VALUES ($id, '$name', '$password', '$active', '$actkey', '$email', $regdate)";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save", '', __LINE__, __FILE__, $sql);
}
if (!$id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
}
/*
* Updates the specified field in the database record
*/
function save_field ($field) {
global $db;
if (!$this->id) {
message_die(GENERAL_ERROR, "You're trying to update a record not yet saved in the database");
}
$id = $db->sql_escape($this->id);
$value = $db->sql_escape($this->$field);
$sql = "UPDATE " . TABLE_USERS . " SET `$field` = '$value' WHERE user_id = '$id'";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save $field field", '', __LINE__, __FILE__, $sql);
}
}
//Generates a unique user id
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
+
+ /*
+ * Fills password field with encrypted version of the specified clear password
+ * @param string $newpassword The user's new password
+ */
public function set_password ($newpassword) {
$this->password = md5($newpassword);
}
/*
+ * Deletes OpenID for this user
+ */
+ public function delete_OpenID () {
+ $this->set_OpenID('');
+ }
+
+ /*
* Sets OpenID for this user
* @param string $url OpenID endpoint URL
*/
public function set_OpenID ($url) {
+ global $db;
if (!$this->id) $this->save_to_database();
$url = $db->sql_escape($url);
$sql = "DELETE FROM " . TABLE_USERS_OPENID . " WHERE user_id = $this->id";
if (!$db->sql_query($sql))
message_die(SQL_ERROR, "Can't delete old OpenID", '', __LINE__, __FILE__, $sql);
- $sql = "INSERT INTO " . TABLE_USERS_OPENID . " (openid_url, user_id) VALUES ('$url', $this->id)";
- if (!$db->sql_query($sql))
- message_die(SQL_ERROR, "Can't add new OpenID", '', __LINE__, __FILE__, $sql);
+ if ($url != '') {
+ $sql = "INSERT INTO " . TABLE_USERS_OPENID . " (openid_url, user_id) VALUES ('$url', $this->id)";
+ if (!$db->sql_query($sql))
+ message_die(SQL_ERROR, "Can't add new OpenID", '', __LINE__, __FILE__, $sql);
+ }
}
//Checks if a login is available
public static function is_available_login ($login) {
global $db;
$sql = "SELECT COUNT(*) FROM " . TABLE_USERS . " WHERE username LIKE '$login' LOCK IN SHARE MODE;";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Utilisateurs non parsable", '', __LINE__, __FILE__, $sql);
}
$row = $db->sql_fetchrow($result);
return ($row[0] ? false : true);
}
//Gets username from specified e-mail
public static function get_username_from_email ($mail) {
global $db;
$sql = "SELECT username FROM " . TABLE_USERS . " WHERE user_email LIKE '$mail' LOCK IN SHARE MODE;";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Utilisateurs non parsable", '', __LINE__, __FILE__, $sql);
}
if ($row = $db->sql_fetchrow($result)) {
return $row['username'];
}
return false;
}
}
?>
\ No newline at end of file
diff --git a/includes/settings/preferences.xml b/includes/settings/preferences.xml
--- a/includes/settings/preferences.xml
+++ b/includes/settings/preferences.xml
@@ -1,135 +1,148 @@
<?xml version="1.0" encoding="UTF-8"?>
<settings>
<page id="account" title="Account">
<setting id="username">
<key>Username</key>
<field>text</field>
<object>CurrentUser</object>
<property>name</property>
</setting>
<setting id="password">
<key>Password</key>
<field>password</field>
<object>CurrentUser</object>
- <method>set_password</method>
+ <handler>
+ <get>
+ return "";
+ </get>
+ <set>
+<![CDATA[
+if ($value) {
+ global $CurrentUser;
+ $CurrentUser->set_password($value);
+ return true;
+}
+]]>
+ </set>
+ </handler>
</setting>
<setting id="email">
<key>Email</key>
<field>text</field>
<object>CurrentUser</object>
<property>email</property>
</setting>
<setting id="OpenID">
<key>OpenID</key>
<field>text</field>
<handler>
<get>
<![CDATA[
global $db, $CurrentUser;
$sql = "SELECT openid_url FROM users_openid WHERE user_id = $CurrentUser->id LIMIT 1";
return $db->sql_query_express($sql);
]]>
</get>
<set>
<![CDATA[
global $db, $CurrentUser, $smarty;
$openid = $db->sql_escape($value);
-$sql = "SELECT user_id FROM users_openid WHERE open_id_url LIKE '$openid'";
+$sql = "SELECT user_id FROM users_openid WHERE openid_url LIKE '$openid'";
if ($user_id = $db->sql_query_express($sql)) {
if ($user_id == $CurrentUser->id) {
$smarty->assign('WAP', "This OpenID is already linked to your account.");
} else {
$smarty->assign('WAP', "This OpenID is currently linked to another account.");
supralog('security', "User tried to add OpenID $openid which belongs to $user_id", "preferences");
}
return false;
}
$CurrentUser->set_OpenID($value);
return true;
]]>
</set>
</handler>
</setting>
</page>
<page id="perso" title="Information">
<setting id="longname">
<key>Name</key>
<field>text</field>
<object>CurrentPerso</object>
<property>name</property>
</setting>
<setting id="nickname">
<key>Nickname</key>
<field>validationtext</field>
<regExp>[a-z][a-z0-9 ]+</regExp>
<object>CurrentPerso</object>
<property>nickname</property>
</setting>
<setting id="race">
<key>Race</key>
<field>text</field>
<object>CurrentPerso</object>
<property>race</property>
</setting>
<setting id="sex">
<key>Sex</key>
<field>filteredlist</field>
<object>CurrentPerso</object>
<property>sex</property>
<choices>
<choice>
<key>male</key>
<value>M</value>
</choice>
<choice>
<key>female</key>
<value>F</value>
</choice>
<choice>
<key>neutral</key>
<value>N</value>
</choice>
<choice>
<key>both</key>
<value>2</value>
</choice>
</choices>
</setting>
</page>
<page id="smartline" title="SmartLine">
<setting id="show">
<key>SmartlineShow</key>
<field>checkbox</field>
<handler>
<set><![CDATA[
global $CurrentPerso;
$flag_value = $value ? 1 : 0;
$CurrentPerso->set_flag('site.smartline.show', $flag_value);
return true;
]]></set>
<get><![CDATA[
global $CurrentPerso;
return (bool)$CurrentPerso->get_flag('site.smartline.show', true);
]]></get>
</handler>
</setting>
<setting id="method">
<key>SmartlineMethod</key>
<field>checkbox</field>
<handler>
<set><![CDATA[
global $CurrentPerso;
$CurrentPerso->set_flag('site.smartline.method', $value ? 'post' : 'get');
return true;
]]></set>
<get><![CDATA[
global $CurrentPerso;
$flag = $CurrentPerso->get_flag('site.smartline.method', 'post');
return $flag != "get";
]]></get>
</handler>
</setting>
</page>
</settings>
\ No newline at end of file
diff --git a/includes/settings/settings.php b/includes/settings/settings.php
--- a/includes/settings/settings.php
+++ b/includes/settings/settings.php
@@ -1,60 +1,60 @@
<?php
/*
* Zed
* (c) 2010, Dereckson, some rights reserved
* Released under BSD license
*
* Settings
*/
//The method to call in your objects, to save data.
define("SETTINGS_SAVE_METHOD", "save_to_database");
require_once("page.php");
/*
* @package Zed
* @subpackage settings
*/
class Settings {
/*
* @var string the file path
*/
public $file;
/*
* @var Array a collection of SettingsPage items.
*/
public $pages;
/*
* Initializes a new instance of Settings class
*/
function __construct ($xmlFile) {
//Opens .xml
if (!file_exists($xmlFile)) {
message_die(GENERAL_ERROR, "$xmlFile not found.", "Settings load error");
}
$this->file = $xmlFile;
- $this->parse();
+ $this->parse();
}
/*
* Parses XML file
*/
function parse () {
//Parses it
$xml = simplexml_load_file($this->file);
foreach ($xml->page as $page) {
//Gets page
$page = SettingsPage::from_xml($page);
//Adds to sections array
$this->pages[$page->id] = $page;
}
}
}
?>
\ No newline at end of file
diff --git a/index.php b/index.php
--- a/index.php
+++ b/index.php
@@ -1,206 +1,207 @@
<?php
/*
* Zed
* (c) 2010, Dereckson, some rights reserved
* Released under BSD license
*
* Application entry point
*/
////////////////////////////////////////////////////////////////////////////////
///
/// Initialization
///
//Pluton library
include('includes/core.php');
//Session
$IP = encode_ip($_SERVER["REMOTE_ADDR"]);
require_once('includes/story/story.php'); //this class can be stored in session
session_start();
$_SESSION[ID] = session_id();
session_update(); //updates or creates the session
include("includes/login.php"); //login/logout
$CurrentUser = get_logged_user(); //Gets current user infos
//Gets current perso
require_once('includes/objects/perso.php');
if ($perso_id = $CurrentUser->session['perso_id']) {
$CurrentPerso = new Perso($perso_id);
}
//Skin and accent to load
define('THEME', $CurrentUser->session['Skin']);
define('ACCENT', $CurrentUser->session['Skin_accent']);
//Loads Smarty
require('includes/Smarty/Smarty.class.php');
$smarty = new Smarty();
$current_dir = dirname(__FILE__);
$smarty->template_dir = $current_dir . '/skins/' . THEME;
$smarty->compile_dir = $current_dir . '/cache/compiled';
$smarty->cache_dir = $current_dir . '/cache';
$smarty->config_dir = $current_dir;
$smarty->config_vars['StaticContentURL'] = $Config['StaticContentURL'];
//Loads language files
initialize_lang();
lang_load('core.conf');
//Gets URL
$url = get_current_url_fragments();
//If the user isn't logged in (is anonymous), prints login/invite page & dies.
if ($CurrentUser->id < 1000) {
include('controllers/anonymous.php');
exit;
}
////////////////////////////////////////////////////////////////////////////////
///
/// Perso selector
///
//Handles form
if ($_POST['form'] == 'perso.create') {
$perso = new Perso();
$perso->load_from_form();
$perso->user_id = $CurrentUser->id;
//Validates forms
if (!$perso->name) $errors[] = lang_get("NoFullnameSpecified");
if (!$perso->race) {
$errors[] = lang_get("NoRaceSpecified");
$perso->race = "being";
}
if (!$perso->sex) $errors[] = lang_get("NoSexSpecified");
if (!$perso->nickname) {
$errors[] = lang_get("NoNicknameSpecified");
} else if (!Perso::is_available_nickname($perso->nickname)) {
$errors[] = lang_get("UnavailableNickname");
}
//Save or prints again forms
if (!$errors) {
//Saves perso, logs in
$perso->save_to_database();
$smarty->assign('NOTIFY', lang_get('NewCharacterCreated'));
$CurrentPerso = $perso;
set_info('perso_id', $perso->id);
$CurrentPerso->set_flag("site.lastlogin", $_SERVER['REQUEST_TIME']);
//Notifies inviter
} else {
$smarty->assign('WAP', join("<br />", $errors));
$smarty->assign('perso', $perso);
}
}
if ($_GET['action'] == 'perso.logout' && $CurrentPerso != null) {
//User wants to change perso
$CurrentPerso->on_logout();
$CurrentPerso = null;
} elseif ($_GET['action'] == 'perso.select') {
//User have selected a perso
$CurrentPerso = new Perso($_GET['perso_id']);
if ($CurrentPerso->user_id != $CurrentUser->id) {
//Hack
message_die(HACK_ERROR, "This isn't your perso.");
}
$CurrentPerso->on_select();
}
if (!$CurrentPerso) {
switch ($count = Perso::get_persos_count($CurrentUser->id)) {
case 0:
//User have to create a perso
$smarty->display("perso_create.tpl");
exit;
case 1:
//Autoselects only perso
$CurrentPerso = Perso::get_first_perso($CurrentUser->id);
$CurrentPerso->on_select();
break;
default:
//User have to pick a perso
$persos = Perso::get_persos($CurrentUser->id);
$smarty->assign("PERSOS", $persos);
$smarty->display("perso_select.tpl");
$_SESSION['UserWithSeveralPersos'] = true;
exit;
}
}
//Assigns current perso object as Smarty variable
$smarty->assign('CurrentPerso', $CurrentPerso);
////////////////////////////////////////////////////////////////////////////////
///
/// Tasks to execute before calling the URL controller:
/// - assert the perso is somewhere
/// - executes the smartline
///
//If the perso location is unknown, ejects it to an asteroid
if (!$CurrentPerso->location_global) {
require_once('includes/geo/place.php');
$smarty->assign('NOTIFY', lang_get('NewLocationNotify'));
$CurrentPerso->move_to(GeoPlace::get_start_location());
}
//SmartLine
include("includes/SmartLine/ZedSmartLine.php");
//Redirects user to user request controller if site.requests flag on
if (defined('PersoSelected') && array_key_exists('site.requests', $CurrentPerso->flags) && $CurrentPerso->flags['site.requests']) {
include('controllers/persorequest.php');
}
////////////////////////////////////////////////////////////////////////////////
///
/// Calls the specific controller to serve the requested page
///
switch ($controller = $url[0]) {
case '':
include('controllers/home.php');
break;
case 'request':
case 'page':
case 'explore':
case 'ship':
+ case 'settings':
include("controllers/$controller.php");
break;
case 'who':
include('controllers/profile.php'); //Azhàr controller
break;
case 'push':
include('controllers/motd.php'); //Azhàr controller
break;
case 'quux':
//It's like a test/debug console/sandbox, you put what you want into
if (file_exists('dev/quux.php')) {
include('dev/quux.php');
} else {
message_die(GENERAL_ERROR, "Quux lost in Hollywood.", "Nay");
}
break;
default:
//TODO: returns a 404 error
dieprint_r($url, 'Unknown URL');
}
?>
\ No newline at end of file
diff --git a/lang/en/core.conf b/lang/en/core.conf
--- a/lang/en/core.conf
+++ b/lang/en/core.conf
@@ -1,167 +1,178 @@
#Zed language config file
#Language: English
#Code: en
#Author: Dereckson
###
### Site configuration
###
SiteTitle = Zed
Product = "<strong>Zed 0.1</strong>, alpha technical preview"
###
### General stuff
###
_t = ":"
Save = Save
###
### Login
###
Login = Login
Password = Password
OK = OK
LoginNotFound = Login not found.
IncorrectPassword = Incorrect password.
JaMata = Ja mata!
WelcomeBack = Welcome back.
OpenID = OpenID
Logout = Logout
###
### Errors
###
UnauthorizedAccess = "Unauthorized access"
SQLError = "SQL Error"
line = line
Error = Error
BackToHome = "Back to homepage"
+GeneralError = General error
+PageNotFound = "Page not found"
+
+#Keep those two lines in English, to help to identify error screens in any lang
FatalErrorScreen = Fatal error screen
FatalErrorInterrupt = Fatal error breaking screen
-GeneralError = General error
-
-PageNotFound = "Page not found"
###
### Homepage
###
Welcome = Welcome
WelcomeText = "<p>Welcome to the Zed alpha technical preview. Zed, it's a mix between a gallery, a place to meet new and existing friends, with some RPG inspiration.<br />
The concept is to have each information stored at physical places in a virtual world, like the 80s cyberspace vision. Another goal is to build a community sharing values like cooperation, freedom, ethic.</p>"
###
### Homepage - messages
###
#messages.tpl, Reply
Reply = Reply
#messages.tpl, the X link title
DeleteThisMessage = Delete this message
#home.php, messages error
MessageDeleted = Message deleted.
NotYourMessage = This message is not one of yours.
MessageAlreadyDeleted = Message already deleted.
###
### Account create
###
CreateAccountTitle = Create an account
CreateAccountIntro = "<p>Welcome to Zed.<br />To get an account, you need an invite code. To get an invite code, ask who tell you about Zed.</p>"
YourLogin = The login you want
InviteCode = Your invite code
YourEmail = Your e-mail
EnterInviteCodePromptMessage = "Your invite code is something like ABC123."
EnterUsernamePromptMessage = "Enter your username, in lowercase (11 characters max.).<br />It's your usual username, not your character name."
EnterEmailPromptMessage = "Enter your e-mail. It will used (1) as password recovery method (2) to send you notification of new messages or events you've configured.<br />We don't like spam, so we take all the measures to protect your mail."
IncorrectInviteCode = "Your invite code's format isn't valid. It's something like ABC123."
InviteCodeAlreadyClaimed = "This invite code were valid. But it have already been claimed."
CreateAccountImageTitle = "Zed is for human being. But it's also for people defining themselves like other beings than humans."
CreateAccountImageAlt = "A strange-looking white picture. An half circle from top right to bottom right, then the brush come back in spirale to create a big white spot. Some brushes effects add fringes at start and end. Grayscale spots have been added in main circle."
MissingUsername = "You need to provide a login."
LoginUnavailable = "This login is already taken."
MissingPassword = "You need to provide a password."
InviteHaveBeenClaimed = "Your invite %s have just been claimed."
AccountCreated = "Your account is created. Welcome to Zed."
###
### Perso create/select
###
NewCharacterCreated = New character created
CreateCharacter = Create a character
EditCharacter = Edit %s information
+FullName = Full name
+Nickname = Nickname
+
+Sex = Sex
+Male = Male
+Female = Female
+Neutral = Neutral
+Hermaphrodit = Hermaphrodit
+Race = Race
+
NoSexSpecified = "Pick a sex, or '<em>Neutral</em>' if you don't want to tell it."
NoNicknameSpecified = "You must pick a nickname, it's like your login to identify your character."
NoFullnameSpecified = "All beings must have a name."
NoRaceSpecified = "You've to specify a race: '<em>humanoid</em>' for human and co.<br />If you don't want to specify a race, use the generic '<em>being</em>'."
NicknameUnavailable = "This nickname is already used.<br />Choose a more original one."
PickPerso = Pick your perso
SwapPerso = "Swap perso (%s's logout)"
NewLocationNotify = "You're slowly awaking in a place you don't recognize."
###
### Places
###
CurrentLocation = "Current location"
UnknownBody = "Unknown asteroid"
UnknownPlace = "Unknown place"
WherePlace = "%s @ %s"
SpaceAround = "Space around %s"
hypership = hypership
asteroid = asteroid
moon = moon
planet = planet
star = star
orbital = orbital
place = place
ship = ship
###
### Stories
###
InvalidStoryGUID = "In story mode, you can't use previous/back URL."
ExpiredStorySession = "Story choices URL are temporary.<br />You can't bookmark them or use in another session."
###
### Requests
###
Request = Request
Title = Title
###
### MOTD
###
PushMessage = Push a message to the header
TextToAdd = Text to add
TextToAddWarning = Warning: once published, it can't be (easily) removed.
Rendering = How it will be printed?
RenderingWhere = "At the top right header corner:"
DummyPlaceholder = Here your message.
Push = Push
Published = Published :)
\ No newline at end of file
diff --git a/lang/en/settings.conf b/lang/en/settings.conf
--- a/lang/en/settings.conf
+++ b/lang/en/settings.conf
@@ -1,39 +1,41 @@
#Zed language config file - Settings
#Language: English
#Code: en
#Author: Dereckson
###
### Generalities
###
-
+Settings = Settings
SaveSettings = "Save settings"
###
### Account information
###
[account]
Account = "Account information"
Username = "Login"
Email = "Mail"
+PasswordConfirm = "one more time"
###
### Perso information
###
[perso]
Information = "Your information"
Name = Name
Nickname = "Username (lowercase)"
Race = Species
Sex = Sex
male = male
female = female
neutral = "neutral or asexual"
both = "hermaphrodite"
###
### SmartLine
###
[smartline]
+SmartLine = SmartLine
SmartlineShow = "Shows the SmartLine at the bottom of the screen"
SmartlineMethod = "Sends a HTTP POST request instead a HTTP GET submitting SmartLine form"
\ No newline at end of file
diff --git a/lang/fr/core.conf b/lang/fr/core.conf
--- a/lang/fr/core.conf
+++ b/lang/fr/core.conf
@@ -1,157 +1,193 @@
#Zed language config file
#Language: English
#Code: fr
#Author: Dereckson
###
### Site configuration
###
SiteTitle = Zed
Product = "<strong>Zed 0.1</strong>, alpha technical preview"
###
### General stuff
###
_t = " :"
Save = Enregistrer
###
### Login
###
Login = Login
Password = Password
OK = OK
LoginNotFound = Login introuvable.
IncorrectPassword = Mot de passe incorrect.
JaMata = Ja mata!
WelcomeBack = Welcome back.
OpenID = OpenID
Logout = Déconnexion
###
+### Erreurs
+###
+
+UnauthorizedAccess = "Accès non autorisé"
+SQLError = "Erreur SQL"
+line = ligne
+Error = Erreur
+BackToHome = "Retourner à la page d'accueil"
+
+GeneralError = "Erreur générale"
+PageNotFound = "Cette page n'existe pas."
+
+#Veuillez laisser en anglais, pour identifier plus clairement les erreurs.
+FatalErrorScreen = Fatal error screen
+FatalErrorInterrupt = Fatal error breaking screen
+
+###
### Homepage
###
Welcome = Bienvenue
WelcomeText = "<p>Bienvenue sur la version alpha de Zed, un hybride un peu étrange entre une galerie, un endroit où rencontrer ses amis ou s'en faire de nouveaux, avec une légère inspiration RPG, dans un environnement galactique inspiré des romans de la Culture de Iain M. Banks.</p>
<p>Le concept est d'expérimenter ce qui se passe lorsque chaque information est dans un espace précis, un peu comme la vision cyberpunk des années 80 du cyberespace. Un autre but est de créer une communauté partagant des valeurs de respect, de coopération, de liberté et d'éthique.</p>"
###
### Homepage - Messages
###
#messages.tpl, Reply
Reply = Répondre
#messages.tpl, the X link title
DeleteThisMessage = Effacer ce message
#home.php, messages error
MessageDeleted = Message effacé.
NotYourMessage = Hey, ce message appartient à autrui !
MessageAlreadyDeleted = Message déjà effacé
###
### Errors
###
UnauthorizedAccess = "Accès non autorisé"
SQLError = "Erreur dans la requête SQL"
line = ligne
Error = Erreur
BackToHome = "Retour à la page d'accueil"
FatalErrorScreen = Fatal error screen
FatalErrorInterrupt = Fatal error screen (interruption)
GeneralError = "Erreur"
PageNotFound = "Cette page n'existe pas."
###
### Account create
###
CreateAccountTitle = Créer un compte
CreateAccountIntro = "<p>Bienvenue sur Zed.<br />Zed est un site privé uniquement accessible suite à l'invitation d'un membre.</p>"
YourLogin = Le login de votre choix
InviteCode = "Votre code d'invitation"
YourEmail = Votre adresse e-mail
EnterInviteCodePromptMessage = "Votre code d'invitation ressemble à ABC123."
EnterUsernamePromptMessage = "Votre login sera en minuscule et d'au plus onze caractères.<br />Il sera uniquement utilisé pour vous identifier, votre login NE sera PAS le nom de votre perso."
EnterEmailPromptMessage = "Votre adresse sera utilisée pour vous permettre de modifier votre mot de passe en cas d'oubli. Vous pourrez également configurer des notifications en cas de nouveau message & co, mais par défaut c'est désactivé."
IncorrectInviteCode = "Format invalide du code d'invitation,<br />recherchez quelque chose ressemblant à ABC123."
+InviteCodeAlreadyClaimed = "Ce code d'invitation était certes valide mais a déjà été utilisé par autrui."
+
+CreateAccountImageTitle = "Zed est un site pour les êtres humains. Mais aussi pour tous ceux qui se définissent autrement que comme humain."
+CreateAccountImageAlt = "Une étrange créature blanche. Un demi cercle allant d'en haut à droite vers le bas à droite ; la brosse poursuit ensuite en spirale pour créer une grosse tâche blanche. Les effets de la brosse ajoutent au début et à la fin des franges. Des tâches grises ont été rajoutées au centre."
+
+MissingUsername = "Vous avez oublié de spécifier le login."
+LoginUnavailable = "Ce login est déjà utilisé."
+MissingPassword = "Vous avez oublié de spécifier le mot de passe."
+InviteHaveBeenClaimed = "Votre invitation %s a été acceptée."
+AccountCreated = "Votre compte a été créé. Bienvenue sur Zed."
###
### Perso create/select
###
NewCharacterCreated = Nouveau perso créé.
CreateCharacter = Nouveau perso
EditCharacter = Éditer les infos de %s
-NoSexSpecified = "Pick a sex, or '<em>Neutral</em>' if you don't want to tell it."
-NoNicknameSpecified = "You must pick a nickname, it's like your login to identify your character."
-NoFullnameSpecified = "All beings must have a name."
-NoRaceSpecified = "You've to specify a race: '<em>humanoid</em>' for human and co.<br />If you don't want to specify a race, use the generic '<em>being</em>'."
-NicknameUnavailable = "This nickname is already used.<br />Choose a more original one."
+FullName = Prénom et nom
+Nickname = Pseudonyme
+
+Sex = Sexe
+Male = Masculin
+Female = Féminin
+Neutral = Neutre
+Hermaphrodit = Hermaphrodite
+Race = Race
+
+NoSexSpecified = "Quel est votre sexe ? Si vous ne souhaitez pas le dévoiler, vous pouvez toujours utiliser '<em>Neutral</em>'."
+NoNicknameSpecified = "Vous devez choisir un pseudo. C'est comme un login, pour votre perso."
+NoFullnameSpecified = "Tous les êtres doivent avoir un nom."
+NoRaceSpecified = "Spécifiez une race: '<em>humanoid</em>' pour les humains et humanoïdes.<br />Si vous ne souhaitez pas spécifier de race, vous pouvez utiliser '<em>being</em>'."
+NicknameUnavailable = "Ce pseudo est déjà utilisé.<br />Veuillez en choisir un plus original."
PickPerso = "Sélectionnez votre perso"
SwapPerso = "Changer de perso (déco %s)"
NewLocationNotify = "Vous vous réveillez lentement dans un endroit inconnu"
###
### Places
###
CurrentLocation = "Localisateur"
UnknownBody = "Astéroïde inconnu"
UnknownPlace = "Endroit inconnu"
WherePlace = "%2$s, %1$s."
-SpaceAround = "%s et l'espace autour"
+SpaceAround = "%s et l'espace aux alentours"
hypership = hypership
asteroid = astéroïde
moon = lune
planet = planète
star = étoile
orbital = orbitale
place = endroit
ship = vaisseau
###
### Stories
###
InvalidStoryGUID = "En mode récit, il n'est pas possible <br />d'utiliser les boutons précédents et suivants."
ExpiredStorySession = "Les URL de choix sont temporaires.<br />Il n'est pas possible de les bookmark pour y revenir."
###
### Requests
###
Request = Requête
Title = Titre
###
### MOTD
###
-
PushMessage = Publier un message tout en haut
TextToAdd = Texte à ajouter
TextToAddWarning = "Une fois publié, ne peut être facilement enlevé."
Rendering = Aperçu
RenderingWhere = "Coin supérieur droit de la page :"
DummyPlaceholder = Lorem ipsum dolor.
Push = Publier
Published = Publié :)
\ No newline at end of file
diff --git a/lang/fr/footer.conf b/lang/fr/footer.conf
--- a/lang/fr/footer.conf
+++ b/lang/fr/footer.conf
@@ -1,1 +1,11 @@
+#Zed language config file - Footer
+#Language: English
+#Code: fr
+#Author: Dereckson
+
+###
+### SmartLine
+###
+
+[SmartLine]
SmartLineHistory = Historique SmartLine
\ No newline at end of file
diff --git a/lang/fr/profile.conf b/lang/fr/profile.conf
--- a/lang/fr/profile.conf
+++ b/lang/fr/profile.conf
@@ -1,104 +1,100 @@
#Zed language config file - Profiles
#Language: French
#Code: fr
#Author: Dereckson
###
### profile.tpl - main profile
###
-#<img src=".../tel.png" title="Phone number" alt="Tel"... />
-PhoneNumber = Téléphone
-PhoneNumberAlt = Tel
-
#<img src=".../mail.png" title="E-mail" alt="@"... />
Mail = Courriel
MailAlt = @
###
### profile.tpl - communication area
###
DropMessage = Laisser un message
SendMessage = Message privé pour %s
AddComment = Publier un commentaire sur ce profil <!--%s-->
###
### profile.tpl - sidebar - Edit account preferences and profile content
###
EditMyPage = Éditer ma page
EditProfile = Éditer mon texte
EditAccount = Éditer mes infos
ManagePhotos = Gérer mes photos
AddPhoto = Upload une photo
###
### profile_edit.tpl - edit my text
###
ProfileTextTitle = Texte
SaveProfile = Enregistrer mon texte
ProfileFont = Police
Calibri = Calibri (police à chasse variable)
FixedSys = FixedSys (police à chasse fixe)
###
### user_account.tpl - edit my information
###
Login = Login
LongName = Nom complet
UpdateAccountInfo = Mettre à jour mon compte
###
### profile_photo.tpl - photo manager - add a photo to my profile
###
AddPhotoToProfile = Ajouter une photo à mon profil
AddPhotoExplanations = Vous pouvez upload ici toute photo dont vous êtes le sujet principal. Celles-ci seront affichées sur votre profil.<br />Pour partager toute autre photo, placez là quelque part dans la galaxie, comme par exemple dans la tour de Zed.
ShortDescription = Courte description
SafeForWorkLabel = Cochez la case "<strong>safe for work</strong>", si la photo peut être regardée sans problème par tout en chacun depuis tout lieu public.
###
### profile_photo.tpl - photo manager - manage current photos
###
ManageCurrentPhotos = Gérer les photos
-PictureProperties = Picture properties
-EditPictureProperties = Edit this picture description or safe status
-Delete = Delete
-DeleteThisPicture = Delete this picture
+PictureProperties = Propriétés de la photo
+EditPictureProperties = Modifier les propriétés
+Delete = Effacer
+DeleteThisPicture = Effacer cette image
###
### profile_photo_edit.tpl - edit individual photo properties
###
EditPhoto = Photo — Propriétés
PhotoInfo = Info sur cette photo
Description = Description
SafeForWork = Safe for work
UseAsAvatar = Avatar
OtherActions = Autres actions
DeletePicture = Effacer cette photo
BackToPhotoManager = < Retourner au gestionnaire de photos
###
### profile.php
###
UnknownUser = Inconnu au bataillon.
Who = Qui ?
WhoIsUser = Qui est %s?
MessageSent = Message envoyé.
MessageSentSelf = Message personnel envoyé.
CommentPublished = Commentaire publié.
PhotoUploaded = Photo enregistrée.
NotYourPic = Same player, try again.
PictureDeleted = Photo effacée.
PromotedToAvatar = Hop, un nouvel avatar.
-InactivatedUser = Attention, ce compte est encore inactif.
+InactivatedUser = "Attention, ce compte n'est pas encore actif."
diff --git a/lang/fr/settings.conf b/lang/fr/settings.conf
new file mode 100644
--- /dev/null
+++ b/lang/fr/settings.conf
@@ -0,0 +1,48 @@
+#Zed language config file - Settings
+#Language: English
+#Code: fr
+#Author: Dereckson
+
+###
+### Generalities
+###
+Settings = Préférences
+SaveSettings = "Enregistrer les préférences"
+
+###
+### Extra pages not handled by Settings classes
+###
+
+EditProfile = "Texte"
+
+###
+### Account information
+###
+[account]
+Account = "Paramètres de votre compte"
+Username = "Login"
+Email = "E-mail"
+Password = "Mot de passe"
+PasswordConfirm = "(répétez)"
+
+###
+### Perso information
+###
+[perso]
+Information = "Vos infos"
+Name = Votre nom
+Nickname = "Username en minuscule"
+Race = Race
+Sex = Genre
+male = masculin
+female = féminin
+neutral = "neutre ou asexué"
+both = "hermaphrodite"
+
+###
+### SmartLine
+###
+[smartline]
+SmartLine = SmartLine
+SmartlineShow = "Afficher la SmartLine. Elle se positionnera en bas de l'écran."
+SmartlineMethod = "Utilisez une requête HTTP POST en lieu et place d'une requête HTTP GET.<br />Cela renforce la sécurité, au détriment de la facilité de navigation par l'historique."
\ No newline at end of file
diff --git a/skins/zed/perso_create.tpl b/skins/zed/perso_create.tpl
--- a/skins/zed/perso_create.tpl
+++ b/skins/zed/perso_create.tpl
@@ -1,36 +1,36 @@
{include file="perso_header.tpl"}
<div class="grid_16">
<h2>{if $perso->nickname}{sprintf(#EditCharacter#, $perso->nickname)}{else}{#CreateCharacter#}{/if}</h2>
<!-- Edit Perso form -->
<form dojoType="dijit.form.Form" id="PersoForm" method="post" execute="document.getElementById('PersoForm').submit()">
<input type="hidden" name="form" value="perso.create" />
{if 0}
<input type="hidden" name="id" value="{$perso->id}" />
{/if}
<div class="row">
- <label class="firstLabel" for="name">Full name</label>
+ <label class="firstLabel" for="name">{#FullName#}</label>
<input type="text" id="name" name="name" maxlength="255" value="{$perso->name}" dojoType="dijit.form.TextBox" class="long" />
</div>
- <div class="row">
- <label class="firstLabel" for="nickname">Nickname</label>
+ <div class="row">}
+ <label class="firstLabel" for="nickname">{#Nickname#}</label>
<input type="text" id="nickname" name="nickname" maxlength="31" value="{$perso->nickname}" dojoType="dijit.form.TextBox" class="medium" />
</div>
<div class="row">
- <label class="firstLabel" for="race">Race</label>
+ <label class="firstLabel" for="race">{#Race#}</label>
<input type="text" id="race" name="race" maxlength="31" value="{if $perso->race}{$perso->race}{else}humanoid{/if}" dojoType="dijit.form.TextBox" class="medium" />
</div>
<div class="row">
- <label class="firstLabel" for="sex">Sex</label>
+ <label class="firstLabel" for="sex">{#Sex#}</label>
<select id="sex" name="sex" dojoType="dijit.form.FilteringSelect" class="medium">
- <option value="M">Male</option>
- <option value="F">Female</option>
- <option value="N">Neutral</option>
- <option value="2">Hermaphrodit</option>
+ <option value="M">{#Male#}</option>
+ <option value="F">{#Female#}</option>
+ <option value="N">{#Neutral#}</option>
+ <option value="2">{#Hermaphrodit#}</option>
</select>
</div>
<div class="row">
- <button dojoType="dijit.form.Button" iconClass="dijitEditorIcon dijitEditorIconSave" type="submit" value="Save" />Save</button>
+ <button dojoType="dijit.form.Button" iconClass="dijitEditorIcon dijitEditorIconSave" type="submit" value="Save" />{#Save#}</button>
</div>
</form>
</div>
{include file="perso_footer.tpl"}
\ No newline at end of file
diff --git a/skins/zed/profile.tpl b/skins/zed/profile.tpl
--- a/skins/zed/profile.tpl
+++ b/skins/zed/profile.tpl
@@ -1,77 +1,77 @@
<!-- Profile -->
<div class="clear">&nbsp;</div>
<div class="grid_11 alpha">
<!-- Profile header -->
<div class="profile_id clearfix">
<h1 class="profile_nick">{$perso->name}</h1>
<div class="profile_info">
{$perso->location}&nbsp;<br />
{if $perso->is_online()}Online{/if}
</div>
</div>
<div class="clear">&nbsp;</div>
<div class="profile">
{if $PICS}
<!-- Photos -->
<div class="profile_photos">
{foreach from=$PICS item=photo}
<a rel="lightbox" href="{$URL_PICS}/{$photo->name}" title="{$photo->description}"><img src="{$URL_PICS}/tn/{$photo->name}" alt="{$photo->description}" /></a>
{/foreach}
</div>
{/if}
<!-- Text -->
<div class="profile_text{if $PROFILE_FIXEDWIDTH} fixedwidth{/if}">{if $PROFILE_TEXT != ""}{if $PROFILE_FIXEDWIDTH}{$PROFILE_TEXT}{else}{$PROFILE_TEXT|nl2br}{/if}{else}{if $PROFILE_SELF}<a href="{get_url('who')}/edit/profile">{/if}<img src="/skins/VacuumCleanerBridge/images/empty_profile.png" width="642" height="392" alt="Be creative ! Fill this space with your best words." />{if $PROFILE_SELF}</a>{/if}{/if}</div>
<div class="profile_separator_light"></div>
<div class="profile_message">
<h2 id="Message">{#DropMessage#}</h2>
<form method="post" action="{get_url('who')}/{$perso->nickname}">
<div class="grid_4 alpha">
<input type="radio" name="message_type" value="private_message" checked onclick="document.getElementById('MessageSubmit').value = '{#Send#}';">{sprintf(#SendMessage#, $NAME)}
</div>
<div class="grid_6 omega">
<input type="radio" name="message_type" value="profile_comment" onclick="document.getElementById('MessageSubmit').value = '{#Publish#}';">{sprintf(#AddComment#, $NAME)}
</div>
<p><textarea rows="7" cols="64" name="message"></textarea></p>
<p><input id="MessageSubmit" type="submit" name="MessageSubmit" value="{#Send#}" /></p>
</form>
</div>
</div>
</div>
<!-- User content -->
<div class="grid_5 omega">
<div class="sidebar_border"></div>
<div id="sidebar">
<div class="border_top"></div>
<div class="sidebar_content">
{if $PROFILE_SELF}
<!-- {{counter name=section}|romanize}. edit profile, account, photos -->
<h2>{#EditMyPage#}</h2>
<ul>
<li><a href="{get_url('who','edit','profile')}">{#EditProfile#}</a></li>
- <li><a href="{get_url('who','edit','account')}">{#EditAccount#}</a></li>
+ <li><a href="{get_url('settings','perso')}">{#EditAccount#}</a></li>
<li><a href="{get_url('who','edit','photos')}">{if $PICS}{#ManagePhotos#}{else}{#AddPhoto#}{/if}</a></li>
</ul>
{/if}
<!-- {{counter name=section}|romanize}. sidebar placeholder/explanation -->
<h2>Sidebar</h2>
<p>Here will be published new art submission, request/offers post it, external content imported, etc.</p>
</div>
<div class="border_bottom"></div>
</div>
</div>
{if $PROFILE_COMMENTS}
<!-- Profile comments -->
<div class="grid_16 alpha omega profile_comments" id="comments" style="margin-bottom: 1em;">
{foreach from=$PROFILE_COMMENTS item=comment}
<div class="comment black">
<div class="profile_comments_text"><p>{$comment->text|nl2br}</p></div>
<div class="profile_comments_info">-- <a href="{get_url('who')}/{$comment->author}">{$comment->authorname}</a>, {$comment->date|date_format:"%Y-%m-%d %H:%M:%S"}.</div>
</div>
{/foreach}
</div>
{/if}
diff --git a/skins/zed/profile_edit.tpl b/skins/zed/profile_edit.tpl
--- a/skins/zed/profile_edit.tpl
+++ b/skins/zed/profile_edit.tpl
@@ -1,58 +1,58 @@
 <!-- Calls dojo -->
<script src="/js/dojo/dojo/dojo.js" type="text/javascript"
djConfig="isDebug: false, parseOnLoad: true"></script>
<script type="text/javascript">
dojo.require("dijit.form.Form");
dojo.require("dijit.form.CheckBox");
dojo.require("dijit.form.Button");
function SetWidgetFont(id, font) {
//TODO: document.getElementById(id).style.font = font;
}
</script>
<!-- Edit profile -->
<div class="grid_11 alpha profile">
<div class="profile_id clearfix">
<h1 class="profile_nick" id="UserLongname">{$USERNAME}</h1>
</div>
<div class="profile_separator"></div>
<div class="profile_text">
- <form action="" class="search_form" name="faerie" method="post">
+ <form action="" method="post">
<h2>{#ProfileTextTitle#}</h2>
<textarea style="font-family: Calibri" id="ProfileText" rows="16" cols="72" name="text" class="text">{$PROFILE_TEXT}</textarea><br />
<div class="row" style="background-color: white; color: black;">
<span>{#ProfileFont#}{#_t#}</span>
<input type="radio" name="fixedwidth" id="fixedwidthNo" value="0" dojoType="dijit.form.RadioButton" {if !$PROFILE_FIXEDWIDTH}checked{/if} onclick="SetWidgetFont('ProfileText', 'Calibri')" />
<label for="fixedwidthNo"><span style="font-family: Calibri, Arial; font-weight: 100; font-size: 1.25em;">{#Calibri#}</span></label>
<input type="radio" name="fixedwidth" id="fixedwidthYes" value="1" dojoType="dijit.form.RadioButton" {if $PROFILE_FIXEDWIDTH}checked={/if} onclick="SetWidgetFont('ProfileText', 'FixedSys')" />
<label for="fixedwidthYes"><span style="font-family: Fixedsys, Fixed; font-weight: 100;">{#FixedSys#}</span></label>
</div>
<div class="row">
<button dojoType="dijit.form.Button" iconClass="dijitEditorIcon dijitEditorIconSave" type=submit onclick="document.forms[0].submit()">
{#SaveProfile#}
</button>
<noscript>
<input type="submit" value="{#SaveProfile#} {#JavaScriptSafeMessage#}" />
</noscript>
</div>
</form>
</div>
</div>
<!-- Faerie content -->
<div class="grid_5 omega">
<div class="sidebar_border"></div>
<div id="sidebar">
<div class="border_top"></div>
<div class="sidebar_content">
<h2>{#EditMyPage#}</h2>
<ul>
<li>{#EditProfile#}</li>
- <li><a href="{get_url('who')}/edit/account">{#EditAccount#}</a></li>
+ <li><a href="{get_url('settings','perso')}">{#EditAccount#}</a></li>
<li><a href="{get_url('who')}/edit/photos">{if $PICS}{#ManagePhotos#}{else}{#AddPhoto#}{/if}</a></li>
</ul>
</div>
<div class="border_bottom"></div>
</div>
</div>
\ No newline at end of file
diff --git a/skins/zed/profile_photo.tpl b/skins/zed/profile_photo.tpl
--- a/skins/zed/profile_photo.tpl
+++ b/skins/zed/profile_photo.tpl
@@ -1,50 +1,50 @@
 <!-- Add a photo -->
<div class="grid_11 alpha profile">
<div class="profile_id clearfix">
<h1 class="profile_nick" id="UserLongname">{$USERNAME}</h1>
</div>
<div class="profile_separator"></div>
<div class="profile_text">
<h2>{#AddPhotoToProfile#}</h2>
<form name="PhotoUpload" method="post" enctype="multipart/form-data">
<p>{#AddPhotoExplanations#}</p>
<p><label>Photo{#_t#}</label> <INPUT type="file" name="photo" /></p>
<p><label>{#ShortDescription#}{#_t#}</label> <input type="text" maxlength="63" size="32" name="description"></p>
<p><INPUT type="checkbox" name="SafeForWork" id="SafeForWork" value="0" /> <label for="SafeForWork">{#SafeForWorkLabel#}</label></p>
<p><input type="submit" value="{#Upload#}" /></p>
</form>
</div>
</div>
<div class="grid_5 omega">
<div class="sidebar_border"></div>
<div id="sidebar" style="min-height: inherit;">
<div class="border_top"></div>
<div class="sidebar_content">
<h2>{#EditMyPage#}</h2>
<ul>
<li><a href="{get_url('who')}/edit/profile">{#EditProfile#}</a></li>
- <li><a href="{get_url('who')}/edit/account">{#EditAccount#}</a></li>
+ <li><a href="{get_url('settings','perso')}">{#EditAccount#}</a></li>
<li>{if $PICS}{#ManagePhotos#}{else}{#AddPhoto#}{/if}</a></li>
</ul>
</div>
<div class="border_bottom"></div>
</div>
</div>
{if $PICS}
<!-- Manage current photos -->
<div class="grid_16 alpha omega profile_comments">
<h2>{#ManageCurrentPhotos#}</h2>
<div class="photos">
{foreach from=$PICS item=photo}
<div class="photo" style="float: left">
<a rel="lightbox" href="{$URL_PICS}/{$photo->name}" title="{$photo->description}"><img src="{$URL_PICS}/tn/{$photo->name}" alt="{$photo->description}" /></a>
<br />
<a href="{get_url('who')}/edit/photos/edit/{$photo->id}" title="{#EditPictureProperties#}"><img src="/skins/VacuumCleanerBridge/images/open.gif" alt="{#PictureProperties#}"></a>
<a href="{get_url('who')}/edit/photos/delete/{$photo->id}" title="{#DeleteThisPicture#}"><img src="/skins/VacuumCleanerBridge/images/del.gif" alt="{#Delete#}"></a>
</div>
{/foreach}
</div>
{/if}
</div>
\ No newline at end of file
diff --git a/skins/zed/profile_photo_edit.tpl b/skins/zed/profile_photo_edit.tpl
--- a/skins/zed/profile_photo_edit.tpl
+++ b/skins/zed/profile_photo_edit.tpl
@@ -1,36 +1,36 @@
<div class="grid_11 alpha">
<h1>{#EditPhoto#}</h1>
<a rel="lightbox" href="{$URL_PICS}/{$photo->name}" title="{$photo->description}"><img src="{$URL_PICS}/tn/{$photo->name}" alt="{$photo->description}" /></a>
<h2>{#PhotoInfo#}</h2>
<form method=post><input type="hidden" name="id" value="{$photo->id}" />
<blockquote>
<table>
<tr><td><strong><label for="description">{#Description#}</label></strong></td><td><input type='text' id='description' name='description' maxlength=63 value="{$photo->description}" /></td></tr>
<tr><td><strong><label for="safe">{#SafeForWork#}</label></strong></td><td><input type='checkbox' id='safe' name='safe' maxlength=3 size=5 value=1{if $photo->safe} checked{/if} /></td></tr>
<tr><td><strong><label for="avatar">{#UseAsAvatar#}</label></strong></td><td><input type='checkbox' id='avatar' name='avatar' maxlength=3 size=5 value=1{if $photo->avatar} checked{/if} /></td></tr>
<tr><td>&nbsp;</td><td><input type="submit" value="{#Save#}" /></td></tr>
</table>
</blockquote>
</form>
<h2>{#OtherActions#}</h2>
<ul>
<li><a href="{get_url('who')}/edit/photos/delete/{$photo->id}" title="{#DeletePicture#}">{#DeletePicture#}</a></li>
<li><a href="{get_url('who')}/edit/photos">{#BackToPhotoManager#}</a></li>
</ul>
</div>
<div class="grid_5 omega">
<div class="sidebar_border"></div>
<div id="sidebar" style="min-height: inherit;">
<div class="border_top"></div>
<div class="sidebar_content">
<h2>{#EditMyPage#}</h2>
<ul>
<li><a href="{get_url('who')}/edit/profile">{#EditProfile#}</a></li>
- <li><a href="{get_url('who')}/edit/account">{#EditAccount#}</a></li>
+ <li><a href="{get_url('settings','perso')}">{#EditAccount#}</a></li>
<li>{if $PICS}{#ManagePhotos#}{else}{#AddPhoto#}{/if}</a></li>
</ul>
</div>
<div class="border_bottom"></div>
</div>
</div>
\ No newline at end of file
diff --git a/skins/zed/settings_page.tpl b/skins/zed/settings_page.tpl
--- a/skins/zed/settings_page.tpl
+++ b/skins/zed/settings_page.tpl
@@ -1,46 +1,67 @@
<!-- DIJIT -->
<script type="text/javascript">
dojo.require("dijit.form.Form");
dojo.require("dijit.form.TextBox");
dojo.require("dijit.form.ValidationTextBox");
dojo.require("dijit.form.Button");
dojo.require("dijit.form.FilteringSelect");
dojo.require("dijit.form.CheckBox");
+
+ dojo.require("dojox.form.PasswordValidator");
</script>
<!-- Settings - #{$page->id} -->
+ <div class="grid_12 alpha">
<h2>{#$page->title#}</h2>
<form method="post">
<input type="hidden" name="settings.page" value="{$page->id}" />
{foreach from=$page->settings item=setting}
<div class="row">
{if $setting->field == "validationtext"}
<label for="{$setting->key}" class="firstLabel ">{#$setting->key#}</label>
<input dojoType="dijit.form.ValidationTextBox" regExp="{$setting->regExp}" id="{$setting->key}" name="{$setting->key}" type="text" value="{$setting->get()}" class="long" />
{elseif $setting->field == "text"}
<label for="{$setting->key}" class="firstLabel ">{#$setting->key#}</label>
<input dojoType="dijit.form.TextBox" id="{$setting->key}" name="{$setting->key}" type="text" value="{$setting->get()}" class="long" />
{elseif $setting->field == "password"}
- <label for="{$setting->key}" class="firstLabel ">{#$setting->key#}</label>
- <input dojoType="dijit.form.TextBox" id="{$setting->key}" name="{$setting->key}" type="password" value="{$setting->get()}" class="long" />
- </div>
- <div class="row">
- <label for="{$setting->key}_confirm" class="firstLabel">{#$setting->key#} (confirm it)</label>
- <input dojoType="dijit.form.TextBox" id="{$setting->key}_confirm" name="{$setting->key}_confirm" type="password" value="{$setting->get()}" class="long" />
+ <div dojoType="dojox.form.PasswordValidator" name="{$setting->key}">
+ <label for="{$setting->key}" class="firstLabel ">{#$setting->key#}</label>
+ <input type="password" pwType="new" id="{$setting->key}" name="{$setting->key}" value="{$setting->get()}" class="long" />
+ <br />
+ <label for="{$setting->key}_confirm" class="firstLabel">{#$setting->key#} {#PasswordConfirm#}</label>
+ <input type="password" pwType="verify" id="{$setting->key}_confirm" name="{$setting->key}_confirm" value="{$setting->get()}" class="long" />
+ </div>
{elseif $setting->field == "filteredlist"}
<label for="{$setting->key}" class="firstLabel ">{#$setting->key#}</label>
<select id="{$setting->key}" name="{$setting->key}" dojoType="dijit.form.FilteringSelect" class="long">
{foreach from=$setting->choices item=value key=key}
<option value="{$value}">{#$key#}</option>
{/foreach}
</select>
{elseif $setting->field == "checkbox"}
<input type="checkbox" dojoType="dijit.form.CheckBox" id="{$setting->key}" name="{$setting->key}" value="1" {if $setting->get()}checked="true" {/if}/> <label for="{$setting->key}">{#$setting->key#}</label>
{else}{dprint_r($setting)}
{/if}
</div>
{/foreach}
<div class="row">
<button dojoType="dijit.form.Button" iconClass="dijitEditorIcon dijitEditorIconSave" type="submit" value="Save" />{#SaveSettings#}</button>
</div>
- </form>
\ No newline at end of file
+ </form>
+ </div>
+
+ <div class="grid_4 omega">
+ <h2>Settings</h2>
+ <ul style="list-style-type: cjk-ideographic; line-height: 2em;">
+{foreach from=$pages item=value key=key}
+{if $key == $page->id}
+ <li>{$value}</li>
+{else}
+ <li><a href="{get_url('settings', $key)}">{$value}</a></li>
+{/if}
+{/foreach}
+ <li><a href="{get_url('who', 'edit', 'profile')}">{#EditProfile#}</a></li>
+ </ul>
+ </div>
+
+ <div class="clear"></div>
\ No newline at end of file

File Metadata

Mime Type
text/x-diff
Expires
Sun, Nov 3, 23:15 (3 w, 5 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
20714
Default Alt Text
(68 KB)

Event Timeline