#1470 updated API & achievements tracker to latest live version
--HG-- branch : gsoc2012-achievements
46
code/web/api/client/time.php
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
/* Copyright (C) 2009 Winch Gate Property Limited
|
||||
*
|
||||
* This file is part of ryzom_api.
|
||||
* ryzom_api is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ryzom_api is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with ryzom_api. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
$tick_cache_timeout = 60;
|
||||
|
||||
function ryzom_time_tick() {
|
||||
$fn = RYAPI_URL.'data/cache/game_cycle.ticks';
|
||||
$handle = fopen($fn, "r");
|
||||
$version = fread($handle, 1);
|
||||
$raw_tick = fread($handle, 4);
|
||||
fclose($handle);
|
||||
$arr = unpack("V", $raw_tick);
|
||||
$tick = $arr[1];
|
||||
return sprintf("%u", $tick & 0xffffffff);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Takes a computed ryzom time array and returns a SimpleXMLElement
|
||||
*/
|
||||
function ryzom_time_xml($rytime) {
|
||||
global $tick_cache_timeout;
|
||||
$out = ryzom_time_xml_without_cache($rytime);
|
||||
$filename = RYAPI_URL.'data/cache/game_cycle.ticks';
|
||||
$cache = $out->addChild('cache');
|
||||
$cache->addAttribute('created', filemtime($filename));
|
||||
$cache->addAttribute('expire', (filemtime($filename)+$tick_cache_timeout));
|
||||
return $out;
|
||||
}
|
||||
|
||||
?>
|
158
code/web/api/common/actionPage.php
Normal file
|
@ -0,0 +1,158 @@
|
|||
<?php
|
||||
|
||||
/* Copyright (C) 2012 Winch Gate Property Limited
|
||||
*
|
||||
* This file is part of ryzom_api.
|
||||
* ryzom_api is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ryzom_api is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with ryzom_app. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
class ryActionClass {
|
||||
public $classname;
|
||||
public $instance;
|
||||
public $args;
|
||||
public $requires;
|
||||
|
||||
function __construct($classname, $instance, $args, $requires) {
|
||||
$this->classname = $classname;
|
||||
$this->instance = $instance;
|
||||
$this->args = $args;
|
||||
$this->requires = $requires;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ryActionPage {
|
||||
|
||||
private static $classesArgs = array();
|
||||
private static $myClasses = array();
|
||||
private static $aliases = array();
|
||||
private static $messages;
|
||||
private static $haveMessage;
|
||||
protected static $id;
|
||||
|
||||
public $instanceName;
|
||||
public $myMethods = array();
|
||||
|
||||
function __construct() {
|
||||
}
|
||||
|
||||
function addMethods($child_class) {
|
||||
if (is_array($child_class)) {
|
||||
foreach ($child_class as $c_class)
|
||||
$this->myMethods = array_merge($this->myMethods, get_class_methods($c_class));
|
||||
} else {
|
||||
$this->myMethods = get_class_methods($child_class);
|
||||
}
|
||||
}
|
||||
|
||||
static function addClass($name, $classname, $args=array(), $requires=NULL) {
|
||||
self::$myClasses[$name] = new ryActionClass($classname, NULL, $args, $requires);
|
||||
}
|
||||
|
||||
static function addAlias($aliasname, $name) {
|
||||
self::$aliases[$aliasname] = $name;
|
||||
}
|
||||
|
||||
static function initInstance($listener) {
|
||||
$i = self::$myClasses[$listener];
|
||||
if (!$i->instance) {
|
||||
// requires
|
||||
if ($i->requires) {
|
||||
self::initInstance($i->requires);
|
||||
}
|
||||
if ($i->args)
|
||||
$i->instance = new $i->classname($listener, $i->args);
|
||||
else
|
||||
$i->instance = new $i->classname($listener);
|
||||
$i->instance->addMethods($i->classname);
|
||||
$i->instance->instanceName = $listener;
|
||||
|
||||
}
|
||||
return $i->instance;
|
||||
}
|
||||
|
||||
static function getInstance($listener) {
|
||||
return self::initInstance($listener);
|
||||
}
|
||||
|
||||
static function _addMSG($type='OK', $message='') {
|
||||
self::$messages[] = array($type, $message);
|
||||
return '';
|
||||
}
|
||||
|
||||
function addMSG($type='OK', $action='', $message='') {
|
||||
self::$messages[] = array($type, $message);
|
||||
$this->haveMessage = $action;
|
||||
return '';
|
||||
}
|
||||
|
||||
static function getMSGs() {
|
||||
return self::$messages;
|
||||
}
|
||||
|
||||
static function call($action, $url_params) {
|
||||
$action_params = explode('_', $action);
|
||||
|
||||
if (count($action_params) != 2)
|
||||
return self::_addMSG('ERR', 'Action call error : bad params of ['.$action.']');
|
||||
|
||||
list($listener, $call) = $action_params;
|
||||
if (array_key_exists($listener,self::$aliases))
|
||||
$listener = self::$aliases[$listener];
|
||||
|
||||
if (!array_key_exists($listener, self::$myClasses))
|
||||
return self::_addMSG('ERR', 'Action call error : class ['. $listener .'] not found');
|
||||
|
||||
$i = self::initInstance($listener);
|
||||
|
||||
if (in_array('action'.$call, $i->myMethods)) {
|
||||
$i->haveMessage = NULL;
|
||||
$ret = call_user_func(array($i, 'action'.$call), $url_params);
|
||||
if (!isset($_SESSION['last_action']) or $action != $_SESSION['last_action'])
|
||||
$_SESSION['last_action'] = $action;
|
||||
$msg = $i->haveMessage;
|
||||
if ($msg and ($msg != $action)) {
|
||||
$ret = self::call($msg, $url_params);
|
||||
return self::_addMSG('OK', $ret);
|
||||
}
|
||||
return self::_addMSG('OK', $ret);
|
||||
} else
|
||||
return self::_addMSG('ERR', 'Action call error : action ['. $call .'] of ['. $listener .'] not found');
|
||||
}
|
||||
}
|
||||
|
||||
function callAction($action) {
|
||||
$c = '';
|
||||
ryActionPage::call($action, ryzom_get_params());
|
||||
$msgs = ryActionPage::getMSGs();
|
||||
|
||||
foreach ($msgs as $msg) {
|
||||
if ($msg[0] == 'HEADER')
|
||||
$c .= $msg[1];
|
||||
}
|
||||
|
||||
foreach ($msgs as $msg) {
|
||||
if ($msg[0] == 'ERR')
|
||||
$c .= _s('message error', $msg[1]);
|
||||
else if ($msg[0] == 'MSG')
|
||||
$c .= _s('message', $msg[1]);
|
||||
else if ($msg[0] == 'WARNING')
|
||||
$c .= _s('message warning', $msg[1]);
|
||||
else if ($msg[0] != 'HEADER')
|
||||
$c .= $msg[1];
|
||||
}
|
||||
return $c;
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,36 +1,96 @@
|
|||
<?php
|
||||
|
||||
function ryzom_app_authenticate(&$user, $ask_login=true, $welcome_message='') {
|
||||
/* Copyright (C) 2009 Winch Gate Property Limited
|
||||
*
|
||||
* This file is part of ryzom_api.
|
||||
* ryzom_api is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ryzom_api is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with ryzom_api. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
function ryzom_app_authenticate(&$user, $ask_login=true, $welcome_message='', $webprivs=true) {
|
||||
$name = ryzom_get_param('name');
|
||||
$authserver = ryzom_get_param('authserver');
|
||||
$authkey = ryzom_get_param('authkey');
|
||||
$urluser = ryzom_get_param('user'); // user serialization send by auth server
|
||||
$urlusercheksum = ryzom_get_param('checksum'); // user serialization checksum
|
||||
$authkey = ryzom_get_param('authkey'); // InGame authkey
|
||||
$lang = ryzom_get_param('lang');
|
||||
$cid = ryzom_get_param('cid', '');
|
||||
$is_ingame = false;
|
||||
$cid = intval(ryzom_get_param('cid'));
|
||||
$is_auth_ingame = false;
|
||||
// we have to set the $user['lang'] even for anonymous user or we cannot display the test in the right langage
|
||||
if($lang == '') {
|
||||
$l = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
|
||||
if($l=='fr'||$l=='en'||$l=='de'||$l=='ru'||$l=='es')
|
||||
if (!isset($_SESSION['lang'])) {
|
||||
$l = isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])?substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2):'en';
|
||||
if ($l=='fr'||$l=='en'||$l=='de'||$l=='ru'||$l=='es')
|
||||
$lang = $l;
|
||||
else
|
||||
$lang = 'en';
|
||||
} else
|
||||
$lang = $_SESSION['lang'];
|
||||
}
|
||||
if ($lang!='fr'&&$lang!='en'&&$lang!='de'&&$lang!='ru'&&$lang!='es')
|
||||
$lang = 'en';
|
||||
|
||||
$user['message'] = '';
|
||||
$user['lang'] = $lang;
|
||||
$user['groups'] = array();
|
||||
|
||||
if ((isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], 'Ryzom')) || ryzom_get_param('ig'))
|
||||
$user['ig'] = true;
|
||||
else
|
||||
$user['ig'] = false;
|
||||
|
||||
if ((isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], 'Ryzom')) || ryzom_get_param('ig')) {
|
||||
$user['ig'] = true;
|
||||
if (isset($_SESSION['user'])) {
|
||||
if (ryzom_get_param('action') == 'logout')
|
||||
unset($_SESSION['user']);
|
||||
else {
|
||||
$_SESSION['user']['ig'] = $user['ig'];
|
||||
define('RYZOM_IG', $user['ig']);
|
||||
$user = $_SESSION['user'];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($urluser && $urlusercheksum) {
|
||||
// Check $authuser (used to test app from another server ingame)
|
||||
if (hash_hmac('sha1', $urluser, RYAPI_AUTH_KEY) == $urlusercheksum) {
|
||||
$ig = $user['ig'];
|
||||
$user = array_merge($user, unserialize(base64_decode($urluser)));
|
||||
$user['ig'] = $ig;
|
||||
if (!isset($user['groups']))
|
||||
$user['groups'] = array();
|
||||
define('RYZOM_IG', $user['ig']);
|
||||
$_SESSION['user'] = $user;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($user['ig']) {
|
||||
// Ingame
|
||||
$shardid = ryzom_get_param('shardid');
|
||||
if (!ryzom_authenticate_ingame($shardid, $cid, $name, $authkey))
|
||||
return false;
|
||||
$is_ingame = true;
|
||||
$error_message = '';
|
||||
if (ryzom_authenticate_ingame($shardid, $cid, $name, $authkey) || ryzom_authenticate_with_session($name, $cid, $error_message)) {
|
||||
$is_auth_ingame = true;
|
||||
}
|
||||
} else {
|
||||
// Outgame : Use session
|
||||
// Outgame or bad ingame auth (external server) : Use session
|
||||
$error_message = '';
|
||||
if (!ryzom_authenticate_with_session($name, $cid, $error_message)) {
|
||||
define('RYZOM_IG', false);
|
||||
if ($ask_login) {
|
||||
|
||||
if ($error_message)
|
||||
$c = '<h3>'._t($error_message).'</h3>';
|
||||
else
|
||||
$c = '';
|
||||
if (!$welcome_message)
|
||||
$welcome_message = '<span style="font-size:11pt; color: #AAAAFF">The application <strong style="color: #99FFFF">'._t(APP_NAME).'</strong> require authentication. Please enter your credentials</span>';
|
||||
|
@ -47,18 +107,44 @@ function ryzom_app_authenticate(&$user, $ask_login=true, $welcome_message='') {
|
|||
}
|
||||
}
|
||||
|
||||
if ($lang)
|
||||
$_SESSION['lang'] = $lang;
|
||||
|
||||
define('RYZOM_IG', $user['ig']);
|
||||
// get user informations
|
||||
$user = ryzom_user_get_info($cid);
|
||||
$user['lang'] = $_SESSION['lang'];
|
||||
$ig = $user['ig'];
|
||||
$user = ryzom_user_get_info($cid, $webprivs, RYAPI_USE_PLAYER_STATS);
|
||||
|
||||
if (isset($user['creation_date']))
|
||||
$user['id'] = ryzom_get_user_id($cid, $user['char_name'], $user['creation_date']);
|
||||
if ($is_ingame && $user['last_played_date'] != '0')
|
||||
$user['ig'] = true;
|
||||
$user['id'] = ryzom_get_user_id($cid, $user['char_name'], $user['creation_date'], $user);
|
||||
|
||||
$user['gender'] = ryzom_get_user_gender($user['id']);
|
||||
|
||||
$user['ig'] = $ig;
|
||||
$user['lang'] = $_SESSION['lang'];
|
||||
if (!isset($user['groups']))
|
||||
$user['groups'] = array();
|
||||
|
||||
if ($is_auth_ingame && $user['last_played_date'] != '0')
|
||||
$user['auth_ig'] = true;
|
||||
else
|
||||
$user['ig'] = false;
|
||||
$user['auth_ig'] = false;
|
||||
|
||||
if (!isset($_SESSION['translater_mode']) || ryzom_get_param('translate_this') == '0')
|
||||
$_SESSION['translater_mode'] = false;
|
||||
|
||||
// Set/unset translation mode
|
||||
if (in_array('WTRS', $user['groups']) && ryzom_get_param('translate_this') == '1')
|
||||
$_SESSION['translater_mode'] = true;
|
||||
|
||||
$user['translation_mode'] = $_SESSION['translater_mode'];
|
||||
|
||||
// $user['after_merge'] = $user['uid'] >= 671686;
|
||||
|
||||
ryzom_unset_url_param('translate_this');
|
||||
|
||||
if (isset($user['last_played_date']))
|
||||
$_SESSION['last_played_date'] = $user['last_played_date'];
|
||||
// don't send this informations to external apps
|
||||
unset($user['last_played_date']);
|
||||
unset($user['creation_date']);
|
||||
return true;
|
||||
|
|
998
code/web/api/common/bbCode.php
Normal file
|
@ -0,0 +1,998 @@
|
|||
<?php
|
||||
|
||||
/* Copyright (C) 2009 Winch Gate Property Limited
|
||||
*
|
||||
* This file is part of ryzom_api.
|
||||
* ryzom_api is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ryzom_api is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with ryzom_api. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// setup bbCode formatter
|
||||
|
||||
bbCode::$ig = RYZOM_IG;
|
||||
|
||||
/**
|
||||
* Image proxy
|
||||
*/
|
||||
if(!defined('IMG_PROXY')){
|
||||
$url = 'http://'.$_SERVER['HTTP_HOST'].'/app_forum/tools/imageproxy.php';
|
||||
define('IMG_PROXY', $url);
|
||||
}
|
||||
if (!function_exists('proxy_image_url')) {
|
||||
function proxy_image_url($href, $attrs=''){
|
||||
return IMG_PROXY.'?'.($attrs != '' ? $attrs.'&' : '').'url='.urlencode($href);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
abstract class bbCodeParser {
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $_ig;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $tags_ignore;
|
||||
private $tags_block_open;
|
||||
private $tags_block_close;
|
||||
private $tags_ignore_depth;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $open_tags;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $last_closed_tag;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $current_tag;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $state;
|
||||
|
||||
/**
|
||||
* @param bool $ig if true, use ingame markup
|
||||
*/
|
||||
function __construct($ig) {
|
||||
$this->_ig = $ig;
|
||||
|
||||
// ignore bbcode between these tags
|
||||
$this->tags_ignore = array(
|
||||
'noparse', 'code',
|
||||
'url', 'img', 'mail', 'page', 'forum', 'topic', 'post', 'wiki', 'time', 'date'
|
||||
);
|
||||
|
||||
// these create block level html code, so '\n' or ' ' or '\t' around them needs to be cleared
|
||||
$this->tags_block_open = array('h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'quote', 'list', 'p');
|
||||
$this->tags_block_close = $this->tags_block_open;
|
||||
if ($this->_ig) {
|
||||
// ingame <p> is not block level when closing, so dont strip there
|
||||
$key = array_search('p', $this->tags_block_close, true);
|
||||
unset($this->tags_block_close[$key]);
|
||||
}
|
||||
|
||||
$this->state = array();
|
||||
|
||||
// reset internals
|
||||
$this->reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Format bbcode tag
|
||||
*
|
||||
* @param string $tag tag name
|
||||
* @param string $open open markup
|
||||
* @param string $close close markup
|
||||
* @param string $attr tag attributes
|
||||
* @param string $text text between tags
|
||||
*/
|
||||
abstract function format($tag, $open, $close, $attr, $text);
|
||||
|
||||
/**
|
||||
* Wrapper to call Child->format(...)
|
||||
*
|
||||
* @param array $tag assoc array with tag info
|
||||
* @return string
|
||||
*/
|
||||
function handle_tag($tag) {
|
||||
return $this->format($tag['tag'], $tag['open'], $tag['close'], $tag['attr'], $tag['text']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset internals
|
||||
*/
|
||||
function reset() {
|
||||
$this->current_tag = 0;
|
||||
$this->tags_ignore_depth = 0;
|
||||
|
||||
// 0'th position is used as result
|
||||
$this->open_tags = array(
|
||||
0 => array('tag' => '', 'open' => '', 'close' => '', 'attr' => '', 'text' => '')
|
||||
);
|
||||
|
||||
$this->last_closed_tag = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save working state
|
||||
*/
|
||||
private function _state_save() {
|
||||
$this->state[] = array($this->current_tag, $this->tags_ignore_depth, $this->open_tags, $this->last_closed_tag);
|
||||
$this->reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore working state
|
||||
*/
|
||||
private function _state_restore() {
|
||||
if (!empty($this->state)) {
|
||||
list($this->current_tag, $this->tags_ignore_depth, $this->open_tags, $this->last_closed_tag) = array_pop($this->state);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Main worker. Parse $text for bbCode tags
|
||||
*
|
||||
* NOTE: Text must already be safe for HTML, ie. treated with htmlspecialchars()
|
||||
*
|
||||
* @param string $text
|
||||
* @return string formatted string
|
||||
*/
|
||||
function bbcode($text) {
|
||||
$text = str_replace("\r\n", "\n", $text);
|
||||
|
||||
$split = preg_split('/(\[[a-zA-Z0-9_\/]*?(?:[= ].*?)?\])/', $text, null, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
|
||||
|
||||
foreach ($split as $chunk) {
|
||||
if (substr($chunk, 0, 1) == '[' && substr($chunk, -1, 1) == ']') {
|
||||
if (substr($chunk, 0, 2) == '[/') {
|
||||
$this->close($chunk);
|
||||
} else {
|
||||
$this->open($chunk);
|
||||
}
|
||||
} else {
|
||||
$this->text($chunk);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->result();
|
||||
}
|
||||
|
||||
/**
|
||||
* Push tag with args to stack
|
||||
* Do not strip whitespace because tag might be invalid
|
||||
*
|
||||
* @param string $chunk full tag string, eg. [tag=attr]
|
||||
*/
|
||||
function open($chunk) {
|
||||
list($tag, $attr) = $this->split_params($chunk);
|
||||
|
||||
// test for [noparse]
|
||||
if ($this->tags_ignore_depth > 0) {
|
||||
$this->text($chunk);
|
||||
} else {
|
||||
$this->current_tag++;
|
||||
// remember tag, attributes and complete string that was used in markup
|
||||
$this->open_tags[$this->current_tag] = array('tag' => $tag, 'attr' => $attr, 'open' => $chunk, 'close' => '', 'text' => '');
|
||||
}
|
||||
|
||||
if (in_array($tag, $this->tags_ignore)) {
|
||||
$this->tags_ignore_depth++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close tag and call tag handler to format output
|
||||
*
|
||||
* @param $chunk full tag string, eg. [/tag]
|
||||
*/
|
||||
function close($chunk) {
|
||||
// extract tag name from [/name]
|
||||
$tag = strtolower(substr($chunk, 2, -1));
|
||||
|
||||
if ($this->tags_ignore_depth > 0 && in_array($tag, $this->tags_ignore)) {
|
||||
$this->tags_ignore_depth--;
|
||||
}
|
||||
|
||||
// stack underrun
|
||||
if ($this->current_tag < 0) {
|
||||
$this->text($chunk);
|
||||
return;
|
||||
}
|
||||
|
||||
// ignore block
|
||||
if ($this->tags_ignore_depth > 0) {
|
||||
$this->text($chunk);
|
||||
return;
|
||||
}
|
||||
|
||||
// tag mismatch
|
||||
if ($this->open_tags[$this->current_tag]['tag'] !== $tag) {
|
||||
// try to find first open tag for this
|
||||
$key = false;
|
||||
for ($i = $this->current_tag - 1; $i > 0; $i--) {
|
||||
if (isset($this->open_tags[$i]['tag']) && $this->open_tags[$i]['tag'] === $tag) {
|
||||
$key = $i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($key === false) {
|
||||
$this->text($chunk);
|
||||
return;
|
||||
}
|
||||
|
||||
// tag is open so we need to 'rewind' a bit
|
||||
for ($i = $this->current_tag; $i > $key; $i--) {
|
||||
$tmp_tag = $this->pop_stack();
|
||||
$this->text($tmp_tag['open'] . $tmp_tag['text']);
|
||||
}
|
||||
}
|
||||
|
||||
// close tag
|
||||
$open = $this->pop_stack();
|
||||
|
||||
// handle bbcode
|
||||
$open['close'] = $chunk;
|
||||
|
||||
$block_level = false;
|
||||
if (in_array($tag, $this->tags_block_open)) {
|
||||
$block_level = true;
|
||||
// for block level element, trim whitespace from inside tag
|
||||
// [tag]<ws>...text...<ws>[/tag]
|
||||
$open['text'] = $this->trim_ws($open['text']);
|
||||
}
|
||||
$result = $this->handle_tag($open);
|
||||
|
||||
// strip whitespace from text before tag 'text...<ws>[tag]'
|
||||
if ($block_level) {
|
||||
$ts = $this->rtrim_ws($this->open_tags[$this->current_tag]['text']);
|
||||
$this->open_tags[$this->current_tag]['text'] = $ts;
|
||||
}
|
||||
|
||||
$this->text($result);
|
||||
|
||||
$this->last_closed_tag = $open['tag'];
|
||||
}
|
||||
|
||||
function text($text) {
|
||||
// strip whitespace after closing '[/tag]<ws>...text'
|
||||
if (in_array($this->last_closed_tag, $this->tags_block_close)) {
|
||||
$text = $this->ltrim_ws($text);
|
||||
}
|
||||
$this->open_tags[$this->current_tag]['text'] .= $text;
|
||||
|
||||
$this->last_closed_tag = false;
|
||||
}
|
||||
|
||||
function result() {
|
||||
// close tags that are still open
|
||||
while ($this->current_tag > 0) {
|
||||
$open = $this->pop_stack();
|
||||
|
||||
if ($this->tags_ignore_depth > 0) {
|
||||
$this->tags_ignore_depth--;
|
||||
// need to reparse text that's after ignore tag
|
||||
$this->_state_save();
|
||||
$text = $open['open'] . $this->bbcode($open['text']);
|
||||
$this->_state_restore();
|
||||
} else {
|
||||
// tag was not closed proprely, include start tag with result
|
||||
$text = $open['open'] . $open['text'];
|
||||
}
|
||||
|
||||
$this->text($text);
|
||||
};
|
||||
|
||||
return $this->open_tags[0]['text'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Pop tag and text from stack and return them
|
||||
*
|
||||
* @return array [0] = tag, [1] = text
|
||||
*/
|
||||
function pop_stack() {
|
||||
// remove from stack
|
||||
$open = $this->open_tags[$this->current_tag];
|
||||
unset($this->open_tags[$this->current_tag]);
|
||||
$this->current_tag--;
|
||||
|
||||
return $open;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trim from end of string
|
||||
* 'text...\s{0,}\n{1}\s{0,}'
|
||||
*
|
||||
* @param string $ts
|
||||
* @return string
|
||||
*/
|
||||
function rtrim_ws($ts){
|
||||
// we want to get rid of all spaces/tabs, but only single \n, so rtrim($ts, " \t\n\r") would not work
|
||||
$ts = rtrim($ts, " \t");
|
||||
if (substr($ts, -1, 1) === "\n") {
|
||||
$ts = substr($ts, 0, -1);
|
||||
$ts = rtrim($ts, " \t");
|
||||
}
|
||||
return $ts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trim from start of string
|
||||
* '\s{0,}\n{1}...text'
|
||||
*
|
||||
* @param string $ts
|
||||
* @return string
|
||||
*/
|
||||
function ltrim_ws($ts){
|
||||
// we want to get rid of all spaces/tabs, but only single \n, so ltrim($ts, " \t\n\r") would not work
|
||||
$ts = ltrim($ts, " \t");
|
||||
if (substr($ts, 0, 1) === "\n") {
|
||||
$ts = substr($ts, 1);
|
||||
}
|
||||
return $ts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trim from both sides
|
||||
* '\s{0,}\n{1}...text...\s{0,}\n{1}\s{0,}
|
||||
*
|
||||
* @param string $ts
|
||||
* @return string
|
||||
*/
|
||||
function trim_ws($ts){
|
||||
$ts = $this->ltrim_ws($ts);
|
||||
$ts = $this->rtrim_ws($ts);
|
||||
return $ts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract tag parameters from [tag=params] or [tag key1=val1 key2=val2]
|
||||
*
|
||||
* @param type $tag
|
||||
* @return type
|
||||
*/
|
||||
function split_params($chunk) {
|
||||
if (substr($chunk, 0, 1) == '[') {
|
||||
$b = '\[';
|
||||
$e = '\]';
|
||||
} else {
|
||||
$b = '';
|
||||
$e = '';
|
||||
}
|
||||
// [1] [2] [3]
|
||||
if (preg_match('/^' . $b . '([\*a-zA-Z0-9]*?)' . '(=| )' . '(.*?)' . $e . '$/', $chunk, $match)) {
|
||||
$tagName = strtolower($match[1]);
|
||||
if ($match[2] == '=') {
|
||||
// = means single parameter
|
||||
$tagParam = $match[3];
|
||||
} else {
|
||||
// <space> means multiple parameters
|
||||
$tagParam = array();
|
||||
$args = preg_split('/[ ]/', $match[3], null, PREG_SPLIT_NO_EMPTY);
|
||||
foreach ($args as $arg) {
|
||||
$pairs = explode('=', $arg);
|
||||
// preg_replace will remove possible quotes around value
|
||||
if (isset($pairs[1])) {
|
||||
$tagParam[strtolower($pairs[0])] = preg_replace('@("|\'|)(.*?)\\1@', '$2', $pairs[1]);
|
||||
} else {
|
||||
$tagParam[] = preg_replace('@("|\'|)(.*?)\\1@', '$2', $pairs[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (substr($chunk, 0, 1) == '[' && substr($chunk, -1, 1) == ']') {
|
||||
$chunk = substr($chunk, 1, -1);
|
||||
}
|
||||
$tagName = strtolower($chunk);
|
||||
$tagParam = '';
|
||||
}
|
||||
return array($tagName, $tagParam);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class bbCode extends bbCodeParser {
|
||||
static $legacy_sync = 1348956841;
|
||||
static $legacy_shard = array(
|
||||
'ani' => 2363920179,
|
||||
'lea' => 2437578274,
|
||||
'ari' => 2358620001,
|
||||
);
|
||||
|
||||
static $ig = false;
|
||||
static $timezone = 'UTC';
|
||||
static $clock12h = false;
|
||||
static $shardid = false;
|
||||
static $lang = 'en';
|
||||
static $disabledTags = array();
|
||||
//
|
||||
const COLOR_P = '#d0d0d0'; // normal text
|
||||
//
|
||||
const COLOR_BBCODE_TAG = '#444444';
|
||||
|
||||
static function bbDisabled($tag) {
|
||||
return in_array(strtolower($tag), self::$disabledTags);
|
||||
}
|
||||
|
||||
static function getFontSize($value) {
|
||||
$size = 16;
|
||||
switch (strtolower($value)) {
|
||||
case '1': case 'xx-small': $size = 9; break;
|
||||
case '2': case 'x-small' : $size = 10; break;
|
||||
case '3': case 'small' : $size = 13; break;
|
||||
case '4': case 'medium' : $size = 16; break;
|
||||
case '5': case 'large' : $size = 18; break;
|
||||
case '6': case 'x-large' : $size = 24; break;
|
||||
case '7': case 'xx-large': $size = 32; break;
|
||||
//case '8': case 'smaller' : break;
|
||||
//case '9': case 'larger' : break;
|
||||
}
|
||||
return $size;
|
||||
}
|
||||
|
||||
static function bb_noparse($code) {
|
||||
return preg_replace(array('/\[/', '/\]/'), array('[', ']'), $code);
|
||||
}
|
||||
|
||||
static function bb_code($code) {
|
||||
return '<pre>' . self::bb_noparse($code) . '</pre>';
|
||||
}
|
||||
|
||||
static function bb_list($list) {
|
||||
$result = '';
|
||||
$list = str_replace("\n[", '[', $list);
|
||||
$result = '<ul>' . preg_replace('/\s*\[\*\]\s*/is', "</li><li>", $list) . '</li></ul>';
|
||||
return preg_replace('#<ul>\s*</li>#is', '<ul>', $result);
|
||||
}
|
||||
|
||||
static function bb_quote($author, $text) {
|
||||
if (self::$ig) {
|
||||
// prevents [color] tag to take over color
|
||||
$author = self::bb_color(self::COLOR_P, $author);
|
||||
$text = self::bb_color(self::COLOR_P, $text);
|
||||
// left/right border, top/bottom border height
|
||||
$l = '<td width="1" bgcolor="#888888" height="1"></td>';
|
||||
$r = '<td width="1" bgcolor="#888888" height="1"></td>';
|
||||
return // 98% gives bit padding on the right
|
||||
'<table width="98%" cellpadding="0" cellspacing="0" border="0">' .
|
||||
'<tr><td width="1" height="5"></td><td></td><td></td></tr>' . // top padding - no border
|
||||
'<tr>' . $l . '<td bgcolor="#888888"></td>' . $r . '</tr>' . // top border
|
||||
'<tr>' . $l . '<td bgcolor="#000000" l_margin="5" height="3"></td>' . $r . '</tr>' . // author top padding
|
||||
'<tr>' . $l . '<td bgcolor="#000000" l_margin="5">' . $author . '</td>' . $r . '</tr>' . // author
|
||||
'<tr>' . $l . '<td bgcolor="#000000" l_margin="5" height="2"></td>' . $r . '</tr>' . // author bottom padding
|
||||
'<tr>' . $l . '<td bgcolor="#555555" l_margin="10" height="3"></td>' . $r . '</tr>' . // quote top padding
|
||||
'<tr>' . $l . '<td bgcolor="#555555" l_margin="10">' . $text . '</td>' . $r . '</tr>' . // quote
|
||||
'<tr>' . $l . '<td bgcolor="#555555" l_margin="10" height="2"></td>' . $r . '</tr>' . // quote bottom padding
|
||||
'<tr>' . $l . '<td bgcolor="#888888"></td>' . $r . '</tr>' . // bottom border
|
||||
'<tr><td width="1" height="8"></td><td></td><td></td></tr>' . // bottom padding - no border
|
||||
'</table>';
|
||||
} else {
|
||||
return '' .
|
||||
'<div class="post-quote">' .
|
||||
'<cite>' . $author . '</cite>' .
|
||||
'<blockquote>' . $text . '</blockquote>' .
|
||||
'</div>';
|
||||
}
|
||||
}
|
||||
|
||||
static function bb_h($nr, $color, $text) {
|
||||
$tag = 'h' . $nr;
|
||||
|
||||
if (self::$ig) {
|
||||
if ($color != '') {
|
||||
$text = '<font color="' . $color . '">' . $text . '</font>';
|
||||
}
|
||||
return '<' . $tag . '>' . $text . '</' . $tag . '>';
|
||||
} else {
|
||||
if ($color != '') {
|
||||
$style = ' style="color: ' . $color . ';"';
|
||||
} else {
|
||||
$style = '';
|
||||
}
|
||||
return '<' . $tag . $style . '>' . $text . '</' . $tag . '>';
|
||||
}
|
||||
}
|
||||
|
||||
static function bb_url($href, $text) {
|
||||
// "http://..../" remove " if present
|
||||
if (substr($href, 0, 6) == '"') {
|
||||
if (substr($href, -6) == '"') {
|
||||
$href = substr($href, 6, -6);
|
||||
} else {
|
||||
$href = substr($href, 6);
|
||||
}
|
||||
}
|
||||
|
||||
if ($href == '')
|
||||
$href = $text;
|
||||
if ($text == '') {
|
||||
$text = $href;
|
||||
$text = wordwrap($text, 65, ' ', true);
|
||||
}
|
||||
|
||||
$disable = self::bbDisabled('url');
|
||||
// if not disabled and in ryzom and is proper url (<scheme>://<host>/)
|
||||
if (!$disable && self::$ig) {
|
||||
$url = @parse_url(strtolower($href));
|
||||
$disable = true;
|
||||
if (!empty($url['scheme']) && !empty($url['host'])) {
|
||||
if (in_array($url['scheme'], array('http', 'https'))) {
|
||||
if (in_array($url['host'], array('app.ryzom.com'))) {
|
||||
if (empty($url['query']) || stripos($url['query'], 'redirect') === false) {
|
||||
// http://atys.ryzom.com/
|
||||
// and does not contain redirect
|
||||
// - allow url in game browser
|
||||
$disable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // !empty
|
||||
}// isRYZOM
|
||||
|
||||
if ($disable) {
|
||||
// empty href will give proper link color without 'underline' - perfect for 'disabled' links
|
||||
if ($href == '') {
|
||||
$text = '<a href="">' . $text . '</a>';
|
||||
} else {
|
||||
$href = wordwrap($href, 65, ' ', true);
|
||||
$text = wordwrap($text, 65, ' ', true);
|
||||
$text = '<a href="">' . $text . '</a> ' . self::bb_color(self::COLOR_BBCODE_TAG, '(' . $href . ')');
|
||||
}
|
||||
return $text;
|
||||
}
|
||||
|
||||
// make sure http:// (or ftp:// or mailto:// etc is present), if not, add it
|
||||
if (!preg_match('#://#', $href)) {
|
||||
$href = 'http://' . $href;
|
||||
}
|
||||
|
||||
return sprintf('<a href="%s"' . (self::$ig ? '' : ' target="_blank"') . '>%s</a>', $href, $text);
|
||||
}
|
||||
|
||||
static function bb_img($attr, $href) {
|
||||
if (self::bbDisabled('img')) {
|
||||
return self::bb_noparse('[img]' . $href . '[/img]');
|
||||
}
|
||||
// $href is treated with htmlspecialchars() so any & in url is &
|
||||
$href = str_replace('&', '&', $href);
|
||||
|
||||
// images from current server directly
|
||||
if ($attr=='src' || strstr($href, $_SERVER['HTTP_HOST']) !== false){
|
||||
return '<img src="' . $href . '" />';
|
||||
}
|
||||
$url = proxy_image_url($href);
|
||||
return '<a href="' . $url . '&no_proxy=1"><img src="' . $url . '" /></a>';
|
||||
}
|
||||
|
||||
static function bb_banner($lang, $ckey) {
|
||||
// $lang and $ckey should already be escaped for HTML, so urlencode() in here would double escape them
|
||||
// - channel it thru image proxy. proxy does caching better and uses '304 Not Modified' status
|
||||
$src = 'http://atys.ryzom.com/api/banner.php?ckey=' . $ckey . '&langid=' . $lang . '&size=500';
|
||||
return self::bb_img('', $src);
|
||||
}
|
||||
|
||||
static function bb_mail($user) {
|
||||
$url = 'http://' . $_SERVER['HTTP_HOST'] . '/app_mail/?page=compose/to/' . urlencode($user);
|
||||
return '<a href="' . $url . '">' . $user . '</a>';
|
||||
}
|
||||
|
||||
static function bb_profile($ptype, $pname) {
|
||||
// types from app_profile
|
||||
$types = array('user', 'player', 'npc', 'fauna', 'entity', 'source');
|
||||
$ptype = array_search($ptype, $types, true);
|
||||
// if type not found, then fall back to player
|
||||
if ($ptype === false)
|
||||
$ptype = 1;
|
||||
|
||||
$url = 'http://' . $_SERVER['HTTP_HOST'] . '/app_profile/?ptype=' . intval($ptype) . '&pname=' . urlencode($pname);
|
||||
return '<a href="' . $url . '">' . $pname . '</a>';
|
||||
}
|
||||
|
||||
static function bb_color($color, $str) {
|
||||
if ($color == '') {
|
||||
return $str;
|
||||
}
|
||||
|
||||
if (self::$ig) {
|
||||
return '<font color="' . $color . '">' . $str . '</font>';
|
||||
} else {
|
||||
return '<span style="color: ' . $color . ';">' . $str . '</span>';
|
||||
}
|
||||
}
|
||||
|
||||
static function bb_size($size, $str) {
|
||||
$size = self::getFontSize($size);
|
||||
|
||||
if (self::$ig) {
|
||||
return '<font size="' . $size . 'px">' . $str . '</font>';
|
||||
} else {
|
||||
return '<span style="font-size: ' . $size . 'px;">' . $str . '</span>';
|
||||
}
|
||||
}
|
||||
|
||||
static function bb_pre($str) {
|
||||
return '<pre>' . $str . '</pre>';
|
||||
}
|
||||
|
||||
static function bb_p($str) {
|
||||
return '<p>' . $str . '</p>';
|
||||
}
|
||||
|
||||
// Added by ulukyn. WebIg compatibility.
|
||||
static function bb_center($str) {
|
||||
if (self::$ig) {
|
||||
return '<table width="100%" cellpadding="0" cellspacing="0"><tr><td align="center" valign="middle">' . $str . '</td></tr></table>';
|
||||
} else {
|
||||
return '<div style="text-align: center;">' . $str . '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
/** Table format : (added by ulukyn)
|
||||
* A1| A2|A3
|
||||
* B1| B2 |B3
|
||||
* C1|C2 |C3
|
||||
*/
|
||||
static function bb_table($attr, $content) {
|
||||
$width = isset($attr['width'])?$attr['width']:'100%';
|
||||
$border = isset($attr['border'])?$attr['border']:'0';
|
||||
$bgcolor = isset($attr['bgcolor'])?' bgcolor="'.$attr['bgcolor'].'" ':'';
|
||||
$ret = '<table width="'.$width.'" border="'.$border.'" cellpadding="0" cellspacing="0" '.$bgcolor.' >';
|
||||
$lines = explode("\n", $content);
|
||||
foreach ($lines as $line) {
|
||||
if ($line) {
|
||||
$ret .= '<tr>';
|
||||
$cols = explode('|', $line);
|
||||
foreach ($cols as $text) {
|
||||
if (!$text)
|
||||
continue;
|
||||
$params = array('valign' => 'middle');
|
||||
if ($text[0] == '#') {
|
||||
$paramsdef = explode(' ', $text);
|
||||
$paramlist = substr(array_shift($paramsdef), 1);
|
||||
$paramlist = explode(',', $paramlist);
|
||||
foreach ($paramlist as $p) {
|
||||
list($name, $value) = explode('=', $p);
|
||||
$params[ _h(str_replace('"', '', $name))] = _h(str_replace('"', '', $value));
|
||||
}
|
||||
if ($paramsdef)
|
||||
$text = implode(' ', $paramsdef);
|
||||
}
|
||||
$param_html = '';
|
||||
foreach ($params as $name => $value)
|
||||
$param_html .= $name.'="'.$value.'" ';
|
||||
|
||||
if ($text && $text[0] == ' ' && $text[strlen($text)-1] == ' ')
|
||||
$align = 'center';
|
||||
else if ($text && $text[0] == ' ')
|
||||
$align = 'right';
|
||||
else
|
||||
$align = 'left';
|
||||
|
||||
$ret .= '<td '.$param_html.' align="'.$align.'">'.$text.'</td>';
|
||||
}
|
||||
$ret .= '</tr>';
|
||||
}
|
||||
}
|
||||
|
||||
$ret .= '</table>';
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
static function bb_page_link($page, $txt) {
|
||||
if ($page == '') {
|
||||
$page = $txt;
|
||||
}
|
||||
$tmp = explode('/', $page);
|
||||
foreach ($tmp as $k => $v) {
|
||||
$tmp[$k] = urlencode($v);
|
||||
}
|
||||
$url = 'http://' . $_SERVER['HTTP_HOST'] . '/app_forum/?page=' . join('/', $tmp);
|
||||
return '<a href="' . $url . '">' . $txt . '</a>';
|
||||
}
|
||||
|
||||
static function bb_forum_link($page, $id, $txt) {
|
||||
$page = $page . '/view/' . $id;
|
||||
if ($id == '') {
|
||||
$page.= $txt;
|
||||
}
|
||||
return self::bb_page_link($page, $txt);
|
||||
}
|
||||
|
||||
// Added by Ulukyn
|
||||
static function bb_wiki_link($page, $txt) {
|
||||
$need_new_txt = false;
|
||||
if ($page == '') {
|
||||
$page = $txt;
|
||||
$need_new_txt = true;
|
||||
}
|
||||
|
||||
if (substr($page, 0, 22) == 'http://atys.ryzom.com/')
|
||||
$url = 'http://atys.ryzom.com/start/app_wiki.php?page=' . substr($page, 21);
|
||||
else {
|
||||
$tmp = explode('/', $page);
|
||||
if (count($tmp) != 2) {
|
||||
return 'Syntax: [wiki]/[page], ex: en/Chronicles';
|
||||
} else {
|
||||
$wiki = $tmp[0];
|
||||
$page = $tmp[1];
|
||||
}
|
||||
if (self::$ig) {
|
||||
$url = 'http://atys.ryzom.com/start/app_wiki.php?page=/projects/pub' . $wiki . '/wiki/' . $page;
|
||||
}
|
||||
else
|
||||
$url = 'http://atys.ryzom.com/projects/pub' . $wiki . '/wiki/' . $page;
|
||||
if ($need_new_txt)
|
||||
$txt = 'WIKI [' . $page . ']';
|
||||
}
|
||||
return '<a href="' . $url . '"' . (self::$ig ? '' : ' target="_blank"') . '>' . $txt . '</a>';
|
||||
}
|
||||
|
||||
static function bb_biu($tag, $txt) {
|
||||
$tag = strtolower($tag);
|
||||
if (self::$ig) {
|
||||
switch ($tag) {
|
||||
// FIXME: darken/lighter or tint current color
|
||||
case 'b': $txt = self::bb_color('white', $txt);
|
||||
break;
|
||||
case 'i': $txt = self::bb_color('#ffffd0', $txt);
|
||||
break;
|
||||
case 'u': $txt = '<a href="ah:">' . self::bb_color(self::COLOR_P, $txt) . '</a>';
|
||||
break;
|
||||
default : $txt = self::bb_color(self::COLOR_BBCODE_TAG, $txt);
|
||||
break; // fallback
|
||||
}
|
||||
return $txt;
|
||||
}
|
||||
|
||||
switch ($tag) {
|
||||
case 'b': $tag = 'strong';
|
||||
break;
|
||||
case 'i': $tag = 'em';
|
||||
break;
|
||||
case 'u': $tag = 'u';
|
||||
break;
|
||||
default: $tag = 'span'; // fallback
|
||||
}
|
||||
return '<' . $tag . '>' . $txt . '</' . $tag . '>';
|
||||
}
|
||||
|
||||
static function bb_date($attr, $txt) {
|
||||
$time = strtotime($txt);
|
||||
|
||||
$shardid = isset($attr['shard']) ? $attr['shard'] : self::$shardid;
|
||||
if ($time === false || $shardid === false)
|
||||
return 'ERR:[' . $txt . ']';
|
||||
|
||||
if (isset(self::$legacy_shard[$shardid])) {
|
||||
$tick = self::$legacy_shard[$shardid];
|
||||
if (self::$legacy_sync > $time) {
|
||||
// only modify game cycle when asked time is before sync
|
||||
$tick = ($time - self::$legacy_sync) * 10 + $tick;
|
||||
}
|
||||
} else {
|
||||
$tick = ryzom_time_tick($shardid);
|
||||
// tick is for NOW, adjust it to match time given
|
||||
$now = time();
|
||||
$tick = ($time - $now) * 10 + $tick;
|
||||
}
|
||||
|
||||
$rytime = ryzom_time_array($tick, $shardid);
|
||||
$txt = ryzom_time_txt($rytime, self::$lang);
|
||||
|
||||
return $txt;
|
||||
}
|
||||
|
||||
static function bb_lang($attr, $txt) {
|
||||
if (_user()->lang == $attr)
|
||||
return $txt;
|
||||
else
|
||||
return '';
|
||||
}
|
||||
|
||||
static function bb_time($options, $txt) {
|
||||
$time = strtotime($txt);
|
||||
|
||||
if ($time == 0) {
|
||||
return $txt;
|
||||
}
|
||||
|
||||
$timezone = self::$timezone;
|
||||
|
||||
$show_time = '';
|
||||
$show_date = '';
|
||||
$show_timer = '';
|
||||
|
||||
if (is_array($options)) {
|
||||
foreach ($options as $key => $val) {
|
||||
switch ($key) {
|
||||
case 'timezone':
|
||||
// fix some timezones for php
|
||||
switch ($val) {
|
||||
case 'pst': // fall thru
|
||||
case 'pdt': $val = 'US/Pacific';
|
||||
break;
|
||||
}
|
||||
$timezone = $val;
|
||||
break;
|
||||
case 'date' :
|
||||
$show_date = $val == 'off' ? false : $val;
|
||||
break;
|
||||
case 'time' :
|
||||
$show_time = $val == 'off' ? false : $val;
|
||||
break;
|
||||
case 'timer':
|
||||
$show_timer = $val == 'off' ? false : $val;
|
||||
break;
|
||||
}//switch
|
||||
}//foreach
|
||||
}
|
||||
|
||||
$ret = array();
|
||||
|
||||
$old_timezone = date_default_timezone_get();
|
||||
@date_default_timezone_set($timezone);
|
||||
if ($show_date !== false) {
|
||||
$date = ryzom_absolute_time($time);
|
||||
//ryzom_absolute_time does not have year, so we need to add it
|
||||
$current_y = date('Y', time());
|
||||
$y = date('Y', $time);
|
||||
if ($y != $current_y) {
|
||||
$date.= ' ' . $y;
|
||||
}
|
||||
$ret[] = self::bb_color($show_date, $date);
|
||||
}
|
||||
if ($show_time !== false) {
|
||||
$fmtTime = self::$clock12h ? 'g:i:s a T' : 'H:i:s T';
|
||||
$ret[] = self::bb_color($show_time, date($fmtTime, $time));
|
||||
}
|
||||
date_default_timezone_set($old_timezone);
|
||||
|
||||
if ($show_timer !== false) {
|
||||
if ($show_time === false && $show_date === false) {
|
||||
$f = '%s';
|
||||
} else {
|
||||
$f = '(%s)';
|
||||
}
|
||||
$ret[] = self::bb_color($show_timer, sprintf($f, ryzom_relative_time($time)));
|
||||
}
|
||||
|
||||
return join(' ', $ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called by bbCodeParser class
|
||||
*
|
||||
* @see bbCodeParser::format
|
||||
*/
|
||||
public function format($tag, $open, $close, $attr, $text) {
|
||||
// silly functions all have different parameters
|
||||
switch ($tag) {
|
||||
case 'noparse' :
|
||||
$result = self::bb_noparse($text);
|
||||
break;
|
||||
case 'code' :
|
||||
$result = self::bb_code($text);
|
||||
break;
|
||||
case 'quote' :
|
||||
$result = self::bb_quote($attr, $text);
|
||||
break;
|
||||
case 'h1' : // fall thru
|
||||
case 'h2' : // fall thru
|
||||
case 'h3' : // fall thru
|
||||
case 'h4' : // fall thru
|
||||
case 'h5' : // fall thru
|
||||
case 'h6' :
|
||||
$nr = (int) substr($tag, -1);
|
||||
$color = isset($attr['color']) ? $attr['color'] : '';
|
||||
$result = self::bb_h($nr, $color, $text);
|
||||
break;
|
||||
case 'color' :
|
||||
$result = self::bb_color($attr, $text);
|
||||
break;
|
||||
case 'size' :
|
||||
$result = self::bb_size($attr, $text);
|
||||
break;
|
||||
case 'list' :
|
||||
$result = self::bb_list($text);
|
||||
break;
|
||||
case 'img' :
|
||||
$result = self::bb_img($attr, $text);
|
||||
break;
|
||||
case 'banner' :
|
||||
$result = self::bb_banner($attr, $text);
|
||||
break;
|
||||
case 'pre' :
|
||||
$result = self::bb_pre($text);
|
||||
break;
|
||||
case 'p' :
|
||||
$result = self::bb_p($text);
|
||||
break;
|
||||
case 'table' :
|
||||
$result = self::bb_table($attr, $text);
|
||||
break;
|
||||
case 'center' :
|
||||
$result = self::bb_center($text);
|
||||
break;
|
||||
case 'url' :
|
||||
$result = self::bb_url($attr, $text);
|
||||
break;
|
||||
case 'mail' :
|
||||
$result = self::bb_mail($text);
|
||||
break;
|
||||
case 'profile' :
|
||||
$result = self::bb_profile($attr, $text);
|
||||
break;
|
||||
case 'page' :
|
||||
$result = self::bb_page_link($attr, $text);
|
||||
break;
|
||||
case 'forum' : // fall thru
|
||||
case 'topic' : // fall thru
|
||||
case 'post' :
|
||||
$result = self::bb_forum_link($tag, $attr, $text);
|
||||
break;
|
||||
case 'wiki' :
|
||||
$result = self::bb_wiki_link($attr, $text);
|
||||
break;
|
||||
case 'b' : // fall thru
|
||||
case 'i' : // fall thru
|
||||
case 'u' :
|
||||
$result = self::bb_biu($tag, $text);
|
||||
break;
|
||||
case 'time' :
|
||||
$result = self::bb_time($attr, $text);
|
||||
break;
|
||||
case 'date' :
|
||||
$result = self::bb_date($attr, $text);
|
||||
break;
|
||||
case 'lang' :
|
||||
$result = self::bb_lang($attr, $text);
|
||||
break;
|
||||
default :
|
||||
$result = $open . $text . $close;
|
||||
break;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces some BBcode with HTML code
|
||||
*
|
||||
* NOTE: $text should be already escaped for HTML
|
||||
*
|
||||
* @param string $text html escaped input text
|
||||
* @param array $disabledTags
|
||||
*/
|
||||
static function parse($text, $disabledTags = array()) {
|
||||
static $parser = null;
|
||||
if ($parser === null) {
|
||||
$parser = new self(self::$ig);
|
||||
}
|
||||
$parser->reset();
|
||||
|
||||
self::$disabledTags = $disabledTags;
|
||||
return $parser->bbcode($text);
|
||||
}
|
||||
|
||||
}
|
|
@ -17,6 +17,9 @@
|
|||
* along with ryzom_api. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define('RYAPI_MODE', 'client');
|
||||
define('RYAPI_USE_PLAYER_STATS', false);
|
||||
|
||||
// Url where the api is
|
||||
define('RYAPI_URL', 'http://');
|
||||
if (!defined('RYAPI_PATH'))
|
||||
|
@ -24,5 +27,6 @@ if (!defined('RYAPI_PATH'))
|
|||
// used by "home" link
|
||||
if (!defined('RYAPP_URL'))
|
||||
define('RYAPP_URL', 'http://');
|
||||
|
||||
if (!defined('RYAPI_AUTH_KEY'))
|
||||
define('RYAPI_AUTH_KEY', ''); // key gived by AUTH_SERVER
|
||||
?>
|
||||
|
|
24
code/web/api/common/db_defs.php
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
/* Copyright (C) 2012 Winch Gate Property Limited
|
||||
*
|
||||
* This file is part of ryzom_api.
|
||||
* ryzom_api is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ryzom_api is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with ryzom_api. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// init database table used by webig
|
||||
$db = ryDB::getInstance('webig');
|
||||
$db->setDbDefs('players', array('id' => SQL_DEF_INT, 'cid' => SQL_DEF_INT, 'name' => SQL_DEF_TEXT, 'gender' => SQL_DEF_INT, 'creation_date' => SQL_DEF_DATE, 'deleted' => SQL_DEF_BOOLEAN, 'last_login' => SQL_DEF_TEXT, 'dev_shard' => SQL_DEF_BOOLEAN));
|
||||
$db->setDbDefs('accounts', array('uid' => SQL_DEF_INT, 'web_privs' => SQL_DEF_TEXT));
|
||||
|
||||
?>
|
|
@ -43,80 +43,85 @@ class ServerDatabase
|
|||
}
|
||||
|
||||
if (($this->hostname != '') && ($this->username != '') && ($this->database != ''))
|
||||
{
|
||||
$this->_connection = mysql_connect($this->hostname, $this->username, $this->password)
|
||||
or die("ERR1"); // ace . $this->get_error());
|
||||
$this->select_db($this->database);
|
||||
}
|
||||
$this->_connection = new mysqli($this->hostname, $this->username, $this->password, $this->database);
|
||||
}
|
||||
|
||||
function close()
|
||||
{
|
||||
@mysql_close($this->_connection);
|
||||
$this->_connection->close();
|
||||
}
|
||||
|
||||
function query($sql_statement)
|
||||
{
|
||||
$result = mysql_query($sql_statement, $this->_connection);
|
||||
$result = $this->_connection->query($sql_statement);
|
||||
if (!$result)
|
||||
alert('MYSQL', $this->get_error(), 2);
|
||||
return $result;
|
||||
}
|
||||
|
||||
function select_db($dbname) {
|
||||
$this->database = $dbname;
|
||||
mysql_select_db($this->database, $this->_connection) or die("Database selection error : " . $this->get_error());
|
||||
$this->_connection->select_db($dbname);
|
||||
}
|
||||
|
||||
function num_rows($result)
|
||||
{
|
||||
return @mysql_num_rows($result);
|
||||
return $result->num_rows;
|
||||
}
|
||||
|
||||
function fetch_row($result, $result_type=MYSQL_BOTH)
|
||||
function fetch_row($result, $result_type=MYSQLI_BOTH)
|
||||
{
|
||||
return @mysql_fetch_array($result, $result_type);
|
||||
if (gettype($result) == "object")
|
||||
return $result->fetch_array($result_type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
function fetch_assoc($result)
|
||||
{
|
||||
return @mysql_fetch_array($result, MYSQL_ASSOC);
|
||||
if (gettype($result) == "object")
|
||||
return $result->fetch_assoc();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
function query_single_row($sql_statement)
|
||||
{
|
||||
$result = $this->query($sql_statement);
|
||||
return @mysql_fetch_array($result);
|
||||
if (gettype($result) == "object")
|
||||
return $result->fetch_array();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
function free_result($result)
|
||||
{
|
||||
@mysql_free_result($result);
|
||||
$result->free();
|
||||
}
|
||||
|
||||
function get_error()
|
||||
{
|
||||
return mysql_errno($this->_connection) .": ". mysql_error($this->_connection);
|
||||
return $this->_connection->errno.': '.$this->_connection->error;
|
||||
}
|
||||
|
||||
function last_insert_id()
|
||||
{
|
||||
return @mysql_insert_id();
|
||||
return $this->_connection->insert_id;
|
||||
}
|
||||
|
||||
function escape_string($escapestr) {
|
||||
return $this->_connection->real_escape_string($escapestr);
|
||||
}
|
||||
|
||||
function change_to($host,$user,$pass,$dbname)
|
||||
{
|
||||
$this->close();
|
||||
/*$this->close();
|
||||
$this->hostname = $host;
|
||||
$this->username = $user;
|
||||
$this->password = $pass;
|
||||
$this->database = $dbname;
|
||||
$this->ServerDatabase();
|
||||
$this->ServerDatabase();*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
class ryDB {
|
||||
|
||||
private static $_instances = array();
|
||||
|
@ -127,7 +132,7 @@ class ryDB {
|
|||
|
||||
private function __construct($db_name) {
|
||||
global $_RYZOM_API_CONFIG;
|
||||
|
||||
$this->db_name = $db_name;
|
||||
$this->db = new ServerDatabase(RYAPI_WEBDB_HOST, RYAPI_WEBDB_LOGIN, RYAPI_WEBDB_PASS, $db_name);
|
||||
$this->db->query("SET NAMES utf8");
|
||||
}
|
||||
|
@ -140,14 +145,37 @@ class ryDB {
|
|||
return self::$_instances[$db_name];
|
||||
}
|
||||
|
||||
function setDbDefs($table, $defs) {
|
||||
function setDbDefs($table, $defs, $check=true) {
|
||||
if ($check)
|
||||
{
|
||||
$result = $this->db->query('SHOW FIELDS FROM '.$table);
|
||||
if (!$result) {
|
||||
die("Table [$table] not found in database [$this->db_name]");
|
||||
|
||||
}
|
||||
|
||||
$fields = array_keys($defs);
|
||||
while ($row = $this->db->fetch_row($result)) {
|
||||
if (in_array($row['Field'], $fields))
|
||||
unset($fields[array_search($row['Field'], $fields)]);
|
||||
else
|
||||
alert('DbLib', 'Missing field '.$row['Field']." on DbDef of table [$table] of database [$this->db_name] !", 2);
|
||||
}
|
||||
if ($fields)
|
||||
die('Missing fields ['.implode('] [', $fields)."] in table [$table] of database [$this->db_name] !");
|
||||
}
|
||||
$this->defs[$table] = $defs;
|
||||
}
|
||||
|
||||
function getDefs($table) {
|
||||
if (!array_key_exists($table, $this->defs))
|
||||
die("Please add tables defs using setDbDefs('$table', \$defs)");
|
||||
if ($this->hasDbDefs($table))
|
||||
return $this->defs[$table];
|
||||
|
||||
alert('DBLIB', "Please add tables to '$this->db_name' defs using setDbDefs('$table', \$defs)", 2);
|
||||
}
|
||||
|
||||
function hasDbDefs($table) {
|
||||
return array_key_exists($table, $this->defs);
|
||||
}
|
||||
|
||||
function getErrors() {
|
||||
|
@ -170,11 +198,36 @@ class ryDB {
|
|||
$this->props[$table] = $props;
|
||||
}
|
||||
|
||||
function sqlEscape($escapestr) {
|
||||
return $this->db->escape_string($escapestr);
|
||||
}
|
||||
|
||||
function insertID() {
|
||||
return $this->db->last_insert_id();
|
||||
}
|
||||
|
||||
|
||||
/// DIRECT QUERY
|
||||
function sqlQuery($sql) {
|
||||
function sqlQuery($sql, $index = false, $result_type = MYSQLI_BOTH) {
|
||||
$result = $this->db->query($sql);
|
||||
if (!$result)
|
||||
return NULL;
|
||||
if($index !== false && !is_array($index)){
|
||||
$index = array($index);
|
||||
}
|
||||
$ret = array();
|
||||
while ($row = $this->db->fetch_row($result)) {
|
||||
while ($row = $this->db->fetch_row($result, $result_type)) {
|
||||
if($index !== false) {
|
||||
// if $index is ['id1', 'id2'], then this code executes as
|
||||
// $ret[$row['id1']][$row['id2']] = $row
|
||||
$current = &$ret;
|
||||
foreach($index as $key){
|
||||
if(!isset($row[$key]))
|
||||
alert('DBLIB', "Requested index field ($key) was not selected from db");
|
||||
$current = &$current[$row[$key]];
|
||||
}
|
||||
$current = $row;
|
||||
} else
|
||||
$ret[] = $row;
|
||||
}
|
||||
return $ret;
|
||||
|
@ -188,16 +241,16 @@ class ryDB {
|
|||
$params = array();
|
||||
$test = array();
|
||||
if (!$props)
|
||||
die("Bad Select on [$table] : missing props");
|
||||
alert('DBLIB', "Bad Select on [$table] : missing props");
|
||||
|
||||
foreach($props as $name => $type)
|
||||
$params[] = '`'.addslashes($name).'`';
|
||||
$params[] = '`'.$this->sqlEscape($name).'`';
|
||||
|
||||
foreach($values as $name => $value) {
|
||||
if ($name[0] == '=')
|
||||
$test[] = '('.addslashes(substr($name, 1)).' LIKE '.var_export($value, true).')';
|
||||
$test[] = '('.$this->sqlEscape(substr($name, 1)).' LIKE '.var_export($value, true).')';
|
||||
else
|
||||
$test[] = '('.addslashes($name).' = '.var_export($value, true).')';
|
||||
$test[] = '('.$this->sqlEscape($name).' = '.var_export($value, true).')';
|
||||
}
|
||||
$sql .= implode(",\n\t", $params)."\nFROM\n\t".$table."\n";
|
||||
if ($test)
|
||||
|
@ -212,36 +265,34 @@ class ryDB {
|
|||
|
||||
function querySingle($table, $values=array(), $extra='') {
|
||||
$sql = $this->sqlSelect($table, $this->getDefs($table), $values, $extra);
|
||||
$result = $this->db->query($sql);
|
||||
return $this->db->fetch_row($result);
|
||||
$result = $this->sqlQuery($sql, false, MYSQLI_BOTH);
|
||||
if(empty($result))
|
||||
return NULL;
|
||||
return $result[0];
|
||||
}
|
||||
|
||||
function querySingleAssoc($table, $values=array(), $extra='') {
|
||||
$sql = $this->sqlSelect($table, $this->getDefs($table), $values, $extra);
|
||||
$result = $this->db->query($sql);
|
||||
return $this->db->fetch_row($result, MYSQL_ASSOC);
|
||||
$result = $this->sqlQuery($sql, false, MYSQLI_ASSOC);
|
||||
if(empty($result))
|
||||
return NULL;
|
||||
return $result[0];
|
||||
}
|
||||
|
||||
function query($table, $values=array(), $extra='') {
|
||||
function query($table, $values=array(), $extra='', $index = false, $result_type = MYSQLI_BOTH) {
|
||||
$sql = $this->sqlSelect($table, $this->getDefs($table), $values, $extra);
|
||||
$result = $this->db->query($sql);
|
||||
$ret = array();
|
||||
while ($row = $this->db->fetch_row($result)) {
|
||||
$ret[] = $row;
|
||||
}
|
||||
return $ret;
|
||||
return $this->sqlQuery($sql, $index, $result_type);
|
||||
}
|
||||
|
||||
function queryAssoc($table, $values=array(), $extra='') {
|
||||
$sql = $this->sqlSelect($table, $this->getDefs($table), $values, $extra);
|
||||
$result = $this->db->query($sql);
|
||||
$ret = array();
|
||||
while ($row = $this->db->fetch_row($result, MYSQL_ASSOC)) {
|
||||
$ret[] = $row;
|
||||
function queryAssoc($table, $values=array(), $extra='', $index = false) {
|
||||
return $this->query($table, $values, $extra, $index, MYSQLI_ASSOC);
|
||||
}
|
||||
return $ret;
|
||||
|
||||
function queryIndex($table, $index, $values=array(), $extra='') {
|
||||
return $this->query($table, $values, $extra, $index, MYSQLI_ASSOC);
|
||||
}
|
||||
|
||||
|
||||
/// INSERT ///
|
||||
function sqlInsert($table, $props, $vals) {
|
||||
$sql = 'INSERT INTO '.$table.' ';
|
||||
|
@ -250,7 +301,7 @@ class ryDB {
|
|||
foreach($props as $name => $type) {
|
||||
if (!isset($vals[$name]))
|
||||
continue;
|
||||
$params[] = $name;
|
||||
$params[] = '`'.$name.'`';
|
||||
switch ($type) {
|
||||
case SQL_DEF_BOOLEAN:
|
||||
$values[] = $vals[$name]?1:0;
|
||||
|
@ -260,12 +311,12 @@ class ryDB {
|
|||
break;
|
||||
case SQL_DEF_DATE: // date
|
||||
if (is_string($vals[$name]))
|
||||
$values[] = "'".addslashes($vals[$name])."'";
|
||||
$values[] = "'".$this->sqlEscape($vals[$name])."'";
|
||||
else
|
||||
$values[] = "'".$this->toDate($vals[$name])."'";
|
||||
break;
|
||||
default:
|
||||
$values[] = "'".addslashes($vals[$name])."'";
|
||||
$values[] = "'".$this->sqlEscape($vals[$name])."'";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -284,7 +335,7 @@ class ryDB {
|
|||
$sql = "DELETE FROM\n\t".$table."\n";
|
||||
$test = array();
|
||||
foreach($values as $name => $value)
|
||||
$test[] = '('.addslashes($name).' = '.var_export($value, true).')';
|
||||
$test[] = '('.$this->sqlEscape($name).' = '.var_export($value, true).')';
|
||||
|
||||
if ($test or $where)
|
||||
$sql .= "WHERE\n\t";
|
||||
|
@ -316,19 +367,19 @@ class ryDB {
|
|||
break;
|
||||
case SQL_DEF_DATE:
|
||||
if (is_string($vals[$name]))
|
||||
$values[] = '`'.$name.'` = \''.addslashes($vals[$name]).'\'';
|
||||
$values[] = '`'.$name.'` = \''.$this->sqlEscape($vals[$name]).'\'';
|
||||
else
|
||||
$values[] = '`'.$name.'` = \''.$this->toDate($vals[$name]).'\'';
|
||||
break;
|
||||
default:
|
||||
$values[] = '`'.$name.'` = \''.addslashes($vals[$name]).'\'';
|
||||
$values[] = '`'.$name.'` = \''.$this->sqlEscape($vals[$name]).'\'';
|
||||
break;
|
||||
}
|
||||
}
|
||||
$sql .= "\n\t".implode(",\n\t", $values)."\n";
|
||||
|
||||
foreach($tests as $name => $value) {
|
||||
$test[] = '('.addslashes($name).' = '.var_export($value, true).')';
|
||||
$test[] = '('.$this->sqlEscape($name).' = '.var_export($value, true).')';
|
||||
}
|
||||
if ($test)
|
||||
$sql .= "WHERE\n\t".implode("\nAND\n\t", $test);
|
||||
|
@ -363,17 +414,17 @@ class ryDB {
|
|||
continue;
|
||||
switch ($type) {
|
||||
case 'trad':
|
||||
$values[] = '`'.$name."` = '".addslashes($vals[$name])."'";
|
||||
$values[] = '`'.$name."` = '".$this->sqlEscape($vals[$name])."'";
|
||||
break;
|
||||
case 'textarea':
|
||||
case 'string':
|
||||
case 'option':
|
||||
$values[] = '`'.$name."` = '".addslashes($vals[$name])."'";
|
||||
$values[] = '`'.$name."` = '".$this->sqlEscape($vals[$name])."'";
|
||||
break;
|
||||
case 'id':
|
||||
case 'int':
|
||||
case 'float':
|
||||
$values[] = '`'.$name.'` = '.addslashes($vals[$name]);
|
||||
$values[] = '`'.$name.'` = '.$this->sqlEscape($vals[$name]);
|
||||
break;
|
||||
case 'bool':
|
||||
$values[] = '`'.$name.'` = '.($vals[$name]?'1':'0');
|
||||
|
@ -417,6 +468,55 @@ class ryDB {
|
|||
return $ret;
|
||||
}
|
||||
|
||||
/// Update Database Structure
|
||||
|
||||
static function updateDatabaseStruct($defs)
|
||||
{
|
||||
if (file_exists(RYAPP_PATH.'database.versions'))
|
||||
$versions = unserialize(file_get_contents(RYAPP_PATH.'database.versions'));
|
||||
else
|
||||
$versions = array();
|
||||
|
||||
$c = "Updating DB Structure...\n";
|
||||
foreach ($defs as $dbname => $tables) {
|
||||
$db = new ServerDatabase(RYAPI_WEBDB_HOST, RYAPI_WEBDB_LOGIN, RYAPI_WEBDB_PASS, $dbname);
|
||||
$db->query("SET NAMES utf8");
|
||||
$c .= "\n Selected DB '$dbname'\n";
|
||||
foreach ($tables as $table => $sql)
|
||||
{
|
||||
$version = count($sql);
|
||||
if (array_key_exists($table, $versions))
|
||||
$diff = $version - $versions[$table];
|
||||
else {
|
||||
$versions[$table] = 0;
|
||||
$diff = $version;
|
||||
}
|
||||
|
||||
$c .= " Table '$table' need v$version (current v".strval($versions[$table].') => ');
|
||||
|
||||
if ($diff > 0) {
|
||||
$sql_to_run = array_slice($sql, $versions[$table], $diff);
|
||||
foreach($sql_to_run as $sql_run) {
|
||||
if ($sql_run) {
|
||||
$c .= "Run sql... ";
|
||||
$result = $db->query($sql_run);
|
||||
} else
|
||||
$c .= "KO!!!";
|
||||
}
|
||||
if ($result) {
|
||||
$c .= "OK";
|
||||
$versions[$table] = $version;
|
||||
}
|
||||
} else
|
||||
$c .= "OK";
|
||||
$c .= "\n";
|
||||
}
|
||||
$c .= "\n";
|
||||
$db->close();
|
||||
}
|
||||
file_put_contents(RYAPP_PATH.'database.versions', serialize($versions));
|
||||
return '<pre>'.$c.'<pre>';
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
151
code/web/api/common/dfm.php
Normal file
|
@ -0,0 +1,151 @@
|
|||
<?php
|
||||
|
||||
/* Copyright (C) 2009 Winch Gate Property Limited
|
||||
*
|
||||
* This file is part of ryzom_api.
|
||||
* ryzom_api is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ryzom_api is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with ryzom_api. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
function getDirLinks($url_params, $path, $getvar, $home) {
|
||||
$ret = '';
|
||||
$dirs = explode('/', $path);
|
||||
$dirpath = '';
|
||||
$ret .= _l($home, $url_params, array($getvar => ''));
|
||||
foreach($dirs as $dirname) {
|
||||
if ($dirname) {
|
||||
$ret .= ' » '._l($dirname, $url_params, array($getvar => '/'.$dirpath.$dirname));
|
||||
$dirpath .= $dirname.'/';
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function isEmptyDir($dir)
|
||||
{
|
||||
if (($files = scandir($dir)) && count($files) <= 2) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
class ryDataFileManager {
|
||||
|
||||
public $id;
|
||||
public $log_dir;
|
||||
public $data_dir;
|
||||
public $user_dir;
|
||||
public $app_name;
|
||||
|
||||
function __construct($id, $app_name=APP_NAME) {
|
||||
$this->app_name = $app_name;
|
||||
$id = (strlen($id) == 0?'0':'').$id;
|
||||
$id = (strlen($id) == 1?'0':'').$id;
|
||||
$this->id = $id;
|
||||
$this->log_dir = RYAPP_PATH.$app_name.'/data/logs/';
|
||||
$this->data_dir = RYAPP_PATH.$app_name.'/data/app/';
|
||||
$this->user_dir = RYAPP_PATH.$app_name.'/data/chars/'.$id[0].'/'.$id[1].'/'.$id.'/';
|
||||
|
||||
if (!is_dir($this->user_dir))
|
||||
@mkdir($this->user_dir, 0777, true);
|
||||
|
||||
if (!is_dir($this->log_dir)) {
|
||||
@mkdir($this->log_dir, 0777, true);
|
||||
@mkdir($this->data_dir, 0777, true);
|
||||
}
|
||||
}
|
||||
|
||||
/*** Generic datafiles access methods ***/
|
||||
|
||||
function getData($name, $default=null) {
|
||||
if (file_exists($name))
|
||||
return unserialize(file_get_contents($name));
|
||||
if ($default !== NULL) {
|
||||
@file_put_contents($name, serialize($default));
|
||||
return $default;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
function saveData($name, $datas, $create_folders=true) {
|
||||
if ($create_folders) {
|
||||
if (!is_dir(dirname($name)))
|
||||
@mkdir(dirname($name), 0777, true);
|
||||
}
|
||||
if ($datas !== NULL)
|
||||
@file_put_contents($name, serialize($datas));
|
||||
else
|
||||
@unlink($name);
|
||||
}
|
||||
|
||||
function listDataFiles($dir) {
|
||||
$ret = array();
|
||||
if ($handle = @opendir($dir)) {
|
||||
while (false !== ($file = readdir($handle))) {
|
||||
if ($file != '.' && $file != '..' && $file[0] != '.')
|
||||
$ret[] = $file;
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/*** App Datas ***/
|
||||
|
||||
function loadAppData($name, $default=null) {
|
||||
return $this->getData($this->data_dir.$name, $default);
|
||||
}
|
||||
|
||||
function saveAppData($name, $datas, $create_folders=true) {
|
||||
return $this->saveData($this->data_dir.$name, $datas, $create_folders);
|
||||
}
|
||||
|
||||
function listAppDataFiles($basedir='') {
|
||||
return $this->listDataFiles($this->data_dir.$basedir);
|
||||
}
|
||||
|
||||
|
||||
/*** User Datas ***/
|
||||
|
||||
function loadUserData($name, $default=null) {
|
||||
return $this->getData($this->user_dir.$name, $default);
|
||||
}
|
||||
|
||||
function saveUserData($name, $datas, $create_folders=true) {
|
||||
return $this->saveData($this->user_dir.$name, $datas, $create_folders);
|
||||
}
|
||||
|
||||
function listUserDataFiles($basedir='') {
|
||||
return $this->listDataFiles($this->user_dir.$basedir);
|
||||
}
|
||||
|
||||
function loadUserDataFromApp($name, $app, $default=null) {
|
||||
$id = $this->id;
|
||||
$file = RYAPP_PATH.$app.'/data/chars/'.$id[0].'/'.$id[1].'/'.$id.'/'.$name;
|
||||
if (file_exists($file))
|
||||
return unserialize(file_get_contents($file));
|
||||
if ($default !== null)
|
||||
return $default;
|
||||
return null;
|
||||
}
|
||||
|
||||
function saveUserDataFromApp($name, $app, $datas) {
|
||||
$id = $this->id;
|
||||
$dir = RYAPP_PATH.$app.'/data/chars/'.$id[0].'/'.$id[1].'/'.$id.'/';
|
||||
if (!is_dir($dir))
|
||||
@mkdir($dir, 0777, true);
|
||||
file_put_contents($dir.$name, serialize($datas));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
|
@ -1,9 +1,26 @@
|
|||
<?php
|
||||
|
||||
/* Copyright (C) 2009 Winch Gate Property Limited
|
||||
*
|
||||
* This file is part of ryzom_api.
|
||||
* ryzom_api is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ryzom_api is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with ryzom_api. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
class ryLogger {
|
||||
|
||||
public $enable = false;
|
||||
private $logs;
|
||||
private $logs = array();
|
||||
private static $_instance = NULL;
|
||||
|
||||
public static function getInstance() {
|
||||
|
@ -32,12 +49,16 @@ class ryLogger {
|
|||
|
||||
function getLogs() {
|
||||
$ret = '';
|
||||
if ($this->logs && $this->enable)
|
||||
$ret = "<b>Debug</b>\n\n".implode("\n", $this->logs);
|
||||
if ($this->logs && $this->enable) {
|
||||
$ret = '<b>Debug</b><br /><br /><pre style="overflow:auto; width:100%">'. implode('<br />', $this->logs).'</pre>';
|
||||
$this->logs = array();
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
function _log() {
|
||||
return ryLogger::getInstance();
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
/* Copyright (C) 2009 Winch Gate Property Limited
|
||||
*
|
||||
* This file is part of ryzom_api.
|
||||
|
@ -16,44 +17,67 @@
|
|||
* along with ryzom_api. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
function ryzom_app_render($title, $content, $ig=false, $bgcolor='', $javascript=array(), $homeLink=false) {
|
||||
function ryzom_app_render($title, $content, $style='', $files=array(), $homeLink=false) {
|
||||
$c = '';
|
||||
|
||||
// get Lua code
|
||||
$c .= ryLua::get(RYZOM_IG);
|
||||
$at_end = ryLua::getEnd(RYZOM_IG);
|
||||
|
||||
// Render header
|
||||
$title_prefix = '';
|
||||
if (ON_IPHONE) {
|
||||
$title_prefix = 'Ryzom - ';
|
||||
}
|
||||
|
||||
if (!$bgcolor)
|
||||
$bgcolor = '#000000'.($ig?'00':'');
|
||||
|
||||
if (!$ig) {
|
||||
if (!RYZOM_IG)
|
||||
$c .= '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">'."\n";
|
||||
$c .= '<html>
|
||||
<head>'."\n";
|
||||
$c .= '<html><head>'."\n";
|
||||
$c .= ' <title>'.$title_prefix.(translation_exists($title)?_t($title):$title).'</title>'."\n";
|
||||
if (!RYZOM_IG)
|
||||
$c .= ' <meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8" />'."\n";
|
||||
|
||||
$events = '';
|
||||
if (!RYZOM_IG) {
|
||||
$c .= ryzom_render_header();
|
||||
$c .= ryzom_render_header_www();
|
||||
$events = ON_IPHONE ? 'onorientationchange="updateOrientation();" ' : '';
|
||||
$c .= ' </head>'."\n";
|
||||
$c .= ' <body '.$events.'bgcolor="'.$bgcolor.'">'."\n";
|
||||
// Javascript
|
||||
$js_code = '';
|
||||
foreach ($javascript as $js)
|
||||
$js_code .= '<script type="text/javascript" src="'.$js.'"></script>';
|
||||
$c .= $js_code;
|
||||
|
||||
$c .= ryzom_render_www(ryzom_render_window($title, $content, $homeLink));
|
||||
$c .= '</body></html>';
|
||||
if (function_exists('newrelic_get_browser_timing_header'))
|
||||
$c .= newrelic_get_browser_timing_header();
|
||||
if(ON_IPHONE) $events = 'onorientationchange="updateOrientation();" ';
|
||||
} else {
|
||||
$c .= '<html><body bgcolor="'.$bgcolor.'">';
|
||||
$c .= $content;
|
||||
$debug = ryLogger::getInstance()->getLogs();
|
||||
if ($debug)
|
||||
$c .= '<table width="100%"><tr bgcolor="#002200"><td>'.$debug.'</td></tr></table>';
|
||||
$c .= '</body></html>';
|
||||
#if (!$style)
|
||||
$style='bgcolor="#00000000"';
|
||||
}
|
||||
|
||||
if (!RYZOM_IG) {
|
||||
// Javascript
|
||||
$extra_code = '';
|
||||
if (is_string($files))
|
||||
$files = array($files);
|
||||
foreach ($files as $file) {
|
||||
$sfile = explode('.', $file);
|
||||
if ($sfile[count($sfile)-1] == 'js')
|
||||
$extra_code .= ' <script type="text/javascript" src="'.$file.'"></script>'."\n";
|
||||
else if ($sfile[count($sfile)-1] == 'css')
|
||||
$extra_code .= ' <link rel="stylesheet" type="text/css" media="all" href="'.$file.'" />'."\n";
|
||||
}
|
||||
$c .= $extra_code;
|
||||
}
|
||||
|
||||
$c .= ' </head>'."\n";
|
||||
$c .= ' <body '.$events.' '.$style.'>'."\n";
|
||||
|
||||
if (!RYZOM_IG) {
|
||||
$c .= ryzom_render_www(ryzom_render_window($title, $content, $homeLink));
|
||||
$c .= '</body>';
|
||||
if (function_exists('newrelic_get_browser_timing_header'))
|
||||
$c .= newrelic_get_browser_timing_footer();
|
||||
} else {
|
||||
$c .= $content.'<br /><table bgcolor="#000000"><tr><td>'.ryLogger::getInstance()->getLogs().'</td></tr></table></body>';
|
||||
}
|
||||
|
||||
$c .= '</html>'.$at_end;
|
||||
|
||||
return $c;
|
||||
}
|
||||
|
||||
|
@ -146,7 +170,9 @@ function ryzom_render_window_begin($title, $homeLink=false) {
|
|||
}
|
||||
|
||||
function ryzom_render_window_end() {
|
||||
global $user;
|
||||
return '</div>
|
||||
<div>P_'.(isset($user['id'])?$user['id']:'GUEST').':'.(isset( $user['groups'])?implode(':', $user['groups']):'').'</div>
|
||||
<div style="background-color: #000000">'.ryLogger::getInstance()->getLogs().'</div></div></div></div>
|
||||
<div class="ryzom-ui-bl"><div class="ryzom-ui-br"><div class="ryzom-ui-b"></div></div></div><p class="ryzom-ui-notice">powered by <a class="ryzom-ui-notice" href="http://dev.ryzom.com/projects/ryzom-api/wiki">ryzom-api</a></p>
|
||||
</div>
|
||||
|
@ -179,6 +205,7 @@ function ryzom_render_www_begin($url='') {
|
|||
<a href="'.$url.'&lang=en"><img hspace="5" border="0" src="'.RYAPI_URL.'data/img/lang/en.png" alt="English" /></a>
|
||||
<a href="'.$url.'&lang=fr"><img hspace="5" border="0" src="'.RYAPI_URL.'data/img/lang/fr.png" alt="French" /></a>
|
||||
<a href="'.$url.'&lang=de"><img hspace="5" border="0" src="'.RYAPI_URL.'data/img/lang/de.png" alt="German" /></a>
|
||||
<a href="'.$url.'&lang=es"><img hspace="5" border="0" src="'.RYAPI_URL.'data/img/lang/es.png" alt="Spanish" /></a>
|
||||
<a href="'.$url.'&lang=ru"><img hspace="5" border="0" src="'.RYAPI_URL.'data/img/lang/ru.png" alt="Russian" /></a>
|
||||
<div style="'.$style2.'">
|
||||
<a href="http://www.ryzom.com/"><img border="0" src="'.RYAPI_URL.'data/img/logo.gif" alt=""/></a>
|
||||
|
@ -191,20 +218,68 @@ function ryzom_render_www_end() {
|
|||
return '</div>';
|
||||
}
|
||||
|
||||
function ryzom_render_login_form($char, $aligned=true) {
|
||||
|
||||
function _s($tag, $text) {
|
||||
global $ryzom_render_styles, $ryzom_render_tmpls;
|
||||
if (!array_key_exists($tag, $ryzom_render_tmpls))
|
||||
return $text;
|
||||
if (is_array($text))
|
||||
return $p = $text;
|
||||
else
|
||||
$p[0] = $text;
|
||||
$p['color1'] = $ryzom_render_styles[$tag][0];
|
||||
$p['color2'] = $ryzom_render_styles[$tag][1];
|
||||
$code = '$c = "'.str_replace('"', '\"', $ryzom_render_tmpls[$tag]).'";';
|
||||
eval($code);
|
||||
return $c;
|
||||
}
|
||||
|
||||
function ryzom_get_color_style($tag, $color=0) {
|
||||
global $ryzom_render_styles;
|
||||
if (!array_key_exists($tag, $ryzom_render_styles))
|
||||
return '000000';
|
||||
return $ryzom_render_styles[$tag][$color];
|
||||
}
|
||||
|
||||
function ryzom_set_title($title) {
|
||||
$GLOBALS['ryzom_render_title'] = $title;
|
||||
}
|
||||
|
||||
function ryzom_get_title() {
|
||||
return $GLOBALS['ryzom_render_title'];
|
||||
}
|
||||
|
||||
function ryzom_font($text, $color="", $size="") {
|
||||
if (RYZOM_IG) {
|
||||
$color = $color?'color="'.$color.'"':'';
|
||||
$size = $size?'size="'.$size.'"':'';
|
||||
} else {
|
||||
$color = $color?'color:'.$color.';':'';
|
||||
$size = $size?'font-size:'.$size.'pt':'';
|
||||
}
|
||||
return (RYZOM_IG?"<font $color $size>":"<font style=\"$color $size\">").$text.'</font>';
|
||||
}
|
||||
|
||||
function ryzom_render_login_form($char, $aligned=true, $action="") {
|
||||
$c = '';
|
||||
if ($aligned) {
|
||||
$c .= '<form action="" method="post"><table>';
|
||||
$c .= '<form action="'.$action.'" method="post"><table>';
|
||||
$c .= '<tr><td>'._t('enter_char').'</td></tr>';
|
||||
$c .= '<tr><td><input style="width: 200px" type="text" name="char" value="'.$char.'"/></td></tr>';
|
||||
$c .= '<tr><td><input cols="80" style="width: 200px" type="text" name="char" value="'.$char.'"/></td></tr>';
|
||||
$c .= '<tr><td>'._t('enter_password').'</td></tr>';
|
||||
if (RYZOM_IG)
|
||||
$c .= '<tr><td><input cols="80" style="width: 200px" type="text" name="password" /></td></tr>';
|
||||
else
|
||||
$c .= '<tr><td><input style="width: 200px" type="password" name="password" /></td></tr>';
|
||||
$c .= '<tr><td><input type="submit" value="'._t('submit').'" /></td></tr>';
|
||||
} else {
|
||||
$c .= '<form action="" method="post"><table width="100%">';
|
||||
$c .= '<form action="'.$action.'" method="post"><table width="100%">';
|
||||
$c .= '<tr><td align="center">'._t('login').'</td></tr>';
|
||||
$c .= '<tr><td align="center"><input style="width: 200px" type="text" name="char" value="'.$char.'"/></td></tr>';
|
||||
$c .= '<tr><td align="center"><input cols="80" style="width: 200px" type="text" name="char" value="'.$char.'"/></td></tr>';
|
||||
$c .= '<tr><td align="center">'._t('password').'</td></tr>';
|
||||
if (RYZOM_IG)
|
||||
$c .= '<tr><td align="center"><input cols="80" style="width: 200px" type="text" name="password" /></td></tr>';
|
||||
else
|
||||
$c .= '<tr><td align="center"><input style="width: 200px" type="password" name="password" /></td></tr>';
|
||||
$c .= '<tr><td align="center"><input type="submit" value="'._t('submit').'" /></td></tr>';
|
||||
}
|
||||
|
@ -212,4 +287,92 @@ function ryzom_render_login_form($char, $aligned=true) {
|
|||
return $c;
|
||||
}
|
||||
|
||||
function ryzom_dialog_yes_no($desc, $action, $name) { // will append ryzom_dialog=yes|no to url
|
||||
|
||||
return '<table width="100%"><tr bgcolor="#333333"><td height="35px" align="center" valign="middle">'.(RYZOM_IG?'<font color="#DDAA33" size="11">':'<font style="color:#DDAA33; font-size:11pt">').
|
||||
$desc.'<form action="'.$action.'" method="POST">
|
||||
<table width="100%">
|
||||
<tr><td align="center"><select name="'.$name.'"><option value="no">'._t('no').'</option><option value="yes">'._t('yes').'</option></select></td></tr>
|
||||
<tr><td align="center"><input type="submit" value="'._t('submit').'"/></td></tr>
|
||||
</table>
|
||||
</form></font></td></tr></table>';
|
||||
}
|
||||
|
||||
$GLOBALS['ryzom_render_title'] = defined('APP_NAME')?APP_NAME:'Ryzom';
|
||||
|
||||
$ig = (isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], 'Ryzom')) || ryzom_get_param('ig'); // need be set using url param because auth is not done
|
||||
$transparency = $ig?'':'';
|
||||
$ryzom_render_styles = array();
|
||||
$ryzom_render_tmpls = array();
|
||||
|
||||
$ryzom_render_styles['main title'] = array('#222222'.$transparency, '#FFFFFF');
|
||||
$ryzom_render_tmpls['main title'] = '<table width="100%" cellpadding="0" cellspacing="0"><tr bgcolor="${p[\'color1\']}"><td height="42px" valign="middle"><font '.($ig?'color="${p[\'color2\']}" size="14"':'style="color:${p[\'color2\']};font-size:16pt; font-weight: bold"').'> ${p[0]}</font></td></tr></table>'."\n";
|
||||
|
||||
$ryzom_render_styles['section'] = array('#555555'.$transparency, '#FFFFFF');
|
||||
$ryzom_render_tmpls['section'] = '<table width="100%" cellpadding="0" cellspacing="0"><tr bgcolor="${p[\'color1\']}"><td height="40px" align="left" valign="middle"><font '.($ig?'color="${p[\'color2\']}" size="12"':'style="color:${p[\'color2\']}; font-size:10pt; font-weight: bold"').'> ${p[0]}</font></td></tr></table>'."\n";
|
||||
|
||||
$ryzom_render_styles['color'] = array('', '');
|
||||
$ryzom_render_tmpls['color'] = ($ig?'<font color="${p[0]}">':'<font style="color:${p[0]}">').'${p[0]}</font>';
|
||||
|
||||
$ryzom_render_styles['link'] = array('#111111', '');
|
||||
$ryzom_render_tmpls['link'] = '<table width="100%" cellpadding="0" cellspacing="0"><tr bgcolor="${p[\'color1\']}" ><td height="24px" valign="middle"> ${p[0]}</td></tr></table>'."\n";
|
||||
|
||||
$ryzom_render_styles['button'] = array('#000000', '');
|
||||
$ryzom_render_tmpls['button'] = '<table cellpadding="5" cellspacing="0"><tr bgcolor="${p[\'color1\']}" ><td height="20px" align="center" valign="middle"> ${p[0]}</td></tr></table>'."\n";
|
||||
|
||||
$ryzom_render_styles['links'] = array('#111111'.$transparency, '');
|
||||
$ryzom_render_tmpls['links'] = '<table width="100%" cellpadding="0" cellspacing="0"><tr bgcolor="${p[\'color1\']}"><td height="28px" valign="middle"> ${p[0]}</td></tr></table>'."\n";
|
||||
|
||||
$ryzom_render_styles['back'] = array('#000000'.$transparency, '');
|
||||
$ryzom_render_tmpls['back'] = '<table cellpadding="0" cellspacing="0" width="100%"><tr valign="middle" bgcolor="${p[\'color1\']}"><td align="left" height="25px" nowrap> <b><a href="${p[0]}">«'.'main'.'</a></b></td></tr><tr><td> </td></tr></table>';
|
||||
|
||||
$ryzom_render_styles['highlight'] = array('#55ff55'.$transparency, '');
|
||||
$ryzom_render_tmpls['highlight'] = '<font color="${p[\'color1\']}">${p[0]}</font>';
|
||||
|
||||
$ryzom_render_styles['backlight'] = array('#272727'.$transparency, '');
|
||||
$ryzom_render_tmpls['backlight'] = '<table width="100%"><tr bgcolor="${p[\'color1\']}"><td height="35px" valign="middle">${p[0]}</td></tr></table>'."\n";
|
||||
|
||||
$ryzom_render_styles['actionbar'] = array('#555555'.$transparency, '');
|
||||
$ryzom_render_tmpls['actionbar'] = '<tr bgcolor="${p[\'color1\']}" valign="middle">${p[0]}</tr>'."\n";
|
||||
|
||||
$ryzom_render_styles['table'] = array('#050505'.$transparency, '#FFFFFF');
|
||||
$ryzom_render_tmpls['table'] = '<table width="100%" cellpadding="0" cellspacing="0">${p[0]}</table>'."\n";
|
||||
|
||||
$ryzom_render_styles['t header'] = array('#111111'.$transparency, '#FFFFFF');
|
||||
$ryzom_render_tmpls['t header'] = '<tr style="color: #FFFFFF" bgcolor="${p[\'color1\']}" valign="middle">${p[0]}</tr>'."\n";
|
||||
|
||||
$ryzom_render_styles['t row 0'] = array('#353535'.$transparency, '');
|
||||
$ryzom_render_tmpls['t row 0'] = '<tr bgcolor="${p[\'color1\']}" valign="middle">${p[0]}</tr>'."\n";
|
||||
|
||||
$ryzom_render_styles['t row 1'] = array('#252525'.$transparency, '');
|
||||
$ryzom_render_tmpls['t row 1'] = '<tr bgcolor="${p[\'color1\']}" valign="middle">${p[0]}</tr>'."\n";
|
||||
|
||||
$ryzom_render_styles['t element'] = array('#FFFFFF'.$transparency, '');
|
||||
$ryzom_render_tmpls['t element'] = '<font color="${p[\'color1\']}">${p[0]}</font>';
|
||||
|
||||
$ryzom_render_styles['log'] = array('#001100'.$transparency, '');
|
||||
$ryzom_render_tmpls['log'] = '<div style="background-color: ${p[\'color1\']}"><pre style="width: auto">${p[0]}</pre></div>'."\n";
|
||||
|
||||
$ryzom_render_styles['message'] = array('#445566'.$transparency, '#FFDDAA');
|
||||
$ryzom_render_tmpls['message'] = '<table width="100%" cellspacing="0" cellpadding="0"><tr bgcolor="${p[\'color1\']}"><td height="5px"></td></tr><tr bgcolor="${p[\'color1\']}"><td align="center" valign="middle"><font '.($ig?'color="${p[\'color2\']}" size="16"':'style="color:${p[\'color2\']};font-size:12pt; font-weight: bold"').'>${p[0]}</font></td></tr><tr bgcolor="${p[\'color1\']}"><td height="5px"></td></tr></table>'."\n";
|
||||
|
||||
$ryzom_render_styles['message warning'] = array('#AA3300'.$transparency, '');
|
||||
$ryzom_render_tmpls['message warning'] = '<table width="100%"><tr bgcolor="${p[\'color1\']}"><td align="center" valign="middle"><h3> ${p[0]}</h3></td></tr></table>'."\n";
|
||||
|
||||
$ryzom_render_styles['message window'] = array('#5555ff'.$transparency, '#7799ff');
|
||||
$ryzom_render_tmpls['message window'] = '<table width="100%" cellspacing="0" cellpadding="0"><tr><td bgcolor="${p[\'color2\']}" width="3px"></td><td height="3px" bgcolor="${p[\'color2\']}"></td><td bgcolor="${p[\'color2\']}"></td><td bgcolor="${p[\'color2\']}" width="3px"></td></tr>'.'<tr><td bgcolor="${p[\'color2\']}" width="3px"></td><td bgcolor="${p[\'color1\']}" align="center" valign="middle">${p[0]}</td><td bgcolor="${p[\'color1\']}" valign="top" align="right">${p[0]}</td><td width="3px" bgcolor="${p[\'color2\']}"></td>'.
|
||||
'<tr bgcolor="${p[\'color1\']}"><td bgcolor="${p[\'color2\']}" width="3px"></td><td height="3px" bgcolor="${p[\'color2\']}"></td><td bgcolor="${p[\'color2\']}" width="3px"></td><td bgcolor="${p[\'color2\']}"></td></tr></table>'."\n";
|
||||
|
||||
$ryzom_render_styles['message ask'] = array('#333333'.$transparency, '');
|
||||
$ryzom_render_tmpls['message ask'] = '<table width="100%"><tr bgcolor="${p[\'color1\']}"><td valign="middle">'.($ig?'<font color="#DDAA33" size="11">':'<font style="color:#DDAA33; font-size:11pt">').'${p[0]}</font></td></tr></table>'."\n";
|
||||
|
||||
$ryzom_render_styles['message error'] = array('#AA2222'.$transparency, '');
|
||||
$ryzom_render_tmpls['message error'] = '<table width="100%"><tr bgcolor="${p[\'color1\']}"><td height="30px" align="center" valign="middle"><h3> ${p[0]}</h3></td></tr></table>'."\n";
|
||||
|
||||
$ryzom_render_styles['message debug'] = array('#FFAA22'.$transparency, '');
|
||||
$ryzom_render_tmpls['message debug'] = '<table width="100%"><tr bgcolor="${p[\'color1\']}"><td height="30px" valign="middle"><font color="#000">${p[0]}</font></td></tr></table>'."\n";
|
||||
|
||||
$ryzom_render_styles['progress bar'] = array('#FF0000'.$transparency, '#000000');
|
||||
$ryzom_render_tmpls['progress bar'] = '<table width="100%"><tr><td bgcolor="${p[\'color1\']}" height="30px" width="${p[0]}%" align="center" valign="middle"> </td>${p[0]}<td bgcolor="${p[\'color2\']}" height="30px" valign="middle" align="center">${p[0]} </td></tr></table>'."\n";
|
||||
|
||||
?>
|
||||
|
|
680
code/web/api/common/ryform.php
Normal file
|
@ -0,0 +1,680 @@
|
|||
<?php
|
||||
|
||||
/* Copyright (C) 2009 Winch Gate Property Limited
|
||||
*
|
||||
* This file is part of ryzom_api.
|
||||
* ryzom_api is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ryzom_api is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with ryzom_api. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
include_once (RYAPI_PATH.'/common/ryformBases.php');
|
||||
|
||||
class ryVar extends basicRyForm {
|
||||
public $formName = '';
|
||||
public $varName = '';
|
||||
public $varValue = '';
|
||||
|
||||
function getFormDefs() {
|
||||
return array(
|
||||
new ryFormDef('varName', DEF_TYPE_TEXT),
|
||||
new ryFormDef('varValue', DEF_TYPE_TEXT),
|
||||
);
|
||||
}
|
||||
|
||||
function getHtmlRepr() {
|
||||
return $this->varName.' => '.$this->varValue;
|
||||
}
|
||||
}
|
||||
|
||||
class ryForm {
|
||||
|
||||
private $name = '';
|
||||
private $defines = array();
|
||||
private $template = '';
|
||||
|
||||
static private $forms;
|
||||
static private $ryformsIcons = array();
|
||||
|
||||
function __construct($dir, $name) {
|
||||
$this->name = $name;
|
||||
self::$forms[$dir.'/'.$name] = $this;
|
||||
}
|
||||
|
||||
static function addRyFormIcon($ryform_name, $icon) {
|
||||
self::$ryformsIcons[$ryform_name] = $icon;
|
||||
}
|
||||
|
||||
function addDefine($def) {
|
||||
$this->defines[$def->name] = $def;
|
||||
}
|
||||
|
||||
function setTemplate($template) {
|
||||
$this->template = $template;
|
||||
}
|
||||
|
||||
function getTemplate() {
|
||||
return $this->template;
|
||||
}
|
||||
|
||||
function addValue($name, $value) {
|
||||
if (array_key_exists($name, $this->defines))
|
||||
$this->defines[$name]->value = $value;
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function addExtraValues($name, $value) {
|
||||
if (array_key_exists($name, $this->defines))
|
||||
$this->defines[$name]->extraValues = $value;
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function getForm($params) {
|
||||
|
||||
if (isset($params['ryform_action']) && $params['ryform_action']) {
|
||||
$res = $this->doAction($params);
|
||||
return $res;
|
||||
}
|
||||
|
||||
if (@$params['validate'] == $this->name)
|
||||
return array(DATA_FORM_VALUES, $_POST);
|
||||
|
||||
if (isset($params['ryform_parent']))
|
||||
$parent_ryform_name = $params['ryform_parent'].'/';
|
||||
else
|
||||
$parent_ryform_name = '';
|
||||
|
||||
$action =_url(ryzom_get_params(), array('validate' => $this->name));
|
||||
$ret = '';
|
||||
$ret .= '<form action="'.$action.'" method="POST">'."\n";
|
||||
|
||||
if (!$this->getTemplate()) {
|
||||
$ret .= ' <table width="100%" cellpadding="0" cellspacing="0">'."\n";
|
||||
$ret .= ' '._s('t header', '<td height="24px">'._t('parameter').'</td><td>'._t('value').'</td><td></td>')."\n";
|
||||
$tmpl = '';
|
||||
} else {
|
||||
$tmpl = $this->getTemplate();
|
||||
}
|
||||
|
||||
$i = 0;
|
||||
|
||||
foreach ($this->defines as $def_id => $def) {
|
||||
if ($def->name == 'name')
|
||||
$def->name = '_name';
|
||||
|
||||
$deffullname = $def->name;
|
||||
$url_params = ryzom_get_params();
|
||||
$type = $def->type;
|
||||
$infos = $def->infos;
|
||||
$value = ($def->value !== NULL)?$def->value:$def->defaultValue;
|
||||
|
||||
if (!is_object($value) && !is_array($value))
|
||||
$str_value = _h(strval($value));
|
||||
else
|
||||
$str_value = '';
|
||||
|
||||
if ($def->hidden)
|
||||
$type = DEF_TYPE_HIDDEN;
|
||||
|
||||
$hidden = false;
|
||||
$input = '';
|
||||
switch ($type) {
|
||||
|
||||
case DEF_TYPE_HIDDEN:
|
||||
$input = '<input type="hidden" name="'.$def->name.'" value="'.$str_value.'" />'."\n";
|
||||
$hidden = true;
|
||||
break;
|
||||
|
||||
case DEF_TYPE_TEXT:
|
||||
$input = '<input style="width:250px" type="text" name="'.$def->name.'" value="'.$str_value.'" size="25'.(_user()->ig?'0':'').'" />';
|
||||
break;
|
||||
case DEF_TYPE_NAMEID:
|
||||
$input = '<input style="width:250px" type="text" name="'.$def->name.'" value="'.getNameId($str_value).'" size="25'.(_user()->ig?'0':'').'" />';
|
||||
break;
|
||||
|
||||
case DEF_TYPE_ID:
|
||||
case DEF_TYPE_INT:
|
||||
case DEF_TYPE_FLOAT:
|
||||
$input = '<input style="width:100px" type="text" name="'.$def->name.'" value="'.$str_value.'" size="10'.(_user()->ig?'0':'').'" />';
|
||||
break;
|
||||
|
||||
case DEF_TYPE_BOOL:
|
||||
$input = '<select name="'.$def->name.'">'."\n";
|
||||
if ($value)
|
||||
$input .= '<option selected="selected" value="on">'._t('yes').'</option>'."\n".'<option value="off">'._t('no').'</option>';
|
||||
else
|
||||
$input .= '<option value="on">'._t('yes').'</option>'."\n".'<option selected="selected" value="off">'._t('no').'</option>';
|
||||
$input .= '</select>';
|
||||
break;
|
||||
|
||||
case DEF_TYPE_OPTION_FUNCTION:
|
||||
case DEF_TYPE_OPTION:
|
||||
if ($type == DEF_TYPE_OPTION)
|
||||
$options = $def->params;
|
||||
else {
|
||||
if (is_array($def->defaultValue))
|
||||
$options = call_user_func_array($def->params, $def->defaultValue);
|
||||
else
|
||||
$options = call_user_func($def->params);
|
||||
}
|
||||
$input = '<select name="'.$def->name.'">'."\n";
|
||||
$options_html = '';
|
||||
foreach ($options as $option => $text) {
|
||||
$option = strval($option);
|
||||
if ($option && $option[0] === '<' && $option[1] === '/')
|
||||
$options_html .= '</optgroup>';
|
||||
else if ($option && $option[0] === '<')
|
||||
$options_html .= '<optgroup label="'.$text.'">';
|
||||
else {
|
||||
if ($value !== NULL and (strval($value) == $option))
|
||||
$options_html .= '<option selected="selected" value="'.$option.'">'.$text.'</option>'."\n";
|
||||
else
|
||||
$options_html .= '<option value="'.$option.'">'.$text.'</option>'."\n";
|
||||
}
|
||||
}
|
||||
$input .= $options_html;
|
||||
$input .= '</select>';
|
||||
break;
|
||||
|
||||
case DEF_TYPE_COMBO_FUNCTION:
|
||||
case DEF_TYPE_COMBO:
|
||||
if ($type == DEF_TYPE_COMBO)
|
||||
$options = $def->params;
|
||||
else {
|
||||
if (is_array($def->defaultValue))
|
||||
$options = call_user_func_array($def->params, $def->defaultValue);
|
||||
else
|
||||
$options = call_user_func($def->params);
|
||||
}
|
||||
if (_user()->ig) {
|
||||
// TODO : try to do it with lua
|
||||
} else { // HTML 4
|
||||
$input .= '<input style="width:400px" type="text" id="'.$def->name.'" name="'.$def->name.'" value="'.$str_value.'" />
|
||||
<select onChange="combo(this, \''.$def->name.'\')" onMouseOut="comboInit(this, \''.$def->name.'\')" >';
|
||||
$options_html = '';
|
||||
$have_selected = false;
|
||||
foreach ($options as $option => $text) {
|
||||
if ($option && $option[0] === '<' && $option[1] === '/')
|
||||
$options_html .= '</optgroup>';
|
||||
else if ($option && $option[0] === '<')
|
||||
$options_html .= '<optgroup label="'.$text.'">';
|
||||
else {
|
||||
|
||||
if ($value and ($value == $option)) {
|
||||
$have_selected = true;
|
||||
$options_html .= '<option selected="selected" value="'.$option.'">'.$text.'</option>'."\n";
|
||||
} else
|
||||
$options_html .= '<option value="'.$option.'">'.$text.'</option>'."\n";
|
||||
}
|
||||
}
|
||||
if ($have_selected)
|
||||
$input .= '<option value=""></option>';
|
||||
else
|
||||
$input .= '<option selected="selected" value=""></option>';
|
||||
$input .= $options_html;
|
||||
$input .= '</select>';
|
||||
}
|
||||
break;
|
||||
|
||||
case DEF_TYPE_TEXTAREA:
|
||||
if (!$value)
|
||||
$value = "";
|
||||
$input = '<pre>'.($type == DEF_TYPE_BBCODE?'<font color="orange">- BBCode -</font><br />':'').'<textarea name="'.$def->name.'" rows="3">'._h($value).'</textarea></pre>';
|
||||
break;
|
||||
|
||||
case DEF_TYPE_TRAD:
|
||||
$base = '';
|
||||
$param = $def->name;
|
||||
$value = array_merge(array('en' => '', 'fr' => '', 'de' => '', 'ru' => '', 'es' => ''), $value);
|
||||
$base = ryzom_get_param('select_base', '');
|
||||
$edit = $display = $input_header = '';
|
||||
foreach (array('en', 'fr', 'de', 'ru', 'es') as $lang) {
|
||||
if (_user()->lang == $lang)
|
||||
$edit = _i($lang == 'en'?API_URL.'data/img/lang/us.png':API_URL.'data/img/lang/'.$lang.'.png').' <textarea style="width: 90%" rows="3" name="'.$param.'['.$lang.']">'._h($value[$lang]).'</textarea>';
|
||||
if ((!$base && $value[$lang]) || $base == $lang) {
|
||||
$base = $lang;
|
||||
$display = strtoupper($lang).' = <font color="orange">'.str_replace("\n", '<br />', _h($value[$lang])).'</font>';
|
||||
}
|
||||
$input .= '<input type="hidden" name="'.$param.'['.$lang.']" value="'.$value[$lang].'" />';
|
||||
$input_header .= _l(_i($lang == 'en'?API_URL.'data/img/lang/us.png':API_URL.'data/img/lang/'.$lang.'.png'), $url_params, array('select_base' => $lang)).' ';
|
||||
}
|
||||
|
||||
$input = $input_header.$input.' '.$display.'<br />'.$edit;
|
||||
break;
|
||||
|
||||
case DEF_TYPE_RYFORM:
|
||||
case DEF_TYPE_RYFORMS_ARRAY:
|
||||
$savedRyform = $value;
|
||||
if (is_array($savedRyform)) {
|
||||
$to_clean = array();
|
||||
foreach ($savedRyform as $id => $ryform) {
|
||||
if (!is_object($ryform))
|
||||
$to_clean[] = $id;
|
||||
}
|
||||
foreach ($to_clean as $id)
|
||||
unset($savedRyform[$id]);
|
||||
$savedRyform = array_values($savedRyform);
|
||||
} else if (is_object($savedRyform)) {
|
||||
$savedRyform = array($savedRyform);
|
||||
} else
|
||||
$savedRyform = array();
|
||||
|
||||
$input .= '<table width="100%" cellspacing="0" cellpadding="0" >';
|
||||
if ($savedRyform) {
|
||||
foreach ($savedRyform as $id => $ryform) {
|
||||
if (!is_object($ryform)) {
|
||||
p('!!! ERROR !!!', $ryform);
|
||||
continue;
|
||||
}
|
||||
$ryform->id = $id+1;
|
||||
if (!isset($ryform->formName) || !$ryform->formName)
|
||||
$ryform->formName = 'Element '.$id;
|
||||
if (count($savedRyform) > 1)
|
||||
$display_id = '<font size="12px" style="font-weight: bold; font-size: 14px" color="#FFAA55">'.strval(intval($id)+1).'</font>';
|
||||
else
|
||||
$display_id = '';
|
||||
|
||||
$script_up = ($id != 0)?_l(_i('16/arrow_up', _t('up')), $url_params, array('ryform_name' => $parent_ryform_name.$deffullname.':'.$id, 'ryform_action' => 'up')).' ':'';
|
||||
$script_down = ($id != count($savedRyform)-1)?_l(_i('16/arrow_down', _t('down')), $url_params, array('ryform_name' => $parent_ryform_name.$deffullname.':'.$id, 'ryform_action' => 'down')).' ':'';
|
||||
|
||||
$icon = (isset(self::$ryformsIcons[get_class($ryform)]))?self::$ryformsIcons[get_class($ryform)]:_i('32/brick');
|
||||
$input .= _s('t row '.($id%2),
|
||||
'<td width="36px">'._l(($def->type == DEF_TYPE_RYFORM?_i('16/arrow_redo', _t('change')):_i('16/add', _t('add'))), $url_params, array('ryform_name' => $parent_ryform_name.$deffullname.':'.strval(intval($id)+1), 'ryform_action' => 'list')).' '.$display_id.'</td>'.
|
||||
'<td width="10px">'.$script_up.$script_down.'</td>'.
|
||||
'<td ><table width="100%"><tr>
|
||||
<td width="40px">'.$icon.'</td>
|
||||
<td valign="middle" width="300px"><font size="12px" style="font-size: 13px;font-weight: bold;" color="#FFAA55">'.
|
||||
_l($ryform->formName, $url_params, array('ryform_name' => $parent_ryform_name.$deffullname.':'.$id, 'ryform_action' => 'edit')).' '.
|
||||
'</font><br />'._t(get_class($ryform).'_short_description').'</td>
|
||||
<td align="left" valign="middle" bgcolor="#000000">'.$ryform->getHtmlRepr().'</td>
|
||||
</tr></table><td width="70px" align="right">'.
|
||||
_l(_i('16/script_edit', _t('edit')), $url_params, array('ryform_name' => $parent_ryform_name.$deffullname.':'.$id, 'ryform_action' => 'edit')).' '.
|
||||
_l(_i('16/script_code', _t('edit_source')), $url_params, array('ryform_name' => $parent_ryform_name.$deffullname.':'.$id, 'ryform_action' => 'source')).' '.
|
||||
_l(_i('16/script_delete', _t('del')), $url_params, array('ryform_name' => $parent_ryform_name.$deffullname.':'.$id, 'ryform_action' => 'del')).'</td><td> </td>');
|
||||
}
|
||||
}
|
||||
$input .= '</table>';
|
||||
if (count($savedRyform) == 0 || $def->type != DEF_TYPE_RYFORM) {
|
||||
if (is_string($def->params))
|
||||
$infos = _l(_i('16/add', _t('add')), $url_params, array('new_ryform' => $def->params, 'ryform_name' => $parent_ryform_name.$deffullname.':0', 'ryform_action' => 'add'));
|
||||
else if (count($def->params) == 1)
|
||||
$infos = _l(_i('16/add', _t('add')), $url_params, array('new_ryform' => $def->params[0], 'ryform_name' => $parent_ryform_name.$deffullname.':0', 'ryform_action' => 'add'));
|
||||
else
|
||||
|
||||
$infos = _l(_i('16/add', _t('add')), $url_params, array('ryform_name' => $parent_ryform_name.$deffullname.':0', 'ryform_action' => 'list'));
|
||||
|
||||
if ($type == DEF_TYPE_RYFORMS_ARRAY)
|
||||
$infos .= ' '._l(_i('16/application_form_add', _t('multiadd')), $url_params, array('ryform_name' => $deffullname, 'ryform_action' => 'list_multiadd'));
|
||||
}
|
||||
break;
|
||||
|
||||
case DEF_TYPE_FUNCTION:
|
||||
if (is_array($def->defaultValue))
|
||||
list($result_type, $value) = call_user_func_array($def->params, $def->defaultValue);
|
||||
else
|
||||
list($result_type, $value) = call_user_func($def->params);
|
||||
if ($result_type == DATA_HTML_FORM) {
|
||||
return array(DATA_HTML_FORM, $value);
|
||||
} else {
|
||||
unset($url_params[$deffullname.'_action']);
|
||||
$input = $value;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$input = '<input type="hidden" name="'.$def->name.'" value="'.$value.'" />'.$value."\n";
|
||||
$hidden = true;
|
||||
|
||||
}
|
||||
|
||||
if ($hidden)
|
||||
$ret .= $input;
|
||||
else
|
||||
{
|
||||
if ($tmpl) {
|
||||
$tmpl = str_replace('{'.$def->name.'}', '<font '.(_user()->ig?'color="orange" size="11"':'style="color:orange;"').'>'._t($def->prefixTrad.$def->name).'</font>', $tmpl);
|
||||
$tmpl = str_replace('{'.$def->name.'.input}', $input, $tmpl);
|
||||
$tmpl = str_replace('{'.$def->name.'.infos}', $infos, $tmpl);
|
||||
} else
|
||||
$ret .= _s('t row '.strval($i % 2), '<td height="32px" width="200px"> '.(!$def->optional?'*':'').($def->superAdmin?'##':'').($def->admin?'#':'')._t($def->prefixTrad.$def->name).'</td><td valign="center">'.$input.'</td><td>'.$infos.'</td>')."\n";
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($tmpl) {
|
||||
$tmpl = str_replace('{submit.input}', '<input type="submit" value="'._t('submit').'" />', $tmpl);
|
||||
$ret .= $tmpl;
|
||||
$ret .= '<table width="100%" cellspacing="0" cellpadding="0" ><tr>'._s('t row '.strval($i % 2), '<td height="32px"> '._t('required_fields').'</td><td></td><td align="middle"><input type="submit" value="'._t('submit').'" /></td>').'</tr></table>';
|
||||
} else {
|
||||
$ret .= _s('t row '.strval($i % 2), '<td height="32px"> '._t('required_fields').'</td><td></td><td><input type="submit" value="'._t('submit').'" /></td>');
|
||||
$ret .= '</table>';
|
||||
}
|
||||
$ret .= '</form><br />';
|
||||
return array(DATA_HTML_FORM, $ret."\n");
|
||||
}
|
||||
|
||||
|
||||
function doAction($url_params) {
|
||||
if (!$url_params['ryform_name'])
|
||||
return array(DATA_RYFORM_VALUE, array());
|
||||
$ret = '';
|
||||
$ryforms = explode('/', $url_params['ryform_name']);
|
||||
$this_ryform_name = array_shift($ryforms);
|
||||
list($ryform_name,$ryform_pos) = explode(':', $this_ryform_name);
|
||||
if (!isset($this->defines[$ryform_name]))
|
||||
return 'Bad ryform name';
|
||||
$def = $this->defines[$ryform_name];
|
||||
|
||||
if ($ryforms) {
|
||||
$action = 'edit';
|
||||
$next_action = $url_params['ryform_action'];
|
||||
} else {
|
||||
$action = $url_params['ryform_action'];
|
||||
$next_action = '';
|
||||
}
|
||||
|
||||
switch ($action) {
|
||||
case 'list':
|
||||
if (isset($url_params['ryform_parent']) && $url_params['ryform_parent'])
|
||||
$ryform_parent = $url_params['ryform_parent'].'/';
|
||||
else
|
||||
$ryform_parent = '';
|
||||
$ret .= '<table cellpadding="0" cellspacing="0" width="100%">';
|
||||
foreach ($def->params as $id => $ryform) {
|
||||
if (is_array($ryform)) {
|
||||
$ret .= _s('t row 1', '<td height="28px" width="22px" bgcolor='.ryzom_get_color_style('section').'></td><td bgcolor='.ryzom_get_color_style('section').'>'.ryzom_font(_t('ryform_cat_'.$id), '', '12').'</td><td bgcolor='.ryzom_get_color_style('section').'></td>');
|
||||
foreach ($ryform as $subid => $subryform) {
|
||||
$ret .= _s('t row '.($subid%2), '<td width="22px" height="34px">'.self::$ryformsIcons[$subryform].'</td><td> '.
|
||||
_l(_t($subryform.'_short_description'), $url_params, array('ryform_name' => $ryform_parent.$url_params['ryform_name'], 'ryform_action' => 'add', 'new_ryform' => $subryform)).'</td><td>'.$subryform.'</td>');
|
||||
}
|
||||
} else
|
||||
$ret .= _s('t row '.($id%2), '<td width="22px" height="34px">'.self::$ryformsIcons[$ryform].'</td><td> '.
|
||||
_l(_t($ryform.'_short_description'), $url_params, array('ryform_name' => $ryform_parent.$url_params['ryform_name'], 'ryform_action' => 'add', 'new_ryform' => $ryform)).'</td><td>'.$ryform.'</td>');
|
||||
}
|
||||
$ret .= '</table>';
|
||||
return array(DATA_HTML_FORM, $ret);
|
||||
break;
|
||||
|
||||
case 'list_multiadd':
|
||||
// TODO
|
||||
/*
|
||||
unset($url_params[$deffullname.'_action']);
|
||||
$ret .= '<table cellpadding="5"><tr>';
|
||||
foreach ($def->params as $ryform) {
|
||||
$ret .= '<td bgcolor="#000000">'._l($ryform, $url_params, array('ryform_action' => 'multiadd', 'new_ryform' => $ryform)).'</td>';
|
||||
}
|
||||
$ret .= '</tr></table>';
|
||||
return array(DATA_HTML_FORM, $ret);*/
|
||||
break;
|
||||
|
||||
case 'add':
|
||||
$new_ryform = ryzom_get_param('new_ryform');
|
||||
$valid_ryform = false;
|
||||
if ($new_ryform) {
|
||||
|
||||
if ((is_string($def->params) && $new_ryform == $def->params) || in_array($new_ryform, $def->params))
|
||||
$valid_ryform = true;
|
||||
else {
|
||||
foreach ($def->params as $param) {
|
||||
if (is_array($param) && in_array($new_ryform, $param))
|
||||
$valid_ryform = true;
|
||||
}
|
||||
}
|
||||
if (!$valid_ryform)
|
||||
return array(DATA_HTML_FORM, 'Bad ryform');
|
||||
|
||||
} else {
|
||||
$new_ryform = $def->params;
|
||||
}
|
||||
$ryform = new $new_ryform($new_ryform, '');
|
||||
$ryform->preSerialization();
|
||||
if ($def->type != DEF_TYPE_RYFORM) {
|
||||
p($def->value);
|
||||
if (!is_array($def->value))
|
||||
$savedRyform = array($def->value);
|
||||
else
|
||||
$savedRyform = $def->value;
|
||||
if ($ryform_pos === 0) {
|
||||
$value = array_values(array_merge(array($ryform), $savedRyform));
|
||||
} else if ($ryform_pos !== NULL) {
|
||||
$begin = array_slice($savedRyform, 0, $ryform_pos);
|
||||
$end = array_slice($savedRyform, $ryform_pos, count($savedRyform)-$ryform_pos);
|
||||
$value = array_values(array_merge($begin, array($ryform), $end));
|
||||
} else
|
||||
$value[] = $ryform;
|
||||
p($ryform_name, $value);
|
||||
//return array(DATA_RYFORM_VALUE, array('stages' => array()));
|
||||
return array(DATA_RYFORM_VALUE, array($ryform_name => $value));
|
||||
} else {
|
||||
p($ryform_name, $ryform);
|
||||
return array(DATA_RYFORM_VALUE, array($ryform_name => $ryform));
|
||||
}
|
||||
break;
|
||||
|
||||
case 'edit':
|
||||
$a_ryforms = $def->value;
|
||||
if (is_array($a_ryforms))
|
||||
$ryform = $a_ryforms[$ryform_pos];
|
||||
else
|
||||
$ryform = $a_ryforms;
|
||||
$ryform->postSerialization();
|
||||
$validate = isset($url_params['validate']) && $url_params['validate'];
|
||||
|
||||
$form = new ryForm('', $def->name);
|
||||
foreach ($ryform->getFormDefs() as $form_def) {
|
||||
$form->addDefine($form_def);
|
||||
$name = $form_def->name;
|
||||
// Init form with ryfom values
|
||||
if (property_exists($ryform, $name)) {
|
||||
$form->addValue($form_def->name, $ryform->$name);
|
||||
}
|
||||
}
|
||||
foreach ($ryform->getFormDefsExtraValues() as $def_name => $extra_values)
|
||||
$form->addExtraValues($def_name, $extra_values);
|
||||
$form->setTemplate($ryform->getTemplate());
|
||||
|
||||
list($result_type, $value) = $form->getForm(array('action' => $url_params['action'], 'script' => $url_params['script'], 'ryform_action' => $next_action, 'ryform_parent' => $this_ryform_name, 'ryform_name' => implode('/', $ryforms), 'validate' => $validate));
|
||||
if ($result_type == DATA_HTML_FORM) {
|
||||
return array(DATA_HTML_FORM, $value);
|
||||
} else {
|
||||
if ($result_type == DATA_FORM_VALUES)
|
||||
$value = $form->validateFormPost($value);
|
||||
$ryform->setFormParams($value);
|
||||
$ryform->preSerialization();
|
||||
|
||||
}
|
||||
if (is_array($a_ryforms))
|
||||
$a_ryforms[$ryform_pos] = $ryform;
|
||||
else
|
||||
$a_ryforms = $ryform;
|
||||
|
||||
$value = array($ryform_name => $a_ryforms);
|
||||
return array(DATA_RYFORM_VALUE, $value);
|
||||
break;
|
||||
|
||||
|
||||
case 'del':
|
||||
$id = $ryform_pos;
|
||||
p($def->value);
|
||||
if (!is_array($def->value))
|
||||
$def->value = array();
|
||||
else
|
||||
unset($def->value[$id]);
|
||||
$value = array_values($def->value);
|
||||
return array(DATA_RYFORM_VALUE, array($ryform_name => $value));
|
||||
break;
|
||||
|
||||
case 'up':
|
||||
$a_ryforms = $def->value;
|
||||
if (!is_array($a_ryforms))
|
||||
ryzom_redirect(_url($url_params, array('ryform_action' => '')));
|
||||
|
||||
$temp_ryform = $a_ryforms[$ryform_pos-1];
|
||||
$a_ryforms[$ryform_pos-1] = $a_ryforms[$ryform_pos];
|
||||
$a_ryforms[$ryform_pos] = $temp_ryform;
|
||||
$a_ryforms = array_values($a_ryforms);
|
||||
p($ryform_name, $a_ryforms);
|
||||
return array(DATA_RYFORM_VALUE, array($ryform_name => $a_ryforms));
|
||||
break;
|
||||
|
||||
case 'down':
|
||||
$a_ryforms = $def->value;
|
||||
if (!is_array($a_ryforms))
|
||||
ryzom_redirect(_url($url_params, array('ryform_action' => '')));
|
||||
|
||||
$temp_ryform = $a_ryforms[$ryform_pos+1];
|
||||
$a_ryforms[$ryform_pos+1] = $a_ryforms[$ryform_pos];
|
||||
$a_ryforms[$ryform_pos] = $temp_ryform;
|
||||
$a_ryforms = array_values($a_ryforms);
|
||||
return array(DATA_RYFORM_VALUE, array($ryform_name => $a_ryforms));
|
||||
break;
|
||||
|
||||
case 'source':
|
||||
$a_ryforms = $def->value;
|
||||
if (is_array($a_ryforms))
|
||||
$ryform = $a_ryforms[$ryform_pos];
|
||||
else
|
||||
$ryform = $a_ryforms;
|
||||
$ryform->postSerialization();
|
||||
|
||||
$form = new ryForm('', $def->name);
|
||||
$form->addDefine(new ryFormDef('ryform_source', DEF_TYPE_TEXTAREA, '', base64_encode(serialize($ryform))));
|
||||
$validate = isset($url_params['validate']) && $url_params['validate'];
|
||||
list($result_type, $value) = $form->getForm(array('ryform_action' => $next_action, 'ryform_parent' => $this_ryform_name, 'ryform_name' => implode('/', $ryforms), 'validate' => $validate));
|
||||
if ($result_type == DATA_HTML_FORM) {
|
||||
return array(DATA_HTML_FORM, $value);
|
||||
} else {
|
||||
if ($result_type == DATA_FORM_VALUES)
|
||||
$params = $form->validateFormPost($value);
|
||||
else
|
||||
$params = $value;
|
||||
$ryform = unserialize(base64_decode($params['ryform_source']));
|
||||
if (!is_object($ryform)) {
|
||||
unset($url_params['validate']);
|
||||
ryzom_redirect(_url($url_params, array('ryform_action' => '', 'message' => 'bad_paste')));
|
||||
}
|
||||
|
||||
$is_valid = false;
|
||||
p($def->params);
|
||||
foreach ($def->params as $id => $ryform_class) {
|
||||
if (is_array($ryform_class)) {
|
||||
if (in_array(get_class($ryform), array_values($ryform_class)))
|
||||
$is_valid = true;
|
||||
} else if (get_class($ryform) == $ryform_class)
|
||||
$is_valid = true;
|
||||
}
|
||||
if (!$is_valid) {
|
||||
p(get_class($ryform), $def->params);
|
||||
ryzom_redirect(_url($url_params, array($deffullname.'_action' => '', 'message' => 'not_valid_stage')));
|
||||
return;
|
||||
}
|
||||
if (is_array($a_ryforms))
|
||||
$a_ryforms[$ryform_pos] = $ryform;
|
||||
else
|
||||
$a_ryforms = $ryform;
|
||||
$value = array($ryform_name => $a_ryforms);
|
||||
return array(DATA_RYFORM_VALUE, $value);
|
||||
}
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function validateFormPost($params, $use_default=true) {
|
||||
$final = array();
|
||||
foreach ($this->defines as $def) {
|
||||
$name = $def->name;
|
||||
if ($def->name == 'name')
|
||||
$def->name = '_name';
|
||||
|
||||
$type = $def->type;
|
||||
if ($def->hidden)
|
||||
$type = DEF_TYPE_HIDDEN;
|
||||
|
||||
if (isset($params[$def->name])) {
|
||||
$value = $params[$def->name];
|
||||
} else if (!$use_default) {
|
||||
continue;
|
||||
} else {
|
||||
$value = '';
|
||||
}
|
||||
|
||||
|
||||
switch ($type) {
|
||||
|
||||
case DEF_TYPE_HIDDEN:
|
||||
case DEF_TYPE_TEXT:
|
||||
case DEF_TYPE_OPTION:
|
||||
case DEF_TYPE_TEXTAREA:
|
||||
$final[$name] = $value;
|
||||
break;
|
||||
|
||||
case DEF_TYPE_TRAD:
|
||||
if (!$value[_user()->lang] && $value['europeanunion'])
|
||||
$value[_user()->lang] = $value['europeanunion'];
|
||||
$final[$name] = $value;
|
||||
break;
|
||||
|
||||
case DEF_TYPE_NAMEID:
|
||||
$final[$name] = cleanNameID($value);
|
||||
break;
|
||||
|
||||
case DEF_TYPE_COMBO:
|
||||
$final[$name] = $value;
|
||||
break;
|
||||
|
||||
case DEF_TYPE_ID:
|
||||
case DEF_TYPE_INT: // TODO
|
||||
$final[$name] = intval($value);
|
||||
break;
|
||||
case DEF_TYPE_FLOAT: // TODO
|
||||
$final[$name] = floatval($value);
|
||||
break;
|
||||
|
||||
case DEF_TYPE_BOOL:
|
||||
$final[$name] = $value == 'on';
|
||||
break;
|
||||
|
||||
case DEF_TYPE_RYFORM:
|
||||
if (is_array($value))
|
||||
$final[$name] = $value[0];
|
||||
break;
|
||||
case DEF_TYPE_RYFORMS_ARRAY:
|
||||
break;
|
||||
|
||||
default:
|
||||
$final[$name] = $value;
|
||||
|
||||
}
|
||||
}
|
||||
return $final;
|
||||
}
|
||||
|
||||
/*
|
||||
function reset() {
|
||||
|
||||
// Clean all temp files
|
||||
$userDatas = _tools()->listAppDataFiles($this->dir);
|
||||
foreach ($userDatas as $userData) {
|
||||
if (substr($userData, 0, strlen($this->name)) == $this->name)
|
||||
_tools()->saveAppData($this->dir.'/'.$userData, NULL);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
?>
|
304
code/web/api/common/ryformBases.php
Normal file
|
@ -0,0 +1,304 @@
|
|||
<?php
|
||||
|
||||
/* Copyright (C) 2012 Winch Gate Property Limited
|
||||
*
|
||||
* This file is part of ryzom_api.
|
||||
* ryzom_api is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ryzom_api is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with ryzom_app. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define('DEF_TYPE_UNKNOWN', 0);
|
||||
define('DEF_TYPE_HIDDEN', 1);
|
||||
define('DEF_TYPE_TEXT', 2);
|
||||
define('DEF_TYPE_ID', 3);
|
||||
define('DEF_TYPE_INT', 4);
|
||||
define('DEF_TYPE_FLOAT', 5);
|
||||
define('DEF_TYPE_BOOL', 6);
|
||||
define('DEF_TYPE_OPTION', 7);
|
||||
define('DEF_TYPE_TEXTAREA', 8);
|
||||
define('DEF_TYPE_TRAD', 9);
|
||||
define('DEF_TYPE_FORM', 10);
|
||||
define('DEF_TYPE_ICON', 11);
|
||||
define('DEF_TYPE_RYFORM', 12);
|
||||
define('DEF_TYPE_RYFORMS_ARRAY', 13);
|
||||
define('DEF_TYPE_BBCODE', 14);
|
||||
define('DEF_TYPE_FUNCTION', 15);
|
||||
define('DEF_TYPE_COMBO', 16);
|
||||
define('DEF_TYPE_OPTION_FUNCTION', 17);
|
||||
define('DEF_TYPE_NAMEID', 18);
|
||||
define('DEF_TYPE_COMBO_FUNCTION', 19);
|
||||
define('DEF_TYPE_DATE', 20);
|
||||
|
||||
|
||||
define('DEF_TYPE_ICON_UNKNOWN', 0);
|
||||
define('DEF_TYPE_ICON_SHARED', 1);
|
||||
define('DEF_TYPE_ICON_RYZITEM', 2);
|
||||
define('DEF_TYPE_ICON_URL', 3);
|
||||
|
||||
define('DATA_HTML_FORM', 0);
|
||||
define('DATA_FORM_VALUES', 1);
|
||||
define('DATA_FORM_VALID_VALUES', 2);
|
||||
define('DATA_RYFORM_VALUE', 3);
|
||||
|
||||
function cleanFormName($name) {
|
||||
$final_name = '';
|
||||
for ($i=0; $i<strlen($name); $i++) {
|
||||
$c = substr($name, $i, 1);
|
||||
if ( ((ord(strtolower($c)) >= ord('a')) && (ord(strtolower($c)) <= ord('z'))) ||
|
||||
(in_array($c, array('-', '.', '_'))) ||
|
||||
(ord(strtolower($c)) >= ord('0')) && (ord(strtolower($c)) <= ord('9')) )
|
||||
$final_name .= $c;
|
||||
}
|
||||
return $final_name;
|
||||
}
|
||||
|
||||
function cleanNameID($name) {
|
||||
$final_name = '';
|
||||
for ($i=0; $i<strlen($name); $i++) {
|
||||
$c = substr($name, $i, 1);
|
||||
if ($c == ' ' || $c == '_')
|
||||
$final_name .= '_';
|
||||
else if ( ((ord(strtolower($c)) >= ord('a')) && (ord(strtolower($c)) <= ord('z'))) ||
|
||||
(ord($c) >= ord('0')) && (ord($c) <= ord('9')) )
|
||||
$final_name .= $c;
|
||||
}
|
||||
return $final_name;
|
||||
}
|
||||
|
||||
function getNameId($name) {
|
||||
return str_replace('_', ' ', $name);
|
||||
}
|
||||
|
||||
function getTrad($value) {
|
||||
if ($value[_user()->lang])
|
||||
$trad = $value[_user()->lang];
|
||||
foreach (array('en', 'fr', 'de', 'ru', 'es') as $lang) {
|
||||
if ($value[$lang]) {
|
||||
$trad = $value[$lang];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (substr($trad, 0, 2) == '//')
|
||||
$trad = strstr(str_replace("\r", '', $trad), "\n");
|
||||
return substr($trad, 1);
|
||||
}
|
||||
|
||||
function setRyformSource($object, $src, $indent=0, $protecteds=array()) {
|
||||
$c = '';
|
||||
$src = str_replace("\r", '', $src);
|
||||
$ssrc = explode("\n", $src);
|
||||
$mode = 'var';
|
||||
$cache = '';
|
||||
$current_ryform = NULL;
|
||||
foreach ($ssrc as $line) {
|
||||
if (!$line)
|
||||
continue;
|
||||
if ($mode != 'ryform')
|
||||
$c .= str_repeat("\t", $indent);
|
||||
switch ($mode) {
|
||||
case 'ryform':
|
||||
if ($line[0] == "\t") {
|
||||
$cache .= substr($line, 1)."\n";
|
||||
break;
|
||||
} else {
|
||||
$mode = 'array';
|
||||
}
|
||||
|
||||
case 'array':
|
||||
if ($line == ')' || $line == '}') {
|
||||
if ($cache && $current_ryform) {
|
||||
$c .= $current_ryform->setSource($cache, $indent+1);
|
||||
$c .= 'SET SOURCE ';
|
||||
if ($line == ')')
|
||||
$array[] = $current_ryform;
|
||||
else
|
||||
$array = $current_ryform;
|
||||
}
|
||||
if (array_key_exists($var_name, $protecteds))
|
||||
call_user_func(array($object, $protecteds[$var_name]), $array);
|
||||
else
|
||||
$object->$var_name = $array;
|
||||
$mode = 'var';
|
||||
$cache = '';
|
||||
continue;
|
||||
} else if ($line[0] == '[') {
|
||||
if ($cache && $current_ryform) {
|
||||
$c .= $current_ryform->setSource($cache, $indent+1);
|
||||
$array[] = $current_ryform;
|
||||
$c .= 'SET SOURCE ';
|
||||
}
|
||||
$ryform_name = substr($line, 1, strlen($line)-2);
|
||||
$c .= 'New Ryform: '.$ryform_name."\n";
|
||||
$cache = '';
|
||||
$current_ryform = new $ryform_name();
|
||||
$mode = 'ryform';
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$sep = strpos($line, '=');
|
||||
if ($sep) {
|
||||
$var_name = substr($line, 0, $sep-1);
|
||||
$value = substr($line, $sep+2);
|
||||
if ($value == '(' || $value == '{') {
|
||||
$c .= $var_name.' is ARRAY'."\n";
|
||||
$mode = 'array';
|
||||
$array = array();
|
||||
} else {
|
||||
$c .= $var_name .' = '.$value."\n";
|
||||
if ($value[0] == '\'' && $value[strlen($value)-1] == '\'')
|
||||
$object->$var_name = str_replace('\n', "\n", substr($value, 1, -1));
|
||||
else {
|
||||
if (is_numeric($value))
|
||||
$object->$var_name = eval('return '.$value.';');
|
||||
else if ($value == 'false')
|
||||
$object->$var_name = false;
|
||||
else if ($value == 'true')
|
||||
$object->$var_name = true;
|
||||
else if ($value == 'NULL')
|
||||
$object->$var_name = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $c;
|
||||
}
|
||||
|
||||
interface iRyForm {
|
||||
function getForm($url_params);
|
||||
function setFormParams($params);
|
||||
function getHtmlRepr();
|
||||
function getFormDefs();
|
||||
function getFormDefsExtraValues();
|
||||
function preSerialization();
|
||||
function postSerialization($vars=array());
|
||||
function getTemplate();
|
||||
}
|
||||
|
||||
class ryFormDef {
|
||||
|
||||
public $name = '';
|
||||
public $type = DEF_TYPE_UNKNOWN;
|
||||
public $params = array();
|
||||
public $infos = '';
|
||||
public $defaultValue = NULL;
|
||||
public $value = NULL;
|
||||
public $extraValues = array();
|
||||
public $hidden = false;
|
||||
public $optional = false;
|
||||
public $admin = false;
|
||||
public $superAdmin = false;
|
||||
public $prefixTrad = '';
|
||||
|
||||
function __construct($name, $type, $params=array(), $defaultValue=NULL, $optional=false, $infos='') {
|
||||
$this->name = $name;
|
||||
$this->type = $type;
|
||||
$this->params = $params;
|
||||
$this->defaultValue = $defaultValue;
|
||||
$this->optional = $optional;
|
||||
$this->infos = $infos;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class basicRyForm implements iRyForm {
|
||||
public $formName = ''; // Used by Form
|
||||
public $id = 0;
|
||||
|
||||
function __construct($name='', $title='') {
|
||||
}
|
||||
|
||||
function getForm($url_params) {
|
||||
$form = new ryForm($this->formName);
|
||||
$form_defs = $this->getFormDefs();
|
||||
foreach ($form_defs as $def)
|
||||
$form->addDefine($def);
|
||||
return $form->getForm(_s('section', $this->formName.' ('.get_class($this).')'));
|
||||
}
|
||||
|
||||
function setFormParams($params) {
|
||||
foreach ($params as $name => $value) {
|
||||
if (property_exists($this, $name))
|
||||
$this->$name = $value;
|
||||
}
|
||||
}
|
||||
|
||||
function getHtmlRepr() {
|
||||
return $this->formName.' ('.get_class($this).')';
|
||||
}
|
||||
|
||||
function getFormDefs() {
|
||||
return array();
|
||||
}
|
||||
|
||||
function getFormDefsExtraValues() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/*function preSerialization() {
|
||||
unset($this->tools);
|
||||
}*/
|
||||
|
||||
function preSerialization() {
|
||||
$all_defs = array('class_name');
|
||||
$this->author = _user()->id;
|
||||
foreach ($this->getFormDefs() as $def)
|
||||
$all_defs[] = $def->name;
|
||||
|
||||
foreach (get_object_vars($this) as $name => $value) {
|
||||
if (!in_array($name, $all_defs))
|
||||
unset($this->$name);
|
||||
}
|
||||
}
|
||||
|
||||
function postSerialization($vars=array()) {
|
||||
}
|
||||
|
||||
function getTemplate() {
|
||||
return '';
|
||||
}
|
||||
|
||||
function getSource($indent=0) {
|
||||
$attrs = $this->getFormDefs();
|
||||
$c = str_repeat("\t", $indent-1).'['.get_class($this).']'."\n";
|
||||
foreach ($attrs as $attr) {
|
||||
$c .= str_repeat("\t", $indent).$attr->name.' ';
|
||||
$var = $this->{$attr->name};
|
||||
if (is_object($var)) {
|
||||
$c .= "= {\n".substr($var->getSource($indent+1), 0, -1)."\n".str_repeat("\t", $indent).'}';
|
||||
} else if (is_array($var)) {
|
||||
$c .= '= ('."\n";
|
||||
foreach ($var as $element) {
|
||||
if (is_object($element))
|
||||
$c .= $element->getSource($indent+1);
|
||||
else if ($element)
|
||||
$c .= '#'.str_replace("\r", '', str_replace("\n", '\\\\n', var_export($element, true)));
|
||||
}
|
||||
$c .= str_repeat("\t", $indent).")";
|
||||
} else
|
||||
$c .= '= '.str_replace("\r", '', str_replace("\n", '\\\\n', var_export($var, true)));
|
||||
$c .= "\n";
|
||||
}
|
||||
return $c;
|
||||
}
|
||||
|
||||
function setSource($src, $indent=0) {
|
||||
$this->preSerialization();
|
||||
return setRyformSource($this, $src, $indent);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
130
code/web/api/common/time.php
Normal file
|
@ -0,0 +1,130 @@
|
|||
<?php
|
||||
/* Copyright (C) 2009 Winch Gate Property Limited
|
||||
*
|
||||
* This file is part of ryzom_api.
|
||||
* ryzom_api is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ryzom_api is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with ryzom_api. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Basic constants */
|
||||
/* 1 IG hour = 3 IRL minutes = 1800 ticks */
|
||||
define('RYTIME_HOUR_TICKS', 1800);
|
||||
define('RYTIME_DAY_HOURS', 24);
|
||||
define('RYTIME_SEASON_DAYS', 90);
|
||||
define('RYTIME_MONTH_DAYS', 30);
|
||||
define('RYTIME_CYCLE_MONTHS', 12);
|
||||
define('RYTIME_JY_CYCLES', 4);
|
||||
define('RYTIME_WEEK_DAYS', 6);
|
||||
/* 0 = spring, 1 = summer, 2 = automn, 3 = winter */
|
||||
define('RYTIME_CYCLE_SEASONS', 4);
|
||||
/* Tick is offset on server of 61 days. */
|
||||
define('RYTIME_TICK_OFFSET', 61 * RYTIME_DAY_HOURS * RYTIME_HOUR_TICKS);
|
||||
|
||||
define('RYTIME_START_JY', 2568);
|
||||
|
||||
/* Helpers */
|
||||
define('RYTIME_CYCLE_DAYS',RYTIME_CYCLE_MONTHS * RYTIME_MONTH_DAYS);
|
||||
define('RYTIME_JY_DAYS', RYTIME_CYCLE_DAYS * RYTIME_JY_CYCLES);
|
||||
define('RYTIME_JY_MONTHS', RYTIME_CYCLE_MONTHS * RYTIME_JY_CYCLES);
|
||||
|
||||
// Takes a server tick and returns a computed array
|
||||
function ryzom_time_array($tick) {
|
||||
$out = array();
|
||||
$out["server_tick"] = $tick;
|
||||
|
||||
$time_in_hours = ($tick-RYTIME_TICK_OFFSET) / RYTIME_HOUR_TICKS;
|
||||
$day = $time_in_hours / RYTIME_DAY_HOURS;
|
||||
|
||||
$out["jena_year"] = floor($day / RYTIME_JY_DAYS) + RYTIME_START_JY;
|
||||
if ($day < 0) $day = RYTIME_JY_DAYS - abs($day) % RYTIME_JY_DAYS;
|
||||
$out["day_of_jy"] = $day % RYTIME_JY_DAYS;
|
||||
$out["month_of_jy"] = floor($out["day_of_jy"] / RYTIME_MONTH_DAYS);
|
||||
|
||||
$out["cycle"] = floor($out["day_of_jy"] / RYTIME_CYCLE_DAYS);
|
||||
$out["day_of_cycle"] = $day % RYTIME_CYCLE_DAYS;
|
||||
$out["month_of_cycle"] = $out["month_of_jy"] % RYTIME_CYCLE_MONTHS;
|
||||
|
||||
$out["day_of_month"] = $out["day_of_jy"] % RYTIME_MONTH_DAYS;
|
||||
$out["day_of_week"] = $day % RYTIME_WEEK_DAYS;
|
||||
|
||||
$out["season"] = ($day / RYTIME_SEASON_DAYS) % RYTIME_CYCLE_SEASONS;
|
||||
$out["day_of_season"] = $day % RYTIME_SEASON_DAYS;
|
||||
|
||||
$out["time_of_day"] = abs($time_in_hours) % RYTIME_DAY_HOURS;
|
||||
if ($time_in_hours < 0 && $out["time_of_day"]) $out["time_of_day"] = RYTIME_DAY_HOURS - $out["time_of_day"];
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
function ryzom_time_xml_without_cache($rytime) {
|
||||
$out = new SimpleXMLElement('<shard_time/>');
|
||||
foreach($rytime as $key => $value) {
|
||||
$out->addChild($key, $value);
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Take number of the month (0-11) and returns its name
|
||||
*/
|
||||
function ryzom_month_name($month_number) {
|
||||
if ($month_number < 0 || $month_number > 11) return "bad month";
|
||||
|
||||
$RYTIME_MONTHS = array(
|
||||
'Winderly', 'Germinally', 'Folially', 'Floris',
|
||||
'Medis', 'Thermis', 'Harvestor', 'Frutor',
|
||||
'Fallenor', 'Pluvia', 'Mystia', 'Nivia'
|
||||
);
|
||||
|
||||
return $RYTIME_MONTHS[(int)$month_number];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Take number of the day of week (0-5) and returns its name
|
||||
*/
|
||||
function ryzom_day_name($day_number) {
|
||||
if ($day_number < 0 || $day_number > 5) return "bad day of week";
|
||||
|
||||
$RYTIME_DAYS = array(
|
||||
'Prima', 'Dua', 'Tria',
|
||||
'Quarta', 'Quinteth', 'Holeth'
|
||||
);
|
||||
|
||||
return $RYTIME_DAYS[(int)$day_number];
|
||||
}
|
||||
|
||||
/**
|
||||
* Take a computed ryzom time array and returns the formatted date
|
||||
* (Official 2004 Format without trailing JY)
|
||||
*/
|
||||
function ryzom_time_txt($rytime, $lang = "en") {
|
||||
if ($lang != "en" && $lang != "fr" && $lang != "de") $lang = "en";
|
||||
|
||||
$RYTIME_AC = array(
|
||||
"de" => array("1. AZ", "2. AZ", "3. AZ", "4. AZ"),
|
||||
"en" => array("1st AC", "2nd AC", "3rd AC", "4th AC"),
|
||||
"fr" => array("1er CA", "2e CA", "3e CA", "4e CA")
|
||||
);
|
||||
|
||||
# Day, Month DayOfMonth, CycleNth AC JY
|
||||
return sprintf("%sh - %s, %s %d, %s %d",
|
||||
$rytime["time_of_day"],
|
||||
ryzom_day_name($rytime["day_of_week"]),
|
||||
ryzom_month_name($rytime["month_of_cycle"]),
|
||||
$rytime["day_of_month"] + 1,
|
||||
$RYTIME_AC[$lang][$rytime["cycle"]],
|
||||
$rytime["jena_year"]);
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,3 +1,69 @@
|
|||
<?php
|
||||
|
||||
/* Copyright (C) 2009 Winch Gate Property Limited
|
||||
*
|
||||
* This file is part of ryzom_api.
|
||||
* ryzom_api is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ryzom_api is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with ryzom_api. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
class ryUser {
|
||||
private $infos;
|
||||
|
||||
function __construct($infos) {
|
||||
$this->infos = $infos;
|
||||
}
|
||||
|
||||
function __get($name)
|
||||
{
|
||||
if (array_key_exists($name, $this->infos)) {
|
||||
return $this->infos[$name];
|
||||
} else {
|
||||
/** TODO **/
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
function inGroup($groups) {
|
||||
$groups = explode(':', $groups);
|
||||
foreach ($groups as $group) {
|
||||
if ($group != '') {
|
||||
if (in_array($group, $this->groups))
|
||||
return true;
|
||||
if ('P_'.$this->id == $group)
|
||||
return true;
|
||||
if ('G_'.$this->guild_id == $group)
|
||||
return true;
|
||||
if ($group == '*')
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function ryzom_auth_user($ask_login=true, $welcome_message='') {
|
||||
global $user, $_USER;
|
||||
|
||||
$result = ryzom_app_authenticate($user, $ask_login, $welcome_message, true);
|
||||
$_USER = new RyUser($user);
|
||||
return $result;
|
||||
}
|
||||
|
||||
function _user() {
|
||||
global $_USER;
|
||||
return $_USER;
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
|
@ -1,6 +1,40 @@
|
|||
<?php
|
||||
|
||||
/* Copyright (C) 2009 Winch Gate Property Limited
|
||||
*
|
||||
* This file is part of ryzom_api.
|
||||
* ryzom_api is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ryzom_api is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with ryzom_api. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
include_once('logger.php');
|
||||
include_once('dfm.php');
|
||||
|
||||
define('SERVER', 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']);
|
||||
|
||||
function stripslashes_deep($value)
|
||||
{
|
||||
$value = is_array($value) ?
|
||||
array_map('stripslashes_deep', $value) :
|
||||
stripslashes($value);
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
if (ini_get('magic_quotes_gpc') == 1) {
|
||||
$_POST = stripslashes_deep($_POST);
|
||||
$_GET = stripslashes_deep($_GET);
|
||||
}
|
||||
|
||||
// Always use this function to get param because in game, the param can be pass by _GET or by _POST
|
||||
function ryzom_get_param($var, $default='')
|
||||
|
@ -24,13 +58,30 @@ function parse_query($var)
|
|||
|
||||
foreach($var as $val) {
|
||||
$x = explode('=', $val);
|
||||
if (count($x) > 1)
|
||||
$arr[$x[0]] = urldecode($x[1]);
|
||||
else
|
||||
$arr[$x[0]] = '';
|
||||
}
|
||||
unset($val, $x, $var);
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
function ryzom_get_params()
|
||||
{
|
||||
if (!isset($GLOBALS['URL_PARAMS']))
|
||||
$GLOBALS['URL_PARAMS'] = parse_query($_SERVER['REQUEST_URI']);
|
||||
return $GLOBALS['URL_PARAMS'];
|
||||
}
|
||||
|
||||
function ryzom_unset_url_param($name) {
|
||||
if (!isset($GLOBALS['URL_PARAMS']))
|
||||
$GLOBALS['URL_PARAMS'] = parse_query($_SERVER['REQUEST_URI']);
|
||||
unset($GLOBALS['URL_PARAMS'][$name]);
|
||||
return $GLOBALS['URL_PARAMS'];
|
||||
}
|
||||
|
||||
if (!function_exists('http_build_query')) {
|
||||
function http_build_query($data, $prefix='', $sep='', $key='') {
|
||||
$ret = array();
|
||||
|
@ -50,6 +101,55 @@ if (!function_exists('http_build_query')) {
|
|||
}
|
||||
}
|
||||
|
||||
if(!function_exists('_url')){
|
||||
function _url($base_params=null, $add_params=array()){
|
||||
if ($base_params !== null)
|
||||
return SERVER.'?'.http_build_query(array_merge($base_params, $add_params));
|
||||
else
|
||||
return SERVER;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(!function_exists('_h')){
|
||||
function _h($s){
|
||||
return htmlspecialchars($s, ENT_QUOTES, 'UTF-8');
|
||||
}
|
||||
}
|
||||
|
||||
if(!function_exists('_i')){
|
||||
function _i($img, $alt=''){
|
||||
if (substr($img, strlen($img)-4) == '.tga') // img from client texture : ig only
|
||||
return $img;
|
||||
|
||||
if (is_file(RYAPI_PATH.'/data/icons/'.$img.'.png'))
|
||||
$img = RYAPI_URL.'/data/icons/'.$img.'.png';
|
||||
else if (is_file(RYAPP_PATH.'/data/icons/'.$img.'.png'))
|
||||
$img = RYAPP_URL.'/data/icons/'.$img.'.png';
|
||||
else
|
||||
$img = 'view_remove';
|
||||
|
||||
if ($alt)
|
||||
return '<img src="'.$img.'" title="'.$alt.'" alt="'.utf8_decode($alt).'" />';
|
||||
else
|
||||
return '<img src="'.$img.'" />';
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if(!function_exists('_l')){
|
||||
function _l($text, $base_params=array(), $add_params=array())
|
||||
{
|
||||
return '<a href="'.SERVER.'?'.http_build_query(array_merge($base_params, $add_params)).'">'.$text.'</a>';
|
||||
}
|
||||
}
|
||||
|
||||
if(!function_exists('_b')){
|
||||
function _b($text, $base_params=array(), $add_params=array())
|
||||
{
|
||||
return '<a href="'.SERVER.'?'.http_build_query(array_merge($base_params, $add_params)).'" class="ryzom-ui-button">'.$text.'</a>';
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
*
|
||||
|
@ -66,8 +166,10 @@ function translation_exists($id) {
|
|||
function get_translation($id, $lang, $args=array()) {
|
||||
global $ryzom_texts, $user;
|
||||
if(!isset($ryzom_texts[$id])) return '{'.$id.'}';
|
||||
if(!isset($ryzom_texts[$id][$lang])) return '{'.$id.'['.$lang.']}';
|
||||
if($ryzom_texts[$id][$lang] == '' && isset($ryzom_texts[$id]['en'])) return @vsprintf($ryzom_texts[$id]['en'], $args);
|
||||
if(empty($ryzom_texts[$id][$lang])){
|
||||
if(isset($ryzom_texts[$id]['en'])) return @vsprintf($ryzom_texts[$id]['en'], $args);
|
||||
return '{'.$id.'['.$lang.']}';
|
||||
}
|
||||
return @vsprintf($ryzom_texts[$id][$lang], $args);
|
||||
}
|
||||
|
||||
|
@ -87,10 +189,12 @@ function _t($id, $args=array()) {
|
|||
$a = ' '.strval($args);
|
||||
}
|
||||
if(!isset($ryzom_texts[$id])) return '{'.$id.$a.'}';
|
||||
if(!isset($ryzom_texts[$id][$user['lang']])) return '{'.$id.'['.$user['lang'].']'.$a.'}';
|
||||
if($ryzom_texts[$id][$user['lang']] == '' && isset($ryzom_texts[$id]['en']) && $ryzom_texts[$id]['en'] != '') return @vsprintf($ryzom_texts[$id]['en'], $args);
|
||||
if($ryzom_texts[$id][$user['lang']] == '' && isset($ryzom_texts[$id]['fr']) && $ryzom_texts[$id]['fr'] != '') return '{'.$id.$a.'}';
|
||||
if($ryzom_texts[$id][$user['lang']] == '' && isset($ryzom_texts[$id]['de']) && $ryzom_texts[$id]['de'] != '') return '{'.$id.$a.'}';
|
||||
if(empty($ryzom_texts[$id][$user['lang']])){
|
||||
if(!empty($ryzom_texts[$id]['en'])) return @vsprintf($ryzom_texts[$id]['en'], $args);
|
||||
if(!empty($ryzom_texts[$id]['fr'])) return '{'.$id.$a.'}';
|
||||
if(!empty($ryzom_texts[$id]['de'])) return '{'.$id.$a.'}';
|
||||
return '{'.$id.'['.$user['lang'].']'.$a.'}';
|
||||
}
|
||||
return @vsprintf($ryzom_texts[$id][$user['lang']], $args);
|
||||
}
|
||||
|
||||
|
@ -100,7 +204,20 @@ function _t($id, $args=array()) {
|
|||
*
|
||||
* ***/
|
||||
|
||||
|
||||
function ryzom_timer($timestamp) {
|
||||
$d = intval($timestamp / 86400);
|
||||
$timestamp = $timestamp % 86400;
|
||||
$h = intval($timestamp / 3600);
|
||||
$timestamp = $timestamp % 3600;
|
||||
$m = intval($timestamp / 60);
|
||||
$s = $timestamp % 60;
|
||||
if ($d>1)
|
||||
return sprintf('%d'._t('days').' %02d:%02d:%02d', $d, $h, $m, $s);
|
||||
else if ($d)
|
||||
return sprintf('%d'._t('day').' %02d:%02d:%02d', $d, $h, $m, $s);
|
||||
else
|
||||
return sprintf("%02d:%02d:%02d", $h, $m, $s);
|
||||
}
|
||||
|
||||
// Get a human and translated readable time, for example "3 days ago"
|
||||
function ryzom_relative_time($timestamp) {
|
||||
|
@ -133,7 +250,10 @@ function ryzom_relative_time($timestamp) {
|
|||
}
|
||||
}
|
||||
|
||||
if(!empty($ryzom_periods[$user['lang']][$form][$j]))
|
||||
$final = $ryzom_periods[$user['lang']][$form][$j];
|
||||
else
|
||||
$final = $ryzom_periods['en'][$form][$j];
|
||||
$text = _t('date_format', array($difference, $final, $ending));
|
||||
return $text;
|
||||
}
|
||||
|
@ -150,33 +270,197 @@ function ryzom_absolute_time($timestamp) {
|
|||
return $text;
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
*
|
||||
* Ryzom utilities
|
||||
*
|
||||
*
|
||||
* ***/
|
||||
|
||||
function ryzom_generate_password($length=8, $level=2, $oneofeach=false) {
|
||||
$validchars[1] = "0123456789abcdfghjkmnpqrstvwxyz";
|
||||
$validchars[2] = "0123456789abcdfghjkmnpqrstvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
$validchars[3] = "0123456789_!@#$%&*()-=+/abcdfghjkmnpqrstvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_!@#$%&*()-=+/";
|
||||
|
||||
$password = "";
|
||||
$counter = 0;
|
||||
|
||||
while ($counter < $length) {
|
||||
$actChar = substr($validchars[$level], rand(0, strlen($validchars[$level])-1), 1);
|
||||
|
||||
// if $oneofeach then All character must be different (slower)
|
||||
if (!$oneofeach || !strstr($password, $actChar)) {
|
||||
$password .= $actChar;
|
||||
$counter++;
|
||||
}
|
||||
}
|
||||
|
||||
return $password;
|
||||
}
|
||||
|
||||
|
||||
function file_get_contents_cached($fn, $cache_time=300) {
|
||||
global $ryzom_bench_text;
|
||||
|
||||
$lfn = 'tmp/'.strtr($fn, ':/.?&=', '____________');
|
||||
|
||||
// get the new file from internet every $cache_time (default=5min)
|
||||
if (file_exists($lfn) && filesize($lfn) > 0 && time() < filemtime($lfn) + $cache_time) {
|
||||
$content = file_get_contents($lfn);
|
||||
} else {
|
||||
$content = file_get_contents($fn);
|
||||
if ($content != '') file_put_contents($lfn, $content);
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
|
||||
function ryzom_redirect($url, $group='', $extra_lua='') {
|
||||
global $user;
|
||||
$lua = $extra_lua."\n";
|
||||
if ($user['ig']) {
|
||||
if (!$group)
|
||||
$lua .= 'getUI(__CURRENT_WINDOW__):browse("'.str_replace('&', '&', $url).'")';
|
||||
else {
|
||||
if (substr($group, 0, 3) == 'ui:')
|
||||
$lua .= 'getUI("'.$group.'"):browse("'.str_replace('&', '&', $url).'")';
|
||||
else
|
||||
$lua .= 'getUI("ui:interface:'.$group.':content:html"):browse("'.str_replace('&', '&', $url).'")';
|
||||
}
|
||||
echo '<lua>'.$lua.'</lua>';
|
||||
exit();
|
||||
} else {
|
||||
header('Location: '.$url);
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
*
|
||||
* Debug tools
|
||||
*
|
||||
* ***/
|
||||
|
||||
function p($var, $value=NULL) {
|
||||
function alert($var, $value=NULL, $level=1) {
|
||||
p($var, $value, '#FF7777', $level);
|
||||
}
|
||||
|
||||
define('pNULL', '§$£¤*µ%ù²&#!;,;:.?/?.<>');
|
||||
|
||||
function p($var, $value=pNULL, $color='#FFFF00', $level=0) {
|
||||
ob_start();
|
||||
debug_print_backtrace();
|
||||
$bt = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$bt = explode("\n",$bt);
|
||||
$bt = explode('[', $bt[1]);
|
||||
ob_start();
|
||||
echo '<font color="#AAFFFF">'.substr($bt[count($bt)-1], 0, -1)."</font>\n";
|
||||
if ($value !== NULL) {
|
||||
echo '<font color="#FFFFFF">'.$var.' : </font>';
|
||||
$bt = explode("\n#",$bt);
|
||||
if (isset($bt[$level]))
|
||||
$bt1 = explode('[', $bt[$level]);
|
||||
else
|
||||
$bt1 = array('');
|
||||
|
||||
if (isset($bt[$level+1]))
|
||||
$bt2 = explode('[', $bt[$level+1]);
|
||||
else
|
||||
$bt2 = array('');
|
||||
|
||||
$c = '';
|
||||
if ($value !== pNULL) {
|
||||
$c .= '<font color="#FFFFFF">'.$var.' : </font>';
|
||||
$var = $value;
|
||||
}
|
||||
//if (is_array($var))
|
||||
echo '<pre>';
|
||||
print_r($var);
|
||||
echo '</pre>';
|
||||
// else
|
||||
// var_dump($var);
|
||||
ryLogger::getInstance()->addPrint(ob_get_contents());
|
||||
$c .= '<font color="#AAFFFF">'.substr(str_replace("\n", "", $bt2[count($bt2)-1]), 0, -1).' => '.substr(str_replace("\n", "", $bt1[count($bt1)-1]), 0, -1)."</font> ";
|
||||
ryLogger::getInstance()->addPrint($c);
|
||||
ob_start();
|
||||
var_dump($var);
|
||||
ryLogger::getInstance()->addPrint(_h(ob_get_contents()), $color);
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
*
|
||||
* Lua tools
|
||||
*
|
||||
* ***/
|
||||
|
||||
class ryLua {
|
||||
|
||||
static private $lua = array();
|
||||
static private $luaend = array();
|
||||
static private $indent;
|
||||
static private $indentend;
|
||||
static private $linkTargetId = 0;
|
||||
|
||||
static function add($code, $indent=NULL) {
|
||||
if ($indent !== NULL)
|
||||
self::$indent += $indent;
|
||||
$tabs = str_repeat(" ", self::$indent);
|
||||
$a = $tabs.str_replace("\n", "\n ".$tabs, $code);
|
||||
self::$lua[] = $a;
|
||||
}
|
||||
|
||||
static function addEnd($code, $indent=NULL) {
|
||||
if ($indent !== NULL)
|
||||
self::$indentend += $indent;
|
||||
$tabs = str_repeat(" ", self::$indentend);
|
||||
$a = $tabs.str_replace("\n", "\n ".$tabs, $code);
|
||||
self::$luaend[] = $a;
|
||||
}
|
||||
|
||||
|
||||
static function get($ig) {
|
||||
ryLogger::getInstance()->addPrint(implode("\n", self::$lua), '#FF00FF');
|
||||
$ret = ($ig)?"<lua>\n".implode("\n", self::$lua)."\n</lua>":'';
|
||||
self::$lua = array();
|
||||
return $ret;
|
||||
}
|
||||
|
||||
static function getEnd($ig) {
|
||||
ryLogger::getInstance()->addPrint(implode("\n", self::$luaend), '#FF55FF');
|
||||
$ret = ($ig)?"<lua>\n".implode("\n", self::$luaend)."\n</lua>":'';
|
||||
self::$luaend = array();
|
||||
return $ret;
|
||||
}
|
||||
|
||||
static function text($text) {
|
||||
return str_replace('"', '\"', $text);
|
||||
}
|
||||
|
||||
static function url($base_params=null, $add_params=array()) {
|
||||
return str_replace('&', '&', _url($base_params, $add_params));
|
||||
}
|
||||
|
||||
|
||||
function openLink($text, $target='webig', $base_params=array(), $add_params=array(), $urllua='', $runlua='')
|
||||
{
|
||||
$url = self::url($base_params, $add_params);
|
||||
if ($target == "help_browser")
|
||||
$url .= "&ignore=";
|
||||
$id = ryzom_generate_password(8).strval(time()).strval(self::$linkTargetId++);
|
||||
$lua = <<< END
|
||||
function openLink{$id}()
|
||||
runAH(nil, "browse", "name=ui:interface:{$target}:content:html|url={$url}"{$urllua})
|
||||
{$runlua}
|
||||
end
|
||||
END;
|
||||
self::add($lua);
|
||||
if (RYZOM_IG)
|
||||
return '<a href="ah:lua&openLink'.$id.'()">'.$text.'</a>';
|
||||
return $text;
|
||||
}
|
||||
|
||||
static function link($id, $luacode, $text) {
|
||||
$lua = <<<END
|
||||
function runLua{$id}()
|
||||
{$luacode}
|
||||
end
|
||||
END;
|
||||
self::add($lua);
|
||||
if (RYZOM_IG)
|
||||
return '<a href="ah:lua&runLua'.$id.'()">'.$text.'</a>';
|
||||
return $text;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
23
code/web/api/common/xml_utils.php
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
/* Copyright (C) 2009 Winch Gate Property Limited
|
||||
*
|
||||
* This file is part of ryzom_api.
|
||||
* ryzom_api is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ryzom_api is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with ryzom_api. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
function ryzom_display_xml_header() {
|
||||
header('Content-Type: application/xml; charset=UTF-8');
|
||||
}
|
||||
|
||||
?>
|
|
@ -33,14 +33,18 @@
|
|||
color: white;
|
||||
}
|
||||
.ryzom-ui input, .ryzom-ui select {
|
||||
border-top: 1px solid #030403;
|
||||
border-right: 1px solid #6e7f57;
|
||||
border-bottom: 1px solid #889e6c;
|
||||
border-left: 1px solid #272d1f;
|
||||
background-color: #37402b;
|
||||
color: #ddd;
|
||||
border-bottom: 1px solid #7B7E80;
|
||||
border-left: 1px solid #7B7E80;
|
||||
border-top: 1px solid #101010;
|
||||
border-right: 1px solid #101010;
|
||||
background-color: #1D1D1D;
|
||||
border-radius: 3px;
|
||||
color: #BBB;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
font-size: 12px;
|
||||
margin: 2px 0 5px 0;
|
||||
padding: 1px;
|
||||
}
|
||||
.ryzom-ui input[type=text] {
|
||||
width: 100%;
|
||||
|
@ -52,27 +56,43 @@
|
|||
|
||||
/* input[type=submit] will make IE6 to ignore whole CSS rule, so cant combine this with .ryzom-ui-button below */
|
||||
input[type=submit] {
|
||||
border-bottom: 1px solid #030403;
|
||||
border-left: 1px solid #6e7f57;
|
||||
border-top: 1px solid #889e6c;
|
||||
border-right: 1px solid #272d1f;
|
||||
background-color: #435120;
|
||||
border-bottom: 1px solid #7B7E80;
|
||||
border-left: 1px solid #7B7E80;
|
||||
border-top: 1px solid #7B7E80;
|
||||
border-right: 1px solid #7B7E80;
|
||||
background-color: #232323;
|
||||
border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
color: #BBB;
|
||||
}
|
||||
input[type=submit]:hover {
|
||||
border-bottom: 1px solid #FFFFFF;
|
||||
border-left: 1px solid #FFFFFF;
|
||||
border-top: 1px solid #FFFFFF;
|
||||
border-right: 1px solid #FFFFFF;
|
||||
color: #FFF;
|
||||
}
|
||||
input.ryzom-ui-button, .ryzom-ui-button {
|
||||
border-bottom: 1px solid #030403;
|
||||
border-left: 1px solid #6e7f57;
|
||||
border-top: 1px solid #889e6c;
|
||||
border-right: 1px solid #272d1f;
|
||||
background-color: #435120;
|
||||
border-bottom: 1px solid #7B7E80;
|
||||
border-left: 1px solid #7B7E80;
|
||||
border-top: 1px solid #7B7E80;
|
||||
border-right: 1px solid #7B7E80;
|
||||
background-color: #232323;
|
||||
border-radius: 3px;
|
||||
color: #BBB;
|
||||
}
|
||||
a.ryzom-ui-button, a.ryzom-ui-button:visited {
|
||||
color: white;
|
||||
padding: 0 .5em;
|
||||
color: #DDD;
|
||||
padding: .2em .5em;
|
||||
text-decoration: none;
|
||||
}
|
||||
a.ryzom-ui-button:hover {
|
||||
background: #536130;
|
||||
color: #ddd;
|
||||
border-bottom: 1px solid #FFFFFF;
|
||||
border-left: 1px solid #FFFFFF;
|
||||
border-top: 1px solid #FFFFFF;
|
||||
border-right: 1px solid #FFFFFF;
|
||||
color: #FFF;
|
||||
}
|
||||
/* window without title - just borders */
|
||||
.ryzom-ui-tl {
|
||||
|
|
BIN
code/web/api/data/icons/add_app.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
code/web/api/data/icons/edit.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
code/web/api/data/icons/edit_16.png
Normal file
After Width: | Height: | Size: 732 B |
BIN
code/web/api/data/icons/no_action.png
Normal file
After Width: | Height: | Size: 566 B |
BIN
code/web/api/data/img/backgrounds/parchemin.png
Normal file
After Width: | Height: | Size: 369 KiB |
BIN
code/web/api/data/img/bordure.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 229 B After Width: | Height: | Size: 736 B |
Before Width: | Height: | Size: 396 B After Width: | Height: | Size: 725 B |
BIN
code/web/api/data/img/lang/es.png
Normal file
After Width: | Height: | Size: 649 B |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 675 B |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 646 B |
17
code/web/api/data/js/combobox.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
|
||||
function comboInit(thelist)
|
||||
{
|
||||
theinput = document.getElementById(theinput);
|
||||
var idx = thelist.selectedIndex;
|
||||
var content = thelist.options[idx].value;
|
||||
if(theinput.value == "")
|
||||
theinput.value = content;
|
||||
}
|
||||
|
||||
function combo(thelist, theinput)
|
||||
{
|
||||
theinput = document.getElementById(theinput);
|
||||
var idx = thelist.selectedIndex;
|
||||
var content = thelist.options[idx].value;
|
||||
theinput.value = content;
|
||||
}
|
9266
code/web/api/data/js/jquery-1.7.1.js
vendored
Normal file
37
code/web/api/data/js/tab.js
Normal file
|
@ -0,0 +1,37 @@
|
|||
|
||||
if(window.addEventListener)
|
||||
window.addEventListener("load", tabulation, false);
|
||||
else
|
||||
window.attachEvent("onload", tabulation);
|
||||
|
||||
function tabulation(){
|
||||
var textareas = document.getElementsByTagName("textarea");
|
||||
for(var i = 0, t = textareas.length; i < t; i++){
|
||||
textareas[i].onkeydown = function(e){
|
||||
var tab = (e || window.event).keyCode == 9;
|
||||
if(tab){
|
||||
var tabString = String.fromCharCode(9);
|
||||
var scroll = this.scrollTop;
|
||||
|
||||
if(window.ActiveXObject){
|
||||
var textR = document.selection.createRange();
|
||||
var selection = textR.text;
|
||||
textR.text = tabString + selection;
|
||||
textR.moveStart("character",-selection.length);
|
||||
textR.moveEnd("character", 0);
|
||||
textR.select();
|
||||
}
|
||||
else {
|
||||
var beforeSelection = this.value.substring(0, this.selectionStart);
|
||||
var selection = this.value.substring(this.selectionStart, this.selectionEnd);
|
||||
var afterSelection = this.value.substring(this.selectionEnd);
|
||||
this.value = beforeSelection + tabString + selection + afterSelection;
|
||||
this.setSelectionRange(beforeSelection.length + tabString.length, beforeSelection.length + tabString.length + selection.length);
|
||||
}
|
||||
this.focus();
|
||||
this.scrollTop = scroll;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
1
code/web/api/data/ryzom/guild_png/.htaccess
Normal file
|
@ -0,0 +1 @@
|
|||
deny from all
|
BIN
code/web/api/data/ryzom/guild_png/guild_back_b_00_1.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_back_b_00_2.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_back_b_01_1.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_back_b_01_2.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_back_b_02_1.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_back_b_02_2.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_back_b_03_1.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_back_b_03_2.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_back_b_04_1.png
Normal file
After Width: | Height: | Size: 3 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_back_b_04_2.png
Normal file
After Width: | Height: | Size: 3 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_back_b_05_1.png
Normal file
After Width: | Height: | Size: 3.7 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_back_b_05_2.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_back_b_06_1.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_back_b_06_2.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_back_b_07_1.png
Normal file
After Width: | Height: | Size: 3.7 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_back_b_07_2.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_back_b_08_1.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_back_b_08_2.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_back_b_09_1.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_back_b_09_2.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_back_b_10_1.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_back_b_10_2.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_back_b_11_1.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_back_b_11_2.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_back_b_12_1.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_back_b_12_2.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_back_b_13_1.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_back_b_13_2.png
Normal file
After Width: | Height: | Size: 3 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_back_b_14_1.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_back_b_14_2.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_back_s_00_1.png
Normal file
After Width: | Height: | Size: 536 B |
BIN
code/web/api/data/ryzom/guild_png/guild_back_s_00_2.png
Normal file
After Width: | Height: | Size: 517 B |
BIN
code/web/api/data/ryzom/guild_png/guild_back_s_01_1.png
Normal file
After Width: | Height: | Size: 543 B |
BIN
code/web/api/data/ryzom/guild_png/guild_back_s_01_2.png
Normal file
After Width: | Height: | Size: 498 B |
BIN
code/web/api/data/ryzom/guild_png/guild_back_s_02_1.png
Normal file
After Width: | Height: | Size: 539 B |
BIN
code/web/api/data/ryzom/guild_png/guild_back_s_02_2.png
Normal file
After Width: | Height: | Size: 502 B |
BIN
code/web/api/data/ryzom/guild_png/guild_back_s_03_1.png
Normal file
After Width: | Height: | Size: 434 B |
BIN
code/web/api/data/ryzom/guild_png/guild_back_s_03_2.png
Normal file
After Width: | Height: | Size: 419 B |
BIN
code/web/api/data/ryzom/guild_png/guild_back_s_04_1.png
Normal file
After Width: | Height: | Size: 387 B |
BIN
code/web/api/data/ryzom/guild_png/guild_back_s_04_2.png
Normal file
After Width: | Height: | Size: 363 B |
BIN
code/web/api/data/ryzom/guild_png/guild_back_s_05_1.png
Normal file
After Width: | Height: | Size: 561 B |
BIN
code/web/api/data/ryzom/guild_png/guild_back_s_05_2.png
Normal file
After Width: | Height: | Size: 457 B |
BIN
code/web/api/data/ryzom/guild_png/guild_back_s_06_1.png
Normal file
After Width: | Height: | Size: 622 B |
BIN
code/web/api/data/ryzom/guild_png/guild_back_s_06_2.png
Normal file
After Width: | Height: | Size: 484 B |
BIN
code/web/api/data/ryzom/guild_png/guild_back_s_07_1.png
Normal file
After Width: | Height: | Size: 625 B |
BIN
code/web/api/data/ryzom/guild_png/guild_back_s_07_2.png
Normal file
After Width: | Height: | Size: 494 B |
BIN
code/web/api/data/ryzom/guild_png/guild_back_s_08_1.png
Normal file
After Width: | Height: | Size: 513 B |
BIN
code/web/api/data/ryzom/guild_png/guild_back_s_08_2.png
Normal file
After Width: | Height: | Size: 366 B |
BIN
code/web/api/data/ryzom/guild_png/guild_back_s_09_1.png
Normal file
After Width: | Height: | Size: 388 B |
BIN
code/web/api/data/ryzom/guild_png/guild_back_s_09_2.png
Normal file
After Width: | Height: | Size: 416 B |
BIN
code/web/api/data/ryzom/guild_png/guild_back_s_10_1.png
Normal file
After Width: | Height: | Size: 543 B |
BIN
code/web/api/data/ryzom/guild_png/guild_back_s_10_2.png
Normal file
After Width: | Height: | Size: 397 B |
BIN
code/web/api/data/ryzom/guild_png/guild_back_s_11_1.png
Normal file
After Width: | Height: | Size: 584 B |
BIN
code/web/api/data/ryzom/guild_png/guild_back_s_11_2.png
Normal file
After Width: | Height: | Size: 405 B |
BIN
code/web/api/data/ryzom/guild_png/guild_back_s_12_1.png
Normal file
After Width: | Height: | Size: 623 B |
BIN
code/web/api/data/ryzom/guild_png/guild_back_s_12_2.png
Normal file
After Width: | Height: | Size: 394 B |
BIN
code/web/api/data/ryzom/guild_png/guild_back_s_13_1.png
Normal file
After Width: | Height: | Size: 528 B |
BIN
code/web/api/data/ryzom/guild_png/guild_back_s_13_2.png
Normal file
After Width: | Height: | Size: 351 B |
BIN
code/web/api/data/ryzom/guild_png/guild_back_s_14_1.png
Normal file
After Width: | Height: | Size: 431 B |
BIN
code/web/api/data/ryzom/guild_png/guild_back_s_14_2.png
Normal file
After Width: | Height: | Size: 238 B |
BIN
code/web/api/data/ryzom/guild_png/guild_symbol_b_00.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_symbol_b_01.png
Normal file
After Width: | Height: | Size: 2 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_symbol_b_02.png
Normal file
After Width: | Height: | Size: 3 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_symbol_b_03.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_symbol_b_04.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_symbol_b_05.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_symbol_b_06.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
code/web/api/data/ryzom/guild_png/guild_symbol_b_07.png
Normal file
After Width: | Height: | Size: 2.6 KiB |